[Zope-dev] Q: adding products, weird behavior

Joerg Wittenberger Joerg Wittenberger <Joerg.Wittenberger@pobox.com>
Mon, 22 Nov 1999 17:21:04 +0100 (CET)


---- =_NextPart_000_01BE9BCA.1CD36B40
Hello,

I'm trying to get a product straight, but I can't find how to add it's
objects programatically the right way(tm).

As explained somewhere (to make things worse, I can't find where I
learned that anymore) I wrote a "manage_addDCDocument" method in my
module, which, AFAIK, should be become a Folder method, in the hope I
could use it like any other e. g., manage_addFile.

When I add such an object via the web, I can actually derive instances
of it (even though I've been wondering, which weird operations I have
to perform inside the object constructor, to find the correct
DestinationURL) but now I tried to use a script derived from
load_site.py I see "manage_addDCDocument Not Found" error.

The load_site.py adds new objects like this:

      call(object.manage_addFile, id=name, file='')

Where object points to the folder, within which the new File object is
to be placed.

I couldn't make head or tail of the code surrounding the problem, base
on wild guess (actually reading the manage_addXYZFom code of ZClass
products) I found the following kludge to work around the problem.
It's so terribly ugly... I beg for help:

      o_kludge = object.__class__(object.url+'/manage_addProduct/docstore',
                 # ==>       F***^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
                              username=object.username,
                              password=object.password)
      call(o_kludge.manage_addDCDocument, id=name, data='')

This o_kludge object shouldn't been needed.  What might I have missed?

For reference I attach 3 files:
  __init__.py      : the product initialization
  DCDocument.py    : the object class I want to use
                     (mirrors the hirarchy in the file system and
                      provides dublin core meta data in rdf format)
  docstore.py      : command line tool to store and retrieve files.

Any help appreciated.

/Jerry

-- 
        You can have it done fast,
        you can have it done cheap,
        and you can have it done well.
        --- But you can only have two of those at once.
---- =_NextPart_000_01BE9BCA.1CD36B40
Content-Type: text/plain;
	name="__init__.py"

# have fun

from Globals import HTMLFile  

import DCDocument, Feature, User

import sys
from zLOG import LOG

def initialize(context):

    perm = 'Add DCDocuments'

    try:
     context.registerClass(
      Feature.Feature,
      permission='Add IBM Features',
      constructors=[Feature.manage_addFeature],
      #icon=''
      )
    except:
      print "%s: %s" % (sys.exc_type, sys.exc_value)
      print 'scheisse'

    try:
     context.registerClass(
      User.IBMUserFolder,
      constructors= (User.manage_addUserFolder,),
      permission='Add Users',
      #icon=''
      )
    except:
      print "%s: %s" % (sys.exc_type, sys.exc_value)
      print 'scheisse'

    context.registerClass(
      DCDocument.DCDocument,
      permission=perm,
      constructors=(DCDocument.manage_addDCDocumentForm,
                    DCDocument.manage_addDCDocument),
      #icon=''
      )

    context.registerBaseClass(DCDocument.DCDocument)




---- =_NextPart_000_01BE9BCA.1CD36B40
Content-Type: text/plain;
	name="DCDocument.py"


""" We add documentation here the other day. """

from OFS.Folder import Folder
import Globals
import ExtensionClass
import DocumentTemplate
from Globals import HTML, HTMLFile, MessageDialog
from DateTime import DateTime

import os, string

from zLOG import LOG

def manage_addDCDocument(self, id, file='', REQUEST=None):
    """ Create a DCDocument """
    if type(file) is not type(''): file=file.read()
    self._setObject(id, DCDocument(id, data=file, REQUEST=REQUEST))
    return self.manage_main(self, REQUEST, update_menu=1)

manage_main=HTMLFile('documentEdit', globals())
manage_addDCDocumentForm=HTMLFile('addDCDocumentForm', globals())

# This should be somewhere else!
def _dropPathSep(path):
    if path[-1] == os.sep: return path[:-1]
    return path

the_publisher = 'IBM Deutschland GmbH'
the_rights = 'all rights reserved'

class DCDocument(Folder):
    """ jojo """

    meta_type   = 'DCDocument'
    description = ''
    index_html=None # Prevent accidental acquisition

    _properties=({'id':'title', 'type':'string', 'mode':'w'},
                 {'id':'creator', 'type':'string', 'mode':'w'},
                 # The subject should better be 'tokens' type
                 {'id':'subject', 'type':'string', 'mode':'w'},
                 {'id':'description', 'type':'text', 'mode':'w'},
                 {'id':'publisher', 'type':'string', 'mode':'w'},
                 #{'id':'contributor', 'type':'string', 'mode':'w'},
                 {'id':'date', 'type':'date', 'mode':''},
                 #{'id':'type', 'type':'string', 'mode':'w'},
                 #{'id':'format', 'type':'string', 'mode':'w'},
                 {'id':'identifier', 'type':'string', 'mode':''},
                 #{'id':'source', 'type':'string', 'mode':'w'},
                 #{'id':'language', 'type':'string', 'mode':'w'},
                 #{'id':'relation', 'type':'string', 'mode':'w'},
                 #{'id':'coverage', 'type':'string', 'mode':'w'},
                 {'id':'rights', 'type':'string', 'mode':'w'},
                 )

    _dc_properties = _properties

    def _init_identifier_ininit(self, id, REQUEST):
        self.id=id
	self.parents = REQUEST['PARENTS']
        self.parents.reverse()
	self.parents=self.parents[2:-2]
        psv=map(lambda i: i.id, self.parents)
        self._setPropValue('identifier', string.join(psv, '/') + '/' + id)

    def _init_other(self, REQUEST):
	self._setPropValue('creator', `REQUEST.AUTHENTICATED_USER`)
	self._setPropValue('date', DateTime().Date())
        self._setPropValue('publisher', the_publisher)
        self._setPropValue('rights', the_rights)
        self.locked = None
	self.manage_changeProperties(REQUEST)

    def __init__(self, id, data=None, REQUEST=None):
        self._init_identifier_ininit(id, REQUEST)
        self._init_other(REQUEST)
        if REQUEST: self.data=REQUEST['data']
        else: self.data=data
	if type(self.data) is not type(''): self.data=self.data.read()
        self._saveData()
        self._saveProperties()
	return ''

    def __str__(self): return self.data

    def _SavePath(self, ext='.sgml', base='/tmp'):
        dirname = os.path.join(base, string.join(map(lambda i: i.id, self.parents), '/'))
        if not os.path.exists(dirname): os.makedirs(dirname)
        return os.path.join(dirname, self.id) + ext

    def _saveData(self, ext='.sgml'):
        path = self._SavePath(ext=ext)
        try:
          f=open(path, 'wb')
        except: raise
        f.write(self.__str__())
        f.close()

    def _saveProperties(self, ext='.rdf'):
        path = self._SavePath(ext=ext)
        try:
          f=open(path, 'w')
        except: raise
        f.write(self.RDF())
        f.close()

    def get_size(self):
	return len(self.__str__())

    def PrincipiaSearchSource(self):
        "Support for searching - the document's contents are searched."
	LOG('Hier', 0, self.data)
        return self.data

    _rdf_header= """<?xml version="1.0" ?>
<rdf:RDF
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns:dc="http://purl.org/dc/elements/1.0/"
>
"""
    def RDF(self, REQUEST=None):
        ' returns the properties as xml '
	md=self._rdf_header
        helpvariable=map(lambda i: i.id, self.parents)
	md = md + ' <rdf:Description about="/' + getattr(self, 'identifier') + '">\n'
	for p in self._dc_properties:
	   n = p['id']
           try:
             v = getattr(self, n)
           except AttributeError:
             v = None
           if v and v != '':
		md=(md + '  <dc:' + n + '>'
                       + DocumentTemplate.DT_Util.html_quote(v)
                       + '</dc:' + n + '>\n')
	md = (md +'  <dc:date>' + self.bobobase_modification_time().Date()
                 + '</dc:date>\n')
	if REQUEST is not None:
	   REQUEST.RESPONSE.setHeader('Content-Type', 'text/xml')
        return md+' </rdf:Description>\n</rdf:RDF>\n'

    _size_changes={
        'Bigger': (5,5),
        'Smaller': (-5,-5),
        'Narrower': (0,-5),
        'Wider': (0,5),
        'Taller': (5,0),
        'Shorter': (-5,0),
        }

    def _er(self,SUBMIT,dtpref_cols,dtpref_rows,REQUEST):
        dr,dc = self._size_changes[SUBMIT]
        
        rows=max(1,string.atoi(dtpref_rows)+dr)
        cols=max(40,string.atoi(dtpref_cols)+dc)
        e=(DateTime('GMT') + 365).rfc822()
        resp=REQUEST['RESPONSE']
        resp.setCookie('dtpref_rows',str(rows),path='/',expires=e)
        resp.setCookie('dtpref_cols',str(cols),path='/',expires=e)

    def manage_edit(self, data, SUBMIT='Change',dtpref_cols='50',
                    dtpref_rows='20', REQUEST=None):
	""" tbc """
        if `REQUEST.AUTHENTICATED_USER` == 'Anonymous User':
           REQUEST.RESPONSE.setStatus(403)
           return MessageDialog(title="Nicht authorisiert",
                                message="Nicht authorisiert")
        if `REQUEST.AUTHENTICATED_USER` != self.locked:
           REQUEST.RESPONSE.setStatus(423)
           return MessageDialog(title="Object locked",
                                message=(getattr(self, 'identifier') +
                                         " ist gelocked durch " +
                                         `self.locked`))
        if self._size_changes.has_key(SUBMIT):
            self._er(SUBMIT,dtpref_cols,dtpref_rows,REQUEST)
	if type(data) is not type(''): data=data.read()
	self.data=data
	self._saveData()
        self.locked=None
	if REQUEST:
		REQUEST.RESPONSE.redirect(REQUEST['URL1'] + '/manage_editForm')

    def manage_getLock(self, REQUEST):
        " tbc "
        if `REQUEST.AUTHENTICATED_USER` == 'Anonymous User':
           REQUEST.RESPONSE.setStatus(403)
           return MessageDialog(title="Nicht authorisiert",
                                message="Nicht authorisiert")
        if not hasattr(self, 'locked') or self.locked is None or `REQUEST.AUTHENTICATED_USER` == self.locked:
           self.locked = `REQUEST.AUTHENTICATED_USER`
        REQUEST.RESPONSE.redirect(REQUEST['URL1'] + '/manage_editForm')

    def manage_unLock(self, REQUEST):
        # " tbc "
        if `REQUEST.AUTHENTICATED_USER` == 'Anonymous User':
           REQUEST.RESPONSE.setStatus(403)
           return MessageDialog(title="Nicht authorisiert",
                                message="Nicht authorisiert")
        if `REQUEST.AUTHENTICATED_USER` == self.locked:
           self.locked = None
        REQUEST.RESPONSE.redirect(REQUEST['URL1'] + '/manage_editForm')

    def manage_editProperties(self, REQUEST):
        """ edit the PRoperties and write the copy into the meta file """
	Folder.manage_editProperties(self, REQUEST)
        self._saveProperties()

    def index_html(self, REQUEST, RESPONSE):
	""" render the document, i.e., give away the plain text """
	if REQUEST: REQUEST.RESPONSE.setHeader('Content-Type', 'text/xml')
	return self.data

    manage_editForm=HTMLFile('documentEdit', globals())

    manage_options=(
        {'label':'Contents', 'action':'manage_editForm'},
        {'label':'Children', 'action':'manage_main'},
        {'label':'View', 'action':''},
        {'label':'Properties', 'action':'manage_propertiesForm'},
        {'label':'Import/Export', 'action':'manage_importExportForm'},
	{'label':'Security', 'action':'manage_access'},
        {'label':'Undo', 'action':'manage_UndoForm'},
	#{'label':'Find', 'action':'manage_findFrame', 'target':'manage_main'},
    )

    __ac_permissions__=(
    ('View management screens',
    ('manage_editForm', 'manage', 'manage_main', 'manage_uploadForm',
     'PrincipiaSearchSource')),
    ('Change DCDocuments',     ('manage_edit', 'manage_upload', 'PUT')),
    ('View', ('__call__', '')),
)

Globals.default__class_init__(DCDocument)
---- =_NextPart_000_01BE9BCA.1CD36B40
Content-Type: text/plain;
	name="docstore.py"

#!/usr/bin/python

import sys, getopt, os, posix, string

usage = """docstore {get|ext|put|create} id..."""

passwordfile = '/.priv/docstore-password'

url = 'http://dev.ffm.tc:9080/ffm.tc'

verbose = 1

def main():
    try:
      cmd = sys.argv[1]
    except IndexError:
      print usage
      sys.exit(1)

    opts, args = getopt.getopt(sys.argv[2:], '')

    if not args:
        print usage
        sys.exit(1)

    sys.path.insert(0,'./lib/python')

    import ZPublisher.Client
    global ServerError
    ServerError=ZPublisher.Client.ServerError

    user = os.environ['USER']
    try:
      f = open(os.environ['HOME']+passwordfile)
      password = f.read()
    except IOError:
      print sys.argv[0] + " can't read " + passwordfile
      sys.exit(1)

    object=ZPublisher.Client.Object(url, username=user, password=password)

    for f in args:
      if cmd == 'ext' or cmd == 'get':
         get_file(object, cmd, f)
      elif cmd == 'put':
         upload_file(object, cmd, f)
      elif cmd == 'create':
         upload_file(object, cmd, f)
      elif cmd == 'unlock':
         print "Unlock unwork"
      elif cmd == 'locate':
         print "locate unwork"
      elif cmd == 'ls':
         print 'ls unwork'
      else:
         print usage

def call(f, *args, **kw):
    # Call a function ignoring redirect bci errors.
    try: apply(f,args, kw)
    except ServerError, v:
        if str(v)[:1] != '3':
            raise sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]

def get_file(object, cmd, f):
    dir, name = os.path.split(f)
    root, ext = os.path.splitext(name)
    if ext in ('.sgml', '.text', '.txt'): name = root
    object = object.__class__(object.url+'/'+name,
                   username=object.username,
                   password=object.password)
    if cmd == 'get':
       call(object.manage_getLock)
    try: posix.chmod(f, 0644)
    except: pass
    out = open(f, "w")
    data = object.index_html()[1]
    out.write(data)
    out.close()
    #n, e = os.path.splitext(f)
    #out = open(n + '.rdf', 'w')
    #data = object.RDF()[1]
    #out.write(data)
    #out.close()

def upload_file(object, cmd, f):
    if os.path.isdir(f): return upload_dir(object, cmd, f)
    dir, name = os.path.split(f)
    root, ext = os.path.splitext(name)
    if ext in ('file', 'dir'): ext=''
    else:
        if ext and ext[0] in '.': ext=ext[1:]
    if ext and globals().has_key('upload_'+ext):
        if verbose: print 'upload_'+ext, f
        return globals()['upload_'+ext](object, cmd, f)

    if verbose: print 'skip_file', f, ext
    #call(object.manage_addFile, id=name, file=open(f))

def upload_dir(object, cmd, f):
    if verbose: print 'upload_dir', f
    dir, name = os.path.split(f)
    if cmd == 'create':
      o_kludge = object.__class__(object.url+'/manage_addProduct/docstore',
                              username=object.username,
                              password=object.password)
      call(o_kludge.manage_addDCDocument, id=name, data='')
    object=object.__class__(object.url+'/'+name,
                              username=object.username,
                              password=object.password)
    for n in os.listdir(f):
        upload_file(object, cmd, os.path.join(f,n))

def upload_sgml(object, cmd, f):
    dir, name = os.path.split(f)
    name, ext = os.path.splitext(name)
    input=open(f)
    input=input.read()
    if cmd == 'create':
       o_kludge = object.__class__(object.url+'/manage_addProduct/docstore',
                              username=object.username,
                              password=object.password)
      call(o_kludge.manage_addDCDocument, id=name, data=input)
    else:
      object=object.__class__(object.url+'/'+name,
                              username=object.username,
                              password=object.password)
      call(object.manage_edit, data=input)
    posix.chmod(f, 0444)

upload_txt=upload_sgml
upload_text=upload_sgml
upload_tex=upload_sgml
    
def upload_ps(object, cmd, f):
    dir, name = os.path.split(f)
    call(object.manage_addFile, id=name, file=open(f))

upload_eps=upload_ps
upload_fig=upload_ps
        
def upload_gif(object, cmd, f):
    dir, name = os.path.split(f)
    call(object.manage_addImage, id=name, file=open(f))

upload_jpg=upload_gif
upload_png=upload_gif

if __name__=='__main__': main()

---- =_NextPart_000_01BE9BCA.1CD36B40--