Exemplo n.º 1
0
    def install(self, installdir):
        # Check if this is actually a locally installed file already.
        if os.path.exists(self.db_entry['uri']):
            raise PackageError('Package is already installed.')
            # Or maybe skip the rest of the function without erroring.

        # Make connection and determine filename.
        p = urllib2.urlopen(self.db_entry['uri'])
        header = p.info().getheader('content-disposition')
        fkey = 'filename="'
        if header and (fkey in header):
            n = header.find(fkey) + len(fkey)
            filename = header[n:].split('"')[0]
        else:
            filename = os.path.basename(p.geturl())
        path = os.path.join(installdir, filename)

        # Put file in place.  No need to check if it already exists; if it
        # does, we probably want to replace it anyways.
        # In the process, check its MD5 sum against the one given in the repo.
        # MD5 is optional in the spec, so only calculate it if it's not given.
        m_target = self.db_entry['md5']
        m = md5()
        with open(path, 'wb') as dest:
            for chunk in iter(lambda: p.read(128*m.block_size), ''):
                if m_target: m.update(chunk)
                dest.write(chunk)
        if m_target and (m.hexdigest() != m_target):
            raise PackageError("File corrupted.  MD5 sums do not match.")

        # Update local database with new info.
        with sqlite3.connect(options.get_database()) as db:
            database_update.update_local_file(path, db)
            db.commit()
Exemplo n.º 2
0
def get_all():
    "Returns Package object for every available package, local or remote."
    tables = get_remote_tables()
    tables.append(LOCAL_TABLE)
    with sqlite3.connect(options.get_database()) as db:
        c = db.execute(
            ' Union '.join([ 'Select id From "%s"'%t for t in tables ]) )
        return [ Package(i[0]) for i in c ]
Exemplo n.º 3
0
def search_local_packages(col, val):
    """Find all packages containing the given value in the given column.
    Also handles columns containing lists of data, ensuring that the given
    value is an entry of that list, not just a substring of an entry."""
    with sqlite3.connect(options.get_database()) as db:
        c = db.execute( '''Select id From "%(tab)s" Where %(col)s Like ?
            Or %(col)s Like ? Or %(col)s Like ? Or %(col)s Like ?'''
            % {'tab':LOCAL_TABLE, 'col':col},
            (val, val+SEPCHAR+'%', '%'+SEPCHAR+val,
            '%'+SEPCHAR+val+SEPCHAR+'%') )

    return [ Package(i[0]) for i in c ]
Exemplo n.º 4
0
 def remove(self):
     "Remove any locally-installed copy of this package."
     # Check if it's even locally installed.
     if not self.local.exists:
         raise PackageError("%s can't be removed since it's not installed." % self.id)
     # If so, remove it.
     os.remove(self.local.db_entry['uri'])
     # Remove it from the local database.
     with sqlite3.connect(options.get_database()) as db:
         db.execute('Delete From "%s" Where id=?' % LOCAL_TABLE, (self.id,))
         db.commit()
     # Local table has changed, so update the local PackageInstance.
     self.local = PackageInstance(LOCAL_TABLE, self.id)
Exemplo n.º 5
0
def update_remote():
    """Adds a table for each repository to the database, adding an entry for each
    application listed in the repository."""
    # Open database connection.
    with sqlite3.connect(options.get_database()) as db:
        db.row_factory = sqlite3.Row
        c = db.cursor()

        for url in options.get_repos():
            try:
                update_remote_url(url, c)
            except Exception as e:
                warnings.warn("Could not process %s: %s" % (url, repr(e)))
Exemplo n.º 6
0
    def __init__(self, sourceid, pkgid):
        "sourceid should be the name of the table in which to look for this package."
        self.sourceid = sourceid
        self.pkgid = pkgid

        with sqlite3.connect(options.get_database()) as db:
            db.row_factory = sqlite3.Row
            db.text_factory = lambda x: unicode(x, 'utf-8', 'replace')
            # Will set db_entry to None if entry or table doesn't exist.
            try:
                self.db_entry = db.execute('Select * From "%s" Where id=?'
                    % database_update.sanitize_sql(sourceid), (pkgid,)).fetchone()
            except sqlite3.OperationalError:
                self.db_entry = None

        self.exists = self.db_entry is not None
        self.version = PNDVersion(self.db_entry['version'] if self.exists
            else 'A') # This should be the lowest possible version.
Exemplo n.º 7
0
def update_local():
    """Adds a table to the database, adding an entry for each application found
    in the searchpath."""
    # Open database connection.
    with sqlite3.connect(options.get_database()) as db:
        db.row_factory = sqlite3.Row
        # Create table from scratch to hold list of all installed PNDs.
        # Drops it first so no old entries get left behind.
        # TODO: Yes, there are probably more efficient ways than dropping
        # the whole thing, whatever, I'll get to it.
        db.execute('Drop Table If Exists "%s"' % LOCAL_TABLE)
        create_table(db, LOCAL_TABLE)

        # Find PND files on searchpath.
        searchpath = ':'.join(options.get_searchpath())
        search = libpnd.disco_search(searchpath, None)
        if not search:
            raise ValueError("Your install of libpnd isn't behaving right!  pnd_disco_search has returned null.")

        # If at least one PND is found, add each to the database.
        # Note that disco_search returns the path to each *application*.  PNDs with
        # multiple apps will therefore be returned multiple times.  Process any
        # such PNDs only once.
        n = libpnd.box_get_size(search)
        done = set()
        if n > 0:
            node = libpnd.box_get_head(search)
            path = libpnd.box_get_key(node)
            try: update_local_file(path, db)
            except Exception as e:
                warnings.warn("Could not process %s: %s" % (path, repr(e)))
            done.add(path)
            for i in xrange(n-1):
                node = libpnd.box_get_next(node)
                path = libpnd.box_get_key(node)
                if path not in done:
                    try: update_local_file(path, db)
                    except Exception as e:
                        warnings.warn("Could not process %s: %s" % (path, repr(e)))
                    done.add(path)
        db.commit()
Exemplo n.º 8
0
def get_remote_tables():
    """Checks the remote index table to find the names of all tables containing
    data from remote databases.  Returns a list of strings."""
    with sqlite3.connect(options.get_database()) as db:
        c = db.execute('Select url From "%s"' % REPO_INDEX_TABLE)
        return [ i[0] for i in c ]
Exemplo n.º 9
0
def get_all_local():
    """Returns Package object for every installed package."""
    with sqlite3.connect(options.get_database()) as db:
        c = db.execute('Select id From "%s"' % LOCAL_TABLE)
        return [ Package(i[0]) for i in c ]
Exemplo n.º 10
0
            node = libpnd.box_get_head(search)
            path = libpnd.box_get_key(node)
            try: update_local_file(path, db)
            except Exception as e:
                warnings.warn("Could not process %s: %s" % (path, repr(e)))
            done.add(path)
            for i in xrange(n-1):
                node = libpnd.box_get_next(node)
                path = libpnd.box_get_key(node)
                if path not in done:
                    try: update_local_file(path, db)
                    except Exception as e:
                        warnings.warn("Could not process %s: %s" % (path, repr(e)))
                    done.add(path)
        db.commit()



# On import, this will execute, ensuring that necessary tables are created and
# can be depended upon to exist in later code.
with sqlite3.connect(options.get_database()) as db:
    # Index for all repositories to track important info.
    db.execute("""Create Table If Not Exists "%s" (
        url Text Primary Key, name Text, etag Text, last_modified Text,
        updates_url Text, last_update Text, last_full_update Text
        )""" % REPO_INDEX_TABLE)
    # Table of installed PNDs.
    create_table(db, LOCAL_TABLE)

    db.commit()