# Copyright (c) 2001-2005 LOGILAB S.A. (Paris, FRANCE). # http://www.logilab.fr/ -- mailto:contact@logilab.fr # # Copyright (c) 2004-2005 DoCoMo Euro-Labs GmbH (Munich, Germany). # http://www.docomolab-euro.com/ -- mailto:tarlano@docomolab-euro.com # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """Basic elements for narval memory's: - data - url - file - command - dict - event (only if mxDateTime is available) :version: $Revision:$ :author: Logilab :copyright: 2001-2005 LOGILAB S.A. (Paris, FRANCE) 2004-2005 DoCoMo Euro-Labs GmbH (Munich, Germany) :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr http://www.docomolab-euro.com/ -- mailto:tarlano@docomolab-euro.com """ __revision__ = "$Id: lib.py,v 1.78 2002/10/14 14:24:11 syt Exp $" __docformat__ = "restructuredtext en" import re from xml.sax.saxutils import escape from mx.DateTime import now from narval.public import NO_NS, normalize_url from narval.element import NSAttribute, ALElement from narval.xml_handlers import data_handler, ListHandler, DictHandler from narval.serialutils import date_time_value, date_time_rev_value from narval.interfaces.base import IURL, IFile, IData, ICommand, IDictionary, \ ICategory, IEvent, IPhoneCall # element definitions ######################################################### class MasterInformationsElement(ALElement): """ :type jabberid: str :ivar jabberid: the jabber id of the bot's master :type username: str :ivar username: bot's master full name :type email: str :ivar email: mater's email :type sip: str :ivar sip: the master's sip uri :type prefered_via: str :ivar prefered_via: the prefered media for the master to be contacted """ __xml_element__ = (NO_NS, 'master-infos') jabberid = NSAttribute(NO_NS, '', str, str) username = NSAttribute(NO_NS, '', str, str) email = NSAttribute(NO_NS, '', str, str) sip = NSAttribute(NO_NS, '', str, str) prefered_via = NSAttribute(NO_NS, '', str, str) class DataElement(ALElement): """simple IData implementation""" __implements__ = (IData,) __xml_element__ = (NO_NS, 'data') __child_handler__ = data_handler('data') data = '' def __init__(self, data = '', **attributes): super(DataElement, self).__init__(**attributes) self.data = data def children_as_xml(self, encoding='UTF-8'): """return the XML representation of children in this element. :type encoding: str :param encoding: the encoding to use in the returned string :rtype: str :return: XML string representing the element """ return self.data class URLElement(ALElement): """IURL implementation""" __implements__ = (IURL,) __xml_element__ = (NO_NS, 'url') address = NSAttribute(NO_NS, None, str, str) encoding = NSAttribute(NO_NS, None, str, str) def raw_address(self): return self.address def normalize(self): """return the expanded normalized url string""" return normalize_url(self.raw_address())[0] def protocol(self): """return the normalized url string""" return normalize_url(self.raw_address())[1][0] or 'file' def path(self): """return the expanded normalized path string""" return normalize_url(self.raw_address())[1][2] class FileElement(URLElement): """IFile and IData implementation""" __implements__ = (IFile, IData) __xml_element__ = (NO_NS, 'file') __child_handler__ = data_handler('data') data = '' mode = NSAttribute(NO_NS, None, str, str) def children_as_xml(self, encoding='UTF-8'): """return the XML representation of children in this element. :type encoding: str :param encoding: the encoding to use in the returned string :rtype: str :return: XML string representing the element """ return escape(getattr(self, 'data', '')) class CommandElement(ALElement): """ICommand implementation""" __implements__ = (ICommand,) __xml_element__ = (NO_NS, 'command') name = NSAttribute(NO_NS, None, str, str) __child_handler__ = ListHandler list_attr = 'args' args = () def children_as_xml(self, encoding='UTF-8'): """return the XML representation of children in this element. :type encoding: str :param encoding: the encoding to use in the returned string :rtype: str :return: XML string representing the element """ result = [] for value in self.args: result.append(' %s' % (value,)) return '\n'.join(result) class DictElement(ALElement): """IDictionary implementation""" __implements__ = (IDictionary,) __xml_element__ = (NO_NS, 'dictionary') __child_handler__ = DictHandler def __init__(self, wrapped_dict = None, **attributes): super(DictElement, self).__init__(**attributes) self._dict = wrapped_dict or {} def children_as_xml(self, encoding='UTF-8'): """return the XML representation of children in this element. :type encoding: str :param encoding: the encoding to use in the returned string :rtype: str :return: XML string representing the element """ result = [] for attr, value in self._dict.items(): if value is not None: result.append(' <%s>%s' % (attr, value, attr)) return '\n'.join(result) def __getitem__(self, item): return self._dict[item] def __setitem__(self, item, value): self._dict[item] = value def as_dict(self): return self._dict class CategoryElement(ALElement): """ICategory implementation""" __implements__ = (ICategory,) __xml_element__ = (NO_NS, 'category') name = NSAttribute(NO_NS, None, str, str) TIMERGX = re.compile('\d\d:\d\d') DATERGX = re.compile('((\d\d[-:/]?)+)') class EventElement(ALElement): """IEvent implementation""" __implements__ = (IEvent,) __xml_element__ = (NO_NS, 'event') from_time = NSAttribute(NO_NS, None, date_time_value, date_time_rev_value) to_time = NSAttribute(NO_NS, None, date_time_value, date_time_rev_value) subject = NSAttribute(NO_NS, None, str, str) description = NSAttribute(NO_NS, None, str, str) location = NSAttribute(NO_NS, None, str, str) attendees = NSAttribute(NO_NS, None, str, str) def extract_time_from_string(datestr): """ take a string, try to extract a date-time from it and return the date time object and the remaining string """ timestr = TIMERGX.finditer(datestr).next().group(0) other = TIMERGX.sub('', datestr, 1) today = now() for group in DATERGX.finditer(datestr): parts = [int(part) for part in re.split('[-:/]', group.group(0))] day = parts[-1] if day > 31 or len(parts) > 3: continue if len(parts) == 1: datestr = '%s-%s-%s' % (today.year, today.month, day) break month = parts[-2] if month > 12: continue if len(parts) == 2: year = today.year else: year = str(parts[0]) if len(year) == 2: year = '20' + str(year) elif len(year) != 4: continue datestr = '%s-%02d-%02d' % (year, month, day) other = other.replace(group.group(0), '') break else: raise Exception('Can\'t find date in %r' % datestr) return date_time_value('%s %s' % (datestr, timestr)), other extract_time_from_string = staticmethod(extract_time_from_string) date_time_from_string = staticmethod(date_time_value) date_time_to_string = staticmethod(date_time_rev_value) class PhoneCallElement(ALElement): """ICategory implementation""" __implements__ = (IPhoneCall,) __xml_element__ = (NO_NS, 'phone-call') sip_uri = NSAttribute(NO_NS, None, str, str) sentence = NSAttribute(NO_NS, None, str, str)