1010from concurrent .futures .thread import ThreadPoolExecutor
1111
1212import pymediainfo
13+ import mutagen
1314import guessit
1415from unidecode import unidecode
1516from requests .exceptions import HTTPError
1920from .torrent import make_torrent
2021from . import tvdb
2122from . import imdb
23+ from . import musicbrainz as mb
2224from . import imagehosting
2325from .ffmpeg import FFMpeg
2426from . import templating as bb
@@ -841,3 +843,202 @@ def _render_description(self):
841843 @form_field ('desc' )
842844 def _render_form_description (self ):
843845 return self ['description' ]
846+
847+
848+ class AudioSubmission (BbSubmission ):
849+ default_fields = ("description" , "form_tags" , "year" , "image" , "artist" ,
850+ "title" , "format" , "bitrate" , "media" )
851+
852+ def subcategory (self ):
853+ return MusicSubmission
854+
855+
856+ class MusicSubmission (AudioSubmission ):
857+ default_fields = (AudioSubmission .default_fields + (
858+ 'remaster' , 'remaster_year' , 'remaster_title' ))
859+ _form_type = 'Music'
860+ ## submit
861+ ## type
862+ ## artist
863+ ## title
864+ # remaster_true (checkbox, special edition info) (!?!?!)
865+ # -> remaster_year
866+ # -> remaster_title (optional)
867+ ## year
868+ ## scene (checkbox)
869+ ## format (select, options: MP3, FLAC, Ogg, AAC, DTS 5.1 Audio, 24bit FLAC)
870+ ## bitrate (select, options: 192, V2 (VBR), 256, V0 (VBR), 320, Lossless, Other)
871+ ## media (select, options: CD, DVD, Vinyl, Soundboard, DAT, Web)
872+ ## image
873+ # album_desc (!!!)
874+ ## release_desc (optional)
875+
876+ @form_field ('remaster_true' , 'checkbox' )
877+ def _render_remaster (self ):
878+ # todo user input function/module to reduce boilerplating
879+ return bool (
880+ input ('Is this a special/remastered edition?' ).lower () != 'n' )
881+
882+ @form_field ('remaster_year' )
883+ def _render_remaster_year (self ):
884+ pass
885+
886+ @form_field ('remaster_title' )
887+ def _render_remaster_title (self ):
888+ pass
889+
890+ @form_field ('format' )
891+ def _render_format (self ):
892+ # MP3, FLAC, Ogg, AAC, DTS 5.1 Audio, 24bit FLAC
893+ choices = ('MP3' , 'FLAC' , 'Ogg' , 'AAC' , '24bit FLAC' )
894+
895+ tl_format = {
896+ 'MP3' : 'MP3' ,
897+ 'EasyMP3' : 'MP3' ,
898+ 'OggVorbis' : 'Ogg' ,
899+ 'OggOpus' : 'Ogg' ,
900+ 'FLAC' : 'FLAC' ,
901+ 'AAC' : 'AAC' ,
902+ }
903+
904+ tags = self ['tags' ]
905+ format = tl_format [tags ['format' ]]
906+ if format == 'FLAC' and tags ['bits_per_sample' ] >= 24 :
907+ format = '24bit FLAC'
908+
909+ return format
910+
911+ @form_field ('bitrate' )
912+ def _render_bitrate (self ):
913+ # 192, V2(VBR), 256, V0(VBR), 320, Lossless, Other)
914+ format = self ['format' ]
915+ tags = self ['tags' ]
916+ if format == 'MP3' :
917+ if tags ['encoder_settings' ] == '-V 0' :
918+ return 'V0(VBR)'
919+ elif tags ['encoder_settings' ] == '-V 2' :
920+ return 'V2(VBR)'
921+ elif tags ['bitrate' ] == 192000 :
922+ return '192'
923+ elif tags ['bitrate' ] == 256000 :
924+ return '256'
925+ elif tags ['bitrate' ] == 320000 :
926+ return '320'
927+
928+ elif 'FLAC' in format :
929+ return 'Lossless'
930+
931+ raise Exception ('Unrecognized format/bitrate' )
932+
933+ @form_field ('media' )
934+ def _render_media (self ):
935+ media = self ['summary' ]['media' ]
936+
937+ if len (media ) == 1 :
938+ return media [0 ]
939+
940+ raise Exception ('Handle this' )
941+
942+ def _render_mediainfo_path (self ):
943+ assert os .path .isdir (self ['path' ])
944+
945+ for dp , dns , fns in os .walk (self ['path' ]):
946+ for fn in fns :
947+ full_path = os .path .join (dp , fn )
948+ if os .path .getsize (full_path ) > 1 * 2 ** 20 :
949+ return full_path
950+ raise Exception ('No media file found' )
951+
952+ def _render_songlist (self ):
953+ return None
954+
955+ def _render_tags (self ):
956+ tags = mutagen .File (self ['mediainfo_path' ], easy = True )
957+ # if type(tags) == mutagen.mp3.MP3:
958+ # tags = mutagen.mp3.MP3(self['mediainfo_path'], ID3=EasyID3)
959+
960+ print (dir (tags .info ))
961+ try :
962+ print (tags .info .encoder_settings )
963+ except :
964+ pass
965+ log .debug (type (tags ))
966+ log .debug (tags .pprint ())
967+
968+ return {'artist' : tags .get ('albumartist' , tags ['artist' ])[0 ],
969+ 'title' : tags ['album' ][0 ],
970+ 'rid' : tags .get ('musicbrainz_albumid' , [None ])[0 ],
971+ 'format' : type (tags ).__name__ ,
972+ 'bitrate' : tags .info .bitrate ,
973+ 'bits_per_sample' : getattr (tags .info , 'bits_per_sample' ,
974+ None ),
975+ 'encoder_settings' : getattr (tags .info , 'encoder_settings' ,
976+ None ),
977+ }
978+
979+ def _render_summary (self ):
980+ # identify self:
981+ # - num tracks todo
982+ # - scan for mb tags
983+ tags = self ['tags' ]
984+ print (tags )
985+ if tags ['rid' ]:
986+ log .info ('Found MusicBrainz release in tags' )
987+ release = mb .musicbrainzngs .get_release_by_id (
988+ tags ['rid' ],
989+ includes = ['release-groups' , 'media' ])['release' ]
990+ rg = mb .musicbrainzngs .get_release_group_by_id (
991+ release ['release-group' ]['id' ],
992+ includes = ['tags' , 'artist-credits' ])['release-group' ]
993+
994+ else :
995+ if self ['title_arg' ]:
996+ query_artist = None
997+ query = self ['title_arg' ]
998+ else :
999+ query_artist = tags ['artist' ]
1000+ query = tags ['title' ]
1001+ rg , release = mb .find_release (query , artist = query_artist )
1002+
1003+ print ('rg' , rg )
1004+ print ('r' , release )
1005+
1006+ print (rg .keys ())
1007+ return {
1008+ 'artist' : rg ['artist-credit-phrase' ],
1009+ 'title' : rg ['title' ],
1010+ 'year' : release ['release-event-list' ][0 ]['date' ][:4 ],
1011+ 'tags' : [t ['name' ] for t in
1012+ sorted (rg .get ('tag-list' , []),
1013+ key = lambda t : int (t ['count' ]))][- 5 :],
1014+ 'media' : [m ['format' ] for m in release ['medium-list' ]],
1015+ 'cover' : mb .get_artwork (rg ['id' ]),
1016+ }
1017+
1018+ @finalize
1019+ @form_field ('image' )
1020+ def _render_image (self ):
1021+ return self ['summary' ]['cover' ]
1022+
1023+ def _finalize_image (self ):
1024+ return ImgurUploader ().upload (self ['image' ])
1025+
1026+ @form_field ('year' )
1027+ def _render_year (self ):
1028+ return self ['summary' ]['year' ]
1029+
1030+ @form_field ('tags' )
1031+ def _render_form_tags (self ):
1032+ return self ['summary' ]['tags' ]
1033+
1034+ @form_field ('album_desc' )
1035+ def _render_description (self ):
1036+ return 'album description'
1037+
1038+ @form_field ('artist' )
1039+ def _render_artist (self ):
1040+ return self ['summary' ]['artist' ]
1041+
1042+ @form_field ('title' )
1043+ def _render_title (self ):
1044+ return self ['summary' ]['title' ]
0 commit comments