#
#  $Id: OldDirectory.py,v 1.2 1999/12/11 12:35:12 rob Exp $
#
#  Copyright 1999 Rob Tillotson <robt@debian.org>
#  All Rights Reserved
#
#  Permission to use, copy, modify, and distribute this software and
#  its documentation for any purpose and without fee or royalty is
#  hereby granted, provided that the above copyright notice appear in
#  all copies and that both the copyright notice and this permission
#  notice appear in supporting documentation or portions thereof,
#  including modifications, that you you make.
#
#  THE AUTHOR ROB TILLOTSON DISCLAIMS ALL WARRANTIES WITH REGARD TO
#  THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
#  AND FITNESS.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
#  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
#  RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
#  CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
#  CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE!
#
"""Store in a local directory.
"""

__version__ = '$Id: OldDirectory.py,v 1.2 1999/12/11 12:35:12 rob Exp $'

__copyright__ = 'Copyright 1999 Rob Tillotson <robt@debian.org>'

import os, time, struct

import Pyrite
import Pyrite.Store
from Pyrite import protect_name
from Pyrite import pdbfile, Database
from Pyrite import _pdapalm, _


class DirectoryStore(Pyrite.Store.BaseStore):
    properties = ('read','create','delete','list')
    db_properties = ('id-store-nulls',)
    
    def __init__(self, path='.'):
	Pyrite.Store.BaseStore.__init__(self)

	self.path = path

    def open(self, name, mode='rs', dbclass=Database, properties=(), **kw):
	if not self.test_db_properties(properties):
	    raise RuntimeError, _("cannot provide db with properties %s") % properties
	if 'w' in mode:
	    raise RuntimeError, _("cannot open an existing database for write")
	# note: silently opens all files for read only.
	db, n = self._find_db(name, dbclass)
	if not db: raise IOError, _("no such database: %s") % name
	return db

    def create(self, name, creator, type, flags=0, version=1, dbclass=Database,
	       properties = (),
	       filename = None, info=None, **kw):
	if not self.test_db_properties(properties):
	    raise RuntimeError, _("cannot provide db with properties %s") % properties
	if flags is None: flags = 0
	i = { 'name': name,
	      'creator': creator,
	      'type': type,
	      'index': 0,
	      'more': 0,
	      'modnum': 0,
	      'version': version,
	      'createDate': int(time.time()),
	      'modifyDate': int(time.time()),
	      'backupDate': 0,
	      }
	i.update(pdbfile.flags_to_info(flags))
	if info is not None: i.update(info)
	if len(i['name']) > 31: i['name'] = i['name'][:31]

	if not filename:
	    filename = protect_name(name)+(flags & 0x0001 and '.prc' or '.pdb')
	f = _pdapalm.fileCreate(os.path.join(self.path, filename), i)
	info = f.getDBInfo()
	return dbclass(f, info, 'rws', self.db_properties)

    def delete(self, name):
	db, n = self._find_db(name)
	if db is None: raise IOError, _("no such database: %s") % name
	db.close()
	os.unlink(os.path.join(self.path, n))

    def info(self, name):
	db, n = self._find_db(name)
	if db is None: raise IOError, _("no such database: %s") % name
	return db.info

    def list(self):
	return map(lambda x: x[1]['name'], pdbfile.listdir(self.path))

    def listinfo(self, name=None, creator=None, type=None):
	l = []
	for i in map(lambda x: x[1], pdbfile.listdir(self.path)):
	    if name is not None and i['name'] != name: continue
	    if creator is not None and i['creator'] != creator: continue
	    if type is not None and i['type'] != type: continue
	    l.append(i)

	return l	    

    def getpref(self, creator, id, saved=1):
	if saved: db, n = self._find_db('Saved Preferences')
	else: db, n = self._find_db('Unsaved Preferences')
	if db is None: raise RuntimeError, _("preferences database not found")

	for r in db:
	    if r.type == creator and r.id == id:
		v = struct.unpack('>H',r.raw[:2])[0]
		return r.raw[2:], v

	raise RuntimeError, _("preference '%s' %s not found") % (creator, id)
    
    def _try_open_db(self, fname, dbname=None, dbclass=Database):
	try:
	    f = _pdapalm.fileOpen(fname)
	    i = f.getDBInfo()

	    if dbname is None or i['name'] == dbname: return dbclass(f, i, 'rs',
								     self.db_properties)
	    else: return None
	except:
	    return None
	
    def _find_db(self, name, dbclass=Database):
	# dbname.pdb
	n = protect_name(name)+'.pdb'
	db = self._try_open_db(os.path.join(self.path,n), name, dbclass)
	# dbname.prc
	if db is None:
	    n = protect_name(name)+'.prc'
	    db = self._try_open_db(os.path.join(self.path,n), name, dbclass)
	# basic name
	if db is None:
	    n = protect_name(name)
	    db = self._try_open_db(os.path.join(self.path,n), name, dbclass)
	# any arbitrary file
	for n, i in pdbfile.listdir(self.path):
	    if i['name'] == name:
		db = self._try_open_db(os.path.join(self.path,n), name, dbclass)
		break

	return db, n
    

class Store(Pyrite.Store.Store):
    name = 'Directory'
    author = Pyrite.author
    version = Pyrite.version
    description = _("PRC/PDB files in a directory.")
    properties = ['read','create','delete','list']

    store_class = DirectoryStore
