[pkg-fso-commits] [SCM] FSO frameworkd Debian packaging branch, debian, updated. upstream/0.9.5.5-717-g0f98819

Sebastian Krzyszkowiak seba.dos1 at gmail.com
Sat Aug 6 08:17:48 UTC 2011


The following commit has been merged in the debian branch:
commit 2d8026109cfedec9e23df4435ec7d7bfedf77ed7
Author: Thomas Zimmermann <zimmermann at vdm-design.de>
Date:   Mon Aug 10 22:49:32 2009 +0200

    opimd: add Dates domain and SQLite-Dates backend
    Signed-off-by: Sebastian Krzyszkowiak <seba.dos1 at gmail.com>

diff --git a/framework/subsystems/opimd/pimb_sqlite_calls.py b/framework/subsystems/opimd/pimb_sqlite_dates.py
similarity index 52%
copy from framework/subsystems/opimd/pimb_sqlite_calls.py
copy to framework/subsystems/opimd/pimb_sqlite_dates.py
index c2ff113..7eb1cae 100644
--- a/framework/subsystems/opimd/pimb_sqlite_calls.py
+++ b/framework/subsystems/opimd/pimb_sqlite_dates.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 #
 #   Openmoko PIM Daemon
-#   SQLite-calls Backend Plugin
+#   SQLite-Dates Backend Plugin
 #
 #   http://openmoko.org/
 #
@@ -23,7 +23,7 @@
 #   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 #
 
-"""opimd SQLite-Calls Backend Plugin"""
+"""opimd SQLite-Dates Backend Plugin"""
 import os
 import sqlite3
 
@@ -40,15 +40,15 @@ import framework.patterns.tasklet as tasklet
 from framework.config import config, rootdir
 rootdir = os.path.join( rootdir, 'opim' )
 
-_DOMAINS = ('Calls', )
-_SQLITE_FILE_NAME = os.path.join(rootdir,'sqlite-calls.db')
+_DOMAINS = ('Dates', )
+_SQLITE_FILE_NAME = os.path.join(rootdir,'sqlite-dates.db')
 
 
 
 #----------------------------------------------------------------------------#
-class SQLiteCallBackend(Backend):
+class SQLiteDatesBackend(Backend):
 #----------------------------------------------------------------------------#
-    name = 'SQLite-Calls'
+    name = 'SQLite-Dates'
     properties = [PIMB_CAN_ADD_ENTRY, PIMB_CAN_DEL_ENTRY, PIMB_CAN_UPD_ENTRY, PIMB_CAN_UPD_ENTRY_WITH_NEW_FIELD]
 
     _domain_handlers = None           # Map of the domain handler objects we support
@@ -56,32 +56,27 @@ class SQLiteCallBackend(Backend):
 #----------------------------------------------------------------------------#
 
     def __init__(self):
-        super(SQLiteCallBackend, self).__init__()
+        super(SQLiteDatesBackend, self).__init__()
         self._domain_handlers = {}
         self._entry_ids = []
         try:
             self.con = sqlite3.connect(_SQLITE_FILE_NAME)
             cur = self.con.cursor()
-            cur.execute("""CREATE TABLE IF NOT EXISTS calls (
+            cur.execute("""CREATE TABLE IF NOT EXISTS dates (
                 id INTEGER PRIMARY KEY,
-                Type TEXT,
-                Timestamp TEXT,
-                Timezone TEXT,
-                Direction TEXT,
-                Duration TEXT,
-                Cost TEXT,
-                Answered INTEGER DEFAULT 0,
-                New INTEGER DEFAULT 0,
-                Replied INTEGER DEFAULT 0,
+                Begin INTEGER,
+                End INTEGER,
+                Message TEXT,
                 deleted INTEGER DEFAULT 0);""")
 
-            cur.execute("CREATE TABLE IF NOT EXISTS call_values (id INTEGER PRIMARY KEY, callId INTEGER, Field TEXT, Value TEXT)")
+            cur.execute("CREATE TABLE IF NOT EXISTS date_values (id INTEGER PRIMARY KEY, dateId INTEGER, Field TEXT, Value TEXT)")
 
-            cur.execute("CREATE INDEX IF NOT EXISTS calls_id_idx ON calls (id)")
-            cur.execute("CREATE INDEX IF NOT EXISTS calls_Direction_idx ON calls (Direction)")
-            cur.execute("CREATE INDEX IF NOT EXISTS calls_New_idx ON calls (New)")
+            cur.execute("CREATE INDEX IF NOT EXISTS dates_id_idx ON dates (id)")
+            cur.execute("CREATE INDEX IF NOT EXISTS dates_Begin_idx ON dates (Begin)")
+            cur.execute("CREATE INDEX IF NOT EXISTS dates_End_idx ON dates (End)")
+            cur.execute("CREATE INDEX IF NOT EXISTS dates_Message_idx ON dates (Message)")
 
-            cur.execute("CREATE INDEX IF NOT EXISTS call_values_callId_idx ON call_values (callId)") 
+            cur.execute("CREATE INDEX IF NOT EXISTS date_values_datesId_idx ON date_values (dateId)")
 
             self.con.text_factory = sqlite3.OptimizedUnicode
             self.con.commit()
@@ -114,25 +109,21 @@ class SQLiteCallBackend(Backend):
 
     def load_entries_from_db(self):
         """Loads all entries from db"""
-        keys = {0:'_backend_entry_id', 1:'Type', 2:'Timestamp', 3:'Timezone', 4:'Direction', 5:'Duration', 6:'Cost', 7:'Answered', 8:'New', 9:'Replied'}
-        floatKeys = ['Timestamp', 'Duration']
+        keys = {0:'_backend_entry_id', 1:'Begin', 2:'End', 3:'Message'}
         cur = self.con.cursor()
         try:
-            cur.execute('SELECT id, Type, Timestamp, Timezone, Direction, Duration, Cost, Answered, New, Replied FROM calls WHERE deleted=0 ORDER BY id DESC')
+            cur.execute('SELECT id, Begin, End, Message FROM dates WHERE deleted=0')
             lines = cur.fetchall()
         except:
-            logger.error("%s: Could not read from database (table calls)! Possible reason is old, uncompatible table structure. If you don't have important data, please remove %s file.", self.name, _SQLITE_FILE_NAME)
+            logger.error("%s: Could not read from database (table dates)! Possible reason is old, uncompatible table structure. If you don't have important data, please remove %s file.", self.name, _SQLITE_FILE_NAME)
             raise OperationalError
 
         for line in lines:
             entry = {}
             for key in keys:
-                if keys[key] in floatKeys and line[key]:
-                    entry[keys[key]] = float(line[key])
-                else:
-                    entry[keys[key]] = line[key]
+                entry[keys[key]] = line[key]
             try:
-                cur.execute('SELECT Field, Value FROM call_values WHERE callId=?',(line[0],))
+                cur.execute('SELECT Field, Value FROM date_values WHERE dateId=?',(line[0],))
                 for pair in cur:
                     if entry.has_key(pair[0]):
                         if type(entry[pair[0]]) == list:
@@ -142,75 +133,72 @@ class SQLiteCallBackend(Backend):
                     else:
                         entry[pair[0]]=pair[1]
             except:
-                logger.error("%s: Could not read from database (table call_values)! Possible reason is old, uncompatible table structure. If you don't have important data, please remove %s file.", self.name, _SQLITE_FILE_NAME)
+                logger.error("%s: Could not read from database (table date_values)! Possible reason is old, uncompatible table structure. If you don't have important data, please remove %s file.", self.name, _SQLITE_FILE_NAME)
                 raise OperationalError
 
-            entry_id = self._domain_handlers['Calls'].register_call(self, entry)
+            entry_id = self._domain_handlers['Dates'].register_entry(self, entry)
             self._entry_ids.append(entry_id)
         cur.close()
 
 
-    def del_call(self, call_data):
+    def del_entry(self, date_data):
         cur = self.con.cursor()
-        for (field_name, field_value) in call_data:
+        for (field_name, field_value) in date_data:
             if field_name=='_backend_entry_id':
-                callId=field_value
-    #    cur.execute('UPDATE calls SET deleted=1 WHERE id=?',(callId,))
-        cur.execute('DELETE FROM calls WHERE id=?',(callId,))
-        cur.execute('DELETE FROM call_values WHERE callId=?',(callId,))
+                dateId=field_value
+    #    cur.execute('UPDATE dates SET deleted=1 WHERE id=?',(dateId,))
+        cur.execute('DELETE FROM dates WHERE id=?',(dateId,))
+        cur.execute('DELETE FROM date_values WHERE dateId=?',(dateId,))
         self.con.commit()
         cur.close()
 
-    def upd_call(self, call_data):
-        reqfields = ['Type', 'Timestamp', 'Timezone', 'Direction', 'Duration', 'Cost', 'Answered', 'New', 'Replied']
+    def upd_entry(self, datet_data):
+        reqfields = ['Begin', 'End', 'Message']
         cur = self.con.cursor()
-        for (field, value) in call_data:
+        for (field, value) in date_data:
             if field=='_backend_entry_id':
-                callId=value
-        for (field, value) in call_data:
+                dateId=value
+        for (field, value) in date_data:
             if field in reqfields:
-                cur.execute('UPDATE calls SET '+field+'=? WHERE id=?',(value,callId))
+                cur.execute('UPDATE dates SET '+field+'=? WHERE id=?',(value,dateId))
             elif not field.startswith('_'):
-                cur.execute('SELECT id FROM call_values WHERE callId=? AND field=?',(callId,field))
+                cur.execute('SELECT id FROM date_values WHERE dateId=? AND field=?',(dateId,field))
                 if cur.fetchone() == None:
-                    cur.execute('INSERT INTO call_values (field,value,callId) VALUES (?,?,?)',(field,value,callId))
+                    cur.execute('INSERT INTO date_values (field,value,dateId) VALUES (?,?,?)',(field,value,dateId))
                 else:
-                    cur.execute('UPDATE call_values SET value=? WHERE field=? AND callId=?',(value,field,callId))
-  #      cur.execute('UPDATE calls SET updated=1 WHERE id=?',(callId,))
+                    cur.execute('UPDATE date_values SET value=? WHERE field=? AND dateId=?',(value,field,dateId))
+    #    cur.execute('UPDATE dates SET updated=1 WHERE id=?',(dateId,))
         self.con.commit()
         cur.close()
 
-    def add_call(self, call_data):
-        reqfields = ['Type', 'Timestamp', 'Timezone', 'Direction', 'Duration', 'Cost']
-        reqIntfields = ['Answered', 'New', 'Replied']
+    def add_entry(self, date_data):
+        date_id = self.add_date_to_db(date_data)
+        return date_id
+
+    def add_date_to_db(self, date_data):
+        reqfields = ['Begin', 'End', 'Message']
 
         for field in reqfields:
             try:
-                call_data[field]
-            except KeyError:
-                call_data[field]=''
-        for field in reqIntfields:
-            try:
-                call_data[field]
+                date_data[field]
             except KeyError:
-                call_data[field]=0
+                date_data[field]=''
 
         cur = self.con.cursor()
-        cur.execute('INSERT INTO calls (Type, Timestamp, Timezone, Direction, Duration, Cost, Answered, New, Replied) VALUES (?,?,?,?,?,?,?,?,?)',(call_data['Type'], call_data['Timestamp'], call_data['Timezone'], call_data['Direction'], call_data['Duration'], call_data['Cost'], call_data['Answered'], call_data['New'], call_data['Replied']))
+        cur.execute('INSERT INTO dates (Begin, End, Message) VALUES (?,?,?)',(date_data['Begin'], date_data['End'], date_data['End']))
         cid = cur.lastrowid
-        for field in call_data:
+        for field in date_data:
             if not field in reqfields:
-                if not field in reqIntfields:
-                    if type(call_data[field]) == Array or type(call_data[field]) == list:
-                        for value in call_data[field]:
-                            cur.execute('INSERT INTO call_values (callId, Field, Value) VALUES (?,?,?)',(cid, field, value))
-                    else:
-                        cur.execute('INSERT INTO call_values (callId, Field, Value) VALUES (?,?,?)',(cid, field, call_data[field]))
+                if type(date_data[field]) == Array or type(date_data[field]) == list:
+                    for value in date_data[field]:
+                        cur.execute('INSERT INTO date_values (dateId, Field, Value) VALUES (?,?,?)',(cid, field, value))
+                else:
+                    cur.execute('INSERT INTO date_values (dateId, Field, Value) VALUES (?,?,?)',(cid, field, date_data[field]))
         
         self.con.commit()
         cur.close()
 
-        call_data['_backend_entry_id']=cid
+        date_data['_backend_entry_id']=cid
 
-        call_id = self._domain_handlers['Calls'].register_call(self, call_data)
-        return call_id
+        date_id = self._domain_handlers['Dates'].register_entry(self, date_data)
+        return date_id
diff --git a/framework/subsystems/opimd/pimd_contacts.py b/framework/subsystems/opimd/pimd_dates.py
similarity index 64%
copy from framework/subsystems/opimd/pimd_contacts.py
copy to framework/subsystems/opimd/pimd_dates.py
index 90acd83..02b30af 100644
--- a/framework/subsystems/opimd/pimd_contacts.py
+++ b/framework/subsystems/opimd/pimd_dates.py
@@ -7,11 +7,12 @@ Open PIM Daemon
 (C) 2008 Openmoko, Inc.
 (C) 2009 Michael 'Mickey' Lauer <mlauer at vanille-media.de>
 (C) 2009 Sebastian Krzyszkowiak <seba.dos1 at gmail.com>
+(C) 2009 Thomas Zimmermann <zimmermann at vdm-design.de>
 GPLv2 or later
 
-Contacts Domain Plugin
+Dates Domain Plugin
 
-Establishes the 'contacts' PIM domain and handles all related requests
+Establishes the 'dates' PIM domain and handles all related requests
 """
 
 from dbus.service import FallbackObject as DBusFBObject
@@ -38,22 +39,22 @@ from pimd_generic import GenericEntry, GenericDomain
 
 #----------------------------------------------------------------------------#
 
-_DOMAIN_NAME = "Contacts"
+_DOMAIN_NAME = "Dates"
 
 _DBUS_PATH_CONTACTS = DBUS_PATH_BASE_FSO + '/' + _DOMAIN_NAME
-_DIN_CONTACTS_BASE = DIN_BASE_FSO
+_DIN_DATES_BASE = DIN_BASE_FSO
 
-_DBUS_PATH_QUERIES = _DBUS_PATH_CONTACTS + '/Queries'
+_DBUS_PATH_QUERIES = _DBUS_PATH_DATES + '/Queries'
 
-_DIN_CONTACTS = _DIN_CONTACTS_BASE + '.' + 'Contacts'
-_DIN_ENTRY = _DIN_CONTACTS_BASE + '.' + 'Contact'
-_DIN_QUERY = _DIN_CONTACTS_BASE + '.' + 'ContactQuery'
+_DIN_DATES = _DIN_DATES_BASE + '.' + 'Dates'
+_DIN_ENTRY = _DIN_DATES_BASE + '.' + 'Date'
+_DIN_QUERY = _DIN_DATES_BASE + '.' + 'DateQuery'
 
 
 #----------------------------------------------------------------------------#
-class Contact(GenericEntry):
+class Date(GenericEntry):
 #----------------------------------------------------------------------------#
-    """Represents one single contact with all the data fields it consists of.
+    """Represents one single calendar entry with all the data fields it consists of.
 
     _fields[n] = [field_name, field_value, value_used_for_comparison, source]
 
@@ -67,6 +68,82 @@ class Contact(GenericEntry):
         self.domain_name = _DOMAIN_NAME
         GenericEntry.__init__( self, path )
 
+    def match_query(self, query_obj):
+        """Checks whether this entry matches the given query
+
+        @param query_obj Dict containing key/value pairs of the required matches
+        @return Accuracy of the match, ranging from 0.0 (no match) to 1.0 (complete match)"""
+
+        overall_match = 1.0
+
+        try:
+            begin = query_obj["Begin"]
+            query_obj.remove(query_obj["Begin"])
+        except KeyError:
+            begin = None
+
+        try:
+            end = query_obj["End"]
+            query_obj.remove(query_obj["End"])
+        except KeyError:
+            end = None
+
+        if (begin == None and end != None) or (begin != None and end == None):
+            return 0.0
+
+        if (begin != None and end != None):
+            if begin > self._field_idx["End"] or end < self._field_idx["Begin"]:
+                return 0.0
+
+        for field_name in query_obj.keys():
+            # Skip fields only meaningful to the parser
+            if field_name[:1] == "_": continue
+
+            field_value = str(query_obj[field_name])
+            best_field_match = 0.0
+
+            matcher = re.compile(field_value)
+
+            # Check if field value(s) of this entry match(es) the query field
+            try:
+                field_ids = self._field_idx[field_name]
+
+                for field_id in field_ids:
+
+                    # A field is (Key,Value,Comp_Value,Source), so [2] is the value we usually use for comparison
+                    comp_value = self._fields[field_id][2]
+                    if not comp_value:
+                        # Use the real value if no comparison value given
+                        comp_value = str(self._fields[field_id][1])
+
+                    # Compare and determine the best match ratio
+                    match = matcher.search(comp_value)
+                    if match:
+                        match_len = match.end() - match.start()
+                    else:
+                        match_len = 0
+
+                    if field_value and comp_value:
+                        field_match = float(match_len) / len(comp_value)
+                    else:
+                        field_match = 0.0
+
+                    if field_match > best_field_match: best_field_match = field_match
+                    logger.debug("%s: Field match for %s / %s: %f", self.domain_name, comp_value, field_value, field_match)
+
+            except KeyError:
+                # entry has no data for this field contained in the query, so this entry cannot match
+                return 0.0
+
+            # Aggregate the field match value into the overall match
+            # We don't use the average of all field matches as one
+            # non-match *must* result in a final value of 0.0
+            overall_match *= best_field_match
+
+            # Stop comparing if there is too little similarity
+            if overall_match == 0.0: break
+
+        return overall_match
 
 
 #----------------------------------------------------------------------------#
@@ -81,7 +158,7 @@ class QueryManager(DBusFBObject):
     def __init__(self, entries):
         """Creates a new QueryManager instance
 
-        @param contacts Set of Contact objects to use"""
+        @param entries Set of Date objects to use"""
 
         self._entries = entries
         self._queries = {}
@@ -91,7 +168,7 @@ class QueryManager(DBusFBObject):
         DBusFBObject.__init__( self, conn=busmap["opimd"], object_path=_DBUS_PATH_QUERIES )
 
         # Still necessary?
-        self.interface = _DIN_CONTACTS
+        self.interface = _DIN_DATES
         self.path = _DBUS_PATH_QUERIES
 
 
@@ -115,7 +192,7 @@ class QueryManager(DBusFBObject):
     def check_new_entry(self, entry_id):
         """Checks whether a newly added contact matches one or more queries so they can signal clients
 
-        @param contact_id Contact ID of the contact that was added"""
+        @param entry_id Date ID of the datethat was added"""
 
         for (query_id, query_handler) in self._queries.items():
             if query_handler.check_new_entry(entry_id):
@@ -131,10 +208,10 @@ class QueryManager(DBusFBObject):
             raise InvalidQueryID( "Existing query IDs: %s" % self._queries.keys() )
 
     def EntryAdded(self, path, rel_path=None):
-        self.ContactAdded(path, rel_path=rel_path)
+        self.DateAdded(path, rel_path=rel_path)
 
     @dbus_signal(_DIN_QUERY, "s", rel_path_keyword="rel_path")
-    def ContactAdded(self, path, rel_path=None):
+    def DateAdded(self, path, rel_path=None):
         pass
 
     @dbus_method(_DIN_QUERY, "", "i", rel_path_keyword="rel_path")
@@ -196,7 +273,7 @@ class QueryManager(DBusFBObject):
         self._queries.__delitem__(num_id)
 
 #----------------------------------------------------------------------------#
-class ContactDomain(Domain, GenericDomain):
+class DateDomain(Domain, GenericDomain):
 #----------------------------------------------------------------------------#
     name = _DOMAIN_NAME
 
@@ -207,9 +284,9 @@ class ContactDomain(Domain, GenericDomain):
     Entry = None
 
     def __init__(self):
-        """Creates a new ContactDomain instance"""
+        """Creates a new DateDomain instance"""
 
-        self.Entry = Contact
+        self.Entry = Date
 
         self._backends = {}
         self._entries = []
@@ -220,8 +297,8 @@ class ContactDomain(Domain, GenericDomain):
         Domain.__init__( self, conn=busmap["opimd"], object_path=DBUS_PATH_BASE_FSO + '/' + self.name )
 
         # Keep frameworkd happy
-        self.interface = _DIN_CONTACTS
-        self.path = _DBUS_PATH_CONTACTS
+        self.interface = _DIN_DATES
+        self.path = _DBUS_PATH_DATES
 
  
     #---------------------------------------------------------------------#
@@ -229,10 +306,10 @@ class ContactDomain(Domain, GenericDomain):
     #---------------------------------------------------------------------#
 
     def NewEntry(self, path):
-        self.NewContact(path)
+        self.NewDate(path)
 
     @dbus_signal(_DIN_CONTACTS, "s")
-    def NewContact(self, path):
+    def NewDate(self, path):
         pass
 
     @dbus_method(_DIN_CONTACTS, "a{sv}", "s")
@@ -242,19 +319,22 @@ class ContactDomain(Domain, GenericDomain):
         @param entry_data List of fields; format is [Key:Value, Key:Value, ...]
         @return Path of the newly created d-bus entry object"""
 
-        return self.add(entry_data)
-
-    @dbus_method(_DIN_CONTACTS, "a{sv}s", "s")
-    def GetSingleEntrySingleField(self, query, field_name):
-        """Returns the first entry found for a query, making it real easy to query simple things
+	begin = False
+	end = False
+	# Required fields: begin, end
+	for (key,value) in entry_data:
+		if key == "Begin":
+			begin = True
+		if key == "End":
+			end = True
 
-        @param query The query object
-        @param field_name The name of the field to return
-        @return The requested data"""
+	#TODO: raise correct error
+	if !(begin and end):
+		raise InvalidQueryID( "Begin or End field missing" )
 
-        return self.get_single_entry_single_field(query, field_name)
+        return self.add(entry_data)
 
-    @dbus_method(_DIN_CONTACTS, "a{sv}", "s", sender_keyword="sender")
+    @dbus_method(_DIN_DATES, "a{sv}", "s", sender_keyword="sender")
     def Query(self, query, sender):
         """Processes a query and returns the dbus path of the resulting query object
 
@@ -264,6 +344,16 @@ class ContactDomain(Domain, GenericDomain):
 
         return self.query_manager.process_query(query, sender)
 
+    @dbus_method(_DIN_DATES, "a{sv}", "i", sender_keyword="sender")
+    def GetDatesOfDayByTimestamp(self, time, sender):
+        """Processes a query and returns the dbus path of the resulting query object
+
+        @param time Timestamp within the day to return the dates for
+        @param sender Unique name of the query sender on the bus
+        @return dbus path of the query object, e.g. /org.freesmartphone.PIM/Entries/Queries/4"""
+
+        return self.query_manager.process_query(query, sender)
+
 
     @dbus_method(_DIN_ENTRY, "", "a{sv}", rel_path_keyword="rel_path")
     def GetContent(self, rel_path):
@@ -290,11 +380,11 @@ class ContactDomain(Domain, GenericDomain):
         return self.get_multiple_fields(num_id, field_list)
 
     @dbus_signal(_DIN_ENTRY, "", rel_path_keyword="rel_path")
-    def ContactDeleted(self, rel_path=None):
+    def DateDeleted(self, rel_path=None):
         pass
 
     def EntryDeleted(self, rel_path=None):
-        self.ContactDeleted(rel_path=rel_path)
+        self.DateDeleted(rel_path=rel_path)
 
     @dbus_method(_DIN_ENTRY, "", "", rel_path_keyword="rel_path")
     def Delete(self, rel_path):
@@ -303,10 +393,10 @@ class ContactDomain(Domain, GenericDomain):
         self.delete(num_id)
 
     def EntryUpdated(self, data, rel_path=None):
-        self.ContactUpdated(data, rel_path=rel_path)
+        self.DateUpdated(data, rel_path=rel_path)
 
     @dbus_signal(_DIN_ENTRY, "a{sv}", rel_path_keyword="rel_path")
-    def ContactUpdated(self, data, rel_path=None):
+    def DateUpdated(self, data, rel_path=None):
         pass
 
     @dbus_method(_DIN_ENTRY, "a{sv}", "", rel_path_keyword="rel_path")

-- 
FSO frameworkd Debian packaging



More information about the pkg-fso-commits mailing list