Advertisement
fuxoft

Google Music sort script (Linux)

Sep 16th, 2012
1,774
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 3.08 KB | None | 0 0
  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. ]]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement