static int clearTn(const char *pathMedia, const char *pathDb, const FILE_LIST_T *pFileList) { DIR *pdir; struct dirent *direntry; char buf[VSX_MAX_PATH_LEN]; char buf2[VSX_MAX_PATH_LEN]; size_t sz,sz2; if(!(pdir = fileops_OpenDir(pathDb))) { return -1; } buf[sizeof(buf) - 1] = '\0'; while((direntry = fileops_ReadDir(pdir))) { if(!(direntry->d_type & DT_DIR)) { // "_tn[idx].jpg" if((sz = strlen(direntry->d_name)) > 9 && (!strncasecmp(&direntry->d_name[sz - 4], ".jpg", 4) || !strncasecmp(&direntry->d_name[sz - VSXTMP_EXT_LEN], VSXTMP_EXT, VSXTMP_EXT_LEN) || !strncasecmp(&direntry->d_name[sz - NOTN_EXT_LEN], NOTN_EXT, NOTN_EXT_LEN))) { strncpy(buf, direntry->d_name, sizeof(buf) - 1); for(sz2 = sz - 4; sz2 > sz - 12; sz2--) { if(buf[sz2] == '_') { break; } } buf[sz2] = '\0'; //fprintf(stdout, "check '%s' '%s'\n", buf, direntry->d_name); if(file_list_find(pFileList, buf) == NULL) { mediadb_prepend_dir(pathDb, direntry->d_name, buf2, sizeof(buf)); LOG(X_DEBUG("Removing thumbnail '%s'\n"), buf2); if(fileops_DeleteFile(buf2) != 0) { LOG(X_ERROR("Failed to delete thumbnail %s"), buf2); } } } } } fileops_CloseDir(pdir); return 0; }
DIR_ENTRY_LIST_T *direntry_getentries(const MEDIADB_DESCR_T *pMediaDb, const char *dir, const char *fidxdir, const char *searchstr, int includedirs, unsigned int startidx, unsigned int max, enum DIR_SORT sort) { DIR *pdir; int rc = 0; struct dirent *direntry; char path[VSX_MAX_PATH_LEN]; struct stat st; int addEntry; FILE_LIST_T fileList; FILE_LIST_ENTRY_T *pFileEntry = NULL; META_FILE_T metaFile; DIR_ENTRY_LIST_T *pEntryList = NULL; DIR_ENTRY_T entry; DIR_ENTRY_T *pEntry; const char *pdispname; unsigned int idx = 0; unsigned int cnt = 0; unsigned int cntInDir = 0; COMPARE_DIR_ENTRY compareFunc = direntry_getcompfunc(sort); VSX_DEBUG_MGR( LOG(X_DEBUG("MGR - direntry_getentries dir: '%s', fidxdir: '%s', searchstr: '%s', " "includedirs: %d, startidx: %d, max: %d"), dir, fidxdir, searchstr, includedirs, startidx, max)); if(!(pdir = fileops_OpenDir(dir))) { return NULL; } memset(&fileList, 0, sizeof(fileList)); if(fidxdir) { file_list_read(fidxdir, &fileList); } // // Read the directory wide metafile to get a list of 'ignore' entries // memset(&metaFile, 0, sizeof(metaFile)); mediadb_prepend_dir(dir, METAFILE_DEFAULT, path, sizeof(path)); if(fileops_stat(path, &st) == 0) { metafile_open(path, &metaFile, 1, 1); } while((direntry = fileops_ReadDir(pdir))) { VSX_DEBUG_MGR( LOG(X_DEBUGV("MGR - direntry_getentries d_name: '%s', isdir: %d"), direntry->d_name, (direntry->d_type & DT_DIR)) ); if(is_entry_ignored(metaFile.pignoreList, direntry->d_name)) { continue; } if(!(pdispname = find_entry_description(metaFile.pDescriptionList, direntry->d_name))) { pdispname = direntry->d_name; } if(searchstr && !is_match_search(pdispname, NULL, searchstr)) { continue; } memset(&entry, 0, sizeof(entry)); strncpy(entry.d_name, direntry->d_name, sizeof(entry.d_name) - 1); if(pdispname != direntry->d_name) { strncpy(entry.displayname, pdispname, sizeof(entry.displayname) - 1); } entry.d_type = direntry->d_type; addEntry = 0; if(direntry->d_type & DT_DIR) { if(includedirs && mediadb_isvalidDirName(pMediaDb, direntry->d_name)) { addEntry = 1; } } else if(mediadb_isvalidFileName(pMediaDb, direntry->d_name, 1, 1)) { mediadb_prepend_dir(dir, direntry->d_name, path, sizeof(path)); if(fileops_stat(path, &st) == 0) { entry.size = st.st_size; //entry.tm = st.st_mtime; entry.tm = st.st_ctime; if(fidxdir && (pFileEntry = file_list_find(&fileList, direntry->d_name))) { entry.numTn = pFileEntry->numTn; entry.duration = pFileEntry->duration; } addEntry = 1; } } if(addEntry) { VSX_DEBUG_MGR( LOG(X_DEBUGV("MGR - direntry_getentries add d_name: '%s', isdir: %d"), direntry->d_name, (direntry->d_type & DT_DIR)) ); if(compareFunc || (idx >= startidx && (max == 0 || cnt < max))) { if(cnt >= DIR_ENTRY_LIST_BUFNUM) { LOG(X_WARNING("Not showing more than %d entries in %s"), cnt, dir); break; } else if(!(pEntry = direntry_addsorted(&pEntryList, &entry, compareFunc))) { LOG(X_ERROR("Failed to add directory entry '%s' to list"), direntry->d_name); rc = -1; break; } cnt++; } idx++; cntInDir++; } } // // Since when a sort is requested we have to sort every entry in the directory. Now we can move the head pointer // to the first desired entry // if(pEntryList && compareFunc && startidx > 0) { pEntry = pEntryList->pHead; for(idx = 0; idx < startidx; idx++) { pEntry = pEntry->pnext; cnt--; } pEntryList->pHead = pEntry; if(cnt > max) { cnt = max; } //fprintf(stderr, "moved phead to %s, cnt:%d, cntInDir:%d\n", pEntryList->pHead ? pEntryList->pHead->d_name : NULL, cnt, cntInDir); } fileops_CloseDir(pdir); if(fidxdir) { file_list_close(&fileList); } metafile_close(&metaFile); if(rc == 0 && !pEntryList) { // If the user requested an index out of bounds, return an empty list with // a valid cntTotalInDir pEntryList = (DIR_ENTRY_LIST_T *) avc_calloc(1, sizeof(DIR_ENTRY_LIST_T)); } if(pEntryList) { pEntryList->cntTotal = cnt; pEntryList->cntTotalInDir = cntInDir; } //if(pEntryList) fprintf(stderr, "DIR '%s' num:%d numAlloc:%d pnext:0x%x TOTAL:%d/%d\n", dir, pEntryList->num, pEntryList->numAlloc, pEntryList->pnext, pEntryList->cntTotal, pEntryList->cntTotalInDir); return pEntryList; }
static int update_fileentry(FILE_LIST_T *pFileList, const char *mediaName, const char *mediaPath, FILE_LIST_ENTRY_T **ppEntry) { MEDIA_DESCRIPTION_T mediaDescr; FILE_STREAM_T fileStream; FILE_LIST_ENTRY_T *pFileEntryCur = NULL; FILE_LIST_ENTRY_T *pFileEntryNew = NULL; FILE_LIST_ENTRY_T fileEntry; char buf[VSX_MAX_PATH_LEN]; struct stat st; struct stat st2; int havestat = 0; size_t szt; int fileChanged = 1; memset(&fileEntry, 0, sizeof(fileEntry)); //fprintf(stdout, "looking for '%s'\n", mediaName); if((pFileEntryCur = file_list_find(pFileList, mediaName))) { //fprintf(stdout, "found entry '%s' numTn:%d\n", pFileEntryCur->name, pFileEntryCur->numTn); // mark the entry as current to avoid deletion pFileEntryCur->flag = 1; if((havestat = !fileops_stat(mediaPath, &st)) == 0) { LOG(X_ERROR("Unable to stat '%s'"), mediaPath); } else if(st.st_size == pFileEntryCur->size && st.st_ctime == pFileEntryCur->tm) { fileChanged = 0; // // Special case to probe for recent creation .seek file // since the last time this entry was written // if(pFileEntryCur->duration == 0) { buf[sizeof(buf) - 1] = '\0'; strncpy(buf, mediaPath, sizeof(buf) - 1); if((szt = strlen(buf))) { strncpy(&buf[szt], MP2TS_FILE_SEEKIDX_NAME, sizeof(buf) - szt - 1); } if(fileops_stat(buf, &st2) == 0) { fileChanged = 1; } } } pFileEntryNew = pFileEntryCur; } else { // Check for invalid chars - ',' is used as a delimeter in .avcfidx if(strchr(mediaName, ',') || mediaName[0] == '#' || mediaName[0] == ' ' || mediaName[0] == '=') { LOG(X_WARNING("Illegal filename '%s' not added to database"), mediaPath); pFileEntryNew = NULL; fileChanged = 0; } else { LOG(X_DEBUG("Could not find database entry '%s'"), mediaPath); pFileEntryNew = &fileEntry; } } if(fileChanged) { if(OpenMediaReadOnly(&fileStream, mediaPath) == 0) { memset(&mediaDescr, 0, sizeof(mediaDescr)); if(filetype_getdescr(&fileStream, &mediaDescr, 1) == 0) { pFileEntryNew->flag = 1; pFileEntryNew->duration = mediaDescr.durationSec; pFileEntryNew->size = mediaDescr.totSz; if(!havestat && (havestat = !fileops_stat(mediaPath, &st)) == 0) { LOG(X_ERROR("Unable to stat new entry '%s'"), mediaPath); } if(havestat) { pFileEntryNew->tm = st.st_ctime; //fprintf(stderr, "-----------set tm:%ld %s\n", pFileEntryNew->tm, mediaPath); } if(mediaDescr.haveVid) { create_viddescrstr(&mediaDescr, pFileEntryNew->vstr, sizeof(pFileEntryNew->vstr)); } if(mediaDescr.haveAud) { create_auddescrstr(&mediaDescr, pFileEntryNew->astr, sizeof(pFileEntryNew->astr)); //fprintf(stdout, "aud descr:'%s'\n", pFileEntryNew->astr); } } else { pFileEntryNew->flag = 1; pFileEntryNew->size = fileStream.size; } CloseMediaFile(&fileStream); } // end of OpenMediaReadOnly if(pFileEntryCur == NULL) { pFileEntryNew->name[sizeof(pFileEntryNew->name) - 1] = '\0'; strncpy(pFileEntryNew->name, mediaName, sizeof(pFileEntryNew->name) - 1); pFileEntryCur = file_list_addcopy(pFileList, pFileEntryNew); } } // end of if(fileChanged) if(ppEntry) { *ppEntry = pFileEntryCur; } return fileChanged; }
/* FIXME: documentation. */ char *tui_file_selector(const char *title, const char *directory, const char *pattern, const char *default_item, read_contents_func_type contents_func, char **browse_file_return, unsigned int *browse_file_number_return) { static char *return_path = NULL; struct file_list *fl; int curr_item, first_item, need_update; int x, y, width, height, num_cols, num_lines, field_width; int num_files; char str[0x100]; int str_len = 0; tui_area_t backing_store = NULL; if (contents_func != NULL) { *browse_file_return = NULL; } if (browse_file_number_return != NULL) { *browse_file_number_return = 0; } if (directory != NULL) { return_path = lib_stralloc(directory); } else { return_path = ioutil_current_dir(); } slashize_path(&return_path); fl = file_list_read(return_path, pattern); if (fl == NULL) { return NULL; } first_item = curr_item = 0; num_cols = 4; field_width = 18; num_lines = 17; height = num_lines + 2; width = field_width * num_cols + 4; num_files = num_cols * num_lines; if (default_item != NULL && *default_item) { int i; for (i = 0; i < fl->num_items; i++) { if (!strcasecmp(default_item, fl->items[i].name)) { curr_item = i; while (curr_item - first_item >= num_files) { first_item += num_lines; } break; } } } x = CENTER_X(width); y = CENTER_Y(height); need_update = 1; tui_area_get(&backing_store, x, y, width + 2, height + 1); tui_display_window(x, y, width, height, MENU_BORDER, MENU_BACK, title, NULL); while (1) { int key; tui_set_attr(MENU_FORE, MENU_BACK, 0); if (need_update) { file_selector_display_path(return_path, x + 1, y + height - 1, width - 2); file_selector_update(fl, first_item, x + 2, y + 1, field_width, num_lines, num_cols); tui_set_attr(FIRST_LINE_FORE, FIRST_LINE_BACK, 0); tui_display(0, tui_num_lines() - 1, tui_num_cols(), "\030\031\033\032: Move <Enter>: Select %s<Alt>-<letter>: Change drive", contents_func != NULL ? "<Space>: Preview " : ""); need_update = 0; } tui_set_attr(MENU_FORE, MENU_HIGHLIGHT, 0); file_selector_display_item(fl, curr_item, first_item, x + 2, y + 1, field_width, num_lines, num_cols); key = getkey(); tui_set_attr(MENU_FORE, MENU_BACK, 0); file_selector_display_item(fl, curr_item, first_item, x + 2, y + 1, field_width, num_lines, num_cols); switch (key) { case K_Escape: tui_area_put(backing_store, x, y); tui_area_free(backing_store); return NULL; case K_Left: str_len = 0; if (curr_item - num_lines >= 0) { curr_item -= num_lines; if (curr_item < first_item) { if (first_item >= num_lines) { first_item -= num_lines; need_update = 1; } else { curr_item += num_lines; } } } break; case K_Up: str_len = 0; if (curr_item > 0) { curr_item--; if (curr_item < first_item) { first_item = curr_item; need_update = 1; } } break; case K_Right: str_len = 0; if (curr_item + num_lines < fl->num_used_items) { curr_item += num_lines; if (curr_item - first_item >= num_files) { first_item += num_lines; need_update = 1; } } break; case K_Down: str_len = 0; if (curr_item < fl->num_used_items - 1) { curr_item++; if (curr_item == first_item + num_files) { first_item++; need_update = 1; } } break; case K_PageDown: str_len = 0; if (curr_item + num_files < fl->num_used_items) { curr_item += num_files; first_item += num_files; } need_update = 1; break; case K_PageUp: str_len = 0; if (curr_item - num_files >= 0) { curr_item -= num_files; first_item -= num_files; if (first_item < 0) { first_item = 0; } need_update = 1; } break; case K_Home: str_len = 0; curr_item = 0; if (first_item != 0) { first_item = 0; need_update = 1; } break; case K_End: str_len = 0; curr_item = fl->num_used_items - 1; first_item = curr_item - num_files + 1; if (first_item < 0) { first_item = 0; } need_update = 1; break; case K_Return: str_len = 0; if (fl->items[curr_item].type == FT_DIR) { struct file_list *new_fl; char *new_path; new_path = change_path(fl, return_path, curr_item); new_fl = file_list_read(new_path, pattern); if (new_fl != NULL) { file_list_free(fl); fl = new_fl; first_item = curr_item = 0; lib_free(return_path); return_path = new_path; need_update = 1; ioutil_chdir(return_path); } else { lib_free(new_path); } } else { char *p = util_concat(return_path, fl->items[curr_item].name, NULL); lib_free(return_path); return_path = p; tui_area_put(backing_store, x, y); tui_area_free(backing_store); return return_path; } break; case K_BackSpace: if (str_len > 1) { int n; str_len--; n = file_list_find(fl, str, str_len); if (n >= 0) { curr_item = n; if (curr_item < first_item) { first_item = curr_item; need_update = 1; } else if (first_item + num_files <= curr_item) { first_item = curr_item - num_files + 1; need_update = 1; } } } else { str_len = 0; curr_item = 0; if (first_item != 0) { first_item = 0; need_update = 1; } } break; case ' ': if (contents_func != NULL && fl->items[curr_item].type != FT_DIR && browse_file_return != NULL) { tui_display(0, tui_num_lines() - 1, tui_num_cols(), ""); *browse_file_return = tui_image_browser(fl->items[curr_item].name, contents_func, browse_file_number_return); if (*browse_file_return != NULL) { char *p = util_concat(return_path, fl->items[curr_item].name, NULL); lib_free(return_path); return_path = p; tui_area_put(backing_store, x, y); tui_area_free(backing_store); return return_path; } need_update = 1; break; } else { tui_beep(); } default: { int drive_num; drive_num = alt_key_to_drive_num(key); if (drive_num > 0) { /* `A-a' ... `A-z' change the current drive. */ int num_available_drives; int current_drive; _dos_getdrive(¤t_drive); _dos_setdrive(current_drive, &num_available_drives); if (drive_num <= num_available_drives) { char *new_path; /* FIXME: This is a hack... Maybe there is a cleaner way to do it, but for now I just don't know. */ _dos_setdrive(drive_num, &num_available_drives); new_path = ioutil_current_dir(); if (new_path != NULL) { slashize_path(&new_path); _dos_setdrive(current_drive, &num_available_drives); if (new_path != NULL) { struct file_list *new_fl; new_fl = file_list_read(new_path, pattern); if (new_fl != NULL) { file_list_free(fl); fl = new_fl; first_item = curr_item = 0; lib_free(return_path); return_path = new_path; need_update = 1; ioutil_chdir(return_path); } else { lib_free(new_path); } } } else { _dos_setdrive(current_drive, &num_available_drives); tui_beep(); } } else { tui_beep(); } } else if (isprint(key) && str_len < 0x100) { int n; str[str_len] = key; n = file_list_find(fl, str, str_len + 1); if (n < 0) { tui_beep(); } else { str_len++; curr_item = n; if (curr_item < first_item) { first_item = curr_item; need_update = 1; } else if (first_item + num_files <= curr_item) { first_item = curr_item - num_files + 1; need_update = 1; } } } } break; } } }