El progtwig Python con Notificación en Gnome Shell no funciona

Estoy escribiendo un progtwig de python que toma información de una página web y la muestro en Notificación en Gnome Shell. Estoy usando Arch, así que quiero iniciar este progtwig al inicio y si hay algún cambio en la página web, me lo notificará. Aquí está mi código:

import time import webbrowser import requests from bs4 import BeautifulSoup from gi.repository import Notify, GLib IPS = {'Mobifone': True, 'Viettel': False, 'Vinaphone': False} LINK = "https://id.vtc.vn/tin-tuc/chuyen-muc-49/tin-khuyen-mai.html" def set_ips_state(ips_name, state): global IPS for key in IPS.iterkeys(): if key == ips_name: IPS[key] = state def call_webbrowser(notification, action_name, link): webbrowser.get('firefox').open_new_tab(link) def create_notify(summary, body, link): Notify.init("Offer") noti = Notify.Notification.new(summary, body, 'dialog-information') noti.add_action('action_click', 'Read more...', call_webbrowser, link) noti.show() # GLib.MainLoop().run() def save_to_file(path_to_file, string): file = open(path_to_file, 'w') file.write(string) file.close() def main(): global IPS global LINK result = [] offer_news = open('offer_news.txt') tag_in_file = BeautifulSoup(offer_news.readline(), 'html.parser') tag = tag_in_file.a offer_news.close() page = requests.get(LINK) soup = BeautifulSoup(page.text, 'html.parser') for div in soup.find_all('div', 'tt_dong1'): # first_a = div.a # main_content = first_a.find_next_subling('a') main_content = div.find_all('a')[1] for k, v in IPS.iteritems(): if v: if main_content.text.find(k) != -1: result.append(main_content) print result[1].encode('utf-8') if tag_in_file == '': pass else: try: old_news_index = result.index(tag) print old_news_index for idx in range(old_news_index): create_notify('Offer News', result[idx].text.encode('utf-8'), result[idx].get('href')) print "I'm here" except ValueError: pass offer_news = open('offer_news.txt', 'w') offer_news.write(result[0].__str__()) offer_news.close() if __name__ == '__main__': while 1: main() time.sleep(10) 

El problema es cuando hago clic en el botón “Leer más …” en la Notificación, no abre Firefox a menos que descomente GLib.MainLoop().run() en la función create_notify, pero eso hace que el progtwig se congele. ¿Alguien podría ayudar?

Las aplicaciones GUI usualmente usan tres componentes principales: widgets, bucles de eventos y devoluciones de llamada. Cuando inicia esa aplicación, crea widgets, registra devoluciones de llamada e inicia el bucle de eventos. El bucle de eventos es un bucle infinito que busca los eventos de los widgets (como ‘botón de clic’) y activa las devoluciones de llamada correspondientes.

Ahora, en tu aplicación tienes otro bucle infinito, por lo que estos dos no funcionarán. En su lugar, debe hacer uso de GLib.MainLoop().run() para GLib.MainLoop().run() eventos. Puede usar GLib.timeout_add_seconds para disparar eventos periódicos como el suyo cada 10 segundos.

El segundo problema es que necesita mantener la referencia a una notificación que se supone que llama a las devoluciones de llamada. La razón por la que funcionó cuando agregó GLib.MainLoop().run() después de noti.show() es que todavía existe una referencia a noti , pero no funcionaría si hiciera los cambios como sugerí anteriormente. Si está seguro de que siempre habrá una sola notificación activa, puede mantener la referencia a la última notificación. De lo contrario, necesitaría una lista y la purgaría periódicamente o algo por el estilo.

El siguiente ejemplo debería ponerte en la dirección correcta:

 from gi.repository import GLib, Notify class App(): def __init__(self): self.last_notification = None Notify.init('Test') self.check() def check(self): self.last_notification = Notify.Notification.new('Test') self.last_notification.add_action('clicked', 'Action', self.notification_callback, None) self.last_notification.show() GLib.timeout_add_seconds(10, self.check) def notification_callback(self, notification, action_name, data): print(action_name) app = App() GLib.MainLoop().run()