示例#1
0
def process(folder):
    os.chdir(folder)
    folder = os.getcwd()
    walk_result = os.walk(folder)

    for f in walk_result:
        (dirpath, dirnames, filenames) = f
        args = dirpath[len(folder):].split('/')
        artist = 'Unknown' if (len(args) < 2) else args[1]
        album = 'Unknown' if (len(args) < 3) else args[2]
        print "Artist:", artist, ", album:", album
        for file in filenames:
            if file[-4:].lower() != '.mp3':
                continue
            title = file[:-4]
            fullpath = dirpath + "/" + file
            print title
            
            if (os.access(fullpath, os.R_OK | os.W_OK) == False):
                print 'Error: bad permissions on', fullpath
                continue

            #mutagen.id3.delete(fullpath)
            id3 = mutagen.id3.ID3()
            id3.add(mutagen.id3.TPE1(encoding = 3, text = artist.decode("utf-8")))
            id3.add(mutagen.id3.TALB(encoding = 3, text = album.decode("utf-8")))
            id3.add(mutagen.id3.TIT2(encoding = 3, text = title.decode("utf-8")))
            id3.save(fullpath)
示例#2
0
def set(filename, src, cover=None):
    mode = ext(filename)
    if mode == "mp3":
        dst = mutagen.easyid3.EasyID3()
        copy_tags(src, dst)
        dst.save(filename)
        if cover:
            id3 = mutagen.mp3.MP3(filename)
            id3.tags.add(
                mutagen.id3.APIC(encoding=3, mime="image/jpeg", type=3, desc=u"Cover", data=open(cover).read())
            )
            id3.save()
    elif mode == "ogg":
        dst = mutagen.oggvorbis.OggVorbis(filename)
        copy_tags(src, dst)
        if cover:
            dst["COVERARTMIME"] = u"image/jpeg"
            dst["COVERARTTYPE"] = u"3"
            dst["COVERARTDESCRIPTION"] = u"Cover"
            dst["COVERART"] = unicode(base64.b64encode(open(cover).read()))
        dst.save()
    elif mode == "flac":
        dst = mutagen.flac.FLAC(filename)
        copy_tags(src, dst)
        dst.save()
    else:
        logger.info(filename + ": tags not supported")
示例#3
0
 def test_nofile_silencetag(self):
     id3 = ID3(self.filename)
     os.unlink(self.filename)
     id3.save(self.filename)
     with open(self.filename, 'rb') as h:
         self.assertEquals(b'ID3', h.read(3))
     self.test_same()
示例#4
0
def delete_frames(deletes, filenames):

    try:
        deletes = frame_from_fsnative(deletes)
    except ValueError as err:
        print_(text_type(err), file=sys.stderr)

    frames = deletes.split(",")

    for filename in filenames:
        with _sig.block():
            if verbose:
                print_(u"deleting %s from" % deletes, filename,
                       file=sys.stderr)
            try:
                id3 = mutagen.id3.ID3(filename)
            except mutagen.id3.ID3NoHeaderError:
                if verbose:
                    print_(u"No ID3 header found; skipping.", file=sys.stderr)
            except Exception as err:
                print_(text_type(err), file=sys.stderr)
                raise SystemExit(1)
            else:
                for frame in frames:
                    id3.delall(frame)
                id3.save()
示例#5
0
def process(folder):
    os.chdir(folder)
    folder = os.getcwd()
    walk_result = os.walk(folder)

    for f in walk_result:
        (dirpath, dirnames, filenames) = f
        args = dirpath[len(folder) :].split("/")
        artist = "Unknown" if (len(args) < 2) else args[1]
        album = "Unknown" if (len(args) < 3) else args[2]
        print "Artist:", artist, ", album:", album
        for file in filenames:
            if file[-4:].lower() != ".mp3":
                continue
            title = file[:-4]
            fullpath = dirpath + "/" + file
            print title

            if os.access(fullpath, os.R_OK | os.W_OK) == False:
                print "Error: bad permissions on", fullpath
                continue

            # mutagen.id3.delete(fullpath)
            id3 = mutagen.id3.ID3()
            id3.add(mutagen.id3.TPE1(encoding=3, text=artist.decode("utf-8")))
            id3.add(mutagen.id3.TALB(encoding=3, text=album.decode("utf-8")))
            id3.add(mutagen.id3.TIT2(encoding=3, text=title.decode("utf-8")))
            id3.save(fullpath)
def delete_frames(deletes, filenames):

    try:
        deletes = frame_from_fsnative(deletes)
    except ValueError as err:
        print_(text_type(err), file=sys.stderr)

    frames = deletes.split(",")

    for filename in filenames:
        with _sig.block():
            if verbose:
                print_(u"deleting %s from" % deletes,
                       filename,
                       file=sys.stderr)
            try:
                id3 = mutagen.id3.ID3(filename)
            except mutagen.id3.ID3NoHeaderError:
                if verbose:
                    print_(u"No ID3 header found; skipping.", file=sys.stderr)
            except Exception as err:
                print_(text_type(err), file=sys.stderr)
                raise SystemExit(1)
            else:
                for frame in frames:
                    id3.delall(frame)
                id3.save()
示例#7
0
 def test_nofile_silencetag(self):
     id3 = ID3(self.filename)
     os.unlink(self.filename)
     id3.save(self.filename)
     with open(self.filename, 'rb') as h:
         self.assertEquals(b'ID3', h.read(3))
     self.test_same()
示例#8
0
 def test_emptyfile_silencetag(self):
     id3 = ID3(self.filename)
     with open(self.filename, 'wb') as h:
         h.truncate()
     id3.save(self.filename)
     with open(self.filename, 'rb') as h:
         self.assertEquals(b'ID3', h.read(3))
     self.test_same()
示例#9
0
 def test_emptyfile_silencetag(self):
     id3 = ID3(self.filename)
     with open(self.filename, 'wb') as h:
         h.truncate()
     id3.save(self.filename)
     with open(self.filename, 'rb') as h:
         self.assertEquals(b'ID3', h.read(3))
     self.test_same()
示例#10
0
 def test_same_v23(self):
     id3 = ID3(self.filename, v2_version=3)
     id3.save(v2_version=3)
     id3 = ID3(self.filename)
     self.assertEqual(id3.version, (2, 3, 0))
     self.assertEquals(id3["TALB"], "Quod Libet Test Data")
     self.assertEquals(id3["TCON"], "Silence")
     self.assertEquals(id3["TIT2"], "Silence")
     self.assertEquals(id3["TPE1"], "piman/jzig")
示例#11
0
def copy(src, dst, merge, write_v1=True, excluded_tags=None, verbose=False):
    """Returns 0 on success"""

    if excluded_tags is None:
        excluded_tags = []

    try:
        id3 = mutagen.id3.ID3(src, translate=False)
    except mutagen.id3.ID3NoHeaderError:
        print_(u"No ID3 header found in ", src, file=sys.stderr)
        return 1
    except Exception as err:
        print_(str(err), file=sys.stderr)
        return 1

    if verbose:
        print_(u"File", src, u"contains:", file=sys.stderr)
        print_(id3.pprint(), file=sys.stderr)

    for tag in excluded_tags:
        id3.delall(tag)

    if merge:
        try:
            target = mutagen.id3.ID3(dst, translate=False)
        except mutagen.id3.ID3NoHeaderError:
            # no need to merge
            pass
        except Exception as err:
            print_(str(err), file=sys.stderr)
            return 1
        else:
            for frame in id3.values():
                target.add(frame)

            id3 = target

    # if the source is 2.3 save it as 2.3
    if id3.version < (2, 4, 0):
        id3.update_to_v23()
        v2_version = 3
    else:
        id3.update_to_v24()
        v2_version = 4

    try:
        id3.save(dst, v1=(2 if write_v1 else 0), v2_version=v2_version)
    except Exception as err:
        print_(u"Error saving",
               dst,
               u":\n%s" % text_type(err),
               file=sys.stderr)
        return 1
    else:
        if verbose:
            print_(u"Successfully saved", dst, file=sys.stderr)
        return 0
示例#12
0
 def test_empty_plustag_minustag_empty(self):
     id3 = ID3(self.filename)
     with open(self.filename, 'wb') as h:
         h.truncate()
     id3.save()
     id3.delete()
     self.failIf(id3)
     with open(self.filename, 'rb') as h:
         self.assertEquals(h.read(10), b'')
示例#13
0
 def test_same_v23(self):
     id3 = ID3(self.filename, v2_version=3)
     id3.save(v2_version=3)
     id3 = ID3(self.filename)
     self.assertEqual(id3.version, (2, 3, 0))
     self.assertEquals(id3["TALB"], "Quod Libet Test Data")
     self.assertEquals(id3["TCON"], "Silence")
     self.assertEquals(id3["TIT2"], "Silence")
     self.assertEquals(id3["TPE1"], "piman/jzig")
示例#14
0
 def test_empty_plustag_minustag_empty(self):
     id3 = ID3(self.filename)
     with open(self.filename, 'wb') as h:
         h.truncate()
     id3.save()
     id3.delete()
     self.failIf(id3)
     with open(self.filename, 'rb') as h:
         self.assertEquals(h.read(10), b'')
示例#15
0
def update(options, filenames):
    encoding = options.encoding or getpreferredencoding()
    verbose = options.verbose
    noupdate = options.noupdate
    force_v1 = options.force_v1
    remove_v1 = options.remove_v1

    def conv(uni):
        return uni.encode('iso-8859-1').decode(encoding)

    for filename in filenames:
        with _sig.block():
            if verbose != "quiet":
                print_(u"Updating", filename)

            if has_id3v1(filename) and not noupdate and force_v1:
                mutagen.id3.delete(filename, False, True)

            try:
                id3 = mutagen.id3.ID3(filename)
            except mutagen.id3.ID3NoHeaderError:
                if verbose != "quiet":
                    print_(u"No ID3 header found; skipping...")
                continue
            except Exception as err:
                print_(text_type(err), file=sys.stderr)
                continue

            for tag in filter(lambda t: t.startswith(("T", "COMM")), id3):
                frame = id3[tag]
                if isinstance(frame, mutagen.id3.TimeStampTextFrame):
                    # non-unicode fields
                    continue
                try:
                    text = frame.text
                except AttributeError:
                    continue
                try:
                    text = [conv(x) for x in frame.text]
                except (UnicodeError, LookupError):
                    continue
                else:
                    frame.text = text
                    if not text or min(map(isascii, text)):
                        frame.encoding = 3
                    else:
                        frame.encoding = 1

            if verbose == "debug":
                print_(id3.pprint())

            if not noupdate:
                if remove_v1:
                    id3.save(filename, v1=False)
                else:
                    id3.save(filename)
示例#16
0
def update(options, filenames):
    encoding = options.encoding or getpreferredencoding()
    verbose = options.verbose
    noupdate = options.noupdate
    force_v1 = options.force_v1
    remove_v1 = options.remove_v1

    def conv(uni):
        return uni.encode('iso-8859-1').decode(encoding)

    for filename in filenames:
        with _sig.block():
            if verbose != "quiet":
                print_(u"Updating", filename)

            if has_id3v1(filename) and not noupdate and force_v1:
                mutagen.id3.delete(filename, False, True)

            try:
                id3 = mutagen.id3.ID3(filename)
            except mutagen.id3.ID3NoHeaderError:
                if verbose != "quiet":
                    print_(u"No ID3 header found; skipping...")
                continue
            except Exception as err:
                print_(text_type(err), file=sys.stderr)
                continue

            for tag in filter(lambda t: t.startswith(("T", "COMM")), id3):
                frame = id3[tag]
                if isinstance(frame, mutagen.id3.TimeStampTextFrame):
                    # non-unicode fields
                    continue
                try:
                    text = frame.text
                except AttributeError:
                    continue
                try:
                    text = [conv(x) for x in frame.text]
                except (UnicodeError, LookupError):
                    continue
                else:
                    frame.text = text
                    if not text or min(map(isascii, text)):
                        frame.encoding = 3
                    else:
                        frame.encoding = 1

            if verbose == "debug":
                print_(id3.pprint())

            if not noupdate:
                if remove_v1:
                    id3.save(filename, v1=False)
                else:
                    id3.save(filename)
示例#17
0
 def split_audio_file(self, file=""):
     file_root, file_ext = os.path.splitext(file)
     file_format = file_ext.replace(".", "").lower()
     if file_format not in ["mp3", "m4a", "mp4"]:
         raise FileNotSupportedError(file_format)
     file_size = os.path.getsize(file)
     if file_size > self.MAX_CONVERT_FILE_SIZE:
         raise FileTooLargeError(file_size)
     file_parts = []
     if file_size <= self.MAX_TG_FILE_SIZE:
         if file_format == "mp3":
             file_parts.append(file)
         else:
             logger.info("Converting: %s", file)
             try:
                 sound = AudioSegment.from_file(file, file_format)
                 file_converted = file.replace(file_ext, ".mp3")
                 sound.export(file_converted, format="mp3")
                 del sound
                 gc.collect()
                 file_parts.append(file_converted)
             except (OSError, MemoryError) as exc:
                 gc.collect()
                 raise FileNotConvertedError
     else:
         logger.info("Splitting: %s", file)
         try:
             id3 = mutagen.id3.ID3(file, translate=False)
         except:
             id3 = None
         parts_number = file_size // self.MAX_TG_FILE_SIZE + 1
         try:
             sound = AudioSegment.from_file(file, file_format)
             part_size = len(sound) / parts_number
             for i in range(parts_number):
                 file_part = file.replace(
                     file_ext, ".part{}{}".format(str(i + 1), file_ext))
                 part = sound[part_size * i:part_size * (i + 1)]
                 part.export(file_part, format="mp3")
                 del part
                 gc.collect()
                 if id3:
                     try:
                         id3.save(file_part, v1=2, v2_version=4)
                     except:
                         pass
                 file_parts.append(file_part)
             # https://github.com/jiaaro/pydub/issues/135
             # https://github.com/jiaaro/pydub/issues/89#issuecomment-75245610
             del sound
             gc.collect()
         except (OSError, MemoryError) as exc:
             gc.collect()
             raise FileConvertedPartiallyError(file_parts)
     return file_parts
示例#18
0
def copy(src, dst, merge, write_v1=True, excluded_tags=None, verbose=False):
    """Returns 0 on success"""

    if excluded_tags is None:
        excluded_tags = []

    try:
        id3 = mutagen.id3.ID3(src, translate=False)
    except mutagen.id3.ID3NoHeaderError:
        print_(u"No ID3 header found in ", src, file=sys.stderr)
        return 1
    except Exception as err:
        print_(str(err), file=sys.stderr)
        return 1

    if verbose:
        print_(u"File", src, u"contains:", file=sys.stderr)
        print_(id3.pprint(), file=sys.stderr)

    for tag in excluded_tags:
        id3.delall(tag)

    if merge:
        try:
            target = mutagen.id3.ID3(dst, translate=False)
        except mutagen.id3.ID3NoHeaderError:
            # no need to merge
            pass
        except Exception as err:
            print_(str(err), file=sys.stderr)
            return 1
        else:
            for frame in id3.values():
                target.add(frame)

            id3 = target

    # if the source is 2.3 save it as 2.3
    if id3.version < (2, 4, 0):
        id3.update_to_v23()
        v2_version = 3
    else:
        id3.update_to_v24()
        v2_version = 4

    try:
        id3.save(dst, v1=(2 if write_v1 else 0), v2_version=v2_version)
    except Exception as err:
        print_(u"Error saving", dst, u":\n%s" % text_type(err),
               file=sys.stderr)
        return 1
    else:
        if verbose:
            print_(u"Successfully saved", dst, file=sys.stderr)
        return 0
示例#19
0
def update(options, filenames):
    encoding = options.encoding or locale.getpreferredencoding()
    verbose = options.verbose
    noupdate = options.noupdate
    force_v1 = options.force_v1
    remove_v1 = options.remove_v1

    def conv(uni):
        #return uni.encode('iso-8859-1').decode(encoding)
        return h2p(uni)

    for filename in filenames:
        if verbose != "quiet":
            print "Updating", filename

        if has_id3v1(filename) and not noupdate and force_v1:
            mutagen.id3.delete(filename, False, True)

        try: id3 = mutagen.id3.ID3(filename)
        except mutagen.id3.ID3NoHeaderError:
            if verbose != "quiet":
                print "No ID3 header found; skipping..."
            continue
        except Exception, err:
            if verbose != "quiet":
                print str(err)
            continue

        for tag in filter(lambda t: t.startswith("T"), id3):
            frame = id3[tag]
            if isinstance(frame, mutagen.id3.TimeStampTextFrame):
                # non-unicode fields
                continue
            try:
                text = frame.text
            except AttributeError:
                continue
            try:
                text = map(conv, frame.text)
            except (UnicodeError, LookupError):
                continue
            else:
                frame.text = text
                if not text or min(map(isascii, text)):
                    frame.encoding = 3
                else:
                    frame.encoding = 1

        enc = locale.getpreferredencoding()
        if verbose == "debug":
            print id3.pprint().encode(enc, "replace")

        if not noupdate:
            if remove_v1: id3.save(filename, v1=False)
            else: id3.save(filename)
示例#20
0
 def write_tags(self):
     """Write all ID3v2.4 tags by mapping dub2id3_dict dictionnary with the
         respect of mutagen classes and methods"""
     from mutagen import id3  
     id3 = id3.ID3(self.dest)
     for tag in self.metadata.keys():
         if tag in self.dub2id3_dict.keys():
             frame_text = self.dub2id3_dict[tag]
             value = self.metadata[tag]
             frame = mutagen.id3.Frames[frame_text](3,value)
             id3.add(frame)
     id3.save()
示例#21
0
    def test_merge_dst_no_tag(self):
        id3 = ID3(self.filename)
        id3.delete()
        id3.save(v2_version=3)

        with open(self.blank_file, "wb") as h:
            h.write(b"SOMEDATA")
        res, out, err = self.call2(
            self.filename, self.blank_file, fsn(u"--merge"))
        assert not any([res, out, err])

        result = ID3(self.blank_file)
        assert result.version == (2, 3, 0)
示例#22
0
文件: mp3.py 项目: MaiTiano/TimeSide
 def write_metadata(self):
     """Write all ID3v2.4 tags to file from self.metadata"""
     from mutagen import id3
     id3 = id3.ID3(self.filename)
     for tag in self.metadata.keys():
         value = self.metadata[tag]
         frame = mutagen.id3.Frames[tag](3,value)
         try:
             id3.add(frame)
         except:
             raise IOError('EncoderError: cannot tag "'+tag+'"')
     try:
         id3.save()
     except:
         raise IOError('EncoderError: cannot write tags')
示例#23
0
文件: mp3.py 项目: j-press/TimeSide
    def write_metadata(self):
        """Write all ID3v2.4 tags to file from self.metadata"""
        import mutagen
        from mutagen import id3

        id3 = id3.ID3(self.filename)
        for tag in self.metadata.keys():
            value = self.metadata[tag]
            frame = mutagen.id3.Frames[tag](3, value)
            try:
                id3.add(frame)
            except:
                raise IOError('EncoderError: cannot tag "' + tag + '"')
        try:
            id3.save()
        except:
            raise IOError('EncoderError: cannot write tags')
示例#24
0
    def test_unknown_chap(self):
        # add ctoc
        id3 = ID3(self.filename)
        id3.add(CTOC(element_id="foo", flags=3, child_element_ids=["ch0"],
                     sub_frames=[TIT2(encoding=3, text=["bla"])]))
        id3.save()

        # pretend we don't know ctoc and save
        id3 = ID3(self.filename, known_frames={"CTOC": CTOC})
        ctoc = id3.getall("CTOC")[0]
        self.assertFalse(ctoc.sub_frames)
        self.assertTrue(ctoc.sub_frames.unknown_frames)
        id3.save()

        # make sure we wrote all sub frames back
        id3 = ID3(self.filename)
        self.assertEqual(
            id3.getall("CTOC")[0].sub_frames.getall("TIT2")[0].text, ["bla"])
示例#25
0
    def test_unknown_chap(self):
        # add ctoc
        id3 = ID3(self.filename)
        id3.add(CTOC(element_id="foo", flags=3, child_element_ids=["ch0"],
                     sub_frames=[TIT2(encoding=3, text=["bla"])]))
        id3.save()

        # pretend we don't know ctoc and save
        id3 = ID3(self.filename, known_frames={"CTOC": CTOC})
        ctoc = id3.getall("CTOC")[0]
        self.assertFalse(ctoc.sub_frames)
        self.assertTrue(ctoc.sub_frames.unknown_frames)
        id3.save()

        # make sure we wrote all sub frames back
        id3 = ID3(self.filename)
        self.assertEqual(
            id3.getall("CTOC")[0].sub_frames.getall("TIT2")[0].text, ["bla"])
示例#26
0
def ape_to_id3(files, version=None):
    """
    Moves gain related tags from APEv2 to ID3v2, then deletes APEv2.

    :param files: list of files to act on
    :param version: ID3 tag version to save as (optional, tags will be ID3v2.4 if not provided)
    """

    for file in files:
        id3 = _get_mutagen_id3(file)
        ape = _get_mutagen_apev2(file)
        updated = add_to_id3(read_from_apev2(ape), id3)
        if updated > 0:
            print 'writing id3'
            id3.save(file)
        ape.delete(file)
        if version != None:
            pymp3utils.set_id3_version(file, version)
示例#27
0
    def test_merge(self):
        id3 = ID3(self.filename)
        id3.delete()
        id3.add(mutagen.id3.TALB(text=[u"foo"]))
        id3.save(v2_version=3)

        target = ID3()
        target.add(mutagen.id3.TPE1(text=[u"bar", u"quux"]))
        target.save(self.blank_file, v2_version=4)

        res, out, err = self.call2(
            self.filename, self.blank_file, fsn(u"--merge"))
        assert not any([res, out, err])

        result = ID3(self.blank_file)
        assert result.version == (2, 4, 0)
        assert result.getall("TALB")[0].text == [u"foo"]
        assert result.getall("TPE1")[0].text == [u"bar", u"quux"]
示例#28
0
文件: mp3.py 项目: MechanisM/TimeSide
 def write_tags(self):
     """Write all ID3v2.4 tags by mapping dub2id3_dict dictionnary with the
         respect of mutagen classes and methods"""
     from mutagen import id3
     id3 = id3.ID3(self.dest)
     for tag in self.metadata.keys():
         if tag in self.dub2id3_dict.keys():
             frame_text = self.dub2id3_dict[tag]
             value = self.metadata[tag]
             frame = mutagen.id3.Frames[frame_text](3,value)
             try:
                 id3.add(frame)
             except:
                 raise IOError('EncoderError: cannot tag "'+tag+'"')
     try:
         id3.save()
     except:
         raise IOError('EncoderError: cannot write tags')
示例#29
0
    for n,v in optList:
        if n in ('--artist'):
          artist = v
        if n in ('--album'):
          album = v

    for filePath in filePaths:
      print '* '+filePath
      if not artist and not album:
       id3 = ID3(filePath)
       print id3

      else:
          id3 = ID3(filePath)
          if album:
            id3.setAlbum(album)
          if artist:
            id3.setArtist(artist)
          id3.save()


    return 0

#-------------------------------------------------------------------------------
if __name__ == '__main__' or __name__ == sys.argv[0]:
    sys.exit(test(sys.argv))

#-------------------------------------------------------------------------------
# end
示例#30
0
      except mutagen.id3.ID3NoHeaderError:
        id3 = mutagen.id3.ID3()

    if ft == u'mp3':
      # adding new id3 frames
      id3.add(TIT2(encoding=3, text=disc.track_list[c].title))
      id3.add(TPE1(encoding=3, text=disc.track_list[c].artist))
      id3.add(TALB(encoding=3, text=disc.title))
      id3.add(TCOM(encoding=3, text=disc.artist))
      id3.add(TPUB(encoding=3, text=disc.label))
      id3.add(TDRC(encoding=3, text=disc.year))
      id3.add(TXXX(encoding=3, desc='Catalog #', text=disc.cat_num))
      id3.add(TCON(encoding=3, text=disc.genre))
      id3.add(TRCK(encoding=3, text=str(disc.track_list[c][0]) + "/" + tot))
      id3.pprint()
      id3.save(f,0)
    elif ft == u'flac':
      disc.track_list[c].title
      audio["TITLE"] = disc.track_list[c].title
      audio["ARTIST"] = disc.track_list[c].artist.artistString
      audio["ALBUM"] = disc.title
      audio["COMPOSER"] = disc.artist.artistString
      audio["ORGANIZATION"] = disc.label
      audio["CATALOGNUM"] = disc.cat_num
      audio["GENRE"] = disc.genre
      if(len(disc.style) != 0):
        audio["STYLE"] = disc.style
      audio["YEAR"] = disc.year
      audio["DATE"] = disc.date
      audio["TRACKNUMBER"] = str(disc.track_list[c].position)
      audio["TRACKTOTAL"] = tot
示例#31
0
文件: scdlbot.py 项目: ZubAnt/scdlbot
 def split_and_send_audio_file(self,
                               bot,
                               chat_id,
                               reply_to_message_id=None,
                               file=""):
     sent_audio_ids = []
     file_root, file_ext = os.path.splitext(file)
     file_name = os.path.split(file)[-1]
     file_format = file_ext.replace(".", "")
     if not (file_format == "mp3" or file_format == "m4a"
             or file_format == "mp4"):
         logger.warning("Unsupported file format: %s", file_name)
         bot.send_message(
             chat_id=chat_id,
             reply_to_message_id=reply_to_message_id,
             text=
             "*Sorry*, downloaded file `{}` is in format I could not yet send or convert"
             .format(file_name),
             parse_mode='Markdown')
         return "format"
     file_size = os.path.getsize(file)
     if file_size > self.MAX_CONVERT_FILE_SIZE:
         logger.warning("Large file for convert: %s", file_name)
         bot.send_message(
             chat_id=chat_id,
             reply_to_message_id=reply_to_message_id,
             text=
             "*Sorry*, downloaded file `{}` is larger than I could convert".
             format(file_name),
             parse_mode='Markdown')
         return "size"
     parts_number = 1
     file_parts = []
     if file_size <= self.MAX_TG_FILE_SIZE:
         file_parts.append(file)
     else:
         logger.info("Splitting: %s", file_name)
         try:
             id3 = mutagen.id3.ID3(file, translate=False)
         except:
             id3 = None
         parts_number = file_size // self.MAX_TG_FILE_SIZE + 1
         try:
             sound = AudioSegment.from_file(file, file_format)
             part_size = len(sound) / parts_number
             for i in range(parts_number):
                 file_part = file.replace(file_ext,
                                          ".part" + str(i + 1) + file_ext)
                 part = sound[part_size * i:part_size * (i + 1)]
                 part.export(file_part, format="mp3")
                 del part
                 if id3:
                     id3.save(file_part, v1=2, v2_version=4)
                 file_parts.append(file_part)
             # https://github.com/jiaaro/pydub/issues/135
             # https://github.com/jiaaro/pydub/issues/89#issuecomment-75245610
             del sound
             gc.collect()
         except (OSError, MemoryError) as exc:
             text = "Failed pydub convert"
             logger.exception(text)
             self.send_alert(bot, text + "\n" + str(exc), file_name)
             bot.send_message(
                 chat_id=chat_id,
                 reply_to_message_id=reply_to_message_id,
                 text=
                 "*Sorry*, not enough memory to convert file `{}`, you may try again later.."
                 .format(file_name),
                 parse_mode='Markdown')
             gc.collect()
             return "memory"
     file_parts_copy = list(file_parts)
     for index, file in enumerate(file_parts):
         logger.info("Sending: %s", file_name)
         bot.send_chat_action(chat_id=chat_id,
                              action=ChatAction.UPLOAD_AUDIO)
         # file = translit(file, 'ru', reversed=True)
         caption = ""
         if file_size > self.MAX_TG_FILE_SIZE:
             caption += "\n" + " ".join(
                 ["Part", str(index + 1), "of",
                  str(parts_number)])
         for i in range(3):
             try:
                 if (i == 0) and (chat_id not in self.NO_CLUTTER_CHAT_IDS):
                     caption = "Downloaded with @{}".format(
                         self.bot_username) + caption
                 audio_msg = bot.send_audio(
                     chat_id=chat_id,
                     reply_to_message_id=reply_to_message_id,
                     audio=open(file, 'rb'),
                     caption=caption)
                 sent_audio_ids.append(audio_msg.audio.file_id)
                 file_parts_copy.remove(file)
                 logger.info("Sending success: %s", file_name)
                 break
             except TelegramError as exc:
                 logger.exception(
                     "Sending failed because of TelegramError: %s",
                     file_name)
                 self.send_alert(bot, "TelegramError:\n" + str(exc),
                                 file_name)
     if not file_parts_copy:
         return "success"
     else:
         logger.warning("Sending total failed: %s", file_name)
         return "send"
示例#32
0
         if value.encoding==0:
             if isinstance(value.text, list):
                 try:
                     bytes= '\n'.join(value.text).encode('iso-8859-1')
                 except TypeError as e:
                     if 'expected str instance, ID3TimeStamp found' in str(e):
                         # TODO: too many different kinds of info avail inside value.text
                         # What are they? How to treat them good?
                         print('ID3TimeStamp found. Skipping ', value.text)
                         continue  
             else:
                 bytes= value.text.encode('iso-8859-1')
             for encoding in tryencodings:
                 try:
                     bytes.decode(encoding)
                     print(f'Succeed with {encoding}')
                 except UnicodeError:
                     pass
                 else:
                     break
             else:
                 raise ValueError(
             'None of the tryencodings work for %r key %r' % (path, key))
             if isinstance(value.text, list):
                 for i in range(len(value.text)):
                     value.text[i]= value.text[i].encode('iso-8859-1').decode(encoding)
             else:
                 value.text = value.text.encode('iso-8859-1').decode(encoding)
         value.encoding= 3
 id3.save()
 print(id3)
示例#33
0
        id3.loaded_frame(frame)
        trackgain = float(rg["REPLAYGAIN_TRACK_GAIN"][0].split(" ")[0])
        if "REPLAYGAIN_TRACK_PEAK" in rg:
            frame = mutagen.id3.Frames["TXXX"](
                encoding=3, desc="replaygain_track_peak", text=rg["REPLAYGAIN_TRACK_PEAK"][0]
            )
            id3.loaded_frame(frame)
            trackpeak = float(rg["REPLAYGAIN_TRACK_PEAK"][0])
            frame = mutagen.id3.Frames["RVA2"](desc="track", channel=1, gain=trackgain, peak=trackpeak)
            id3.loaded_frame(frame)
        else:
            frame = mutagen.id3.Frames["RVA2"](desc="track", channel=1, gain=trackgain)
            id3.loaded_frame(frame)

    try:
        id3.save(file)
    except Exception, err:
        print str(err)
        return 0
    return 1


def removeape(file):
    mutagen.apev2.delete(file)


from mutagen.id3 import ID3, COMM, RVA2


def gain_to_watts(gain):
    return pow(10, -gain * 0.1)
def write_files(edits, filenames, escape):
    # unescape escape sequences and decode values
    encoded_edits = []
    for frame, value in edits:
        if not value:
            continue

        try:
            frame = frame_from_fsnative(frame)
        except ValueError as err:
            print_(text_type(err), file=sys.stderr)

        assert isinstance(frame, str)

        # strip "--"
        frame = frame[2:]

        try:
            value = value_from_fsnative(value, escape)
        except ValueError as err:
            error(u"%s: %s" % (frame, text_type(err)))

        assert isinstance(value, text_type)

        encoded_edits.append((frame, value))
    edits = encoded_edits

    # preprocess:
    #   for all [frame,value] pairs in the edits list
    #      gather values for identical frames into a list
    tmp = {}
    for frame, value in edits:
        if frame in tmp:
            tmp[frame].append(value)
        else:
            tmp[frame] = [value]
    # edits is now a dictionary of frame -> [list of values]
    edits = tmp

    # escape also enables escaping of the split separator
    if escape:
        string_split = split_escape
    else:
        string_split = lambda s, *args, **kwargs: s.split(*args, **kwargs)

    for filename in filenames:
        with _sig.block():
            if verbose:
                print_(u"Writing", filename, file=sys.stderr)
            try:
                id3 = mutagen.id3.ID3(filename)
            except mutagen.id3.ID3NoHeaderError:
                if verbose:
                    print_(u"No ID3 header found; creating a new tag",
                           file=sys.stderr)
                id3 = mutagen.id3.ID3()
            except Exception as err:
                print_(str(err), file=sys.stderr)
                continue
            for (frame, vlist) in edits.items():
                if frame == "POPM":
                    for value in vlist:
                        values = string_split(value, ":")
                        if len(values) == 1:
                            email, rating, count = values[0], 0, 0
                        elif len(values) == 2:
                            email, rating, count = values[0], values[1], 0
                        else:
                            email, rating, count = values

                        frame = mutagen.id3.POPM(email=email,
                                                 rating=int(rating),
                                                 count=int(count))
                        id3.add(frame)
                elif frame == "APIC":
                    for value in vlist:
                        values = string_split(value, ":")
                        # FIXME: doesn't support filenames with an invalid
                        # encoding since we have already decoded at that point
                        fn = values[0]

                        if len(values) >= 2:
                            desc = values[1]
                        else:
                            desc = u"cover"

                        if len(values) >= 3:
                            try:
                                picture_type = int(values[2])
                            except ValueError:
                                error(u"Invalid picture type: %r" % values[1])
                        else:
                            picture_type = PictureType.COVER_FRONT

                        if len(values) >= 4:
                            mime = values[3]
                        else:
                            mime = mimetypes.guess_type(fn)[0] or "image/jpeg"

                        if len(values) >= 5:
                            error("APIC: Invalid format")

                        encoding = get_frame_encoding(frame, desc)

                        try:
                            with open(fn, "rb") as h:
                                data = h.read()
                        except IOError as e:
                            error(text_type(e))

                        frame = mutagen.id3.APIC(encoding=encoding,
                                                 mime=mime,
                                                 desc=desc,
                                                 type=picture_type,
                                                 data=data)

                        id3.add(frame)
                elif frame == "COMM":
                    for value in vlist:
                        values = string_split(value, ":")
                        if len(values) == 1:
                            value, desc, lang = values[0], "", "eng"
                        elif len(values) == 2:
                            desc, value, lang = values[0], values[1], "eng"
                        else:
                            value = ":".join(values[1:-1])
                            desc, lang = values[0], values[-1]
                        frame = mutagen.id3.COMM(encoding=3,
                                                 text=value,
                                                 lang=lang,
                                                 desc=desc)
                        id3.add(frame)
                elif frame == "UFID":
                    for value in vlist:
                        values = string_split(value, ":")
                        if len(values) != 2:
                            error(u"Invalid value: %r" % values)
                        owner = values[0]
                        data = values[1].encode("utf-8")
                        frame = mutagen.id3.UFID(owner=owner, data=data)
                        id3.add(frame)
                elif frame == "TXXX":
                    for value in vlist:
                        values = string_split(value, ":", 1)
                        if len(values) == 1:
                            desc, value = "", values[0]
                        else:
                            desc, value = values[0], values[1]
                        frame = mutagen.id3.TXXX(encoding=3,
                                                 text=value,
                                                 desc=desc)
                        id3.add(frame)
                elif issubclass(mutagen.id3.Frames[frame],
                                mutagen.id3.UrlFrame):
                    frame = mutagen.id3.Frames[frame](encoding=3, url=vlist)
                    id3.add(frame)
                else:
                    frame = mutagen.id3.Frames[frame](encoding=3, text=vlist)
                    id3.add(frame)
            id3.save(filename)
示例#35
0
    def _download \
            (
                self,
                song_id,
                metadata  = None,
                thumbnail = None,
                directory = None,
                video     = False,
            ):
        '''
        '''

        import mutagen.easyid3
        import mutagen.id3
        import mutagen.mp4
        import mutagen.easymp4
        import youtube_dl

        file_name_format = '%(title)s.%(ext)s'

        if not metadata:
            metadata = {}

        if directory:
            path_directory = pathlib.Path(directory)
        else:
            path_directory = pathlib.Path(os.getcwd())

        path_file = path_directory.joinpath(file_name_format)

        post_processors = []

        if video:
            format = 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]'
            to_ext = 'mp4'
        else:
            format = 'bestaudio'
            to_ext = 'mp3'

            post_processors.append \
            (
                {
                    'key': 'FFmpegExtractAudio',
                    'preferredcodec': to_ext,
                }
            )

        ytdl = youtube_dl.YoutubeDL \
        (
            params = \
            {
                'quiet':          True,
                'outtmpl':        str(path_file),
                'postprocessors': post_processors,
                'format':         format,
            }
        )

        url = utils.url_yt \
        (
            'watch',
            params = {'v': song_id},
        )

        info = ytdl.extract_info \
        (
            url      = url,
            ie_key   = 'Youtube',
            download = True,
        )

        any_title = info.get('track', info.get('title'))
        metadata = utils.filter \
        (
            {
                'title':       any_title,
                'artist':      info.get('artist'),
                'album':       info.get('album'),
                'albumartist': info.get('artist'),
                'discnumber':  '1',
                'tracknumber': '1',
                'date':        str(info.get('release_year')),
                **metadata,
            }
        )
        info.setdefault('track', any_title)

        file_path_src = self._get_file_path \
        (
            info,
            file_name_format % \
            {
                'title': info.get('title'),
                'ext': to_ext,
            },
            directory,
        )

        file_path_dst = file_path_src.parent.joinpath \
        (
            file_name_format % \
            {
                'title': info.get('title'),
                'ext':   to_ext,
            }
        )

        if not thumbnail:
            thumbnail = self._get_album_art(info['thumbnails'][0]['url'], crop=True)

        if video:
            mp4 = mutagen.mp4.MP4(file_path_dst)

            cover = mutagen.mp4.MP4Cover \
            (
                thumbnail,
                imageformat = mutagen.mp4.AtomDataType.PNG,
            )

            mp4['covr'] = (cover,)

            mp4.save()

            easymp4 = mutagen.easymp4.EasyMP4(file_path_dst)

            easymp4.update(metadata)

            easymp4.save()
        else:
            id3 = mutagen.id3.ID3(file_path_dst)

            ENCODING_UTF8 = 3
            MIME_PNG  = 'image/png'
            IMAGE_TYPE_COVER = 3
            IMAGE_DESCRIPTION_COVER = 'Cover'

            id3.add \
            (
                mutagen.id3.APIC
                (
                    encoding = ENCODING_UTF8,
                    mime     = MIME_PNG,
                    type     = IMAGE_TYPE_COVER,
                    desc     = IMAGE_DESCRIPTION_COVER,
                    data     = thumbnail,
                )
            )

            id3.save(v2_version = 3)

            easyid3 = mutagen.easyid3.EasyID3(file_path_dst)

            easyid3.update(metadata)

            easyid3.save(v2_version = 3)

        # Rename to {track}.{ext} here?

        success = not ytdl._download_retcode

        if success:
            return info
示例#36
0
def write_files(edits, filenames, escape):
    # unescape escape sequences and decode values
    encoded_edits = []
    for frame, value in edits:
        if not value:
            continue

        try:
            frame = frame_from_fsnative(frame)
        except ValueError as err:
            print_(text_type(err), file=sys.stderr)

        assert isinstance(frame, str)

        # strip "--"
        frame = frame[2:]

        try:
            value = value_from_fsnative(value, escape)
        except ValueError as err:
            error(u"%s: %s" % (frame, text_type(err)))

        assert isinstance(value, text_type)

        encoded_edits.append((frame, value))
    edits = encoded_edits

    # preprocess:
    #   for all [frame,value] pairs in the edits list
    #      gather values for identical frames into a list
    tmp = {}
    for frame, value in edits:
        if frame in tmp:
            tmp[frame].append(value)
        else:
            tmp[frame] = [value]
    # edits is now a dictionary of frame -> [list of values]
    edits = tmp

    # escape also enables escaping of the split separator
    if escape:
        string_split = split_escape
    else:
        string_split = lambda s, *args, **kwargs: s.split(*args, **kwargs)

    for filename in filenames:
        with _sig.block():
            if verbose:
                print_(u"Writing", filename, file=sys.stderr)
            try:
                id3 = mutagen.id3.ID3(filename)
            except mutagen.id3.ID3NoHeaderError:
                if verbose:
                    print_(u"No ID3 header found; creating a new tag",
                          file=sys.stderr)
                id3 = mutagen.id3.ID3()
            except Exception as err:
                print_(str(err), file=sys.stderr)
                continue
            for (frame, vlist) in edits.items():
                if frame == "POPM":
                    for value in vlist:
                        values = string_split(value, ":")
                        if len(values) == 1:
                            email, rating, count = values[0], 0, 0
                        elif len(values) == 2:
                            email, rating, count = values[0], values[1], 0
                        else:
                            email, rating, count = values

                        frame = mutagen.id3.POPM(
                            email=email, rating=int(rating), count=int(count))
                        id3.add(frame)
                elif frame == "APIC":
                    for value in vlist:
                        values = string_split(value, ":")
                        # FIXME: doesn't support filenames with an invalid
                        # encoding since we have already decoded at that point
                        fn = values[0]

                        if len(values) >= 2:
                            desc = values[1]
                        else:
                            desc = u"cover"

                        if len(values) >= 3:
                            try:
                                picture_type = int(values[2])
                            except ValueError:
                                error(u"Invalid picture type: %r" % values[1])
                        else:
                            picture_type = PictureType.COVER_FRONT

                        if len(values) >= 4:
                            mime = values[3]
                        else:
                            mime = mimetypes.guess_type(fn)[0] or "image/jpeg"

                        if len(values) >= 5:
                            error("APIC: Invalid format")

                        encoding = get_frame_encoding(frame, desc)

                        try:
                            with open(fn, "rb") as h:
                                data = h.read()
                        except IOError as e:
                            error(text_type(e))

                        frame = mutagen.id3.APIC(encoding=encoding, mime=mime,
                            desc=desc, type=picture_type, data=data)

                        id3.add(frame)
                elif frame == "COMM":
                    for value in vlist:
                        values = string_split(value, ":")
                        if len(values) == 1:
                            value, desc, lang = values[0], "", "eng"
                        elif len(values) == 2:
                            desc, value, lang = values[0], values[1], "eng"
                        else:
                            value = ":".join(values[1:-1])
                            desc, lang = values[0], values[-1]
                        frame = mutagen.id3.COMM(
                            encoding=3, text=value, lang=lang, desc=desc)
                        id3.add(frame)
                elif frame == "USLT":
                    for value in vlist:
                        values = string_split(value, ":")
                        if len(values) == 1:
                            value, desc, lang = values[0], "", "eng"
                        elif len(values) == 2:
                            desc, value, lang = values[0], values[1], "eng"
                        else:
                            value = ":".join(values[1:-1])
                            desc, lang = values[0], values[-1]
                        frame = mutagen.id3.USLT(
                            encoding=3, text=value, lang=lang, desc=desc)
                        id3.add(frame)
                elif frame == "UFID":
                    for value in vlist:
                        values = string_split(value, ":")
                        if len(values) != 2:
                            error(u"Invalid value: %r" % values)
                        owner = values[0]
                        data = values[1].encode("utf-8")
                        frame = mutagen.id3.UFID(owner=owner, data=data)
                        id3.add(frame)
                elif frame == "TXXX":
                    for value in vlist:
                        values = string_split(value, ":", 1)
                        if len(values) == 1:
                            desc, value = "", values[0]
                        else:
                            desc, value = values[0], values[1]
                        frame = mutagen.id3.TXXX(
                            encoding=3, text=value, desc=desc)
                        id3.add(frame)
                elif frame == "WXXX":
                    for value in vlist:
                        values = string_split(value, ":", 1)
                        if len(values) == 1:
                            desc, value = "", values[0]
                        else:
                            desc, value = values[0], values[1]
                        frame = mutagen.id3.WXXX(
                            encoding=3, url=value, desc=desc)
                        id3.add(frame)
                elif issubclass(mutagen.id3.Frames[frame],
                                mutagen.id3.UrlFrame):
                    frame = mutagen.id3.Frames[frame](
                        encoding=3, url=vlist[-1])
                    id3.add(frame)
                else:
                    frame = mutagen.id3.Frames[frame](encoding=3, text=vlist)
                    id3.add(frame)
            id3.save(filename)