plugin.py 4.51 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# This file is part of Birthday Reminder.
#
# Birthday Reminder is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published
# by the Free Software Foundation; version 3 only.
#
# Birthday Reminder is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Birthday Reminder.  If not, see <http://www.gnu.org/licenses/>.

15
import os
16
import json
17
import datetime
18 19 20
import logging

from gi.repository import GLib
21

22 23 24
from gajim.common import configpaths
from gajim.common import app
from gajim.common import ged
25

26 27 28
from gajim.plugins import GajimPlugin
from gajim.plugins.plugins_i18n import _

29

30
log = logging.getLogger('gajim.plugin_system.birthday')
31

32 33
TITLE = _('%s has birthday today')
TEXT = _('Send him a message')
34 35


36 37
class BirthDayPlugin(GajimPlugin):
    def init(self):
38 39
        self.config_dialog = None
        self.description = ('Birthday reminder plugin')
40
        self.events_handlers = {
41
            'vcard-received': (ged.GUI2, self._vcard_received)}
42

43
        self._timeout_id = None
44
        self._timeout_id_start = None
45

46
        self.showed_accounts = []
47

48 49
        self._birthdays = {}
        self._load_birthdays()
50

51 52 53 54 55
    def activate(self):
        self._timeout_id_start = GLib.timeout_add_seconds(
            5, self._check_birthdays_at_start)
        self._timeout_id = GLib.timeout_add_seconds(
            86400, self._check_birthdays)
56

57 58
    def deactivate(self):
        if self._timeout_id is not None:
59
            GLib.source_remove(self._timeout_id)
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
        if self._timeout_id_start is not None:
            GLib.source_remove(self._timeout_id_start)

    def _load_birthdays(self):
        path = os.path.join(configpaths.get('MY_DATA'), 'birthdays.json')
        if os.path.exists(path):
            with open(path, 'r', encoding='utf-8') as file:
                content = file.read()
                if content:
                    self._birthdays = json.loads(content)

    def _store_birthdays(self):
        path = os.path.join(configpaths.get('MY_DATA'), 'birthdays.json')
        with open(path, 'w', encoding='utf-8') as file:
            json.dump(self._birthdays, file)

    def _vcard_received(self, event):
        birthday = event.vcard_dict.get('BDAY')
        if not birthday:
            if event.jid in self._birthdays:
                del self._birthdays[event.jid]
                log.info('Received empty birthday: %s', event.jid)
        else:
83
            try:
84 85 86 87 88 89 90 91
                year, month, day = birthday.split('-')
                year = int(year)
                month = int(month)
                day = int(day)
            except Exception:
                log.warning('Invalid date: %s', birthday)
                if event.jid in self._birthdays:
                    del self._birthdays[event.jid]
92
            else:
93 94 95 96
                self._birthdays[event.jid] = (year, month, day)
                log.info('Received birthday: %s %s',
                         event.jid, (year, month, day))
        self._store_birthdays()
97

98 99
    def _check_birthdays_at_start(self):
        self._check_birthdays()
100

101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
    def _check_birthdays(self):
        log.info('Check birthdays...')
        today = datetime.date.today()
        for jid, birthdate in self._birthdays.items():
            year, month, day = birthdate
            if today.month == month and today.day == day:
                account, contact = self._find_contact(jid)
                if contact is None:
                    if jid in self._birthdays:
                        del self._birthdays[jid]
                        self._store_birthdays()
                        continue
                else:
                    log.info('Issue notification for %s', jid)
                    nick = contact.get_shown_name() or jid
                    app.notification.popup(
                        'reminder',
                        jid,
                        account,
                        icon_name='trophy-gold',
                        title=TITLE % GLib.markup_escape_text(nick),
                        text=TEXT)
123

124
        return True
125

126 127
    @staticmethod
    def _find_contact(jid):
128 129 130 131 132
        accounts = app.contacts.get_accounts()
        for account in accounts:
            contact = app.contacts.get_contacts(account, jid)
            if contact is not None:
                return account, contact[0]