TitleInfo.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. #include "main.h"
  2. #include "../replicant/nu/AutoChar.h"
  3. #include "../replicant/nu/ns_wc.h"
  4. #include <shlwapi.h>
  5. #include <malloc.h> // for alloca
  6. static wchar_t m_lastfn[2048];
  7. static wchar_t m_lastartist[256], m_lasttitle[256], m_lastalbum[256], m_gracenotefileid[128];
  8. static int m_lasttrack;
  9. static int m_playcount;
  10. static int m_ispodcast;
  11. static int m_rating;
  12. static int m_db_found;
  13. void ClearTitleHookCache()
  14. {
  15. memset(m_lastfn, 0, sizeof(m_lastfn));
  16. }
  17. BOOL IPC_HookExtInfoW(INT_PTR param)
  18. {
  19. if (skipTitleInfo) // we're reading metadata and being asked to skip title hooking (so we can get a valid title for guessing, if need be)
  20. return false;
  21. extendedFileInfoStructW *p = (extendedFileInfoStructW *)param;
  22. // fill in our own titles from db? not for now, just let it default to hitting the tags?
  23. if (!g_config->ReadInt(L"newtitle", 1))
  24. return FALSE;
  25. if (NULL == p->filename || L'\0' == *p->filename ||
  26. NULL == p->metadata || L'\0' == *p->metadata)
  27. {
  28. return FALSE;
  29. }
  30. int which = 0;
  31. if (!_wcsicmp(p->metadata, DB_FIELDNAME_artist )) which = 1;
  32. else if (!_wcsicmp(p->metadata, DB_FIELDNAME_title )) which = 2;
  33. else if (!_wcsicmp(p->metadata, DB_FIELDNAME_album )) which = 3;
  34. //else if (!_wcsicmp(p->metadata, L"tuid")) which = 4;
  35. else if (!_wcsicmp(p->metadata, DB_FIELDNAME_track )) which = 5;
  36. else if (!_wcsicmp(p->metadata, DB_FIELDNAME_rating )) which = 6;
  37. else if (!_wcsicmp(p->metadata, DB_FIELDNAME_playcount )) which = 7;
  38. else if (!_wcsicmp(p->metadata, DB_FIELDNAME_GracenoteFileID )) which=8;
  39. else if (!_wcsicmp(p->metadata, DB_FIELDNAME_ispodcast )) which=9;
  40. if (which)
  41. {
  42. if (_wcsicmp(m_lastfn, p->filename))
  43. {
  44. if (!g_table) openDb();
  45. if (!g_table) return 0;
  46. m_lastartist[0] = 0;
  47. m_lasttitle[0] = 0;
  48. m_lastalbum[0] = 0;
  49. m_gracenotefileid[0]=0;
  50. m_lasttrack = 0;
  51. m_rating=-1;
  52. m_playcount=-1;
  53. m_ispodcast=-1;
  54. lstrcpynW(m_lastfn, p->filename, sizeof(m_lastfn)/sizeof(wchar_t));
  55. wchar_t filename2[MAX_PATH] = {0}; // full lfn path if set
  56. EnterCriticalSection(&g_db_cs);
  57. nde_scanner_t s = NDE_Table_CreateScanner(g_table);
  58. int found = FindFileInDatabase(s, MAINTABLE_ID_FILENAME, m_lastfn, filename2);
  59. if (found == 2)
  60. lstrcpynW(m_lastfn, filename2, sizeof(m_lastfn)/sizeof(m_lastfn));
  61. if (found)
  62. {
  63. nde_field_t f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_ARTIST);
  64. if (f) lstrcpynW(m_lastartist, NDE_StringField_GetString(f), sizeof(m_lastartist)/sizeof(wchar_t));
  65. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_ALBUM);
  66. if (f) lstrcpynW(m_lastalbum, NDE_StringField_GetString(f), sizeof(m_lastalbum)/sizeof(wchar_t));
  67. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_TITLE);
  68. if (f) lstrcpynW(m_lasttitle, NDE_StringField_GetString(f), sizeof(m_lasttitle)/sizeof(wchar_t));
  69. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_TRACKNB);
  70. if (f) m_lasttrack = NDE_IntegerField_GetValue(f);
  71. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_PLAYCOUNT);
  72. if (f) m_playcount = NDE_IntegerField_GetValue(f);
  73. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_RATING);
  74. if (f) m_rating = NDE_IntegerField_GetValue(f);
  75. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_ISPODCAST);
  76. if (f) m_ispodcast = NDE_IntegerField_GetValue(f);
  77. f = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_GRACENOTEFILEID);
  78. if (f) lstrcpynW(m_gracenotefileid, NDE_StringField_GetString(f), sizeof(m_gracenotefileid)/sizeof(wchar_t));
  79. m_db_found = 1;
  80. }
  81. else m_db_found = 0;
  82. NDE_Table_DestroyScanner(g_table, s);
  83. LeaveCriticalSection(&g_db_cs);
  84. }
  85. if (m_db_found == 1)
  86. {
  87. switch(which)
  88. {
  89. case 1:
  90. if (m_lastartist[0])
  91. {
  92. lstrcpynW(p->ret, m_lastartist, p->retlen);
  93. return 1;
  94. }
  95. break;
  96. case 2:
  97. if (m_lasttitle[0])
  98. {
  99. lstrcpynW(p->ret, m_lasttitle, p->retlen);
  100. return 1;
  101. }
  102. break;
  103. case 3:
  104. if (m_lastalbum[0])
  105. {
  106. lstrcpynW(p->ret, m_lastalbum, p->retlen);
  107. return 1;
  108. }
  109. break;
  110. case 5:
  111. if (m_lasttrack && m_lasttrack != -1)
  112. {
  113. _snwprintf(p->ret, p->retlen, L"%d", m_lasttrack);
  114. return 1;
  115. }
  116. break;
  117. case 6:
  118. if (m_rating != -1)
  119. {
  120. _snwprintf(p->ret, p->retlen, L"%d", m_rating);
  121. return 1;
  122. }
  123. break;
  124. case 7:
  125. if (m_playcount != -1)
  126. {
  127. _snwprintf(p->ret, p->retlen, L"%d", m_playcount);
  128. return 1;
  129. }
  130. break;
  131. case 8:
  132. if (m_gracenotefileid[0])
  133. {
  134. lstrcpynW(p->ret, m_gracenotefileid, p->retlen);
  135. return 1;
  136. }
  137. break;
  138. case 9:
  139. if (m_ispodcast != -1)
  140. {
  141. _snwprintf(p->ret, p->retlen, L"%d", m_ispodcast);
  142. return 1;
  143. }
  144. break;
  145. }
  146. }
  147. }
  148. return FALSE;
  149. }
  150. BOOL IPC_HookExtInfo(INT_PTR param)
  151. {
  152. extendedFileInfoStruct *p = (extendedFileInfoStruct*)param;
  153. // fill in our own titles from db? not for now, just let it default to hitting the tags?
  154. if (!g_config->ReadInt(L"newtitle", 1))
  155. return FALSE;
  156. if (NULL == p->filename || '\0' == *p->filename ||
  157. NULL == p->metadata || '\0' == *p->metadata)
  158. {
  159. return FALSE;
  160. }
  161. extendedFileInfoStructW pW = {0};
  162. AutoWide wideFn(p->filename), wideMetadata(p->metadata);
  163. pW.filename = wideFn;
  164. pW.metadata = wideMetadata;
  165. pW.retlen = p->retlen;
  166. pW.ret = (wchar_t *)alloca(pW.retlen * sizeof(wchar_t));
  167. if (IPC_HookExtInfoW((INT_PTR)&pW))
  168. {
  169. WideCharToMultiByteSZ(CP_ACP, 0, pW.ret, -1, p->ret, p->retlen, 0, 0);
  170. return 1;
  171. }
  172. return 0;
  173. }
  174. BOOL IPC_HookTitleInfo(INT_PTR param)
  175. {
  176. if (skipTitleInfo) // we're reading metadata and being asked to skip title hooking (so we can get a valid title for guessing, if need be)
  177. return false;
  178. waHookTitleStructW *hts = (waHookTitleStructW*)param;
  179. if (NULL != hts->filename &&
  180. !StrStrW(hts->filename, L"://") &&
  181. g_config->ReadInt(L"newtitle", 1))
  182. {
  183. if (!g_table) openDb();
  184. if (!g_table) return 0;
  185. wchar_t filename2[MAX_PATH] = {0}; // full lfn path if set
  186. EnterCriticalSection(&g_db_cs);
  187. nde_scanner_t s = NDE_Table_CreateScanner(g_table);
  188. int found=FindFileInDatabase(s, MAINTABLE_ID_FILENAME, hts->filename, filename2);
  189. if (found)
  190. {
  191. nde_field_t length = NDE_Scanner_GetFieldByID(s, MAINTABLE_ID_LENGTH);
  192. int l = -1;
  193. if (length)
  194. l = NDE_IntegerField_GetValue(length);
  195. if (l > 0)
  196. hts->length = l;
  197. else hts->length = -1;
  198. if (hts->title)
  199. {
  200. TAG_FMT_EXT(hts->filename, fieldTagFunc, ndeTagFuncFree, (void*)s, hts->title, 2048, 1);
  201. }
  202. }
  203. NDE_Table_DestroyScanner(g_table, s);
  204. LeaveCriticalSection(&g_db_cs);
  205. if (found) return 1;
  206. } // not http://
  207. return FALSE;
  208. }
  209. DWORD doGuessProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  210. {
  211. // call the old wndproc, and if it produces empty results or no results, try to guess
  212. extendedFileInfoStruct *p = (extendedFileInfoStruct*)wParam;
  213. LRESULT ret = CallWindowProc(wa_oldWndProc, hwndDlg, uMsg, wParam, lParam);
  214. if (NULL != p &&
  215. (!ret || !p->ret[0]) &&
  216. g_config->ReadInt(L"guessmode", 0) != 2)
  217. {
  218. int which = 0;
  219. if (NULL != p->metadata)
  220. {
  221. if (!_stricmp(p->metadata, "artist")) which = 1;
  222. else if (!_stricmp(p->metadata, "title")) which = 2;
  223. else if (!_stricmp(p->metadata, "album")) which = 3;
  224. else if (!_stricmp(p->metadata, "track")) which = 5;
  225. else which = 0;
  226. }
  227. else
  228. which = 0;
  229. if (which)
  230. {
  231. static char m_lastfn[2048];
  232. if (NULL != p->filename && _strnicmp(m_lastfn, p->filename, sizeof(m_lastfn)))
  233. {
  234. m_db_found = 2;
  235. m_lastartist[0] = 0;
  236. m_lasttitle[0] = 0;
  237. m_lastalbum[0] = 0;
  238. m_lasttrack = 0;
  239. StringCbCopyA(m_lastfn, sizeof(m_lastfn), p->filename);
  240. int tn = 0;
  241. wchar_t *artist = 0, *album = 0, *title = 0;
  242. wchar_t *guessbuf = guessTitles(AutoWide(m_lastfn), &tn, &artist, &album, &title);
  243. if (guessbuf)
  244. {
  245. if (artist) StringCbCopyW(m_lastartist, sizeof(m_lastartist), artist);
  246. if (album) StringCbCopyW(m_lastalbum, sizeof(m_lastalbum), album);
  247. if (title) StringCbCopyW(m_lasttitle, sizeof(m_lasttitle), title);
  248. m_lasttrack = tn;
  249. free(guessbuf);
  250. }
  251. }
  252. if (m_db_found == 2)
  253. {
  254. if (which == 1 && m_lastartist[0])
  255. {
  256. WideCharToMultiByteSZ(CP_ACP, 0, m_lastartist, -1, p->ret, p->retlen, 0, 0);
  257. return 1;
  258. }
  259. if (which == 2 && m_lasttitle[0])
  260. {
  261. WideCharToMultiByteSZ(CP_ACP, 0, m_lasttitle, -1, p->ret, p->retlen, 0, 0);
  262. return 1;
  263. }
  264. if (which == 3 && m_lastalbum[0])
  265. {
  266. WideCharToMultiByteSZ(CP_ACP, 0, m_lastalbum, -1, p->ret, p->retlen, 0, 0);
  267. return 1;
  268. }
  269. if (which == 5 && m_lasttrack)
  270. {
  271. _snprintf(p->ret, p->retlen, "%d", m_lasttrack);
  272. return 1;
  273. }
  274. if (which == 6 && m_rating != -1)
  275. {
  276. _snprintf(p->ret, p->retlen, "%d", m_rating);
  277. return 1;
  278. }
  279. if (which == 7 && m_playcount != -1)
  280. {
  281. _snprintf(p->ret, p->retlen, "%d", m_playcount);
  282. return 1;
  283. }
  284. }
  285. }
  286. }
  287. return (int)ret;
  288. }