Blame plugins/generate_completion_cache.py

Packit 3a9065
# coding=utf-8
Packit 3a9065
# generate_completion_cache.py - generate cache for dnf bash completion
Packit 3a9065
# Copyright © 2013 Elad Alfassa <elad@fedoraproject.org>
Packit 3a9065
# Copyright (C) 2014-2015 Igor Gnatenko <i.gnatenko.brain@gmail.com>
Packit 3a9065
# Copyright (C) 2015  Red Hat, Inc.
Packit 3a9065
Packit 3a9065
# This copyrighted material is made available to anyone wishing to use,
Packit 3a9065
# modify, copy, or redistribute it subject to the terms and conditions of
Packit 3a9065
# the GNU General Public License v.2, or (at your option) any later version.
Packit 3a9065
# This program is distributed in the hope that it will be useful, but WITHOUT
Packit 3a9065
# ANY WARRANTY expressed or implied, including the implied warranties of
Packit 3a9065
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
Packit 3a9065
# Public License for more details.  You should have received a copy of the
Packit 3a9065
# GNU General Public License along with this program; if not, write to the
Packit 3a9065
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit 3a9065
# 02110-1301, USA.
Packit 3a9065
Packit 3a9065
from __future__ import absolute_import
Packit 3a9065
from __future__ import unicode_literals
Packit 3a9065
from dnf.i18n import ucd
Packit 3a9065
from dnfpluginscore import logger
Packit 3a9065
Packit 3a9065
import dnf
Packit 3a9065
import os.path
Packit 3a9065
import sqlite3
Packit 3a9065
Packit 3a9065
Packit 3a9065
class BashCompletionCache(dnf.Plugin):
Packit 3a9065
    name = 'generate_completion_cache'
Packit 3a9065
Packit 3a9065
    def __init__(self, base, cli):
Packit 3a9065
        super(BashCompletionCache, self).__init__(base, cli)
Packit 3a9065
        self.base = base
Packit 3a9065
        self.cache_file = "/var/cache/dnf/packages.db"
Packit 3a9065
Packit 3a9065
    @staticmethod
Packit 3a9065
    def _out(msg):
Packit 3a9065
        logger.debug('Completion plugin: %s', msg)
Packit 3a9065
Packit 3a9065
    def sack(self):
Packit 3a9065
        ''' Generate cache of available packages '''
Packit 3a9065
        # We generate this cache only if the repos were just freshed or if the
Packit 3a9065
        # cache file doesn't exist
Packit 3a9065
Packit 3a9065
        fresh = False
Packit 3a9065
        for repo in self.base.repos.iter_enabled():
Packit 3a9065
            if repo.metadata is not None and repo.metadata.fresh:
Packit 3a9065
                # One fresh repo is enough to cause a regen of the cache
Packit 3a9065
                fresh = True
Packit 3a9065
                break
Packit 3a9065
Packit 3a9065
        if not os.path.exists(self.cache_file) or fresh:
Packit 3a9065
            try:
Packit 3a9065
                with sqlite3.connect(self.cache_file) as conn:
Packit 3a9065
                    self._out('Generating completion cache...')
Packit 3a9065
                    cur = conn.cursor()
Packit 3a9065
                    cur.execute(
Packit 3a9065
                        "create table if not exists available (pkg TEXT)")
Packit 3a9065
                    cur.execute(
Packit 3a9065
                        "create unique index if not exists "
Packit 3a9065
                        "pkg_available ON available(pkg)")
Packit 3a9065
                    cur.execute("delete from available")
Packit 3a9065
                    avail_pkgs = self.base.sack.query().available()
Packit 3a9065
                    avail_pkgs_insert = [[str(x)] for x in avail_pkgs if x.arch != "src"]
Packit 3a9065
                    cur.executemany("insert or ignore into available values (?)",
Packit 3a9065
                                    avail_pkgs_insert)
Packit 3a9065
                    conn.commit()
Packit 3a9065
            except sqlite3.OperationalError as e:
Packit 3a9065
                self._out("Can't write completion cache: %s" % ucd(e))
Packit 3a9065
Packit 3a9065
    def transaction(self):
Packit 3a9065
        ''' Generate cache of installed packages '''
Packit 3a9065
        if not self.transaction:
Packit 3a9065
            return
Packit 3a9065
Packit 3a9065
        try:
Packit 3a9065
            with sqlite3.connect(self.cache_file) as conn:
Packit 3a9065
                self._out('Generating completion cache...')
Packit 3a9065
                cur = conn.cursor()
Packit 3a9065
                cur.execute("create table if not exists installed (pkg TEXT)")
Packit 3a9065
                cur.execute(
Packit 3a9065
                    "create unique index if not exists "
Packit 3a9065
                    "pkg_installed ON installed(pkg)")
Packit 3a9065
                cur.execute("delete from installed")
Packit 3a9065
                inst_pkgs = dnf.sack._rpmdb_sack(self.base).query().installed()
Packit 3a9065
                inst_pkgs_insert = [[str(x)] for x in inst_pkgs if x.arch != "src"]
Packit 3a9065
                cur.executemany("insert or ignore into installed values (?)",
Packit 3a9065
                                inst_pkgs_insert)
Packit 3a9065
                conn.commit()
Packit 3a9065
        except sqlite3.OperationalError as e:
Packit 3a9065
            self._out("Can't write completion cache: %s" % ucd(e))