Ejemplo n.º 1
0
def _shorten_to_bytes_length(text, length):
    """Truncates a unicode object to the given number of bytes it would take
    when encoded in the "filesystem encoding".
    """
    assert isinstance(text, str), "This function only works on unicode"
    raw = encode_filename(text)
    # maybe there's no need to truncate anything
    if len(raw) <= length:
        return text
    # or maybe there's nothing multi-byte here
    if len(raw) == len(text):
        return text[:length]
    # if we're dealing with utf-8, we can use an efficient algorithm
    # to deal with character boundaries
    if _re_utf8.match(_io_encoding):
        i = length
        # a UTF-8 intermediate byte starts with the bits 10xxxxxx,
        # so ord(char) & 0b11000000 = 0b10000000
        while i > 0 and (raw[i] & 0xC0) == 0x80:
            i -= 1
        return decode_filename(raw[:i])
    # finally, a brute force approach
    i = length
    while i > 0:
        try:
            return decode_filename(raw[:i])
        except UnicodeDecodeError:
            pass
        i -= 1
    # hmm. we got here?
    return u""
Ejemplo n.º 2
0
def _shorten_to_bytes_length(text, length):
    """Truncates a unicode object to the given number of bytes it would take
    when encoded in the "filesystem encoding".
    """
    assert isinstance(text, unicode), "This function only works on unicode"
    raw = encode_filename(text)
    # maybe there's no need to truncate anything
    if len(raw) <= length:
        return text
    # or maybe there's nothing multi-byte here
    if len(raw) == len(text):
        return text[:length]
    # if we're dealing with utf-8, we can use an efficient algorithm
    # to deal with character boundaries
    if _re_utf8.match(_io_encoding):
        i = length
        # a UTF-8 intermediate byte starts with the bits 10xxxxxx,
        # so ord(char) & 0b11000000 = 0b10000000
        while i > 0 and (ord(raw[i]) & 0xC0) == 0x80:
            i -= 1
        return decode_filename(raw[:i])
    # finally, a brute force approach
    i = length
    while i > 0:
        try:
            return decode_filename(raw[:i])
        except UnicodeDecodeError:
            pass
        i -= 1
    # hmm. we got here?
    return u""
Ejemplo n.º 3
0
 def _run_init(self):
     if self._cmdline_files:
         files = []
         for file in self._cmdline_files:
             if os.path.isdir(file):
                 self.add_directory(decode_filename(file))
             else:
                 files.append(decode_filename(file))
         if files:
             self.add_files(files)
         del self._cmdline_files
Ejemplo n.º 4
0
 def _run_init(self):
     if self._args:
         files = []
         for file in self._args:
             if os.path.isdir(file):
                 self.add_directory(decode_filename(file))
             else:
                 files.append(decode_filename(file))
         if files:
             self.add_files(files)
         del self._args
Ejemplo n.º 5
0
 def _next_filename(self, filename, counters):
     if counters[filename]:
         new_filename = "%s (%d)" % (decode_filename(filename), counters[filename])
     else:
         new_filename = filename
     counters[filename] += 1
     return encode_filename(new_filename)
Ejemplo n.º 6
0
Archivo: file.py Proyecto: Freso/picard
 def _move_additional_files(self, old_filename, new_filename):
     """Move extra files, like playlists..."""
     old_path = encode_filename(os.path.dirname(old_filename))
     new_path = encode_filename(os.path.dirname(new_filename))
     patterns = encode_filename(config.setting["move_additional_files_pattern"])
     patterns = filter(bool, [p.strip() for p in patterns.split()])
     try:
         names = os.listdir(old_path)
     except os.error:
         log.error("Error: {} directory not found".format(old_path))
         return
     filtered_names = filter(lambda x: x[0] != '.', names)
     for pattern in patterns:
         pattern_regex = re.compile(fnmatch.translate(pattern), re.IGNORECASE)
         file_names = names
         if pattern[0] != '.':
             file_names = filtered_names
         for old_file in file_names:
             if pattern_regex.match(old_file):
                 new_file = os.path.join(new_path, old_file)
                 old_file = os.path.join(old_path, old_file)
                 # FIXME we shouldn't do this from a thread!
                 if self.tagger.files.get(decode_filename(old_file)):
                     log.debug("File loaded in the tagger, not moving %r", old_file)
                     continue
                 log.debug("Moving %r to %r", old_file, new_file)
                 shutil.move(old_file, new_file)
Ejemplo n.º 7
0
 def _move_additional_files(self, old_filename, new_filename):
     """Move extra files, like playlists..."""
     old_path = os.path.dirname(old_filename)
     new_path = os.path.dirname(new_filename)
     try:
         names = os.listdir(old_path)
     except os.error:
         log.error("Error: {} directory not found".naming_format(old_path))
         return
     filtered_names = [name for name in names if name[0] != "."]
     for pattern in config.setting["move_additional_files_pattern"].split():
         pattern = pattern.strip()
         if not pattern:
             continue
         pattern_regex = re.compile(fnmatch.translate(pattern),
                                    re.IGNORECASE)
         file_names = names
         if pattern[0] != '.':
             file_names = filtered_names
         for old_file in file_names:
             if pattern_regex.match(old_file):
                 new_file = os.path.join(new_path, old_file)
                 old_file = os.path.join(old_path, old_file)
                 # FIXME we shouldn't do this from a thread!
                 if self.tagger.files.get(decode_filename(old_file)):
                     log.debug("File loaded in the tagger, not moving %r",
                               old_file)
                     continue
                 log.debug("Moving %r to %r", old_file, new_file)
                 shutil.move(old_file, new_file)
Ejemplo n.º 8
0
 def process_directory_listing(self, root, queue, result=None, error=None):
     try:
         # Read directory listing
         if result is not None and error is None:
             files = []
             directories = deque()
             try:
                 for path in result:
                     path = os.path.join(root, path)
                     if os.path.isdir(path):
                         directories.appendleft(path)
                     else:
                         try:
                             files.append(decode_filename(path))
                         except UnicodeDecodeError:
                             self.log.warning(
                                 "Failed to decode filename: %r", path)
                             continue
             finally:
                 if files:
                     self.add_files(files)
                 queue.extendleft(directories)
     finally:
         # Scan next directory in the queue
         try:
             path = queue.popleft()
         except IndexError:
             pass
         else:
             self.other_queue.put(
                 (partial(os.listdir, path),
                  partial(self.process_directory_listing, path,
                          queue), QtCore.Qt.LowEventPriority))
Ejemplo n.º 9
0
 def _move_additional_files(self, old_filename, new_filename):
     """Move extra files, like playlists..."""
     old_path = encode_filename(os.path.dirname(old_filename))
     new_path = encode_filename(os.path.dirname(new_filename))
     patterns = encode_filename(
         config.setting["move_additional_files_pattern"])
     patterns = filter(bool, [p.strip() for p in patterns.split()])
     try:
         names = os.listdir(old_path)
     except os.error:
         log.error("Error: {} directory not found".format(old_path))
         return
     filtered_names = filter(lambda x: x[0] != '.', names)
     for pattern in patterns:
         pattern_regex = re.compile(fnmatch.translate(pattern),
                                    re.IGNORECASE)
         file_names = names
         if pattern[0] != '.':
             file_names = filtered_names
         for old_file in file_names:
             if pattern_regex.match(old_file):
                 old_file = os.path.join(old_path, old_file)
                 # FIXME we shouldn't do this from a thread!
                 if self.tagger.files.get(decode_filename(old_file)):
                     log.debug("File loaded in the tagger, not moving %r",
                               old_file)
                     continue
                 new_file = os.path.join(new_path, old_file)
                 log.debug("Moving %r to %r", old_file, new_file)
                 shutil.move(old_file, new_file)
Ejemplo n.º 10
0
 def _next_filename(self, filename, counters):
     if counters[filename]:
         new_filename = "%s (%d)" % (decode_filename(filename), counters[filename])
     else:
         new_filename = filename
     counters[filename] += 1
     return encode_filename(new_filename)
Ejemplo n.º 11
0
 def process_directory_listing(self, root, queue, result=None, error=None):
     try:
         # Read directory listing
         if result is not None and error is None:
             files = []
             directories = deque()
             try:
                 for path in result:
                     path = os.path.join(root, path)
                     if os.path.isdir(path):
                         directories.appendleft(path)
                     else:
                         try:
                             files.append(decode_filename(path))
                         except UnicodeDecodeError:
                             self.log.warning("Failed to decode filename: %r", path)
                             continue
             finally:
                 if files:
                     self.add_files(files)
                 queue.extendleft(directories)
     finally:
         # Scan next directory in the queue
         try:
             path = queue.popleft()
         except IndexError:
             pass
         else:
             self.other_queue.put(
                 (
                     partial(os.listdir, path),
                     partial(self.process_directory_listing, path, queue),
                     QtCore.Qt.LowEventPriority,
                 )
             )
Ejemplo n.º 12
0
Archivo: file.py Proyecto: mineo/picard
 def _move_additional_files(self, old_filename, new_filename):
     """Move extra files, like playlists..."""
     old_path = os.path.dirname(old_filename)
     new_path = os.path.dirname(new_filename)
     try:
         names = set(os.listdir(old_path))
     except os.error:
         log.error("Error: {} directory not found".naming_format(old_path))
         return
     filtered_names = {name for name in names if name[0] != "."}
     for pattern in config.setting["move_additional_files_pattern"].split():
         pattern = pattern.strip()
         if not pattern:
             continue
         pattern_regex = re.compile(fnmatch.translate(pattern), re.IGNORECASE)
         file_names = names
         if pattern[0] != '.':
             file_names = filtered_names
         for old_file in set(file_names):
             if pattern_regex.match(old_file):
                 names.discard(old_file)
                 filtered_names.discard(old_file)
                 new_file = os.path.join(new_path, old_file)
                 old_file = os.path.join(old_path, old_file)
                 # FIXME we shouldn't do this from a thread!
                 if self.tagger.files.get(decode_filename(old_file)):
                     log.debug("File loaded in the tagger, not moving %r", old_file)
                     continue
                 log.debug("Moving %r to %r", old_file, new_file)
                 shutil.move(old_file, new_file)
Ejemplo n.º 13
0
def calculate_replay_gain_for_files(files, format, tagger):
    """Calculates the replay gain for a list of files in album mode."""
    file_list = ['%s' % encode_filename(f.filename) for f in files]

    if format in REPLAYGAIN_COMMANDS \
        and tagger.config.setting[REPLAYGAIN_COMMANDS[format][0]]:
        command = tagger.config.setting[REPLAYGAIN_COMMANDS[format][0]]
        options = tagger.config.setting[REPLAYGAIN_COMMANDS[format][1]].split(' ')
        tagger.log.debug('%s %s %s' % (command, ' '.join(options), decode_filename(' '.join(file_list))))
        check_call([command] + options + file_list)
    else:
        raise Exception('ReplayGain: Unsupported format %s' % (format))
Ejemplo n.º 14
0
 def _apply_additional_files_moves(self, moves):
     for old_file_path, new_file_path in moves:
         # FIXME we shouldn't do this from a thread!
         if self.tagger.files.get(decode_filename(old_file_path)):
             log.debug("File loaded in the tagger, not moving %r",
                       old_file_path)
             continue
         log.debug("Moving %r to %r", old_file_path, new_file_path)
         try:
             shutil.move(old_file_path, new_file_path)
         except OSError as why:
             log.error("Failed to move %r to %r: %s", old_file_path,
                       new_file_path, why)
Ejemplo n.º 15
0
def generate_moodbar_for_files(files, format, tagger):
    """Generate the moodfiles for a list of files in album mode."""
    file_list = ['%s' % encode_filename(f.filename) for f in files]
    for mood_file in file_list:
        new_filename = os.path.join(
            os.path.dirname(mood_file),
            '.' + os.path.splitext(os.path.basename(mood_file))[0] + '.mood')
        # file format to make it compaitble with Amarok and hidden in linux
        file_list_mood = ['%s' % new_filename]

    if format in MOODBAR_COMMANDS \
            and tagger.config.setting[MOODBAR_COMMANDS[format][0]]:
        command = tagger.config.setting[MOODBAR_COMMANDS[format][0]]
        options = tagger.config.setting[MOODBAR_COMMANDS[format][1]].split(' ')
        #        tagger.log.debug('My debug >>>  %s' % (file_list_mood))
        tagger.log.debug(
            '%s %s %s %s' %
            (command, decode_filename(' '.join(file_list)), ' '.join(options),
             decode_filename(' '.join(file_list_mood))))
        check_call([command] + file_list + options + file_list_mood)
    else:
        raise Exception('Moodbar: Unsupported format %s' % (format))
Ejemplo n.º 16
0
    def _move_additional_files(self, old_filename, new_filename):
        """Move extra files, like images, playlists..."""
        new_path = os.path.dirname(new_filename)
        old_path = os.path.dirname(old_filename)
        if new_path == old_path:
            # skip, same directory, nothing to move
            return
        config = get_config()
        patterns = config.setting["move_additional_files_pattern"]
        pattern_regexes = set()
        for pattern in patterns.split():
            pattern = pattern.strip()
            if not pattern:
                continue
            pattern_regex = re.compile(fnmatch.translate(pattern),
                                       re.IGNORECASE)
            match_hidden = pattern.startswith('.')
            pattern_regexes.add((pattern_regex, match_hidden))
        if not pattern_regexes:
            return
        moves = set()
        try:
            # TODO: use with statement with python 3.6+
            for entry in os.scandir(old_path):
                is_hidden = entry.name.startswith('.')
                for pattern_regex, match_hidden in pattern_regexes:
                    if is_hidden and not match_hidden:
                        continue
                    if pattern_regex.match(entry.name):
                        new_file_path = os.path.join(new_path, entry.name)
                        moves.add((entry.path, new_file_path))
                        break  # we are done with this file
        except OSError as why:
            log.error("Failed to scan %r: %s", old_path, why)
            return

        for old_file_path, new_file_path in moves:
            # FIXME we shouldn't do this from a thread!
            if self.tagger.files.get(decode_filename(old_file_path)):
                log.debug("File loaded in the tagger, not moving %r",
                          old_file_path)
                continue
            log.debug("Moving %r to %r", old_file_path, new_file_path)
            try:
                shutil.move(old_file_path, new_file_path)
            except OSError as why:
                log.error("Failed to move %r to %r: %s", old_file_path,
                          new_file_path, why)
Ejemplo n.º 17
0
 def _move_additional_files(self, old_filename, new_filename):
     """Move extra files, like playlists..."""
     old_path = encode_filename(os.path.dirname(old_filename))
     new_path = encode_filename(os.path.dirname(new_filename))
     patterns = encode_filename(config.setting["move_additional_files_pattern"])
     patterns = filter(bool, [p.strip() for p in patterns.split()])
     for pattern in patterns:
         # FIXME glob1 is not documented, maybe we need our own implemention?
         for old_file in glob.glob1(old_path, pattern):
             new_file = os.path.join(new_path, old_file)
             old_file = os.path.join(old_path, old_file)
             # FIXME we shouldn't do this from a thread!
             if self.tagger.files.get(decode_filename(old_file)):
                 log.debug("File loaded in the tagger, not moving %r", old_file)
                 continue
             log.debug("Moving %r to %r", old_file, new_file)
             shutil.move(old_file, new_file)
Ejemplo n.º 18
0
 def _move_additional_files(self, old_filename, new_filename):
     """Move extra files, like playlists..."""
     old_path = encode_filename(os.path.dirname(old_filename))
     new_path = encode_filename(os.path.dirname(new_filename))
     patterns = encode_filename(config.setting["move_additional_files_pattern"])
     patterns = filter(bool, [p.strip() for p in patterns.split()])
     for pattern in patterns:
         # FIXME glob1 is not documented, maybe we need our own implemention?
         for old_file in glob.glob1(old_path, pattern):
             new_file = os.path.join(new_path, old_file)
             old_file = os.path.join(old_path, old_file)
             # FIXME we shouldn't do this from a thread!
             if self.tagger.files.get(decode_filename(old_file)):
                 log.debug("File loaded in the tagger, not moving %r", old_file)
                 continue
             log.debug("Moving %r to %r", old_file, new_file)
             shutil.move(old_file, new_file)
Ejemplo n.º 19
0
    def _move_additional_files(self, old_filename, new_filename):
        """Move extra files, like images, playlists..."""
        new_path = os.path.dirname(new_filename)
        old_path = os.path.dirname(old_filename)
        if new_path == old_path:
            # skip, same directory, nothing to move
            return
        patterns = config.setting["move_additional_files_pattern"]
        pattern_regexes = set()
        for pattern in patterns.split():
            pattern = pattern.strip()
            if not pattern:
                continue
            pattern_regex = re.compile(fnmatch.translate(pattern), re.IGNORECASE)
            match_hidden = pattern.startswith('.')
            pattern_regexes.add((pattern_regex, match_hidden))
        if not pattern_regexes:
            return
        moves = set()
        try:
            # TODO: use with statement with python 3.6+
            for entry in os.scandir(old_path):
                is_hidden = entry.name.startswith('.')
                for pattern_regex, match_hidden in pattern_regexes:
                    if is_hidden and not match_hidden:
                        continue
                    if pattern_regex.match(entry.name):
                        new_file_path = os.path.join(new_path, entry.name)
                        moves.add((entry.path, new_file_path))
                        break  # we are done with this file
        except OSError as why:
            log.error("Failed to scan %r: %s", old_path, why)
            return

        for old_file_path, new_file_path in moves:
            # FIXME we shouldn't do this from a thread!
            if self.tagger.files.get(decode_filename(old_file_path)):
                log.debug("File loaded in the tagger, not moving %r", old_file_path)
                continue
            log.debug("Moving %r to %r", old_file_path, new_file_path)
            try:
                shutil.move(old_file_path, new_file_path)
            except OSError as why:
                log.error("Failed to move %r to %r: %s", old_file_path,
                          new_file_path, why)
Ejemplo n.º 20
0
 def _delete_additional_files(self, old_filename):
     """Delete all other files of type that are not being saved.."""
     """Retrieve path of saved file"""
     old_path = encode_filename(os.path.dirname(old_filename))
     """Retrieve patterns(types) to be deleted"""
     patterns = encode_filename(
         config.setting["delete_additional_files_pattern"])
     patterns = filter(bool, [p.strip() for p in patterns.split()])
     for pattern in patterns:
         # FIXME glob1 is not documented, maybe we need our own implementation?
         for old_file in glob.glob1(old_path, pattern):
             old_file = os.path.join(old_path, old_file)
             # FIXME we shouldn't do this from a thread!
             if self.tagger.files.get(decode_filename(old_file)):
                 """Ensures file being saved is not deleted"""
                 log.debug("File loaded in the tagger, not deleting %r",
                           old_file)
                 continue
             log.debug("Deleting %r", old_file)
             os.remove(old_file)
Ejemplo n.º 21
0
def generate_moodbar_for_files(files, format, tagger):
    """Generate the moodfiles for a list of files in album mode."""
    file_list = ['%s' % encode_filename(f.filename) for f in files]
    for mood_file in file_list:
        new_filename = os.path.join(os.path.dirname(
            mood_file), '.' + os.path.splitext(os.path.basename(mood_file))[0] + '.mood')
        # file format to make it compaitble with Amarok and hidden in linux
        file_list_mood = ['%s' % new_filename]

    if format in MOODBAR_COMMANDS \
            and tagger.config.setting[MOODBAR_COMMANDS[format][0]]:
        command = tagger.config.setting[MOODBAR_COMMANDS[format][0]]
        options = tagger.config.setting[
            MOODBAR_COMMANDS[format][1]].split(' ')
#        tagger.log.debug('My debug >>>  %s' % (file_list_mood))
        tagger.log.debug(
            '%s %s %s %s' % (command, decode_filename(' '.join(file_list)), ' '.join(options), decode_filename(' '.join(file_list_mood))))
        check_call([command] + file_list + options + file_list_mood)
    else:
        raise Exception('Moodbar: Unsupported format %s' % (format))
Ejemplo n.º 22
0
 def _run_init(self):
     if self._cmdline_files:
         files = [decode_filename(f) for f in self._cmdline_files]
         self.add_paths(files)
         del self._cmdline_files