2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
12 #ifdef BUILD_ECORE_CON
13 # include "Ecore_Con.h"
16 #include "ecore_file_private.h"
18 #ifdef BUILD_ECORE_CON
20 #define ECORE_MAGIC_FILE_DOWNLOAD_JOB 0xf7427cb8
22 struct _Ecore_File_Download_Job
26 Ecore_Con_Url *url_con;
31 void (*completion_cb)(void *data, const char *file, int status);
33 int (*progress_cb) (void *data, const char *file,
34 long int dltotal, long int dlnow,
35 long int ultotal, long int ulnow);
39 Ecore_File_Download_Job *_ecore_file_download_curl(const char *url, const char *dst,
40 void (*completion_cb)(void *data, const char *file, int status),
41 int (*progress_cb)(void *data, const char *file, long int dltotal, long int dlnow, long int ultotal, long int ulnow),
44 static int _ecore_file_download_url_complete_cb(void *data, int type, void *event);
45 static int _ecore_file_download_url_progress_cb(void *data, int type, void *event);
48 static Ecore_Event_Handler *_url_complete_handler = NULL;
49 static Ecore_Event_Handler *_url_progress_download = NULL;
50 static Eina_List *_job_list;
52 #endif /* BUILD_ECORE_CON */
55 ecore_file_download_init(void)
57 #ifdef BUILD_ECORE_CON
58 if (!ecore_con_url_init())
62 _url_complete_handler = ecore_event_handler_add(ECORE_CON_EVENT_URL_COMPLETE, _ecore_file_download_url_complete_cb, NULL);
63 _url_progress_download = ecore_event_handler_add(ECORE_CON_EVENT_URL_PROGRESS, _ecore_file_download_url_progress_cb, NULL);
66 #endif /* BUILD_ECORE_CON */
72 ecore_file_download_shutdown(void)
74 #ifdef BUILD_ECORE_CON
75 if (_url_complete_handler)
76 ecore_event_handler_del(_url_complete_handler);
77 if (_url_progress_download)
78 ecore_event_handler_del(_url_progress_download);
79 _url_complete_handler = NULL;
80 _url_progress_download = NULL;
81 ecore_file_download_abort_all();
83 ecore_con_url_shutdown();
84 #endif /* BUILD_ECORE_CON */
88 ecore_file_download_abort_all(void)
90 #ifdef BUILD_ECORE_CON
91 Ecore_File_Download_Job *job;
93 EINA_LIST_FREE(_job_list, job)
94 ecore_file_download_abort(job);
95 #endif /* BUILD_ECORE_CON */
99 * Download @p url to the given @p dst
100 * @param url The complete url to download
101 * @param dst The local file to save the downloaded to
102 * @param completion_cb A callback called on download complete
103 * @param progress_cb A callback called during the download operation
104 * @param data User data passed to both callbacks
105 * @param job_ret If the protocol in use is http or ftp, this parameter will be
106 * filled with the job. Then you can use ecore_file_download_abort() to cancel it.
108 * @return 1 if the download start or 0 on failure
110 * You must provide the full url, including 'http://', 'ftp://' or 'file://'.\n
111 * If @p dst already exist it will not be overwritten and the function will fail.\n
112 * Ecore must be compiled with CURL to download using http and ftp protocols.\n
113 * The @p status param in the @p completion_cb() will be 0 if the download goes well or
114 * 1 in case of failure.
117 ecore_file_download(const char *url, const char *dst,
118 void (*completion_cb)(void *data, const char *file, int status),
119 int (*progress_cb)(void *data, const char *file, long int dltotal, long int dlnow, long int ultotal, long int ulnow),
120 void *data, Ecore_File_Download_Job **job_ret)
122 #ifdef BUILD_ECORE_CON
123 char *dir = ecore_file_dir_get(dst);
125 if (!ecore_file_is_dir(dir))
131 if (ecore_file_exists(dst)) return 0;
133 /* FIXME: Add handlers for http and ftp! */
134 if (!strncmp(url, "file://", 7))
136 /* FIXME: Maybe fork? Might take a while to copy.
142 url = strchr(url, '/');
143 return ecore_file_cp(url, dst);
146 else if ((!strncmp(url, "http://", 7)) ||
147 (!strncmp(url, "ftp://", 6)))
150 Ecore_File_Download_Job *job;
152 job = _ecore_file_download_curl(url, dst, completion_cb, progress_cb, data);
153 if(job_ret) *job_ret = job;
162 completion_cb = NULL;
166 #endif /* BUILD_ECORE_CON */
170 * Check if the given protocol is available
171 * @param protocol The protocol to check
172 * @return 1 if protocol is handled or 0 if not
174 * @p protocol can be 'http://', 'ftp://' or 'file://'.\n
175 * Ecore must be compiled with CURL to handle http and ftp protocols.
178 ecore_file_download_protocol_available(const char *protocol)
180 #ifdef BUILD_ECORE_CON
181 if (!strncmp(protocol, "file://", 7)) return 1;
183 else if (!strncmp(protocol, "http://", 7)) return 1;
184 else if (!strncmp(protocol, "ftp://", 6)) return 1;
186 #endif /* BUILD_ECORE_CON */
191 #ifdef BUILD_ECORE_CON
195 _ecore_file_download_url_compare_job(const void *data1, const void *data2)
197 const Ecore_File_Download_Job *job = data1;
198 const Ecore_Con_Url *url = data2;
200 if (job->url_con == url) return 0;
205 _ecore_file_download_url_complete_cb(void *data __UNUSED__, int type __UNUSED__, void *event)
207 Ecore_Con_Event_Url_Complete *ev = event;
208 Ecore_File_Download_Job *job;
210 job = eina_list_search_unsorted(_job_list, _ecore_file_download_url_compare_job, ev->url_con);
211 if (!ECORE_MAGIC_CHECK(job, ECORE_MAGIC_FILE_DOWNLOAD_JOB)) return 1;
214 if (job->completion_cb)
215 job->completion_cb(ecore_con_url_data_get(job->url_con), job->dst, !ev->status);
217 _job_list = eina_list_remove(_job_list, job);
226 _ecore_file_download_url_progress_cb(void *data __UNUSED__, int type __UNUSED__, void *event)
228 /* this reports the downloads progress. if we return 0, then download
229 * continues, if we return anything else, then the download stops */
230 Ecore_Con_Event_Url_Progress *ev = event;
231 Ecore_File_Download_Job *job;
233 job = eina_list_search_unsorted(_job_list, _ecore_file_download_url_compare_job, ev->url_con);
234 if (!ECORE_MAGIC_CHECK(job, ECORE_MAGIC_FILE_DOWNLOAD_JOB)) return 1;
236 if (job->progress_cb)
237 if (job->progress_cb(ecore_con_url_data_get(job->url_con), job->dst,
238 (long int) ev->down.total, (long int) ev->down.now,
239 (long int) ev->up.total, (long int) ev->up.now) != 0)
241 _job_list = eina_list_remove(_job_list, job);
252 Ecore_File_Download_Job *
253 _ecore_file_download_curl(const char *url, const char *dst,
254 void (*completion_cb)(void *data, const char *file,
256 int (*progress_cb)(void *data, const char *file,
257 long int dltotal, long int dlnow,
258 long int ultotal, long int ulnow),
261 Ecore_File_Download_Job *job;
263 job = calloc(1, sizeof(Ecore_File_Download_Job));
264 if (!job) return NULL;
266 ECORE_MAGIC_SET(job, ECORE_MAGIC_FILE_DOWNLOAD_JOB);
268 job->file = fopen(dst, "wb");
274 job->url_con = ecore_con_url_new(url);
282 ecore_con_url_fd_set(job->url_con, fileno(job->file));
283 ecore_con_url_data_set(job->url_con, data);
285 job->dst = strdup(dst);
287 job->completion_cb = completion_cb;
288 job->progress_cb = progress_cb;
289 _job_list = eina_list_append(_job_list, job);
291 ecore_con_url_send(job->url_con, NULL, 0, NULL);
299 * Abort the given download job
300 * @param job The download job to abort
304 ecore_file_download_abort(Ecore_File_Download_Job *job)
306 #ifdef BUILD_ECORE_CON
308 ecore_con_url_destroy(job->url_con);
310 _job_list = eina_list_remove(_job_list, job);
314 #endif /* BUILD_ECORE_CON */