Source

PackageManager / db.py

Full commit
"""This module manages the local packages database. The database is a txt file
in a tab separated format. Internally it's called the "catalogue".
"""

import os
import csv
import contextlib

import sublime

# XXX LocalPackage belongs here.
from package_manager import LocalPackage


_CATALOGUE_DB = os.path.join(sublime.packages_path(), 'PackageManager/catalogue_db.txt')


def fetch_by_any_field(name):
    """Returns a record from the database. :name can be any unique field.
    """
    recs = []
    with open(_CATALOGUE_DB) as f:
        for rec in csv.reader(f, delimiter='\t'):
            if name in rec:
                recs.append(rec)
    
    return (recs[-1] if recs else None)


def gen_records():
    """Returns a generator generating all the records in the databse.
    """
    with open(_CATALOGUE_DB) as f:
        for rec in csv.reader(f, delimiter='\t'):
            yield rec


def reset():
    """Deletes the contents of the database.
    """
    with open(_CATALOGUE_DB, 'w') as f:
        f.write('')


@contextlib.contextmanager
def open_db(mode='r'):
    with open(_CATALOGUE_DB, mode=mode) as f:
        yield f


def purge():
    """Remove duplicates in database. Last wins.
    """
    recs = {}
    for rec in gen_records():
        recs[rec[0]] = rec
    
    with open_db(mode='w') as f:
        writer = csv.writer(f, delimiter='\t')
        for k, v in recs.iteritems():
            writer.writerow(v)


def update_db_info(items=[]):
    if not items: return
    recs = {}
    updated = []
    for rec in gen_records():
        recs[rec[1]] = rec

    for i in items:
        if i in recs.keys():
            lp = LocalPackage(i)
            if not lp.is_installed():
                recs[i][-1] = 'UNINSTALLED'
                updated.append((lp.name, 'UNINSTALLED'))
            elif not lp.is_current():
               recs[i][-1] = 'OLD'
               updated.append((lp.name, 'OLD'))
            else:
                recs[i][-1] = 'CURRENT'
                updated.append((lp.name, 'CURRENT'))
    
    if updated:
        reset()
        with open_db(mode='a') as f:
            for k, v in recs.iteritems():
                f.write('\t'.join(v) + '\n')

    return updated