Source

sphinx-gsoc2009 / sphinx / web / dbutils.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
    sphinx.web.reposums
    ~~~~~~~~~~~~~~~~~~~

    Handle MD5 sums database and checking.
  
    :copyright: Copyright 2007-2009 by the Sphinx team, see AUTHORS.
    :license: BSD, see LICENSE for details.
"""

import cPickle
from sphinx.errors import SphinxError

class PickleLoadSave(object):
    """Basic class for loading and saving pickle files. Contains two methods:
    dbread() and dbsave()."""
    def dbread(self, dbfile):
        try:
            w = open(dbfile)
            data = cPickle.load(w)
            w.close()
        except:
            return {}
        return data

    def dbsave(self, dbfile, data):
        try:
            w = open(dbfile, 'w')
            cPickle.dump(data, w)
            w.close()
        except Exception, err:
            raise SphinxError(err)


class RepoSums(PickleLoadSave):
    def __init__(self, sumsfile):
        self.sumsfile = sumsfile

    def add_record(self, filename, md5sum):
        data = self.dbread(self.sumsfile)
        data[filename] = md5sum
        self.dbsave(self.sumsfile, data)

    def get_record(self, filename):
        data = self.dbread(self.sumsfile)
        return data.get(filename)

    def sum_changed(self, filename, md5sum):
        """Compare the pair filename:md5sum with the pair from the database.

        Return True if the pair with which the method was invoked is not the
        same as the pair saved in the database (also, return True, if the pair
        did not exist in the database before the method was invoked).
        In any of above cases - add a new pair to the database.

        Return False otherwise (e.g. the pairs are the same)."""
        data = self.dbread(self.sumsfile)
        if not data:
            self.add_record(filename, md5sum)
            return True

        dbsum = data.get(filename)
        if dbsum != md5sum:
            self.add_record(filename, md5sum)
            return True
        else:
            return False


class PidDb(PickleLoadSave):
    def __init__(self, dbfile):
        self.dbfile = dbfile
        self.data = self.dbread(self.dbfile)

    def add_record(self, filename, pid, paragraph, save=False):
        """Add a record to the database. 'filename' is key
        for the first-level dictionary, and 'pid' is a key for the
        second-level dictionary. 'paragraph' is a value assigned
        to the second-level dictionary:

        database[filename][pid] = paragraph
        """
        if filename not in self.data:
            self.data[filename] = {}
        else:
            self.data[filename][pid] = paragraph
        if save:
            self.dbsave(self.dbfile, self.data)

    def get_paragraph(self, filename, pid):
        if filename in self.data and pid in self.data[filename]:
            return self.data[filename][pid]
        return None

    def get_pids(self, filename):
        return self.data.get(filename)

    def get_filenames(self):
        return filter(lambda x: x.endswith('.rst'), self.data.keys())