示例#1
0
class Note(items.ContentItem):

    ##
    ## Attribute declarations
    ##

    # ensure that the displayName carries over
    schema.kindInfo(displayName="Note")

    # temporarily make this a real attribute instead of a redirection,
    # because we want don't want to redirect this anywhere
    who = schema.One(schema.String, initialValue="")

    # redirections
    about = schema.One(redirectTo="displayName")

    date = schema.One(redirectTo="createdOn")

    def InitOutgoingAttributes(self):
        """ Init any attributes on ourself that are appropriate for
        a new outgoing item.
        """
        try:
            super(Note, self).InitOutgoingAttributes()
        except AttributeError:
            pass

        self.processingStatus = 'processing'

    def getAnyAbout(self):
        """
        Get any non-empty definition for the "about" attribute.
        """
        return self.displayName

    def getAnyDate(self):
        """
        Get any non-empty definition for the "date" attribute.
        """
        return self.createdOn

    def getAnyWho(self):
        """
        Get any non-empty definition for the "who" attribute.
        """
        raise AttributeError

    def getAnyWhoFrom(self):
        """
        Get any non-empty definition for the "whoFrom" attribute.
        """
        return self.creator

    def ExportItemData(self, clipboardHandler):
        # Create data for this kind of item in the clipboard handler
        # The data is used for Drag and Drop or Cut and Paste
        super(Note, self).ExportItemData(clipboardHandler)

        # Let the clipboard handler know we've got a Note to export
        clipboardHandler.ExportItemFormat(self, 'Note')
示例#2
0
class Calendar(ContentItem):
    """
    @note: Calendar should have an attribute that points to all the Calendar Events.
    @note: Calendar should maybe have a 'Timezone' attribute.
    """

    schema.kindInfo(displayName="Calendar", displayAttribute="displayName")
示例#3
0
class Project(ContentItem):

    schema.kindInfo(
        displayName="Project",
        examples=[
            'my "Housewarming Party" project',
            "my department's \"Move to new building\" project",
            "my company's \"Open Seattle Store\" project",
        ],
        description=
        "Users can create projects to help organize their work. Users can "
        "take content items (like tasks and mail messages) and assign "
        "them to different projects.")

    parentProject = schema.One(
        'Project',
        displayName='Parent Project',
        doc=
        'Projects can be organized into hierarchies. Each project can have one parent.',
        inverse='subProjects',
    )
    subProjects = schema.Sequence(
        'Project',
        displayName='Sub Projects',
        doc=
        'Projects can be organized into hierarchies. Each project can have many sub-projects.',
        inverse='parentProject',
    )
示例#4
0
class AmazonCollection(ItemCollection):

    schema.kindInfo(displayName="Amazon Collection Kind")

    keywords = schema.One(schema.String, displayName='Keywords')

    myKindID = None
    myKindPath = "//parcels/osaf/examples/amazon/schema/AmazonCollection"

    def __init__(self,
                 keywords=None,
                 email=None,
                 name=None,
                 parent=None,
                 kind=None,
                 view=None):
        super(AmazonCollection, self).__init__(name, parent, kind, view)
        if keywords:
            bags = amazon.searchByKeyword(keywords)
            self.displayName = 'Amzn: ' + keywords
        elif email:
            results = amazon.searchWishListByEmail(email)
            customerName = results[0]
            bags = results[1]
            self.displayName = 'Amzn: ' + customerName
        else:
            bags = {}
        for aBag in bags:
            self.add(AmazonItem(aBag, view=view))
示例#5
0
class StampBranchSubtree(BranchSubtree):
    """
    A mapping between an Item and the list of top-level blocks ('rootBlocks')
    that should appear when an Item inheriting from that Kind is displayed.
    Each rootBlock entry should have its 'position' attribute specified, to
    enable it to be sorted with other root blocks.)
    """
    schema.kindInfo(annotates=schema.Item)
示例#6
0
class Location(ContentItem):
    """
       @note: Location may not be calendar specific.
    """

    schema.kindInfo(displayName="Location", displayAttribute="displayName")

    eventsAtLocation = schema.Sequence(CalendarEventMixin,
                                       displayName="Calendar Events",
                                       inverse=CalendarEventMixin.location)

    def __str__(self):
        """
          User readable string version of this Location
        """
        if self.isStale():
            return super(Location, self).__str__()
            # Stale items can't access their attributes
        return self.getItemDisplayName()

    def getLocation(cls, view, locationName):
        """
          Factory Method for getting a Location.

          Lookup or create a Location based on the supplied name string.
        If a matching Location object is found in the repository, it
        is returned.  If there is no match, then a new item is created
        and returned.  
        @param locationName: name of the Location
        @type locationName: C{String}
        @return: C{Location} created or found
        """
        # make sure the locationName looks reasonable
        assert locationName, "Invalid locationName passed to getLocation factory"

        # get all Location objects whose displayName match the param
        its = Location.iterItems(view, exact=True)
        locQuery = [i for i in its if i.displayName == locationName]

        ##         locQuery = view.findPath('//Queries/calendarLocationQuery')
        ##         if locQuery is None:
        ##             queryString = u'for i in "//parcels/osaf/pim/calendar/Location" \
        ##                       where i.displayName == $0'
        ##             p = view.findPath('//Queries')
        ##             k = view.findPath('//Schema/Core/Query')
        ##             locQuery = Query.Query ('calendarLocationQuery', p, k, queryString)
        ##         locQuery.args["$0"] = ( locationName, )

        # return the first match found, if any
        for firstSpot in locQuery:
            return firstSpot

        # make a new Location
        newLocation = Location(view=view)
        newLocation.displayName = locationName
        return newLocation

    getLocation = classmethod(getLocation)
示例#7
0
class EventTask(
    tasks.TaskMixin,
    tasks.TaskEventExtraMixin,
    calendar.Calendar.CalendarEvent
):
    schema.kindInfo(
        displayName = "Event Task",
        description = "A Task stamped as an Event, or vica versa",
    )
示例#8
0
class TimeTransparencyEnum(schema.Enumeration):
    """Time Transparency Enum

    The iCalendar values for Time Transparency are slightly different. We should consider making our values match the iCalendar ones, or be a superset of them.  Mitch suggested that a 'cancelled' value would be a useful extension.

    It'd be nice to not maintain the transparency choices separately from the enum values"""

    schema.kindInfo(displayName="Time Transparency")
    values = "confirmed", "tentative", "fyi"
示例#9
0
class Group(ContentItem):

    schema.kindInfo(
        description=
        "See http://wiki.osafoundation.org/twiki/bin/view/Jungle/CollectionProject\n\n"
        "Issues:\n"
        '   We still need to work out some issues about how '
        '"playlists"/"item collections" are modeled.\n'
        '   We need to find a name for these things.\n')
示例#10
0
class ContentKind(Kind):
    """This kind is a metakind for creating other kinds.  Kinds which are
    an instance of ContentKind will have an attribute 'detailView' of type
    Block.  We could also make this attribute a bidiref."""

    __metaclass__ = schema.ItemClass

    schema.kindInfo(displayName="Metakind 'Content Kind'")

    detailView = schema.One()  # Block
示例#11
0
class MailedEventTask(
    tasks.TaskMixin,
    tasks.TaskEventExtraMixin,
    calendar.Calendar.CalendarEventMixin,
    mail.MailMessage
):
    schema.kindInfo(
        displayName = "Mailed Event Task",
        description = "A Task stamped as an Event stamped as Mail, in any sequence",
    )
示例#12
0
class Script(pim.ContentItem):
    """ Persistent Script Item, to be executed. """
    schema.kindInfo(displayName="Script", displayAttribute="displayName")

    def __init__(self, name=_('untitled'), parent=None, kind=None):
        super(Script, self).__init__(name, parent, kind, displayName=name)

    def execute(self):
        executable = ExecutableScript(self.bodyString, self.itsView)
        executable.execute()
示例#13
0
class CalendarEvent(CalendarEventMixin, Note):
    """
    @note: CalendarEvent should maybe have a 'Timezone' attribute.
    @note: Do we want to have 'Duration' as a derived attribute on Calendar Event?
    @note: Do we want to have a Boolean 'AllDay' attribute, to indicate that an event is an all day event? Or should we instead have the 'startTime' and 'endTime' attributes be 'RelativeDateTime' instead of 'DateTime', so that they can store all day values like '14 June 2004' as well as specific time values like '4:05pm 14 June 2004'?
    """
    schema.kindInfo(displayName="Calendar Event")

    def __init__(self, name=None, parent=None, kind=None, view=None, **kw):
        kw.setdefault('participants', [])
        super(CalendarEvent, self).__init__(name, parent, kind, view, **kw)
示例#14
0
class Group(ContentItem):

    schema.kindInfo(
        displayName='"Playlist"/"Item Collection"',
        description=
        "See http://wiki.osafoundation.org/twiki/bin/view/Jungle/CollectionProject",
        issues=[
            'We still need to work out some issues about how '
            '"playlists"/"item collections" are modeled.',
            'We need to find a name for these things.',
        ])
示例#15
0
class Task(TaskMixin, notes.Note):

    schema.kindInfo(
        displayName = "Task",
        issues = [
            "Do we want to support the idea of tasks having sub-tasks? If so, "
            "then we need to add attributes for 'superTask' and 'subTasks'.",
            
            "Task should maybe have a 'Timezone' attribute.",
        ]
    )
示例#16
0
class String(schema.Item):

    schema.kindInfo(displayName="Container for string attribute tests")

    uString = schema.One(schema.UString)

    bString = schema.One(schema.BString)

    localizableString = schema.One(schema.LocalizableString)

    text = schema.One(schema.Text)
示例#17
0
class UserCollection(schema.Annotation):
    schema.kindInfo(annotates=ContentCollection)

    renameable = schema.One(schema.Boolean, defaultValue=True)
    color = schema.One(ColorType)
    iconName = schema.One(schema.Text, defaultValue="")
    colorizeIcon = schema.One(schema.Boolean, defaultValue=True)
    dontDisplayAsCalendar = schema.One(schema.Boolean, defaultValue=False)
    outOfTheBoxCollection = schema.One(schema.Boolean, defaultValue=False)
    canAdd = schema.One(schema.Boolean, defaultValue=True)
    allowOverlay = schema.One(schema.Boolean, defaultValue=True)
    searchMatches = schema.One(schema.Integer, defaultValue=0)
    checked = schema.One(schema.Boolean, defaultValue=False)
    """
      preferredClass is used as a hint to the user-interface to choose the right
      view for the display, e.g. CalendarView for collections that have a
      preferredClass of EventStamp.
    """
    preferredClass = schema.One(schema.Class)

    schema.addClouds(copying=schema.Cloud(byRef=[preferredClass]), )

    def ensureColor(self):
        """
        Make sure the collection has a color. Pick up the next color in a predefined 
        list if none was set.
        """
        if not hasattr(self, 'color'):
            self.color = schema.ns(
                'osaf.usercollections',
                self.itsItem.itsView).collectionColors.nextColor()
        return self

    def setColor(self, colorname):
        """
        Set the collection color by name. Raises an error if colorname doesn't exist.
        """
        hue = None
        for colname, coltitle, colhue in collectionHues:
            if colname == colorname:
                hue = colhue
                break
        if hue is None:
            raise ValueError("Unknown color name")
        rgb = colorsys.hsv_to_rgb(hue / 360.0, 0.5, 1.0)
        self.color = ColorType(int(rgb[0] * 255), int(rgb[1] * 255),
                               int(rgb[2] * 255), 255)

    def setValues(self, **kwds):

        for attr, value in kwds.iteritems():
            setattr(self, attr, value)
示例#18
0
class TaskEventExtraMixin(items.ContentItem):
    """
      Task Event Extra Mixin is the bag of attributes that
    appears when you have an Item that is both a Task and a
    CalendarEvent.
    We only instantiate these Items when we "unstamp" an
    Item, to save the attributes for later "restamping".
    """

    schema.kindInfo(
        displayName = "Task Event Extra Mixin Kind",
        description =
            "The attributes specific to an item that is both a task and an "
            "event.  This is additional 'due by' information. "
    )

    dueByDate = schema.One(
        schema.DateTime,
        displayName = 'Due by Date',
        doc = 'The date when a Task Event is due.',
    )
    dueByRecurrence = schema.Sequence(
        'osaf.pim.calendar.Calendar.RecurrencePattern',
        displayName = 'Due by Recurrence',
        doc = 'Recurrence information for a Task Event.',
    )
    dueByTickler = schema.One(
        schema.DateTime,
        displayName = 'Due by Tickler',
        doc = 'The reminder information for a Task Event.',
    )

    def InitOutgoingAttributes (self):
        """ Init any attributes on ourself that are appropriate for
        a new outgoing item.
        """
        try:
            super(TaskEventExtraMixin, self).InitOutgoingAttributes ()
        except AttributeError:
            pass
        TaskEventExtraMixin._initMixin (self) # call our init, not the method of a subclass

    def _initMixin (self):
        """
          Init only the attributes specific to this mixin.
        Called when stamping adds these attributes, and from __init__ above.
        """
        # default the dueByDate to the task's dueDate
        try:
            self.dueByDate = self.dueDate
        except AttributeError:
            pass
示例#19
0
class NotificationItem(schema.Item):
    """
    A notification item, mainly intended as a dummy for query subscriptions.
    """

    schema.kindInfo(
        displayName="Notification Item",
        description="A notification item, mainly intended as a dummy for "
        "query subscriptions.")

    def __init__(self, name=None, parent=None, kind=None):
        super(NotificationItem, self).__init__(name, parent, kind)

    def handle(self, action):
        pass
示例#20
0
class TaskStamp(Stamp):
    """
    TaskStamp is the bag of Task-specific attributes.
    """

    schema.kindInfo(annotates = notes.Note)

    __use_collection__ = True
    
    requestor = schema.One(
        Contact,
        description =
            "Issues:\n"
            '   Type could be Contact, EmailAddress or String\n'
            '   Think about using the icalendar terminology\n',
        inverse = Contact.requestedTasks,
    )
    requestee = schema.Sequence(
        Contact,
        description =
            "Issues:\n"
            '   Type could be Contact, EmailAddress or String\n'
            '   Think about using the icalendar terminology\n',
        inverse = Contact.taskRequests,
    )

    # Redirections
    @apply
    def summary():
        def fget(self):
            return self.itsItem.displayName
        def fset(self, value):
            self.itsItem.displayName = value
        return schema.Calculated(schema.Text, (items.ContentItem.displayName,),
                                 fget, fset)

    schema.addClouds(
        copying = schema.Cloud(
            requestor, requestee
        )
    )

    def InitOutgoingAttributes (self):
        self.itsItem.InitOutgoingAttributes()
示例#21
0
class MyKind1(ContentItem):
    """An example content kind"""
    
    attr1 = schema.One(schema.String, displayName="Attribute 1")
   
    schema.kindInfo(
        displayName = "Example Kind"
    )

    # redirection attributes
    who = schema.Role(redirectTo="attr1")

    attr2 = schema.One(schema.String, displayName="Attribute 2")
  
    # Typical clouds include a "copying" cloud, and a "sharing" cloud

    schema.addClouds(
        sharing = schema.Cloud(attr1, attr2)
    )
示例#22
0
class AmazonItem(ContentItem):

    schema.kindInfo(displayName="Amazon Item")

    amazonCollection = schema.One(
        AmazonCollection,
        displayName='Amazon Collection',
    )
    ProductName = schema.One(schema.String, displayName='Product Name')
    Author = schema.One(schema.String, displayName='Author(s)')
    ReleaseDate = schema.One(schema.String, displayName='Release Date')
    imageURL = schema.One(schema.String, displayName='image path')
    about = schema.One(redirectTo='ProductName')
    who = schema.One(redirectTo='Author')
    date = schema.One(redirectTo='ReleaseDate')

    myKindID = None
    myKindPath = "//parcels/osaf/examples/amazon/schema/AmazonItem"

    def __init__(self, bag, name=None, parent=None, kind=None, view=None):
        super(AmazonItem, self).__init__(name, parent, kind, view)
        if bag:
            self.ProductName = bag.ProductName
            self.imageURL = bag.ImageUrlLarge
            self.ReleaseDate = getattr(bag, 'ReleaseDate', '')
            if hasattr(bag, 'Authors'):
                if type(bag.Authors.Author) == type([]):
                    self.Author = ', '.join(bag.Authors.Author)
                else:
                    self.Author = bag.Authors.Author
            elif hasattr(bag, 'Directors'):
                if type(bag.Directors.Director) == type([]):
                    self.Author = ', '.join(bag.Directors.Director)
                else:
                    self.Author = bag.Directors.Director
            elif hasattr(bag, 'Artists'):
                if type(bag.Artists.Artist) == type([]):
                    self.Author = ', '.join(bag.Artists.Artist)
                else:
                    self.Author = bag.Artists.Artist
            else:
                self.Author = ''
            self.displayName = self.ProductName
示例#23
0
class KindCollection(AbstractCollection):
    """
    """
    schema.kindInfo(
        displayName="KindCollection"
    )

    kind = schema.One(schema.TypeReference('//Schema/Core/Kind'), initialValue=None)

    def contentsUpdated(self, item):
#        print "KindCollection.contentsUpdated: ",item
        self._collectionChanged('changed' , 'rep', item)
        pass

    def onValueChanged(self, name):
        if name == "kind":
            try:
                self.rep = KindSet(self.kind)
            except AttributeError:
                pass
示例#24
0
class IntersectionCollection(AbstractCollection):
    """
    """
    schema.kindInfo(
        displayName="IntersectionCollection"
    )

    left = schema.One(AbstractCollection, initialValue=None)
    right = schema.One(AbstractCollection, initialValue=None)

    schema.addClouds(
        copying = schema.Cloud(byCloud=[left, right]),
    )

    def onValueChanged(self, name):
        if name == "left" or name == "right":
            try:
                if self.left != None and self.right != None:
                    self.rep = Intersection((self.left, "rep"),(self.right, "rep"))
            except AttributeError:
                pass
示例#25
0
class FilteredCollection(AbstractCollection):
    """
    """
    schema.kindInfo(
        displayName="FilteredCollection"
    )

    source = schema.One(AbstractCollection, initialValue=None)
    filterExpression = schema.One(schema.String, initialValue="")

    schema.addClouds(
        copying = schema.Cloud(byCloud=[source]),
    )

    def onValueChanged(self, name):
        if name == "source" or name == "filterExpression":
            try:
                if self.source != None and self.filterExpression != "":
                    s = "lambda item: %s" % self.filterExpression
                    self.rep = FilteredSet((self.source, "rep"), eval(s))
            except AttributeError, ae:
                print ae
                pass
示例#26
0
class ListCollection(AbstractCollection):
    """
    """
    schema.kindInfo(
        displayName="ListCollection"
    )

    refCollection = schema.Sequence(otherName=Item.collections,initialValue=[])

    def __init__(self, *args, **kw):
        super(ListCollection, self).__init__(*args, **kw)
        self.rep = Set((self,'refCollection'))
        self.refCollection = []

    def add(self, item):
        self.refCollection.append(item)

    def remove(self, item):
        self.refCollection.remove(item)

    def contentsUpdated(self, item):
        self._collectionChanged('changed' , 'rep', item)
        pass
示例#27
0
class WeekdayEnum(schema.Enumeration):
    """The names of weekdays."""
    schema.kindInfo(displayName="Weekdays")
    values="monday","tuesday","wednesday","thursday","friday", \
           "saturday","sunday"
示例#28
0
class FrequencyEnum(schema.Enumeration):
    """The base frequency for a recurring event."""
    schema.kindInfo(displayName="Frequency")
    values = "yearly", "monthly", "weekly", "daily", "hourly", "minutely", "secondly"
示例#29
0
class Photo(PhotoMixin, Note):
    schema.kindInfo(displayName="Photo")
示例#30
0
class PhotoMixin(items.ContentItem):
    schema.kindInfo(displayName="Photo Mixin Kind",
                    displayAttribute="displayName")
    dateTaken = schema.One(schema.DateTime, displayName="taken")
    file = schema.One(schema.String)
    exif = schema.Mapping(schema.String, initialValue={})
    photoBody = schema.One(schema.Lob)

    about = schema.One(redirectTo='displayName')
    date = schema.One(redirectTo='dateTaken')
    who = schema.One(redirectTo='creator')

    schema.addClouds(sharing=schema.Cloud(dateTaken, photoBody))

    def importFromFile(self, path):
        data = file(path, "rb").read()
        (mimeType, encoding) = mimetypes.guess_type(path)
        self.photoBody = utils.dataToBinary(self,
                                            'photoBody',
                                            data,
                                            mimeType=mimeType)

    def importFromURL(self, url):
        if isinstance(url, URL):
            url = str(url)
        data = urllib.urlopen(url).read()
        (mimeType, encoding) = mimetypes.guess_type(url)
        self.photoBody = utils.dataToBinary(self,
                                            'photoBody',
                                            data,
                                            mimeType=mimeType)

    def exportToFile(self, path):
        data = utils.binaryToData(self.photoBody)
        out = file(path, "wb")
        out.write(data)
        out.close()

    def processEXIF(self):
        input = self.photoBody.getInputStream()
        data = input.read()
        input.close()
        stream = cStringIO.StringIO(data)
        try:
            exif = EXIF.process_file(stream)

            # Warning, serious nesting ahead
            self.dateTaken = datetime.datetime.fromtimestamp(
                time.mktime(
                    time.strptime(str(exif['Image DateTime']),
                                  "%Y:%m:%d %H:%M:%S")))

            self.exif = {}
            for (key, value) in exif.iteritems():
                if isinstance(value, EXIF.IFD_Tag):
                    self.exif[key] = value.printable
                else:
                    self.exif[key] = value

        except Exception, e:
            logger.debug("Couldn't process EXIF of Photo %s (%s)" % \
                (self.itsPath, e))