fuxoft

Google Music sort script (Linux)

Sep 16th, 2012
1,105
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env lua
  2. -- Copy your MP3s from src folder to dest folder, where they will be
  3. -- sorted into subdirectory structure: Dest_dir/genre/album/song.mp3
  4. require("lfs") --sudo apt-get install liblua5.1-filesystem0
  5. math.randomseed(123)
  6.  
  7. local function sanitize(str)
  8.     return (str:gsub("[^a-zA-Z0-9. ]","_"))
  9. end
  10.  
  11. local function get_tag(tagname, str)
  12.     local val = str:match(" %("..tagname.."%)%: (.-)>")
  13.     if val=="" then
  14.         val = false
  15.     end
  16.     return val
  17. end
  18.  
  19. local function scan_dir(directory, albums)
  20.     print("Entering directory: "..directory)
  21.     for fname in lfs.dir(directory) do
  22.         if fname ~= "." and fname ~= ".." then
  23.             local attrs = lfs.attributes(directory..fname)
  24.             if attrs.mode == "directory" then
  25.                 scan_dir(directory..fname.."/", albums)
  26.             else
  27.                 --print (fullname)
  28.                 assert(fname:match("mp3$"))
  29.                 --print(fullname)
  30.                 local escaped = fname:gsub("%$","\\$")
  31.                 escaped = escaped:gsub("`","\\`")
  32. --              print (escaped)
  33.                 local fd = assert(io.popen("eyeD3 -v \""..directory..escaped.."\""))
  34.                 local txt = fd:read("*a")
  35.                 fd:close()
  36.                 assert(txt:match("ID3"))
  37.                 local tags = {}
  38.                 for i,tagname in ipairs{"TPE1", "TPE2", "TALB", "TCON"} do
  39.                     tags[tagname] = get_tag(tagname, txt)
  40.                 end
  41.                 --print(tags.TPE2)
  42.                 local album = tags.TALB or "_no_album_"..math.random(999999)
  43.                 local genre = tags.TCON or "_no_genre"
  44. --              local dirname = sanitize(genre).."/"..sanitize(album)
  45.                 album = genre.."/"..album
  46.                 if not albums[album] then
  47.                     albums[album] = {}
  48.                 end
  49.                 table.insert(albums[album],{dir=directory,fname=escaped, genre=genre})
  50.             end
  51.         end
  52.     end
  53. end
  54.  
  55. local function main()
  56.     local dir_src = assert(arg[1])
  57.     local dir_dest = assert(arg[2])
  58.     assert(dir_src ~= dir_dest)
  59.     assert(dir_src:match("/$"))
  60.     assert(dir_dest:match("/$"))
  61.     local albums = {}
  62.     scan_dir(dir_src, albums)
  63.     for album, songs in pairs(albums) do
  64.         table.sort(songs,function(a,b) return (a.fname < b.fname) end)
  65.         --print(#songs, album)
  66.         local destdir = album
  67.         assert(#destdir > 0)
  68. --      destdir = dir_dest..destdir:sub(1,1).."/"..destdir.."/"
  69.         destdir = dir_dest..destdir.."/"
  70.         print("===Copying "..#songs.." songs in album: "..destdir)
  71.         local stat, err = os.execute('mkdir -p "'..destdir..'"')
  72.         if not stat then
  73.             print(err)
  74.         else
  75.             for i, song in ipairs(songs) do
  76.                 local destfname = destdir..sanitize(song.fname)
  77.                 if lfs.attributes(destfname) then
  78.                     print("File exists, skipping: "..destfname)
  79.                 else
  80.                     local command = 'cp "'..song.dir..song.fname..'" "'..destfname..'"'
  81.                     print(command)
  82.                     os.execute(command)
  83.                 end
  84.             end
  85.         end
  86.     end
  87. end
  88.  
  89. main()
  90.  
  91. --[[
  92. -------------------------------------------------------------------------------
  93. ID3 Frames:
  94. <Title/songname/content description (TIT2): The Terrace>
  95. <Lead performer(s)/Soloist(s) (TPE1): John Williams>
  96. !!! Album artist = TPE2
  97. <Composer (TCOM): John Williams>
  98. <Album/Movie/Show title (TALB): Superman>
  99. <Year (TYER): >
  100. <Track number/Position in set (TRCK): 3/0>
  101. <Part of a set (TPOS): 2/0>
  102. <Content type (TCON): Soundtrack>
  103. <Attached picture Frame (APIC)>
  104. ]]
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×