From waterbug at step.nasa.gov Tue May 1 01:43:35 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Tue May 1 01:43:37 2007 Subject: [pangalactic-commits] Begin work on full part 21 parsing. Message-ID: <200705010543.l415hZBk020962@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/utils/io/part21.py 1.9 1.10 PanGalactic/sandbox/parsers/part21_pyparsing.py 1.1 None PanGalactic/sandbox/parsers/part21_simpleparse.py 1.1 None Log message: Begin work on full part 21 parsing. Index: PanGalactic/pangalactic/utils/io/part21.py diff -u PanGalactic/pangalactic/utils/io/part21.py:1.9 PanGalactic/pangalactic/utils/io/part21.py:1.10 --- PanGalactic/pangalactic/utils/io/part21.py:1.9 Sun Apr 29 02:14:58 2007 +++ PanGalactic/pangalactic/utils/io/part21.py Tue May 1 01:43:33 2007 @@ -1,556 +1,116 @@ #!/usr/bin/env python -# $Id: part21.py,v 1.9 2007/04/29 06:14:58 waterbug Exp $ +# $Id: part21.py,v 1.10 2007/05/01 05:43:33 waterbug Exp $ """ A generic (no dependencies on the rest of PanGalactic) reader/writer for "Part 21 files" (ISO 10303-21, STEP "Clear Text Encoding", a serialization -format). This module reads a STEP Part 21 data file into a set of -Python dictionaries. +format). -@version: $Revision: 1.9 $ +@version: $Revision: 1.10 $ """ -__version__ = "$Revision: 1.9 $"[11:-2] +__version__ = "$Revision: 1.10 $"[11:-2] -import re, sys, string, time +import sys, string from optparse import OptionParser from pprint import pprint -from simpleparse.common import numbers, strings, comments -from simpleparse.parser import Parser -from simpleparse import dispatchprocessor as dp - - -# Part 21 File EBNF syntax specification (informal) - -# Productions whose names are all caps are formally named and specified in ISO -# 10303-21:2002(E). Productions with lower-case names are either "convenience" -# productions invented for this parser, or are specified in ISO 10303-21:2002(E) -# somewhere other than the formal file syntax specification (e.g., the -# attributes of the HEADER entities such as the 'name' attribute of the -# FILE_DESCRIPTION, etc.). - -# us_entity_instance -> "unparsed simple entity instance" -# uc_entity_instance -> "unparsed complex entity instance" -# u_entity_instance -> "unparsed entity instance" - -p21_syntax_all = r''' -STRING := "'", [][ \ta-zA-Z0-9\.+,-:_!"*$%&#,()?/:;<=>@{|}^`~_]*, - "'" -LIST_OF_STRING := '(', STRING?, (comma, STRING)*, ')' -STANDARD_KEYWORD := [A-Z_], [A-Z0-9_]* -USER_DEFINED_KEYWORD := '!', STANDARD_KEYWORD -KEYWORD := USER_DEFINED_KEYWORD/STANDARD_KEYWORD -ENUMERATION := '.', [A-Z], [A-Z0-9]*, '.' -INTEGER := [+-]?, [0-9]+ -BINARY := [0-3], [0-9a-fA-F]+ -ENTITY_INSTANCE_NAME := '#', [0-9]+ - := '\r'?, '\n' - := ';', eol - := ');', eol -simple_content := -simple_terminator*, simple_terminator -complex_content := -complex_terminator*, complex_terminator -us_entity_instance := ts, ENTITY_INSTANCE_NAME, ts, '=', ts, KEYWORD, - simple_content -uc_entity_instance := ts, ENTITY_INSTANCE_NAME, ts, '=', ts, '(', KEYWORD, - complex_content -u_entity_instance := us_entity_instance/uc_entity_instance - := [ \t]* - := ',', ts, eol?, ts - := ts, eol -record := u_entity_instance/(ts, c_comment)/nullline -DATA_SECTION := 'DATA;', record*, ts, 'ENDSEC;', eol -description := LIST_OF_STRING -implementation_level := STRING -FILE_DESCRIPTION := ts, 'FILE_DESCRIPTION(', description, comma, - implementation_level, ');' -name := STRING -timestamp := STRING -authors := LIST_OF_STRING -organization := LIST_OF_STRING -preprocessor_version := STRING -originating_system := STRING -authorization := STRING -FILE_NAME := ts, 'FILE_NAME(', name, comma, timestamp, comma, - authors, comma, organization, comma, - preprocessor_version, comma, originating_system, comma, - authorization, ');', eol -schema_identifier := STRING -object_identifier := STRING -schema_name := schema_identifier, ts, object_identifier? -schema_identifiers := '(', schema_name, (comma, schema_name)*, ')' -FILE_SCHEMA := ts, 'FILE_SCHEMA(', schema_identifiers, ');', eol - := 'HEADER;', eol? - := (ts, c_comment)/nullline -HEADER_SECTION := header_tag, FILE_DESCRIPTION, eol?, FILE_NAME, eol?, - FILE_SCHEMA, ignorable_stuff*, 'ENDSEC;', eol - := 'ISO-10303-21;', eol? -EXCHANGE_FILE := exch_file_tag, ignorable_stuff*, HEADER_SECTION, - ignorable_stuff*, DATA_SECTION, (ignorable_stuff*, - DATA_SECTION)*, ignorable_stuff*, 'END-ISO-10303-21;', - nullline* -''' - -p21_syntax = r''' -ENTITY_INSTANCE_NAME := '#', [0-9]+ -STANDARD_KEYWORD := [A-Z_], [A-Z0-9_]* -USER_DEFINED_KEYWORD := '!', STANDARD_KEYWORD -KEYWORD := USER_DEFINED_KEYWORD/STANDARD_KEYWORD - := '\r'?, '\n' - := ';', eol - := ');', eol -simple_content := -simple_terminator*, simple_terminator -complex_content := -complex_terminator*, complex_terminator -us_entity_instance := ts, ENTITY_INSTANCE_NAME, ts, '=', ts, KEYWORD, - simple_content -uc_entity_instance := ts, ENTITY_INSTANCE_NAME, ts, '=', ts, '(', KEYWORD, - complex_content -u_entity_instance := us_entity_instance/uc_entity_instance - := [ \t]* - := ',', ts, eol?, ts - := ts, eol -record := u_entity_instance/(ts, c_comment)/nullline -DATA_SECTION := 'DATA;', record*, ts, 'ENDSEC;', eol -header_tag := 'HEADER;', eol? -end_tag := 'ENDSEC;', eol - := (ts, c_comment)/nullline -HEADER_SECTION := header_tag, -end_tag*, end_tag - := 'ISO-10303-21;', eol? -EXCHANGE_FILE := exch_file_tag, ignorable_stuff*, HEADER_SECTION, - ignorable_stuff*, DATA_SECTION, (ignorable_stuff*, - DATA_SECTION)*, ignorable_stuff*, 'END-ISO-10303-21;', - nullline* -''' - - -class Part21Parser(Parser): - """ - Parser for Part 21 files. - """ - - def __init__(self, *arg): - Parser.__init__(self, *arg) - self.res = {} - - def buildProcessor(self): - return Part21Processor(self.res) - - -class Part21Processor(dp.DispatchProcessor): - """ - Processing object for postprocessing the Part 21 grammar definitions into a - new generator. - """ - - def __init__(self, res): - self.res = res - - def STRING(self, (tag, start, stop, subtags), buffer): - """ - Process C{STRING} production. - """ - return (tag, start, stop, subtags) - - def LIST_OF_STRING(self, (tag, start, stop, subtags), buffer): - """ - Process C{LIST_OF_STRING} production. - """ - value = [] - if subtags: - value = [dp.getString(s) for s in subtags] - return value - - def KEYWORD(self, (tag, start, stop, subtags), buffer): - """ - Process C{KEYWORD} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def STANDARD_KEYWORD(self, (tag, start, stop, subtags), buffer): - """ - Process C{STANDARD_KEYWORD} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def USER_DEFINED_KEYWORD(self, (tag, start, stop, subtags), buffer): - """ - Process C{USER_DEFINED_KEYWORD} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def ENUMERATION(self, (tag, start, stop, subtags), buffer): - """ - Process C{ENUMERATION} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def INTEGER(self, (tag, start, stop, subtags), buffer): - """ - Process C{INTEGER} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def BINARY(self, (tag, start, stop, subtags), buffer): - """ - Process C{BINARY} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def ENTITY_INSTANCE_NAME(self, (tag, start, stop, subtags), buffer): - """ - Process C{ENTITY_INSTANCE_NAME} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def simple_content(self, (tag, start, stop, subtags), buffer): - """ - Process C{simple_content} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def complex_content(self, (tag, start, stop, subtags), buffer): - """ - Process C{complex_content} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def us_entity_instance(self, (tag, start, stop, subtags), buffer): - """ - Process C{us_entity_instance} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def uc_entity_instance(self, (tag, start, stop, subtags), buffer): - """ - Process C{uc_entity_instance} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def u_entity_instance(self, (tag, start, stop, subtags), buffer): - """ - Process C{u_entity_instance} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def record(self, (tag, start, stop, subtags), buffer): - """ - Process C{record} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def DATA_SECTION(self, (tag, start, stop, subtags), buffer): - """ - Process C{DATA_SECTION} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def description(self, (tag, start, stop, subtags), buffer): - """ - Process C{description} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def implementation_level(self, (tag, start, stop, subtags), buffer): - """ - Process C{implementation_level} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def FILE_DESCRIPTION(self, (tag, start, stop, subtags), buffer): - """ - Process C{FILE_DESCRIPTION} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def name(self, (tag, start, stop, subtags), buffer): - """ - Process C{name} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def timestamp(self, (tag, start, stop, subtags), buffer): - """ - Process C{timestamp} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def authors(self, (tag, start, stop, subtags), buffer): - """ - Process C{authors} production. - """ - self.res['authors'] = [] - if subtags: - self.res['authors'] = self.LIST_OF_STRING(subtags[0]) - - def organization(self, (tag, start, stop, subtags), buffer): - """ - Process C{organization} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def preprocessor_version(self, (tag, start, stop, subtags), buffer): - """ - Process C{preprocessor_version} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def originating_system(self, (tag, start, stop, subtags), buffer): - """ - Process C{originating_system} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def authorization(self, (tag, start, stop, subtags), buffer): - """ - Process C{authorization} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def FILE_NAME(self, (tag, start, stop, subtags), buffer): - """ - Process C{FILE_NAME} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def schema_identifier(self, (tag, start, stop, subtags), buffer): - """ - Process C{schema_identifier} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def object_identifier(self, (tag, start, stop, subtags), buffer): - """ - Process C{object_identifier} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def schema_name(self, (tag, start, stop, subtags), buffer): - """ - Process C{schema_name} production. - """ - self.res['schema_name'] = dp.getString((tag, start, stop, subtags), - buffer) - - def schema_identifiers(self, (tag, start, stop, subtags), buffer): - """ - Process C{schema_identifiers} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - def FILE_SCHEMA(self, (tag, start, stop, subtags), buffer): - """ - Process C{FILE_SCHEMA} production. - """ - self.res['FILE_SCHEMA'] = dp.getString((tag, start, stop, subtags), - buffer) - - def HEADER_SECTION(self, (tag, start, stop, subtags), buffer): - """ - Process C{HEADER_SECTION} production. - """ - return (tag, start, stop, subtags) - - def EXCHANGE_FILE(self, (tag, start, stop, subtags), buffer): - """ - Process C{EXCHANGE_FILE} production. - """ - return dp.getString((tag, start, stop, subtags), buffer) - - -def read(f=None, perf=False, verbose=False, test=False): - # NOTE: test is always True for now ... - """ - (These docs are fiction at the moment ... ;) - - Read a STEP Part 21 file/stream and return a set of Python dictionaries. - - @param f: path to a file containing STEP Part 21 data - @type f: C{str} - - @param null: a value to use for nulls in the data, which are - represented by '$' in Part 21. Attributes with null values will not - be included in the instance dictionaries unless a value is supplied - for null, in which case they will be included with that value - @type null: C{str} - - @return: a dictionary of instance dictionaries, mapped by their - C{id} attributes. - - {id-1 : {attr:value, ...}, - id-2 : {attr:value, ...}, - ...} - - ... where each C{id-n} attribute is of the form '#'+str(int) and - must be unique within the dataset. - - @rtype: C{dict} - """ - p = Parser(p21_syntax) - if f: - data = open(f).read() - if perf: - start = time.clock() - success, res, nextchar = p.parse(data, production='EXCHANGE_FILE') - if perf: - end = time.clock() - print "\nTotal parse time: %6.2f sec" % (end - start) - print len(data.split("\n"))," lines\n" - if test: - print '---------------' - print 'Sample of Data:' - print '---------------' - sample = data[:100] - print sample - print '\n------------' - print 'Result Tree:' - print '------------' - # print res - pprint(res) - else: - print '\n------------' - print 'Result Tree:' - print '------------' - # print res - pprint(res) - rd = makeResDict(res, data) - print '\n------------' - print 'Result Dict:' - print '------------\n' - pprint(rd) - elif test: - # run all tests on p21_syntax - from pangalactic.test import test_part21 - for production, test_data in test_part21.tests.items(): - if verbose: - print '* production:', production - for data in test_data: - success, children, nextcharacter = p.parse(data, - production=production) - assert success and nextcharacter==len(data), ''.join([ - "Wasn't able to parse %s as a %s " % ( - repr(data), production), - "(%s chars parsed of %s), returned value was %s" % ( - nextcharacter, len(data), - (success, children, nextcharacter)) - ]) - if verbose: - print ' * data:', data - print ' * output:' - pprint(p.parse(data, production=production)) - print - elif success: - print ' * passed: ', production - else: - pass - -def makeResDict(res, data): - """ - Create a dictionary from a result tree. - """ - next = res - rd = {} - while next: - this_level = next - next = [] - for e in this_level: - if e[3]: - rd[e[0]] = e[3] or data[e[1]:e[2]] - next += e[3] - return rd - -### THIS APPROACH IS ON HOLD FOR NOW ################### -# -# def processChildren(children, data): -# """ -# Process the children; if there are any primitives among the children, return -# their values. -# """ -# -# if len(children) == 1 and -# for child in children: -# f = primitives.get(child[0]) -# if f: -# -# -# primitives = ['STRING' : -# 'LIST_OF_STRING', [dp.getString(s) for s in subtags] -# 'INTEGER', -# 'ENUMERATION', -# 'BINARY', -# 'ENTITY_INSTANCE_NAME', -# 'STANDARD_KEYWORD', -# 'simple_content', -# 'complex_content'] -# -# def list_of_string(x): -# return [dp.getString(s) for s in subtags] - -def write(dataset, schema='pgef', fname='out.p21', description='', - null='$', wrap='element'): - """ - Write a dataset out to a Part 21 file/stream. - - @param dataset: a dictionary of dictionaries of the form: - - {id-1 : {attr:value, ...}, - id-2 : {attr:value, ...}, - ...} - - ... where each C{id-n} attribute is of the form '#'+str(int) and - must be unique within the dataset. - - @type dataset: C{dict} - - @param schema: name of the schema governing the data - @type schema: C{str} - - @param fname: the name of the file to write to - @type fname: C{str} - - @param description: some text describing the data - @type description: C{str} - - @param null: a value to use for nulls in the data, which are - represented by '$' in Part 21. Attributes with null values will not be - included in the instance dictionaries unless a value is supplied for - null, in which case they will be included with that value - @type null: C{str} - - @param wrap: type of wrapping to use for output: - - 'element' : wrap elements - 'pprint' : wrap elements and attributes - otherwise : no wrap (any other value of 'wrap') - - @type wrap: C{str} - """ - f = file(fname, 'w') - f.write('Part 21 File\n') - f.close() +from pyparsing import Word, Optional, Forward, ZeroOrMore +from pyparsing import delimitedList + +# added by Paul McGuire (thanks, Paul!) +from pyparsing import Combine,sglQuotedString,Group,Suppress,removeQuotes +from pyparsing import Dict,OneOrMore,cppStyleComment + +from pangalactic.utils.io.part21_preparse + +import time +time.clock() + +def groupInParens(expr): + return Group(Suppress("(") + expr + Suppress(")")) + +pre = '0123' +HEX = string.hexdigits +BINARY = Word(pre, HEX) + +DIGIT = string.digits +LOWER = string.lowercase +UPPER = string.uppercase + '_' +SPECIAL = '!"*$%&.#+,-()?/:;<=>@[]{|}^`~' +REVERSE_SOLIDUS = '\\' +APOSTROPHE = "'" +SIGN = Word('+-', max=1) +CHARACTER = Word((' ' + DIGIT + LOWER + UPPER + SPECIAL + REVERSE_SOLIDUS + + APOSTROPHE), max=1) +NON_Q_CHAR = Word((' ' + DIGIT + LOWER + UPPER + SPECIAL), max=1) +STRING = sglQuotedString.setParseAction(removeQuotes) +ENUMERATION = Combine('.' + Word(UPPER, UPPER + DIGIT) + '.') +ENTITY_INSTANCE_NAME = Word('#',DIGIT) + +REAL = Combine(Optional(SIGN) + Word(DIGIT) + "." + Optional(Word(DIGIT)) + + Optional('E' + Optional(SIGN) + Word(DIGIT))) +INTEGER = Word('+-'+DIGIT,DIGIT) +STANDARD_KEYWORD = Word(UPPER, UPPER + DIGIT) +USER_DEFINED_KEYWORD = Combine('!' + STANDARD_KEYWORD) +KEYWORD = USER_DEFINED_KEYWORD | STANDARD_KEYWORD + +OMITTED_PARAMETER = '*' +LIST = Forward() +UNTYPED_PARAMETER = Forward() +PARAMETER = Forward() +TYPED_PARAMETER = Forward() +PARAMETER_LIST = Forward() +LIST << groupInParens( Optional(PARAMETER_LIST) ) + +# replacing '^' with '|' in the next two expressions accounted for most of the performance speedup +UNTYPED_PARAMETER << ("$" | REAL | INTEGER | STRING | ENTITY_INSTANCE_NAME + | ENUMERATION | BINARY | LIST) +PARAMETER << (TYPED_PARAMETER | UNTYPED_PARAMETER | OMITTED_PARAMETER) +TYPED_PARAMETER << (KEYWORD + groupInParens( PARAMETER )) +PARAMETER_LIST << Group(delimitedList(PARAMETER, delim=',')) +unparsed_record = KEYWORD + groupInParens('.*') +SIMPLE_RECORD = KEYWORD + groupInParens( Optional(PARAMETER_LIST) ) +SIMPLE_RECORD_LIST = SIMPLE_RECORD + ZeroOrMore(SIMPLE_RECORD) +SUBSUPER_RECORD = groupInParens( SIMPLE_RECORD_LIST ) +#~ COMPLEX_ENTITY_INSTANCE = ENTITY_INSTANCE_NAME + '=' + SUBSUPER_RECORD + ';' +#~ ENTITY_INSTANCE = (SIMPLE_ENTITY_INSTANCE ^ COMPLEX_ENTITY_INSTANCE) +ENTITY_INSTANCE = Group(ENTITY_INSTANCE_NAME + '=' + ( SIMPLE_RECORD | SUBSUPER_RECORD ) + ';') +ENTITY_INSTANCE_LIST = ZeroOrMore(ENTITY_INSTANCE) + +DATA_SECTION = ('DATA' + Optional( groupInParens( PARAMETER_LIST ).setResultsName("PARAMETERS")) + ';' + Dict(ENTITY_INSTANCE_LIST) + 'ENDSEC;') + +HEADER_ENTITY = KEYWORD + groupInParens( Optional(PARAMETER_LIST) ) + ";" +HEADER_ENTITY_LIST = HEADER_ENTITY + ZeroOrMore(HEADER_ENTITY) +HEADER_SECTION = ("HEADER;" + HEADER_ENTITY + HEADER_ENTITY + HEADER_ENTITY + + Optional(HEADER_ENTITY_LIST) + "ENDSEC;") +EXCHANGE_FILE = ("ISO-10303-21;" + HEADER_SECTION.setResultsName("HEADER") + + OneOrMore(DATA_SECTION).setResultsName("DATA") + "END-ISO-10303-21;") +EXCHANGE_FILE.ignore(cppStyleComment) if __name__ == '__main__': usage = 'usage: %prog [options] file.p21' optparser = OptionParser(usage) - optparser.add_option("-p", "--perf", action='store_true', - dest="performance", default=False, - help="run the parser's unit tests") - optparser.add_option("-t", "--test", action='store_true', - dest="test", default=False, - help="run the parser's unit tests") - optparser.add_option("-v", "--verbose", action='store_true', - dest="verbose", default=False, - help="verbose output from test (no effect on normal function)") - (options, args) = optparser.parse_args(args=sys.argv) - # debugging: - # print "options: %s" % str(options) - # print "args: %s" % str(args) - if len(args) > 1: - read(f=args[1], - perf=options.performance, - verbose=options.verbose, - test=options.test) - elif options.test: - read(test=True, - perf=options.performance, - verbose=options.verbose) - else: - optparser.print_help() + optparser.add_option("-t", "--time", action='store_true', + dest="show_time", default=False, + help="show the time consumed") + (options, args) = optparser.parse_args(args=sys.argv[1:] or ['-h']) + if args[0] != '-h': + data = open(args[0]).read() + if options.show_time: + startTime = time.clock() + res = EXCHANGE_FILE.parseString(data) + if options.show_time: + endTime = time.clock() + totalTime = endTime - startTime + print "\nTotal parse time: %6.2f sec" % totalTime + print len(data.split("\n"))," lines\n" + # pprint( res.asList() ) + print res.HEADER + keylist = list(res.DATA.keys()) + # print '\nitem IDs are:', keylist + print '\nfirst 10 items are:' + for k in range(10): + print keylist[k], res.DATA[keylist[k]][1], res.DATA[keylist[k]][2] + print '\nlast 10 items are:' + for k in range(11)[1:]: + print keylist[(-1)*k], res.DATA[keylist[(-1)*k]][1], res.DATA[keylist[(-1)*k]][2] From waterbug at step.nasa.gov Thu May 3 12:27:18 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Thu May 3 12:27:20 2007 Subject: [pangalactic-commits] Mainly refinements to part 21 file parsing ... Message-ID: <200705031627.l43GRIWY024575@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/node/pangalaxian.py 1.183 1.184 PanGalactic/pangalactic/test/test_part21_preparse.py 1.2 1.3 PanGalactic/pangalactic/utils/io/import_assembly.py None 1.1 PanGalactic/pangalactic/utils/io/part21.py 1.10 1.11 PanGalactic/pangalactic/utils/io/part21_preparse.py 1.3 1.4 Log message: Mainly refinements to part 21 file parsing ... also, a "demo" application (get assemblies from a file). Index: PanGalactic/pangalactic/test/test_part21_preparse.py diff -u PanGalactic/pangalactic/test/test_part21_preparse.py:1.2 PanGalactic/pangalactic/test/test_part21_preparse.py:1.3 --- PanGalactic/pangalactic/test/test_part21_preparse.py:1.2 Mon Apr 30 15:43:55 2007 +++ PanGalactic/pangalactic/test/test_part21_preparse.py Thu May 3 12:27:15 2007 @@ -1,10 +1,10 @@ -# $Id: test_part21_preparse.py,v 1.2 2007/04/30 19:43:55 waterbug Exp $ +# $Id: test_part21_preparse.py,v 1.3 2007/05/03 16:27:15 waterbug Exp $ """ Tests for STEP Part 21 file parsing -@version: $Revision: 1.2 $ +@version: $Revision: 1.3 $ """ -__version__ = "$Revision: 1.2 $"[11:-2] +__version__ = "$Revision: 1.3 $"[11:-2] tests = { @@ -52,15 +52,13 @@ """#57=DATE_TIME_ROLE('classification_date'); """, """#58=APPROVAL_DATE_TIME(#50,#21); +""", + """#167=APPLICATION_CONTEXT +('CONFIGURATION CONTROLLED 3D DESIGNS OF MECHANICAL PARTS AND ASSEMBLIES'); """ ], 'complex_instance' : [ - """#90=(GEOMETRIC_REPRESENTATION_CONTEXT(3) - GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#91)) - GLOBAL_UNIT_ASSIGNED_CONTEXT((#92,#93,#94)) - REPRESENTATION_CONTEXT('','')); -""", """#92=(LENGTH_UNIT() NAMED_UNIT(*) SI_UNIT(.MILLI.,.METRE.)); """, """#93=(NAMED_UNIT(*) PLANE_ANGLE_UNIT() SI_UNIT($,.RADIAN.)); Index: PanGalactic/pangalactic/utils/io/part21_preparse.py diff -u PanGalactic/pangalactic/utils/io/part21_preparse.py:1.3 PanGalactic/pangalactic/utils/io/part21_preparse.py:1.4 --- PanGalactic/pangalactic/utils/io/part21_preparse.py:1.3 Mon Apr 30 15:43:56 2007 +++ PanGalactic/pangalactic/utils/io/part21_preparse.py Thu May 3 12:27:16 2007 @@ -1,14 +1,14 @@ #!/usr/bin/env python -# $Id: part21_preparse.py,v 1.3 2007/04/30 19:43:56 waterbug Exp $ +# $Id: part21_preparse.py,v 1.4 2007/05/03 16:27:16 waterbug Exp $ """ A generic (no dependencies on the rest of PanGalactic) reader/writer for "Part 21 files" (ISO 10303-21, STEP "Clear Text Encoding", a serialization format). This module reads a STEP Part 21 data file into a set of Python dictionaries. -@version: $Revision: 1.3 $ +@version: $Revision: 1.4 $ """ -__version__ = "$Revision: 1.3 $"[11:-2] +__version__ = "$Revision: 1.4 $"[11:-2] import re, sys, string, time from optparse import OptionParser @@ -37,14 +37,14 @@ ENTITY_INSTANCE_NAME := '#', [0-9]+ KEYWORD := [A-Z_], [A-Z0-9_]* := '\r'?, '\n' - := ';', eol - := ');', eol -simple_content := -simple_terminator*, simple_terminator -complex_content := -complex_terminator*, complex_terminator + := ')', ts, ';', eol +parameter_list := -record_terminator, -record_terminator* simple_instance := ts, ENTITY_INSTANCE_NAME, ts, '=', ts, KEYWORD, - simple_content -complex_instance := ts, ENTITY_INSTANCE_NAME, ts, '=', ts, '(', KEYWORD, - complex_content + ts, eol?, '(', parameter_list, record_terminator +instance_list := KEYWORD, ts, eol?, '(', parameter_list, ')', ts, eol?, + (KEYWORD, '(', parameter_list, ')', ts, eol?)* +complex_instance := ts, ENTITY_INSTANCE_NAME, ts, '=', ts, '(', + parameter_list, record_terminator := [ \t]* := ',', ts, eol?, ts := ts, eol @@ -65,9 +65,9 @@ ''' -class Part21Parser(Parser): +class Part21Preparser(Parser): """ - Parser for Part 21 files. + Preparser for Part 21 files. """ def __init__(self, *arg): @@ -104,17 +104,22 @@ """ return dp.getString((tag, start, stop, subtags), buffer) - def simple_content(self, (tag, start, stop, subtags), buffer): + def parameter_list(self, (tag, start, stop, subtags), buffer): """ Process C{simple_content} production. """ return dp.getString((tag, start, stop, subtags), buffer) - def complex_content(self, (tag, start, stop, subtags), buffer): + def instance_list(self, (tag, start, stop, subtags), buffer): """ Process C{complex_content} production. + + @return: a 2-tuple of (keywords, parameter lists), where keywords is + the list of KEYWORD occurrences and parameter lists is a list of + strings (each of which is an unparsed parameter list). """ - return dp.getString((tag, start, stop, subtags), buffer) + inst = dp.multiMap((tag, start, stop, subtags), buffer) + return inst.get('KEYWORD'), inst.get('parameter_list') def simple_instance(self, (tag, start, stop, subtags), buffer): """ @@ -122,7 +127,7 @@ """ inst = dp.singleMap(subtags, self, buffer) self.res['contents'][ - inst.get('ENTITY_INSTANCE_NAME')] = inst.get('simple_content') + inst.get('ENTITY_INSTANCE_NAME')] = inst.get('parameter_list') self.res['insttype'][ inst.get('ENTITY_INSTANCE_NAME')] = inst.get('KEYWORD') @@ -132,9 +137,9 @@ """ inst = dp.singleMap(subtags, self, buffer) self.res['contents'][ - inst.get('ENTITY_INSTANCE_NAME')] = inst.get('complex_content') + inst.get('ENTITY_INSTANCE_NAME')] = inst.get('parameter_list') self.res['insttype'][ - inst.get('ENTITY_INSTANCE_NAME')] = inst.get('KEYWORD') + inst.get('ENTITY_INSTANCE_NAME')] = 'complex_type' def HEADER_SECTION(self, (tag, start, stop, subtags), buffer): """ @@ -143,7 +148,7 @@ self.res['header'] = dp.getString((tag, start, stop, subtags), buffer) -def read(f=None, perf=False, verbose=False, test=False): +def readStepFile(f=None, perf=False, verbose=False, test=False): # NOTE: test is always True for now ... """ (These docs are fiction at the moment ... ;) @@ -159,19 +164,14 @@ for null, in which case they will be included with that value @type null: C{str} - @return: a dictionary of instance dictionaries, mapped by their - C{id} attributes. - - {id-1 : {attr:value, ...}, - id-2 : {attr:value, ...}, - ...} - - ... where each C{id-n} attribute is of the form '#'+str(int) and - must be unique within the dataset. - + @return: a result C{dict} that contains 3 items: (1) 'header', the + unparsed header section of the part 21 file; (2) 'contents', a C{dict} + that maps entity instance numbers (production: 'ENTITY_INSTANCE_NAME') + to their unparsed content; and (3) 'insttype', a C{dict} that maps + entity instance numbers to their declared types (production: 'KEYWORD'). @rtype: C{dict} """ - p = Part21Parser(p21_syntax) + p = Part21Preparser(p21_syntax) if f: data = open(f).read() if perf: @@ -187,10 +187,11 @@ print '---------------' sample = data[:100] print sample - print '\n------------' - print 'Result Tree:' - print '------------' - pprint(p.res) + # print '\n------------' + # print 'Result Tree:' + # print '------------' + # pprint(p.res) + return p.res elif test: # run all tests on p21_syntax from pangalactic.test import test_part21_preparse as tpp @@ -278,14 +279,14 @@ # print "options: %s" % str(options) # print "args: %s" % str(args) if len(args) > 1: - read(f=args[1], - perf=options.performance, - verbose=options.verbose, - test=options.test) + readStepFile(f=args[1], + perf=options.performance, + verbose=options.verbose, + test=options.test) elif options.test: - read(test=True, - perf=options.performance, - verbose=options.verbose) + readStepFile(test=True, + perf=options.performance, + verbose=options.verbose) else: optparser.print_help() Index: PanGalactic/pangalactic/utils/io/part21.py diff -u PanGalactic/pangalactic/utils/io/part21.py:1.10 PanGalactic/pangalactic/utils/io/part21.py:1.11 --- PanGalactic/pangalactic/utils/io/part21.py:1.10 Tue May 1 01:43:33 2007 +++ PanGalactic/pangalactic/utils/io/part21.py Thu May 3 12:27:16 2007 @@ -1,13 +1,13 @@ #!/usr/bin/env python -# $Id: part21.py,v 1.10 2007/05/01 05:43:33 waterbug Exp $ +# $Id: part21.py,v 1.11 2007/05/03 16:27:16 waterbug Exp $ """ A generic (no dependencies on the rest of PanGalactic) reader/writer for "Part 21 files" (ISO 10303-21, STEP "Clear Text Encoding", a serialization format). -@version: $Revision: 1.10 $ +@version: $Revision: 1.11 $ """ -__version__ = "$Revision: 1.10 $"[11:-2] +__version__ = "$Revision: 1.11 $"[11:-2] import sys, string from optparse import OptionParser @@ -19,7 +19,7 @@ from pyparsing import Combine,sglQuotedString,Group,Suppress,removeQuotes from pyparsing import Dict,OneOrMore,cppStyleComment -from pangalactic.utils.io.part21_preparse +from pangalactic.utils.io.part21_preparse import Part21Preparser import time time.clock() Index: PanGalactic/pangalactic/node/pangalaxian.py diff -u PanGalactic/pangalactic/node/pangalaxian.py:1.183 PanGalactic/pangalactic/node/pangalaxian.py:1.184 --- PanGalactic/pangalactic/node/pangalaxian.py:1.183 Wed Apr 25 13:47:47 2007 +++ PanGalactic/pangalactic/node/pangalaxian.py Thu May 3 12:27:15 2007 @@ -2,16 +2,16 @@ # -*- coding: ANSI_X3.4-1968 -*- # generated by wxGlade 0.3.5.1 on Tue Feb 1 00:19:02 2005 -# $Id: pangalaxian.py,v 1.183 2007/04/25 17:47:47 waterbug Exp $ +# $Id: pangalaxian.py,v 1.184 2007/05/03 16:27:15 waterbug Exp $ """ Main application module for PanGalaxian, the PGEF GUI client. WE ARE THE PANGALAXIANS! :) -@version: $Revision: 1.183 $ +@version: $Revision: 1.184 $ """ -__version__ = "$Revision: 1.183 $"[11:-2] +__version__ = "$Revision: 1.184 $"[11:-2] # Python import logging @@ -111,6 +111,10 @@ id=wx.ID_ANY, text="Log&out", help="Logout from repository ...") + self.file_import = self.file_menu.Append( + id=wx.ID_ANY, + text="&Import...", + help="Import data from file ...") # self.file_export = self.file_menu.Append( # id=wx.ID_ANY, # text="&Export", @@ -473,6 +477,7 @@ self.Bind(wx.EVT_MENU, self.onNewObject, self.file_object) self.Bind(wx.EVT_MENU, self.openFullLoginDialog, self.file_login) self.Bind(wx.EVT_MENU, self.onLogout, self.file_logout) + self.Bind(wx.EVT_MENU, self.onImport, self.file_import) # self.Bind(wx.EVT_MENU, self.onExport, self.file_export) self.Bind(wx.EVT_MENU, self.onExit, self.file_exit) # @@ -579,6 +584,14 @@ self.log.info(' Wizard was cancelled') wizard.Destroy() + def onImport(self, event): + """ + Import data from a file. + """ + # TODO: create a Wizard for the import process + self.log.info(' - PanGalaxian.onImport') + + def updateProjects(self): """ Update the C{projects} instance variable, if necessary. From waterbug at step.nasa.gov Thu May 3 16:29:11 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Thu May 3 16:29:12 2007 Subject: [pangalactic-commits] Point commit for demo. Message-ID: <200705032029.l43KTBPb030891@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/utils/io/import_assembly.py 1.1 1.2 PanGalactic/pangalactic/utils/io/part21_preparse.py 1.4 1.5 Log message: Point commit for demo. Index: PanGalactic/pangalactic/utils/io/part21_preparse.py diff -u PanGalactic/pangalactic/utils/io/part21_preparse.py:1.4 PanGalactic/pangalactic/utils/io/part21_preparse.py:1.5 --- PanGalactic/pangalactic/utils/io/part21_preparse.py:1.4 Thu May 3 12:27:16 2007 +++ PanGalactic/pangalactic/utils/io/part21_preparse.py Thu May 3 16:29:09 2007 @@ -1,14 +1,14 @@ #!/usr/bin/env python -# $Id: part21_preparse.py,v 1.4 2007/05/03 16:27:16 waterbug Exp $ +# $Id: part21_preparse.py,v 1.5 2007/05/03 20:29:09 waterbug Exp $ """ A generic (no dependencies on the rest of PanGalactic) reader/writer for "Part 21 files" (ISO 10303-21, STEP "Clear Text Encoding", a serialization format). This module reads a STEP Part 21 data file into a set of Python dictionaries. -@version: $Revision: 1.4 $ +@version: $Revision: 1.5 $ """ -__version__ = "$Revision: 1.4 $"[11:-2] +__version__ = "$Revision: 1.5 $"[11:-2] import re, sys, string, time from optparse import OptionParser @@ -87,10 +87,12 @@ def __init__(self, res): self.res = res # TODO: set this up as a sqlite database - # contents: maps ent inst nbr (n) to unparsed content - # insttype: maps ent inst nbr (n) to KEYWORD (i.e. type) + # contents: maps entity inst nbr (n) to unparsed content + # insttype: maps entity inst nbr (n) to KEYWORD (i.e. type) + # insttype: maps KEYWORD (i.e. type) (n) to entity inst nbr self.res['contents'] = {} self.res['insttype'] = {} + self.res['typeinst'] = {} def ENTITY_INSTANCE_NAME(self, (tag, start, stop, subtags), buffer): """ @@ -130,6 +132,12 @@ inst.get('ENTITY_INSTANCE_NAME')] = inst.get('parameter_list') self.res['insttype'][ inst.get('ENTITY_INSTANCE_NAME')] = inst.get('KEYWORD') + try: + self.res['typeinst'][ + inst.get('KEYWORD')].append(inst.get('ENTITY_INSTANCE_NAME')) + except: + self.res['typeinst'][ + inst.get('KEYWORD')] = [inst.get('ENTITY_INSTANCE_NAME')] def complex_instance(self, (tag, start, stop, subtags), buffer): """ @@ -140,6 +148,12 @@ inst.get('ENTITY_INSTANCE_NAME')] = inst.get('parameter_list') self.res['insttype'][ inst.get('ENTITY_INSTANCE_NAME')] = 'complex_type' + try: + self.res['typeinst'][ + inst.get('KEYWORD')].append(inst.get('ENTITY_INSTANCE_NAME')) + except: + self.res['typeinst'][ + inst.get('KEYWORD')] = [inst.get('ENTITY_INSTANCE_NAME')] def HEADER_SECTION(self, (tag, start, stop, subtags), buffer): """ @@ -180,17 +194,17 @@ if perf: end = time.clock() print "\nTotal parse time: %6.2f sec" % (end - start) - print len(data.split("\n"))," lines\n" + print len(list(p.res.get('contents', [])))," instances\n" if test: print '---------------' print 'Sample of Data:' print '---------------' sample = data[:100] print sample - # print '\n------------' - # print 'Result Tree:' - # print '------------' - # pprint(p.res) + print '\n------------' + print 'Result Tree:' + print '------------' + pprint(p.res) return p.res elif test: # run all tests on p21_syntax Index: PanGalactic/pangalactic/utils/io/import_assembly.py diff -u PanGalactic/pangalactic/utils/io/import_assembly.py:1.1 PanGalactic/pangalactic/utils/io/import_assembly.py:1.2 --- PanGalactic/pangalactic/utils/io/import_assembly.py:1.1 Thu May 3 12:27:16 2007 +++ PanGalactic/pangalactic/utils/io/import_assembly.py Thu May 3 16:29:09 2007 @@ -1,3 +1,4 @@ +from pprint import pprint from pangalactic.utils.io.part21 import PARAMETER_LIST from pangalactic.utils.io.part21_preparse import readStepFile @@ -34,7 +35,17 @@ def getAssemblies(f): data = readStepFile(f) - nauo_ids = [i for i in list(data['insttype']) - if data['insttype'][i] == 'NEXT_ASSEMBLY_USAGE_OCCURRENCE'] - return nauo_ids + nauo = {} + for n in data['typeinst']['NEXT_ASSEMBLY_USAGE_OCCURRENCE']: + parent, child = [x.strip(' \n\r#') + for x in data['contents'][n].split(',')[3:5]] + nauo[n] = {'oid' : ''.join(['#', n]), + 'id' : ' '.join(['nauo', n]), + # relating_product_definition (4th attr) + 'parent' : parent, + # related_product_definition (5th attr) + 'child' : child, + 'reference_designator' : '' # test data doesn't have + } + pprint(nauo) From waterbug at step.nasa.gov Thu May 3 19:05:09 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Thu May 3 19:05:11 2007 Subject: [pangalactic-commits] STEP importAssemblies demo works! Yay! :) Message-ID: <200705032305.l43N59Sq000659@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/node/pangalaxian.py 1.184 1.185 PanGalactic/pangalactic/utils/io/import_assembly.py 1.2 1.3 Log message: STEP importAssemblies demo works! Yay! :) Index: PanGalactic/pangalactic/node/pangalaxian.py diff -u PanGalactic/pangalactic/node/pangalaxian.py:1.184 PanGalactic/pangalactic/node/pangalaxian.py:1.185 --- PanGalactic/pangalactic/node/pangalaxian.py:1.184 Thu May 3 12:27:15 2007 +++ PanGalactic/pangalactic/node/pangalaxian.py Thu May 3 19:05:06 2007 @@ -2,16 +2,16 @@ # -*- coding: ANSI_X3.4-1968 -*- # generated by wxGlade 0.3.5.1 on Tue Feb 1 00:19:02 2005 -# $Id: pangalaxian.py,v 1.184 2007/05/03 16:27:15 waterbug Exp $ +# $Id: pangalaxian.py,v 1.185 2007/05/03 23:05:06 waterbug Exp $ """ Main application module for PanGalaxian, the PGEF GUI client. WE ARE THE PANGALAXIANS! :) -@version: $Revision: 1.184 $ +@version: $Revision: 1.185 $ """ -__version__ = "$Revision: 1.184 $"[11:-2] +__version__ = "$Revision: 1.185 $"[11:-2] # Python import logging @@ -53,6 +53,7 @@ from pangalactic.node.uberorb import orb from pangalactic.utils.identity import generateOid from pangalactic.utils.identity import setOidBase +from pangalactic.utils.io.import_assembly import getAssemblies from pangalactic.utils.datetimes import dtstamp @@ -113,8 +114,8 @@ help="Logout from repository ...") self.file_import = self.file_menu.Append( id=wx.ID_ANY, - text="&Import...", - help="Import data from file ...") + text="&Import STEP data...", + help="Import STEP data from a file ...") # self.file_export = self.file_menu.Append( # id=wx.ID_ANY, # text="&Export", @@ -590,7 +591,15 @@ """ # TODO: create a Wizard for the import process self.log.info(' - PanGalaxian.onImport') - + dlg = wx.FileDialog( + self, message="Choose a file", defaultDir=os.getcwd(), + defaultFile="", style=wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR) + if dlg.ShowModal() == wx.ID_OK: + paths = dlg.GetPaths() + project, acus, models = getAssemblies(paths[0]) + orb.save(project) + orb.save(models) + orb.save(acus) def updateProjects(self): """ Index: PanGalactic/pangalactic/utils/io/import_assembly.py diff -u PanGalactic/pangalactic/utils/io/import_assembly.py:1.2 PanGalactic/pangalactic/utils/io/import_assembly.py:1.3 --- PanGalactic/pangalactic/utils/io/import_assembly.py:1.2 Thu May 3 16:29:09 2007 +++ PanGalactic/pangalactic/utils/io/import_assembly.py Thu May 3 19:05:07 2007 @@ -1,4 +1,7 @@ +import os from pprint import pprint +from pangalactic.meta.pgefobject import PgefObject +from pangalactic.node.uberorb import orb from pangalactic.utils.io.part21 import PARAMETER_LIST from pangalactic.utils.io.part21_preparse import readStepFile @@ -35,17 +38,54 @@ def getAssemblies(f): data = readStepFile(f) + projid = os.path.basename(f).split('.')[0].upper() + projoid = ''.join(['DEMO_', projid]) + project = PgefObject(_schema=orb.interfaces['Project'], oid=projoid, + id=projid) nauo = {} for n in data['typeinst']['NEXT_ASSEMBLY_USAGE_OCCURRENCE']: - parent, child = [x.strip(' \n\r#') + parent, child = [x.strip(" \n\r#'") for x in data['contents'][n].split(',')[3:5]] - nauo[n] = {'oid' : ''.join(['#', n]), - 'id' : ' '.join(['nauo', n]), + nauo[n] = {'oid' : n, + 'id' : ''.join(['nauo #', n]), # relating_product_definition (4th attr) 'parent' : parent, # related_product_definition (5th attr) 'child' : child, 'reference_designator' : '' # test data doesn't have } - pprint(nauo) + # product_definitions + pdset = (set([na['parent'] for na in nauo.values()]) | + set([na['child'] for na in nauo.values()])) + pd = {} + for pdref in pdset: + pdfref = data['contents'][pdref].split(',')[2].strip(" \n\r#'") + version = data['contents'][pdfref].split(',')[0].strip(" \n\r#'") + mpref = data['contents'][pdfref].split(',')[2].strip(" \n\r#'") + # product name (or id if no name) + product_name = (data['contents'][mpref].split(',')[1].strip(" \n\r#'") + or data['contents'][mpref].split(',')[0].strip(" \n\r#'")) + pd[pdref] = {'oid' : pdref, + 'id' : ''.join(['product definition #', pdref, + 'v.', version]), + 'base_id' : ''.join(['product definition #', pdref]) + 'cm_authority' : projoid, + # version from pdf + 'version' : version, + # modeled product + 'name' : product_name + } + # print 'assemblies:' + # pprint(nauo) + # print '-----------------------------------' + # print 'product_definitions:' + # print pdset + # print '-----------------------------------' + # print 'models:' + # pprint(pd) + acus = [PgefObject(_schema=orb.interfaces['Acu'], **nauo[n]) + for n in nauo] + models = [PgefObject(_schema=orb.interfaces['Model'], **pd[p]) + for p in pd] + return project, acus, models From waterbug at step.nasa.gov Thu May 3 20:03:49 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Thu May 3 20:03:50 2007 Subject: [pangalactic-commits] A few tweaks to the demo ... Message-ID: <200705040003.l4403nwm001122@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/utils/io/import_assembly.py 1.3 1.4 Log message: A few tweaks to the demo ... Index: PanGalactic/pangalactic/utils/io/import_assembly.py diff -u PanGalactic/pangalactic/utils/io/import_assembly.py:1.3 PanGalactic/pangalactic/utils/io/import_assembly.py:1.4 --- PanGalactic/pangalactic/utils/io/import_assembly.py:1.3 Thu May 3 19:05:07 2007 +++ PanGalactic/pangalactic/utils/io/import_assembly.py Thu May 3 20:03:47 2007 @@ -63,12 +63,17 @@ version = data['contents'][pdfref].split(',')[0].strip(" \n\r#'") mpref = data['contents'][pdfref].split(',')[2].strip(" \n\r#'") # product name (or id if no name) - product_name = (data['contents'][mpref].split(',')[1].strip(" \n\r#'") - or data['contents'][mpref].split(',')[0].strip(" \n\r#'")) + pre_id = (data['contents'][mpref].split(',')[1].strip(" \n\r#'") + or data['contents'][mpref].split(',')[0].strip(" \n\r#'")) + base_id = ''.join([pre_id, ' (#', pdref, ')']) + vinfo = '' + if version: + vinfo = ''.join([' v. ', version]) + product_id = ''.join([pre_id, '_', pdref, '_', version]) + product_name = ''.join([pre_id, vinfo, ' (#', pdref, ')']) pd[pdref] = {'oid' : pdref, - 'id' : ''.join(['product definition #', pdref, - 'v.', version]), - 'base_id' : ''.join(['product definition #', pdref]) + 'id' : product_id, + 'base_id' : base_id, 'cm_authority' : projoid, # version from pdf 'version' : version, From waterbug at step.nasa.gov Fri May 4 20:51:17 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Fri May 4 20:51:19 2007 Subject: [pangalactic-commits] Minor refinements to assembly import. Message-ID: <200705050051.l450pHhk011998@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/node/pangalaxian.py 1.185 1.186 PanGalactic/pangalactic/utils/io/import_assembly.py 1.4 1.5 PanGalactic/pangalactic/utils/io/part21_preparse.py 1.5 1.6 Log message: Minor refinements to assembly import. Index: PanGalactic/pangalactic/utils/io/part21_preparse.py diff -u PanGalactic/pangalactic/utils/io/part21_preparse.py:1.5 PanGalactic/pangalactic/utils/io/part21_preparse.py:1.6 --- PanGalactic/pangalactic/utils/io/part21_preparse.py:1.5 Thu May 3 16:29:09 2007 +++ PanGalactic/pangalactic/utils/io/part21_preparse.py Fri May 4 20:51:16 2007 @@ -1,14 +1,14 @@ #!/usr/bin/env python -# $Id: part21_preparse.py,v 1.5 2007/05/03 20:29:09 waterbug Exp $ +# $Id: part21_preparse.py,v 1.6 2007/05/05 00:51:16 waterbug Exp $ """ A generic (no dependencies on the rest of PanGalactic) reader/writer for "Part 21 files" (ISO 10303-21, STEP "Clear Text Encoding", a serialization format). This module reads a STEP Part 21 data file into a set of Python dictionaries. -@version: $Revision: 1.5 $ +@version: $Revision: 1.6 $ """ -__version__ = "$Revision: 1.5 $"[11:-2] +__version__ = "$Revision: 1.6 $"[11:-2] import re, sys, string, time from optparse import OptionParser @@ -18,7 +18,7 @@ from simpleparse import dispatchprocessor as dp -# Part 21 File EBNF syntax specification (informal) +# Part 21 File syntax specification (informal) # Productions whose names are all caps are formally named and specified in ISO # 10303-21:2002(E). Productions with lower-case names are either "convenience" Index: PanGalactic/pangalactic/node/pangalaxian.py diff -u PanGalactic/pangalactic/node/pangalaxian.py:1.185 PanGalactic/pangalactic/node/pangalaxian.py:1.186 --- PanGalactic/pangalactic/node/pangalaxian.py:1.185 Thu May 3 19:05:06 2007 +++ PanGalactic/pangalactic/node/pangalaxian.py Fri May 4 20:51:15 2007 @@ -2,16 +2,16 @@ # -*- coding: ANSI_X3.4-1968 -*- # generated by wxGlade 0.3.5.1 on Tue Feb 1 00:19:02 2005 -# $Id: pangalaxian.py,v 1.185 2007/05/03 23:05:06 waterbug Exp $ +# $Id: pangalaxian.py,v 1.186 2007/05/05 00:51:15 waterbug Exp $ """ Main application module for PanGalaxian, the PGEF GUI client. WE ARE THE PANGALAXIANS! :) -@version: $Revision: 1.185 $ +@version: $Revision: 1.186 $ """ -__version__ = "$Revision: 1.185 $"[11:-2] +__version__ = "$Revision: 1.186 $"[11:-2] # Python import logging @@ -1020,7 +1020,6 @@ dlg = wx.MessageDialog(self, "No projects have been created or retrieved yet.", "Yes, we have no projects", wx.OK) - prefs['projects'] = [] dlg.ShowModal() dlg.Destroy() Index: PanGalactic/pangalactic/utils/io/import_assembly.py diff -u PanGalactic/pangalactic/utils/io/import_assembly.py:1.4 PanGalactic/pangalactic/utils/io/import_assembly.py:1.5 --- PanGalactic/pangalactic/utils/io/import_assembly.py:1.4 Thu May 3 20:03:47 2007 +++ PanGalactic/pangalactic/utils/io/import_assembly.py Fri May 4 20:51:16 2007 @@ -1,8 +1,8 @@ -import os +import os, sys, time +from optparse import OptionParser from pprint import pprint from pangalactic.meta.pgefobject import PgefObject from pangalactic.node.uberorb import orb -from pangalactic.utils.io.part21 import PARAMETER_LIST from pangalactic.utils.io.part21_preparse import readStepFile # nauo attrs: @@ -39,7 +39,13 @@ def getAssemblies(f): data = readStepFile(f) projid = os.path.basename(f).split('.')[0].upper() - projoid = ''.join(['DEMO_', projid]) + projoid = projid + # TODO: + # - this function really needs a wizard + # + pick a namespace (default to user's preferred ns) + # + ask if user wants to create a context related to this data + # + pick a project (default to current project if user has permission; + # otherwise, default to user's preferred project, if any) project = PgefObject(_schema=orb.interfaces['Project'], oid=projoid, id=projid) nauo = {} @@ -66,31 +72,44 @@ pre_id = (data['contents'][mpref].split(',')[1].strip(" \n\r#'") or data['contents'][mpref].split(',')[0].strip(" \n\r#'")) base_id = ''.join([pre_id, ' (#', pdref, ')']) - vinfo = '' + vinfo = 'v.0' if version: - vinfo = ''.join([' v. ', version]) - product_id = ''.join([pre_id, '_', pdref, '_', version]) - product_name = ''.join([pre_id, vinfo, ' (#', pdref, ')']) - pd[pdref] = {'oid' : pdref, - 'id' : product_id, - 'base_id' : base_id, + vinfo = ''.join(['v.', version]) + product_id = '-'.join([pre_id, pdref, vinfo]) + product_name = ' '.join([pre_id, vinfo, '( STEP file instance:', pdref, ')']) + pd[pdref] = {'oid' : pdref, + 'id' : product_id, + 'base_id' : base_id, 'cm_authority' : projoid, # version from pdf - 'version' : version, + 'version' : version, # modeled product - 'name' : product_name + 'name' : product_name } - # print 'assemblies:' - # pprint(nauo) - # print '-----------------------------------' - # print 'product_definitions:' - # print pdset - # print '-----------------------------------' - # print 'models:' - # pprint(pd) acus = [PgefObject(_schema=orb.interfaces['Acu'], **nauo[n]) for n in nauo] models = [PgefObject(_schema=orb.interfaces['Model'], **pd[p]) for p in pd] return project, acus, models +if __name__ == '__main__': + usage = 'usage: %prog [options] file.p21' + opt = OptionParser(usage) + opt.add_option("-p", "--perf", action='store_true', + dest="performance", default=False, + help="run the parser's unit tests") + (options, args) = opt.parse_args(args=sys.argv) + # debugging: + # print "options: %s" % str(options) + # print "args: %s" % str(args) + if len(args) > 1: + if options.performance: + start = time.clock() + project, nauo, pdset = getAssemblies(f=args[1]) + if options.performance: + end = time.clock() + print "\nTotal time: %6.2f sec" % (end - start) + print len(list(nauo))," assemblies\n" + else: + opt.print_help() + From waterbug at step.nasa.gov Sat May 5 20:13:08 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Sat May 5 20:13:10 2007 Subject: [pangalactic-commits] Work on namespace management, and some notes. Message-ID: <200705060013.l460D8WT014078@ned.gsfc.nasa.gov> Modified files: PanGalactic/NOTES 1.13 1.14 PanGalactic/pangalactic/node/uberorb.py 1.142 1.143 PanGalactic/pangalactic/utils/xmlrpcinterface.py 1.116 1.117 Log message: Work on namespace management, and some notes. Index: PanGalactic/pangalactic/node/uberorb.py diff -u PanGalactic/pangalactic/node/uberorb.py:1.142 PanGalactic/pangalactic/node/uberorb.py:1.143 --- PanGalactic/pangalactic/node/uberorb.py:1.142 Thu Apr 26 09:41:59 2007 +++ PanGalactic/pangalactic/node/uberorb.py Sat May 5 20:13:05 2007 @@ -1,11 +1,11 @@ -# $Id: uberorb.py,v 1.142 2007/04/26 13:41:59 waterbug Exp $ +# $Id: uberorb.py,v 1.143 2007/05/06 00:13:05 waterbug Exp $ # -*- test-case-name: pangalactic.test.test_uberorb -*- """ A PanGalaxian node's UberORB -@version: $Revision: 1.142 $ +@version: $Revision: 1.143 $ """ -__version__ = "$Revision: 1.142 $"[11:-2] +__version__ = "$Revision: 1.143 $"[11:-2] import logging import mimetypes @@ -838,7 +838,7 @@ self.log.debug(' + logged in -- going to the server ...') base_ids = self.xmlrpc.getBaseIds(ns) or [] else: - self.log.info(" + in local mode -- can't give a good answer.") + self.log.info(" + in local mode -- info may be incomplete ...") base_ids = [] return base_ids Index: PanGalactic/NOTES diff -u PanGalactic/NOTES:1.13 PanGalactic/NOTES:1.14 --- PanGalactic/NOTES:1.13 Tue Apr 17 01:11:55 2007 +++ PanGalactic/NOTES Sat May 5 20:13:05 2007 @@ -51,24 +51,38 @@ - general interfaces: PanGalaticFu [Identifiable, Manageable, etc.] - these will be managed in 'p.meta.metaobjects' as code (but still in the form of extracts, maybe) - - Everything else is really "domain" and can go into a "pgef domain ontology" - that is not required. Can be maintained as OWL, etc. and cached at startup; - can be versioned separately from "core pgef", but as a close companion for - which some application niceties have been developed. + - maintain all pgef ontology objects as extracts; + - need to be able to generate OWL for them so they can be used by + application developers who want to use Protege or some type of OWL-based + technology for defining their application domain objects. Semi-random notes: * PmofDatatype - - new datatypes can be created and managed. - - needs to reference a serialization method - - some way to specify presentation/editing (smth. MIME-like?) - - also mapped from imported schemas' datatypes + - new datatypes can be created and managed. + - needs to reference a serialization method + - some way to specify presentation/editing (smth. MIME-like?) + - also mapped from imported schemas' datatypes * PgefProperty - implements IProperty and IPgefObject - attrs defined in __slots__, which is constructed from the attrs of PmofProperty +* Namespaces (PgefNamespace and PmofNamespace) + - runtime namespaces (PgefNamespace instances) for metaobject (M1 and above) + names (i.e., 'pgef' and any application namespaces -- e.g. 'space_mission', + etc.) must be distinguishable from those for runtime object (M0) names. + - metaobject namespaces and the names they contain should only be displayed + when in a 'meta' context -- which should be selectable, and should not be + the "default default" (although one could set it as a preference). + - try using a 'meta_level' property, with values 'Mn'. Namespaces for + normal application objects would have a meta_level of 'M0', and only those + namespaces would be displayed unless a 'meta' context other than M0 is set + (in which case the 'M0' namespaces would be excluded). + - it should be possible to set the meta context to any one or any combination + of two or more meta levels (M0, M1, M2, etc.). + * Pmof MetaObjects - created by registry from extracts (createPmofObjectFromExtract) - need methodology for versioning @@ -81,6 +95,8 @@ iteration = 0, etc.) + for namespace types (PmofClass, PmofOntology, PmofTaxonomy, etc.), 'names' should probably be a Python property (e.g., for PmofClass, all registered + PmofProperties with domain of that PmofClass would populate its 'names' + property). *** ITEM 2 *** @@ -94,13 +110,14 @@ Should it be a datatype object instead? + pro: - * doable - - PmofProperty.range would still be strings (name of class or - datatype) - * PgefProperty.range could be used for casting, if nec. + * doable + - PmofProperty.range would still be strings (name of class or + datatype) + * PgefProperty.range could be used for casting, if nec. + * might make generic functions easier to implement where useful + con: - * will need unit tests (not a huge deal, really) + * will need unit tests (not a huge deal, really) - Should there be a module-level dictionary of datatypes in pgefdatatype? (I think so -- it is needed especially if PgefProperty.range remains a Index: PanGalactic/pangalactic/utils/xmlrpcinterface.py diff -u PanGalactic/pangalactic/utils/xmlrpcinterface.py:1.116 PanGalactic/pangalactic/utils/xmlrpcinterface.py:1.117 --- PanGalactic/pangalactic/utils/xmlrpcinterface.py:1.116 Wed Mar 7 00:21:56 2007 +++ PanGalactic/pangalactic/utils/xmlrpcinterface.py Sat May 5 20:13:06 2007 @@ -1,17 +1,18 @@ -# $Id: xmlrpcinterface.py,v 1.116 2007/03/07 05:21:56 waterbug Exp $ +# $Id: xmlrpcinterface.py,v 1.117 2007/05/06 00:13:06 waterbug Exp $ """ PanGalactic Client XML-RPC Interfaces -@version: $Revision: 1.116 $ +@version: $Revision: 1.117 $ """ -__version__ = "$Revision: 1.116 $"[11:-2] +__version__ = "$Revision: 1.117 $"[11:-2] import base64 import xmlrpclib import string import httplib from pprint import pprint +from pangalactic.node.uberorb import orb class BasicAuthTransport(xmlrpclib.Transport): @@ -120,9 +121,9 @@ else: conns = 'http://' conns = conns + hostandport - print 'XmlrpcInterface: connection string is', conns - print ' userid is: ', userid - print ' passwd is: ', passwd + orb.log.debug('XmlrpcInterface: connection string is "%s"' % conns) + orb.log.debug(' userid is: "%s"' % userid) + orb.log.debug(' passwd is: "%s"' % passwd) if userid and passwd: self.userid = userid if secure: @@ -185,14 +186,14 @@ (now with new state info in their repository-related attributes) """ - print "XmlrpcInterface.addobjects" + orb.log.debug("XmlrpcInterface.addobjects") if not objs: - print " * empty object list" + orb.log.debug(" * empty object list") newexts = [] else: - print " * oids and schemas of objects to be added:" + orb.log.debug(" * oids and schemas of objects to be added:") for o in objs: - print ' + %s (%s)' % (o.oid, o._schema.__name__) + orb.log.debug(' + %s (%s)' % (o.oid, o._schema.__name__)) extracts = [o.extract() for o in objs] newexts = self._RPC.addObjects(extracts) return newexts @@ -209,14 +210,14 @@ (now with new state info in their repository-related attributes) """ - print "XmlrpcInterface.updateObjects" + orb.log.debug("XmlrpcInterface.updateObjects") if not objs: - print " * empty object list" + orb.log.debug(" * empty object list") newexts = [] else: - print " * oids and schemas of objects to be updated:" + orb.log.debug(" * oids and schemas of objects to be updated:") for o in objs: - print ' + %s (%s)' % (o.oid, o._schema.__name__) + orb.log.debug(' + %s (%s)' % (o.oid, o._schema.__name__)) extracts = [o.extract() for o in objs] newexts = self._RPC.updateObjects(extracts) return newexts @@ -232,14 +233,14 @@ updated with an iteration, version, id, etc. @rtype: C{list} of extracts (C{dict}s) """ - print "XmlrpcInterface.commitVersions()" + orb.log.debug("XmlrpcInterface.commitVersions()") if not objs: - print " * empty object list" + orb.log.debug(" * empty object list") newexts = [] else: - print " * ids and schemas of versions to be committed:" + orb.log.debug(" * ids and schemas of versions to be committed:") for o in objs: - print ' + %s (%s)' % (o.id, o._schema.__name__) + orb.log.debug(' + %s (%s)' % (o.id, o._schema.__name__)) extracts = [o.extract() for o in objs] newexts = self._RPC.commitVersions(extracts) return newexts @@ -267,9 +268,10 @@ @param params: attr-value criteria for desired objects @type params: C{dict} """ - # print "xmlrpc.getobjects" - print ' - xmlrpc.getObjects command is:' - print ' getObjects(%s, %s, %s, %s)' % (schema_name, refs, subtypes, params) + orb.log.debug("XmlrpcInterface.getobjects") + orb.log.debug(' - xmlrpc.getObjects command is:') + orb.log.debug(' getObjects(%s, %s, %s, %s)' % ( + schema_name, refs, subtypes, params)) return self._RPC.getObjects(schema_name, refs, subtypes, params) def getObjectsByOids(self, oids): @@ -279,7 +281,7 @@ @type oids: C{list} @param oids: oids of the desired objects """ - # print "xmlrpcinterface.getObjectsByOids" + orb.log.debug("XmlrpcInterface.getObjectsByOids") return self._RPC.getObjectsByOids(oids) def getNames(self, ns): @@ -289,7 +291,7 @@ @param ns: the URL (oid) of a namespace @type ns: C{str} """ - # print "xmlrpcinterface.getNames()" + orb.log.debug("XmlrpcInterface.getNames()") return self._RPC.getNames(ns) def getBaseIds(self, ns): @@ -299,7 +301,7 @@ @param ns: the URL (oid) of a namespace @type ns: C{str} """ - # print "xmlrpcinterface.getNames()" + orb.log.debug("xmlrpcinterface.getBaseIds()") return self._RPC.getBaseIds(ns) def search(self, schema_name, refs, subtypes, params, spec): @@ -337,16 +339,16 @@ @return: a C{list} of extracts of the objects that were found """ - print "- Xmlrpcinterface.search:" - print " search(%s, %s, %s, %s, %s)" % ( - schema_name, refs, subtypes, params, spec) + orb.log.debug("- XmlrpcInterface.search:") + orb.log.debug(" search(%s, %s, %s, %s, %s)" % ( + schema_name, refs, subtypes, params, spec)) if not spec: spec = [] data = self._RPC.search(schema_name, refs, subtypes, params, spec) if data: - print " - data returned:", len(data), 'items' + orb.log.debug(" - data returned: %s items." % len(data)) else: - print " - no %s instances found" % schema_name + orb.log.debug(" - no %s instances found" % schema_name) return data def getCount(self, schema_name, refs, subtypes, params): @@ -380,14 +382,14 @@ @return: a C{list} of extracts of the objects that were found """ - print " - Xmlrpcinterface.getCount()" - print " search(schema_name, refs, subtypes, params)" - print " search(%s, %s, %s, %s)" % ( - schema_name, refs, subtypes, params) + orb.log.debug(" - XmlrpcInterface.getCount()") + orb.log.debug(" search(schema_name, refs, subtypes, params)") + orb.log.debug(" search(%s, %s, %s, %s)" % ( + schema_name, refs, subtypes, params)) count = self._RPC.getCount(schema_name, refs, subtypes, params) - # if count: - # print " - count returned:", count - # else: - # print " - no %s instances matched" % schema_name + if count: + orb.log.debug(" - count returned: %s" % count) + else: + orb.log.debug(" - no %s instances matched" % schema_name) return count From waterbug at step.nasa.gov Sun May 6 02:24:42 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Sun May 6 02:24:42 2007 Subject: [pangalactic-commits] Improvements to PanGalaxian's logging. Message-ID: <200705060624.l466Ogvq014474@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/meta/registry.py 1.173 1.174 PanGalactic/pangalactic/node/cache.py 1.32 1.33 PanGalactic/pangalactic/node/uberorb.py 1.143 1.144 PanGalactic/pangalactic/utils/xmlrpcinterface.py 1.117 1.118 Log message: Improvements to PanGalaxian's logging. Index: PanGalactic/pangalactic/node/uberorb.py diff -u PanGalactic/pangalactic/node/uberorb.py:1.143 PanGalactic/pangalactic/node/uberorb.py:1.144 --- PanGalactic/pangalactic/node/uberorb.py:1.143 Sat May 5 20:13:05 2007 +++ PanGalactic/pangalactic/node/uberorb.py Sun May 6 02:24:39 2007 @@ -1,11 +1,11 @@ -# $Id: uberorb.py,v 1.143 2007/05/06 00:13:05 waterbug Exp $ +# $Id: uberorb.py,v 1.144 2007/05/06 06:24:39 waterbug Exp $ # -*- test-case-name: pangalactic.test.test_uberorb -*- """ A PanGalaxian node's UberORB -@version: $Revision: 1.143 $ +@version: $Revision: 1.144 $ """ -__version__ = "$Revision: 1.143 $"[11:-2] +__version__ = "$Revision: 1.144 $"[11:-2] import logging import mimetypes @@ -113,7 +113,7 @@ # self.__cache = ObjectCache(self.interfaces.values(), home=home) ifaces = [self.interfaces[i] for i in self.persistables] self.log.debug(' interfaces: %s' % str(self.persistables)) - self.__cache = ObjectCache(ifaces, home=home) + self.__cache = ObjectCache(ifaces, home=home, log=self.log) # self.createDefaultNamespace() else: raise ValueError, 'the orb already has a cache.' @@ -175,7 +175,7 @@ @type secure: C{bool} """ # TODO: implement HTTP proxy handling - # self.log.debug(' - orb._initXmlrpcInterface creating XmlrpcInterface') + self.log.debug(' - orb._initXmlrpcInterface creating XmlrpcInterface') if secure: conns = 'https://' + hostandport else: @@ -183,7 +183,8 @@ return XmlrpcInterface(hostandport=hostandport, userid=userid, passwd=passwd, - secure=secure) + secure=secure, + log=self.log) def login(self, hostandport, userid, passwd, secure=True): """ @@ -202,7 +203,7 @@ in this case) @type secure: C{bool} """ - # self.log.debug(' - orb.login') + self.log.debug(' - orb.login') self.xmlrpc = self._initXmlrpcInterface(hostandport, userid, passwd, secure=secure) try: @@ -865,11 +866,11 @@ Retrieves all Acu objects associated with a specified assembly (parent) oid. """ - # self.log.debug(' - getAcusByAssemblyOid') - # self.log.debug(' + parent oid: %s' % oid) + self.log.debug(' - getAcusByAssemblyOid') + self.log.debug(' + parent oid: %s' % oid) acus = [] if oid in self.assy_maps: - # self.log.debug(' + oid found in self.assy_maps') + self.log.debug(' + oid found in self.assy_maps') acus = self.assy_maps[oid] else: for obj in self.getDict('Acu').values(): @@ -877,10 +878,10 @@ acus.append(obj) elif getattr(obj.parent, 'oid', '') == oid: acus.append(obj) - # self.log.debug(' local acus with parent oid == %s: %s' % (oid, - # str([o.oid for o in acus]))) - # self.log.debug(' + returning %s acus' % len(acus)) - # self.log.debug(' + end getAcusByAssemblyOid') + self.log.debug(' local acus with parent oid == %s: %s' % (oid, + str([o.oid for o in acus]))) + self.log.debug(' + returning %s acus' % len(acus)) + self.log.debug(' + end getAcusByAssemblyOid') return acus def removeLocalObjFromCache(self, o): @@ -890,6 +891,7 @@ @param objoroid: a C{PgefObject} instance @type objoroid: C{PgefObject} """ + self.log.debug(' - removeLocalObjFromCache') if getattr(self, 'cache'): self.cache.delete(o) Index: PanGalactic/pangalactic/meta/registry.py diff -u PanGalactic/pangalactic/meta/registry.py:1.173 PanGalactic/pangalactic/meta/registry.py:1.174 --- PanGalactic/pangalactic/meta/registry.py:1.173 Sun Mar 18 02:28:28 2007 +++ PanGalactic/pangalactic/meta/registry.py Sun May 6 02:24:38 2007 @@ -1,11 +1,11 @@ -# $Id: registry.py,v 1.173 2007/03/18 06:28:28 waterbug Exp $ +# $Id: registry.py,v 1.174 2007/05/06 06:24:38 waterbug Exp $ """ The Pan Galactic Meta Object Registry -@version: $Revision: 1.173 $ +@version: $Revision: 1.174 $ """ -__version__ = "$Revision: 1.173 $"[11:-2] +__version__ = "$Revision: 1.174 $"[11:-2] # Python import glob @@ -112,10 +112,11 @@ # start in-memory logging until we get a file to write to ... class logger: pass self.log = logger() - self.log.temp = [] - self.log.info = lambda x: self.log.temp.append(x) - self.log.debug = lambda x: self.log.temp.append(x) - self.log.info('initializing registry logging.') + self.log.info_temp = [] + self.log.debug_temp = [] + self.log.info = lambda x: self.log.info_temp.append(x) + self.log.debug = lambda x: self.log.debug_temp.append(x) + self.log.info(' - initializing registry logging.') self.sources = {} self.interfaces = {} self.properties = {} @@ -137,15 +138,22 @@ """ Begin registry logging. """ - self.templog = None - if hasattr(self, 'log') and hasattr(self.log, 'temp'): - self.templog = self.log.temp + self.tempinfolog = None + self.tempdebuglog = None + if hasattr(self, 'log'): + if hasattr(self.log, 'info_temp'): + self.tempinfolog = self.log.info_temp + if hasattr(self.log, 'debug_temp'): + self.tempdebuglog = self.log.debug_temp import logging if hasattr(logging, 'filename'): self.log = logging.getLogger('registry') - if self.templog: - for line in self.templog: + if self.tempinfolog: + for line in self.tempinfolog: self.log.info(line) + if self.tempdebuglog: + for line in self.tempdebuglog: + self.log.debug(line) def createCoreMetaObjects(self, module='pangalactic.meta.names'): """ @@ -447,8 +455,8 @@ self.log.info(' + to_python = %s' % str(to_python)) cnames = source.getClassNames(nsprefix) self.log.debug(' + cnames: %s' % cnames) - # self.log.debug(' ... finding build order of <%s> cnames ...' % ( - # nsprefix)) + self.log.debug(' ... finding build order of <%s> cnames ...' % ( + nsprefix)) # First construct a dictionary mapping names to lists of base names # (to avoid calling source.getBaseNames too much). Since the purpose # here is to find the proper build order (so all dependendencies of an @@ -489,7 +497,7 @@ extr['_schema_name'] = 'PmofProperty' extracts[pname] = extr for cname in build_order: - # self.log.debug(' - constructing interface for %s' % cname) + self.log.debug(' + constructing interface for %s' % cname) if nsprefix == 'pgef': # for 'pgef' interfaces, just include 'pgef' base classes (scope # is just 'pgef') ... @@ -501,18 +509,19 @@ # class hierarchy all the way up (scope is 'pgef' and nsprefix) base_names = source.getBaseNames(nsprefix, cname, scope=['pgef', nsprefix]) - # self.log.debug(' base_names: %s' % base_names) + # self.log.debug(' base_names: %s' % base_names) # in case this is an app interface, some of its bases may need to be # looked up in self.interfaces ... interface_bases = [ifdict.get(bn, self.interfaces[bn]) for bn in base_names] - # self.log.debug(' bases ... %s' % str(interface_bases)) + # self.log.debug(' bases ... %s' % str(interface_bases)) interface_props = [p for p in propdict.values() if p.domain == cname] - # self.log.debug(' properties:') + # self.log.debug(' properties:') # for p in interface_props: - # self.log.debug(' - %s (%s), range: %s' % (p.id, type(p.id), - # p.range)) + # self.log.debug(' - %s (%s), range: %s' % (p.id, + # type(p.id), + # p.range)) # for a in p._schema: # self.log.debug(' + %s ... %s (%s)' % (a, getattr(p, a), # type(getattr(p, a)))) @@ -530,7 +539,7 @@ bases=interface_bases, attrs=interface_attrs ) - self.log.debug(' interface created: %s' % str(i)) + self.log.debug(' + interface created: %s' % str(i)) ifdict[cname] = i # only add interfaces to the registered (runtime) interfaces if not # generating python ... @@ -595,7 +604,7 @@ pprint(extracts[i], f) f.write('\n') f.close() - self.log.debug(' %s of %s interfaces written to classes.py' % ( + self.log.debug(' + %s of %s interfaces written to classes.py' % ( str(len(build_order)), str(len(ifdict)))) f = open(os.path.join(to_python, 'properties.py'), 'w') @@ -606,7 +615,7 @@ pprint(extracts[p], f) f.write('\n') f.close() - self.log.debug(' %s properties written to properties.py' % ( + self.log.debug(' + %s properties written to properties.py' % ( str(len(propdict)))) # save the namespace for nsprefix as an extract of a PmofNamespace # object @@ -617,7 +626,7 @@ pprint(extracts[nsprefix], f) f.write('\n') f.close() - self.log.debug(' %s namespace written to nspaces.py' % ( + self.log.debug(' + %s namespace written to nspaces.py' % ( str(nsprefix))) # update registry [meta object] extracts from the imported ontology -- # its Classes and Properties are assumed authoritative (modulo @@ -856,7 +865,7 @@ break for name in build_order: e = interface_extracts[name] - # self.log.debug('- constructing interface for %s' % name) + self.log.debug('- constructing interface for %s' % name) interface_bases = [interfaces[n] for n in e['bases']] # self.log.debug(' bases ... %s' % str(interface_bases)) interface_props = props[name] Index: PanGalactic/pangalactic/node/cache.py diff -u PanGalactic/pangalactic/node/cache.py:1.32 PanGalactic/pangalactic/node/cache.py:1.33 --- PanGalactic/pangalactic/node/cache.py:1.32 Mon Apr 23 15:48:55 2007 +++ PanGalactic/pangalactic/node/cache.py Sun May 6 02:24:39 2007 @@ -1,12 +1,12 @@ """ Local object cache manager (a layer over ZODB) -@version: $Revision: 1.32 $ +@version: $Revision: 1.33 $ """ -__version__ = "$Revision: 1.32 $"[11:-2] +__version__ = "$Revision: 1.33 $"[11:-2] # Python -import os +import os, sys # ZODB from persistent.mapping import PersistentMapping @@ -25,18 +25,22 @@ Light-weight local object persistence for a PanGalactic node. """ - def __init__(self, interfaces, home=''): + def __init__(self, interfaces, home='', log=None): """ Initialize an C{ObjectCache} instance. @param interfaces: """ + self.log = log + if not log: + self.log.debug = sys.stdout.write + self.log.info = sys.stdout.write # If modifying this stuff, be careful: order is important - print 'ObjectCache (ZODB) starting up ...' - print ' - initializing LocalStorage' + self.log.debug('ObjectCache (ZODB) starting up ...') + self.log.debug(' - initializing LocalStorage') datadir = os.path.join(home, "data") if not os.path.exists(datadir): - print ' - no data dir found; creating one' + self.log.debug(' - no data dir found; creating one') os.makedirs(datadir) self.filename = os.path.join(datadir, "pgef.fs") self.storage = FileStorage.FileStorage(self.filename) @@ -91,7 +95,8 @@ @param iface: an C{Interface} to be supported by the cache @type iface: L{zope.interface.interface.InterfaceClass} instance """ - # print ' - ObjectCache.addInterface: adding', iface.__name__ + self.log.debug(' - ObjectCache.addInterface: adding %s' + % iface.__name__) if iface.__name__ not in self.dbroot.keys(): self.dbroot[iface.__name__] = PersistentMapping() self.commit() @@ -110,7 +115,7 @@ @type objs: list (usually of instances of L{pangalactic.meta.pgefobject.PgefObject} """ - # print " - ObjectCache.saveObjects" + self.log.debug(" - ObjectCache.saveObjects") # TODO: 'merge' -- i.e., in case of oid collision, compare # last-modified dates. If the repo copy has been modified and the # cache copy has not, replace the cache copy; if both have been @@ -153,8 +158,8 @@ @return: a list of objects @rtype: C{list} """ - print " - ObjectCache.searchLocalObjects" - print " + kw =", kw + self.log.debug(" - ObjectCache.searchLocalObjects") + self.log.debug(" + kw = %s" % str(kw)) if kw: objs = [x for x in self.objs.values() if self._getFilter(x, **kw)] else: @@ -172,7 +177,7 @@ @param objs: C{PgefObject}s to be added @type objs: C{list} """ - # print " - ObjectCache.add" + self.log.debug(" - ObjectCache.add") self.saveObjects(objs) self.commit() @@ -197,7 +202,7 @@ # strange special cases for Workflow stuff def GetWorkflows(self, attrlist = None): - # print " - ObjectCache.getworkflows" + self.log.debug(" - ObjectCache.getworkflows") wf_dict = self.getDict(self.WFPROCESSINSTANCE) objdict = {} for wfid, wfobj in wf_dict.items(): @@ -210,7 +215,7 @@ itemdict = dict(objdict) for wfid, wfobj in itemdict.items(): if wfobj._schema.__name__ == "WfProcessInstance": - #print " + wfobj.name", wfobj.name + self.log.debug(" + wfobj.name '%s'" % str(wfobj.name)) if objdict.has_key(wfid): if wfobj.state != 'DELETE': tmpobj = self.objs[wfobj.oid] @@ -221,11 +226,11 @@ if wfobj.state != 'DELETE': tmpobj = self.objs[wfobj.oid] objdict[wfid] = tmpobj - #print " + objdict", objdict + self.log.debug(" + objdict: %s" % str(objdict)) return objdict def saveWfProcessInstance(self, wflist, recurse=False): - #print " - ObjectCache.SaveWfProcessInstance" + self.log.debug(" - ObjectCache.SaveWfProcessInstance") self.saveObjects(wflist) for wfobj in wflist: for entry in wfobj.history: @@ -236,7 +241,7 @@ self.commit() def addWfProcessInstance(self, wflist, recurse=False): - #print " - ObjectCache.addWfProcessInstance" + #self.log.debug(" - ObjectCache.addWfProcessInstance") self.saveObjects(wflist) for wfobj in wflist: for entry in wfobj.history: Index: PanGalactic/pangalactic/utils/xmlrpcinterface.py diff -u PanGalactic/pangalactic/utils/xmlrpcinterface.py:1.117 PanGalactic/pangalactic/utils/xmlrpcinterface.py:1.118 --- PanGalactic/pangalactic/utils/xmlrpcinterface.py:1.117 Sat May 5 20:13:06 2007 +++ PanGalactic/pangalactic/utils/xmlrpcinterface.py Sun May 6 02:24:40 2007 @@ -1,18 +1,17 @@ -# $Id: xmlrpcinterface.py,v 1.117 2007/05/06 00:13:06 waterbug Exp $ +# $Id: xmlrpcinterface.py,v 1.118 2007/05/06 06:24:40 waterbug Exp $ """ PanGalactic Client XML-RPC Interfaces -@version: $Revision: 1.117 $ +@version: $Revision: 1.118 $ """ -__version__ = "$Revision: 1.117 $"[11:-2] +__version__ = "$Revision: 1.118 $"[11:-2] import base64 import xmlrpclib import string import httplib from pprint import pprint -from pangalactic.node.uberorb import orb class BasicAuthTransport(xmlrpclib.Transport): @@ -97,7 +96,8 @@ """ XML-RPC API to PGER """ - def __init__(self, hostandport, userid='', passwd='', secure=True): + def __init__(self, hostandport, userid='', passwd='', secure=True, + log=None): """ Initialize an XML-RPC server proxy for the specified host, port, userid, and password. @@ -114,16 +114,23 @@ @param secure: flag to indicate whether connection should use SSL (True, the default) or not. @type secure: C{bool} + + @param log: a writable log object (normally, the orb's log) + @type log: C{logging.Logger} """ + self.log = log + if not log: + self.log.debug = sys.stdout.write + self.log.info = sys.stdout.write # (worry about proxies later, if necessary) if secure: conns = 'https://' else: conns = 'http://' conns = conns + hostandport - orb.log.debug('XmlrpcInterface: connection string is "%s"' % conns) - orb.log.debug(' userid is: "%s"' % userid) - orb.log.debug(' passwd is: "%s"' % passwd) + self.log.debug('XmlrpcInterface: connection string is "%s"' % conns) + self.log.debug(' userid is: "%s"' % userid) + self.log.debug(' passwd is: "%s"' % passwd) if userid and passwd: self.userid = userid if secure: @@ -186,14 +193,14 @@ (now with new state info in their repository-related attributes) """ - orb.log.debug("XmlrpcInterface.addobjects") + self.log.debug("XmlrpcInterface.addobjects") if not objs: - orb.log.debug(" * empty object list") + self.log.debug(" * empty object list") newexts = [] else: - orb.log.debug(" * oids and schemas of objects to be added:") + self.log.debug(" * oids and schemas of objects to be added:") for o in objs: - orb.log.debug(' + %s (%s)' % (o.oid, o._schema.__name__)) + self.log.debug(' + %s (%s)' % (o.oid, o._schema.__name__)) extracts = [o.extract() for o in objs] newexts = self._RPC.addObjects(extracts) return newexts @@ -210,14 +217,14 @@ (now with new state info in their repository-related attributes) """ - orb.log.debug("XmlrpcInterface.updateObjects") + self.log.debug("XmlrpcInterface.updateObjects") if not objs: - orb.log.debug(" * empty object list") + self.log.debug(" * empty object list") newexts = [] else: - orb.log.debug(" * oids and schemas of objects to be updated:") + self.log.debug(" * oids and schemas of objects to be updated:") for o in objs: - orb.log.debug(' + %s (%s)' % (o.oid, o._schema.__name__)) + self.log.debug(' + %s (%s)' % (o.oid, o._schema.__name__)) extracts = [o.extract() for o in objs] newexts = self._RPC.updateObjects(extracts) return newexts @@ -233,14 +240,14 @@ updated with an iteration, version, id, etc. @rtype: C{list} of extracts (C{dict}s) """ - orb.log.debug("XmlrpcInterface.commitVersions()") + self.log.debug("XmlrpcInterface.commitVersions()") if not objs: - orb.log.debug(" * empty object list") + self.log.debug(" * empty object list") newexts = [] else: - orb.log.debug(" * ids and schemas of versions to be committed:") + self.log.debug(" * ids and schemas of versions to be committed:") for o in objs: - orb.log.debug(' + %s (%s)' % (o.id, o._schema.__name__)) + self.log.debug(' + %s (%s)' % (o.id, o._schema.__name__)) extracts = [o.extract() for o in objs] newexts = self._RPC.commitVersions(extracts) return newexts @@ -268,9 +275,9 @@ @param params: attr-value criteria for desired objects @type params: C{dict} """ - orb.log.debug("XmlrpcInterface.getobjects") - orb.log.debug(' - xmlrpc.getObjects command is:') - orb.log.debug(' getObjects(%s, %s, %s, %s)' % ( + self.log.debug("XmlrpcInterface.getobjects") + self.log.debug(' - xmlrpc.getObjects command is:') + self.log.debug(' getObjects(%s, %s, %s, %s)' % ( schema_name, refs, subtypes, params)) return self._RPC.getObjects(schema_name, refs, subtypes, params) @@ -281,7 +288,7 @@ @type oids: C{list} @param oids: oids of the desired objects """ - orb.log.debug("XmlrpcInterface.getObjectsByOids") + self.log.debug("XmlrpcInterface.getObjectsByOids") return self._RPC.getObjectsByOids(oids) def getNames(self, ns): @@ -291,7 +298,7 @@ @param ns: the URL (oid) of a namespace @type ns: C{str} """ - orb.log.debug("XmlrpcInterface.getNames()") + self.log.debug("XmlrpcInterface.getNames()") return self._RPC.getNames(ns) def getBaseIds(self, ns): @@ -301,7 +308,7 @@ @param ns: the URL (oid) of a namespace @type ns: C{str} """ - orb.log.debug("xmlrpcinterface.getBaseIds()") + self.log.debug("xmlrpcinterface.getBaseIds()") return self._RPC.getBaseIds(ns) def search(self, schema_name, refs, subtypes, params, spec): @@ -339,16 +346,16 @@ @return: a C{list} of extracts of the objects that were found """ - orb.log.debug("- XmlrpcInterface.search:") - orb.log.debug(" search(%s, %s, %s, %s, %s)" % ( + self.log.debug("- XmlrpcInterface.search:") + self.log.debug(" search(%s, %s, %s, %s, %s)" % ( schema_name, refs, subtypes, params, spec)) if not spec: spec = [] data = self._RPC.search(schema_name, refs, subtypes, params, spec) if data: - orb.log.debug(" - data returned: %s items." % len(data)) + self.log.debug(" - data returned: %s items." % len(data)) else: - orb.log.debug(" - no %s instances found" % schema_name) + self.log.debug(" - no %s instances found" % schema_name) return data def getCount(self, schema_name, refs, subtypes, params): @@ -382,14 +389,14 @@ @return: a C{list} of extracts of the objects that were found """ - orb.log.debug(" - XmlrpcInterface.getCount()") - orb.log.debug(" search(schema_name, refs, subtypes, params)") - orb.log.debug(" search(%s, %s, %s, %s)" % ( + self.log.debug(" - XmlrpcInterface.getCount()") + self.log.debug(" search(schema_name, refs, subtypes, params)") + self.log.debug(" search(%s, %s, %s, %s)" % ( schema_name, refs, subtypes, params)) count = self._RPC.getCount(schema_name, refs, subtypes, params) if count: - orb.log.debug(" - count returned: %s" % count) + self.log.debug(" - count returned: %s" % count) else: - orb.log.debug(" - no %s instances matched" % schema_name) + self.log.debug(" - no %s instances matched" % schema_name) return count From waterbug at step.nasa.gov Sun May 6 02:30:18 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Sun May 6 02:30:19 2007 Subject: [pangalactic-commits] Start work on getting namespaces from repo. Message-ID: <200705060630.l466UIJB014538@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/repo/pger.py 1.144 1.145 Log message: Start work on getting namespaces from repo. Index: PanGalactic/pangalactic/repo/pger.py diff -u PanGalactic/pangalactic/repo/pger.py:1.144 PanGalactic/pangalactic/repo/pger.py:1.145 --- PanGalactic/pangalactic/repo/pger.py:1.144 Sun Mar 18 02:28:31 2007 +++ PanGalactic/pangalactic/repo/pger.py Sun May 6 02:30:17 2007 @@ -1,10 +1,10 @@ -# $Id: pger.py,v 1.144 2007/03/18 06:28:31 waterbug Exp $ +# $Id: pger.py,v 1.145 2007/05/06 06:30:17 waterbug Exp $ """ The Pan Galactic Entropy Reverser -@version: $Revision: 1.144 $ +@version: $Revision: 1.145 $ """ -__version__ = "$Revision: 1.144 $"[11:-2] +__version__ = "$Revision: 1.145 $"[11:-2] import base64 import sys @@ -764,6 +764,16 @@ system='PGER') log.err(error) + def getNamespaces(self, requestor, ns): + """ + Get all names (C{id} Property values) currently registered for the + specified namespace. + """ + res = self.search(requestor, 'Identifiable', refs=0, subtypes=1, + spec=['id'], args=[('id_ns', '=', ns)]) + res.addCallback(lambda x: [r[0] for r in x]) + return res + def getNames(self, requestor, ns): """ Get all names (C{id} Property values) currently registered for the From waterbug at step.nasa.gov Tue May 8 23:50:13 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Tue May 8 23:50:15 2007 Subject: [pangalactic-commits] Minor bug fix and some notes. Message-ID: <200705090350.l493oDPk001906@ned.gsfc.nasa.gov> Modified files: PanGalactic/NOTES 1.14 1.15 PanGalactic/pangalactic/meta/names.py 1.41 1.42 PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py 1.7 1.8 Log message: Minor bug fix and some notes. Index: PanGalactic/NOTES diff -u PanGalactic/NOTES:1.14 PanGalactic/NOTES:1.15 --- PanGalactic/NOTES:1.14 Sat May 5 20:13:05 2007 +++ PanGalactic/NOTES Tue May 8 23:50:10 2007 @@ -8,7 +8,39 @@ Other stuff is just notes that haven't found their way into regular docs yet. ----------------------------------------------------------------------------- -*** ITEM 1 *** +----------------------------------------------------------------------- +Enhancements to "Project", contexts, namespaces, ids, oids, names, etc. +----------------------------------------------------------------------- + +New names (created by user) must have a namespace + +* default namespace is "local" (prefix only; not a valid URL) +* before committing local objs to a repo, user must pick or define a namespace + - can be any namespace to which user has permission to add names + - can be a Project created by the user + - the Project will be checked by the repository for uniqueness of its id + within either its parent namespace (e.g., an organizational namespace) or + within the repository's knowledge of the "world" namespace +* the current namespace serves as default ns for all local user-created objects + + +So ... coding: + +* Rules: + - oid = id_ns + id + - id must not have spaces (so oid is a valid URL) + + default id = name, with spaces (if any) replaced by underscores + + as currently, id must include version reference for uniqueness + +* Display should use prefixes for all "non-local" id's (id's that are not within + the current context's namespace) + - this is important for the Project select widget + - also may be important for id's in grids + - think about whether it is needed for PgxnObject ... + + maybe not: already have id_ns (which is prefix) + + but maybe so: when PgxnObj becomes customizable, user might not want to + have id_ns in the interface -- then prefix should be used with id. + --------------------------------------------- Pgef/Pmof MetaObject creation and maintenance --------------------------------------------- @@ -206,31 +238,3 @@ - namespaces ------------------------------------------------------ -Enhancements to "Project", contexts, namespaces, etc. ------------------------------------------------------ - -* Need to have a context -- a "space" (really, a namespace) - - space will be the area in which the user can create objects, etc. - - space will typically be the user's organization's space, but could be an - arbitrary namespace - - space will determine the local namespace (id's with no prefixes) - - PanGalaxian needs to append a prefix to "non-local" names when "space" is - specified as a context, and to *all* names when space is "Any" - -* User can create a Project in their space (which, again, may be an arbitrary - namespace they specify, or their organization's space, etc.) - - their new Project will then be the default context for any new objects they - create (the New Object dialog will allow them to specify another namespace - for which they are authorized). - -So ... coding: - -* Use prefixes for all "non-local" id's - - this is especially important for the Project select widget - - also do it for all id's in grids - - think about whether it is needed for PgxnObject ... - + maybe not: already have id_ns (which is prefix) - + but maybe so: when PgxnObj becomes customizable, user might not want to - have id_ns in the interface -- then prefix should be used with id. - Index: PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py diff -u PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py:1.7 PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py:1.8 --- PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py:1.7 Wed Apr 25 13:47:47 2007 +++ PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py Tue May 8 23:50:11 2007 @@ -1,10 +1,10 @@ -# $Id: pgxnchecklist.py,v 1.7 2007/04/25 17:47:47 waterbug Exp $ +# $Id: pgxnchecklist.py,v 1.8 2007/05/09 03:50:11 waterbug Exp $ """ A dialog that has a checkable list of items. -@version: $Revision: 1.7 $ +@version: $Revision: 1.8 $ """ -__version__ = "$Revision: 1.7 $"[11:-2] +__version__ = "$Revision: 1.8 $"[11:-2] from pprint import pprint import sys @@ -31,7 +31,7 @@ @type content: C{dict} @param colnames: a list of column names - @type colnames: C{dict} + @type colnames: C{list} @param checked: a list of the keys of rows that are initially checked -- note that this parameter becomes an instance variable, and is the best @@ -45,7 +45,7 @@ CheckListCtrlMixin.__init__(self) self.itemdict = content or {} self.colnames = colnames or [] - self.checked = checked + self.checked = checked or [] self.setColumns(colnames) self.setCheckListItems(content) self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated) Index: PanGalactic/pangalactic/meta/names.py diff -u PanGalactic/pangalactic/meta/names.py:1.41 PanGalactic/pangalactic/meta/names.py:1.42 --- PanGalactic/pangalactic/meta/names.py:1.41 Wed Apr 25 17:48:15 2007 +++ PanGalactic/pangalactic/meta/names.py Tue May 8 23:50:10 2007 @@ -1,11 +1,11 @@ -# $Id: names.py,v 1.41 2007/04/25 21:48:15 waterbug Exp $ +# $Id: names.py,v 1.42 2007/05/09 03:50:10 waterbug Exp $ """ Objects and services for handling identifiers, addresses, and namespaces. -@version: $Revision: 1.41 $ +@version: $Revision: 1.42 $ """ -__version__ = "$Revision: 1.41 $"[11:-2] +__version__ = "$Revision: 1.42 $"[11:-2] try: @@ -33,12 +33,18 @@ @ivar names: the namespace's names @type names: C{set} + + @ivar meta: the meta-level of the namespace -- an integer corresponding to + the n in the "Mn" meta-levels specified for the OMG's Meta Object + Facility. A meta-level of 10 is used to indicate that a namespace can + apply at any meta-level > 0. + @type meta: C{int} """ # TODO: decide whether an exception should be raised for attempts to # add a name that a Namespace already has def __init__(self, id, uri, names=None, complete=False, iteration=0, - version='baseline'): + version='baseline', meta=0): """ Initialize a PgefNamespace. @@ -54,6 +60,9 @@ @param complete: flag indicating whether the included member set is complete @type complete: C{bool} + + @param meta: (see definition in ivars, above.) + @type meta: C{int} """ if not id and not uri: raise NameError, 'At least one of id and uri must be non-empty.' @@ -65,6 +74,7 @@ else: self.names = set([]) self.complete = complete + self.meta = meta self.iteration = iteration self.version = version @@ -143,6 +153,7 @@ # XML Schema namespace (not available anywhere in RDF that I could find). registerNamespace(PgefNamespace(id=u'xsd', uri=u'http://www.w3.org/2001/XMLSchema', + meta=10, names=[ u'string', u'normalizedString', u'boolean', u'decimal', u'float', u'double', @@ -158,14 +169,18 @@ # RDF namespace registerNamespace(PgefNamespace(id='rdf', + meta=10, uri='http://www.w3.org/1999/02/22-rdf-syntax-ns#')) # RDFS namespace registerNamespace(PgefNamespace(id='rdfs', + meta=10, uri='http://www.w3.org/2000/01/rdf-schema#')) # OWL namespace -registerNamespace(PgefNamespace(id='owl', uri='http://www.w3.org/2002/07/owl#')) +registerNamespace(PgefNamespace(id='owl', + meta=10, + uri='http://www.w3.org/2002/07/owl#')) # 'pgeftest' namespace # PGEF permanent test object namespace. This namespace is intended to include @@ -174,6 +189,7 @@ # PanGalactic/src/sql/populate_pgerdb.sh. NOTE: insertion of other names into # this namespace may cause some unit tests to fail. registerNamespace(PgefNamespace(id='pgeftest', + meta=0, uri='http://pangalactic.us/test/lib/')) # 'pgeftesttmp' namespace @@ -181,11 +197,13 @@ # NOTE: insertion of other names into this namespace may cause some unit tests # to fail. registerNamespace(PgefNamespace(id='pgeftesttmp', + meta=0, uri='http://pangalactic.us/test/tmp/')) # 'pgefobjects' namespace # Namespace for PGEF reference objects (e.g., the 'admin' Person object). registerNamespace(PgefNamespace(id='pgefobjects', + meta=0, uri='http://pangalactic.us/objects/')) # 'world' namespace @@ -193,11 +211,13 @@ # appropriate -- should be used with the awareness that it may get "crowded" # eventually ... ;) registerNamespace(PgefNamespace(id='world', + meta=0, uri='http://earth.milkyway.universe/')) # 'mime' namespace # MIME media-types registerNamespace(PgefNamespace(id='mime', + meta=0, uri='http://www.iana.org/assignments/media-types/')) def u2q(uri): From waterbug at step.nasa.gov Wed May 9 14:47:33 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Wed May 9 14:47:36 2007 Subject: [pangalactic-commits] Attempt to fix bug in proj selection checklist on mswin. Message-ID: <200705091847.l49IlXQN014805@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/node/pangalaxian.py 1.186 1.187 Log message: Attempt to fix bug in proj selection checklist on mswin. Index: PanGalactic/pangalactic/node/pangalaxian.py diff -u PanGalactic/pangalactic/node/pangalaxian.py:1.186 PanGalactic/pangalactic/node/pangalaxian.py:1.187 --- PanGalactic/pangalactic/node/pangalaxian.py:1.186 Fri May 4 20:51:15 2007 +++ PanGalactic/pangalactic/node/pangalaxian.py Wed May 9 14:47:30 2007 @@ -2,16 +2,16 @@ # -*- coding: ANSI_X3.4-1968 -*- # generated by wxGlade 0.3.5.1 on Tue Feb 1 00:19:02 2005 -# $Id: pangalaxian.py,v 1.186 2007/05/05 00:51:15 waterbug Exp $ +# $Id: pangalaxian.py,v 1.187 2007/05/09 18:47:30 waterbug Exp $ """ Main application module for PanGalaxian, the PGEF GUI client. WE ARE THE PANGALAXIANS! :) -@version: $Revision: 1.186 $ +@version: $Revision: 1.187 $ """ -__version__ = "$Revision: 1.186 $"[11:-2] +__version__ = "$Revision: 1.187 $"[11:-2] # Python import logging @@ -999,14 +999,17 @@ self.log.info(' - onSelectProjects()') if orb.projects: nonseloids = set(list(orb.projects)) - set(prefs['projects']) - self.log.debug(' orb.projects [oids]: %s' + self.log.debug(' + orb.projects [oids]: %s' % str(list(orb.projects))) - self.log.debug(' prefs[projects]: %s' % str(prefs['projects'])) + self.log.debug(' + current prefs[projects]: %s' + % str(prefs['projects'])) projoids = prefs['projects'] + list(nonseloids) projdict = dict([(i, [orb.projects[projoids[i]].id, str(orb.projects[projoids[i]].name)]) for i in range(len(projoids))]) - self.selected_projects = list(range(len(prefs['projects']))) + self.selected_projects = range(len(prefs['projects'])) + self.log.debug(' + selected_projects: %s' + % str(self.selected_projects)) dlg = PgxnCheckListDialog(self, title='Select Projects', content=projdict, @@ -1014,7 +1017,11 @@ checked=self.selected_projects) dlg.ShowModal() dlg.Destroy() - prefs['projects'] = [projoids[i] for i in self.selected_projects] + # str() is here because of possible unicode issue on mswin + prefs['projects'] = [str(projoids[i]) + for i in self.selected_projects] + self.log.debug(' + new prefs[projects]: %s' + % str(prefs['projects'])) self.updateProjects() else: dlg = wx.MessageDialog(self, From waterbug at step.nasa.gov Wed May 9 14:57:19 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Wed May 9 14:57:19 2007 Subject: [pangalactic-commits] *Actually* fix the proj selection bug. ;) Message-ID: <200705091857.l49IvJvU015192@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py 1.8 1.9 Log message: *Actually* fix the proj selection bug. ;) Index: PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py diff -u PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py:1.8 PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py:1.9 --- PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py:1.8 Tue May 8 23:50:11 2007 +++ PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py Wed May 9 14:57:17 2007 @@ -1,10 +1,10 @@ -# $Id: pgxnchecklist.py,v 1.8 2007/05/09 03:50:11 waterbug Exp $ +# $Id: pgxnchecklist.py,v 1.9 2007/05/09 18:57:17 waterbug Exp $ """ A dialog that has a checkable list of items. -@version: $Revision: 1.8 $ +@version: $Revision: 1.9 $ """ -__version__ = "$Revision: 1.8 $"[11:-2] +__version__ = "$Revision: 1.9 $"[11:-2] from pprint import pprint import sys @@ -61,7 +61,7 @@ if flag: what = "checked" if index not in self.checked: - (self.checked.append(index)).sort() + self.checked.append(index) else: what = "unchecked" if index in self.checked: From waterbug at step.nasa.gov Wed May 9 15:18:46 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Wed May 9 15:18:50 2007 Subject: [pangalactic-commits] OK, so I lied ... another attempt ... Message-ID: <200705091918.l49JIkOQ016093@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/node/pangalaxian.py 1.187 1.188 Log message: OK, so I lied ... another attempt ... Index: PanGalactic/pangalactic/node/pangalaxian.py diff -u PanGalactic/pangalactic/node/pangalaxian.py:1.187 PanGalactic/pangalactic/node/pangalaxian.py:1.188 --- PanGalactic/pangalactic/node/pangalaxian.py:1.187 Wed May 9 14:47:30 2007 +++ PanGalactic/pangalactic/node/pangalaxian.py Wed May 9 15:18:42 2007 @@ -2,16 +2,16 @@ # -*- coding: ANSI_X3.4-1968 -*- # generated by wxGlade 0.3.5.1 on Tue Feb 1 00:19:02 2005 -# $Id: pangalaxian.py,v 1.187 2007/05/09 18:47:30 waterbug Exp $ +# $Id: pangalaxian.py,v 1.188 2007/05/09 19:18:42 waterbug Exp $ """ Main application module for PanGalaxian, the PGEF GUI client. WE ARE THE PANGALAXIANS! :) -@version: $Revision: 1.187 $ +@version: $Revision: 1.188 $ """ -__version__ = "$Revision: 1.187 $"[11:-2] +__version__ = "$Revision: 1.188 $"[11:-2] # Python import logging @@ -1004,9 +1004,13 @@ self.log.debug(' + current prefs[projects]: %s' % str(prefs['projects'])) projoids = prefs['projects'] + list(nonseloids) + self.log.debug(' + projoids: %s' + % str(projoids)) projdict = dict([(i, [orb.projects[projoids[i]].id, str(orb.projects[projoids[i]].name)]) for i in range(len(projoids))]) + self.log.debug(' + projdict: %s' + % str(projdict)) self.selected_projects = range(len(prefs['projects'])) self.log.debug(' + selected_projects: %s' % str(self.selected_projects)) From waterbug at step.nasa.gov Wed May 9 15:31:00 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Wed May 9 15:31:04 2007 Subject: [pangalactic-commits] Okay, let's see what this does. Message-ID: <200705091931.l49JV0Tc016609@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/node/pangalaxian.py 1.188 1.189 Log message: Okay, let's see what this does. Index: PanGalactic/pangalactic/node/pangalaxian.py diff -u PanGalactic/pangalactic/node/pangalaxian.py:1.188 PanGalactic/pangalactic/node/pangalaxian.py:1.189 --- PanGalactic/pangalactic/node/pangalaxian.py:1.188 Wed May 9 15:18:42 2007 +++ PanGalactic/pangalactic/node/pangalaxian.py Wed May 9 15:30:57 2007 @@ -2,16 +2,16 @@ # -*- coding: ANSI_X3.4-1968 -*- # generated by wxGlade 0.3.5.1 on Tue Feb 1 00:19:02 2005 -# $Id: pangalaxian.py,v 1.188 2007/05/09 19:18:42 waterbug Exp $ +# $Id: pangalaxian.py,v 1.189 2007/05/09 19:30:57 waterbug Exp $ """ Main application module for PanGalaxian, the PGEF GUI client. WE ARE THE PANGALAXIANS! :) -@version: $Revision: 1.188 $ +@version: $Revision: 1.189 $ """ -__version__ = "$Revision: 1.188 $"[11:-2] +__version__ = "$Revision: 1.189 $"[11:-2] # Python import logging @@ -1007,7 +1007,8 @@ self.log.debug(' + projoids: %s' % str(projoids)) projdict = dict([(i, [orb.projects[projoids[i]].id, - str(orb.projects[projoids[i]].name)]) + orb.projects[projoids[i]].name or + orb.projects[projoids[i]].id]) for i in range(len(projoids))]) self.log.debug(' + projdict: %s' % str(projdict)) From waterbug at step.nasa.gov Wed May 9 16:14:59 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Wed May 9 16:15:01 2007 Subject: [pangalactic-commits] Try some more things ... Message-ID: <200705092014.l49KExBV017423@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py 1.9 1.10 Log message: Try some more things ... Index: PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py diff -u PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py:1.9 PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py:1.10 --- PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py:1.9 Wed May 9 14:57:17 2007 +++ PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py Wed May 9 16:14:57 2007 @@ -1,10 +1,10 @@ -# $Id: pgxnchecklist.py,v 1.9 2007/05/09 18:57:17 waterbug Exp $ +# $Id: pgxnchecklist.py,v 1.10 2007/05/09 20:14:57 waterbug Exp $ """ A dialog that has a checkable list of items. -@version: $Revision: 1.9 $ +@version: $Revision: 1.10 $ """ -__version__ = "$Revision: 1.9 $"[11:-2] +__version__ = "$Revision: 1.10 $"[11:-2] from pprint import pprint import sys @@ -40,14 +40,15 @@ """ def __init__(self, parent, content, colnames, checked): - orb.log.debug('PgxnCheckList') + orb.log.debug(' + PgxnCheckList') wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT) CheckListCtrlMixin.__init__(self) self.itemdict = content or {} + orb.log.debug(' self.itemdict: %s' % (pprint(self.itemdict))) self.colnames = colnames or [] self.checked = checked or [] self.setColumns(colnames) - self.setCheckListItems(content) + self.setCheckListItems(self.itemdict) self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated) self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self) self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.OnItemDeselected, self) @@ -76,8 +77,9 @@ # self.InsertColumn(1, "Title", wx.LIST_FORMAT_RIGHT) def setCheckListItems(self, content): - orb.log.debug(' content: %s' % (pprint(content))) - content = content or [] + orb.log.debug(' + PgxnCheckList.setCheckListItems') + orb.log.debug(' content: %s' % (pprint(content))) + content = content or {} for key, data in content.iteritems(): index = self.InsertStringItem(sys.maxint, data[0]) if len(data) > 1: @@ -102,7 +104,7 @@ """ # TODO: define "checkeditems" property, based on state of checklist - def __init__(self, parent, title, content, colnames, checked=None, + def __init__(self, parent, title, content, colnames, checked, size=wx.DefaultSize, pos=wx.DefaultPosition, style=wx.DEFAULT_DIALOG_STYLE): @@ -113,9 +115,13 @@ style=wx.NORMAL, weight=wx.BOLD)) sizer.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5) - self.checklist = PgxnCheckList(self, content, colnames, checked) - self.checked = self.checklist.checked + self.checked = checked self.content = content + self.colnames = colnames + self.checklist = PgxnCheckList(self, + self.content, + self.colnames, + self.checked) minsize = self.checklist.GetSize() sizer.Add(self.checklist, 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0) sizer.SetMinSize(minsize) From waterbug at step.nasa.gov Thu May 10 00:30:58 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Thu May 10 00:31:00 2007 Subject: [pangalactic-commits] Okay, no defaults here, dammit! Fixed ... Message-ID: <200705100430.l4A4UwW3022191@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py 1.10 1.11 Log message: Okay, no defaults here, dammit! Fixed ... Index: PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py diff -u PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py:1.10 PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py:1.11 --- PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py:1.10 Wed May 9 16:14:57 2007 +++ PanGalactic/pangalactic/node/gui/dialogs/pgxnchecklist.py Thu May 10 00:30:56 2007 @@ -1,10 +1,10 @@ -# $Id: pgxnchecklist.py,v 1.10 2007/05/09 20:14:57 waterbug Exp $ +# $Id: pgxnchecklist.py,v 1.11 2007/05/10 04:30:56 waterbug Exp $ """ A dialog that has a checkable list of items. -@version: $Revision: 1.10 $ +@version: $Revision: 1.11 $ """ -__version__ = "$Revision: 1.10 $"[11:-2] +__version__ = "$Revision: 1.11 $"[11:-2] from pprint import pprint import sys @@ -45,8 +45,8 @@ CheckListCtrlMixin.__init__(self) self.itemdict = content or {} orb.log.debug(' self.itemdict: %s' % (pprint(self.itemdict))) - self.colnames = colnames or [] - self.checked = checked or [] + self.colnames = colnames + self.checked = checked self.setColumns(colnames) self.setCheckListItems(self.itemdict) self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated) From waterbug at step.nasa.gov Thu May 10 11:13:51 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Thu May 10 11:13:53 2007 Subject: [pangalactic-commits] Fixed state/prefs writing bug. Message-ID: <200705101513.l4AFDp2S028710@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/node/pangalaxian.py 1.189 1.190 PanGalactic/pangalactic/node/gui/widgets/pgxncontextpanel.py 1.5 1.6 Log message: Fixed state/prefs writing bug. Index: PanGalactic/pangalactic/node/pangalaxian.py diff -u PanGalactic/pangalactic/node/pangalaxian.py:1.189 PanGalactic/pangalactic/node/pangalaxian.py:1.190 --- PanGalactic/pangalactic/node/pangalaxian.py:1.189 Wed May 9 15:30:57 2007 +++ PanGalactic/pangalactic/node/pangalaxian.py Thu May 10 11:13:49 2007 @@ -2,16 +2,16 @@ # -*- coding: ANSI_X3.4-1968 -*- # generated by wxGlade 0.3.5.1 on Tue Feb 1 00:19:02 2005 -# $Id: pangalaxian.py,v 1.189 2007/05/09 19:30:57 waterbug Exp $ +# $Id: pangalaxian.py,v 1.190 2007/05/10 15:13:49 waterbug Exp $ """ Main application module for PanGalaxian, the PGEF GUI client. WE ARE THE PANGALAXIANS! :) -@version: $Revision: 1.189 $ +@version: $Revision: 1.190 $ """ -__version__ = "$Revision: 1.189 $"[11:-2] +__version__ = "$Revision: 1.190 $"[11:-2] # Python import logging @@ -420,7 +420,7 @@ # self.GodMenu = None # self.GodMode = None # self.prefs_loginconfirm.Check(prefs.get('show_login_confirmed', True)) - prefs['projects'] = prefs.get('projects', list(orb.projects)) + prefs['projects'] = prefs.get('projects', []) self.contexts = state.get('contexts') or [] self.__set_properties() self.__do_layout() @@ -603,7 +603,7 @@ def updateProjects(self): """ - Update the C{projects} instance variable, if necessary. + Update the project selection widget. """ # TODO: pass in a namespace or some form of context to restrict the # list @@ -771,12 +771,12 @@ for s in state: if s != 'imaps' and s != 'pmaps': self.log.info(" * %s = %s" % (s, state[s])) - self.log.info(' + writing state to %s ...' % os.path.join( - os.getcwd(), 'state')) - writeState('state') - self.log.info(' + writing prefs to %s ...' % os.path.join( - os.getcwd(), 'prefs')) - writePrefs('prefs') + self.log.info(' + writing state to %s ...' + % os.path.join(prefs['home'], 'state')) + writeState(os.path.join(prefs['home'], 'state')) + self.log.info(' + writing prefs to %s ...' + % os.path.join(prefs['home'], 'prefs')) + writePrefs(os.path.join(prefs['home'], 'prefs')) self.log.info(' - state and prefs files written.') self.log.info(" - g'night!") self.Destroy() Index: PanGalactic/pangalactic/node/gui/widgets/pgxncontextpanel.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxncontextpanel.py:1.5 PanGalactic/pangalactic/node/gui/widgets/pgxncontextpanel.py:1.6 --- PanGalactic/pangalactic/node/gui/widgets/pgxncontextpanel.py:1.5 Sun Apr 22 22:07:52 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxncontextpanel.py Thu May 10 11:13:50 2007 @@ -1,9 +1,9 @@ """ PanGalaxian's panel containing context widgets (combos) -@version: $Revision: 1.5 $ +@version: $Revision: 1.6 $ """ -__version__ = "$Revision: 1.5 $"[11:-2] +__version__ = "$Revision: 1.6 $"[11:-2] import wx from pangalactic.node import prefs, state @@ -54,7 +54,6 @@ self.contextwidget = contextwgt def onStateChange(self): - # TODO: change orb.projects to pref['projects'], when available self.projectwidget.items = [(orb.projects[oid].id, oid) for oid in prefs['projects']] self.projectwidget.selected = state.get('project') From waterbug at step.nasa.gov Fri May 11 17:40:22 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Fri May 11 17:40:24 2007 Subject: [pangalactic-commits] Beginnings of a trash can for cache objs. Message-ID: <200705112140.l4BLeMcB022463@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/node/cache.py 1.33 1.34 PanGalactic/pangalactic/node/uberorb.py 1.144 1.145 Log message: Beginnings of a trash can for cache objs. Index: PanGalactic/pangalactic/node/cache.py diff -u PanGalactic/pangalactic/node/cache.py:1.33 PanGalactic/pangalactic/node/cache.py:1.34 --- PanGalactic/pangalactic/node/cache.py:1.33 Sun May 6 02:24:39 2007 +++ PanGalactic/pangalactic/node/cache.py Fri May 11 17:40:20 2007 @@ -1,9 +1,9 @@ """ Local object cache manager (a layer over ZODB) -@version: $Revision: 1.33 $ +@version: $Revision: 1.34 $ """ -__version__ = "$Revision: 1.33 $"[11:-2] +__version__ = "$Revision: 1.34 $"[11:-2] # Python import os, sys @@ -52,6 +52,14 @@ self.interfaces = {} for i in interfaces: self.addInterface(i) + # create a cache trashcan + self.trashfilename = os.path.join(datadir, "trash.fs") + self.trashstorage = FileStorage.FileStorage(self.trashfilename) + self.trashdb = DB(self.trashstorage) + self.trashdbconnection = self.trashdb.open() + self.trashdbroot = self.trashdbconnection.root() + if not self.trashdbroot.get('OidLookup'): + self.trashdbroot['OidLookup'] = PersistentMapping() # property: objs @@ -61,13 +69,23 @@ """ return self.dbroot['OidLookup'] - def setObjs(self, value): - raise TypeError, 'objs attribute cannot be set.' + objs = property(getObjs, 'objs') - def delObjs(self): - raise TypeError, 'objs attribute cannot be deleted.' + # property: trash - objs = property(getObjs, setObjs, delObjs, 'objs') + def getTrash(self): + """ + Get a dictionary of the objects in the cache's trashcan by oid. + """ + return self.trashdbroot['OidLookup'] + + def setTrash(self, value): + raise TypeError, 'trash attribute cannot be set.' + + def delTrash(self): + raise TypeError, 'trash attribute cannot be deleted.' + + trash = property(getTrash, 'trash') def pack(self): """ @@ -77,11 +95,12 @@ self.commit() def clear(self): + import shutil + shutil.copy("data/pgef.fs", "data/pgef.fs.deleted") for entry in self.dbroot['OidLookup'].keys(): del self.dbroot['OidLookup'][entry] + self.commit() del self.dbroot['OidLookup'] - import shutil - shutil.copy("data/pgef.fs", "data/pgef.fs.deleted") def commit(self): transaction.get().commit() @@ -104,7 +123,37 @@ def saveObjects(self, objs): """ - Save some objects in the cache. Map the object's oid to the object + Save some objects to the cache. Map the object's oid to the object + in the dictionary C{self.objs} (which includes *all* objects in the + cache). By default, also add the object to the dictionary + C{self.dbroot[schema]}, where C{schema} is the object's + _schema.__name__, and to any dictionaries whose schemas are parents + of the object's _schema. + + @param objs: objects to be saved + @type objs: list (usually of instances of + L{pangalactic.meta.pgefobject.PgefObject} + """ + self.log.debug(" - ObjectCache.saveObjects") + # TODO: 'merge' -- i.e., in case of oid collision, compare + # last-modified dates. If the object to be saved has been modified more + # recently than the cache copy, replace the cache copy; if both have + # been modified, notify user of the conflict. + if type(objs) is not list: + objs = [objs] + for obj in objs: + self.objs[obj.oid] = obj + if hasattr(obj, '_schema'): + self.dbroot[obj._schema.__name__][obj.oid] = obj + # dictionaries of parents of the object's _schema + for name in [x.__name__ for x in self.interfaces.values() + if x in allYourBase(obj._schema)]: + self.dbroot[name][obj.oid] = obj + self.commit() + + def deleteObjects(self, objs): + """ + Save some objects to the cache. Map the object's oid to the object in the dictionary C{self.objs} (which includes *all* objects in the cache). By default, also add the object to the dictionary C{self.dbroot[schema]}, where C{schema} is the object's @@ -117,12 +166,11 @@ """ self.log.debug(" - ObjectCache.saveObjects") # TODO: 'merge' -- i.e., in case of oid collision, compare - # last-modified dates. If the repo copy has been modified and the - # cache copy has not, replace the cache copy; if both have been - # modified, notify user of the conflict. + # last-modified dates. If the object to be saved has been modified more + # recently than the cache copy, replace the cache copy; if both have + # been modified, notify user of the conflict. if type(objs) is not list: objs = [objs] - iface_names = list(self.interfaces) for obj in objs: self.objs[obj.oid] = obj if hasattr(obj, '_schema'): @@ -133,6 +181,21 @@ self.dbroot[name][obj.oid] = obj self.commit() + def delete(self, o): + """ + Delete an object from the local cache, either by direct reference + or by oid. + + @param obj: a C{PgefObject} instance or the oid of an instance + @type obj: C{PgefObject} or C{str} + """ + if isAString(o): + if self.objs[o]: + del self.objs[o] + elif o.oid in self.objs: + del self.objs[o.oid] + self.commit() + def _getFilter(self, obj, **kw): """ Return True for an object that matches all attr/values, False @@ -170,32 +233,6 @@ # applications may only have some of the dicts that the cache has return self.dbroot.get(name) - def add(self, objs): - """ - Add new locally created objects to the cache. - - @param objs: C{PgefObject}s to be added - @type objs: C{list} - """ - self.log.debug(" - ObjectCache.add") - self.saveObjects(objs) - self.commit() - - def delete(self, o): - """ - Delete an object from the local cache, either by direct reference - or by oid. - - @param obj: a C{PgefObject} instance or the oid of an instance - @type obj: C{PgefObject} or C{str} - """ - if isAString(o): - if self.objs[o]: - del self.objs[o] - elif o.oid in self.objs: - del self.objs[o.oid] - self.commit() - # FIXME: Domain-specific stuff (everything from here on) should be in one # or more separate modules Index: PanGalactic/pangalactic/node/uberorb.py diff -u PanGalactic/pangalactic/node/uberorb.py:1.144 PanGalactic/pangalactic/node/uberorb.py:1.145 --- PanGalactic/pangalactic/node/uberorb.py:1.144 Sun May 6 02:24:39 2007 +++ PanGalactic/pangalactic/node/uberorb.py Fri May 11 17:40:20 2007 @@ -1,11 +1,11 @@ -# $Id: uberorb.py,v 1.144 2007/05/06 06:24:39 waterbug Exp $ +# $Id: uberorb.py,v 1.145 2007/05/11 21:40:20 waterbug Exp $ # -*- test-case-name: pangalactic.test.test_uberorb -*- """ A PanGalaxian node's UberORB -@version: $Revision: 1.144 $ +@version: $Revision: 1.145 $ """ -__version__ = "$Revision: 1.144 $"[11:-2] +__version__ = "$Revision: 1.145 $"[11:-2] import logging import mimetypes @@ -400,12 +400,6 @@ self.log.info(' * no updates found.') return objs - def add(self, addlist): - if self.cache: - self.cache.add(addlist) - else: - pass - def save(self, objs): if self.cache: self.cache.saveObjects(objs) From waterbug at step.nasa.gov Fri May 11 22:54:54 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Fri May 11 22:54:55 2007 Subject: [pangalactic-commits] Cache interface improvements (more coming ...). Message-ID: <200705120254.l4C2ssf6023428@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/node/cache.py 1.34 1.35 PanGalactic/pangalactic/node/uberorb.py 1.145 1.146 Log message: Cache interface improvements (more coming ...). Index: PanGalactic/pangalactic/node/cache.py diff -u PanGalactic/pangalactic/node/cache.py:1.34 PanGalactic/pangalactic/node/cache.py:1.35 --- PanGalactic/pangalactic/node/cache.py:1.34 Fri May 11 17:40:20 2007 +++ PanGalactic/pangalactic/node/cache.py Fri May 11 22:54:53 2007 @@ -1,9 +1,9 @@ """ Local object cache manager (a layer over ZODB) -@version: $Revision: 1.34 $ +@version: $Revision: 1.35 $ """ -__version__ = "$Revision: 1.34 $"[11:-2] +__version__ = "$Revision: 1.35 $"[11:-2] # Python import os, sys @@ -49,9 +49,7 @@ self.dbroot = self.dbconnection.root() if not self.dbroot.get('OidLookup'): self.dbroot['OidLookup'] = PersistentMapping() - self.interfaces = {} - for i in interfaces: - self.addInterface(i) + self.addInterfaces(interfaces) # create a cache trashcan self.trashfilename = os.path.join(datadir, "trash.fs") self.trashstorage = FileStorage.FileStorage(self.trashfilename) @@ -79,12 +77,6 @@ """ return self.trashdbroot['OidLookup'] - def setTrash(self, value): - raise TypeError, 'trash attribute cannot be set.' - - def delTrash(self): - raise TypeError, 'trash attribute cannot be deleted.' - trash = property(getTrash, 'trash') def pack(self): @@ -105,21 +97,24 @@ def commit(self): transaction.get().commit() - def addInterface(self, iface): + def addInterfaces(self, ifaces): """ For an C{Interface}, set up a root dictionary in the cache that will contain C{PgefObject} instances whose _schema is that C{Interface}. - @param iface: an C{Interface} to be supported by the cache - @type iface: L{zope.interface.interface.InterfaceClass} instance - """ - self.log.debug(' - ObjectCache.addInterface: adding %s' - % iface.__name__) - if iface.__name__ not in self.dbroot.keys(): - self.dbroot[iface.__name__] = PersistentMapping() + @param ifaces: a list of C{Interface} instances that will be supported + by the cache + @type ifaces: C{list} of L{zope.interface.interface.InterfaceClass} + """ + self.log.debug(' - ObjectCache.addInterfaces') + self.interfaces = getattr(self, 'interfaces', {}) + for i in ifaces: + self.log.debug(' + %s' % i.__name__) + if i.__name__ not in self.dbroot.keys(): + self.dbroot[i.__name__] = PersistentMapping() + self.interfaces[i.__name__] = i self.commit() - self.interfaces[iface.__name__] = iface def saveObjects(self, objs): """ @@ -153,12 +148,7 @@ def deleteObjects(self, objs): """ - Save some objects to the cache. Map the object's oid to the object - in the dictionary C{self.objs} (which includes *all* objects in the - cache). By default, also add the object to the dictionary - C{self.dbroot[schema]}, where C{schema} is the object's - _schema.__name__, and to any dictionaries whose schemas are parents - of the object's _schema. + Delete objects from the cache and save them into trash. @param objs: objects to be saved @type objs: list (usually of instances of @@ -172,28 +162,14 @@ if type(objs) is not list: objs = [objs] for obj in objs: - self.objs[obj.oid] = obj if hasattr(obj, '_schema'): - self.dbroot[obj._schema.__name__][obj.oid] = obj - # dictionaries of parents of the object's _schema + del self.dbroot[obj._schema.__name__][obj.oid] + # delete from dictionaries of parents of the object's _schema for name in [x.__name__ for x in self.interfaces.values() - if x in allYourBase(obj._schema)]: - self.dbroot[name][obj.oid] = obj - self.commit() - - def delete(self, o): - """ - Delete an object from the local cache, either by direct reference - or by oid. - - @param obj: a C{PgefObject} instance or the oid of an instance - @type obj: C{PgefObject} or C{str} - """ - if isAString(o): - if self.objs[o]: - del self.objs[o] - elif o.oid in self.objs: - del self.objs[o.oid] + if (x in allYourBase(obj._schema) + and self.dbroot[name].get(obj.oid))]: + del self.dbroot[name][obj.oid] + del self.objs[obj.oid] self.commit() def _getFilter(self, obj, **kw): Index: PanGalactic/pangalactic/node/uberorb.py diff -u PanGalactic/pangalactic/node/uberorb.py:1.145 PanGalactic/pangalactic/node/uberorb.py:1.146 --- PanGalactic/pangalactic/node/uberorb.py:1.145 Fri May 11 17:40:20 2007 +++ PanGalactic/pangalactic/node/uberorb.py Fri May 11 22:54:53 2007 @@ -1,11 +1,11 @@ -# $Id: uberorb.py,v 1.145 2007/05/11 21:40:20 waterbug Exp $ +# $Id: uberorb.py,v 1.146 2007/05/12 02:54:53 waterbug Exp $ # -*- test-case-name: pangalactic.test.test_uberorb -*- """ A PanGalaxian node's UberORB -@version: $Revision: 1.145 $ +@version: $Revision: 1.146 $ """ -__version__ = "$Revision: 1.145 $"[11:-2] +__version__ = "$Revision: 1.146 $"[11:-2] import logging import mimetypes @@ -878,17 +878,6 @@ self.log.debug(' + end getAcusByAssemblyOid') return acus - def removeLocalObjFromCache(self, o): - """ - Remove a local object from the cache (ZODB). - - @param objoroid: a C{PgefObject} instance - @type objoroid: C{PgefObject} - """ - self.log.debug(' - removeLocalObjFromCache') - if getattr(self, 'cache'): - self.cache.delete(o) - """ A singleton UberORB instance: orb From waterbug at step.nasa.gov Sat May 12 16:00:48 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Sat May 12 16:00:51 2007 Subject: [pangalactic-commits] Enhanced: logging, events, state change ... Message-ID: <200705122000.l4CK0mPI025413@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/node/cache.py 1.35 1.36 PanGalactic/pangalactic/node/pangalaxian.py 1.190 1.191 PanGalactic/pangalactic/node/uberorb.py 1.146 1.147 PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py 1.146 1.147 PanGalactic/pangalactic/node/gui/widgets/pgxnstatusbar.py 1.34 1.35 PanGalactic/pangalactic/utils/xmlrpcinterface.py 1.118 1.119 Log message: Enhanced: logging, events, state change ... * widget-specific loggers, cache and xmlrpcinterface loggers * more sensible login/logout state changes * UI now less jumpy on those events, e.g. (phew! :) Index: PanGalactic/pangalactic/node/cache.py diff -u PanGalactic/pangalactic/node/cache.py:1.35 PanGalactic/pangalactic/node/cache.py:1.36 --- PanGalactic/pangalactic/node/cache.py:1.35 Fri May 11 22:54:53 2007 +++ PanGalactic/pangalactic/node/cache.py Sat May 12 16:00:44 2007 @@ -1,12 +1,12 @@ """ Local object cache manager (a layer over ZODB) -@version: $Revision: 1.35 $ +@version: $Revision: 1.36 $ """ -__version__ = "$Revision: 1.35 $"[11:-2] +__version__ = "$Revision: 1.36 $"[11:-2] # Python -import os, sys +import logging, os, sys # ZODB from persistent.mapping import PersistentMapping @@ -25,16 +25,13 @@ Light-weight local object persistence for a PanGalactic node. """ - def __init__(self, interfaces, home='', log=None): + def __init__(self, interfaces, home=''): """ Initialize an C{ObjectCache} instance. @param interfaces: """ - self.log = log - if not log: - self.log.debug = sys.stdout.write - self.log.info = sys.stdout.write + self.log = logging.getLogger('cache') # If modifying this stuff, be careful: order is important self.log.debug('ObjectCache (ZODB) starting up ...') self.log.debug(' - initializing LocalStorage') @@ -50,7 +47,7 @@ if not self.dbroot.get('OidLookup'): self.dbroot['OidLookup'] = PersistentMapping() self.addInterfaces(interfaces) - # create a cache trashcan + # create a cache trash self.trashfilename = os.path.join(datadir, "trash.fs") self.trashstorage = FileStorage.FileStorage(self.trashfilename) self.trashdb = DB(self.trashstorage) @@ -84,6 +81,7 @@ Remove old entries from and optimize the cache. """ self.db.pack() + self.dbtrash.pack() self.commit() def clear(self): Index: PanGalactic/pangalactic/utils/xmlrpcinterface.py diff -u PanGalactic/pangalactic/utils/xmlrpcinterface.py:1.118 PanGalactic/pangalactic/utils/xmlrpcinterface.py:1.119 --- PanGalactic/pangalactic/utils/xmlrpcinterface.py:1.118 Sun May 6 02:24:40 2007 +++ PanGalactic/pangalactic/utils/xmlrpcinterface.py Sat May 12 16:00:46 2007 @@ -1,16 +1,17 @@ -# $Id: xmlrpcinterface.py,v 1.118 2007/05/06 06:24:40 waterbug Exp $ +# $Id: xmlrpcinterface.py,v 1.119 2007/05/12 20:00:46 waterbug Exp $ """ PanGalactic Client XML-RPC Interfaces -@version: $Revision: 1.118 $ +@version: $Revision: 1.119 $ """ -__version__ = "$Revision: 1.118 $"[11:-2] +__version__ = "$Revision: 1.119 $"[11:-2] import base64 -import xmlrpclib -import string import httplib +import logging +import string +import xmlrpclib from pprint import pprint @@ -96,8 +97,7 @@ """ XML-RPC API to PGER """ - def __init__(self, hostandport, userid='', passwd='', secure=True, - log=None): + def __init__(self, hostandport, userid='', passwd='', secure=True): """ Initialize an XML-RPC server proxy for the specified host, port, userid, and password. @@ -114,23 +114,17 @@ @param secure: flag to indicate whether connection should use SSL (True, the default) or not. @type secure: C{bool} - - @param log: a writable log object (normally, the orb's log) - @type log: C{logging.Logger} """ - self.log = log - if not log: - self.log.debug = sys.stdout.write - self.log.info = sys.stdout.write + self.log = logging.getLogger('xmlrpciface') # (worry about proxies later, if necessary) if secure: conns = 'https://' else: conns = 'http://' conns = conns + hostandport - self.log.debug('XmlrpcInterface: connection string is "%s"' % conns) - self.log.debug(' userid is: "%s"' % userid) - self.log.debug(' passwd is: "%s"' % passwd) + self.log.debug(' - connect: "%s"' % conns) + self.log.debug(' - userid: "%s"' % userid) + self.log.debug(' - passwd: "%s"' % passwd) if userid and passwd: self.userid = userid if secure: @@ -193,14 +187,14 @@ (now with new state info in their repository-related attributes) """ - self.log.debug("XmlrpcInterface.addobjects") + self.log.debug(" - addObjects") if not objs: - self.log.debug(" * empty object list") + self.log.debug(" + empty object list") newexts = [] else: - self.log.debug(" * oids and schemas of objects to be added:") + self.log.debug(" + oids and schemas of objects to be added:") for o in objs: - self.log.debug(' + %s (%s)' % (o.oid, o._schema.__name__)) + self.log.debug(' * %s (%s)' % (o.oid, o._schema.__name__)) extracts = [o.extract() for o in objs] newexts = self._RPC.addObjects(extracts) return newexts @@ -217,14 +211,14 @@ (now with new state info in their repository-related attributes) """ - self.log.debug("XmlrpcInterface.updateObjects") + self.log.debug(" - updateObjects") if not objs: - self.log.debug(" * empty object list") + self.log.debug(" + empty object list") newexts = [] else: - self.log.debug(" * oids and schemas of objects to be updated:") + self.log.debug(" + oids and schemas of objects to be updated:") for o in objs: - self.log.debug(' + %s (%s)' % (o.oid, o._schema.__name__)) + self.log.debug(' * %s (%s)' % (o.oid, o._schema.__name__)) extracts = [o.extract() for o in objs] newexts = self._RPC.updateObjects(extracts) return newexts @@ -240,14 +234,14 @@ updated with an iteration, version, id, etc. @rtype: C{list} of extracts (C{dict}s) """ - self.log.debug("XmlrpcInterface.commitVersions()") + self.log.debug(" - commitVersions()") if not objs: - self.log.debug(" * empty object list") + self.log.debug(" + empty object list") newexts = [] else: - self.log.debug(" * ids and schemas of versions to be committed:") + self.log.debug(" + ids and schemas of versions to be committed:") for o in objs: - self.log.debug(' + %s (%s)' % (o.id, o._schema.__name__)) + self.log.debug(' * %s (%s)' % (o.id, o._schema.__name__)) extracts = [o.extract() for o in objs] newexts = self._RPC.commitVersions(extracts) return newexts @@ -275,9 +269,7 @@ @param params: attr-value criteria for desired objects @type params: C{dict} """ - self.log.debug("XmlrpcInterface.getobjects") - self.log.debug(' - xmlrpc.getObjects command is:') - self.log.debug(' getObjects(%s, %s, %s, %s)' % ( + self.log.debug(' - getObjects(%s, %s, %s, %s)' % ( schema_name, refs, subtypes, params)) return self._RPC.getObjects(schema_name, refs, subtypes, params) @@ -288,7 +280,7 @@ @type oids: C{list} @param oids: oids of the desired objects """ - self.log.debug("XmlrpcInterface.getObjectsByOids") + self.log.debug(" - getObjectsByOids(%s)" % (str(oids))) return self._RPC.getObjectsByOids(oids) def getNames(self, ns): @@ -298,7 +290,7 @@ @param ns: the URL (oid) of a namespace @type ns: C{str} """ - self.log.debug("XmlrpcInterface.getNames()") + self.log.debug(" - getNames(%s)" % ns) return self._RPC.getNames(ns) def getBaseIds(self, ns): @@ -308,7 +300,7 @@ @param ns: the URL (oid) of a namespace @type ns: C{str} """ - self.log.debug("xmlrpcinterface.getBaseIds()") + self.log.debug(" - getBaseIds(%s)" % ns) return self._RPC.getBaseIds(ns) def search(self, schema_name, refs, subtypes, params, spec): @@ -346,16 +338,15 @@ @return: a C{list} of extracts of the objects that were found """ - self.log.debug("- XmlrpcInterface.search:") - self.log.debug(" search(%s, %s, %s, %s, %s)" % ( + self.log.debug(" - search(%s, %s, %s, %s, %s)" % ( schema_name, refs, subtypes, params, spec)) if not spec: spec = [] data = self._RPC.search(schema_name, refs, subtypes, params, spec) if data: - self.log.debug(" - data returned: %s items." % len(data)) + self.log.debug(" + data returned: %s items." % len(data)) else: - self.log.debug(" - no %s instances found" % schema_name) + self.log.debug(" + no %s instances found" % schema_name) return data def getCount(self, schema_name, refs, subtypes, params): @@ -389,14 +380,13 @@ @return: a C{list} of extracts of the objects that were found """ - self.log.debug(" - XmlrpcInterface.getCount()") - self.log.debug(" search(schema_name, refs, subtypes, params)") - self.log.debug(" search(%s, %s, %s, %s)" % ( + self.log.debug(" - getCount(schema_name, refs, subtypes, params)") + self.log.debug(" + getCount(%s, %s, %s, %s)" % ( schema_name, refs, subtypes, params)) count = self._RPC.getCount(schema_name, refs, subtypes, params) if count: - self.log.debug(" - count returned: %s" % count) + self.log.debug(" + count returned: %s" % count) else: - self.log.debug(" - no %s instances matched" % schema_name) + self.log.debug(" + no %s instances matched" % schema_name) return count Index: PanGalactic/pangalactic/node/uberorb.py diff -u PanGalactic/pangalactic/node/uberorb.py:1.146 PanGalactic/pangalactic/node/uberorb.py:1.147 --- PanGalactic/pangalactic/node/uberorb.py:1.146 Fri May 11 22:54:53 2007 +++ PanGalactic/pangalactic/node/uberorb.py Sat May 12 16:00:45 2007 @@ -1,11 +1,11 @@ -# $Id: uberorb.py,v 1.146 2007/05/12 02:54:53 waterbug Exp $ +# $Id: uberorb.py,v 1.147 2007/05/12 20:00:45 waterbug Exp $ # -*- test-case-name: pangalactic.test.test_uberorb -*- """ A PanGalaxian node's UberORB -@version: $Revision: 1.146 $ +@version: $Revision: 1.147 $ """ -__version__ = "$Revision: 1.146 $"[11:-2] +__version__ = "$Revision: 1.147 $"[11:-2] import logging import mimetypes @@ -73,7 +73,6 @@ def register(self, receiver, signal, **kw): dispatcher.connect(receiver, signal, **kw) - def startLogging(self, console=False, server=False, level=logging.INFO): """ Create a logger and begin writing to the log. This function assumes @@ -113,7 +112,7 @@ # self.__cache = ObjectCache(self.interfaces.values(), home=home) ifaces = [self.interfaces[i] for i in self.persistables] self.log.debug(' interfaces: %s' % str(self.persistables)) - self.__cache = ObjectCache(ifaces, home=home, log=self.log) + self.__cache = ObjectCache(ifaces, home=home) # self.createDefaultNamespace() else: raise ValueError, 'the orb already has a cache.' @@ -183,8 +182,7 @@ return XmlrpcInterface(hostandport=hostandport, userid=userid, passwd=passwd, - secure=secure, - log=self.log) + secure=secure) def login(self, hostandport, userid, passwd, secure=True): """ Index: PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py:1.146 PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py:1.147 --- PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py:1.146 Mon Mar 26 02:12:39 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py Sat May 12 16:00:45 2007 @@ -1,10 +1,10 @@ -# $Id: pgxnobject.py,v 1.146 2007/03/26 06:12:39 waterbug Exp $ +# $Id: pgxnobject.py,v 1.147 2007/05/12 20:00:45 waterbug Exp $ """ PanGalaxianObject (a C{PgefObject} viewer/editor) -@version: $Revision: 1.146 $ +@version: $Revision: 1.147 $ """ -__version__ = "$Revision: 1.146 $"[11:-2] +__version__ = "$Revision: 1.147 $"[11:-2] import logging from copy import deepcopy @@ -81,7 +81,7 @@ zero-length string. @type editing: C{str} """ - self.log = logging.getLogger('PanGalaxianObject') + self.log = logging.getLogger('pgxnobject') self.log.debug(' - PanGalaxianObject initializing for %s ...' % ( obj._schema.__name__,)) wx.Frame.__init__(self, parent, -1, Index: PanGalactic/pangalactic/node/gui/widgets/pgxnstatusbar.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnstatusbar.py:1.34 PanGalactic/pangalactic/node/gui/widgets/pgxnstatusbar.py:1.35 --- PanGalactic/pangalactic/node/gui/widgets/pgxnstatusbar.py:1.34 Sat Feb 17 16:11:45 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnstatusbar.py Sat May 12 16:00:45 2007 @@ -1,11 +1,11 @@ -# $Id: pgxnstatusbar.py,v 1.34 2007/02/17 21:11:45 waterbug Exp $ +# $Id: pgxnstatusbar.py,v 1.35 2007/05/12 20:00:45 waterbug Exp $ """ Custom status bar for PanGalaxian (the PGEF desktop client). -@version: $Revision: 1.34 $ +@version: $Revision: 1.35 $ """ -__version__ = "$Revision: 1.34 $"[11:-2] +__version__ = "$Revision: 1.35 $"[11:-2] # Python core modules import logging @@ -33,7 +33,7 @@ self.Bind(wx.EVT_SIZE, self.OnSize) self.Bind(wx.EVT_IDLE, self.OnIdle) self.SetFieldsCount(6) - self.log = logging.getLogger('pgxnstatusbar') + self.log = logging.getLogger('statusbar') # fields: # 0 - help on current menu item (maybe) # 1 - offline or repo status @@ -92,24 +92,24 @@ self.reposition() def onClick(self, evt): - self.log.info("onClick() [status bar 'connect' icon]") + self.log.debug(" - onClick() ['connect' icon]") if state.get('repo'): # self.parent.onLogout(wx.EVT_MENU) - self.log.info(" - dispatching 'logout' message") + self.log.debug(" + dispatching 'logout' message") dispatcher.send(signal='logout', event=None) else: # self.parent.onLogin(wx.EVT_MENU) - self.log.info(" - dispatching 'login' message") + self.log.debug(" + dispatching 'login' message") dispatcher.send(signal='login', event=None) def onStateChange(self): """ Check state and set things accordingly. """ - self.log.info("onStateChange() -- checking state") + self.log.debug(" - onStateChange() -- checking state") if state.get('repo'): - self.log.debug(" - state['repo'] = '%s'" % state['repo']) - self.log.debug(" - logged in") + self.log.debug(" + state['repo'] = '%s'" % state['repo']) + self.log.debug(" + logged in") self.SetStatusText('repo: ' + state['repo'], 1) # self.SetBackgroundColour((100, 255, 0)) self.onbutton.Hide() @@ -121,9 +121,9 @@ self.unlockbitmap.Hide() self.lockbitmap.Show() else: - self.log.debug(" - state.get('repo') = '%s'" % str( + self.log.debug(" + state.get('repo') = '%s'" % str( state.get('repo'))) - self.log.debug(" - logged out") + self.log.debug(" + logged out") self.SetStatusText('offline', 1) # self.SetBackgroundColour((255, 255, 255)) self.onbutton.Show() Index: PanGalactic/pangalactic/node/pangalaxian.py diff -u PanGalactic/pangalactic/node/pangalaxian.py:1.190 PanGalactic/pangalactic/node/pangalaxian.py:1.191 --- PanGalactic/pangalactic/node/pangalaxian.py:1.190 Thu May 10 11:13:49 2007 +++ PanGalactic/pangalactic/node/pangalaxian.py Sat May 12 16:00:45 2007 @@ -2,16 +2,16 @@ # -*- coding: ANSI_X3.4-1968 -*- # generated by wxGlade 0.3.5.1 on Tue Feb 1 00:19:02 2005 -# $Id: pangalaxian.py,v 1.190 2007/05/10 15:13:49 waterbug Exp $ +# $Id: pangalaxian.py,v 1.191 2007/05/12 20:00:45 waterbug Exp $ """ Main application module for PanGalaxian, the PGEF GUI client. WE ARE THE PANGALAXIANS! :) -@version: $Revision: 1.190 $ +@version: $Revision: 1.191 $ """ -__version__ = "$Revision: 1.190 $"[11:-2] +__version__ = "$Revision: 1.191 $"[11:-2] # Python import logging @@ -353,14 +353,15 @@ self.log.info(" - build: %s. version: %s" % (BUILD_DATE, VERSION)) self.log.info(" - wxPython version: %s" % wx.__version__) self.log.info(" - home directory (and current working dir) = %s" % prefs['home']) - self.log.info(" - prefs:") - for p in prefs: - if p != 'imaps' and p != 'pmaps': - self.log.info(" * %s = %s" % (p, prefs[p])) - self.log.info(" - state:") - for s in state: - if s != 'imaps' and s != 'pmaps': - self.log.info(" * %s = %s" % (s, state[s])) + if self.debugmode: + self.log.debug(" - prefs:") + for p in prefs: + if p != 'imaps' and p != 'pmaps': + self.log.debug(" * %s = %s" % (p, prefs[p])) + self.log.debug(" - state:") + for s in state: + if s != 'imaps' and s != 'pmaps': + self.log.debug(" * %s = %s" % (s, state[s])) # start orb logging orb.startLogging() # the "interfaces updated" event needs to be registered before @@ -448,7 +449,8 @@ self.projectwidget = self.contextpanel.projectwidget self.systemwidget = self.contextpanel.systemwidget self.contextwidget = self.contextpanel.contextwidget - # eine kleine nachttesting! + # TODO: "contexts" (incl. projects) are being refactored/enhanced + self.updateProjectWidget() # self.projectwidget.items = [(i,i) for i in ['foo', 'bar']] self.systemwidget.items = [(i,i) for i in ['spam', 'eggs']] self.contextwidget.items = [(i,i) for i in ['garg', 'barg']] @@ -529,7 +531,7 @@ # getObject, getObjectsFromServer, commit, getNamespaces, and # getAcusByAssemblyOid. orb.register(self.refreshView, 'updates received') - orb.register(self.updateProjects, 'update projects') + orb.register(self.updateProjectWidget, 'update projects') def onInterfaceUpdate(self): """ @@ -601,7 +603,7 @@ orb.save(models) orb.save(acus) - def updateProjects(self): + def updateProjectWidget(self): """ Update the project selection widget. """ @@ -761,16 +763,17 @@ PanGalaxian exit process. """ self.log.info(' - onExit()') - self.log.info(" + setting state['repo'] = ''") + self.log.debug(" + setting state['repo'] = ''") state['repo'] = '' - self.log.info(" - prefs:") - for p in prefs: - if p != 'imaps' and p != 'pmaps': - self.log.info(" * %s = %s" % (p, prefs[p])) - self.log.info(" - state:") - for s in state: - if s != 'imaps' and s != 'pmaps': - self.log.info(" * %s = %s" % (s, state[s])) + if self.debugmode: + self.log.debug(" - prefs:") + for p in prefs: + if p != 'imaps' and p != 'pmaps': + self.log.debug(" * %s = %s" % (p, prefs[p])) + self.log.debug(" - state:") + for s in state: + if s != 'imaps' and s != 'pmaps': + self.log.debug(" * %s = %s" % (s, state[s])) self.log.info(' + writing state to %s ...' % os.path.join(prefs['home'], 'state')) writeState(os.path.join(prefs['home'], 'state')) @@ -910,14 +913,15 @@ from one. """ self.log.info(" - onStateChange") - self.log.info(" - prefs:") - for p in prefs: - if p != 'imaps' and p != 'pmaps': - self.log.info(" * %s = %s" % (p, prefs[p])) - self.log.info(" - state:") - for s in state: - if s != 'imaps' and s != 'pmaps': - self.log.info(" * %s = %s" % (s, state[s])) + if self.debugmode: + self.log.debug(" - prefs:") + for p in prefs: + if p != 'imaps' and p != 'pmaps': + self.log.debug(" * %s = %s" % (p, prefs[p])) + self.log.debug(" - state:") + for s in state: + if s != 'imaps' and s != 'pmaps': + self.log.debug(" * %s = %s" % (s, state[s])) if state.get('repo'): self.log.info("*** logged in to repository (non-local mode) ***") orb.getProjectsFromServer() @@ -949,16 +953,14 @@ self.tools_getmystuff.Enable(0) self.tools_passwd.Enable(0) self.log.info("*** not logged in (local mode) ***") - self.onSetProject(None) self.statusbar.onStateChange() - self.contextpanel.onStateChange() - self.treebook.onStateChange() # signal to any interested objects that state has changed ... + # NOTE: currently there are no receivers for this signal # NOTE: this does not force the state to change, it just notifies any # receiver to check state['repo'] -- if it is an empty string, we're in # "local mode" (not talking to a repo); if a non-empty string, we're # "connected to" (authenticated and directing messages to) a repo. - # Note: PanGalaxian has no "session" concept. + # NOTE: PanGalaxian has no "session" concept. dispatcher.send(signal='state changed') self.log.info(' - signal "state changed" dispatched ...') @@ -1027,7 +1029,7 @@ for i in self.selected_projects] self.log.debug(' + new prefs[projects]: %s' % str(prefs['projects'])) - self.updateProjects() + self.updateProjectWidget() else: dlg = wx.MessageDialog(self, "No projects have been created or retrieved yet.", From waterbug at step.nasa.gov Sun May 13 20:41:32 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Sun May 13 20:41:34 2007 Subject: [pangalactic-commits] ObjectCache.deleteObjects seems to work. Message-ID: <200705140041.l4E0fWrH012568@ned.gsfc.nasa.gov> Modified files: PanGalactic/TODO 1.121 1.122 PanGalactic/pangalactic/node/cache.py 1.36 1.37 PanGalactic/pangalactic/node/pangalaxian.py 1.191 1.192 PanGalactic/pangalactic/node/uberorb.py 1.147 1.148 PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py 1.46 1.47 PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py 1.66 1.67 PanGalactic/pangalactic/node/gui/widgets/pgxntree.py 1.12 1.13 PanGalactic/pangalactic/test/test_uberorb.py 1.5 1.6 Log message: ObjectCache.deleteObjects seems to work. - also deprecated orb.getLocalObject in favor of getObject, since getObject does the same thing unless logged in ... - so getLocalObject should only be used if it is important *not* to get the object from the repo even if logged in. Index: PanGalactic/TODO diff -u PanGalactic/TODO:1.121 PanGalactic/TODO:1.122 --- PanGalactic/TODO:1.121 Thu Apr 26 09:41:58 2007 +++ PanGalactic/TODO Sun May 13 20:41:28 2007 @@ -10,6 +10,7 @@ TOP PRIORITIES -------------- [*] BUG: fix namespace collision-checking in PanGalaxianObject + (are we sure it's broken?) [*] ENHANCEMENTS: give PanGalaxianObject some reasonable defaults: [-] creator, owner, modifier = current user [-] cm auth = current project @@ -597,5 +598,5 @@ [+] one-many (aggregate attrs) -------------------------------------------------------------------------- -# $Id: TODO,v 1.121 2007/04/26 13:41:58 waterbug Exp $ +# $Id: TODO,v 1.122 2007/05/14 00:41:28 waterbug Exp $ Index: PanGalactic/pangalactic/test/test_uberorb.py diff -u PanGalactic/pangalactic/test/test_uberorb.py:1.5 PanGalactic/pangalactic/test/test_uberorb.py:1.6 --- PanGalactic/pangalactic/test/test_uberorb.py:1.5 Sat Jan 6 23:39:16 2007 +++ PanGalactic/pangalactic/test/test_uberorb.py Sun May 13 20:41:30 2007 @@ -1,4 +1,4 @@ -# $Id: test_uberorb.py,v 1.5 2007/01/07 04:39:16 waterbug Exp $ +# $Id: test_uberorb.py,v 1.6 2007/05/14 00:41:30 waterbug Exp $ """ Unit tests for pangalactic.node.uberorb @@ -61,18 +61,6 @@ pass test_save.todo = 'not done.' - def test_clearCache(self): - pass - test_clearCache.todo = 'not done.' - - def test_packLocalDB(self): - pass - test_packLocalDB.todo = 'not done.' - - def test_getLocalObjects(self, oid): - pass - test_getLocalObjects.todo = 'not done.' - def test_getObject(self, dict, oid): pass test_getObject.todo = 'not done.' Index: PanGalactic/pangalactic/node/cache.py diff -u PanGalactic/pangalactic/node/cache.py:1.36 PanGalactic/pangalactic/node/cache.py:1.37 --- PanGalactic/pangalactic/node/cache.py:1.36 Sat May 12 16:00:44 2007 +++ PanGalactic/pangalactic/node/cache.py Sun May 13 20:41:28 2007 @@ -1,9 +1,9 @@ """ Local object cache manager (a layer over ZODB) -@version: $Revision: 1.36 $ +@version: $Revision: 1.37 $ """ -__version__ = "$Revision: 1.36 $"[11:-2] +__version__ = "$Revision: 1.37 $"[11:-2] # Python import logging, os, sys @@ -46,7 +46,6 @@ self.dbroot = self.dbconnection.root() if not self.dbroot.get('OidLookup'): self.dbroot['OidLookup'] = PersistentMapping() - self.addInterfaces(interfaces) # create a cache trash self.trashfilename = os.path.join(datadir, "trash.fs") self.trashstorage = FileStorage.FileStorage(self.trashfilename) @@ -55,6 +54,7 @@ self.trashdbroot = self.trashdbconnection.root() if not self.trashdbroot.get('OidLookup'): self.trashdbroot['OidLookup'] = PersistentMapping() + self.addInterfaces(interfaces) # property: objs @@ -76,22 +76,6 @@ trash = property(getTrash, 'trash') - def pack(self): - """ - Remove old entries from and optimize the cache. - """ - self.db.pack() - self.dbtrash.pack() - self.commit() - - def clear(self): - import shutil - shutil.copy("data/pgef.fs", "data/pgef.fs.deleted") - for entry in self.dbroot['OidLookup'].keys(): - del self.dbroot['OidLookup'][entry] - self.commit() - del self.dbroot['OidLookup'] - def commit(self): transaction.get().commit() @@ -111,6 +95,8 @@ self.log.debug(' + %s' % i.__name__) if i.__name__ not in self.dbroot.keys(): self.dbroot[i.__name__] = PersistentMapping() + if i.__name__ not in self.trashdbroot.keys(): + self.trashdbroot[i.__name__] = PersistentMapping() self.interfaces[i.__name__] = i self.commit() @@ -127,7 +113,7 @@ @type objs: list (usually of instances of L{pangalactic.meta.pgefobject.PgefObject} """ - self.log.debug(" - ObjectCache.saveObjects") + self.log.debug(" - saveObjects()") # TODO: 'merge' -- i.e., in case of oid collision, compare # last-modified dates. If the object to be saved has been modified more # recently than the cache copy, replace the cache copy; if both have @@ -152,7 +138,7 @@ @type objs: list (usually of instances of L{pangalactic.meta.pgefobject.PgefObject} """ - self.log.debug(" - ObjectCache.saveObjects") + self.log.debug(" - deleteObjects()") # TODO: 'merge' -- i.e., in case of oid collision, compare # last-modified dates. If the object to be saved has been modified more # recently than the cache copy, replace the cache copy; if both have @@ -160,16 +146,51 @@ if type(objs) is not list: objs = [objs] for obj in objs: + self.log.debug(' + oid: %s' % obj.oid) if hasattr(obj, '_schema'): - del self.dbroot[obj._schema.__name__][obj.oid] + self.log.debug(" * _schema: %s" % obj._schema.__name__) + if self.dbroot[obj._schema.__name__].get(obj.oid): + self.log.debug(" * deleting from dbroot['%s']" + % obj._schema.__name__) + del self.dbroot[obj._schema.__name__][obj.oid] + else: + self.log.debug(" * not found in dbroot['%s']" + % obj._schema.__name__) # delete from dictionaries of parents of the object's _schema for name in [x.__name__ for x in self.interfaces.values() - if (x in allYourBase(obj._schema) - and self.dbroot[name].get(obj.oid))]: - del self.dbroot[name][obj.oid] - del self.objs[obj.oid] + if x in allYourBase(obj._schema)]: + if self.dbroot[name].get(obj.oid): + del self.dbroot[name][obj.oid] + self.log.debug(" * deleting from dbroot['%s']" % name) + else: + self.log.debug(" * not found in dbroot['%s']" % name) + if self.dbroot['OidLookup'].get(obj.oid): + self.log.debug(" * deleting from dbroot['OidLookup']") + del self.dbroot['OidLookup'][obj.oid] + else: + self.log.debug(" * not found in dbroot['OidLookup']") + if self.objs.get(obj.oid): + self.log.debug(" * deleting from cache.objs") + del self.objs[obj.oid] + else: + self.log.debug(" * not found in cache.objs") + # put objects into trash + for obj in objs: + self.trash[obj.oid] = obj + if hasattr(obj, '_schema'): + self.trashdbroot[obj._schema.__name__][obj.oid] = obj + # dictionaries of parents of the object's _schema + for name in [x.__name__ for x in self.interfaces.values() + if x in allYourBase(obj._schema)]: + self.trashdbroot[name][obj.oid] = obj self.commit() + def clear(self): + """ + Delete all objects in the cache. + """ + self.deleteObjects(self.objs.values()) + def _getFilter(self, obj, **kw): """ Return True for an object that matches all attr/values, False @@ -207,6 +228,17 @@ # applications may only have some of the dicts that the cache has return self.dbroot.get(name) + # May revisit pack() later, but probably don't need it for now, and it is a + # very expensive operation. + # + # def pack(self): + # """ + # Remove old entries from and optimize the cache. + # """ + # self.db.pack() + # self.dbtrash.pack() + # self.commit() + # FIXME: Domain-specific stuff (everything from here on) should be in one # or more separate modules Index: PanGalactic/pangalactic/node/pangalaxian.py diff -u PanGalactic/pangalactic/node/pangalaxian.py:1.191 PanGalactic/pangalactic/node/pangalaxian.py:1.192 --- PanGalactic/pangalactic/node/pangalaxian.py:1.191 Sat May 12 16:00:45 2007 +++ PanGalactic/pangalactic/node/pangalaxian.py Sun May 13 20:41:28 2007 @@ -2,16 +2,16 @@ # -*- coding: ANSI_X3.4-1968 -*- # generated by wxGlade 0.3.5.1 on Tue Feb 1 00:19:02 2005 -# $Id: pangalaxian.py,v 1.191 2007/05/12 20:00:45 waterbug Exp $ +# $Id: pangalaxian.py,v 1.192 2007/05/14 00:41:28 waterbug Exp $ """ Main application module for PanGalaxian, the PGEF GUI client. WE ARE THE PANGALAXIANS! :) -@version: $Revision: 1.191 $ +@version: $Revision: 1.192 $ """ -__version__ = "$Revision: 1.191 $"[11:-2] +__version__ = "$Revision: 1.192 $"[11:-2] # Python import logging @@ -308,8 +308,10 @@ readState(os.path.join(home, 'state')) # in case 'home' was omitted from the prefs file prefs['home'] = home - prefs['userid'] = prefs.get('userid', '') - useroid = prefs.get('userid', 'local') + prefs['userid'] = prefs.get('userid', 'localuser') + # TODO: create a temporary user Person object here that can be updated + # later if necessary when logging in to services + useroid = prefs['userid'] # cd to the user-selected home directory os.chdir(prefs['home']) # make sure we have a directory for user ontologies (there also needs to @@ -390,7 +392,6 @@ # onto it until it exits self.hold_passwd = True setOidBase(useroid) - prefs['userid'] = prefs.get('userid', '') state['userid'] = prefs['userid'] passwds = prefs.get('passwds', {}) state['passwd'] = passwds.get('userid', '') @@ -567,14 +568,23 @@ props['id'] = ' '.join([wizard.new_id, '(working version)']) props['version'] = 'working' props['iteration'] = 0 + # TODO: this should be prompted for by the wizard + if state['project'] != 'Any': + props['cm_authority'] = orb.cache.objs[state['project']] else: props['id'] = wizard.new_id props['id_ns'] = wizard.ns - props['oid'] = generateOid(prefs['userid']) # FIXME - props['owner'] = prefs['userid'] - props['creator'] = prefs['userid'] - props['modifier'] = prefs['userid'] dt = dtstamp() + # find user's Person object, or create a placeholder + user = orb.getObject(state['userid']) + if not user: + user = PgefObject(orb.interfaces['Person'], + oid=state['userid']) + orb.save(user) + props['oid'] = generateOid(state['userid']) # FIXME + props['owner'] = user + props['creator'] = user + props['modifier'] = user props['create_datetime'] = dt props['mod_datetime'] = dt new_obj = PgefObject(wizard.iface, **props) @@ -657,8 +667,9 @@ prefs['repo']) state['repo'] = prefs['repo'] # order is very important here: state['repo'] *must* be set - # before onStateChange() is called -- state['repo'] is the - # loggedin/loggedout state indicator! + # before getting the user object and before onStateChange() + # is called -- state['repo'] is the loggedin/loggedout state + # indicator! self.onStateChange() else: self.log.info(' + login failed (no answer).') Index: PanGalactic/pangalactic/node/uberorb.py diff -u PanGalactic/pangalactic/node/uberorb.py:1.147 PanGalactic/pangalactic/node/uberorb.py:1.148 --- PanGalactic/pangalactic/node/uberorb.py:1.147 Sat May 12 16:00:45 2007 +++ PanGalactic/pangalactic/node/uberorb.py Sun May 13 20:41:28 2007 @@ -1,11 +1,11 @@ -# $Id: uberorb.py,v 1.147 2007/05/12 20:00:45 waterbug Exp $ +# $Id: uberorb.py,v 1.148 2007/05/14 00:41:28 waterbug Exp $ # -*- test-case-name: pangalactic.test.test_uberorb -*- """ A PanGalaxian node's UberORB -@version: $Revision: 1.147 $ +@version: $Revision: 1.148 $ """ -__version__ = "$Revision: 1.147 $"[11:-2] +__version__ = "$Revision: 1.148 $"[11:-2] import logging import mimetypes @@ -117,6 +117,41 @@ else: raise ValueError, 'the orb already has a cache.' + # property: cache + + def getCache(self): + return self.__cache + + cache = property(fget=getCache, doc='cache') + + # cache operations + + def getDict(self, name): + """ + Get the {oid : obj} dictionary for the named Interface from the cache + (this is a wrapper for cache.getDict). + """ + d = {} + if getattr(self, 'cache'): + d = self.cache.getDict(name) + else: + self.log.debug(' + no cache -- call orb.initCache() first') + return d + + def save(self, objs): + self.log.debug(' - save()') + if getattr(self, 'cache'): + self.log.debug(' + saving %s objs to cache' % str(len(objs))) + self.cache.saveObjects(objs) + else: + self.log.debug(' + no cache -- call orb.initCache() first') + + def clearCache(self): + if self.cache: + self.cache.clear() + else: + pass + def getAppOntologies(self, home=''): """ Add application ontologies from models/owl to the core ontology. @@ -149,13 +184,6 @@ else: raise ValueError, 'the cache has not been initialized yet.' - # property: cache - - def getCache(self): - return self.__cache - - cache = property(fget=getCache, doc='cache') - def _initXmlrpcInterface(self, hostandport, userid, passwd, secure=True): """ Initialize a server proxy for a host and port. @@ -249,16 +277,6 @@ response = "Not logged in; can't change password" return response - def getDict(self, name): - """ - Get the {oid : obj} dictionary for the named Interface from the cache - (this is a wrapper for cache.getDict). - """ - d = {} - if self.cache: - d = self.cache.getDict(name) - return d - def getUser(self, userid): return self.getObject(userid) @@ -398,19 +416,6 @@ self.log.info(' * no updates found.') return objs - def save(self, objs): - if self.cache: - self.cache.saveObjects(objs) - else: - pass - - def clearCache(self): - if self.cache: - self.cache.clear() - self.cache.pack() - else: - pass - def remember(self, e): """ Marshall (re-member heh ;) a C{PgefObject} from an extract. If no local @@ -484,19 +489,21 @@ def getObject(self, oid): """ - Get an object from the server by oid and save it to the cache. + Get an object, trying the cache first, and if it's not there and we are + logged in to a repository, getting it by oid from the server and saving + it to the cache. @param oid: unique identifier attribute of the object sought @type oid: C{str} """ - self.log.debug(' - getObject') + self.log.debug(' - getObject(%s)' % oid) obj = None if not oid: - pass + self.log.debug(' + no oid -- ignoring request') if self.cache: obj = self.cache.objs.get(oid) if not obj and state.get('repo'): - self.log.debug(' + logged in, checking server') + self.log.debug(' + not in cache; logged in, checking repo') res = self.xmlrpc.getObjectsByOids([oid]) if res: obj = self.remember(res[0]) @@ -504,9 +511,13 @@ obj.repo = state['repo'] self.save(obj) self.log.debug( - ' + object from server is: %s' % repr(obj)) + ' + object from repo is: %s' % repr(obj)) self.log.debug('dispatching signal "updates received"') dispatcher.send(signal='updates received') + elif not obj: + self.log.debug(' + not in cache and no repo, giving up') + else: + self.log.debug(' + initialize cache first!') return obj def getLocalObject(self, oid): @@ -818,7 +829,7 @@ names = self.xmlrpc.getNames(ns) or [] else: self.log.info(" + in local mode -- can't give a good answer.") - names = [] + names = set([o.id for o in self.searchLocalObjects(id_ns=ns)]) return names def getBaseIds(self, ns): @@ -832,7 +843,8 @@ base_ids = self.xmlrpc.getBaseIds(ns) or [] else: self.log.info(" + in local mode -- info may be incomplete ...") - base_ids = [] + base_ids = set([getattr(o, 'base_id', o.id) + for o in self.searchLocalObjects(id_ns=ns)]) return base_ids def getVersionsForBaseId(self, base_id): Index: PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py:1.46 PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py:1.47 --- PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py:1.46 Sun Mar 18 17:20:35 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py Sun May 13 20:41:29 2007 @@ -1,9 +1,9 @@ """ The central widgets of the PanGalaxian main window. -@version: $Revision: 1.46 $ +@version: $Revision: 1.47 $ """ -__version__ = "$Revision: 1.46 $"[11:-2] +__version__ = "$Revision: 1.47 $"[11:-2] import wx @@ -162,7 +162,7 @@ self.trees[oid] = PanGalaxianTree(self, dragndrop=False) self.trees[oid].SetBackgroundColour('WHITE') self.AddPage(self.trees[oid], id) - self.trees[oid].loadTreeForObject(orb.getLocalObject(oid)) + self.trees[oid].loadTreeForObject(orb.getObject(oid)) self.pages[oid] = oid else: # TODO: figure out some rational policy for picking @@ -173,7 +173,7 @@ self.trees[oid] = PanGalaxianTree(self, dragndrop=False) self.trees[oid].SetBackgroundColour('WHITE') self.AddPage(self.trees[oid], id) - self.trees[oid].loadTreeForObject(orb.getLocalObject(oid)) + self.trees[oid].loadTreeForObject(orb.getObject(oid)) self.pages[oid] = oid self.SetSelection(0) Index: PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py:1.66 PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py:1.67 --- PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py:1.66 Sun Mar 18 17:20:35 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py Sun May 13 20:41:29 2007 @@ -1,10 +1,10 @@ -# $Id: pgxnproperty.py,v 1.66 2007/03/18 21:20:35 waterbug Exp $ +# $Id: pgxnproperty.py,v 1.67 2007/05/14 00:41:29 waterbug Exp $ """ PanGalaxianProperty (the Mother of all PanGalaxian Property widgets) -@version: $Revision: 1.66 $ +@version: $Revision: 1.67 $ """ -__version__ = "$Revision: 1.66 $"[11:-2] +__version__ = "$Revision: 1.67 $"[11:-2] import logging from pprint import pprint @@ -130,7 +130,7 @@ label = '[None]' elif isAString(v): # (an oid) # objects may not have been fetched yet ... give it a try - v = orb.getLocalObject(v) or v + v = orb.getObject(v) or v if isAString(v): # I got nothin' label = '[' + self.prop.range + ' -- not available]' @@ -160,7 +160,7 @@ helpwin = wx.TipWindow(self, helptext, 250) else: if isAString(self.value): - obj = orb.getLocalObject(self.value) + obj = orb.getObject(self.value) else: obj = self.value if obj: @@ -794,7 +794,7 @@ # objects have not been fetched yet ... give it a try # print ' - has not been fetched ... trying now ...' for val in v: - v[v.index(val)] = orb.getLocalObject(val) or val + v[v.index(val)] = orb.getObject(val) or val if isAString(v[0]): # I got nothin' # print ' nothing found.' @@ -835,7 +835,7 @@ self.menu = wx.Menu() for v in self.value: if isAString(v): # (oid) - obj = orb.getLocalObject(v) + obj = orb.getObject(v) else: obj = v if obj: Index: PanGalactic/pangalactic/node/gui/widgets/pgxntree.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxntree.py:1.12 PanGalactic/pangalactic/node/gui/widgets/pgxntree.py:1.13 --- PanGalactic/pangalactic/node/gui/widgets/pgxntree.py:1.12 Mon Apr 23 10:18:46 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxntree.py Sun May 13 20:41:29 2007 @@ -1,10 +1,10 @@ -# $Id: pgxntree.py,v 1.12 2007/04/23 14:18:46 waterbug Exp $ +# $Id: pgxntree.py,v 1.13 2007/05/14 00:41:29 waterbug Exp $ """ Base class for PanGalaxian's trees -@version: $Revision: 1.12 $ +@version: $Revision: 1.13 $ """ -__version__ = "$Revision: 1.12 $"[11:-2] +__version__ = "$Revision: 1.13 $"[11:-2] import wx @@ -91,9 +91,9 @@ acu_oids.append(acu_obj.oid) # print ' - acu_oids: ', acu_oids for acu_oid in acu_oids: - acu_obj = orb.getLocalObject(acu_oid) + acu_obj = orb.getObject(acu_oid) if acu_obj: - child = orb.getLocalObject(acu_obj.child) + child = orb.getObject(acu_obj.child) if child: treeid = self.AppendItem(rootnode, child.id) self.SetPyData(treeid, [acu_obj.oid, child.oid]) @@ -121,7 +121,7 @@ # print " - looking for children" treetuple = self.GetPyData(node) # print ' - treetuple:', treetuple - obj = orb.getLocalObject(treetuple[1]) + obj = orb.getObject(treetuple[1]) # print ' - obj:', obj linkedobjs = [] linkedobjs = orb.getAcusByAssemblyOid(obj.oid) From waterbug at step.nasa.gov Mon May 14 02:05:39 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Mon May 14 02:05:41 2007 Subject: [pangalactic-commits] Record bug fix. Message-ID: <200705140605.l4E65dlA013420@ned.gsfc.nasa.gov> Modified files: PanGalactic/TODO 1.122 1.123 Log message: Record bug fix. Index: PanGalactic/TODO diff -u PanGalactic/TODO:1.122 PanGalactic/TODO:1.123 --- PanGalactic/TODO:1.122 Sun May 13 20:41:28 2007 +++ PanGalactic/TODO Mon May 14 02:05:37 2007 @@ -9,10 +9,11 @@ -------------- TOP PRIORITIES -------------- -[*] BUG: fix namespace collision-checking in PanGalaxianObject - (are we sure it's broken?) [*] ENHANCEMENTS: give PanGalaxianObject some reasonable defaults: [-] creator, owner, modifier = current user + note: need to get or create a Person object for current user; if + created locally, it will need to be updated when connected to a + repository or identity service (esp. the latter) [-] cm auth = current project [-] others? [*] ENHANCEMENT: add 'delete from cache' function, accessible from any object @@ -448,6 +449,7 @@ ---- DONE ---- +[+] *** BUG FIXED: namespace collision-checking in PanGalaxianObject [+] ENHANCEMENT: Fix Project handling -- use 'id' property (using oid as handle right now) [+] Finish work on pgxndictcombo.py (will select project oid but show @@ -598,5 +600,5 @@ [+] one-many (aggregate attrs) -------------------------------------------------------------------------- -# $Id: TODO,v 1.122 2007/05/14 00:41:28 waterbug Exp $ +# $Id: TODO,v 1.123 2007/05/14 06:05:37 waterbug Exp $ From waterbug at step.nasa.gov Wed May 16 22:16:26 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Wed May 16 22:16:30 2007 Subject: [pangalactic-commits] Improvements to logging. Message-ID: <200705170216.l4H2GQeV027311@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py 1.47 1.48 PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py 1.67 1.68 Log message: Improvements to logging. Index: PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py:1.47 PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py:1.48 --- PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py:1.47 Sun May 13 20:41:29 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py Wed May 16 22:16:24 2007 @@ -1,14 +1,14 @@ """ The central widgets of the PanGalaxian main window. -@version: $Revision: 1.47 $ +@version: $Revision: 1.48 $ """ -__version__ = "$Revision: 1.47 $"[11:-2] +__version__ = "$Revision: 1.48 $"[11:-2] +import logging import wx from twisted.python.reflect import allYourBase -from pprint import pprint from pangalactic.node.gui.widgets.pgxntree import PanGalaxianTree from pangalactic.node.gui.widgets.pgxnobjectgrid import PanGalaxianObjectGrid from pangalactic.node.uberorb import orb @@ -26,6 +26,7 @@ wx.Panel.__init__(self, parent, -1) minor = wx.SashLayoutWindow(self, -1, wx.DefaultPosition, (200,30), wx.NO_BORDER|wx.SW_3D) + self.log = logging.getLogger('PgxnPanes') minor.SetDefaultSize((220, 600)) minor.SetOrientation(wx.LAYOUT_VERTICAL) minor.SetAlignment(wx.LAYOUT_LEFT) @@ -88,6 +89,7 @@ wx.Choicebook.__init__(self, parent, -1, pos=wx.DefaultPosition, size=wx.Size(250,600)) + self.log = logging.getLogger('PgxnTreeBook') self.master = master self.trees = {} self.pages = {} @@ -117,35 +119,31 @@ """ Handler for the event of state['view'] being set. """ - # print 'PgxnTreeBook.onSetView' + self.log.debug(' - PgxnTreeBook.onSetView') if self.pages: for page in self.pages: id = self.GetSelection() if id < 0: break - # print ' - deleting page:', id + self.log.debug(' + deleting page: %s' % id) self.DeletePage(id) self.pages = {} if not assemblies: - # print ' - no assemblies passed to me -- checking for myself ...' + self.log.debug( + ' + no assemblies passed to me -- checking for myself ...') # no assemblies were passed in, taking matters into my own hands if getattr(self.master, 'objs', None): - # print ' - the notebook has refs to objects:' - # for o in self.master.objs: - # print 'oid: %s (%s)' % (o.oid, o._schema.__name__) models = [x for x in self.master.objs if ((x._schema.__name__ == 'Model') or (orb.interfaces['Model'] in allYourBase(x._schema)))] if models: - print ' - Models found' - # for o in models: - # print 'oid: %s (%s)' % (o.oid, o._schema.__name__) - print ' - now looking for Acus ...' + self.log.debug(' + %s Models found' % len(models)) + self.log.debug(' now looking for assemblies ...') assemblies = [x for x in models if orb.getAcusByAssemblyOid(x.oid)] if not assemblies: - print ' - no assemblies found.' + self.log.debug(' * no assemblies found.') self.pages = {} win = wx.Panel(self) win.SetBackgroundColour('WHITE') @@ -157,7 +155,7 @@ self.pages['default'] = win else: if len(assemblies) == 1: - print ' - 1 assembly found: oid =', assemblies[0].oid + self.log.debug(' * 1 assembly found.') oid, id = assemblies[0].oid, assemblies[0].id self.trees[oid] = PanGalaxianTree(self, dragndrop=False) self.trees[oid].SetBackgroundColour('WHITE') @@ -167,8 +165,7 @@ else: # TODO: figure out some rational policy for picking # default page (for now, page 0 is default) - print ' - multiple assemblies found' - # print ' %s' % str([a.oid for a in assemblies]) + self.log.debug(' * %s assemblies found.' % len(assemblies)) for oid, id in [(o.oid, o.id) for o in assemblies]: self.trees[oid] = PanGalaxianTree(self, dragndrop=False) self.trees[oid].SetBackgroundColour('WHITE') @@ -201,6 +198,7 @@ wx.Notebook.__init__(self, parent, -1, pos=wx.DefaultPosition, size=size) self.parent = parent + self.log = logging.getLogger('PgxnNotebook') self.pages = {} if not objs: self.objs = [] @@ -241,13 +239,13 @@ @type val: C{list} or C{Set} """ # TODO: set a default tab order and make it customizable - # print 'PgxnNotebook.setObjs' + self.log.debug('PgxnNotebook.setObjs') self.__objs = val self.parent.objs = val if self.pages: for page in self.pages: id = self.GetSelection() - # print ' - deleting page:', id + self.log.debug(' - deleting page:', id) self.DeletePage(id) self.pages = {} if val: Index: PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py:1.67 PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py:1.68 --- PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py:1.67 Sun May 13 20:41:29 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py Wed May 16 22:16:24 2007 @@ -1,10 +1,10 @@ -# $Id: pgxnproperty.py,v 1.67 2007/05/14 00:41:29 waterbug Exp $ +# $Id: pgxnproperty.py,v 1.68 2007/05/17 02:16:24 waterbug Exp $ """ PanGalaxianProperty (the Mother of all PanGalaxian Property widgets) -@version: $Revision: 1.67 $ +@version: $Revision: 1.68 $ """ -__version__ = "$Revision: 1.67 $"[11:-2] +__version__ = "$Revision: 1.68 $"[11:-2] import logging from pprint import pprint @@ -61,7 +61,7 @@ @type obj: L{pangalactic.node.gui.widgets.pgxnobject.PanGalaxianObject} """ - self.log = logging.getLogger('PanGalaxianProperty') + self.log = logging.getLogger('pgxnproperty') self.prop = prop self.obj = obj self.link = hl.HyperLinkCtrl( @@ -298,7 +298,7 @@ in length. """ def __init__(self, parent, prop, obj): - self.log = logging.getLogger('PgxnStringFnEdit') + self.log = logging.getLogger('PgxnStrFnEd') PanGalaxianProperty.__init__(self, parent, prop, obj) # initialize widget # TODO: make 'height' (instead of simply 'narrative') a parameter @@ -338,7 +338,7 @@ and is a "narrative" type of property, typically several lines of text. """ def __init__(self, parent, prop, obj): - self.log = logging.getLogger('PgxnStringFnEditNarrative') + self.log = logging.getLogger('PgxnStrFnEdNar') self.parent = parent PanGalaxianProperty.__init__(self, parent, prop, obj) self.__value = getattr(self.obj, prop.id) or '' # in case None From waterbug at step.nasa.gov Thu May 17 01:37:49 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Thu May 17 01:37:50 2007 Subject: [pangalactic-commits] Add a grid "object menu" ... Message-ID: <200705170537.l4H5bneZ027885@ned.gsfc.nasa.gov> Modified files: PanGalactic/NOTES 1.15 1.16 PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py 1.35 1.36 Log message: Add a grid "object menu" ... which will first be used for deleting objects. Index: PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py:1.35 PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py:1.36 --- PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py:1.35 Wed Jan 3 11:18:31 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py Thu May 17 01:37:47 2007 @@ -1,12 +1,13 @@ -# $Id: pgxnobjectgrid.py,v 1.35 2007/01/03 16:18:31 waterbug Exp $ +# $Id: pgxnobjectgrid.py,v 1.36 2007/05/17 05:37:47 waterbug Exp $ """ A table-based, late-bound, configurable object grid -@version: $Revision: 1.35 $ +@version: $Revision: 1.36 $ """ -__version__ = "$Revision: 1.35 $"[11:-2] +__version__ = "$Revision: 1.36 $"[11:-2] from pprint import pprint +import logging import wx import wx.grid as gridlib @@ -206,6 +207,7 @@ @type objs: C{list or Set} """ gridlib.Grid.__init__(self, parent, -1, **kw) + self.log = logging.getLogger('PgxnObjectGrid') # put an icon in the (-1,-1) label position, to be clicked on to # change column configuration cornerwin = self.GetGridCornerLabelWindow() @@ -235,6 +237,7 @@ self.Bind(gridlib.EVT_GRID_LABEL_LEFT_DCLICK, self.sortOnColumn) self.Bind(gridlib.EVT_GRID_LABEL_LEFT_CLICK, self.noSelect) self.Bind(gridlib.EVT_GRID_CELL_LEFT_DCLICK, self.viewObject, self) + self.Bind(gridlib.EVT_GRID_CELL_RIGHT_CLICK, self.popupObjectMenu, self) # properties (for convenience) @@ -319,7 +322,7 @@ # print "No objects -- can't operate on an empty grid." return else: - self.gridPopup(evt) + self.gridPopupMenu(evt) def onColMove(self,evt): """ @@ -330,11 +333,11 @@ self._table.MoveColumn(frm,to) self.reset() - def gridPopup(self, evt): + def gridPopupMenu(self, evt): """ Display the grid popup menu for adding/removing columns. """ - # print '- in PanGalaxianObjectGrid.gridPopup' + self.log.debug(' - gridPopupMenu') self.grid_menu = wx.Menu() self.visible_cols_menu = wx.Menu() self.grid_menu.AppendMenu(-1, 'Visible Columns', @@ -466,6 +469,23 @@ obj = self.getObject(evt.GetRow()) PanGalaxianObject(None, obj).Show() + def popupObjectMenu(self, evt): + """ + View (and edit, if permissions allow) an Object from the grid. + """ + self.log.debug(' - popupObjectMenu') + row = evt.GetRow() + self.object_menu = wx.Menu() + self.delete_object = self.object_menu.Append( + id=wx.ID_ANY, + text="Delete Object", + help="Delete this Object") + epos = evt.GetPosition() + pos = (epos[0] - 80, epos[1] - 30) + self.PopupMenu(self.object_menu, pos) + self.reset() + self.object_menu.Destroy() + ############### # Testing stuff Index: PanGalactic/NOTES diff -u PanGalactic/NOTES:1.15 PanGalactic/NOTES:1.16 --- PanGalactic/NOTES:1.15 Tue May 8 23:50:10 2007 +++ PanGalactic/NOTES Thu May 17 01:37:47 2007 @@ -14,15 +14,16 @@ New names (created by user) must have a namespace -* default namespace is "local" (prefix only; not a valid URL) -* before committing local objs to a repo, user must pick or define a namespace - - can be any namespace to which user has permission to add names - - can be a Project created by the user - - the Project will be checked by the repository for uniqueness of its id - within either its parent namespace (e.g., an organizational namespace) or - within the repository's knowledge of the "world" namespace -* the current namespace serves as default ns for all local user-created objects - +* namespaces + - default local prefix for all user-created objects is "sandbox:" + - when committed to a repo, would go into repo's sandbox under user's id on + the repo unless specifically committed to some other namespace to which the + user has permission to commit. + - to create a top-level Project on a repo requires permission from the repo + admin(s) + + a Project will be checked by the repository for uniqueness of its id + within the repo's projects or within another namespace (e.g., an + organizational namespace) used on that repo, etc. So ... coding: From waterbug at step.nasa.gov Fri May 18 01:11:20 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Fri May 18 01:11:22 2007 Subject: [pangalactic-commits] orb.deleteFromCache() works -- yarrr! :) Message-ID: <200705180511.l4I5BKTZ011819@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/node/cache.py 1.37 1.38 PanGalactic/pangalactic/node/pangalaxian.py 1.192 1.193 PanGalactic/pangalactic/node/uberorb.py 1.148 1.149 PanGalactic/pangalactic/node/gui/dialogs/useradmin.py 1.26 1.27 PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py 1.147 1.148 PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py 1.36 1.37 PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py 1.48 1.49 PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py 1.68 1.69 PanGalactic/pangalactic/utils/io/import_assembly.py 1.5 1.6 Log message: orb.deleteFromCache() works -- yarrr! :) - deletes any Relationships in which the deleted objects are parents or children - right-click on object grid pops up a menu, in which 'delete' is currently the only choice ;) - deletion triggers PanGalaxian's refreshView(), which updates the grid and tree - also did some more improvements to logging ... Index: PanGalactic/pangalactic/node/gui/dialogs/useradmin.py diff -u PanGalactic/pangalactic/node/gui/dialogs/useradmin.py:1.26 PanGalactic/pangalactic/node/gui/dialogs/useradmin.py:1.27 --- PanGalactic/pangalactic/node/gui/dialogs/useradmin.py:1.26 Wed Apr 18 02:19:03 2007 +++ PanGalactic/pangalactic/node/gui/dialogs/useradmin.py Fri May 18 01:11:16 2007 @@ -2,9 +2,9 @@ A dialog to enable the admin user to add, modify, or delete users for a PGER Node. -@version: $Revision: 1.26 $ +@version: $Revision: 1.27 $ """ -__version__ = "$Revision: 1.26 $"[11:-2] +__version__ = "$Revision: 1.27 $"[11:-2] import wx @@ -168,7 +168,7 @@ # with such things as record_create_datetime, etc., filled in project_persons = orb.xmlrpc.addObjects([project_person]) # save the new ProjectPerson to the cache - orb.save([project_persons[0]]) + orb.saveToCache([project_persons[0]]) self.person_projects.items += [project] else: dlg = wx.MessageDialog(self, 'No Project selected!', Index: PanGalactic/pangalactic/node/cache.py diff -u PanGalactic/pangalactic/node/cache.py:1.37 PanGalactic/pangalactic/node/cache.py:1.38 --- PanGalactic/pangalactic/node/cache.py:1.37 Sun May 13 20:41:28 2007 +++ PanGalactic/pangalactic/node/cache.py Fri May 18 01:11:15 2007 @@ -1,9 +1,9 @@ """ Local object cache manager (a layer over ZODB) -@version: $Revision: 1.37 $ +@version: $Revision: 1.38 $ """ -__version__ = "$Revision: 1.37 $"[11:-2] +__version__ = "$Revision: 1.38 $"[11:-2] # Python import logging, os, sys @@ -120,6 +120,7 @@ # been modified, notify user of the conflict. if type(objs) is not list: objs = [objs] + self.log.debug(" + oids: %s" % str([o.oid for o in objs])) for obj in objs: self.objs[obj.oid] = obj if hasattr(obj, '_schema'): @@ -145,6 +146,7 @@ # been modified, notify user of the conflict. if type(objs) is not list: objs = [objs] + self.log.debug(" + oids: %s" % str([o.oid for o in objs])) for obj in objs: self.log.debug(' + oid: %s' % obj.oid) if hasattr(obj, '_schema'): @@ -225,6 +227,10 @@ return objs def getDict(self, name): + """ + Get the cache's dictionary of objects that implement the interface with + the specified name. + """ # applications may only have some of the dicts that the cache has return self.dbroot.get(name) Index: PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py:1.36 PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py:1.37 --- PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py:1.36 Thu May 17 01:37:47 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py Fri May 18 01:11:17 2007 @@ -1,11 +1,12 @@ -# $Id: pgxnobjectgrid.py,v 1.36 2007/05/17 05:37:47 waterbug Exp $ +# $Id: pgxnobjectgrid.py,v 1.37 2007/05/18 05:11:17 waterbug Exp $ """ A table-based, late-bound, configurable object grid -@version: $Revision: 1.36 $ +@version: $Revision: 1.37 $ """ -__version__ = "$Revision: 1.36 $"[11:-2] +__version__ = "$Revision: 1.37 $"[11:-2] +from louie import dispatcher from pprint import pprint import logging @@ -322,7 +323,7 @@ # print "No objects -- can't operate on an empty grid." return else: - self.gridPopupMenu(evt) + self.popupGridMenu(evt) def onColMove(self,evt): """ @@ -333,11 +334,11 @@ self._table.MoveColumn(frm,to) self.reset() - def gridPopupMenu(self, evt): + def popupGridMenu(self, evt): """ Display the grid popup menu for adding/removing columns. """ - self.log.debug(' - gridPopupMenu') + self.log.debug(' - popupGridMenu') self.grid_menu = wx.Menu() self.visible_cols_menu = wx.Menu() self.grid_menu.AppendMenu(-1, 'Visible Columns', @@ -475,17 +476,33 @@ """ self.log.debug(' - popupObjectMenu') row = evt.GetRow() + self.SelectRow(row) self.object_menu = wx.Menu() self.delete_object = self.object_menu.Append( - id=wx.ID_ANY, - text="Delete Object", - help="Delete this Object") + id=wx.ID_ANY, + text="Delete Object", + help="Delete this Object") + self.Bind(wx.EVT_MENU, self.onDeleteObject, self.delete_object) epos = evt.GetPosition() pos = (epos[0] - 80, epos[1] - 30) self.PopupMenu(self.object_menu, pos) self.reset() self.object_menu.Destroy() + def onDeleteObject(self, evt): + """ + Delete the object for which this event was triggered. + """ + self.log.debug(' - onDeleteObject') + obj = self.getObject(self.GetSelectedRows()[0]) + self.log.debug(' + deleting obj with oid %s' % obj.oid) + orb.deleteFromCache([obj]) + # remove that row from the grid + objsnow = list(self.objs) + objsnow.remove(obj) + self.objs = objsnow + dispatcher.send(signal='refresh views') + ############### # Testing stuff Index: PanGalactic/pangalactic/node/uberorb.py diff -u PanGalactic/pangalactic/node/uberorb.py:1.148 PanGalactic/pangalactic/node/uberorb.py:1.149 --- PanGalactic/pangalactic/node/uberorb.py:1.148 Sun May 13 20:41:28 2007 +++ PanGalactic/pangalactic/node/uberorb.py Fri May 18 01:11:16 2007 @@ -1,11 +1,11 @@ -# $Id: uberorb.py,v 1.148 2007/05/14 00:41:28 waterbug Exp $ +# $Id: uberorb.py,v 1.149 2007/05/18 05:11:16 waterbug Exp $ # -*- test-case-name: pangalactic.test.test_uberorb -*- """ A PanGalaxian node's UberORB -@version: $Revision: 1.148 $ +@version: $Revision: 1.149 $ """ -__version__ = "$Revision: 1.148 $"[11:-2] +__version__ = "$Revision: 1.149 $"[11:-2] import logging import mimetypes @@ -138,14 +138,36 @@ self.log.debug(' + no cache -- call orb.initCache() first') return d - def save(self, objs): - self.log.debug(' - save()') + def saveToCache(self, objs): + """ + Save the specified objects to the cache. + """ + self.log.debug(' - saveToCache()') if getattr(self, 'cache'): - self.log.debug(' + saving %s objs to cache' % str(len(objs))) self.cache.saveObjects(objs) else: self.log.debug(' + no cache -- call orb.initCache() first') + def deleteFromCache(self, objs): + """ + Delete the specified objects from the cache. + + @param objs: C{PgefObject} instance(s) in the cache + @type objs: C{list} or C{PgefObject} + """ + self.log.debug(' - deleteFromCache()') + if type(objs) is not list: + objs = [objs] + if getattr(self, 'cache'): + # make sure *all* Relationships in which these objects are the + # parent or child are also deleted + rels = self.cache.getDict('Relationship').values() + objs += [r for r in rels if [o for o in objs if ( + r.parent == o.oid or r.child == o.oid)]] + self.cache.deleteObjects(objs) + else: + self.log.debug(' + no cache -- call orb.initCache() first') + def clearCache(self): if self.cache: self.cache.clear() @@ -180,7 +202,7 @@ if not self.searchLocalObjects(base_id=e['id'], id_ns=e['id_ns']): mos.append(self.createPmofObjectFromExtract(e)) - self.save(mos) + self.saveToCache(mos) else: raise ValueError, 'the cache has not been initialized yet.' @@ -509,7 +531,7 @@ obj = self.remember(res[0]) if obj: obj.repo = state['repo'] - self.save(obj) + self.saveToCache(obj) self.log.debug( ' + object from repo is: %s' % repr(obj)) self.log.debug('dispatching signal "updates received"') @@ -557,7 +579,7 @@ params=params) if res: objs = [self.remember(e) for e in res] - self.save(objs) + self.saveToCache(objs) if objs: self.log.info(' + %s objects retrieved from server' % str( len(objs))) @@ -640,7 +662,7 @@ else: objs = [self.remember(e) for e in data] ret = objs - self.save(objs) + self.saveToCache(objs) return ret # except: # self.log.info(' + exception: xmlrpc error') @@ -773,7 +795,7 @@ self.log.info(""" + not logged in; can't commit.""") else: self.log.info(' + no objects specified.') - self.save(objs) + self.saveToCache(objs) def getProjectsFromServer(self): """ @@ -809,7 +831,7 @@ # params=params) # namespaces = [self.remember(e) for e in nsexts] # if namespaces: -# self.save(namespaces) +# self.saveToCache(namespaces) # self.log.info('dispatching signal "updates received"') # dispatcher.send(signal='updates received') # else: Index: PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py:1.48 PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py:1.49 --- PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py:1.48 Wed May 16 22:16:24 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py Fri May 18 01:11:17 2007 @@ -1,9 +1,9 @@ """ The central widgets of the PanGalaxian main window. -@version: $Revision: 1.48 $ +@version: $Revision: 1.49 $ """ -__version__ = "$Revision: 1.48 $"[11:-2] +__version__ = "$Revision: 1.49 $"[11:-2] import logging @@ -125,7 +125,7 @@ id = self.GetSelection() if id < 0: break - self.log.debug(' + deleting page: %s' % id) + self.log.debug(' + deleting page') self.DeletePage(id) self.pages = {} if not assemblies: @@ -245,7 +245,7 @@ if self.pages: for page in self.pages: id = self.GetSelection() - self.log.debug(' - deleting page:', id) + self.log.debug(' - deleting page') self.DeletePage(id) self.pages = {} if val: Index: PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py:1.68 PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py:1.69 --- PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py:1.68 Wed May 16 22:16:24 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py Fri May 18 01:11:17 2007 @@ -1,10 +1,10 @@ -# $Id: pgxnproperty.py,v 1.68 2007/05/17 02:16:24 waterbug Exp $ +# $Id: pgxnproperty.py,v 1.69 2007/05/18 05:11:17 waterbug Exp $ """ PanGalaxianProperty (the Mother of all PanGalaxian Property widgets) -@version: $Revision: 1.68 $ +@version: $Revision: 1.69 $ """ -__version__ = "$Revision: 1.68 $"[11:-2] +__version__ = "$Revision: 1.69 $"[11:-2] import logging from pprint import pprint @@ -383,7 +383,7 @@ editor.Show(True) if self.value: self.widget.SetLabel(self.genLabel(self.value)) - self.log.debug(' - editor done; value is: %s' % str(self.value)) + self.log.debug(' - value: %s' % str(self.value)) class PgxnDatetimeFnView(PanGalaxianProperty): Index: PanGalactic/pangalactic/utils/io/import_assembly.py diff -u PanGalactic/pangalactic/utils/io/import_assembly.py:1.5 PanGalactic/pangalactic/utils/io/import_assembly.py:1.6 --- PanGalactic/pangalactic/utils/io/import_assembly.py:1.5 Fri May 4 20:51:16 2007 +++ PanGalactic/pangalactic/utils/io/import_assembly.py Fri May 18 01:11:18 2007 @@ -37,6 +37,12 @@ def getAssemblies(f): + """ + Extract assembly structures from a STEP file. + + @param f: name of a STEP file + @type f: C{str} + """ data = readStepFile(f) projid = os.path.basename(f).split('.')[0].upper() projoid = projid Index: PanGalactic/pangalactic/node/pangalaxian.py diff -u PanGalactic/pangalactic/node/pangalaxian.py:1.192 PanGalactic/pangalactic/node/pangalaxian.py:1.193 --- PanGalactic/pangalactic/node/pangalaxian.py:1.192 Sun May 13 20:41:28 2007 +++ PanGalactic/pangalactic/node/pangalaxian.py Fri May 18 01:11:16 2007 @@ -2,16 +2,16 @@ # -*- coding: ANSI_X3.4-1968 -*- # generated by wxGlade 0.3.5.1 on Tue Feb 1 00:19:02 2005 -# $Id: pangalaxian.py,v 1.192 2007/05/14 00:41:28 waterbug Exp $ +# $Id: pangalaxian.py,v 1.193 2007/05/18 05:11:16 waterbug Exp $ """ Main application module for PanGalaxian, the PGEF GUI client. WE ARE THE PANGALAXIANS! :) -@version: $Revision: 1.192 $ +@version: $Revision: 1.193 $ """ -__version__ = "$Revision: 1.192 $"[11:-2] +__version__ = "$Revision: 1.193 $"[11:-2] # Python import logging @@ -524,13 +524,16 @@ orb.register(self.onLogout, 'logout') # to avoid creating loops: # * 'objects saved' should be used *only* for local saves - # * 'updates received' should be used *only* for remote interactions orb.register(self.refreshView, 'objects saved') - # in addition to triggering self.refreshView, - # 'updates received' triggers all PanGalaxianObjects to resync() - # -- it's dispatched by the following UberORB methods: - # getObject, getObjectsFromServer, commit, getNamespaces, and - # getAcusByAssemblyOid. + # * 'refresh views' is used (so far) only by orb.deleteObjectsFromCache + # + it *only* triggers self.refreshView + orb.register(self.refreshView, 'refresh views') + # * 'updates received' should be used *only* for remote interactions + # + in addition to triggering self.refreshView, + # it triggers all PanGalaxianObjects to resync() + # + it's dispatched by the following UberORB methods: + # getObject, getObjectsFromServer, commit, getNamespaces, and + # getAcusByAssemblyOid. orb.register(self.refreshView, 'updates received') orb.register(self.updateProjectWidget, 'update projects') @@ -580,7 +583,7 @@ if not user: user = PgefObject(orb.interfaces['Person'], oid=state['userid']) - orb.save(user) + orb.saveToCache(user) props['oid'] = generateOid(state['userid']) # FIXME props['owner'] = user props['creator'] = user @@ -608,10 +611,11 @@ defaultFile="", style=wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR) if dlg.ShowModal() == wx.ID_OK: paths = dlg.GetPaths() + self.log.debug(' + paths: %s' % str(paths)) project, acus, models = getAssemblies(paths[0]) - orb.save(project) - orb.save(models) - orb.save(acus) + orb.saveToCache(project) + orb.saveToCache(models) + orb.saveToCache(acus) def updateProjectWidget(self): """ Index: PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py:1.147 PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py:1.148 --- PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py:1.147 Sat May 12 16:00:45 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py Fri May 18 01:11:17 2007 @@ -1,10 +1,10 @@ -# $Id: pgxnobject.py,v 1.147 2007/05/12 20:00:45 waterbug Exp $ +# $Id: pgxnobject.py,v 1.148 2007/05/18 05:11:17 waterbug Exp $ """ PanGalaxianObject (a C{PgefObject} viewer/editor) -@version: $Revision: 1.147 $ +@version: $Revision: 1.148 $ """ -__version__ = "$Revision: 1.147 $"[11:-2] +__version__ = "$Revision: 1.148 $"[11:-2] import logging from copy import deepcopy @@ -520,7 +520,7 @@ self.log.debug(' - PGO.onEdit') self.obj.editor = prefs.get('userid') self.editing = True - orb.save([self.obj]) + orb.saveToCache([self.obj]) self.setPropertybookState() self.setToolbarState() @@ -559,7 +559,7 @@ """ self.log.debug(' - PGO.onSaveToCache: saving to cache ...') self.obj.update(**self.view) - orb.save(self.obj) + orb.saveToCache(self.obj) self.notebook.resync() self.resyncVersionPanel() self.setPropertybookState() From waterbug at step.nasa.gov Fri May 18 10:43:17 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Fri May 18 10:43:19 2007 Subject: [pangalactic-commits] Removed overriding grid events from cachebrowser ... Message-ID: <200705181443.l4IEhHbW016448@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/node/gui/widgets/cachebrowser.py 1.32 1.33 PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py 1.37 1.38 Log message: Removed overriding grid events from cachebrowser ... now right-click menu (with delete) works in cachebrowser -- ha! :) Index: PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py:1.37 PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py:1.38 --- PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py:1.37 Fri May 18 01:11:17 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py Fri May 18 10:43:15 2007 @@ -1,10 +1,10 @@ -# $Id: pgxnobjectgrid.py,v 1.37 2007/05/18 05:11:17 waterbug Exp $ +# $Id: pgxnobjectgrid.py,v 1.38 2007/05/18 14:43:15 waterbug Exp $ """ A table-based, late-bound, configurable object grid -@version: $Revision: 1.37 $ +@version: $Revision: 1.38 $ """ -__version__ = "$Revision: 1.37 $"[11:-2] +__version__ = "$Revision: 1.38 $"[11:-2] from louie import dispatcher from pprint import pprint @@ -474,6 +474,9 @@ """ View (and edit, if permissions allow) an Object from the grid. """ + # see also code below, "def OnRightDown", removed from cachebrowser, + # which generated a right-click menu. Some good ideas/techniques in + # there. self.log.debug(' - popupObjectMenu') row = evt.GetRow() self.SelectRow(row) @@ -503,6 +506,38 @@ self.objs = objsnow dispatcher.send(signal='refresh views') + # Code removed from the cachebrowser module -- some of it might be useful + # (it was interfering with popupObjectMenu, above) + # def OnRightDown(self, event): + # """ + # Generate and show the menu for a mouse right-click + # """ + # # print "dbb.onrightdown" + # if self.objs: + # if len(self.objs) == 0: + # return + # else: + # return + # if event.GetId() == self.objectgrid.GetId(): + # menu = wx.Menu() + # x,y = event.GetPosition() + # y1 = y - self.objectgrid.GetColLabelSize() + # curr_row = self.objectgrid.YToRow(y1) + # if curr_row >= 0: + # self.objectgrid.SelectRow(curr_row) + # else: + # return + # obj = self.objs[curr_row] + # options = self.BaseRightClickMenuOptions + # options.extend(self.RightClickMenuOptions) + # for menuid, menulabel in options: + # if menuid == OBJECT_VIEWER: + # if isinstance(obj, PgefObject): + # menu.Append(menuid, menulabel) + # else: + # menu.Append(menuid, menulabel) + # gridx, gridy = self.objectgrid.GetPositionTuple() + # self.PopupMenuXY(menu, x+gridx, y+gridy) ############### # Testing stuff Index: PanGalactic/pangalactic/node/gui/widgets/cachebrowser.py diff -u PanGalactic/pangalactic/node/gui/widgets/cachebrowser.py:1.32 PanGalactic/pangalactic/node/gui/widgets/cachebrowser.py:1.33 --- PanGalactic/pangalactic/node/gui/widgets/cachebrowser.py:1.32 Mon Apr 23 10:18:46 2007 +++ PanGalactic/pangalactic/node/gui/widgets/cachebrowser.py Fri May 18 10:43:15 2007 @@ -1,5 +1,5 @@ #!/bin/env python -# $Id: cachebrowser.py,v 1.32 2007/04/23 14:18:46 waterbug Exp $ +# $Id: cachebrowser.py,v 1.33 2007/05/18 14:43:15 waterbug Exp $ #---------------------------------------------------------------------------- # Authors: Ginny, Steve #---------------------------------------------------------------------------- @@ -7,9 +7,9 @@ PanGalaxian cache browser and display customizer (Works with PgefObjects in a local ZODB) -@version: $Revision: 1.32 $ +@version: $Revision: 1.33 $ """ -__version__ = "$Revision: 1.32 $"[11:-2] +__version__ = "$Revision: 1.33 $"[11:-2] # wxPython import wx @@ -33,10 +33,6 @@ PanGalaxian cache browser (works with PgefObjects in a local ZODB). """ - BaseRightClickMenuOptions = [(OBJECT_VIEWER, "Object Viewer..."), - (ID_POPUP_CLEAR_SELECTION, "Clear Selection")] - RightClickMenuOptions = [] - def __init__(self, parent, pos=wx.DefaultPosition, size=wx.DefaultSize): wx.Panel.__init__(self, parent, -1, pos=pos, size=size, style=wx.THICK_FRAME) @@ -78,19 +74,9 @@ self.Bind(wx.EVT_LISTBOX, self.FillGrid, self.rootitems) self.Bind(wx.EVT_CLOSE, self.OnClose) self.objs = None - grid.EVT_GRID_CELL_RIGHT_CLICK(self.objectgrid, self.OnRightDown) - grid.EVT_GRID_CELL_LEFT_CLICK(self.objectgrid, self.onLeftClick) self.FillChoice() orb.register(self.FillGrid, 'objects saved') - def onLeftClick(self, event): - # print "cachebrowser.leftclick" - if event.GetId() == self.objectgrid.GetId(): - temprow = event.GetRow() - self.objectgrid.SelectRow(temprow) - else: - event.Skip() - def FillChoice(self): choice = self.rootitems choice.Clear() @@ -119,36 +105,6 @@ if self.objdict is not None: self.objectgrid.objs = self.objdict.values() - def OnRightDown(self, event): - """ - Generate and show the menu for a mouse right-click - """ - # print "dbb.onrightdown" - if self.objs: - if len(self.objs) == 0: - return - else: - return - if event.GetId() == self.objectgrid.GetId(): - menu = wx.Menu() - x,y = event.GetPosition() - y1 = y - self.objectgrid.GetColLabelSize() - curr_row = self.objectgrid.YToRow(y1) - if curr_row >= 0: - self.objectgrid.SelectRow(curr_row) - else: - return - obj = self.objs[curr_row] - options = self.BaseRightClickMenuOptions - options.extend(self.RightClickMenuOptions) - for menuid, menulabel in options: - if menuid == OBJECT_VIEWER: - if isinstance(obj, PgefObject): - menu.Append(menuid, menulabel) - else: - menu.Append(menuid, menulabel) - gridx, gridy = self.objectgrid.GetPositionTuple() - self.PopupMenuXY(menu, x+gridx, y+gridy) class TestFrame(wx.Frame): def __init__(self, parent): From waterbug at step.nasa.gov Mon May 21 00:24:50 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Mon May 21 00:24:52 2007 Subject: [pangalactic-commits] Revise docs and roadmap; capture some notes. Message-ID: <200705210424.l4L4Oo9k010278@ned.gsfc.nasa.gov> Modified files: PanGalactic/NOTES 1.16 1.17 PanGalactic/TODO 1.123 1.124 PanGalactic/doc/PgefManual.txt 1.47 1.48 PanGalactic/doc/PgefRoadmap.txt 1.16 1.17 Log message: Revise docs and roadmap; capture some notes. Index: PanGalactic/TODO diff -u PanGalactic/TODO:1.123 PanGalactic/TODO:1.124 --- PanGalactic/TODO:1.123 Mon May 14 02:05:37 2007 +++ PanGalactic/TODO Mon May 21 00:24:47 2007 @@ -10,14 +10,19 @@ TOP PRIORITIES -------------- [*] ENHANCEMENTS: give PanGalaxianObject some reasonable defaults: + [-] new oids: each object will have a local oid in the following default + canonical format: + 'pgef-local:[project id]:[id]' + ... in which the default project-id is "sandbox" [-] creator, owner, modifier = current user note: need to get or create a Person object for current user; if created locally, it will need to be updated when connected to a repository or identity service (esp. the latter) + [-] each user will have an Person object. The user's Person object will + have an associated Role (with credentials, e.g. userid/passwd) for each + service (e.g. repository) known to PanGalaxian. [-] cm auth = current project [-] others? -[*] ENHANCEMENT: add 'delete from cache' function, accessible from any object - grid, by right-click menu [*] ENHANCEMENT: show by background color-coding which objects are local-only (i.e., not saved to any repository) [*] ENHANCEMENT: re-factor registry to use Pmof objects as the canonical @@ -371,13 +376,6 @@ [-] ENHANCEMENT: PanGalaxian Editor (text fields) [-] append a file's contents to the field [-] journal/undo/redo -[-] *** ENHANCEMENT: New userid paradigms ... - [-] each user will have an oid in the form of a URI. The default format of - the URI will be: 'http://pangalactic.us/pgef/Person/[userid]', where - userid is unique within the pgef/Person namespace. This URI will serve - as the oid of their Person object, and the userid string will be their - PanGalactic userid. LDAP connection is TBD -- for NASA, probably by way - of the canonical email address/identifier. [-] easiest method to implement userid/passwd assignment: admin assigns a userid/passwd and notifies the user of them (possibly requiring an immediate change of passwd upon login). @@ -449,6 +447,8 @@ ---- DONE ---- +[+] ENHANCEMENT: add 'delete from cache' function, accessible from any object + grid, by right-click menu [+] *** BUG FIXED: namespace collision-checking in PanGalaxianObject [+] ENHANCEMENT: Fix Project handling -- use 'id' property (using oid as handle right now) @@ -600,5 +600,5 @@ [+] one-many (aggregate attrs) -------------------------------------------------------------------------- -# $Id: TODO,v 1.123 2007/05/14 06:05:37 waterbug Exp $ +# $Id: TODO,v 1.124 2007/05/21 04:24:47 waterbug Exp $ Index: PanGalactic/doc/PgefManual.txt diff -u PanGalactic/doc/PgefManual.txt:1.47 PanGalactic/doc/PgefManual.txt:1.48 --- PanGalactic/doc/PgefManual.txt:1.47 Mon Dec 18 04:10:20 2006 +++ PanGalactic/doc/PgefManual.txt Mon May 21 00:24:48 2007 @@ -7,8 +7,8 @@ :Author: Stephen Waterbury :Author: Ginny Keech -:Version: $Revision: 1.47 $ -:Date: $Date: 2006/12/18 09:10:20 $ +:Version: $Revision: 1.48 $ +:Date: $Date: 2007/05/21 04:24:48 $ .. contents:: Table of Contents @@ -416,14 +416,16 @@ Each **PanGalactic** application object is assigned a unique identifier, the ``oid``. The preferred form for the oid is a URI, if one is available or - can be constructed canonically. Otherwise, an arbitrary (but unique) - one will be generated as follows: + can be constructed canonically. The default canonical form is: :: - [object creator's oid] + [creation time-date stamp] + 'http://[local IP]/pgef/oids/[datetime stamp].[sequence number]' - where the creation time-date stamp is in Universal Time. + where the creation datetime stamp is in Universal Time and is created + by PanGalaxian when it starts up. That datetime stamp is used for all + objects created during a PanGalaxian session, the sequence number being + incremented for each new oid, thus ensuring uniqueness. .. _`Security and Access Control`: @@ -1895,4 +1897,4 @@ .. _Interfaces: http://www.zope.org/Wikis/Interfaces/FrontPage .. _Interface: Interfaces_ -$Id: PgefManual.txt,v 1.47 2006/12/18 09:10:20 waterbug Exp $ +$Id: PgefManual.txt,v 1.48 2007/05/21 04:24:48 waterbug Exp $ Index: PanGalactic/doc/PgefRoadmap.txt diff -u PanGalactic/doc/PgefRoadmap.txt:1.16 PanGalactic/doc/PgefRoadmap.txt:1.17 --- PanGalactic/doc/PgefRoadmap.txt:1.16 Thu Nov 16 15:57:55 2006 +++ PanGalactic/doc/PgefRoadmap.txt Mon May 21 00:24:48 2007 @@ -11,10 +11,10 @@ -------------------- [*] meta-modeling thread: - [-] create MOF ontologies using PanGalaxian (PmofClass, PmofProperty, etc.) + [*] create MOF ontologies using PanGalaxian (PmofClass, PmofProperty, etc.) [-] use MOF ontology to create schema-driven XMI parser(s) [-] use MOF-schema-driven XMI parser to create MEXICO model parser - [-] use MEXICO model parser to parse EXPRESS-XMI STEP AP's + [*] use MEXICO model parser to parse EXPRESS-XMI STEP AP's [-] use resulting STEP AP models to drive Part 21 parser [-] use MOF-schema-driven XMI parser to create UML and SysML parsers/writers @@ -117,5 +117,5 @@ [+] implement build process for Mac platform ----------------------------------------------------------------- -# $Id: PgefRoadmap.txt,v 1.16 2006/11/16 20:57:55 waterbug Exp $ +# $Id: PgefRoadmap.txt,v 1.17 2007/05/21 04:24:48 waterbug Exp $ Index: PanGalactic/NOTES diff -u PanGalactic/NOTES:1.16 PanGalactic/NOTES:1.17 --- PanGalactic/NOTES:1.16 Thu May 17 01:37:47 2007 +++ PanGalactic/NOTES Mon May 21 00:24:47 2007 @@ -15,12 +15,29 @@ New names (created by user) must have a namespace * namespaces - - default local prefix for all user-created objects is "sandbox:" - - when committed to a repo, would go into repo's sandbox under user's id on - the repo unless specifically committed to some other namespace to which the - user has permission to commit. + + - default local prefix for all user-created object ids is: + "pgef-local:[project id]:" + + - "pgef-local" prefix will be used by PanGalaxian to identify local objects + + - when a ns-prefix is selected in the New Object Wizard, they will be shown as + either "local" or "remote" prefixes (remote ones will show the origin + prefix -- whether a repo or other service). + + - when committed to a repo, objects will go into repo's sandbox under user's + id on the repo: + + "http://[repo addr]/vger/sandbox/[userid]/[project id]/objs" + + (a fully-qualified URL) unless specifically committed to some other + namespace (e.g., a Project) to which the user has permission to commit. + (The default VGER config will give users permission to have a sandbox; this + will be configurable by the site admin -- i.e. may be disallowed.) + - to create a top-level Project on a repo requires permission from the repo admin(s) + + a Project will be checked by the repository for uniqueness of its id within the repo's projects or within another namespace (e.g., an organizational namespace) used on that repo, etc. @@ -91,18 +108,44 @@ Semi-random notes: +* Wizards (in general) + + - PanGalaxian's Object creation wizard should dynamically invoke + the appropriate "sub-wizard" if one exists for the selected + Class + + - By prefs and/or app config, add type-specific wizards to the menus + (e.g. Document Wizard, Project Wizard, etc.) + + - For metaobjects, wizards should give the user access to + everything PGER/VGER knows about existing metaobjects + and contexts -- in particular, Classes, Properties, + Ontologies, Taxonomies, Vocabularies, Concept Maps, + etc. should never be created in a vacuum + + + provide access to relevant metaobjects + + also industry standard metadata + + provide capability to create formal mappings + (Express-X / OMG OCL equivalent mappings) + + Taxonomies should be constrained by Ontologies + (classification by Properties is more powerful + than arbitrary instance classification) + * PmofDatatype + - new datatypes can be created and managed. - needs to reference a serialization method - some way to specify presentation/editing (smth. MIME-like?) - also mapped from imported schemas' datatypes * PgefProperty + - implements IProperty and IPgefObject - attrs defined in __slots__, which is constructed from the attrs of PmofProperty * Namespaces (PgefNamespace and PmofNamespace) + - runtime namespaces (PgefNamespace instances) for metaobject (M1 and above) names (i.e., 'pgef' and any application namespaces -- e.g. 'space_mission', etc.) must be distinguishable from those for runtime object (M0) names. @@ -117,6 +160,7 @@ of two or more meta levels (M0, M1, M2, etc.). * Pmof MetaObjects + - created by registry from extracts (createPmofObjectFromExtract) - need methodology for versioning + core objects, PmofClass (Interface) and PmofProperty (PgefProperty) @@ -130,7 +174,10 @@ should probably be a Python property (e.g., for PmofClass, all registered PmofProperties with domain of that PmofClass would populate its 'names' property). - + * specifically: PmofClass should populate its 'names' property with all + PmofProperties that have it or a superclass as their domain (the + corresponding Interface instance does this anyway), etc. + *** ITEM 2 *** -------------------- @@ -238,4 +285,147 @@ - groups of schemas (domain models -- aka schemas) - namespaces +---------------------- +PGEF Components (eggs) +---------------------- + +* probably have to wait for Twisted eggs to do some, but can start now on + architecture +* rename 'pangalactic' package to 'pgef' +* prepare pgef to be a namespace +* release as namespace packages: + - owl2zi (creates zope.interfaces from owl) + - pger (obj repo and cm service, no gui) + - PanGalaxian (gui client w/cache) + - uberorb (twisted services hub) + - pmof (MOF-like, manages models and maps, etc.) + + ontolgies, uml, vocabs, taxonomies, ... +* define APIs between these components + - uberorb hub of everything + - pmof can use pger (ZODB is default -- other backend?) + - etc. + +* Some proposed components (eggs) + - registry/orb + - vger (multi-protocol services hub) + + requires: registry + - pangalaxian (vger client, non-gui, minimal: admin fns) + + requires: registry, vger + - pangalaxian.gui + + requires: registry, vger, pangalaxian + - vger.web (future: web interfaces to vger services) + + requires: registry, vger + - pger (repository + versioning system) + + requires: registry, vger + - maybe import/export functions (?) + + requires: registry + - workflow (future) + + requires: registry, other? + +* [future] "simple components" (orthogonalize?) + - workflow + - schema/ontology design and mapping, data integration + + various file format imports/exports (STEP, etc.) + - rule service (rule engine + event dispatch) + - notification (email, im, amp [general]) + - real-time collaboration (Foolscap) + +--------- +PGEF Apps +--------- + +* include a multi-service (a VGER configuration) and a client + (a PanGalaxian configuration) + +* this type of configuration should be able to use + "standard pgef components", enabling interoperability: + - ontologies + - ontology maps (conversions between data of 2 or more ontologies) + - behaviors (interfaces, API's) + - display maps (typically go with ontologies) + +* PGEF App configuration includes: + - metadata + + ontology + + behaviors (defined by z.i Interfaces) + + display maps (presentation -- similar to Zope "Schema") + - VGER configuration, if any (which services + protocols) + - PanGalaxian configuration (app context and subcontext definitions) + + contexts = definitions of the "views" used by the app + + used by PanGalaxian to define + * up to 4 PanGalaxian app (sub-)context choices (choice widgets) + * menu choices (canned searches, dialogs, etc.) + * tree types (semantics of the tree - what are nodes, etc.) + * tree context choices (may correspond to global context) + * main window + - grids (tab meanings) + - canvases + - notification widgets + + contexts can constrain: + * the set of visible domain Classes and Properties + * display maps (e.g., naming and grouping of Properties) + +* PGEF App Architecture + - simplest component apps are 1 service and 1 view/context + - component apps should be as orthogonal as possible + - distributable as python eggs + +* Some proposed PGEF Apps + - issue tracker ("marvin") + - CM/PDM ("PGPDM") + - knowledge management service ("hermione") + - systems engineer's assistant + - parts engineer's assistant + - project manager's assistant + - structured document editor/assembler + + [extension] collaborative document editor/assembler + - collaborative system modeler + (various kinds/disciplines ... eng/sci/sw/etc.) + +* More notes on apps (see also: ~/sandbox/pangalacticsb/ + + - structured document editor/assembler: + + Create a late-bound wizard that can initialize a document of a + given type, with user name (etc.: prefs), appropriate document + template(s) (MS Word, Powerpoint, etc.), and initial content + (could include boilerplate text, logos, etc.) + + This could also be useful for IMDC / systems engineers, etc. + + Essentially, creating an instance of PGEF Document, with an + MS Word Representation (and possibly others -- e.g., RST, + html, pdf, etc.) + + Also can incorporate data and references from data sources + (databases, web sites, etc.) via wizard links. + + + templates for various document types + * technology evals / whitepapers + * project plans + * other project docs + + easy doc creation + * use template + * fill in only content + * user should not have to do formatting + + version management + + "publishing" + * automated web pub of latest version + * pub/sub notifications on modifications + + system for collab + * comment / markup of doc drafts + * pub/sub for comments / markups + + MS Office templates + + python "harness" (COM interface to docs) + * inject rst content into MS Office template + * doc creation wizard + - creates an instance of a doc type + - guides addition of content + + doc repo with + * webdav interface + * pub/sub notification service + * workflow service + +------------------------------------------------------------- + From waterbug at step.nasa.gov Wed May 23 01:45:53 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Wed May 23 01:45:54 2007 Subject: [pangalactic-commits] More notes. Message-ID: <200705230545.l4N5jrNA006964@ned.gsfc.nasa.gov> Modified files: PanGalactic/NOTES 1.17 1.18 Log message: More notes. Index: PanGalactic/NOTES diff -u PanGalactic/NOTES:1.17 PanGalactic/NOTES:1.18 --- PanGalactic/NOTES:1.17 Mon May 21 00:24:47 2007 +++ PanGalactic/NOTES Wed May 23 01:45:51 2007 @@ -25,15 +25,17 @@ either "local" or "remote" prefixes (remote ones will show the origin prefix -- whether a repo or other service). - - when committed to a repo, objects will go into repo's sandbox under user's - id on the repo: + - when committed to a repo, objects will be assigned to the repo's sandbox + under user's id, which will be the following id namespace: "http://[repo addr]/vger/sandbox/[userid]/[project id]/objs" - (a fully-qualified URL) unless specifically committed to some other - namespace (e.g., a Project) to which the user has permission to commit. - (The default VGER config will give users permission to have a sandbox; this - will be configurable by the site admin -- i.e. may be disallowed.) + (which when combined with their id will give them an oid that is a + fully-qualified URL) unless they are specifically committed to some other + namespace (e.g., a Project) to which the user has permission to commit (in + which case their oid will be *that* ns + their id). (The default VGER + config will give users permission to have a sandbox; this will be + configurable by the site admin -- i.e. may be disallowed.) - to create a top-level Project on a repo requires permission from the repo admin(s) From waterbug at step.nasa.gov Fri May 25 01:55:04 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Fri May 25 01:55:06 2007 Subject: [pangalactic-commits] Usability enhancements for PgxnObject ... Message-ID: <200705250555.l4P5t4Vp009554@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/node/gui/dialogs/pgxneditor.py 1.10 1.11 PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py 1.148 1.149 PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py 1.69 1.70 Log message: Usability enhancements for PgxnObject ... * tab order works now (tabs from button to button in a single notebook page; this should be modified later to cross notebook pages and cycle) * all values are shown in buttons, which display more when pushed * all text fields are edited by way of the pop-up editor - editor's text box receives focus when editor is invoked - ESC key kills editor (without saving, currently, but this will change) - focus returns to parent button when editor is closed, so tabbing can continue - editor can also be invoked by pressing on a button that has focus Index: PanGalactic/pangalactic/node/gui/dialogs/pgxneditor.py diff -u PanGalactic/pangalactic/node/gui/dialogs/pgxneditor.py:1.10 PanGalactic/pangalactic/node/gui/dialogs/pgxneditor.py:1.11 --- PanGalactic/pangalactic/node/gui/dialogs/pgxneditor.py:1.10 Sat Dec 2 15:45:07 2006 +++ PanGalactic/pangalactic/node/gui/dialogs/pgxneditor.py Fri May 25 01:55:01 2007 @@ -3,8 +3,9 @@ PanGalaxian Editor: an editor for PanGalaxian 'narrative' style text fields. """ -import sys -import wx +import logging +import sys +import wx from pangalactic.node import state @@ -22,6 +23,7 @@ @param pgxnprop: the property widget that called us. @type pgxnprop: L{PanGalaxianProperty} """ + self.log = logging.getLogger('pgxneditor') self.pgxnprop = pgxnprop # prop is the PgefProperty instance that the pgxnprop widget holds if pgxnprop: @@ -48,6 +50,7 @@ def bindEventHandlers(self): self.Bind(wx.EVT_CLOSE, self.onCloseWindow) + self.Bind(wx.EVT_KEY_DOWN, self.onKeyDown) def makeToolbar(self, win): sizer = wx.BoxSizer(wx.HORIZONTAL) @@ -104,8 +107,18 @@ self.editwin.SetValue("") def onCloseWindow(self, event): + self.log.debug(' - onCloseWindow') + self.pgxnprop.widget.SetFocus() self.Destroy() + def onKeyDown(self, event): + self.log.debug(' - onKeyDown') + if event.GetKeyCode() == wx.WXK_ESCAPE: + self.pgxnprop.widget.SetFocus() + self.Destroy() + else: + event.Skip() + def onClear(self, event): if self.editwin.GetValue(): if not self.okCancelDialog("Clear: delete all text?", "Clear"): Index: PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py:1.69 PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py:1.70 --- PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py:1.69 Fri May 18 01:11:17 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py Fri May 25 01:55:02 2007 @@ -1,10 +1,10 @@ -# $Id: pgxnproperty.py,v 1.69 2007/05/18 05:11:17 waterbug Exp $ +# $Id: pgxnproperty.py,v 1.70 2007/05/25 05:55:02 waterbug Exp $ """ PanGalaxianProperty (the Mother of all PanGalaxian Property widgets) -@version: $Revision: 1.69 $ +@version: $Revision: 1.70 $ """ -__version__ = "$Revision: 1.69 $"[11:-2] +__version__ = "$Revision: 1.70 $"[11:-2] import logging from pprint import pprint @@ -27,7 +27,7 @@ from pangalactic.utils.toolbox import curry, isAString -class PanGalaxianProperty(object): +class PanGalaxianProperty(wx.Window): """ A widget to display or edit a C{PgefProperty}. C{PanGalaxianProperty} is designed to be embedded within an instance of C{PanGalaxianObject}. @@ -82,7 +82,7 @@ # parent, # label=state['pmaps']['display_names'][prop.id]+':', # size=(200, -1), - # style=wx.NO_BORDER|wx.BU_RIGHT) + # style=wx.BORDER|wx.BU_RIGHT) # self.button.Bind(wx.EVT_BUTTON, self.onHelp, self.button) def onHelp(self, event): @@ -102,7 +102,7 @@ def __init__(self, parent, prop, obj): PanGalaxianProperty.__init__(self, parent, prop, obj) wx.Button.__init__(self, parent, label='', size=(250, -1), - style=wx.NO_BORDER) + style=wx.BORDER) # print ' - PgxnObjectFnView (%s)' % prop.id self._available = False self.Bind(wx.EVT_BUTTON, self._onPush, self) @@ -167,7 +167,7 @@ dispatcher.send('view object', obj=obj, editing=False) -class PgxnStringFnView(PanGalaxianProperty): +class PgxnStringFnView(PanGalaxianProperty, wx.Button): """ PgxnStringFnView is the PanGalaxianProperty view-only subtype for a PgefProperty that has a C{range} of C{'str'} and is Functional @@ -177,77 +177,45 @@ def __init__(self, parent, prop, obj): # print ' - %s: PgxnStringFnView' % prop.id PanGalaxianProperty.__init__(self, parent, prop, obj) + wx.Button.__init__(self, parent, label='', size=(250, -1), + style=wx.BORDER) # initialize widgets - self.maxi_me = _LargeStringView(parent, prop, obj) - self.mini_me = _SmallStringView(parent, prop, obj) - self.widgets = [self.maxi_me, self.mini_me] + self.obj = obj + self.prop = prop self.value = getattr(self.obj, prop.id) + self.Bind(wx.EVT_BUTTON, self._onPush, self) + self.widgets = [self] ###################################################################### # Property: value ###################################################################### def getValue(self): - """ - Get the current value of the Property being viewed or edited. - """ - # print ' - PgxnStringFnView.getValue' return self.__value def setValue(self, v): - """ - Set the value of the Property being viewed or edited. - - @param v: the value to be set - @type v: C{str} - """ - if not v or (len(v) < 32 and not '\n' in v): - self.maxi_me.Hide() - self.mini_me.Show() - else: - self.mini_me.Hide() - self.maxi_me.Show() - for widget in self.widgets: - widget.value = v self.__value = v + self.SetLabel(self.genLabel(v)) - value = property(fget=getValue, fset=setValue, doc='value') - - -class _SmallStringView(wx.TextCtrl): - def __init__(self, parent, prop, obj): - # parent should be a PanGalaxianProperty instance -- so this guy's - # actual parent is it's parent's parent: the PanGalaxianObject - self.obj = obj - self.prop = prop - self.parent = parent - # right, the str() is needed here because of the slight evilness that - # this widget is used to display other simple types, like integers, - # floats, bools, and datetimes ... :P - wx.TextCtrl.__init__(self, parent, - value=str(getattr(obj, prop.id)), - size=(250, -1), - style=wx.TE_PROCESS_TAB|wx.TE_READONLY) - self.SetFont(wx.ITALIC_FONT) - - ###################################################################### - # Property: value - ###################################################################### - - def getValue(self): - """ - Get the current value of the Property being viewed or edited. - """ - # print ' - _SmallStringViewWidget.getValue' - return self.GetValue() + value = property(fget=getValue, + fset=setValue, + doc='value') - def setValue(self, v): + def genLabel(self, v): """ - Set the value of the Property being viewed or edited. + Get a string to put on our button. """ - self.SetValue(str(v)) + label = '[None]' + if v: + sub = v.splitlines()[0][:32] + if len(sub) < len(v): + sub = ' '.join(sub.split(' ')[:-1]) + ' ...' + label = sub + return label - value = property(fget=getValue, fset=setValue, doc='value') + def _onPush(self, event): + viewer = wx.TipWindow(self, str(getattr(self.obj, self.prop.id)), 250) + viewer.Show(True) class _LargeStringView(wx.Button): @@ -258,7 +226,7 @@ self.obj = obj self.prop = prop wx.Button.__init__(self, parent, label='', size=(250, -1), - style=wx.NO_BORDER) + style=wx.BORDER) self.value = str(getattr(obj, prop.id)) self.Bind(wx.EVT_BUTTON, self._onPush, self) @@ -343,7 +311,7 @@ PanGalaxianProperty.__init__(self, parent, prop, obj) self.__value = getattr(self.obj, prop.id) or '' # in case None self.widget = wx.Button(parent, label=self.genLabel(self.__value), - size=(250, -1), style=wx.NO_BORDER) + size=(250, -1), style=wx.BORDER) self.widget.Bind(wx.EVT_BUTTON, self._onEdit, self.widget) self.widgets = [self.widget] @@ -381,6 +349,7 @@ x, y = self.widget.GetPositionTuple() editor = PgxnEditor(self, pos=(x+200, y+300)) editor.Show(True) + editor.editwin.SetFocus() if self.value: self.widget.SetLabel(self.genLabel(self.value)) self.log.debug(' - value: %s' % str(self.value)) @@ -397,7 +366,7 @@ # print ' - %s: PgxnDatetimeFnView' % prop.id PanGalaxianProperty.__init__(self, parent, prop, obj) # initialize widget - self.widget = _SmallStringView(parent, prop, obj) + self.widget = _LargeStringView(parent, prop, obj) self.widgets = [self.widget] self.value = getattr(self.obj, prop.id) @@ -512,7 +481,7 @@ # print ' - %s: PgxnBooleanFnView' % prop.id PanGalaxianProperty.__init__(self, parent, prop, obj) # initialize widget - self.widget = _SmallStringView(parent, prop, obj) + self.widget = _LargeStringView(parent, prop, obj) self.widgets = [self.widget] self.value = bool(getattr(self.obj, prop.id)) @@ -597,7 +566,7 @@ # print ' - %s: PgxnIntegerFnView' % prop.id PanGalaxianProperty.__init__(self, parent, prop, obj) # initialize widget - self.widget = _SmallStringView(parent, prop, obj) + self.widget = _LargeStringView(parent, prop, obj) self.widgets = [self.widget] self.value = getattr(self.obj, prop.id) @@ -682,7 +651,7 @@ # print ' - %s: PgxnFloatFnView' % prop.id PanGalaxianProperty.__init__(self, parent, prop, obj) # initialize widget - self.widget = _SmallStringView(parent, prop, obj) + self.widget = _LargeStringView(parent, prop, obj) self.widgets = [self.widget] self.value = getattr(self.obj, prop.id) @@ -772,7 +741,7 @@ PanGalaxianProperty.__init__(self, parent, prop, obj) self._available = False self.widget = wx.Button(parent, label='', size=(250, -1), - style=wx.NO_BORDER) + style=wx.BORDER) self.widget.Bind(wx.EVT_BUTTON, self._onPush, self.widget) self.widgets = [self.widget] self.value = getattr(self.obj, prop.id) @@ -867,7 +836,7 @@ PanGalaxianProperty.__init__(self, parent, prop, obj) # initialize widget self.widget = wx.Button(parent, label='', size=(250, -1), - style=wx.NO_BORDER) + style=wx.BORDER) # print ' - PgxnStringNonFnView (%s)' % prop.id self.widget.Bind(wx.EVT_BUTTON, self._onPush, self.widget) self.value = getattr(self.obj, self.prop.id) @@ -922,7 +891,7 @@ # TODO: make the edit_widget an EditableListBox. # initialize widget self.widget = wx.Button(parent, label='', size=(250, -1), - style=wx.NO_BORDER) + style=wx.BORDER) # print ' - PgxnDatetimeNonFnView (%s)' % prop.id self.widget.Bind(wx.EVT_BUTTON, self._onPush, self.widget) self.value = getattr(self.obj, self.prop.id) @@ -977,7 +946,7 @@ # non-functional integer type should be an array -- use Numeric types PGXN_WIDGETS = { # Functional (single-valued) - (True, 'edit', 'str', '') : PgxnStringFnEdit, + (True, 'edit', 'str', '') : PgxnStringFnEditNarrative, (True, 'edit', 'str', 'narrative') : PgxnStringFnEditNarrative, (True, 'edit', 'bool', '') : PgxnBooleanFnEdit, (True, 'edit', 'int', '') : PgxnIntegerFnEdit, Index: PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py:1.148 PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py:1.149 --- PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py:1.148 Fri May 18 01:11:17 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py Fri May 25 01:55:01 2007 @@ -1,10 +1,10 @@ -# $Id: pgxnobject.py,v 1.148 2007/05/18 05:11:17 waterbug Exp $ +# $Id: pgxnobject.py,v 1.149 2007/05/25 05:55:01 waterbug Exp $ """ PanGalaxianObject (a C{PgefObject} viewer/editor) -@version: $Revision: 1.148 $ +@version: $Revision: 1.149 $ """ -__version__ = "$Revision: 1.148 $"[11:-2] +__version__ = "$Revision: 1.149 $"[11:-2] import logging from copy import deepcopy @@ -93,7 +93,7 @@ self.log.debug(' - setting up interface map ...') self.interface_map = state['imaps'][self.obj._schema.__name__] self.groups = self.interface_map['groups'] - # self.log.debug(' - interface map: %s' % str(self.interface_map)) + self.log.debug(' - interface map: %s' % str(self.interface_map)) # self.log.debug(' - groups for %s are: %s' % ( # self.obj._schema.__name__, # self.groups)) @@ -287,7 +287,7 @@ """ Initialize PgxnPropertybook for this PanGalaxianObject. """ - # self.log.debug(' - initPropertybook()') + self.log.debug(' - initPropertybook()') working_prop_ids = list(self.obj._schema) # 'main' group is first notebook page main_prop_ids = self.groups['main'] @@ -656,7 +656,7 @@ @ivar parent: the wx object that is the parent of this one. @type parent: a subclass of C{wx.Window} """ - self.log = logging.getLogger('PgxnPropertyBook') + self.log = logging.getLogger('pgxnpropbook') wx.Notebook.__init__(self, parent) self.pobj = pobj self.obj = self.pobj.obj @@ -695,7 +695,7 @@ @param name: name of the page @type name: C{str} """ - # self.log.debug(' - PgxnPropertybook.addPropertyPage()') + self.log.debug(' - addPropertyPage()') win = wx.Window(self, style=wx.CLIP_CHILDREN|wx.FULL_REPAINT_ON_RESIZE) win.panels = {} # NOTE: the order in which the panels are instantiated is important @@ -737,14 +737,14 @@ must be either 'view' or 'edit' @type mode: C{str} """ - # self.log.debug(' - PgxnPropertybook.buildPropertyWidgetsForPage()') + self.log.debug(' - buildPropertyWidgetsForPage()') group = self.pobj.groups[page_name] panel = self.panels[(page_name, mode)] gridsizer = RowColSizer() panel.sizer = gridsizer props = [(a, self.obj._schema[a], getattr(self.obj, a)) for a in group] - # self.log.debug(' - building new widgets for panel: %s (%s)') % ( - # page_name, mode) + self.log.debug(' - building new widgets for panel: %s (%s)' % ( + page_name, mode)) row = 0 linkflags = wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL widgetflags = wx.ALL|wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL @@ -752,11 +752,12 @@ widgetorderro = [] linkorder = [] for a, prop, p_val in props: - # self.log.debug(' * %s' % a) + self.log.debug(' * %s' % a) if getattr(prop, 'read_only', False): m = 'view' else: m = mode + self.log.debug(' - m: %s' % m) pw = PGXN_WIDGETS[(prop.functional, m, prop.range, state['pmaps']['display_styles'].get(prop.id, ''))]( panel, prop, self.pobj.obj) @@ -779,6 +780,9 @@ flag=widgetflags) linkorder.append(pw.link) row += 1 + # self.log.debug(' - linkorder: %s' % str(linkorder)) + # self.log.debug(' - widgetorderro: %s' % str(widgetorderro)) + # self.log.debug(' - widgetorder: %s' % str(widgetorder)) widgetorder = linkorder + widgetorderro + widgetorder for i in xrange(len(widgetorder) - 1): widgetorder[i+1].MoveAfterInTabOrder(widgetorder[i]) From waterbug at step.nasa.gov Fri May 25 02:02:37 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Fri May 25 02:02:39 2007 Subject: [pangalactic-commits] Revise relevant TODO items. Message-ID: <200705250602.l4P62bCw009584@ned.gsfc.nasa.gov> Modified files: PanGalactic/TODO 1.124 1.125 Log message: Revise relevant TODO items. Index: PanGalactic/TODO diff -u PanGalactic/TODO:1.124 PanGalactic/TODO:1.125 --- PanGalactic/TODO:1.124 Mon May 21 00:24:47 2007 +++ PanGalactic/TODO Fri May 25 02:02:35 2007 @@ -42,6 +42,11 @@ (preferably identical, modulo objects vs. files) to Bzr/Subversion: e.g., checkout, update, commit, etc. [*] ENHANCEMENTS: PanGalaxianObject (late-bound viewer/editor) + [-] need to do some cleaning up of PgxnProperty now that text field + viewing/editing widgets have been rationalized: eliminate "style" + (narrative or not), make PgxnProperty subtypes widgets themselves (as + some already are), and rather than having a 'widgets' attribute, the + PgxnProperty instance itself will be referenced [-] dragndrop or menu selection for setting object-valued properties [-] improve datatype support: create a PmofMetaObject for 'Datatype' so that users can define custom types using PMOF. @@ -50,8 +55,6 @@ [*] provide field display/order customization (similar to PgefObjectGrid, but separate) -- including GUI dialogs to define new notebook tabs, which properties go on which notebook page, and the order of the pages -[-] *** BUG: PanGalaxianObject's tab order doesn't work properly -- probably - because some of the datatype "widgets" are not really wx objects [-] ENHANCEMENT: PanGalaxianObject "New Object" dialog's classes should be in alphabetical order [-] *** BUG: PanGalaxianObject's "New Object" dialog can't create instances of @@ -447,6 +450,7 @@ ---- DONE ---- +[-] *** BUG FIXED: PanGalaxianObject's tab order works now [+] ENHANCEMENT: add 'delete from cache' function, accessible from any object grid, by right-click menu [+] *** BUG FIXED: namespace collision-checking in PanGalaxianObject @@ -600,5 +604,5 @@ [+] one-many (aggregate attrs) -------------------------------------------------------------------------- -# $Id: TODO,v 1.124 2007/05/21 04:24:47 waterbug Exp $ +# $Id: TODO,v 1.125 2007/05/25 06:02:35 waterbug Exp $ From waterbug at step.nasa.gov Sat May 26 13:58:24 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Sat May 26 13:58:26 2007 Subject: [pangalactic-commits] Lose all those [None]'s ... Message-ID: <200705261758.l4QHwOB1024500@ned.gsfc.nasa.gov> Modified files: PanGalactic/NOTES 1.18 1.19 PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py 1.70 1.71 Log message: Lose all those [None]'s ... too cluttered; unlabeled buttons are better. Index: PanGalactic/NOTES diff -u PanGalactic/NOTES:1.18 PanGalactic/NOTES:1.19 --- PanGalactic/NOTES:1.18 Wed May 23 01:45:51 2007 +++ PanGalactic/NOTES Sat May 26 13:58:21 2007 @@ -71,7 +71,7 @@ etc.) ** DONE (for OWL) -c. create all runtime metaobjects from Pmof (managed) metaobjects. +b. create all runtime metaobjects from Pmof (managed) metaobjects. Managed Metaobjects and their runtime equivalents: Managed Metaobject Runtime Metaobject @@ -81,13 +81,13 @@ PmofClass Interface (zope.interface) PmofDatatype types (Python built-in, Numpy, Scientific, etc.) -d. the Pmof objects will be cached as extracts but also saved to the +c. the Pmof objects will be cached as extracts but also saved to the repository. They should be fetched from the repository at startup, unless the repository has been re-initialized, in which case the file cache of extracts can be used. The oids for the Pmof objects should be canonicalized as their URI's (which should include version/iteration discriminators). -e. Long term: +d. Long term: (1) every metaobject is uniquely identified by a URI - a PmofClass contains full info about a "node" metaobject + has optional versioning info Index: PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py:1.70 PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py:1.71 --- PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py:1.70 Fri May 25 01:55:02 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py Sat May 26 13:58:22 2007 @@ -1,10 +1,10 @@ -# $Id: pgxnproperty.py,v 1.70 2007/05/25 05:55:02 waterbug Exp $ +# $Id: pgxnproperty.py,v 1.71 2007/05/26 17:58:22 waterbug Exp $ """ PanGalaxianProperty (the Mother of all PanGalaxian Property widgets) -@version: $Revision: 1.70 $ +@version: $Revision: 1.71 $ """ -__version__ = "$Revision: 1.70 $"[11:-2] +__version__ = "$Revision: 1.71 $"[11:-2] import logging from pprint import pprint @@ -127,7 +127,7 @@ """ if not v: # print ' ... (empty)' - label = '[None]' + label = '' elif isAString(v): # (an oid) # objects may not have been fetched yet ... give it a try v = orb.getObject(v) or v @@ -205,7 +205,7 @@ """ Get a string to put on our button. """ - label = '[None]' + label = '' if v: sub = v.splitlines()[0][:32] if len(sub) < len(v): @@ -245,7 +245,7 @@ """ Get a string to put on our button. """ - label = '[None]' + label = '' if v: sub = v.splitlines()[0][:32] if len(sub) < len(v): @@ -334,7 +334,7 @@ """ Generate a label for our button from a value. """ - label = '[None]' + label = '' if v: sub = v.splitlines()[0][:32] if len(sub) < len(v): @@ -853,13 +853,13 @@ def setValue(self, v): if not v: # print ' ... (empty)' - label = '[None]' + label = '[]' else: label = ''.join(['[', state['pmaps']['display_names'][self.prop.id], ']']) self.widget.SetLabel(label) - if label == '[None]': + if label == '[]': self.widget.SetForegroundColour(wx.RED) else: self.widget.SetBackgroundColour(wx.WHITE) @@ -908,13 +908,13 @@ def setValue(self, v): if not v: # print ' ... (empty)' - label = '[None]' + label = '[]' else: label = ''.join(['[', state['pmaps']['display_names'][self.prop.id], ']']) self.widget.SetLabel(label) - if label == '[None]': + if label == '[]': self.widget.SetForegroundColour(wx.RED) else: self.widget.SetBackgroundColour(wx.WHITE) From waterbug at step.nasa.gov Sun May 27 01:27:07 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Sun May 27 01:27:08 2007 Subject: [pangalactic-commits] PgxnObject's buttons should not always be pushable ... Message-ID: <200705270527.l4R5R7av025161@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py 1.71 1.72 Log message: PgxnObject's buttons should not always be pushable ... -- only pushable if the property value does not fit on the button's label. Index: PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py:1.71 PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py:1.72 --- PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py:1.71 Sat May 26 13:58:22 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnproperty.py Sun May 27 01:27:05 2007 @@ -1,10 +1,10 @@ -# $Id: pgxnproperty.py,v 1.71 2007/05/26 17:58:22 waterbug Exp $ +# $Id: pgxnproperty.py,v 1.72 2007/05/27 05:27:05 waterbug Exp $ """ PanGalaxianProperty (the Mother of all PanGalaxian Property widgets) -@version: $Revision: 1.71 $ +@version: $Revision: 1.72 $ """ -__version__ = "$Revision: 1.71 $"[11:-2] +__version__ = "$Revision: 1.72 $"[11:-2] import logging from pprint import pprint @@ -183,7 +183,11 @@ self.obj = obj self.prop = prop self.value = getattr(self.obj, prop.id) - self.Bind(wx.EVT_BUTTON, self._onPush, self) + label, pushable = self.genLabel(self.value) + self.SetLabel(label) + if pushable: + self.SetForegroundColour(wx.BLUE) + self.Bind(wx.EVT_BUTTON, self._onPush, self) self.widgets = [self] ###################################################################### @@ -195,7 +199,6 @@ def setValue(self, v): self.__value = v - self.SetLabel(self.genLabel(v)) value = property(fget=getValue, fset=setValue, @@ -203,15 +206,18 @@ def genLabel(self, v): """ - Get a string to put on our button. + Get a label for our button and decide whether it will be pushable (only + if the label doesn't contain the whole value). """ label = '' + pushable = False if v: sub = v.splitlines()[0][:32] if len(sub) < len(v): - sub = ' '.join(sub.split(' ')[:-1]) + ' ...' + sub = ' '.join(sub.split(' ')[:-1] + ['...']) + pushable = True label = sub - return label + return label, pushable def _onPush(self, event): viewer = wx.TipWindow(self, str(getattr(self.obj, self.prop.id)), 250) From waterbug at step.nasa.gov Mon May 28 02:50:24 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Mon May 28 02:50:26 2007 Subject: [pangalactic-commits] Some changes to grid table; more needed. Message-ID: <200705280650.l4S6oOJj010639@ned.gsfc.nasa.gov> Modified files: PanGalactic/TODO 1.125 1.126 PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py 1.38 1.39 PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py 1.49 1.50 Log message: Some changes to grid table; more needed. Index: PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py:1.49 PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py:1.50 --- PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py:1.49 Fri May 18 01:11:17 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnpanes.py Mon May 28 02:50:22 2007 @@ -1,9 +1,9 @@ """ The central widgets of the PanGalaxian main window. -@version: $Revision: 1.49 $ +@version: $Revision: 1.50 $ """ -__version__ = "$Revision: 1.49 $"[11:-2] +__version__ = "$Revision: 1.50 $"[11:-2] import logging @@ -232,7 +232,8 @@ def setObjs(self, val): """ - Add a page for each object type in val + Make sure there is a grid page for each object type in val, and that it + is populated with all objects of that type in val. @param val: a list or set of instances of L{pangalactic.meta.pgefobject.PgefObject} @@ -240,8 +241,6 @@ """ # TODO: set a default tab order and make it customizable self.log.debug('PgxnNotebook.setObjs') - self.__objs = val - self.parent.objs = val if self.pages: for page in self.pages: id = self.GetSelection() @@ -259,6 +258,8 @@ self._addGridPage(objs) else: self._addDefaultPage() + self.__objs = val + self.parent.objs = val def delObjs(self): raise TypeError, 'objs attribute cannot be deleted' Index: PanGalactic/TODO diff -u PanGalactic/TODO:1.125 PanGalactic/TODO:1.126 --- PanGalactic/TODO:1.125 Fri May 25 02:02:35 2007 +++ PanGalactic/TODO Mon May 28 02:50:21 2007 @@ -9,6 +9,11 @@ -------------- TOP PRIORITIES -------------- +[-] *** BUG: PgxnObjectGrid rebuilds its whole notebook of grids every time its + 'objs' attr is set -- this is very disruptive and unnecessary! (It makes + the interface jump and changes the selected page.) Need to add or delete + pages only as necessary, and only reset a page if objs have been added or + removed from it. [*] ENHANCEMENTS: give PanGalaxianObject some reasonable defaults: [-] new oids: each object will have a local oid in the following default canonical format: @@ -604,5 +609,5 @@ [+] one-many (aggregate attrs) -------------------------------------------------------------------------- -# $Id: TODO,v 1.125 2007/05/25 06:02:35 waterbug Exp $ +# $Id: TODO,v 1.126 2007/05/28 06:50:21 waterbug Exp $ Index: PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py:1.38 PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py:1.39 --- PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py:1.38 Fri May 18 10:43:15 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py Mon May 28 02:50:22 2007 @@ -1,10 +1,10 @@ -# $Id: pgxnobjectgrid.py,v 1.38 2007/05/18 14:43:15 waterbug Exp $ +# $Id: pgxnobjectgrid.py,v 1.39 2007/05/28 06:50:22 waterbug Exp $ """ A table-based, late-bound, configurable object grid -@version: $Revision: 1.38 $ +@version: $Revision: 1.39 $ """ -__version__ = "$Revision: 1.38 $"[11:-2] +__version__ = "$Revision: 1.39 $"[11:-2] from louie import dispatcher from pprint import pprint @@ -257,8 +257,13 @@ return self._table.objs def set_objs(self, val): - self._table.objs = val - self.reset() + """ + Set the C{objs} attr of the underlying table to val if the objects in + val are different from the current set. + """ + if set([o.oid for o in val]) != set([o.oid for o in self._table.objs]): + self.reset() + self._table.objs = val def del_objs(self): raise TypeError, 'objs attribute cannot be deleted.' @@ -293,12 +298,22 @@ def reset(self): """ - Reset the view -- called when the current set of objects and/or the - display_map may have changed. + Reset the grid table's view. This method should only be called when + rows and/or columns have been added or removed from the table. If the + objects in the table are the same but their values may have changed, use + C{update} (less disruptive). """ self._table.setup() self._table.ResetView(self) + def update(self): + """ + Update the grid table's view. Call this method if the objects in the + table are the same but their values may have changed (less disruptive + than C{reset}). + """ + self._table.UpdateValues(self) + def noSelect(self, evt): """ Do not select a column. From waterbug at step.nasa.gov Mon May 28 23:45:23 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Mon May 28 23:45:25 2007 Subject: [pangalactic-commits] Fix bug introduced by change to objectgrid ... Message-ID: <200705290345.l4T3jNmK014584@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/node/uberorb.py 1.149 1.150 PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py 1.39 1.40 Log message: Fix bug introduced by change to objectgrid ... setting of objs attr and reset() of grid were being done in wrong order. Index: PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py:1.39 PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py:1.40 --- PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py:1.39 Mon May 28 02:50:22 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py Mon May 28 23:45:21 2007 @@ -1,10 +1,10 @@ -# $Id: pgxnobjectgrid.py,v 1.39 2007/05/28 06:50:22 waterbug Exp $ +# $Id: pgxnobjectgrid.py,v 1.40 2007/05/29 03:45:21 waterbug Exp $ """ A table-based, late-bound, configurable object grid -@version: $Revision: 1.39 $ +@version: $Revision: 1.40 $ """ -__version__ = "$Revision: 1.39 $"[11:-2] +__version__ = "$Revision: 1.40 $"[11:-2] from louie import dispatcher from pprint import pprint @@ -221,7 +221,6 @@ # table and will destroy it when done. Otherwise we would need to keep # a reference to it and call its Destroy method later. self.SetTable(self._table, True) - self.objs = self._table.objs self.schema = self._table.schema self.AutoSizeColumns(True) self.AutoSizeRows(True) @@ -261,9 +260,8 @@ Set the C{objs} attr of the underlying table to val if the objects in val are different from the current set. """ - if set([o.oid for o in val]) != set([o.oid for o in self._table.objs]): - self.reset() - self._table.objs = val + self._table.objs = val + self.reset() def del_objs(self): raise TypeError, 'objs attribute cannot be deleted.' Index: PanGalactic/pangalactic/node/uberorb.py diff -u PanGalactic/pangalactic/node/uberorb.py:1.149 PanGalactic/pangalactic/node/uberorb.py:1.150 --- PanGalactic/pangalactic/node/uberorb.py:1.149 Fri May 18 01:11:16 2007 +++ PanGalactic/pangalactic/node/uberorb.py Mon May 28 23:45:20 2007 @@ -1,11 +1,11 @@ -# $Id: uberorb.py,v 1.149 2007/05/18 05:11:16 waterbug Exp $ +# $Id: uberorb.py,v 1.150 2007/05/29 03:45:20 waterbug Exp $ # -*- test-case-name: pangalactic.test.test_uberorb -*- """ A PanGalaxian node's UberORB -@version: $Revision: 1.149 $ +@version: $Revision: 1.150 $ """ -__version__ = "$Revision: 1.149 $"[11:-2] +__version__ = "$Revision: 1.150 $"[11:-2] import logging import mimetypes @@ -66,7 +66,7 @@ self.log.info = lambda x: self.log.temp.append(x) self.log.debug = lambda x: self.log.temp.append(x) PanGalacticRegistry.__init__(self, debug=debug) - self.__cache = None + self.cache = None self.xmlrpc = None self.assy_maps = {} # cached maps {assy oid : [acu oids]} @@ -104,25 +104,24 @@ @type home: C{str} """ self.log.info(' - initCache (initializing the object cache)') - if not self.__cache: + if not self.cache: # if prefs['home'] is not set, this will raise (as it should) # note: you *can* hand the cache *all* interfaces, but it might be # confusing to the end-user to see things there that they can't # instantiate. Here, we just give it 'persistables' ... - # self.__cache = ObjectCache(self.interfaces.values(), home=home) ifaces = [self.interfaces[i] for i in self.persistables] self.log.debug(' interfaces: %s' % str(self.persistables)) - self.__cache = ObjectCache(ifaces, home=home) + self.cache = ObjectCache(ifaces, home=home) # self.createDefaultNamespace() else: - raise ValueError, 'the orb already has a cache.' + raise ValueError, 'the cache has already been initialized.' # property: cache - def getCache(self): - return self.__cache + # def getCache(self): + # return self.__cache - cache = property(fget=getCache, doc='cache') + # cache = property(fget=getCache, doc='cache') # cache operations From waterbug at step.nasa.gov Tue May 29 02:10:50 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Tue May 29 02:10:52 2007 Subject: [pangalactic-commits] Beginnings of enforcing local oid uniqueness ... Message-ID: <200705290610.l4T6AnMH015053@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/meta/registry.py 1.174 1.175 PanGalactic/pangalactic/node/uberorb.py 1.150 1.151 Log message: Beginnings of enforcing local oid uniqueness ... just in registry so far -- next: * replace PgefObject() invocations in orb, etc. with orb.makePgefObject() * also, for PgxnObjects: if the oid for a new PgxnObject is the same as the oid of an existing PgxnObject, merely transfer focus to the existing one rather than creating a new one * figure out impacts on remember(), etc. * think about relationship to Cacheable, Referenceable, Copyable, etc. Index: PanGalactic/pangalactic/meta/registry.py diff -u PanGalactic/pangalactic/meta/registry.py:1.174 PanGalactic/pangalactic/meta/registry.py:1.175 --- PanGalactic/pangalactic/meta/registry.py:1.174 Sun May 6 02:24:38 2007 +++ PanGalactic/pangalactic/meta/registry.py Tue May 29 02:10:47 2007 @@ -1,11 +1,11 @@ -# $Id: registry.py,v 1.174 2007/05/06 06:24:38 waterbug Exp $ +# $Id: registry.py,v 1.175 2007/05/29 06:10:47 waterbug Exp $ """ The Pan Galactic Meta Object Registry -@version: $Revision: 1.174 $ +@version: $Revision: 1.175 $ """ -__version__ = "$Revision: 1.174 $"[11:-2] +__version__ = "$Revision: 1.175 $"[11:-2] # Python import glob @@ -72,14 +72,18 @@ that no interface occurs in the C{list} before its bases. @type interface_base_order: C{list} - @ivar properties: A mapping of the names of C{PgefProperty}s known to the - registry to their instances. - @type interfaces: C{dict} - @ivar persistables: The set of names of C{Interface}s for which there are tables in PGER. @type persistables: C{set} + @ivar pgefobjs: A C{dict} that maps oids to instances for all objects + created by L{makePgefObject}. + @type pgefobjs: C{dict} + + @ivar properties: A mapping of the names of C{PgefProperty}s known to the + registry to their instances. + @type interfaces: C{dict} + @ivar refs: A mapping of the names of C{Interface}s to the set of names of C{Interface}s that occur as the range of a C{PgefProperty} of which they are the domain. @@ -117,6 +121,7 @@ self.log.info = lambda x: self.log.info_temp.append(x) self.log.debug = lambda x: self.log.debug_temp.append(x) self.log.info(' - initializing registry logging.') + self.pgefobjs = {} self.sources = {} self.interfaces = {} self.properties = {} @@ -155,6 +160,17 @@ for line in self.tempdebuglog: self.log.debug(line) + def makePgefObject(self, _schema, **kw): + """ + Create a new L{pangalactic.meta.pgefobject.PgefObject} instance or (if + the computed oid exists) return a reference to an existing one. + """ + o = PgefObject(_schema, **kw) + if o.oid in self.pgefobjs: + return self.pgefobjs[o.oid] + else: + return o + def createCoreMetaObjects(self, module='pangalactic.meta.names'): """ Build a dictionary of C{Interface} instances from the @@ -556,7 +572,7 @@ # TODO: this policy should be user-configurable and/or # context-dependent. ns = namespaces[nsprefix] - pgns = PgefObject( + pgns = self.makePgefObject( _schema=self.interfaces['PmofNamespace'], base_id=nsprefix, uri=ns.uri, names=[str(nom) for nom in ns.names], @@ -947,7 +963,7 @@ if kw.get('iteration') is None: kw['iteration'] = 0 kw['security_mask'] = kw.get('security_mask', 0) - pmofobj = PgefObject(_schema, **kw) + pmofobj = self.makePgefObject(_schema, **kw) pmofobj.frozen = True return pmofobj @@ -1227,10 +1243,11 @@ e['_schema_name'] = 'PmofClass' d[cname] = self.createPmofObjectFromExtract(e) ns = namespaces[nsprefix] - d[nsprefix] = PgefObject(_schema=self.interfaces['PmofNamespace'], - base_id=nsprefix, uri=ns.uri, - names=[str(nom) for nom in ns.names], - complete=True) + d[nsprefix] = self.makePgefObject( + _schema=self.interfaces['PmofNamespace'], + base_id=nsprefix, uri=ns.uri, + names=[str(nom) for nom in ns.names], + complete=True) return d registry = PanGalacticRegistry() Index: PanGalactic/pangalactic/node/uberorb.py diff -u PanGalactic/pangalactic/node/uberorb.py:1.150 PanGalactic/pangalactic/node/uberorb.py:1.151 --- PanGalactic/pangalactic/node/uberorb.py:1.150 Mon May 28 23:45:20 2007 +++ PanGalactic/pangalactic/node/uberorb.py Tue May 29 02:10:48 2007 @@ -1,11 +1,11 @@ -# $Id: uberorb.py,v 1.150 2007/05/29 03:45:20 waterbug Exp $ +# $Id: uberorb.py,v 1.151 2007/05/29 06:10:48 waterbug Exp $ # -*- test-case-name: pangalactic.test.test_uberorb -*- """ A PanGalaxian node's UberORB -@version: $Revision: 1.150 $ +@version: $Revision: 1.151 $ """ -__version__ = "$Revision: 1.150 $"[11:-2] +__version__ = "$Revision: 1.151 $"[11:-2] import logging import mimetypes @@ -116,13 +116,6 @@ else: raise ValueError, 'the cache has already been initialized.' - # property: cache - - # def getCache(self): - # return self.__cache - - # cache = property(fget=getCache, doc='cache') - # cache operations def getDict(self, name): From waterbug at step.nasa.gov Wed May 30 01:08:11 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Wed May 30 01:08:13 2007 Subject: [pangalactic-commits] New! Only one PanGalaxianObject per PgefObject! :D Message-ID: <200705300508.l4U58BLw031907@ned.gsfc.nasa.gov> Modified files: PanGalactic/pangalactic/node/uberorb.py 1.151 1.152 PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py 1.149 1.150 PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py 1.40 1.41 Log message: New! Only one PanGalaxianObject per PgefObject! :D At last ... the orb keeps track of all PanGalaxianObjects (orb.pgxnobjs dict) and all PanGalaxianObject spawning functions check with the orb to see if there is already a PanGalaxianObject for the PgefObject in the spawning call ... if there is one, it is raised to the top of the window hierarchy (z-order) and given focus; if not, then a new one is spawned. Index: PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py:1.40 PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py:1.41 --- PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py:1.40 Mon May 28 23:45:21 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnobjectgrid.py Wed May 30 01:08:09 2007 @@ -1,10 +1,10 @@ -# $Id: pgxnobjectgrid.py,v 1.40 2007/05/29 03:45:21 waterbug Exp $ +# $Id: pgxnobjectgrid.py,v 1.41 2007/05/30 05:08:09 waterbug Exp $ """ A table-based, late-bound, configurable object grid -@version: $Revision: 1.40 $ +@version: $Revision: 1.41 $ """ -__version__ = "$Revision: 1.40 $"[11:-2] +__version__ = "$Revision: 1.41 $"[11:-2] from louie import dispatcher from pprint import pprint @@ -481,7 +481,11 @@ """ # print ' - PanGalaxianObjectGrid.viewObject()' obj = self.getObject(evt.GetRow()) - PanGalaxianObject(None, obj).Show() + if obj.oid in orb.pgxnobjs: + orb.pgxnobjs[obj.oid].Raise() + orb.pgxnobjs[obj.oid].SetFocus() + else: + PanGalaxianObject(None, obj).Show() def popupObjectMenu(self, evt): """ Index: PanGalactic/pangalactic/node/uberorb.py diff -u PanGalactic/pangalactic/node/uberorb.py:1.151 PanGalactic/pangalactic/node/uberorb.py:1.152 --- PanGalactic/pangalactic/node/uberorb.py:1.151 Tue May 29 02:10:48 2007 +++ PanGalactic/pangalactic/node/uberorb.py Wed May 30 01:08:08 2007 @@ -1,11 +1,11 @@ -# $Id: uberorb.py,v 1.151 2007/05/29 06:10:48 waterbug Exp $ +# $Id: uberorb.py,v 1.152 2007/05/30 05:08:08 waterbug Exp $ # -*- test-case-name: pangalactic.test.test_uberorb -*- """ A PanGalaxian node's UberORB -@version: $Revision: 1.151 $ +@version: $Revision: 1.152 $ """ -__version__ = "$Revision: 1.151 $"[11:-2] +__version__ = "$Revision: 1.152 $"[11:-2] import logging import mimetypes @@ -21,7 +21,6 @@ # PanGalactic imports from pangalactic.meta.interfaces import IMofFactory -from pangalactic.meta.pgefobject import PgefObject from pangalactic.meta.registry import PanGalacticRegistry from pangalactic.node import state, prefs from pangalactic.node.cache import ObjectCache @@ -32,20 +31,28 @@ class UberORB(PanGalacticRegistry): """ - The UberORB handles all local persistence (i.e., the ObjectCache, a ZODB - service) and all communications with the repository. + The UberORB provides a local metaobject facility, manages all local + persistence (i.e., the ObjectCache, a ZODB service), and mediates all + communications with remote repositories (and in the future, other services). + + IMPORTANT: the UberORB is intended to be a singleton. The module-level + UberORB instance created at the end of this module, 'orb', is what should + normally be imported by PanGalactic components and modules (exceptions: + testing and debugging -- hence the 'debug' parameter). - IMPORTANT: UberORB is intended to be a singleton. The module-level UberORB - instance created at the end of this module, 'orb', is what should normally - be imported by PanGalactic components and modules (exceptions: testing and - debugging -- hence the 'debug' parameter). + @ivar cache: the local object cache (ZODB) + @type cache: L{pangalactic.node.cache.ObjectCache} @ivar interfaces: a C{dict} of C{Interface} objects (inherited from the C{PanGalacticRegistry}) @type interfaces: L{pangalactic.node.cache.ObjectCache} - @ivar cache: an instance of C{ObjectCache} - @type cache: L{pangalactic.node.cache.ObjectCache} + @ivar pgxnobjs: a C{dict} mapping the oids of all C{PgefObject} instances + that have an active C{PanGalaxianObject} instance to that instance + @type pgxnobjs: C{list} + + @ivar xmlrpc: an XML-RPC client interface + @type xmlrpc: L{pangalactic.utils.xmlrpcinterface.XmlrpcInterface} """ implements(IMofFactory) @@ -69,6 +76,9 @@ self.cache = None self.xmlrpc = None self.assy_maps = {} # cached maps {assy oid : [acu oids]} + self.pgxnobjs = {} + self.register(self.addPgxnObj, signal='pgxnobj spawned') + self.register(self.delPgxnObj, signal='pgxnobj killed') def register(self, receiver, signal, **kw): dispatcher.connect(receiver, signal, **kw) @@ -105,10 +115,12 @@ """ self.log.info(' - initCache (initializing the object cache)') if not self.cache: - # if prefs['home'] is not set, this will raise (as it should) - # note: you *can* hand the cache *all* interfaces, but it might be - # confusing to the end-user to see things there that they can't - # instantiate. Here, we just give it 'persistables' ... + # Note: you *can* hand the cache all the interfaces known to the + # orb, but it might be confusing for the end-user to see interfaces + # for which they can't directly create providing instances, so here + # we just use the 'instantiable' ones, a.k.a. 'persistables', which + # are the ones that have corresponding tables in the repository + # (PGER). ifaces = [self.interfaces[i] for i in self.persistables] self.log.debug(' interfaces: %s' % str(self.persistables)) self.cache = ObjectCache(ifaces, home=home) @@ -120,8 +132,8 @@ def getDict(self, name): """ - Get the {oid : obj} dictionary for the named Interface from the cache - (this is a wrapper for cache.getDict). + Get the {oid : obj} dictionary of cache objects that provide the named + Interface (this is a wrapper for cache.getDict). """ d = {} if getattr(self, 'cache'): @@ -198,6 +210,20 @@ else: raise ValueError, 'the cache has not been initialized yet.' + def addPgxnObj(self, pgxnobj=None): + """ + When a C{PanGalaxianObject} has been spawned, add its C{PgefObject}'s + oid to the 'pgxnobjs' dict. + """ + self.pgxnobjs[pgxnobj.obj.oid] = pgxnobj + + def delPgxnObj(self, pgxnobj=None): + """ + When a C{PanGalaxianObject} has been killed, remove its C{PgefObject}'s + oid from the 'pgxnobjs' dict. + """ + del self.pgxnobjs[pgxnobj.obj.oid] + def _initXmlrpcInterface(self, hostandport, userid, passwd, secure=True): """ Initialize a server proxy for a host and port. @@ -454,7 +480,7 @@ if not obj: self.log.debug(' + no cache obj with oid = %s' % e['oid']) self.log.debug(' ... creating a blank obj ...') - obj = PgefObject(_schema=self.interfaces[schema_name]) + obj = self.makePgefObject(_schema=self.interfaces[schema_name]) updates = dict([(a, schema[a].uncook(e.get(a))) for a in schema]) self.log.debug(' + updating object') @@ -481,9 +507,10 @@ schema_name = self.getSchemaIdForEntityName(entity_name) # create objects, using xid's as temp oids (convenient since # they already use them to cross-ref each other) - objs[xid] = PgefObject(_schema=self.interfaces[schema_name], - oid=xid, - **osebdataset['data'][xid]) + objs[xid] = self.makePgefObject( + _schema=self.interfaces[schema_name], + oid=xid, + **osebdataset['data'][xid]) return objs def objects2Oseb(self, objs): Index: PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py:1.149 PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py:1.150 --- PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py:1.149 Fri May 25 01:55:01 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py Wed May 30 01:08:09 2007 @@ -1,10 +1,10 @@ -# $Id: pgxnobject.py,v 1.149 2007/05/25 05:55:01 waterbug Exp $ +# $Id: pgxnobject.py,v 1.150 2007/05/30 05:08:09 waterbug Exp $ """ PanGalaxianObject (a C{PgefObject} viewer/editor) -@version: $Revision: 1.149 $ +@version: $Revision: 1.150 $ """ -__version__ = "$Revision: 1.149 $"[11:-2] +__version__ = "$Revision: 1.150 $"[11:-2] import logging from copy import deepcopy @@ -263,6 +263,7 @@ # register statusbar.onStateChange to receive 'state changed' message orb.register(self.statusbar.onStateChange, 'state changed') orb.register(self.onStateChange, 'state changed') + dispatcher.send(signal='pgxnobj spawned', pgxnobj=self) # TODO: pgxnobject should only be notified if *its* specific object # changes ... so redo these 'updates received' events # orb.register(self.notebook.resync, 'updates received') @@ -501,6 +502,8 @@ if self.closing: event.Skip() else: + # tell the orb to remove this oid from the pgxnobjs set + dispatcher.send(signal='pgxnobj killed', pgxnobj=self) self.closing = True # if self.unsaved: # dlg = wx.MessageDialog(self, @@ -634,8 +637,12 @@ """ Spawn a new instance of PanGalaxianObject. """ - viewer = PanGalaxianObject(None, obj, editing=editing) - viewer.Show() + if obj.oid in orb.pgxnobjs: + orb.pgxnobjs[obj.oid].Raise() + orb.pgxnobjs[obj.oid].SetFocus() + else: + viewer = PanGalaxianObject(None, obj, editing=editing) + viewer.Show() orb.register(spawnPgxnObject, 'view object') From waterbug at step.nasa.gov Thu May 31 02:17:37 2007 From: waterbug at step.nasa.gov (waterbug CVS) Date: Thu May 31 02:17:39 2007 Subject: [pangalactic-commits] Minor fixes + some notes. Message-ID: <200705310617.l4V6HbOS015246@ned.gsfc.nasa.gov> Modified files: PanGalactic/TODO 1.126 1.127 PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py 1.150 1.151 Log message: Minor fixes + some notes. Index: PanGalactic/TODO diff -u PanGalactic/TODO:1.126 PanGalactic/TODO:1.127 --- PanGalactic/TODO:1.126 Mon May 28 02:50:21 2007 +++ PanGalactic/TODO Thu May 31 02:17:34 2007 @@ -13,7 +13,16 @@ 'objs' attr is set -- this is very disruptive and unnecessary! (It makes the interface jump and changes the selected page.) Need to add or delete pages only as necessary, and only reset a page if objs have been added or - removed from it. + removed from it. This needs several separate fixes: + [-] only set the 'objs' attr if there is a change of "context" -- e.g., the + current project is switched + [-] change dispatcher's 'objects saved' message to include an argument + (probably 'objs') that passes the saved objects so that the grid (and + any other subscribers) can make more fine-grained responses -- e.g., the + PgxnObjectGrid can update the specific cells in the pertinent rows (on + specific notebook pages), or add rows as necessary + [-] change dispatcher's 'updates received' message and listeners in the same + way [*] ENHANCEMENTS: give PanGalaxianObject some reasonable defaults: [-] new oids: each object will have a local oid in the following default canonical format: @@ -24,8 +33,8 @@ created locally, it will need to be updated when connected to a repository or identity service (esp. the latter) [-] each user will have an Person object. The user's Person object will - have an associated Role (with credentials, e.g. userid/passwd) for each - service (e.g. repository) known to PanGalaxian. + have an associated Role (Role == 'Avatar' in twisted.cred) with + credentials, e.g. userid/passwd, for each. [-] cm auth = current project [-] others? [*] ENHANCEMENT: show by background color-coding which objects are local-only @@ -609,5 +618,5 @@ [+] one-many (aggregate attrs) -------------------------------------------------------------------------- -# $Id: TODO,v 1.126 2007/05/28 06:50:21 waterbug Exp $ +# $Id: TODO,v 1.127 2007/05/31 06:17:34 waterbug Exp $ Index: PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py diff -u PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py:1.150 PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py:1.151 --- PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py:1.150 Wed May 30 01:08:09 2007 +++ PanGalactic/pangalactic/node/gui/widgets/pgxnobject.py Thu May 31 02:17:35 2007 @@ -1,10 +1,10 @@ -# $Id: pgxnobject.py,v 1.150 2007/05/30 05:08:09 waterbug Exp $ +# $Id: pgxnobject.py,v 1.151 2007/05/31 06:17:35 waterbug Exp $ """ PanGalaxianObject (a C{PgefObject} viewer/editor) -@version: $Revision: 1.150 $ +@version: $Revision: 1.151 $ """ -__version__ = "$Revision: 1.150 $"[11:-2] +__version__ = "$Revision: 1.151 $"[11:-2] import logging from copy import deepcopy @@ -33,7 +33,7 @@ """ A viewer/editor for instances of C{PgefObject}. PanGalaxianObject can be in any one of 14 possible states, which are documented in The PGEF Manual - (PanGalactic/docs/PgefManual.{txt|html}). + (PanGalactic/docs/PgefManual.txt). @ivar groups: a dictionary that maps the names of groups of the object's Properties to lists of Property names @@ -502,18 +502,10 @@ if self.closing: event.Skip() else: + self.onSaveToCache(None) # tell the orb to remove this oid from the pgxnobjs set dispatcher.send(signal='pgxnobj killed', pgxnobj=self) self.closing = True - # if self.unsaved: - # dlg = wx.MessageDialog(self, - # 'Do you want to save your changes?', - # 'PanGalactic Info', - # wx.YES_NO | wx.ICON_INFORMATION) - # dlg.CentreOnParent() - # if dlg.ShowModal() == wx.ID_YES: - # self.onSaveToCache(event) - # dlg.Destroy() self.Close(True) def onEdit(self, event): @@ -523,7 +515,7 @@ self.log.debug(' - PGO.onEdit') self.obj.editor = prefs.get('userid') self.editing = True - orb.saveToCache([self.obj]) + # orb.saveToCache([self.obj]) self.setPropertybookState() self.setToolbarState() @@ -534,27 +526,7 @@ self.log.debug(' - PGO.onView') self.editing = False self.obj.editor = '' - if event: - self.onSaveToCache(event) - # the "typing in widget" event is disabled (triggered by wx.EVT_TEXT, - # etc.) because it is behaving erratically, for whatever reason. A - # simplified approach will be used: if you go into edit mode, the "Save - # to Cache" button will be active, period. - # *** This dialog might be reactivated later based on comparing the - # "view" object (what's in the property widgets) with the object and if - # there are differences, prompting the user. *** - # self.log.debug(' + self.unsaved = %s' % self.unsaved) - # if self.unsaved: - # dlg = wx.MessageDialog(self, - # 'Do you want to save your changes?', - # 'PanGalactic Info', - # wx.YES_NO | wx.ICON_INFORMATION) - # dlg.CentreOnParent() - # if dlg.ShowModal() == wx.ID_YES: - # self.onSaveToCache(event) - # dlg.Destroy() - # else: - # self.log.debug(' - no changes; nothing to save.') + self.onSaveToCache(None) def onSaveToCache(self, event): """