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-11 19:04:41 (GMT)
committer flavio <fdanesse@gmail.com>2012-04-11 19:04:41 (GMT)
commit56811517bc85b6d64ed752c0400803a47eb7c9a8 (patch)
tree25e420e38a626b34a83c918c8658a09a96ed92c9
Ceibal Notifica
-rw-r--r--.gitignore3
-rw-r--r--CeibalNotifica.py262
-rw-r--r--Iconos/ceibal.pngbin0 -> 7127 bytes
-rw-r--r--activity/ceibal.svg75
-rw-r--r--base.py40
-rw-r--r--prueba.dbbin0 -> 2048 bytes
-rw-r--r--store.py161
7 files changed, 541 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..81f8dd0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+*.pyc
+*.pyo
+*.??~
diff --git a/CeibalNotifica.py b/CeibalNotifica.py
new file mode 100644
index 0000000..ddccc08
--- /dev/null
+++ b/CeibalNotifica.py
@@ -0,0 +1,262 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Autor: Flavio Danesse - fdanesse@activitycentral.com
+'''
+La idea es hacer una aplicación que sea capaz de mostrar todos los mensajes, no importa su prioridad.
+La aplicación se llevará a cabo tanto en el azúcar y el Gnome y debe ser capaz de:
+- Muestra todos los mensajes activos
+- Filtrar y ordenar los mensajes por prioridad, fecha o tipo de mensajes'''
+
+import shelve
+import sqlite3
+import time
+import datetime
+import os
+import gtk
+import sys
+import gobject
+import string
+
+from store import *
+
+BASE = os.path.dirname(__file__)
+
+class CeibalNotifica(gtk.Window):
+ def __init__(self):
+ super(CeibalNotifica, self).__init__()
+ self.set_title("CeibalNotifica")
+ self.set_icon_from_file(os.path.join(BASE, "Iconos", "ceibal.png"))
+ self.set_resizable(True)
+ self.set_size_request(640, 480)
+ self.set_border_width(2)
+ self.set_position(gtk.WIN_POS_CENTER)
+ #self.modify_bg(gtk.STATE_NORMAL, G.GRIS)
+
+ self.notify_store = None
+ self.store = None
+ self.text_buffer = None
+ self.text_view = None
+
+ self.set_layout()
+
+ self.show_all()
+
+ self.connect("delete_event", self.delete_event)
+ self.notify_store.connect("set_notify", self.set_notify)
+
+ self.load_notify()
+
+ def set_layout(self):
+ self.text_buffer = gtk.TextBuffer()
+ self.text_view = gtk.TextView(buffer = self.text_buffer)
+ hpanel = gtk.HPaned()
+
+ self.notify_store = Notify_Store()
+ self.store = Store(db_filename = "prueba.db")
+ scroll = gtk.ScrolledWindow()
+ scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ scroll.add_with_viewport(self.notify_store)
+ hpanel.pack1(scroll, resize = False, shrink = True)
+
+ scroll = gtk.ScrolledWindow()
+ scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ scroll.add_with_viewport(self.text_view)
+ hpanel.pack2(scroll, resize = False, shrink = False)
+ hpanel.show_all()
+
+ self.add(hpanel)
+
+ def set_notify(self, widget, text):
+ self.text_buffer.set_text(text)
+
+ def load_notify(self):
+ notificaciones = self.store.db.get_messages([])
+ self.notify_store.clear()
+ for notif in notificaciones:
+ self.notify_store.add_notify(notif)
+
+ def delete_event(self, widget, event):
+ self.salir()
+ return False
+ def salir(self, widget = None):
+ sys.exit(0)
+
+
+class Notify_Store(gtk.TreeView):
+ __gsignals__ = {"set_notify":(gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (gobject.TYPE_STRING, ))}
+ def __init__(self):
+ gtk.TreeView.__init__(self)
+ self.set_property("rules-hint", True)
+ # self.connect("row-activated", self.callback_activated, None)
+ self.add_events(gtk.gdk.BUTTON2_MASK)
+ #self.connect("button-press-event", self.handler_click)
+
+ self.modelo = gtk.ListStore (gobject.TYPE_STRING,
+ gobject.TYPE_STRING, gobject.TYPE_STRING,
+ gobject.TYPE_STRING, gobject.TYPE_STRING)
+
+ self.set_model(self.modelo)
+ render = gtk.CellRendererText()
+ columna = gtk.TreeViewColumn ("Notificaciones:", render, text=0)
+ self.append_column(columna)
+
+ render = gtk.CellRendererText()
+ columna = gtk.TreeViewColumn("text", render, text=1)
+ columna.set_property('visible', False)
+ self.append_column(columna)
+
+ render = gtk.CellRendererText()
+ columna = gtk.TreeViewColumn("launched", render, text=2)
+ columna.set_property('visible', False)
+ self.append_column(columna)
+
+ render = gtk.CellRendererText()
+ columna = gtk.TreeViewColumn("expires", render, text=3)
+ columna.set_property('visible', False)
+ self.append_column(columna)
+
+ render = gtk.CellRendererText()
+ columna = gtk.TreeViewColumn("type", render, text=4)
+ columna.set_property('visible', False)
+ self.append_column(columna)
+ self.show_all()
+
+ self.treeselection = self.get_selection()
+ self.treeselection.set_mode(gtk.SELECTION_SINGLE)
+ # conecta a una funcion que manejará las selecciones
+ self.treeselection.set_select_function(self.func_selecciones, self.modelo, True)
+
+ def clear(self):
+ self.modelo.clear()
+ def add_notify(self, notify):
+ notify = [notify['title'], notify['text'], notify['launched'], notify['expires'], notify['type']]
+ iter = self.modelo.append(notify)
+
+ def func_selecciones(self, selection, model, path, is_selected, user_data):
+ # Control de selecciones sobre treestore
+ # print selection, model, path, is_selected, user_data
+ iter = self.modelo.get_iter(path)
+ self.emit("set_notify", self.modelo.get_value(iter, 1))
+ #direccion = self.modelo.get_value(iter, 2)
+ #self.preview.control_preview(direccion)
+ return True # Debe devolver True
+
+ def callback_activated (self, treeview, path, view_column, user_param1):
+ pass
+ # print treeview, path, view_column, user_param1
+ # Cuando se hace doble click sobre una fila
+ '''
+ # Obtengo el valor almacenado
+ iter = treeview.modelo.get_iter(path)
+ valor = treeview.modelo.get_value(iter, 2)
+
+ if os.path.isdir(os.path.join(valor)):
+ # Si representa a un directorio
+ if treeview.row_expanded(path):
+ # Si está expandida, colapsarla
+ treeview.collapse_row(path)
+ elif not treeview.row_expanded(path):
+ # Si no está expandida, expandirla
+ treeview.expand_to_path(path)
+ elif os.path.isfile(os.path.join(valor)):
+ # Si representa a un archivo
+ pass'''
+
+ def handler_click(self, widget, event):
+ pass
+ # reacciona a los clicks sobre las filas de tresstore
+ # print widget, event
+ '''
+ boton = event.button
+ pos = (event.x, event.y)
+ tiempo = event.time
+ # widget es TreeView widget.get_name()
+ # Obteniendo datos a partir de coordenadas de evento
+ path, columna, xdefondo, ydefondo= widget.get_path_at_pos(int(pos[0]), int(pos[1]))
+ # TreeView.get_path_at_pos(event.x, event.y) devuelve:
+ # * La ruta de acceso en el punto especificado (x, y), en relación con las coordenadas widget
+ # * El gtk.TreeViewColumn en ese punto
+ # * La coordenada X en relación con el fondo de la celda
+ # * La coordenada Y en relación con el fondo de la celda
+ if boton == 1:
+ return
+ elif boton == 3:
+ # Abrir menu - popup pasando el path de la fila seleccionada
+ self.crear_menu_emergente(boton, pos, tiempo, path)
+ return
+ elif boton == 2:
+ return'''
+
+ '''
+ def crear_menu_emergente(self, boton, pos, tiempo, path):
+ # un menu para agregar o eliminar radios de la base de datos
+ menu= gtk.Menu()
+ iter= self.modelo.get_iter(path)
+ direccion= self.modelo.get_value(iter, 2)
+ # verificamos los permisos del archivo o directorio
+ lectura, escritura, ejecucion= self.manejadordearchivos.verificar_permisos(direccion)
+
+ # Items del menu
+ if lectura: #and not os.path.ismount(os.path.join(direccion)):
+ copiar = gtk.MenuItem("Copiar")
+ menu.append(copiar)
+ copiar.connect_object("activate", self.seleccionar_origen, path, "Copiar")
+
+ if escritura and not os.path.ismount(os.path.join(direccion)):
+ borrar = gtk.MenuItem("Borrar")
+ menu.append(borrar)
+ borrar.connect_object("activate", self.seleccionar_origen, path, "Borrar")
+
+ if escritura and (os.path.isdir(os.path.join(direccion)) or os.path.ismount(os.path.join(direccion))) \
+ and (self.direccion_seleccionada != None or self.direccion_seleccionada_para_cortar != None):
+ pegar = gtk.MenuItem("Pegar")
+ menu.append(pegar)
+ pegar.connect_object("activate", self.seleccionar_origen, path, "Pegar")
+
+ if escritura and (os.path.isdir(os.path.join(direccion)) or os.path.isfile(os.path.join(direccion))):
+ cortar = gtk.MenuItem("Cortar")
+ menu.append(cortar)
+ cortar.connect_object("activate", self.seleccionar_origen, path, "Cortar")
+
+ if escritura and (os.path.isdir(os.path.join(direccion)) or os.path.ismount(os.path.join(direccion))):
+ nuevodirectorio = gtk.MenuItem("Crear Directorio")
+ menu.append(nuevodirectorio)
+ nuevodirectorio.connect_object("activate", self.seleccionar_origen, path, "Crear Directorio")
+
+ menu.show_all()
+ #popup(parent_menu_shell, parent_menu_item, func, button, activate_time, data=None)
+ gtk.Menu.popup(menu, None, None, None, boton, tiempo)'''
+
+if __name__=="__main__":
+ CeibalNotifica()
+ gtk.main()
+
+'''
+# Archivo notificaciones # http://docs.python.org/library/shelve.html
+filename = os.path.join('/tmp', 'notify_0')
+d = shelve.open(filename)
+d['id'] = 0
+d['title'] = "Prueba Titulo"
+d['text'] = "Prueba Texto"
+d['priority'] = 1
+d['launched'] = datetime.date(1972, 6, 21)
+d['expires'] = datetime.date(2012, 6, 21)
+d['type'] = "Prueba tipo"
+d.close()
+
+filename = os.path.join('/tmp', 'notify_1')
+d = shelve.open(filename)
+d['id'] = 1
+d['title'] = "Prueba Titulo1"
+d['text'] = "Prueba Texto1"
+d['priority'] = 1
+d['launched'] = datetime.date(1972, 6, 21)
+d['expires'] = datetime.date(2013, 6, 21)
+d['type'] = "Prueba tipo1"
+d.close()
+
+store = Store(db_filename="prueba.db")
+mensaje = store.db.get_messages([])
+print mensaje'''
+
diff --git a/Iconos/ceibal.png b/Iconos/ceibal.png
new file mode 100644
index 0000000..c1de3f3
--- /dev/null
+++ b/Iconos/ceibal.png
Binary files differ
diff --git a/activity/ceibal.svg b/activity/ceibal.svg
new file mode 100644
index 0000000..3503ada
--- /dev/null
+++ b/activity/ceibal.svg
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="55"
+ height="55"
+ id="svg2"
+ inkscape:version="0.48.1 r9760"
+ sodipodi:docname="JAMediaTube.svg">
+ <metadata
+ id="metadata29">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1360"
+ inkscape:window-height="715"
+ id="namedview27"
+ showgrid="false"
+ inkscape:zoom="6.2"
+ inkscape:cx="5.753863"
+ inkscape:cy="21.410092"
+ inkscape:window-x="0"
+ inkscape:window-y="26"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <defs
+ id="defs4" />
+ <path
+ style="fill:#81c900;fill-opacity:1;stroke:#000000;stroke-width:0.06929866;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 5.3972179,26.199757 c 2.2223425,5.051966 12.7749441,17.837 27.9669601,9.404816 C 43.306195,31.02232 44.0682,11.905603 37.076607,7.7613636 32.277124,8.5153225 32.621695,15.527463 23.835612,21.249852 17.318236,25.251025 8.8839177,22.261598 5.3972179,26.199757 z"
+ id="path3066-72-8"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:#81c900;fill-opacity:1;stroke:#000000;stroke-width:0.086823;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 16.087045,4.7309368 c -1.819391,0.010603 -3.484943,0.3855362 -4.861734,1.1910706 -2.1077907,5.7156256 5.784425,9.5734566 6.680824,22.6628266 0.398173,9.562147 -8.0394056,17.001403 -5.857902,23.204221 4.43789,0.399354 14.510366,-1.045682 21.125262,-7.936862 -2.827129,-0.676143 -5.373521,-2.15472 -7.027317,-4.623519 -0.237521,-0.304311 -0.464325,-0.655036 -0.680741,-0.959232 3.999793,-0.744506 10.158829,-2.066333 13.847486,-8.536849 0.08602,-0.929174 0.127558,-1.89763 0.129935,-2.901882 C 40.336076,15.29955 25.911751,4.6737273 16.087045,4.7309368 z M 39.312923,29.732593 c -0.577075,6.233303 -2.957888,10.805177 -6.139428,14.1196 6.955506,1.663497 15.656835,-1.538385 17.227211,-6.908209 -1.305739,-3.783336 -5.778051,-3.02929 -11.087783,-7.211391 z"
+ id="path3066-5-2-7"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sccccccccscccc" />
+ <path
+ style="fill:#006900;fill-opacity:1;stroke:#000000;stroke-width:0.06929866;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 32.332012,11.993374 c -1.67525,2.663174 -3.754099,6.16036 -8.543225,9.279523 -2.116904,1.299616 -4.427155,1.864051 -6.713307,2.165583 0.375578,1.550599 0.659712,3.266877 0.790437,5.175744 0.123255,2.95997 -0.609533,5.703926 -1.602531,8.283354 2.663795,1.189685 5.746102,1.819034 9.171244,1.407629 -0.0028,-0.0039 -0.008,-0.0069 -0.01082,-0.01081 1.249937,-0.23266 2.714166,-0.522072 4.244543,-1.006996 0.05711,-0.01808 0.11595,-0.03549 0.173247,-0.05414 0.0423,-0.01549 0.08754,-0.02748 0.129934,-0.04331 1.088343,-0.406433 2.203448,-0.925154 3.345826,-1.559219 0.344956,-0.158989 0.684085,-0.337817 1.006997,-0.530568 0.01497,-0.01 0.02837,-0.02248 0.04331,-0.03247 1.151775,-0.771543 2.262089,-1.730498 3.27003,-2.945192 0.046,-0.05864 0.09558,-0.113755 0.140764,-0.173247 0.06078,-0.07543 0.113265,-0.160884 0.173246,-0.238214 0.498272,-0.684328 0.946924,-1.422532 1.342662,-2.198067 0.07147,-0.854352 0.106109,-1.736191 0.108279,-2.652839 0.427637,-5.520658 -2.662018,-10.834077 -7.070626,-14.866733 z"
+ id="path3066-72-8-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ff0000;stroke:#000000;stroke-width:0.08696981;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 25.656115,38.344237 c -5.855303,-9.370125 -1.158406,-15.462208 3.748139,-19.940578 2.41378,3.76265 3.040258,9.396741 9.095449,12.622254 -2.656377,3.396352 -5.029672,5.491257 -12.843588,7.318324 z"
+ id="path3917-0-1"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+</svg>
diff --git a/base.py b/base.py
new file mode 100644
index 0000000..2737881
--- /dev/null
+++ b/base.py
@@ -0,0 +1,40 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Autor: Flavio Danesse - fdanesse@activitycentral.com
+'''
+La idea es hacer una aplicación que sea capaz de mostrar todos los mensajes, no importa su prioridad.
+La aplicación se llevará a cabo tanto en el azúcar y el Gnome y debe ser capaz de:
+- Muestra todos los mensajes activos
+- Filtrar y ordenar los mensajes por prioridad, fecha o tipo de mensajes'''
+
+import shelve, sqlite3, time, datetime, os
+from store import *
+
+# Archivo notificaciones # http://docs.python.org/library/shelve.html
+filename = os.path.join('/tmp', 'notify_0')
+d = shelve.open(filename)
+d['id'] = 0
+d['title'] = "Prueba Titulo"
+d['text'] = "Prueba Texto"
+d['priority'] = 1
+d['launched'] = datetime.date(1972, 6, 21)
+d['expires'] = datetime.date(2012, 6, 21)
+d['type'] = "Prueba tipo"
+d.close()
+
+filename = os.path.join('/tmp', 'notify_1')
+d = shelve.open(filename)
+d['id'] = 1
+d['title'] = "Prueba Titulo1"
+d['text'] = "Prueba Texto1"
+d['priority'] = 1
+d['launched'] = datetime.date(1972, 6, 21)
+d['expires'] = datetime.date(2013, 6, 21)
+d['type'] = "Prueba tipo1"
+d.close()
+
+store = Store(db_filename="prueba.db")
+mensaje = store.db.get_messages([])
+print mensaje
+
diff --git a/prueba.db b/prueba.db
new file mode 100644
index 0000000..7df1365
--- /dev/null
+++ b/prueba.db
Binary files differ
diff --git a/store.py b/store.py
new file mode 100644
index 0000000..6c271b2
--- /dev/null
+++ b/store.py
@@ -0,0 +1,161 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# 2011-12-16
+# Autor: Esteban Bordón - ebordon@plan.ceibal.edu.uy
+#
+# Guarda los mensajes obtenidos desde el servidor
+# Actualmente se guardan en una base de datos sqlite3
+# y los archivos vienen en shelve
+
+import sqlite3
+import os
+import datetime
+import shelve
+#from ceibal.notifier import env
+# for future releases
+#from xml.dom import minidom
+
+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 ''); """
+ if db_filename:
+ self._db_filename = db_filename
+ else:
+ 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):
+ 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.text_factory = str
+ return conn
+
+ def _close_connection(self, conn):
+ conn.close()
+
+ def add_message(self, keys, values):
+ con = self._connect()
+ c = con.cursor()
+ c.execute('BEGIN TRANSACTION')
+ try:
+ c.execute('insert into notifications(%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)
+
+ def run_query(self, query):
+ con = self._connect()
+ con.row_factory = self.dict_factory
+ c = con.cursor()
+ c.execute('BEGIN TRANSACTION')
+ c.execute(query)
+ output = c.fetchall()
+ c.execute('END TRANSACTION')
+ self._close_connection(con)
+ return output
+
+ def get_messages(self, args):
+ con = self._connect()
+ con.row_factory = self.dict_factory
+ filters = ''
+ if args:
+ filters = 'where '
+ while args:
+ clave,valor = args.popitem()
+ filters+=clave+' '+str(valor)
+ filters+=' and ' if args else ''
+ c = con.cursor()
+ c.execute('BEGIN TRANSACTION')
+ c.execute('SELECT title, text, type, launched, expires FROM notifications %s order by priority desc;' %filters)
+ output = c.fetchall()
+ c.execute('END TRANSACTION')
+ self._close_connection(con)
+ return output
+
+ """
+ def get_msg_by_priority(self, priority):
+ con = self._connect()
+ con.row_factory = self.dict_factory
+ c = con.cursor()
+ c.execute('BEGIN TRANSACTION')
+ c.execute('select * from notifications where prority=%d' %priority)
+ output = c.fetchall()
+ c.execute('END TRANSACTION')
+ self._close_connection(con)
+ return output
+ """
+
+class Store:
+ def __init__(self, xmlpath=None, db_filename=None):
+ 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
+ self.db.run_query(query)
+ # Implementado para futuras versiones
+ """
+ if not xmlpath:
+ xmlpath = os.path.join(env.get_data_root(),"mensajes.xml")
+ fsock = open(xmlpath)
+ self.xmldoc = minidom.parse(fsock)
+ 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/
+ # 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))
+ self.msg_list = {}
+ #msg_items = ['id', 'title', 'text', 'launched', 'expired', 'priority',]
+ for file in files:
+ abspath = os.path.join(xmlpath,file)
+ try:
+ f = shelve.open(abspath)
+ self._save_message(f)
+ f.close()
+ os.remove(abspath)
+ 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"]
+ keys = msg.keys()
+ values = []
+ for item in keys:
+ values.append(str(msg[item]))
+ self.db.add_message(keys, values)
+
+ 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")
+ refNode = msg.childNodes
+ keys = ["id","type","priority"]
+ values = []
+ 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)
+ keys.append(node.localName)
+ values.append(node.firstChild.wholeText.strip())
+ self.db.add_message(keys, values)
+
+
+if __name__ == "__main__":
+ #db_filename = '../data/messages.db'
+ #xmlpath = "../data/mensajes.xml"
+ notification = Store()