X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=minimenu%2Fmmcache.c;h=4480a12d35ef7046c9456b86e0f0c6a44efc4cce;hb=62547c89828b74197844b2e298e44f468622c516;hp=48a023d488ff31a9e0482904f99674a6b5f5c042;hpb=c7cccda18ca6ec71a1f3fbb98f5efca3139b133b;p=pandora-libraries.git diff --git a/minimenu/mmcache.c b/minimenu/mmcache.c index 48a023d..4480a12 100644 --- a/minimenu/mmcache.c +++ b/minimenu/mmcache.c @@ -29,12 +29,17 @@ #include "pnd_desktop.h" #include "pnd_pndfiles.h" #include "pnd_apps.h" +#include "../lib/pnd_pathiter.h" +#include "pnd_locate.h" #include "mmenu.h" #include "mmapps.h" #include "mmcache.h" +#include "mmcat.h" +#include "mmui.h" extern pnd_conf_handle g_conf; +extern unsigned char g_pvwcache; mm_cache_t *g_icon_cache = NULL; mm_cache_t *g_preview_cache = NULL; @@ -56,33 +61,107 @@ unsigned char cache_preview ( pnd_disco_t *app, unsigned int maxwidth, unsigned // not cached, load it up // + // show hourglass + ui_show_hourglass ( 1 /* updaterect*/ ); + // see if we can mount the pnd/dir // does preview file exist? // if so, load it up, size it, cache it // if not, warning and bail // unmount it - // can we mount? - char fullpath [ PATH_MAX ]; - char filepath [ PATH_MAX ]; + // can we mount? or can we find it in preview cache? or an override? + char fullpath [ PATH_MAX ] = ""; + char filepath [ PATH_MAX ] = ""; + + // first, check for preview override + { + char ovrfile [ PATH_MAX ]; + char *fooby; + sprintf ( ovrfile, "%s/%s", app -> object_path, app -> object_filename ); + fooby = strcasestr ( ovrfile, PND_PACKAGE_FILEEXT ); + if ( fooby ) { + sprintf ( fooby, "_pvw#%u.png", app -> subapp_number ); + struct stat statbuf; + if ( stat ( ovrfile, &statbuf ) == 0 ) { + strncpy ( filepath, ovrfile, PATH_MAX ); + } // stat + } // ovr? + } + + // if not yet found, try to find in cache + if ( filepath [ 0 ] == '\0' && g_pvwcache ) { + static char *cache_findpath = NULL; + if ( ! cache_findpath ) { + cache_findpath = pnd_conf_get_as_char ( g_conf, "previewpic.cache_findpath" ); + } + char buffer [ FILENAME_MAX ]; + sprintf ( buffer, "%s.png", app -> unique_id ); + char *f = pnd_locate_filename ( cache_findpath, buffer ); + if ( f ) { + strncpy ( filepath, f, PATH_MAX ); + } + } + + // if we don't have a file path sorted out yet, means we need to mount and figure it + if ( ! filepath [ 0 ] ) { + sprintf ( fullpath, "%s/%s", app -> object_path, app -> object_filename ); - sprintf ( fullpath, "%s/%s", app -> object_path, app -> object_filename ); + if ( ! pnd_pnd_mount ( pnd_run_script, fullpath, app -> unique_id ) ) { + pnd_log ( pndn_debug, "Couldn't mount '%s' for preview\n", fullpath ); + return ( 0 ); // couldn't mount?! + } - if ( ! pnd_pnd_mount ( pnd_run_script, fullpath, app -> unique_id ) ) { - pnd_log ( pndn_debug, "Couldn't mount '%s' for preview\n", fullpath ); - return ( 0 ); // couldn't mount?! + sprintf ( filepath, "%s/%s/%s", PND_MOUNT_PATH, app -> unique_id, app -> preview_pic1 ); } - sprintf ( filepath, "%s/%s/%s", PND_MOUNT_PATH, app -> unique_id, app -> preview_pic1 ); + // load whatever path we've got s = IMG_Load ( filepath ); - pnd_pnd_unmount ( pnd_run_script, fullpath, app -> unique_id ); - if ( ! s ) { + // unmount it, if mounted + if ( fullpath [ 0 ] ) { + pnd_pnd_unmount ( pnd_run_script, fullpath, app -> unique_id ); + } pnd_log ( pndn_debug, "Couldn't open image '%s' for preview\n", filepath ); return ( 0 ); } + // try to copy file to the cache, if we're doing that, and if mounted + if ( g_pvwcache && fullpath [ 0 ] ) { + char cacheoutpath [ PATH_MAX ] = ""; + + // figure out where we want to write the file to + if ( cache_find_writable ( app -> object_path, cacheoutpath, PATH_MAX ) ) { + static char *cache_path = NULL; + char buffer [ PATH_MAX ]; + if ( ! cache_path ) { + cache_path = pnd_conf_get_as_char ( g_conf, "previewpic.cache_path" ); + } + // make the dir + snprintf ( buffer, PATH_MAX, "%s/%s", cacheoutpath, cache_path ); + struct stat statbuf; + if ( stat ( buffer, &statbuf ) != 0 ) { + snprintf ( buffer, PATH_MAX, "/bin/mkdir -p %s/%s", cacheoutpath, cache_path ); + system ( buffer ); + } + // set up target filename to copy + snprintf ( buffer, PATH_MAX, "%s/%s/%s.png", cacheoutpath, cache_path, app -> unique_id ); + pnd_log ( pndn_debug, "Found free space to cache preview to here: %s", buffer ); + if ( ! pnd_filecopy ( filepath, buffer ) ) { + pnd_log ( pndn_error, "ERROR: Copying preview from %s to %s", filepath, buffer ); + } + } else { + pnd_log ( pndn_warning, "WARN: Couldn't find a device to cache preview to.\n" ); + } + + } // preview file cache + + // unmount it, if mounted + if ( fullpath [ 0 ] ) { + pnd_pnd_unmount ( pnd_run_script, fullpath, app -> unique_id ); + } + //pnd_log ( pndn_debug, "Image size is %u x %u (max %u x %u)\n", s -> w, s -> h, maxwidth, maxheight ); // scale @@ -160,10 +239,32 @@ unsigned char cache_icon ( pnd_disco_t *app, unsigned char maxwidth, unsigned ch } // stat } // ovr? - // pull icon into buffer from .pnd + // if this is a real pnd file (dir-app or pnd-file-app), then try to pull icon from there if ( ! iconbuf ) { - iconbuf = pnd_emit_icon_to_buffer ( app, &buflen ); - } + + if ( app -> object_flags & PND_DISCO_GENERATED ) { + + // maybe we can discover this single-file and find an icon? + if ( strcasestr ( app -> object_filename, PND_PACKAGE_FILEEXT ) ) { + + // looks like a pnd, now what do we do.. + pnd_box_handle h = pnd_disco_file ( app -> object_path, app -> object_filename ); + + if ( h ) { + pnd_disco_t *d = pnd_box_get_head ( h ); + iconbuf = pnd_emit_icon_to_buffer ( d, &buflen ); + } + + } // filename has .pnd? + + } else { + + // pull icon into buffer from .pnd if not already found an icon + iconbuf = pnd_emit_icon_to_buffer ( app, &buflen ); + + } // generated? + + } // already got icon? if ( ! iconbuf ) { return ( 0 ); @@ -245,3 +346,63 @@ mm_cache_t *cache_query_icon ( char *id ) { mm_cache_t *cache_query_preview ( char *id ) { return ( cache_query ( id, g_preview_cache ) ); } + +unsigned char cache_find_writable ( char *originpath, char *r_writepath, unsigned int len ) { + static char *searchpaths = NULL; + static unsigned int minfree = 0; + char searchpath [ PATH_MAX ] = ""; + char cmdbuf [ PATH_MAX ]; + FILE *f; + unsigned int freespace = 0; + + // figure out the mountpoint for the file, and stick that in at front of searchpath + // so that it will get picked first, if possible. + char mountpath [ PATH_MAX ]; + if ( pnd_determine_mountpoint ( originpath, mountpath, PATH_MAX ) ) { + sprintf ( searchpath, "%s:", mountpath ); + //pnd_log ( pndn_debug, "Preferred cache target for %s: %s\n", originpath, mountpath ); + } + + // try to find a device, in order of searchpath, with enough space for this cache-out + // + + // populate the searchpath + if ( ! searchpaths ) { + searchpaths = pnd_conf_get_as_char ( g_conf, "previewpic.cache_searchpath" ); + minfree = pnd_conf_get_as_int_d ( g_conf, "previewpic.cache_minfree", 500 ); + } + + if ( ! searchpaths ) { + return ( 0 ); // fail! + } + + strncat ( searchpath, searchpaths, PATH_MAX ); + + SEARCHPATH_PRE + { + + // since I didn't figure out which /sys/block I can pull remaining space from, I'll use df for now :/ + sprintf ( cmdbuf, "/bin/df %s", buffer ); + + f = popen ( cmdbuf, "r" ); + + if ( f ) { + while ( fgets ( cmdbuf, PATH_MAX, f ) ) { + // just eat it up + // /dev/sdc2 7471392 725260 6366600 11% /media/IMAGE + if ( sscanf ( cmdbuf, "%*s %*u %*u %u %*u %*s\n", &freespace ) == 1 ) { + strncpy ( r_writepath, buffer, len ); + if ( freespace > minfree ) { + pclose ( f ); + return ( 1 ); + } // enough free? + } // df + } // while + pclose ( f ); + } + + } + SEARCHPATH_POST + + return ( 0 ); +}