Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorflavio <fdanesse@gmail.com>2012-04-26 22:00:54 (GMT)
committer flavio <fdanesse@gmail.com>2012-04-26 22:00:54 (GMT)
commitc388594908413dc39b532da1dadb13f7df1c8e48 (patch)
tree72dae4ecf3fba07a689916c1331a0fa64f3d5fc9
parent6639fe3fd851bfb9704c79054799d490013141f8 (diff)
Filtrando
-rw-r--r--CeibalNotifica.py166
-rw-r--r--store.py78
2 files changed, 206 insertions, 38 deletions
diff --git a/CeibalNotifica.py b/CeibalNotifica.py
index e86b350..5fc5531 100644
--- a/CeibalNotifica.py
+++ b/CeibalNotifica.py
@@ -44,12 +44,16 @@ class CeibalNotifica(gtk.Window):
self.modelsort = None
self.notify_store = None
self.info_toolbar = None
+ self.control_toolbar = None
+ self.filter = None
self.set_layout()
self.show_all()
self.connect("delete_event", self.delete_event)
self.notify_store.connect("show_notify", self.show_notify)
self.notify_store.connect("delete_notify", self.delete_notify)
self.notify_store.connect("marcar_notify", self.marcar_notify)
+ self.control_toolbar.connect("get_filter", self.get_filter)
+ self.control_toolbar.connect("make_filter", self.make_filter)
self.load_notify()
self.notify_store.columns_autosize()
@@ -60,6 +64,7 @@ class CeibalNotifica(gtk.Window):
self.text_buffer = gtk.TextBuffer()
self.text_view = gtk.TextView(buffer=self.text_buffer)
self.text_view.set_editable(False)
+ self.text_view.set_justification(gtk.JUSTIFY_LEFT)
hpanel = gtk.HPaned()
self.store = Store(db_filename="prueba.db")
scroll = gtk.ScrolledWindow()
@@ -71,12 +76,41 @@ class CeibalNotifica(gtk.Window):
scroll.add_with_viewport(self.text_view)
hpanel.pack2(scroll, resize = False, shrink = True)
vbox = gtk.VBox()
- self.info_toolbar = Toolbar()
+ self.info_toolbar = ToolbarInfo()
+ self.control_toolbar = ToolbarControl()
+ vbox.pack_start(self.control_toolbar, False, False, 0)
vbox.pack_start(hpanel, True, True, 0)
vbox.pack_start(self.info_toolbar, False, False, 0)
hpanel.show_all()
self.add(vbox)
+ def get_filter(self, widget, value):
+ # En value viene el primer valor para el filtro,
+ # a saber: ["Tipo", "Prioridad", "Lanzamiento", "Expiración"]
+ # Con este valor se obtienen todos los valores en la base,
+ # en ese campo, mediante:
+ # filtro_nivel2 = self.store.db.get_categories()
+ # y se llena con ellos el segundo combo en la toolbar, mediante:
+ # widget.set_filter(filtro_nivel2)
+
+ # cuando el usuario selecciona algún valor allí, se realiza el
+ # filtro sobre los datos en la base.
+
+ # obtener valores posibles para el 1º filtro y
+ # llamar a set_filter(lista) de esta misma toolbar
+ # El filtro final será [tipo, valor]
+ # Ejemplo:
+ filtro_nivel2 = self.store.db.get_categories()
+ widget.set_filter(filtro_nivel2)
+
+ def make_filter(self, widget, value):
+ if value[1] == "Ninguno":
+ self.filter = None
+ return
+ else:
+ self.filter = value
+ self.load_notify()
+
def show_notify(self, widget, text, info):
self.text_buffer.set_text(text)
self.info_toolbar.set_text(info)
@@ -118,12 +152,14 @@ class CeibalNotifica(gtk.Window):
self.listore_model.clear()
for notif in notificaciones:
self.add_notify(notif)
-
+
def add_notify(self, notify):
mark = pixbuf1
if bool(notify['fav']): mark = pixbuf2
notify = [mark, notify['id'], notify['priority'], notify['title'], notify['text'],
notify['launched'], notify['expires'], notify['type'], bool(notify['fav'])]
+ # Filtrado
+ print self.filter
io = self.modelsort.get_model().append(notify)
sel = self.notify_store.get_selection()
il = self.modelsort.convert_child_iter_to_iter(None, io)
@@ -194,6 +230,10 @@ class Notify_Store(gtk.TreeView):
nid = self.get_model().get_value(iter, 1)
lanzamiento = self.get_model().get_value(iter, 5)
fav = self.get_model().get_value(iter, 8)
+ if fav:
+ fav = "Si"
+ else:
+ fav = "No"
info = "id: %s Lanzamiento: %s Favorito: %s" % (nid, lanzamiento, fav)
self.emit("show_notify", texto, info)
return True
@@ -241,7 +281,7 @@ class Notify_Store(gtk.TreeView):
def emit_marcar_notify(self, path):
self.emit("marcar_notify", path)
-class Toolbar(gtk.Toolbar):
+class ToolbarInfo(gtk.Toolbar):
def __init__(self):
gtk.Toolbar.__init__(self)
self.modify_bg(gtk.STATE_NORMAL,
@@ -265,7 +305,127 @@ class Toolbar(gtk.Toolbar):
self.insert(separator, -1)
def set_text(self, text=""):
self.info_label.set_text(text)
+
+class ToolbarControl(gtk.Toolbar):
+ __gsignals__ = {"get_filter": (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, (gobject.TYPE_STRING, )),
+ "make_filter": (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT, ))}
+ def __init__(self):
+ gtk.Toolbar.__init__(self)
+ #self.modify_bg(gtk.STATE_NORMAL,
+ # gtk.gdk.Color(0, 0, 0, 1))
+ self.filter_combo1 = None
+ self.filter_combo2 = None
+ self.set_layout()
+ self.show_all()
+
+ self.filter_combo1.connect("change_selection", self.emit_get_filter)
+ self.filter_combo2.connect("change_selection", self.emit_make_filter)
+
+ def set_layout(self):
+ separator = gtk.SeparatorToolItem()
+ separator.props.draw = False
+ separator.set_size_request(10, -1)
+ separator.set_expand(False)
+ self.insert(separator, -1)
+
+ item = gtk.ToolItem()
+ label = gtk.Label("Filtrar por:")
+ #label.modify_fg(gtk.STATE_NORMAL,
+ # gtk.gdk.Color(65535, 65535, 65535,1))
+ label.show()
+ item.add(label)
+ self.insert(item, -1)
+
+ separator = gtk.SeparatorToolItem()
+ separator.props.draw = False
+ separator.set_size_request(10, -1)
+ separator.set_expand(False)
+ self.insert(separator, -1)
+
+ item = gtk.ToolItem()
+ self.filter_combo1 = Combo()
+ self.filter_combo1.set_items(["Tipo", "Prioridad",
+ "Lanzamiento", "Expiración"])
+ self.filter_combo1.show()
+ item.add(self.filter_combo1)
+ self.insert(item, -1)
+
+ separator = gtk.SeparatorToolItem()
+ separator.props.draw = False
+ separator.set_size_request(10, -1)
+ separator.set_expand(False)
+ self.insert(separator, -1)
+
+ item = gtk.ToolItem()
+ label = gtk.Label("Seleccionar:")
+ #label.modify_fg(gtk.STATE_NORMAL,
+ # gtk.gdk.Color(65535, 65535, 65535,1))
+ label.show()
+ item.add(label)
+ self.insert(item, -1)
+
+ separator = gtk.SeparatorToolItem()
+ separator.props.draw = False
+ separator.set_size_request(10, -1)
+ separator.set_expand(False)
+ self.insert(separator, -1)
+
+ item = gtk.ToolItem()
+ self.filter_combo2 = Combo()
+ self.filter_combo2.set_items([])
+ self.filter_combo2.show()
+ item.add(self.filter_combo2)
+ self.insert(item, -1)
+
+ separator = gtk.SeparatorToolItem()
+ separator.props.draw = False
+ separator.set_size_request(0, -1)
+ separator.set_expand(True)
+ self.insert(separator, -1)
+
+ def emit_get_filter(self, widget, value):
+ self.emit("get_filter", value)
+ def emit_make_filter(self, widget, value):
+ val1 = self.filter_combo1.get_value_select()
+ self.emit("make_filter", [val1,value])
+ def set_filter(self, lista):
+ self.filter_combo2.set_items(lista)
+
+class Combo(gtk.ComboBox):
+ __gsignals__ = {"change_selection": (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, (gobject.TYPE_STRING, ))}
+ def __init__(self):
+ gtk.ComboBox.__init__(self, gtk.ListStore(str))
+ cell = gtk.CellRendererText()
+ self.pack_start(cell, True)
+ self.add_attribute(cell, 'text', 0)
+ self.show_all()
+ self.connect("changed", self.emit_selection)
+
+ def set_items(self, items):
+ self.get_model().clear()
+ self.append_text("Ninguno")
+ for item in items:
+ self.append_text(item)
+ self.set_active(0)
+
+ def emit_selection(self, widget):
+ indice = widget.get_active()
+ if indice < 0: return
+ iter = widget.get_model().get_iter(indice)
+ value = widget.get_model().get_value(iter, 0)
+ self.emit("change_selection", value)
+
+ def get_value_select(self):
+ indice = self.get_active()
+ if indice < 0: return None
+ iter = self.get_model().get_iter(indice)
+ value = self.get_model().get_value(iter, 0)
+ return value
+
if __name__ == "__main__":
CeibalNotifica()
gtk.main()
diff --git a/store.py b/store.py
index 9940403..fdfc131 100644
--- a/store.py
+++ b/store.py
@@ -15,27 +15,35 @@ import shelve
# for future releases
#from xml.dom import minidom
+init_db = """
+CREATE TABLE IF NOT EXISTS notifications (id INTEGER PRIMARY KEY,
+title VARCHAR(30) NOT NULL ON CONFLICT REPLACE DEFAULT '',
+text TEXT NOT NULL ON CONFLICT REPLACE DEFAULT '',
+priority INTEGER NOT NULL,
+launched DATE NOT NULL ON CONFLICT REPLACE DEFAULT 00000000,
+expires DATETIME,
+type VARCHAR(15) NOT NULL ON CONFLICT REPLACE DEFAULT '',
+fav INTEGER NOT NULL ON CONFLICT REPLACE DEFAULT 0 ); """
+
class Db:
def __init__(self, db_filename=None):
- init_db = """
-CREATE TABLE IF NOT EXISTS notifications (id INTEGER PRIMARY KEY,title VARCHAR(30) NOT NULL ON CONFLICT REPLACE DEFAULT '',text TEXT NOT NULL ON CONFLICT REPLACE DEFAULT '', priority INTEGER NOT NULL, launched DATE NOT NULL ON CONFLICT REPLACE DEFAULT 00000000,expires DATETIME, type VARCHAR(15) NOT NULL ON CONFLICT REPLACE DEFAULT '',fav INTEGER NOT NULL ON CONFLICT REPLACE DEFAULT 0 ); """
if db_filename:
self._db_filename = db_filename
else:
- self._db_filename = os.path.join(env.get_data_root(),"messages.db")
+ self._db_filename = os.path.join(env.get_data_root(), "messages.db")
conn = self._connect()
c = conn.cursor()
c.executescript(init_db)
self._close_connection(conn)
- def dict_factory(self,cursor, row):
+ def dict_factory(self, cursor, row):
d = {}
for idx, col in enumerate(cursor.description):
d[col[0]] = row[idx]
return d
def _connect(self):
- conn = sqlite3.connect(self._db_filename,isolation_level=None)
+ conn = sqlite3.connect(self._db_filename, isolation_level=None)
conn.text_factory = str
return conn
@@ -48,9 +56,9 @@ CREATE TABLE IF NOT EXISTS notifications (id INTEGER PRIMARY KEY,title VARCHAR(3
c = con.cursor()
c.execute('BEGIN TRANSACTION')
try:
- c.execute('insert into notifications(%s,%s,%s,%s,%s,%s,%s,%s) values (?,?,?,?,?,?,?,?)' %tuple(keys), values)
- except sqlite3.IntegrityError,e:
- print "Error al insertar datos: %s" %str(e)
+ c.execute('insert into notifications(%s,%s,%s,%s,%s,%s,%s,%s) values (?,?,?,?,?,?,?,?)' % tuple(keys), values)
+ except sqlite3.IntegrityError, e:
+ print "Error al insertar datos: %s" % str(e)
c.execute('END TRANSACTION')
self._close_connection(con)
@@ -60,9 +68,9 @@ CREATE TABLE IF NOT EXISTS notifications (id INTEGER PRIMARY KEY,title VARCHAR(3
c = con.cursor()
c.execute('BEGIN TRANSACTION')
try:
- c.execute('delete from notifications where id=%i' %id_msg)
- except sqlite3.IntegrityError,e:
- print "Error al eliminar datos: %s" %str(e)
+ c.execute('delete from notifications where id=%i' % id_msg)
+ except sqlite3.IntegrityError, e:
+ print "Error al eliminar datos: %s" % str(e)
c.execute('END TRANSACTION')
self._close_connection(con)
@@ -73,7 +81,7 @@ CREATE TABLE IF NOT EXISTS notifications (id INTEGER PRIMARY KEY,title VARCHAR(3
order = "DESC"
query = "select distinct type from notifications order by type "+order
return map(lambda x:x['type'],self.run_query(query))
-
+
def set_fav(self, id_msg, fav=True):
"""Marca un mensaje como favorito.
Si fav == False lo desmarca"""
@@ -81,15 +89,15 @@ CREATE TABLE IF NOT EXISTS notifications (id INTEGER PRIMARY KEY,title VARCHAR(3
c = con.cursor()
c.execute('BEGIN TRANSACTION')
try:
- c.execute('update notifications set fav=%i where id=%i' %(int(fav),id_msg))
- except sqlite3.IntegrityError,e:
- print "Error al eliminar datos: %s" %str(e)
+ c.execute('update notifications set fav=%i where id=%i' % (int(fav), id_msg))
+ except sqlite3.IntegrityError, e:
+ print "Error al eliminar datos: %s" % str(e)
c.execute('END TRANSACTION')
self._close_connection(con)
def is_fav(self, id_msg):
- fav = self.run_query("select fav from notifications where id=%i" %id_msg)
- return fav[0]['fav']
+ fav = self.run_query("select fav from notifications where id=%i" % id_msg)
+ return bool(int(fav[0]['fav']))
def run_query(self, query):
"""
@@ -113,12 +121,12 @@ CREATE TABLE IF NOT EXISTS notifications (id INTEGER PRIMARY KEY,title VARCHAR(3
if args:
filters = 'where '
while args:
- clave,valor = args.popitem()
- filters+=clave+' '+str(valor)
- filters+=' and ' if args else ''
+ clave, valor = args.popitem()
+ filters += clave + ' ' + str(valor)
+ filters += ' and ' if args else ''
c = con.cursor()
c.execute('BEGIN TRANSACTION')
- c.execute('SELECT id, priority, title, text, launched, expires, type, fav FROM notifications %s order by priority desc;' %filters)
+ c.execute('SELECT id, priority, title, text, launched, expires, type, fav FROM notifications %s order by priority desc;' % filters)
output = c.fetchall()
c.execute('END TRANSACTION')
self._close_connection(con)
@@ -142,10 +150,10 @@ class Store:
self.db = Db(db_filename)
# Borro todas las notificaciones que ya expiraron
# Para el futuro puede interesar tener un hisórico, habría que cambiar esto
- today = datetime.datetime.strftime(datetime.date.today(), "%Y-%m-%d")
- query = "delete from notifications where expires < %s;" %today
+ today = datetime.datetime.strftime(datetime.date.today(), "%Y-%m-%d")
+ query = "delete from notifications where expires < %s;" % today
self.db.run_query(query)
- # Implementado para futuras versiones
+ # Implementado para futuras versiones
"""
if not xmlpath:
xmlpath = os.path.join(env.get_data_root(),"mensajes.xml")
@@ -154,27 +162,28 @@ class Store:
fsock.close()
self.msg_list = self.xmldoc.getElementsByTagName("message")
"""
- # por el momento se implementa un parseo de los archivos shelve
- # de texto que se encuentren en /etc/notifier/data/tmp/
+ # por el momento se implementa un parseo de los archivos shelve
+ # de texto que se encuentren en /etc/notifier/data/tmp/
# obtengo todos los archivos que comiencen con 'notify_'
- xmlpath = '/tmp' # os.path.join(env.get_data_root(),'tmp')
- files = filter(lambda x: x.startswith("notify_"),os.listdir(xmlpath))
+ xmlpath = '/tmp' # os.path.join(env.get_data_root(),'tmp')
+ files = filter(lambda x: x.startswith("notify_"), os.listdir(xmlpath))
self.msg_list = {}
#msg_items = ['id', 'title', 'text', 'launched', 'expired', 'priority',]
for file in files:
- abspath = os.path.join(xmlpath,file)
+ abspath = os.path.join(xmlpath, file)
try:
f = shelve.open(abspath)
self._save_message(f)
f.close()
os.remove(abspath)
- except: pass
+ except:
+ pass
#for msg in self.msg_list:
# self._save_message(msg)
def _save_message(self, msg):
"""Procesa los mensajes que vienen en el diccionario msg"""
- print "procesando nodo %s" %msg["id"]
+ print "procesando nodo %s" % msg["id"]
keys = msg.keys()
values = []
for item in keys:
@@ -184,11 +193,11 @@ class Store:
def _save_XML_message(self, msg):
# For future releases
#TODO: Poder leer links html en el campo text
- print "procesando nodo %s" %msg.getAttribute("id")
+ print "procesando nodo %s" % msg.getAttribute("id")
refNode = msg.childNodes
- keys = ["id","type","priority"]
+ keys = ["id", "type", "priority"]
values = []
- map(lambda x: values.append(msg.getAttribute(x)),keys)
+ map(lambda x: values.append(msg.getAttribute(x)), keys)
for node in refNode:
if node.nodeType == 1:
#print "clave: %s, valor: %s" % (node.localName, node.firstChild.data)
@@ -196,7 +205,6 @@ class Store:
values.append(node.firstChild.wholeText.strip())
self.db.add_message(keys, values)
-
if __name__ == "__main__":
#db_filename = '../data/messages.db'
#xmlpath = "../data/mensajes.xml"