[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