예제 #1
0
def print_renamed_files(files):
    """
    Present the files that need to be renamed to the user.
    """
    if not files:
        print("Failed to find any files to rename")
        sys.exit(1)

    print("PATH = {}".format(Settings.path))
    print("-------" + '-' * len(Settings.path))

    same = 0
    for tuple_ in files:
        if not tuple_:
            same += 1
            continue
        else:
            old, new = tuple_

        old = os.path.split(old)[1].encode(Settings.encoding, 'ignore')
        new = os.path.split(new)[1].encode(Settings.encoding, 'ignore')

        print("OLD: {0}".format(utils.encode(old)))
        print("NEW: {0}".format(utils.encode(new)))
        print()

    if same > 0:
        if same == 1:
            num = "1 file doesn't"
        else:
            num = "{} files don't".format(same)
        print("{} need to be renamed".format(num))
예제 #2
0
def print_renamed_files(files):
    """
    Present the files that need to be renamed to the user.
    """
    if not files:
        print ("Failed to find any files to rename")
        sys.exit(1)

    print ("PATH = {}".format(Settings.path))
    print ("-------" + '-' * len(Settings.path))

    same = 0
    for tuple_ in files:
        if not tuple_:
            same += 1
            continue
        else:
            old, new = tuple_

        old = os.path.split(old)[1].encode(Settings.encoding, 'ignore')
        new = os.path.split(new)[1].encode(Settings.encoding, 'ignore')

        print ("OLD: {0}".format(utils.encode(old)))
        print ("NEW: {0}".format(utils.encode(new)))
        print()

    if same > 0:
        if same == 1:
            num = "1 file doesn't"
        else:
            num = "{} files don't".format(same)
        print("{} need to be renamed".format(num))
예제 #3
0
    def __init__(self, files, parent=None):
        super(RenameDialog, self).__init__(parent)
        self.setGeometry(100, 100, 750, 500)
        self.setWindowTitle("Rename Files Utility")

        self.files = files

        self.buttonBox = QtGui.QDialogButtonBox(QtCore.Qt.Vertical)
        self.buttonBox = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Cancel
                                                | QtGui.QDialogButtonBox.Ok)
        self.buttonBox.rejected.connect(self.close)

        self.model = QtGui.QStandardItemModel()
        self.view = QtGui.QListView()

        self.view.setModel(self.model)

        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.view)
        layout.addWidget(self.buttonBox)

        self.setLayout(layout)

        if not self.files:
            self.model.appendRow(
                QtGui.QStandardItem("No files need to be renamed"))
            self.buttonBox.accepted.connect(self.close)
            self.buttonBox.accepted.connect(self.close)
        else:

            self.files, self.same_count = self.prepare_renamed_files(
                self.files)

            if not self.files:
                self.print_renamed_files()

            for old, new in self.files:
                item = QtGui.QStandardItem()

                old_name = utils.encode(os.path.split(old)[1])
                new_name = utils.encode(os.path.split(new)[1])
                string = utils.encode("OLD: {}\nNEW: {}\n".format(
                    old_name, new_name))
                item.setText(string)
                item.setCheckState(QtCore.Qt.Checked)
                item.setCheckable(True)
                item.rename_info = (old, new)

                if item.text():
                    self.model.appendRow(item)

            self.buttonBox.accepted.connect(self.rename)

        self.view.show()
        self.show()
예제 #4
0
    def __init__(self, files, parent=None):
        super(RenameDialog, self).__init__(parent)
        self.setGeometry(100, 100, 750, 500)
        self.setWindowTitle("Rename Files Utility")

        self.files = files

        self.buttonBox = QtGui.QDialogButtonBox(QtCore.Qt.Vertical)
        self.buttonBox = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Ok)
        self.buttonBox.rejected.connect(self.close)

        self.model = QtGui.QStandardItemModel()
        self.view = QtGui.QListView()

        self.view.setModel(self.model)

        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.view)
        layout.addWidget(self.buttonBox)

        self.setLayout(layout)

        if not self.files:
            self.model.appendRow(QtGui.QStandardItem("No files need to be renamed"))
            self.buttonBox.accepted.connect(self.close)
            self.buttonBox.accepted.connect(self.close)
        else:

            self.files, self.same_count = self.prepare_renamed_files(self.files)

            if not self.files:
                self.print_renamed_files()

            for old, new in self.files:
                item = QtGui.QStandardItem()

                old_name = utils.encode(os.path.split(old)[1])
                new_name = utils.encode(os.path.split(new)[1])
                string = utils.encode("OLD: {}\nNEW: {}\n".format(old_name, new_name))
                item.setText(string)
                item.setCheckState(QtCore.Qt.Checked)
                item.setCheckable(True)
                item.rename_info = (old, new)

                if item.text():
                    self.model.appendRow(item)

            self.buttonBox.accepted.connect(self.rename)

        self.view.show()
        self.show()
예제 #5
0
def _parse_local(title):
    """
    Try to find the anime ID (aid) in the dump file provided by AniDB
    """
    if not utils.file_exists_in_resources('animetitles.dat'):
        logging.warning("AniDB database file not found, unable to poll AniDB at this time")
        logging.warning("Try using the --update-db option to download an copy of it")
        return -1

    logging.info("Searching the AniDB database file")

    title = title.lower()

    regex = re.compile(r'(?P<aid>\d+)\|(?P<type>\d)\|(?P<lang>.+)\|(?P<title>.*)')

    sequence = difflib.SequenceMatcher(lambda x: x in punct, title.lower())

    guesses = []

    with utils.open_file_in_resources('animetitles.dat') as f:
        for line in f:
            res = regex.search(line)

            if not res:
                continue

            original_title = utils.encode(res.group('title').lower())
            clean_title = utils.prepare_title(utils.encode(res.group('title'))).lower()

            if utils.prepare_title(title) in (original_title, clean_title):
                return int(res.group('aid'))

            sequence.set_seq2(clean_title.lower())
            ratio = sequence.quick_ratio()

            if ratio > .80:
                d = dict(ratio=ratio, aid=res.group('aid'), title=original_title)
                guesses.append(d)

    if guesses:
        logging.info("{} possibilities".format(len(guesses)))
        guesses = sorted(guesses, key=lambda x: x['ratio'])
        aid = guesses[0]['aid']
        name = guesses[0]['title']
        logging.error("Closest show to '{}' on AniDB is '{}'' with id {}".format(title, name, aid))

        for guess in guesses[1:]:
            logging.info("Similar show {} [{}] also found".format(guess['title'], guess['aid']))

    return -1
예제 #6
0
    def get_episodes(self, showTitle, expiration=None):
        """Returns the episodes associated with the show id"""
        if not showTitle:
            raise ValueError("get_episodes expects a string")

        title = (showTitle, )
        query = """
            SELECT e.title, e.season, e.number, e.count, e.type, s.sid, s.time
            FROM episodes AS e INNER JOIN shows AS s
            ON s.sid=e.sid AND s.title=?
            """

        with self.connection as conn:
            curs = conn.execute(query, title)
            result = curs.fetchall()

        eps = []

        if not result:
            return eps

        diffDays = (datetime.datetime.now() - result[0][-1])

        logging.info("{} days old".format(diffDays.days))

        if not expiration:
            expiration = Settings.db_update

        if diffDays.days >= expiration:
            #If the show is older than a week remove it then return not found
            logging.warning("Show is older than a week, updating...")
            sid = result[0][-2]
            self.remove_show(sid)
            return eps

        for episode in result:
            title = utils.encode(episode[0])
            season = episode[1]
            number = episode[2]
            count = episode[3]
            type_ = utils.encode(episode[4])
            eps.append(
                Episode(title=title,
                        number=number,
                        season=season,
                        count=count,
                        type=type_))

        return eps
예제 #7
0
 def show_title(self, val):
     """
     Sets the shows title to the value passed as well as prepares it for use
     """
     logging.debug("Setting show title to: {}".format(val))
     self.title = utils.encode(val.capitalize())
     self.proper_title = utils.prepare_title(val)
예제 #8
0
    def __init__(self, show, fmt=None):
        """
        Allows printing of custom formatted episode information
        """
        self.show = show
        self._format_string = utils.encode(fmt) if fmt else Settings.format

        ## Use a negative lookahead assertion to ensure that the
        ## tag had not been escaped
        regex = r'(?<!\\)(?P<tag>\{start}.*?\{end})'

        regex = regex.format(start=Settings.tag_start, end=Settings.tag_end)

        self.tag_regex = re.compile(regex, re.I)
        self.tokens = self.tag_regex.split(self._format_string)
        self.strip_whitespace_regex = re.compile(r'[\s]+')

        self.episode_number_tags = Settings.tags['episode_number_tags']
        self.type_tags = Settings.tags['type_tags']
        self.season_number_tags = Settings.tags['season_number_tags']
        self.episode_count_tags = Settings.tags['episode_count_tags']
        self.episode_name_tags = Settings.tags['episode_name_tags']
        self.hash_tags = Settings.tags['hash_tags']
        self.series_name_tags = Settings.tags['series_name_tags']

        self.check_for_duplicate_tokens()
예제 #9
0
 def show_title(self, val):
     """
     Sets the shows title to the value passed as well as prepares it for use
     """
     logging.debug("Setting show title to: {}".format(val))
     self.title = utils.encode(val.capitalize())
     self.proper_title = utils.prepare_title(val)
예제 #10
0
    def __init__(self, show, fmt=None):
        """
        Allows printing of custom formatted episode information
        """
        self.show = show
        self._format_string = utils.encode(fmt) if fmt else Settings.format

        ## Use a negative lookahead assertion to ensure that the
        ## tag had not been escaped
        regex = r'(?<!\\)(?P<tag>\{start}.*?\{end})'

        regex = regex.format(start=Settings.tag_start,
                             end=Settings.tag_end)

        self.tag_regex = re.compile(regex, re.I)
        self.tokens = self.tag_regex.split(self._format_string)
        self.strip_whitespace_regex = re.compile(r'[\s]+')

        self.episode_number_tags = Settings.tags['episode_number_tags']
        self.type_tags = Settings.tags['type_tags']
        self.season_number_tags = Settings.tags['season_number_tags']
        self.episode_count_tags = Settings.tags['episode_count_tags']
        self.episode_name_tags = Settings.tags['episode_name_tags']
        self.hash_tags = Settings.tags['hash_tags']
        self.series_name_tags = Settings.tags['series_name_tags']

        self.check_for_duplicate_tokens()
예제 #11
0
def poll(title):
    cleanTitle = utils.prepare_title(title)
    episodes = []
    url = "http://www.epguides.com/{0}".format(cleanTitle)
    fd = utils.get_url_descriptor(url)

    if fd is None:
        return utils.show_not_found

    count = 1
    for line in fd.iter_lines():
        info = epguides_regex.match(utils.encode(line))

        if info is not None:
            name = info.group('name')
            episode = info.group('episode')
            season = int(info.group('season'))
            name = re.sub('<.*?>', '', name).strip()

            if '[Trailer]' in name:
                name = name.replace('[Trailer]', '')

            if name == "TBA":
                continue

            episodes.append(
                Episode(title=name, number=episode, season=season,
                        count=count))
            count += 1

    return episodes
예제 #12
0
def poll(title):
    cleanTitle = utils.prepare_title(title)
    episodes = []
    url = "http://www.epguides.com/{0}".format(cleanTitle)
    fd = utils.get_url_descriptor(url)

    if fd is None:
        return utils.show_not_found

    count = 1
    for line in fd.iter_lines():
        info = epguides_regex.match(utils.encode(line))

        if info is not None:
            name = info.group('name')
            episode = info.group('episode')
            season = int(info.group('season'))
            name = re.sub('<.*?>', '', name).strip()

            if '[Trailer]' in name:
                name = name.replace('[Trailer]', '')

            if name == "TBA":
                continue

            episodes.append(Episode(title=name, number=episode, season=season, count=count))
            count += 1

    return episodes
예제 #13
0
def display_specials(show, header=False):
    if header:
        print ("\nSpecials")
        print ("---------")

    for eps in show.specials:
        line = show.formatter.display(eps).encode(Settings.encoding, 'ignore')
        print(utils.encode(line))
예제 #14
0
def display_specials(show, header=False):
    if header:
        print("\nSpecials")
        print("---------")

    for eps in show.specials:
        line = show.formatter.display(eps).encode(Settings.encoding, 'ignore')
        print(utils.encode(line))
예제 #15
0
    def get_episodes(self, showTitle, expiration=None):
        """Returns the episodes associated with the show id"""
        if not showTitle:
            raise ValueError("get_episodes expects a string")

        title = (showTitle, )
        query = """
            SELECT e.title, e.season, e.number, e.count, e.type, s.sid, s.time
            FROM episodes AS e INNER JOIN shows AS s
            ON s.sid=e.sid AND s.title=?
            """

        with self.connection as conn:
            curs = conn.execute(query, title)
            result = curs.fetchall()

        eps = []

        if not result:
            return eps

        diffDays = (datetime.datetime.now() - result[0][-1])

        logging.info("{} days old".format(diffDays.days))

        if not expiration:
            expiration = Settings.db_update

        if diffDays.days >= expiration:
            #If the show is older than a week remove it then return not found
            logging.warning("Show is older than a week, updating...")
            sid = result[0][-2]
            self.remove_show(sid)
            return eps

        for episode in result:
            title = utils.encode(episode[0])
            season = episode[1]
            number = episode[2]
            count = episode[3]
            type_ = utils.encode(episode[4])
            eps.append(Episode(title=title, number=number, season=season,
                               count=count, type=type_))

        return eps
예제 #16
0
 def format_string(self, fmt=None):
     """
     Set the format string for the formatter
     """
     if fmt:
         self._format_string = utils.encode(fmt)
         self.tokens = self.tag_regex.split(fmt)
     else:
         raise AttributeError("Empty format string set")
예제 #17
0
 def format_string(self, fmt=None):
     """
     Set the format string for the formatter
     """
     if fmt:
         self._format_string = utils.encode(fmt)
         self.tokens = self.tag_regex.split(fmt)
     else:
         raise AttributeError("Empty format string set")
예제 #18
0
    def __init__(self, seriesTitle, episodes=None):
        self.title = utils.encode(string.capwords(seriesTitle))
        self.proper_title = utils.prepare_title(seriesTitle.lower())
        self.episodes = []
        self.specials = []
        self._episodes_by_season = defaultdict(list)
        self.formatter = None

        if episodes:
            self.add_episodes(episodes)
예제 #19
0
    def __init__(self, seriesTitle, episodes=None):
        self.title = utils.encode(string.capwords(seriesTitle))
        self.proper_title = utils.prepare_title(seriesTitle.lower())
        self.episodes = []
        self.specials = []
        self._episodes_by_season = defaultdict(list)
        self.formatter = None

        if episodes:
            self.add_episodes(episodes)
예제 #20
0
 def __init__(self, **kwargs):
     """
     A container for an episode's information collected from the web
     """
     #title, number, season=1, count=-1,
     super(Episode, self).__init__(kwargs)
     self.title = utils.encode(kwargs['title'])
     self.season = int(kwargs.get('season', 1))
     self.number = int(kwargs['number'])
     self.count = int(kwargs.get('count', '-1'))
     self.type = kwargs.get('type', 'Episode')
     self.file = kwargs.get('file', None)
     self.is_special = (self.type.lower() != "episode")
예제 #21
0
 def __init__(self, **kwargs):
     """
     A container for an episode's information collected from the web
     """
     #title, number, season=1, count=-1,
     super(Episode, self).__init__(kwargs)
     self.title = utils.encode(kwargs['title'])
     self.season = int(kwargs.get('season', 1))
     self.number = int(kwargs['number'])
     self.count = int(kwargs.get('count', '-1'))
     self.type = kwargs.get('type', 'Episode')
     self.file = kwargs.get('file', None)
     self.is_special = (self.type.lower() != "episode")
예제 #22
0
    def display(self, episode):
        """
        Displays the episode according to the users format
        """
        args = []
        escaped_token = "\{}".format(Settings.tag_start)
        for token in self.tokens:
            if escaped_token in token:
                args.append(token.replace(escaped_token, Settings.tag_start))
            elif self.tag_regex.match(token):
                #If it's a tag try to resolve it
                token = self.strip_whitespace_regex.sub("", token)
                args.append(self._parse(episode, token[1:-1]))
            else:
                args.append(token)

        return utils.encode(''.join(args)).strip()
예제 #23
0
def display_episodes(show, episodes, header=False):
    if header:
        print ("\nShow: {0}".format(show.title))
        print ("Number of episodes: {0}".format(len(show.episodes)))
        print ("Number of specials: {0}".format(len(show.specials)))
        print ("Number of seasons: {0}".format(show.episodes[-1].season))
        print ("-" * 30)

    curr_season = episodes[0].season
    for eps in episodes:
        if curr_season != eps.season and header:
            print ("\nSeason {0}".format(eps.season))
            print ("----------")

        line = show.formatter.display(eps).encode(Settings.encoding, 'ignore')
        print(utils.encode(line))
        curr_season = eps.season
예제 #24
0
    def display(self, episode):
        """
        Displays the episode according to the users format
        """
        args = []
        escaped_token = "\{}".format(Settings.tag_start)
        for token in self.tokens:
            if escaped_token in token:
                args.append(token.replace(escaped_token, Settings.tag_start))
            elif self.tag_regex.match(token):
                #If it's a tag try to resolve it
                token = self.strip_whitespace_regex.sub("", token)
                args.append(self._parse(episode, token[1:-1]))
            else:
                args.append(token)

        return utils.encode(''.join(args)).strip()
예제 #25
0
def display_episodes(show, episodes, header=False):
    if header:
        print("\nShow: {0}".format(show.title))
        print("Number of episodes: {0}".format(len(show.episodes)))
        print("Number of specials: {0}".format(len(show.specials)))
        print("Number of seasons: {0}".format(show.episodes[-1].season))
        print("-" * 30)

    curr_season = episodes[0].season
    for eps in episodes:
        if curr_season != eps.season and header:
            print("\nSeason {0}".format(eps.season))
            print("----------")

        line = show.formatter.display(eps).encode(Settings.encoding, 'ignore')
        print(utils.encode(line))
        curr_season = eps.season
예제 #26
0
    def __init__(self, dbName=""):
        """Establish a connection to the show database"""

        if not dbName:
            raise ValueError("Empty database name passed to cache")

        if dbName != ':memory:':
            dbName = os.path.join(resource_path, dbName)

        try:
            self.connection = connect(dbName, detect_types=PARSE_DECLTYPES)
            logging.debug("Creating database: {}".format(dbName))
            self.connection.executescript(create_database)
        except OperationalError as reason:
            logging.error("Error connecting to database: {}".format(reason))
            raise reason
        else:
            #Make sure everything is utf-8
            self.connection.text_factory = lambda x: utils.encode(x)
예제 #27
0
    def __init__(self, dbName=""):
        """Establish a connection to the show database"""

        if not dbName:
            raise ValueError("Empty database name passed to cache")

        if dbName != ':memory:':
            dbName = os.path.join(resource_path, dbName)

        try:
            self.connection = connect(dbName, detect_types=PARSE_DECLTYPES)
            logging.debug("Creating database: {}".format(dbName))
            self.connection.executescript(create_database)
        except OperationalError as reason:
            logging.error("Error connecting to database: {}".format(reason))
            raise reason
        else:
            #Make sure everything is utf-8
            self.connection.text_factory = lambda x: utils.encode(x)