All pastes #2132013 Raw Edit

Stuff

public text v1 · immutable
#2132013 ·published 2012-03-25 13:32 UTC
rendered paste body

   


   

/* Enna Media Server - a library and daemon for medias indexation and streaming
 *
 * Copyright (C) 2012 Enna Team. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *    1. Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *    2. Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>

#include <Eina.h>
#include <Ecore.h>
#include <Ecore_Con.h>
#include <Ecore_File.h>

#include "ems_private.h"
#include "ems_downloader.h"
#include "ems_config.h"

/*============================================================================*
 *                                  Local                                     *
 *============================================================================*/
typedef struct _Ems_Downloader Ems_Downloader;
typedef struct _Ems_Downloader_Req Ems_Downloader_Req;

struct _Ems_Downloader
{
   Eina_Hash *hash_req;
};

struct _Ems_Downloader_Req
{
   const char *url;
   const char *filename;
   Ecore_Con_Url *ec_url;
   long size;
   int fd;
   void (*end_cb)(void *data, const char *filename);
   void *data;
};

static Ems_Downloader *_downloader = NULL;

static void
_request_free_cb(Ems_Downloader_Req *req)
{
   if (!req)
     return;

   if (req->fd != -1)
     close(req->fd);
   eina_stringshare_del(req->filename);
   eina_stringshare_del(req->url);
   free(req);
}

static Eina_Bool
_url_progress_cb(void *data, int type, void *event_info)
{
   float percent;
   Ecore_Con_Event_Url_Progress *url_progress = event_info;
   Ems_Downloader_Req *req = eina_hash_find(_downloader->hash_req, url_progress->url_con);

   if (!req || url_progress->url_con != req->ec_url)
     return EINA_TRUE;

   if (url_progress->down.total > 0)
     {
        /* if (!req) */
        /*   return EINA_FALSE; */

        req->size = url_progress->down.now;

        percent = (url_progress->down.now / url_progress->down.total) * 100;
        printf("Total of download complete: %0.1f (%0.0f)%%\n",
               percent, url_progress->down.now);
     }

   return EINA_TRUE;
}

static Eina_Bool
_url_complete_cb(void *data, int type, void *event_info)
{
   Ecore_Con_Event_Url_Complete *url_complete = event_info;

   Ems_Downloader_Req *req = eina_hash_find(_downloader->hash_req, url_complete->url_con);

   if (!req || url_complete->url_con != req->ec_url)
     {
        ERR("There is maybe a problem here ?");
        return EINA_TRUE;
     }

   int nbytes = ecore_con_url_received_bytes_get(url_complete->url_con);

   /* if (!req) */
   /*   return EINA_FALSE; */

   printf("\n");
   printf("download completed with status code: %d\n", url_complete->status);
   printf("Total size of downloaded file: %ld bytes\n", req->size);
   printf("Total size of downloaded file: %d bytes "
          "(from received_bytes_get)\n", nbytes);

   eina_hash_del(_downloader->hash_req, req->ec_url, req);
   ecore_con_url_free(req->ec_url);
   return EINA_TRUE;
}
/*============================================================================*
 *                                 Global                                     *
 *============================================================================*/

Eina_Bool
ems_downloader_init(void)
{

   _downloader = calloc(1, sizeof(Ems_Downloader));
   if (!_downloader)
     return EINA_FALSE;

   _downloader->hash_req = eina_hash_pointer_new((Eina_Free_Cb)_request_free_cb);

   return EINA_TRUE;
}

Eina_Bool
ems_downloader_url_download(const char *url,
                            Ems_Downloader_End_Cb end_cb, void *data )
{
   Ems_Downloader_Req *req;
   char filename[PATH_MAX];
   char *tmp;




   if (!url)
     return EINA_FALSE;

   req = calloc(1, sizeof(Ems_Downloader_Req));
   if (!req)
     return EINA_FALSE;

   req->ec_url = ecore_con_url_new(url);
   req->end_cb = end_cb;
   req->data = data;

   req->url = eina_stringshare_add(url);

   if (!req->ec_url)
     goto err1;

   DBG("Url : %s\n", url);
   tmp = ecore_file_file_get(url);
   snprintf(filename, sizeof(filename), "%s/%s", ems_config_cache_dirname_get(), tmp);
   req->filename = eina_stringshare_add(filename);

   DBG("save file to : %s\n", filename);

   req->fd = open(filename, O_CREAT|O_WRONLY|O_TRUNC, 0644);
   if (req->fd == -1)
     {
        ERR("Unable to open %s for writing", filename);
        goto err2;
     }

   eina_hash_add(_downloader->hash_req, req->ec_url, req);
   ecore_con_url_fd_set(req->ec_url, req->fd);

   ecore_event_handler_add(ECORE_CON_EVENT_URL_PROGRESS, _url_progress_cb, NULL);
   ecore_event_handler_add(ECORE_CON_EVENT_URL_COMPLETE, _url_complete_cb, NULL);
  if (!ecore_con_url_get(req->ec_url))
     {
        ERR("could not realize request.");
        goto err3;
     }

   return EINA_TRUE;

 err3:
   ecore_con_url_free(req->ec_url);
   close(req->fd);
 err2:
   eina_stringshare_del(req->filename);
 err1:
   eina_stringshare_del(req->url);
   free(req);

   return EINA_FALSE;
}


/*============================================================================*
 *                                   API                                      *
 *============================================================================*/