monitor: Support NFO file changes

Detect when a .nfo file changes, and rescan metadata for the associated
video file.
This commit is contained in:
Justin Maggard 2017-08-22 15:30:10 -07:00
parent c8665bcf40
commit 9e534c56fd
10 changed files with 87 additions and 59 deletions

View File

@ -125,7 +125,7 @@ check_for_captions(const char *path, int64_t detailID)
strncpyt(file, path, sizeof(file)); strncpyt(file, path, sizeof(file));
p = strip_ext(file); p = strip_ext(file);
if (!p) if (!p)
p = strrchr(file, '\0'); return;
/* If we weren't given a detail ID, look for one. */ /* If we weren't given a detail ID, look for one. */
if (!detailID) if (!detailID)
@ -287,7 +287,7 @@ GetFolderMetadata(const char *name, const char *path, const char *artist, const
} }
int64_t int64_t
GetAudioMetadata(const char *path, char *name) GetAudioMetadata(const char *path, const char *name)
{ {
char type[4]; char type[4];
static char lang[6] = { '\0' }; static char lang[6] = { '\0' };
@ -303,7 +303,6 @@ GetAudioMetadata(const char *path, char *name)
if ( stat(path, &file) != 0 ) if ( stat(path, &file) != 0 )
return 0; return 0;
strip_ext(name);
if( ends_with(path, ".mp3") ) if( ends_with(path, ".mp3") )
{ {
@ -384,7 +383,9 @@ GetAudioMetadata(const char *path, char *name)
} }
else else
{ {
m.title = name; free_flags |= FLAG_TITLE;
m.title = strdup(name);
strip_ext(m.title);
} }
for( i = ROLE_START; i < N_ROLE; i++ ) for( i = ROLE_START; i < N_ROLE; i++ )
{ {
@ -493,7 +494,7 @@ libjpeg_error_handler(j_common_ptr cinfo)
} }
int64_t int64_t
GetImageMetadata(const char *path, char *name) GetImageMetadata(const char *path, const char *name)
{ {
ExifData *ed; ExifData *ed;
ExifEntry *e = NULL; ExifEntry *e = NULL;
@ -514,7 +515,6 @@ GetImageMetadata(const char *path, char *name)
//DEBUG DPRINTF(E_DEBUG, L_METADATA, "Parsing %s...\n", path); //DEBUG DPRINTF(E_DEBUG, L_METADATA, "Parsing %s...\n", path);
if ( stat(path, &file) != 0 ) if ( stat(path, &file) != 0 )
return 0; return 0;
strip_ext(name);
//DEBUG DPRINTF(E_DEBUG, L_METADATA, " * size: %jd\n", file.st_size); //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * size: %jd\n", file.st_size);
/* MIME hard-coded to JPEG for now, until we add PNG support */ /* MIME hard-coded to JPEG for now, until we add PNG support */
@ -639,13 +639,15 @@ no_exifdata:
else if( (width <= 4096 && height <= 4096) || !GETFLAG(DLNA_STRICT_MASK) ) else if( (width <= 4096 && height <= 4096) || !GETFLAG(DLNA_STRICT_MASK) )
m.dlna_pn = strdup("JPEG_LRG"); m.dlna_pn = strdup("JPEG_LRG");
xasprintf(&m.resolution, "%dx%d", width, height); xasprintf(&m.resolution, "%dx%d", width, height);
m.title = strdup(name);
strip_ext(m.title);
ret = sql_exec(db, "INSERT into DETAILS" ret = sql_exec(db, "INSERT into DETAILS"
" (PATH, TITLE, SIZE, TIMESTAMP, DATE, RESOLUTION," " (PATH, TITLE, SIZE, TIMESTAMP, DATE, RESOLUTION,"
" ROTATION, THUMBNAIL, CREATOR, DLNA_PN, MIME) " " ROTATION, THUMBNAIL, CREATOR, DLNA_PN, MIME) "
"VALUES" "VALUES"
" (%Q, '%q', %lld, %lld, %Q, %Q, %u, %d, %Q, %Q, %Q);", " (%Q, '%q', %lld, %lld, %Q, %Q, %u, %d, %Q, %Q, %Q);",
path, name, (long long)file.st_size, (long long)file.st_mtime, m.date, path, m.title, (long long)file.st_size, (long long)file.st_mtime, m.date,
m.resolution, m.rotation, thumb, m.creator, m.dlna_pn, m.mime); m.resolution, m.rotation, thumb, m.creator, m.dlna_pn, m.mime);
if( ret != SQLITE_OK ) if( ret != SQLITE_OK )
{ {
@ -662,7 +664,7 @@ no_exifdata:
} }
int64_t int64_t
GetVideoMetadata(const char *path, char *name) GetVideoMetadata(const char *path, const char *name)
{ {
struct stat file; struct stat file;
int ret, i; int ret, i;
@ -685,7 +687,6 @@ GetVideoMetadata(const char *path, char *name)
//DEBUG DPRINTF(E_DEBUG, L_METADATA, "Parsing video %s...\n", name); //DEBUG DPRINTF(E_DEBUG, L_METADATA, "Parsing video %s...\n", name);
if ( stat(path, &file) != 0 ) if ( stat(path, &file) != 0 )
return 0; return 0;
strip_ext(name);
//DEBUG DPRINTF(E_DEBUG, L_METADATA, " * size: %jd\n", file.st_size); //DEBUG DPRINTF(E_DEBUG, L_METADATA, " * size: %jd\n", file.st_size);
ret = lav_open(&ctx, path); ret = lav_open(&ctx, path);
@ -1533,7 +1534,10 @@ video_no_dlna:
} }
if( !m.title ) if( !m.title )
{
m.title = strdup(name); m.title = strdup(name);
strip_ext(m.title);
}
album_art = find_album_art(path, m.thumb_data, m.thumb_size); album_art = find_album_art(path, m.thumb_data, m.thumb_size);
freetags(&video); freetags(&video);

View File

@ -92,12 +92,12 @@ int64_t
GetFolderMetadata(const char *name, const char *path, const char *artist, const char *genre, int64_t album_art); GetFolderMetadata(const char *name, const char *path, const char *artist, const char *genre, int64_t album_art);
int64_t int64_t
GetAudioMetadata(const char *path, char *name); GetAudioMetadata(const char *path, const char *name);
int64_t int64_t
GetImageMetadata(const char *path, char *name); GetImageMetadata(const char *path, const char *name);
int64_t int64_t
GetVideoMetadata(const char *path, char *name); GetVideoMetadata(const char *path, const char *name);
#endif #endif

View File

@ -327,8 +327,20 @@ monitor_remove_file(const char * path)
return 0; return 0;
} }
int static char *
monitor_insert_file(char * name, const char * path) check_nfo(const char *path)
{
char file[PATH_MAX];
strncpyt(file, path, sizeof(file));
strip_ext(file);
return sql_get_text_field(db, "SELECT PATH from DETAILS where (PATH > '%q.' and PATH <= '%q.z')"
" and MIME glob 'video/*' limit 1", file, file);
}
static int
monitor_insert_file(const char *name, const char *path)
{ {
int len; int len;
char *last_dir; char *last_dir;
@ -337,6 +349,7 @@ monitor_insert_file(char * name, const char * path)
char *base_copy; char *base_copy;
char *parent_buf = NULL; char *parent_buf = NULL;
char *id = NULL; char *id = NULL;
char video[PATH_MAX];
int depth = 1; int depth = 1;
int ts; int ts;
media_types types = ALL_MEDIA; media_types types = ALL_MEDIA;
@ -348,6 +361,21 @@ monitor_insert_file(char * name, const char * path)
update_if_album_art(path); update_if_album_art(path);
else if( is_caption(path) ) else if( is_caption(path) )
check_for_captions(path, 0); check_for_captions(path, 0);
else if( is_nfo(path) )
{
char *vpath = check_nfo(path);
if (!vpath)
return -1;
strncpyt(video, vpath, sizeof(video));
sqlite3_free(vpath);
DPRINTF(E_DEBUG, L_INOTIFY, "Found modified nfo %s\n", video);
monitor_remove_file(video);
path = video;
name = strrchr(video, '/');
if (!name)
return -1;
name++;
}
/* Check if we're supposed to be scanning for this file type in this directory */ /* Check if we're supposed to be scanning for this file type in this directory */
while( media_path ) while( media_path )

View File

@ -1,14 +1,6 @@
int int monitor_insert_directory(int fd, char *name, const char * path);
monitor_insert_file(char * name, const char * path); int monitor_remove_file(const char * path);
int monitor_remove_directory(int fd, const char * path);
int
monitor_insert_directory(int fd, char *name, const char * path);
int
monitor_remove_file(const char * path);
int
monitor_remove_directory(int fd, const char * path);
#ifdef HAVE_INOTIFY #ifdef HAVE_INOTIFY
void * void *

View File

@ -37,11 +37,12 @@
#include "log.h" #include "log.h"
int int
insert_playlist(const char * path, char * name) insert_playlist(const char *path, const char *name)
{ {
struct song_metadata plist; struct song_metadata plist;
struct stat file; struct stat file;
int items = 0, matches, ret; int items = 0, matches, ret;
char *objname;
char type[4]; char type[4];
strncpyt(type, strrchr(name, '.')+1, 4); strncpyt(type, strrchr(name, '.')+1, 4);
@ -61,18 +62,19 @@ insert_playlist(const char * path, char * name)
DPRINTF(E_WARN, L_SCANNER, "Bad playlist [%s]\n", path); DPRINTF(E_WARN, L_SCANNER, "Bad playlist [%s]\n", path);
return -1; return -1;
} }
strip_ext(name); objname = strdup(name);
strip_ext(objname);
DPRINTF(E_DEBUG, L_SCANNER, "Playlist %s contains %d items\n", name, items); DPRINTF(E_DEBUG, L_SCANNER, "Playlist %s contains %d items\n", objname, items);
matches = sql_get_int_field(db, "SELECT count(*) from PLAYLISTS where NAME = '%q'", name); matches = sql_get_int_field(db, "SELECT count(*) from PLAYLISTS where NAME = '%q'", objname);
if( matches > 0 ) if( matches > 0 )
{ {
sql_exec(db, "INSERT into PLAYLISTS" sql_exec(db, "INSERT into PLAYLISTS"
" (NAME, PATH, ITEMS) " " (NAME, PATH, ITEMS) "
"VALUES" "VALUES"
" ('%q(%d)', '%q', %d)", " ('%q(%d)', '%q', %d)",
name, matches, path, items); objname, matches, path, items);
} }
else else
{ {
@ -80,8 +82,9 @@ insert_playlist(const char * path, char * name)
" (NAME, PATH, ITEMS) " " (NAME, PATH, ITEMS) "
"VALUES" "VALUES"
" ('%q', '%q', %d)", " ('%q', '%q', %d)",
name, path, items); objname, path, items);
} }
free(objname);
return 0; return 0;
} }

View File

@ -24,10 +24,7 @@
#ifndef __PLAYLIST_H__ #ifndef __PLAYLIST_H__
#define __PLAYLIST_H__ #define __PLAYLIST_H__
int int insert_playlist(const char *path, const char *name);
insert_playlist(const char * path, char * name); int fill_playlists(void);
int
fill_playlists(void);
#endif // __PLAYLIST_H__ #endif // __PLAYLIST_H__

View File

@ -447,7 +447,7 @@ insert_directory(const char *name, const char *path, const char *base, const cha
} }
int int
insert_file(char *name, const char *path, const char *parentID, int object, media_types types) insert_file(const char *name, const char *path, const char *parentID, int object, media_types types)
{ {
char class[32]; char class[32];
char objectID[64]; char objectID[64];
@ -455,7 +455,7 @@ insert_file(char *name, const char *path, const char *parentID, int object, medi
char base[8]; char base[8];
char *typedir_parentID; char *typedir_parentID;
char *baseid; char *baseid;
char *orig_name = NULL; char *objname;
if( (types & TYPE_IMAGES) && is_image(name) ) if( (types & TYPE_IMAGES) && is_image(name) )
{ {
@ -467,12 +467,9 @@ insert_file(char *name, const char *path, const char *parentID, int object, medi
} }
else if( (types & TYPE_VIDEO) && is_video(name) ) else if( (types & TYPE_VIDEO) && is_video(name) )
{ {
orig_name = strdup(name);
strcpy(base, VIDEO_DIR_ID); strcpy(base, VIDEO_DIR_ID);
strcpy(class, "item.videoItem"); strcpy(class, "item.videoItem");
detailID = GetVideoMetadata(path, name); detailID = GetVideoMetadata(path, name);
if( !detailID )
strcpy(name, orig_name);
} }
else if( is_playlist(name) ) else if( is_playlist(name) )
{ {
@ -485,7 +482,6 @@ insert_file(char *name, const char *path, const char *parentID, int object, medi
strcpy(class, "item.audioItem.musicTrack"); strcpy(class, "item.audioItem.musicTrack");
detailID = GetAudioMetadata(path, name); detailID = GetAudioMetadata(path, name);
} }
free(orig_name);
if( !detailID ) if( !detailID )
{ {
DPRINTF(E_WARN, L_SCANNER, "Unsuccessful getting details for %s!\n", path); DPRINTF(E_WARN, L_SCANNER, "Unsuccessful getting details for %s!\n", path);
@ -493,12 +489,14 @@ insert_file(char *name, const char *path, const char *parentID, int object, medi
} }
sprintf(objectID, "%s%s$%X", BROWSEDIR_ID, parentID, object); sprintf(objectID, "%s%s$%X", BROWSEDIR_ID, parentID, object);
objname = strdup(name);
strip_ext(objname);
sql_exec(db, "INSERT into OBJECTS" sql_exec(db, "INSERT into OBJECTS"
" (OBJECT_ID, PARENT_ID, CLASS, DETAIL_ID, NAME) " " (OBJECT_ID, PARENT_ID, CLASS, DETAIL_ID, NAME) "
"VALUES" "VALUES"
" ('%s', '%s%s', '%s', %lld, '%q')", " ('%s', '%s%s', '%s', %lld, '%q')",
objectID, BROWSEDIR_ID, parentID, class, detailID, name); objectID, BROWSEDIR_ID, parentID, class, detailID, objname);
if( *parentID ) if( *parentID )
{ {
@ -510,16 +508,18 @@ insert_file(char *name, const char *path, const char *parentID, int object, medi
typedir_objectID = strtol(baseid+1, NULL, 16); typedir_objectID = strtol(baseid+1, NULL, 16);
*baseid = '\0'; *baseid = '\0';
} }
insert_directory(name, path, base, typedir_parentID, typedir_objectID); insert_directory(objname, path, base, typedir_parentID, typedir_objectID);
free(typedir_parentID); free(typedir_parentID);
} }
sql_exec(db, "INSERT into OBJECTS" sql_exec(db, "INSERT into OBJECTS"
" (OBJECT_ID, PARENT_ID, REF_ID, CLASS, DETAIL_ID, NAME) " " (OBJECT_ID, PARENT_ID, REF_ID, CLASS, DETAIL_ID, NAME) "
"VALUES" "VALUES"
" ('%s%s$%X', '%s%s', '%s', '%s', %lld, '%q')", " ('%s%s$%X', '%s%s', '%s', '%s', %lld, '%q')",
base, parentID, object, base, parentID, objectID, class, detailID, name); base, parentID, object, base, parentID, objectID, class, detailID, objname);
insert_containers(objname, path, objectID, class, detailID);
free(objname);
insert_containers(name, path, objectID, class, detailID);
return 0; return 0;
} }

View File

@ -75,7 +75,7 @@ int64_t
insert_directory(const char *name, const char *path, const char *base, const char *parentID, int objectID); insert_directory(const char *name, const char *path, const char *base, const char *parentID, int objectID);
int int
insert_file(char *name, const char *path, const char *parentID, int object, media_types dir_types); insert_file(const char *name, const char *path, const char *parentID, int object, media_types dir_types);
int int
CreateDatabase(void); CreateDatabase(void);

View File

@ -249,6 +249,8 @@ strip_ext(char *name)
{ {
char *period; char *period;
if (!name)
return NULL;
period = strrchr(name, '.'); period = strrchr(name, '.');
if (period) if (period)
*period = '\0'; *period = '\0';

View File

@ -89,6 +89,8 @@ int is_audio(const char * file);
int is_image(const char * file); int is_image(const char * file);
int is_playlist(const char * file); int is_playlist(const char * file);
int is_caption(const char * file); int is_caption(const char * file);
#define is_nfo(file) ends_with(file, ".nfo")
int is_album_art(const char * name); int is_album_art(const char * name);
int resolve_unknown_type(const char * path, media_types dir_type); int resolve_unknown_type(const char * path, media_types dir_type);
const char *mime_to_ext(const char * mime); const char *mime_to_ext(const char * mime);