| 1 | # -*- coding: utf-8 -*- |
|---|
| 2 | |
|---|
| 3 | # Promogest |
|---|
| 4 | # |
|---|
| 5 | # Copyright (C) 2005 by Promotux Informatica - http://www.promotux.it/ |
|---|
| 6 | |
|---|
| 7 | import gtk |
|---|
| 8 | import threading |
|---|
| 9 | import webbrowser |
|---|
| 10 | |
|---|
| 11 | from GladeWidget import GladeWidget |
|---|
| 12 | from promogest import Environment |
|---|
| 13 | import promogest.dao.Promemoria |
|---|
| 14 | from promogest.dao.Promemoria import Promemoria |
|---|
| 15 | from promogest.lib import feedparser |
|---|
| 16 | from utils import * |
|---|
| 17 | from promogest.ui.SendEmail import SendEmail |
|---|
| 18 | from promogest.lib.HtmlHandler import createHtmlObj, renderTemplate, renderHTML |
|---|
| 19 | |
|---|
| 20 | class VistaPrincipale(GladeWidget): |
|---|
| 21 | """ |
|---|
| 22 | Frame Principale di visualizzazione principale da costruire all'uscita di ogni anagrafica |
|---|
| 23 | alla chiamata del metodo _refresh() con update dei promemoria in scadenza. |
|---|
| 24 | """ |
|---|
| 25 | |
|---|
| 26 | def __init__(self, mainWindow, azs=None): |
|---|
| 27 | GladeWidget.__init__(self, 'vista_principale_frame', fileName='_main_window_view_select.glade') |
|---|
| 28 | #self.cancel_alarm_button.set_sensitive(False) |
|---|
| 29 | #self.alarm_notify_treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE) |
|---|
| 30 | self._loading=None |
|---|
| 31 | self.html = createHtmlObj(self) |
|---|
| 32 | self.feed_scrolled.add(self.html) |
|---|
| 33 | html = """<html><body></body></html>""" |
|---|
| 34 | renderHTML(self.html,html) |
|---|
| 35 | self.draw() |
|---|
| 36 | # self.getfeedFromSite() |
|---|
| 37 | |
|---|
| 38 | def draw(self): |
|---|
| 39 | """ |
|---|
| 40 | disegna questo frame nella finestra principale |
|---|
| 41 | """ |
|---|
| 42 | treeview = self.alarm_notify_treeview |
|---|
| 43 | renderer = gtk.CellRendererText() |
|---|
| 44 | rendererCtr = gtk.CellRendererText() |
|---|
| 45 | rendererCtr.set_property('xalign', 0.5) |
|---|
| 46 | |
|---|
| 47 | column = gtk.TreeViewColumn('Data Scadenza', rendererCtr, text=1) |
|---|
| 48 | column.set_sizing(gtk.TREE_VIEW_COLUMN_GROW_ONLY) |
|---|
| 49 | column.set_clickable(True) |
|---|
| 50 | column.set_resizable(True) |
|---|
| 51 | column.set_expand(False) |
|---|
| 52 | column.set_min_width(120) |
|---|
| 53 | treeview.append_column(column) |
|---|
| 54 | |
|---|
| 55 | column = gtk.TreeViewColumn('Oggetto', renderer, text=2) |
|---|
| 56 | column.set_sizing(gtk.TREE_VIEW_COLUMN_GROW_ONLY) |
|---|
| 57 | column.set_clickable(True) |
|---|
| 58 | column.set_resizable(True) |
|---|
| 59 | column.set_expand(False) |
|---|
| 60 | column.set_min_width(150) |
|---|
| 61 | treeview.append_column(column) |
|---|
| 62 | |
|---|
| 63 | column = gtk.TreeViewColumn('Descrizione', renderer, text=3) |
|---|
| 64 | column.set_sizing(gtk.TREE_VIEW_COLUMN_GROW_ONLY) |
|---|
| 65 | column.set_clickable(True) |
|---|
| 66 | column.set_resizable(True) |
|---|
| 67 | column.set_expand(False) |
|---|
| 68 | column.set_min_width(150) |
|---|
| 69 | treeview.append_column(column) |
|---|
| 70 | |
|---|
| 71 | column = gtk.TreeViewColumn('Incaricato', rendererCtr, text=4) |
|---|
| 72 | column.set_sizing(gtk.TREE_VIEW_COLUMN_GROW_ONLY) |
|---|
| 73 | column.set_clickable(True) |
|---|
| 74 | column.set_resizable(True) |
|---|
| 75 | column.set_expand(False) |
|---|
| 76 | column.set_min_width(100) |
|---|
| 77 | treeview.append_column(column) |
|---|
| 78 | |
|---|
| 79 | column = gtk.TreeViewColumn('Autore', rendererCtr, text=5) |
|---|
| 80 | column.set_sizing(gtk.TREE_VIEW_COLUMN_GROW_ONLY) |
|---|
| 81 | column.set_clickable(True) |
|---|
| 82 | column.set_resizable(True) |
|---|
| 83 | column.set_expand(False) |
|---|
| 84 | column.set_min_width(100) |
|---|
| 85 | treeview.append_column(column) |
|---|
| 86 | |
|---|
| 87 | column = gtk.TreeViewColumn('Annotazioni', renderer, text=6) |
|---|
| 88 | column.set_sizing(gtk.TREE_VIEW_COLUMN_GROW_ONLY) |
|---|
| 89 | column.set_clickable(True) |
|---|
| 90 | column.set_resizable(True) |
|---|
| 91 | column.set_expand(False) |
|---|
| 92 | column.set_min_width(200) |
|---|
| 93 | treeview.append_column(column) |
|---|
| 94 | |
|---|
| 95 | model = gtk.ListStore(object, str, str, str, str, str, str) |
|---|
| 96 | treeview.set_model(model) |
|---|
| 97 | |
|---|
| 98 | if Environment.feed == "True": |
|---|
| 99 | feedAll = Environment.feedAll |
|---|
| 100 | feedToHtml = Environment.feedCache |
|---|
| 101 | if feedAll == "": |
|---|
| 102 | Environment.pg2log.debug("LEGGERO RITARDO NEL RECUPERO DEI FEED") |
|---|
| 103 | |
|---|
| 104 | """apro un thread per il recupero dei feed , su piattaforma a 32 bit |
|---|
| 105 | tutto procede per il meglio tanne qualche warning, su 64 bit ci sono |
|---|
| 106 | invece dei crash core dump dovuti ad una asyncronia tra il textbuffer e la texview che |
|---|
| 107 | si ritrova il cursore cambiato senza capire perchÚ |
|---|
| 108 | ho visto che con un join del thread che "ritarda" di un secondo e mezzo |
|---|
| 109 | l'apertura della finestra di main tutto procede per il meglio""" |
|---|
| 110 | thread = threading.Thread(target=self.getfeedFromSite) |
|---|
| 111 | thread.start() |
|---|
| 112 | thread.join(1.3) |
|---|
| 113 | #print "AAAAAAAAAAA", sys.version_info |
|---|
| 114 | #gobject.io_add_watch(self.getfeedFromSite) |
|---|
| 115 | |
|---|
| 116 | #time.sleep(20) |
|---|
| 117 | #thread.stop() |
|---|
| 118 | #gobject.idle_add(self.getfeedFromSite) |
|---|
| 119 | elif feedAll and feedToHtml: |
|---|
| 120 | self.renderPage(feedToHtml) |
|---|
| 121 | else: |
|---|
| 122 | self.getfeedFromSite() |
|---|
| 123 | #gobject.idle_add(self.checkUpdate) |
|---|
| 124 | #thread = threading.Thread(target=self.checkUpdate) |
|---|
| 125 | #thread.start() |
|---|
| 126 | #thread.join(1.3) |
|---|
| 127 | #time.sleep(2) |
|---|
| 128 | #thread.stop() |
|---|
| 129 | self.anno_lavoro_label.set_markup('<b>Anno di lavoro: ' + Environment.workingYear + '</b>') |
|---|
| 130 | self._refresh() |
|---|
| 131 | |
|---|
| 132 | def checkUpdate(self): |
|---|
| 133 | self.rigasvn1 =0 |
|---|
| 134 | self.rigasvn2 =0 |
|---|
| 135 | |
|---|
| 136 | command = 'svn info ~/pg2' |
|---|
| 137 | stdin, stdouterr = os.popen4(command) |
|---|
| 138 | print "INFO REPO LOCALE", stdouterr.read() |
|---|
| 139 | for r in stdouterr.readlines(): |
|---|
| 140 | if "Revision" in str(r): |
|---|
| 141 | self.rigasvn1=r |
|---|
| 142 | commandremote = 'svn info http://svn.promotux.it/svn/promogest2/trunk/' |
|---|
| 143 | stdin, stdouterr = os.popen4(commandremote) |
|---|
| 144 | print "INFO REPO REMOTO",stdouterr.read() |
|---|
| 145 | for line in stdouterr.readlines(): |
|---|
| 146 | if "Revision" in str(line): |
|---|
| 147 | self.rigasvn2=r |
|---|
| 148 | if self.rigasvn1 == self.rigasvn2: |
|---|
| 149 | print "aggiornamento da fare" |
|---|
| 150 | msg ="""ATTENZIONE!! |
|---|
| 151 | Andate nella sezione "opzioni" ed aggiornare l'applicazione. |
|---|
| 152 | E' presente una nuova versione disponibile""" |
|---|
| 153 | dialog = gtk.MessageDialog(None, |
|---|
| 154 | gtk.DIALOG_MODAL |
|---|
| 155 | | gtk.DIALOG_DESTROY_WITH_PARENT, |
|---|
| 156 | gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, |
|---|
| 157 | "pippo") |
|---|
| 158 | response = dialog.run() |
|---|
| 159 | #dialog.destroy() |
|---|
| 160 | dialog.hide() |
|---|
| 161 | #return False |
|---|
| 162 | else: |
|---|
| 163 | print "NON CI SONO NUOVE VERSIONI DEL PROMOGEST2 DISPONIBILI" |
|---|
| 164 | #return False |
|---|
| 165 | gobject.source_remove(self.__a) |
|---|
| 166 | |
|---|
| 167 | def _refresh(self): |
|---|
| 168 | """ |
|---|
| 169 | aggiorna la treeview con i promemoria che hanno uno stato "in_scadenza" |
|---|
| 170 | """ |
|---|
| 171 | self._loading=True |
|---|
| 172 | #clear the treeview |
|---|
| 173 | model = self.alarm_notify_treeview.get_model() |
|---|
| 174 | model.clear() |
|---|
| 175 | #get the current alarms from db |
|---|
| 176 | idAllarmi = promogest.dao.Promemoria.getScadenze() |
|---|
| 177 | #fill again the model of the treeview (a gtk.ListStore) |
|---|
| 178 | for idAllarme in idAllarmi: |
|---|
| 179 | dao = Promemoria().getRecord(id=idAllarme) |
|---|
| 180 | model.append((dao, dateToString(dao.data_scadenza), |
|---|
| 181 | dao.oggetto, |
|---|
| 182 | dao.descrizione, |
|---|
| 183 | dao.incaricato, |
|---|
| 184 | dao.autore, |
|---|
| 185 | dao.annotazione)) |
|---|
| 186 | self._loading=False |
|---|
| 187 | #self.checkUpdate() |
|---|
| 188 | #self.__a = gobject.idle_add(self.checkUpdate) |
|---|
| 189 | |
|---|
| 190 | |
|---|
| 191 | def show_all(self): |
|---|
| 192 | """ Visualizza/aggiorna tutta la struttura del frame """ |
|---|
| 193 | self.vista_principale_frame.show_all() |
|---|
| 194 | |
|---|
| 195 | def on_cancel_alarm_button_clicked(self, button): |
|---|
| 196 | """ |
|---|
| 197 | viene(vengono) eliminato(i) l'allarme(i) selezionato(i) nella treeview |
|---|
| 198 | """ |
|---|
| 199 | count = self.alarm_notify_treeview.get_selection().count_selected_rows() |
|---|
| 200 | dialog = gtk.MessageDialog(None, |
|---|
| 201 | gtk.DIALOG_MODAL |
|---|
| 202 | | gtk.DIALOG_DESTROY_WITH_PARENT, |
|---|
| 203 | gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, |
|---|
| 204 | 'Sono stati selezionati '+str(count)+' allarmi.\nConfermi l\'eliminazione?') |
|---|
| 205 | |
|---|
| 206 | response = dialog.run() |
|---|
| 207 | dialog.destroy() |
|---|
| 208 | if response == gtk.RESPONSE_YES: |
|---|
| 209 | (model, indexes)= self.alarm_notify_treeview.get_selection().get_selected_rows() |
|---|
| 210 | rows = [] |
|---|
| 211 | for index in indexes: |
|---|
| 212 | iter = model.get_iter(index) |
|---|
| 213 | dao = model.get(iter,0)[0] |
|---|
| 214 | dao.delete() |
|---|
| 215 | model.remove(iter) |
|---|
| 216 | else: |
|---|
| 217 | return |
|---|
| 218 | |
|---|
| 219 | def on_snooze_alarm_button_clicked(self, button): |
|---|
| 220 | (model, indexes)= self.alarm_notify_treeview.get_selection().get_selected_rows() |
|---|
| 221 | rows = [] |
|---|
| 222 | for index in indexes: |
|---|
| 223 | iter = model.get_iter(index) |
|---|
| 224 | dao = model.get(iter,0)[0] |
|---|
| 225 | dao.giorni_preavviso += 1 |
|---|
| 226 | dao.in_scadenza = False |
|---|
| 227 | dao.persist() |
|---|
| 228 | model.remove(iter) |
|---|
| 229 | |
|---|
| 230 | def on_alarm_notify_treeview_cursor_changed(self,treeview): |
|---|
| 231 | if self._loading: |
|---|
| 232 | return |
|---|
| 233 | self.cancel_alarm_button.set_sensitive(True) |
|---|
| 234 | |
|---|
| 235 | def renderPage(self, feedToHtml): |
|---|
| 236 | """ show the html page in the custom widget""" |
|---|
| 237 | pageData = {} |
|---|
| 238 | pageData = { |
|---|
| 239 | "file" :"feed.html", |
|---|
| 240 | "feed" :feedToHtml, |
|---|
| 241 | } |
|---|
| 242 | html = renderTemplate(pageData) |
|---|
| 243 | renderHTML(self.html,html) |
|---|
| 244 | |
|---|
| 245 | def getfeedFromSite(self): |
|---|
| 246 | string = "" |
|---|
| 247 | if Environment.feedAll == "": |
|---|
| 248 | d = feedparser.parse("http://blog.promotux.it/category/promogest/feed") |
|---|
| 249 | else: |
|---|
| 250 | d = Environment.feedAll |
|---|
| 251 | feedList = d['entries'] |
|---|
| 252 | feedToHtml = [] |
|---|
| 253 | for feed in feedList[:-1]: |
|---|
| 254 | try: |
|---|
| 255 | body = feed['content'][0]['value'] |
|---|
| 256 | except: |
|---|
| 257 | body = feed["summary_detail"]['value'] |
|---|
| 258 | feed = { |
|---|
| 259 | "title" :feed['title'], |
|---|
| 260 | "links": feed['links'][0]['href'], |
|---|
| 261 | "body" : body, |
|---|
| 262 | "updated" : feed['updated'][4:-14], |
|---|
| 263 | "autore" : feed['author'] |
|---|
| 264 | } |
|---|
| 265 | feedToHtml.append(feed) |
|---|
| 266 | Environment.feedCache = feedToHtml |
|---|
| 267 | self.renderPage(feedToHtml) |
|---|
| 268 | |
|---|
| 269 | def on_promotux_button_clicked(self, button): |
|---|
| 270 | url ="http://www.promotux.it" |
|---|
| 271 | webbrowser.open_new_tab(url) |
|---|
| 272 | |
|---|
| 273 | def on_promogest_button_clicked(self, button): |
|---|
| 274 | from promogest.dao.TestataDocumento import TestataDocumento |
|---|
| 275 | daos = TestataDocumento().select(batchSize=1000) |
|---|
| 276 | if daos: |
|---|
| 277 | for d in daos: |
|---|
| 278 | print d |
|---|
| 279 | # d.delete() |
|---|
| 280 | Environment.session.delete(d) |
|---|
| 281 | Environment.session.commit() |
|---|
| 282 | print "FINITA QUESTA TRANCE da 1000" |
|---|
| 283 | else: |
|---|
| 284 | print "FINITTIIIIIIWW" |
|---|
| 285 | |
|---|
| 286 | |
|---|
| 287 | # print daos |
|---|
| 288 | return |
|---|
| 289 | # from promogest.dao.Inventario import Inventario |
|---|
| 290 | # daos = Inventario().select(idMagazzino=3, batchSize=None) |
|---|
| 291 | # for d in daos: |
|---|
| 292 | # print d.id |
|---|
| 293 | # d.delete() |
|---|
| 294 | # Environment.session.delete(d) |
|---|
| 295 | # Environment.session.commit() |
|---|
| 296 | # url ="http://onebip.com/otms/?item=9855" |
|---|
| 297 | # webbrowser.open_new_tab(url) |
|---|
| 298 | |
|---|
| 299 | def on_numero_verde_button_clicked(self, button): |
|---|
| 300 | sendemail = SendEmail() |
|---|
| 301 | |
|---|
| 302 | def on_rivenditore_button_clicked(self, button): |
|---|
| 303 | url = Environment.rivenditoreUrl |
|---|
| 304 | webbrowser.open_new_tab(url) |
|---|