Home

I Don't Know Why I Wrote This @ 2010-02-14 20:45:01
Filed under: Personal  Code  Tech  Python 
More or less a dictionary store on the network with very simple authentication. I don't know what got into me ... I had no intention of writing this ... hopefully it will be of use to someone. It is a little messy, but it works on Python2.6.

# WHY DID I WRITE THIS?!

import os
import yaml

from multiprocessing import Process
from multiprocessing.managers import BaseManager


class WriteableDict(dict):
    """
    A dictionary which can write to disk.
    """

    def __init__(self, fs_loc, *args, **kwargs):
        """
        Create the instance.

        :Parameters:
           - `fs_loc`: location on disk to write to
           - `args`: all other non-keyword arguments
           - `kwargs`: all other keyword arguments
        """
        dict.__init__(self, *args, **kwargs)
        self.__fs_loc = fs_loc
        self.__saving = None

    def __save_to_disk(self):
        """
        Save to disk.
        """
        # If we are trying to save while anothe save is happening
        # kill the previous save as it's already out of date
        try:
            if self.__saving.is_alive():
                self.__saving.terminate()
            self.__saving.join()
        except:
            pass

        def save(write, data):
            with open(write, 'w') as fs_file:
                fs_file.write(yaml.dump(data.copy()))
            self.__saving = False

        self.__saving = Process(target=save, args=(self.__fs_loc, self))
        self.__saving.daemon = True
        self.__saving.start()

    def update(self, *args, **kwargs):
        """
        Write enabled update.

        :Parameters:
           - `args`: all other non-keyword arguments
           - `kwargs`: all other keyword arguments
        """
        dict.update(self, *args, **kwargs)
        self.__save_to_disk()

    def pop(self, *args, **kwargs):
        """
        Write enabled pop.

        :Parameters:
           - `args`: all other non-keyword arguments
           - `kwargs`: all other keyword arguments
        """
        dict.pop(self, *args, **kwargs)
        self.__save_to_disk()

    def popitem(self, *args, **kwargs):
        """
        Write enabled popitem.

        :Parameters:
           - `args`: all other non-keyword arguments
           - `kwargs`: all other keyword arguments
        """
        dict.popitem(self, *args, **kwargs)
        self.__save_to_disk()

    def clear(self, *args, **kwargs):
        """
        Write enabled clear.

        :Parameters:
           - `args`: all other non-keyword arguments
           - `kwargs`: all other keyword arguments
        """
        dict.clear(self, *args, **kwargs)
        self.__save_to_disk()


class DataBroker(object):

    __data = {}

    def __init__(self, data_loc, auth):
        """
        Creates an instance of the broker and loads any initial data found.

        :Parameters:
           - `data_loc`: directory on disk that houses any .data files to load
           - `auth`: auth information to use
        """
        self.__auth = auth
        self.__data_loc = data_loc
        for loc in filter(lambda s: s.endswith('.data'), os.listdir(data_loc)):
            full_path = os.path.sep.join([data_loc, loc])
            name = os.path.basename(loc).replace('.data', '')
            with open(full_path, 'r') as f_loc:
                self.__data[name] = WriteableDict(
                    full_path, yaml.load(f_loc.read()))

    def __authenticate(self, user, passwd):
        """
        Poor mans authentication.

        :Parameters:
           - `user`: username
           - `pasword`: ... password
        """
        if user in self.__auth.keys():
            if self.__auth[user][0] == passwd:
                return True
        return False

    def get_data(self, user, passwd, name):
        """
        Hands over access to the dictionary.

        :Parameters:
           - `user`: username
           - `password`: password
           - `name`: name of the dictionary to access
        """
        if self.__authenticate(user, passwd):
            if name in self.__auth[user][1]:
                if name not in self.__data.keys():
                    self.__data[name] = WriteableDict(self.__data_loc + name + ".data")
                return self.__data[name]
        raise Exception


class DataManager(BaseManager):
    """
    Data Manager.
    """

    def __init__(self, *args, **kwargs):
        """
        Creates an instance of the manager.

        :Parameters:
           - `args`: all other non-keyword arguments
           - `kwargs`: all other keyword arguments
        """
        BaseManager.__init__(self, *args, **kwargs)
        self.register('get_data',
            callable=lambda u, p, s: broker.get_data(u, p, s))


if __name__ == '__main__':
    # Auth information user: (password (dicts, that, they, can, access))
    auth = {'test': ('testing', ('something', ))}
    # Setup the broker and manager
    broker = DataBroker('/tmp/', auth)
    manager = DataManager(address=('', 50000), authkey='abracadabra')
    # and serve until a ctrl+c
    server = manager.get_server()
    try:
        server.serve_forever()
    except KeyboardInterrupt, ki:
        server.shutdown()

 digg it   seed it   del.icio.us   ma.gnolia
Tags:         Log in to post comments.


 
A Django joint.
© 2007-2009 Steve 'Ashcrow' Milner | Studio7designs | Arbutus Photography