listSong.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. /*
  2. List Song
  3. This function will list all song with the given directories.
  4. Type of operations
  5. listSong=(type)
  6. listSong=search:(keyword)
  7. listdir=root
  8. listdir= (Target path)
  9. listfolder=(target folder)
  10. This module is a direct lanuage translation from the original module.Musi.go
  11. */
  12. //Global variables
  13. var MINCACHESIZE = 300; //Min song list length for start using cache method
  14. //Include the common library
  15. var succ = includes("common.js")
  16. if (succ == false){
  17. console.log("Failed to load common.js");
  18. }
  19. //Handle user request
  20. function handleUserRequest(){
  21. if (requirelib("filelib") == false){
  22. sendJSONResp(JSON.stringify({
  23. error: "Unable to load filelib"
  24. }));
  25. }else{
  26. var musicDis = [];
  27. //Make the user's root music folder if not exists
  28. if (filelib.fileExists("user:/Music/") == false){
  29. filelib.mkdir("user:/Music/");
  30. }
  31. //Scan all music directories
  32. var rootDirs = filelib.glob("/");
  33. for (var i = 0; i < rootDirs.length; i++){
  34. var thisRoot = rootDirs[i];
  35. //Always use all roots
  36. musicDis.push(thisRoot);
  37. }
  38. //Handle user request on listing
  39. if (typeof(listSong) != "undefined"){
  40. //List song given type
  41. if (listSong == "all"){
  42. //Load from cache first. If cache list > 1000 then deliver the cache then update the cache file
  43. newDBTableIfNotExists("AirMusic");
  44. var cacheListRaw = readDBItem("AirMusic", "cache");
  45. if (cacheListRaw == ""){
  46. //Cache list not generated yet. Continue
  47. }else if (cacheListRaw != ""){
  48. //There is something in the cache list. Try parse it
  49. try{
  50. //Try parse it.
  51. var cacheList = JSON.parse(cacheListRaw);
  52. if (cacheList.length > MINCACHESIZE){
  53. //Too many songs. Just use the cache list instead.
  54. sendJSONResp(JSON.stringify({
  55. cached: true,
  56. list: cacheList
  57. }));
  58. return
  59. }
  60. }catch(ex){
  61. }
  62. }
  63. //Do the scanning
  64. var songData = [];
  65. var musicFiles = [];
  66. for (var i = 0; i < musicDis.length; i++){
  67. var thisFileLib = musicDis[i];
  68. var allfilelist = filelib.walk(thisFileLib, "file");
  69. for (var k = 0; k < allfilelist.length; k++){
  70. var ext = allfilelist[k].split('.').pop();
  71. if (IsSupportExt(ext) == true && !IsMetaFile(allfilelist[k])){
  72. musicFiles.push(allfilelist[k]);
  73. }
  74. }
  75. }
  76. for (var i = 0; i < musicFiles.length; i++){
  77. var thisMusicFile = musicFiles[i];
  78. var thisSongData = [];
  79. //Access Path
  80. thisSongData.push("/media?file=" + thisMusicFile);
  81. //File Name only
  82. var filename = thisMusicFile.split("/").pop()
  83. filename = filename.split(".");
  84. var ext = filename.pop();
  85. filename = filename.join(".");
  86. thisSongData.push(filename);
  87. //File Extension
  88. thisSongData.push(ext);
  89. //File size
  90. var fileSize = bytesToSize(filelib.filesize(thisMusicFile))
  91. thisSongData.push(fileSize)
  92. songData.push(thisSongData);
  93. }
  94. //Return the parsed info
  95. //sendJSONResp(JSON.stringify(songData));
  96. //Write to cache and send
  97. writeDBItem("AirMusic", "cache", JSON.stringify(songData));
  98. sendJSONResp(JSON.stringify({
  99. cached: false,
  100. list: songData
  101. }));
  102. }else if (listSong.substr(0,7) == "search:"){
  103. //Search mode
  104. var keyword = listSong.substr(7)
  105. keyword = keyword.toLowerCase();
  106. var songData = [];
  107. var cachedList = readDBItem("AirMusic", "cache");
  108. var allfilelist = [];
  109. function getRealtimeAllFleList(){
  110. var allfilelist = [];
  111. for (var i = 0; i < musicDis.length; i++){
  112. var thisFileLib = musicDis[i];
  113. thisDirList = filelib.walk(thisFileLib, "file");
  114. for (var j = 0; j < thisDirList.length; j++){
  115. allfilelist.push(thisDirList[j]);
  116. }
  117. }
  118. return allfilelist;
  119. }
  120. if (cachedList == ""){
  121. //No cache. Do real time scanning
  122. allfilelist = getRealtimeAllFleList();
  123. }else{
  124. //Try parse it. If parse failed fallback to realtime scanning
  125. try{
  126. cachedList = JSON.parse(cachedList);
  127. for (var j = 0; j < cachedList.length; j++){
  128. var thisCachedSong = cachedList[j];
  129. var thisFilepath = thisCachedSong[0].replace("/media?file=", "");
  130. //Check if this file still exists. If not, get realtime list instead.
  131. if (filelib.fileExists(thisFilepath)){
  132. allfilelist.push(thisFilepath);
  133. }else{
  134. //Cache outdated. Rescanning now
  135. allfilelist = getRealtimeAllFleList();
  136. execd("buildCache.js")
  137. break;
  138. }
  139. }
  140. }catch(ex){
  141. //Fallback
  142. allfilelist = getRealtimeAllFleList();
  143. }
  144. }
  145. for (var k = 0; k < allfilelist.length; k++){
  146. var thisFile = allfilelist[k];
  147. var ext = allfilelist[k].split('.').pop();
  148. var filename = allfilelist[k].split('/').pop();
  149. filename = filename.toLowerCase();
  150. if (IsSupportExt(ext) == true && filename.indexOf(keyword) !== -1 && !IsMetaFile(allfilelist[k])){
  151. //This file match our ext req and keyword exists
  152. var thisSongData = [];
  153. //Access Path
  154. thisSongData.push("/media?file=" + thisFile);
  155. //File Name only
  156. var filename = thisFile.split("/").pop()
  157. filename = filename.split(".");
  158. var ext = filename.pop();
  159. filename = filename.join(".");
  160. thisSongData.push(filename);
  161. //File Extension
  162. thisSongData.push(ext);
  163. //File size
  164. var fileSize = bytesToSize(filelib.filesize(thisFile))
  165. thisSongData.push(fileSize)
  166. songData.push(thisSongData);
  167. }
  168. }
  169. //Send resp
  170. sendJSONResp(JSON.stringify(songData));
  171. //Run build cache in background so to update any cache if exists
  172. execd("buildCache.js")
  173. }else{
  174. //WIP
  175. console.log("listSong type " + listSong + " work in progress")
  176. }
  177. }else if (typeof(listdir) != "undefined"){
  178. //List dir given path
  179. if (listdir == "root"){
  180. //List the information of the user roots that contain Music folder
  181. var rootInfo = [];
  182. for (var i =0; i < musicDis.length; i++){
  183. var thisRootInfo = [];
  184. var thisMusicDir = musicDis[i];
  185. var thisRoot = thisMusicDir.split("/").shift() + "/";
  186. var objcetsInRoot = [];
  187. if (thisRoot == "user:/"){
  188. objcetsInRoot = filelib.glob(thisRoot + "Music/*");
  189. }else{
  190. objcetsInRoot = filelib.glob(thisRoot + "*");
  191. thisMusicDir = thisRoot;
  192. }
  193. var rootName = filelib.rootName(thisRoot);
  194. if (rootName == false){
  195. rootName = thisRoot
  196. }
  197. thisRootInfo.push(rootName);
  198. thisRootInfo.push(thisMusicDir);
  199. var files = [];
  200. var folders = [];
  201. for (var j = 0; j < objcetsInRoot.length; j++){
  202. if (filelib.isDir(objcetsInRoot[j])){
  203. folders.push(objcetsInRoot[j]);
  204. }else{
  205. files.push(objcetsInRoot[j]);
  206. }
  207. }
  208. thisRootInfo.push(files.length);
  209. thisRootInfo.push(folders.length);
  210. rootInfo.push(thisRootInfo);
  211. }
  212. sendJSONResp(JSON.stringify(rootInfo));
  213. }else{
  214. //List information about other folders
  215. var targetpath = decodeURIComponent(listdir)
  216. var filelist = filelib.aglob(targetpath + "*")
  217. var files = [];
  218. var folders = [];
  219. for (var j = 0; j < filelist.length; j++){
  220. if (filelib.isDir(filelist[j])){
  221. folders.push(filelist[j]);
  222. }else{
  223. var ext = filelist[j].split(".").pop();
  224. if (IsSupportExt(ext) && !IsMetaFile(filelist[j])){
  225. files.push(filelist[j]);
  226. }
  227. }
  228. }
  229. //For each folder, get its information
  230. var folderInfo = [];
  231. for (var i = 0; i < folders.length; i++){
  232. var thisFolderInfo = [];
  233. var folderName = folders[i].split("/").pop();
  234. var thisFolderSubfolder = [];
  235. var thisFolderSubfiles = [];
  236. var subFolderFileList = filelib.aglob(folders[i] + "/*")
  237. for (var j = 0; j < subFolderFileList.length; j++){
  238. if (filelib.isDir(subFolderFileList[j])){
  239. var thisFolderName = subFolderFileList[j].split("/").pop();
  240. if (thisFolderName.substring(0,1) != "."){
  241. thisFolderSubfolder.push(subFolderFileList[j]);
  242. }
  243. }else{
  244. var ext = subFolderFileList[j].split(".").pop();
  245. if (IsSupportExt(ext) && !IsMetaFile(subFolderFileList[j])){
  246. thisFolderSubfiles.push(subFolderFileList[j]);
  247. }
  248. }
  249. }
  250. thisFolderInfo.push(folderName);
  251. thisFolderInfo.push(folders[i] + "/");
  252. thisFolderInfo.push((thisFolderSubfiles).length + "");
  253. thisFolderInfo.push((thisFolderSubfolder).length + "");
  254. folderInfo.push(thisFolderInfo)
  255. }
  256. var fileInfo = [];
  257. for (var i = 0; i < files.length; i++){
  258. var thisFileInfo = [];
  259. var filename = files[i].split("/").pop();
  260. filename = filename.split('.')
  261. filename.pop();
  262. filename = filename.join(".");
  263. var ext = files[i].split(".").pop()
  264. var filesize = filelib.filesize(files[i]);
  265. filesize = bytesToSize(filesize);
  266. thisFileInfo.push("/media?file=" + files[i]);
  267. thisFileInfo.push(filename);
  268. thisFileInfo.push(ext);
  269. thisFileInfo.push(filesize);
  270. fileInfo.push(thisFileInfo);
  271. }
  272. var results = [];
  273. results.push(folderInfo);
  274. results.push(fileInfo);
  275. sendJSONResp(JSON.stringify(results));
  276. }
  277. }else if (typeof(listFolder) != "undefined"){
  278. //List folder giben filepath
  279. }
  280. }
  281. }
  282. //Execute Handler
  283. handleUserRequest();