listSong.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  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. //var isRanged = false; //Check if this only need to return from a range
  46. //if (typeof(start) != "undefined" && typeof(end) != "undefined"){
  47. // isRanged = true;
  48. //}
  49. if (cacheListRaw == ""){
  50. //Cache list not generated yet. Continue
  51. }else if (cacheListRaw != ""){
  52. //There is something in the cache list. Try parse it
  53. try{
  54. //Try parse it.
  55. var cacheList = JSON.parse(cacheListRaw);
  56. if (cacheList.length > MINCACHESIZE){
  57. //Too many songs. Just use the cache list instead.
  58. sendJSONResp(JSON.stringify({
  59. cached: true,
  60. list: cacheList
  61. }));
  62. return
  63. }
  64. }catch(ex){
  65. }
  66. }
  67. //Do the scanning
  68. var songData = [];
  69. var musicFiles = [];
  70. for (var i = 0; i < musicDis.length; i++){
  71. var thisFileLib = musicDis[i];
  72. var allfilelist = filelib.walk(thisFileLib + "Music/", "file");
  73. for (var k = 0; k < allfilelist.length; k++){
  74. var ext = allfilelist[k].split('.').pop();
  75. if (IsSupportExt(ext) == true && !IsMetaFile(allfilelist[k])){
  76. musicFiles.push(allfilelist[k]);
  77. }
  78. }
  79. }
  80. for (var i = 0; i < musicFiles.length; i++){
  81. var thisMusicFile = musicFiles[i];
  82. var thisSongData = [];
  83. /*
  84. Catch formats looks like this
  85. entry = [access_url, filename, ext, filesize]
  86. */
  87. //Access Path
  88. thisSongData.push("/media?file=" + thisMusicFile);
  89. //File Name only
  90. var filename = thisMusicFile.split("/").pop()
  91. filename = filename.split(".");
  92. var ext = filename.pop();
  93. filename = filename.join(".");
  94. thisSongData.push(filename);
  95. //File Extension
  96. thisSongData.push(ext);
  97. //File size
  98. var fileSize = bytesToSize(filelib.filesize(thisMusicFile))
  99. thisSongData.push(fileSize)
  100. songData.push(thisSongData);
  101. }
  102. //Return the parsed info
  103. //sendJSONResp(JSON.stringify(songData));
  104. //Write to cache and send
  105. writeDBItem("AirMusic", "cache", JSON.stringify(songData));
  106. sendJSONResp(JSON.stringify({
  107. cached: false,
  108. list: songData
  109. }));
  110. }else if (listSong.substr(0,7) == "search:"){
  111. //Search mode
  112. var keyword = listSong.substr(7)
  113. keyword = keyword.toLowerCase();
  114. var songData = [];
  115. var cachedList = readDBItem("AirMusic", "cache");
  116. var allfilelist = [];
  117. function getRealtimeAllFleList(){
  118. var allfilelist = [];
  119. for (var i = 0; i < musicDis.length; i++){
  120. var thisFileLib = musicDis[i];
  121. thisDirList = filelib.walk(thisFileLib, "file");
  122. for (var j = 0; j < thisDirList.length; j++){
  123. allfilelist.push(thisDirList[j]);
  124. }
  125. }
  126. return allfilelist;
  127. }
  128. if (cachedList == ""){
  129. //No cache. Do real time scanning
  130. allfilelist = getRealtimeAllFleList();
  131. }else{
  132. //Try parse it. If parse failed fallback to realtime scanning
  133. try{
  134. cachedList = JSON.parse(cachedList);
  135. for (var j = 0; j < cachedList.length; j++){
  136. var thisCachedSong = cachedList[j];
  137. var thisFilepath = thisCachedSong[0].replace("/media?file=", "");
  138. //Check if this file still exists. If not, get realtime list instead.
  139. if (filelib.fileExists(thisFilepath)){
  140. allfilelist.push(thisFilepath);
  141. }else{
  142. //Cache outdated. Rescanning now
  143. allfilelist = getRealtimeAllFleList();
  144. execd("buildCache.js")
  145. break;
  146. }
  147. }
  148. }catch(ex){
  149. //Fallback
  150. allfilelist = getRealtimeAllFleList();
  151. }
  152. }
  153. for (var k = 0; k < allfilelist.length; k++){
  154. var thisFile = allfilelist[k];
  155. var ext = allfilelist[k].split('.').pop();
  156. var filename = allfilelist[k].split('/').pop();
  157. filename = filename.toLowerCase();
  158. if (IsSupportExt(ext) == true && filename.indexOf(keyword) !== -1 && !IsMetaFile(allfilelist[k])){
  159. //This file match our ext req and keyword exists
  160. var thisSongData = [];
  161. //Access Path
  162. thisSongData.push("/media?file=" + thisFile);
  163. //File Name only
  164. var filename = thisFile.split("/").pop()
  165. filename = filename.split(".");
  166. var ext = filename.pop();
  167. filename = filename.join(".");
  168. thisSongData.push(filename);
  169. //File Extension
  170. thisSongData.push(ext);
  171. //File size
  172. var fileSize = bytesToSize(filelib.filesize(thisFile))
  173. thisSongData.push(fileSize)
  174. songData.push(thisSongData);
  175. }
  176. }
  177. //Send resp
  178. sendJSONResp(JSON.stringify(songData));
  179. //Run build cache in background so to update any cache if exists
  180. execd("buildCache.js")
  181. }else{
  182. //WIP
  183. console.log("listSong type " + listSong + " work in progress")
  184. }
  185. }else if (typeof(listdir) != "undefined"){
  186. //List dir given path
  187. if (listdir == "root"){
  188. //List the information of the user roots that contain Music folder
  189. var rootInfo = [];
  190. for (var i =0; i < musicDis.length; i++){
  191. var thisRootInfo = [];
  192. var thisMusicDir = musicDis[i];
  193. var thisRoot = thisMusicDir.split("/").shift() + "/";
  194. var objcetsInRoot = [];
  195. if (thisRoot == "user:/"){
  196. objcetsInRoot = filelib.readdir(thisRoot + "Music");
  197. }else{
  198. objcetsInRoot = filelib.readdir(thisRoot);
  199. thisMusicDir = thisRoot;
  200. }
  201. var rootName = filelib.rootName(thisRoot);
  202. if (rootName == false){
  203. rootName = thisRoot
  204. }
  205. thisRootInfo.push(rootName);
  206. thisRootInfo.push(thisMusicDir);
  207. var files = [];
  208. var folders = [];
  209. for (var j = 0; j < objcetsInRoot.length; j++){
  210. var thisObject = objcetsInRoot[j];
  211. if (thisObject.IsDir){
  212. folders.push(thisObject.Filepath);
  213. }else{
  214. files.push(thisObject.Filepath);
  215. }
  216. }
  217. thisRootInfo.push(files.length);
  218. thisRootInfo.push(folders.length);
  219. rootInfo.push(thisRootInfo);
  220. }
  221. sendJSONResp(JSON.stringify(rootInfo));
  222. }else{
  223. //List information about other folders
  224. var targetpath = decodeURIComponent(listdir);
  225. var filelist = filelib.readdir(targetpath);
  226. var files = [];
  227. var fileSizes = [];
  228. var folders = [];
  229. for (var j = 0; j < filelist.length; j++){
  230. var thisFile = filelist[j];
  231. if (thisFile.IsDir){
  232. folders.push(thisFile.Filepath);
  233. }else{
  234. var ext = thisFile.Ext.substr(1);
  235. if (IsSupportExt(ext) && !IsMetaFile(thisFile.Filepath)){
  236. files.push(thisFile.Filepath);
  237. fileSizes.push(thisFile.Filesize);
  238. }
  239. }
  240. }
  241. //For each folder, get its information
  242. var folderInfo = [];
  243. for (var i = 0; i < folders.length; i++){
  244. var thisFolderInfo = [];
  245. var folderName = folders[i].split("/").pop();
  246. /*
  247. var thisFolderSubfolder = [];
  248. var thisFolderSubfiles = [];
  249. var subFolderFileList = filelib.readdir(folders[i])
  250. for (var j = 0; j < subFolderFileList.length; j++){
  251. var thisFileinfo = subFolderFileList[j];
  252. if (thisFileinfo.IsDir){
  253. var thisFolderName = thisFileinfo.Filename;
  254. if (thisFolderName.substring(0,1) != "."){
  255. thisFolderSubfolder.push(thisFileinfo.Filepath);
  256. }
  257. }else{
  258. var ext = thisFileinfo.Ext.substr(1);
  259. if (IsSupportExt(ext) && !IsMetaFile(thisFileinfo.Filepath)){
  260. thisFolderSubfiles.push(thisFileinfo.Filepath);
  261. }
  262. }
  263. }
  264. */
  265. thisFolderInfo.push(folderName);
  266. thisFolderInfo.push(folders[i] + "/");
  267. //thisFolderInfo.push((thisFolderSubfiles).length + "");
  268. //thisFolderInfo.push((thisFolderSubfolder).length + "");
  269. thisFolderInfo.push(-1);
  270. thisFolderInfo.push(-1);
  271. folderInfo.push(thisFolderInfo)
  272. }
  273. var fileInfo = [];
  274. for (var i = 0; i < files.length; i++){
  275. var thisFileInfo = [];
  276. var filename = files[i].split("/").pop();
  277. filename = filename.split('.')
  278. filename.pop();
  279. filename = filename.join(".");
  280. var ext = files[i].split(".").pop()
  281. var filesize = fileSizes[i];
  282. filesize = bytesToSize(filesize);
  283. thisFileInfo.push("/media?file=" + files[i]);
  284. thisFileInfo.push(filename);
  285. thisFileInfo.push(ext);
  286. thisFileInfo.push(filesize);
  287. fileInfo.push(thisFileInfo);
  288. }
  289. var results = [];
  290. results.push(folderInfo);
  291. results.push(fileInfo);
  292. sendJSONResp(JSON.stringify(results));
  293. }
  294. }else if (typeof(listFolder) != "undefined"){
  295. //List folder giben filepath
  296. }
  297. }
  298. }
  299. //Execute Handler
  300. handleUserRequest();