Esempio n. 1
0
class History:
    date_format = '%Y%m%d%H%M%S'

    def __init__(self):
        self.db = DBConnection()

    def clear(self):
        """
        Clear all the history
        """
        self.db.action(
            'DELETE '
            'FROM history '
            'WHERE 1 = 1'
        )

    def get(self, limit=100, action=None):
        """
        :param limit: The maximum number of elements to return
        :param action: The type of action to filter in the history. Either 'downloaded' or 'snatched'. Anything else or
                        no value will return everything (up to ``limit``)
        :return: The last ``limit`` elements of type ``action`` in the history
        """

        actions = History._get_actions(action)
        limit = History._get_limit(limit)

        common_sql = 'SELECT action, date, episode, provider, h.quality, resource, season, show_name, showid ' \
                     'FROM history h, tv_shows s ' \
                     'WHERE h.showid = s.indexer_id '
        filter_sql = 'AND action in (' + ','.join(['?'] * len(actions)) + ') '
        order_sql = 'ORDER BY date DESC '

        if limit == 0:
            if len(actions) > 0:
                results = self.db.select(common_sql + filter_sql + order_sql, actions)
            else:
                results = self.db.select(common_sql + order_sql)
        else:
            if len(actions) > 0:
                results = self.db.select(common_sql + filter_sql + order_sql + 'LIMIT ?', actions + [limit])
            else:
                results = self.db.select(common_sql + order_sql + 'LIMIT ?', [limit])

        data = []
        for result in results:
            data.append({
                'action': result['action'],
                'date': result['date'],
                'episode': result['episode'],
                'provider': result['provider'],
                'quality': result['quality'],
                'resource': result['resource'],
                'season': result['season'],
                'show_id': result['showid'],
                'show_name': result['show_name']
            })

        return data

    def trim(self):
        """
        Remove all elements older than 30 days from the history
        """

        self.db.action(
            'DELETE '
            'FROM history '
            'WHERE date < ?',
            [(datetime.today() - timedelta(days=30)).strftime(History.date_format)]
        )

    @staticmethod
    def _get_actions(action):
        action = action.lower() if isinstance(action, (str, unicode)) else ''

        if action == 'downloaded':
            return Quality.DOWNLOADED

        if action == 'snatched':
            return Quality.SNATCHED

        return []

    @staticmethod
    def _get_limit(limit):
        limit = try_int(limit, 0)

        return max(limit, 0)
Esempio n. 2
0
class History:
    date_format = '%Y%m%d%H%M%S'

    def __init__(self):
        self.db = DBConnection()

    def clear(self):
        """
        Clear all the history
        """
        self.db.action('DELETE ' 'FROM history ' 'WHERE 1 = 1')

    def get(self, limit=100, action=None):
        """
        :param limit: The maximum number of elements to return
        :param action: The type of action to filter in the history. Either 'downloaded' or 'snatched'. Anything else or
                        no value will return everything (up to ``limit``)
        :return: The last ``limit`` elements of type ``action`` in the history
        """

        action = action.lower() if isinstance(action, str) else ''
        limit = int(limit)

        if action == 'downloaded':
            actions = Quality.DOWNLOADED
        elif action == 'snatched':
            actions = Quality.SNATCHED
        else:
            actions = []

        common_sql = 'SELECT action, date, episode, provider, h.quality, resource, season, show_name, showid ' \
                     'FROM history h, tv_shows s ' \
                     'WHERE h.showid = s.indexer_id '
        filter_sql = 'AND action in (' + ','.join(['?'] * len(actions)) + ') '
        order_sql = 'ORDER BY date DESC '

        if limit == 0:
            if len(actions) > 0:
                results = self.db.select(common_sql + filter_sql + order_sql,
                                         actions)
            else:
                results = self.db.select(common_sql + order_sql)
        else:
            if len(actions) > 0:
                results = self.db.select(
                    common_sql + filter_sql + order_sql + 'LIMIT ?',
                    actions + [limit])
            else:
                results = self.db.select(common_sql + order_sql + 'LIMIT ?',
                                         [limit])

        data = []
        for result in results:
            data.append({
                'action': result['action'],
                'date': result['date'],
                'episode': result['episode'],
                'provider': result['provider'],
                'quality': result['quality'],
                'resource': result['resource'],
                'season': result['season'],
                'show_id': result['showid'],
                'show_name': result['show_name']
            })

        return data

    def trim(self):
        """
        Remove all elements older than 30 days from the history
        """

        self.db.action('DELETE '
                       'FROM history '
                       'WHERE date < ?',
                       [(datetime.today() - timedelta(days=30)).strftime(
                           History.date_format)])
Esempio n. 3
0
class History:
    date_format = '%Y%m%d%H%M%S'

    def __init__(self):
        self.db = DBConnection()

    def clear(self):
        self.db.action(
            'DELETE '
            'FROM history '
            'WHERE 1 = 1'
        )

    def get(self, limit=100, action=None):
        action = action.lower() if isinstance(action, str) else ''
        limit = int(limit)

        if action == 'downloaded':
            actions = Quality.DOWNLOADED
        elif action == 'snatched':
            actions = Quality.SNATCHED
        else:
            actions = Quality.SNATCHED + Quality.DOWNLOADED

        if limit == 0:
            results = self.db.select(
                'SELECT h.*, show_name '
                'FROM history h, tv_shows s '
                'WHERE h.showid = s.indexer_id '
                'AND action in (' + ','.join(['?'] * len(actions)) + ') '
                                                                     'ORDER BY date DESC',
                actions
            )
        else:
            results = self.db.select(
                'SELECT h.*, show_name '
                'FROM history h, tv_shows s '
                'WHERE h.showid = s.indexer_id '
                'AND action in (' + ','.join(['?'] * len(actions)) + ') '
                                                                     'ORDER BY date DESC '
                                                                     'LIMIT ?',
                actions + [limit]
            )

        data = []
        for result in results:
            data.append({
                'action': result['action'],
                'date': result['date'],
                'episode': result['episode'],
                'provider': result['provider'],
                'quality': result['quality'],
                'resource': result['resource'],
                'season': result['season'],
                'show_id': result['showid'],
                'show_name': result['show_name']
            })

        return data

    def trim(self):
        self.db.action(
            'DELETE '
            'FROM history '
            'WHERE date < ?',
            [(datetime.today() - timedelta(days=30)).strftime(History.date_format)]
        )
Esempio n. 4
0
class History(object):
    date_format = '%Y%m%d%H%M%S'

    def __init__(self):
        self.db = DBConnection()

    def remove(self, toRemove):
        """
        Removes the selected history
        :param toRemove: Contains the properties of the log entries to remove
        """
        query = ''

        for item in toRemove:
            query = query + ' OR ' if query != '' else ''
            query = query + '(date IN ({0}) AND showid = {1} ' \
                            'AND season = {2} AND episode = {3})' \
                            .format(','.join(item['dates']), item['show_id'], \
                                    item['season'], item['episode'])

        self.db.action('DELETE FROM history WHERE ' + query)

    def clear(self):
        """
        Clear all the history
        """
        self.db.action('DELETE ' 'FROM history ' 'WHERE 1 = 1')

    def get(self, limit=100, action=None):
        """
        :param limit: The maximum number of elements to return
        :param action: The type of action to filter in the history. Either 'downloaded' or 'snatched'. Anything else or
                        no value will return everything (up to ``limit``)
        :return: The last ``limit`` elements of type ``action`` in the history
        """

        actions = History._get_actions(action)
        limit = History._get_limit(limit)

        common_sql = 'SELECT action, date, episode, provider, h.quality, resource, season, show_name, showid ' \
                     'FROM history h, tv_shows s ' \
                     'WHERE h.showid = s.indexer_id '
        filter_sql = 'AND action in (' + ','.join(['?'] * len(actions)) + ') '
        order_sql = 'ORDER BY date DESC '

        if limit == 0:
            if actions:
                results = self.db.select(common_sql + filter_sql + order_sql,
                                         actions)
            else:
                results = self.db.select(common_sql + order_sql)
        else:
            if actions:
                results = self.db.select(
                    common_sql + filter_sql + order_sql + 'LIMIT ?',
                    actions + [limit])
            else:
                results = self.db.select(common_sql + order_sql + 'LIMIT ?',
                                         [limit])

        data = []
        for result in results:
            data.append({
                'action': result[b'action'],
                'date': result[b'date'],
                'episode': result[b'episode'],
                'provider': result[b'provider'],
                'quality': result[b'quality'],
                'resource': result[b'resource'],
                'season': result[b'season'],
                'show_id': result[b'showid'],
                'show_name': result[b'show_name']
            })

        return data

    def trim(self):
        """
        Remove all elements older than 30 days from the history
        """

        self.db.action('DELETE '
                       'FROM history '
                       'WHERE date < ?',
                       [(datetime.today() - timedelta(days=30)).strftime(
                           History.date_format)])

    @staticmethod
    def _get_actions(action):
        action = action.lower() if isinstance(action, six.string_types) else ''

        if action == 'downloaded':
            return Quality.DOWNLOADED

        if action == 'snatched':
            return Quality.SNATCHED

        return []

    @staticmethod
    def _get_limit(limit):
        limit = try_int(limit, 0)

        return max(limit, 0)
Esempio n. 5
0
class History(object):
    date_format = '%Y%m%d%H%M%S'

    def __init__(self):
        self.db = DBConnection()

    def clear(self):
        """
        Clear all the history
        """
        self.db.action(
            'DELETE '
            'FROM history '
            'WHERE 1 = 1'
        )

    def get(self, limit=100, action=None):
        """
        :param limit: The maximum number of elements to return
        :param action: The type of action to filter in the history. Either 'downloaded' or 'snatched'. Anything else or
                        no value will return everything (up to ``limit``)
        :return: The last ``limit`` elements of type ``action`` in the history
        """

        # TODO: Make this a generator instead
        # TODO: Split compact and detailed into separate methods
        # TODO: Add a date limit as well
        # TODO: Clean up history.mako

        actions = History._get_actions(action)
        limit = max(try_int(limit), 0)

        common_sql = 'SELECT show_name, showid, season, episode, h.quality, ' \
                     'action, provider, resource, date ' \
                     'FROM history h, tv_shows s ' \
                     'WHERE h.showid = s.indexer_id '
        filter_sql = 'AND action in (' + ','.join(['?'] * len(actions)) + ') '
        order_sql = 'ORDER BY date DESC '

        if actions:
            sql_results = self.db.select(common_sql + filter_sql + order_sql,
                                         actions)
        else:
            sql_results = self.db.select(common_sql + order_sql)

        detailed = []
        compact = dict()

        # TODO: Convert to a defaultdict and compact items as needed
        # TODO: Convert to using operators to combine items
        for row in sql_results:
            row = History.Item(*row)
            if row.index in compact:
                compact[row.index].actions.append(row.cur_action)
            elif not limit or len(compact) < limit:
                detailed.append(row)
                compact[row.index] = row.compacted()

        results = namedtuple('results', ['detailed', 'compact'])
        return results(detailed, compact.values())

    def trim(self, days=30):
        """
        Remove expired elements from history

        :param days: number of days to keep
        """
        date = datetime.today() - timedelta(days)
        self.db.action(
            'DELETE '
            'FROM history '
            'WHERE date < ?',
            [date.strftime(History.date_format)]
        )

    @staticmethod
    def _get_actions(action):
        action = action.lower() if isinstance(action, (str, unicode)) else ''

        result = None
        if action == 'downloaded':
            result = Quality.DOWNLOADED
        elif action == 'snatched':
            result = Quality.SNATCHED

        return result or []

    action_fields = ('action', 'provider', 'resource', 'date', )
    # A specific action from history
    Action = namedtuple('Action', action_fields)
    Action.width = len(action_fields)

    index_fields = ('show_id', 'season', 'episode', 'quality', )
    # An index for an item or compact item from history
    Index = namedtuple('Index', index_fields)
    Index.width = len(index_fields)

    compact_fields = ('show_name', 'index', 'actions', )
    # Related items compacted with a list of actions from history
    CompactItem = namedtuple('CompactItem', compact_fields)

    item_fields = tuple(  # make it a tuple so its immutable
        ['show_name'] + list(index_fields) + list(action_fields)
    )

    class Item(namedtuple('Item', item_fields)):
        # TODO: Allow items to be added to a compact item
        """
        An individual row item from history
        """
        # prevent creation of a __dict__ when subclassing
        # from a class that uses __slots__
        __slots__ = ()

        @property
        def index(self):
            """
            Create a look-up index for the item
            """
            return History.Index(
                self.show_id,
                self.season,
                self.episode,
                self.quality,
            )

        @property
        def cur_action(self):
            """
            Create the current action from action_fields
            """
            return History.Action(
                self.action,
                self.provider,
                self.resource,
                self.date,
            )

        def compacted(self):
            """
            Create a CompactItem

            :returns: the current item in compact form
            """
            result = History.CompactItem(
                self.show_name,
                self.index,
                [self.cur_action],  # actions
            )
            return result

        def __add__(self, other):
            """
            Combines two history items with the same index

            :param other: The other item to add
            :returns: a compact item with elements from both items
            :raises AssertionError: if indexes do not match
            """
            # Index comparison and validation is done by _radd_
            return self.compacted() + other

        def __radd__(self, other):
            """
            Adds a history item to a compact item

            :param other: The compact item to append
            :returns: the updated compact item
            :raises AssertionError: if indexes do not match
            """
            if self.index == other.index:
                other.actions.append(self.cur_action)
                return other
            else:
                raise AssertionError('cannot add items with different indexes')