|
| 1 | +# |
1 | 2 | # Gramps - a GTK+/GNOME based genealogy program
|
2 | 3 | #
|
3 | 4 | # Copyright (C) 2010 Peter Potrowl <[email protected]>
|
| 5 | +# Copyright (C) 2019 Matthias Kemmer <[email protected]> |
4 | 6 | #
|
5 | 7 | # This program is free software; you can redistribute it and/or modify
|
6 | 8 | # it under the terms of the GNU General Public License as published by
|
|
15 | 17 | # You should have received a copy of the GNU General Public License
|
16 | 18 | # along with this program; if not, write to the Free Software
|
17 | 19 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
| 20 | +# |
18 | 21 |
|
19 | 22 | from gramps.gen.plug import Gramplet
|
20 | 23 | from gramps.gen.const import GRAMPS_LOCALE as glocale
|
| 24 | +from gramps.gen.display.name import displayer as name_displayer |
| 25 | +from gramps.gen.lib.date import Today, Date |
| 26 | +import gramps.gen.datehandler |
| 27 | +from gramps.gen.config import config |
| 28 | +from gramps.gen.plug.menu import EnumeratedListOption |
21 | 29 | try:
|
22 | 30 | _trans = glocale.get_addon_translator(__file__)
|
23 | 31 | except ValueError:
|
24 | 32 | _trans = glocale.translation
|
25 | 33 | _ = _trans.gettext
|
26 | 34 |
|
27 |
| -from gramps.gen.display.name import displayer as name_displayer |
28 |
| -from gramps.gen.lib.date import Today, Date |
29 |
| -import gramps.gen.datehandler |
30 |
| -import time |
31 |
| -import datetime |
32 |
| -import posixpath |
33 |
| -from gramps.gen.config import config |
34 |
| - |
35 |
| -""" |
36 |
| -This Gramplet displays the incoming birthdays. |
37 |
| -""" |
38 | 35 |
|
39 | 36 | class BirthdaysGramplet(Gramplet):
|
40 | 37 | def init(self):
|
41 | 38 | self.set_text(_("No Family Tree loaded."))
|
42 | 39 | self.max_age = config.get('behavior.max-age-prob-alive')
|
43 | 40 |
|
| 41 | + def build_options(self): |
| 42 | + """Build the configuration options""" |
| 43 | + db = self.dbstate.db |
| 44 | + |
| 45 | + name = _("Ignore birthdays with tag") |
| 46 | + self.option = EnumeratedListOption(name, self.ignore_tag) |
| 47 | + |
| 48 | + self.option.add_item('', '') # No ignore tag |
| 49 | + if db.is_open(): |
| 50 | + for tag_handle in db.get_tag_handles(sort_handles=True): |
| 51 | + tag = db.get_tag_from_handle(tag_handle) |
| 52 | + tag_name = tag.get_name() |
| 53 | + self.option.add_item(tag_name, tag_name) |
| 54 | + |
| 55 | + self.add_option(self.option) |
| 56 | + |
| 57 | + def save_options(self): |
| 58 | + """Save gramplet configuration data""" |
| 59 | + self.ignore_tag = self.option.get_value() |
| 60 | + |
| 61 | + def save_update_options(self, obj): |
| 62 | + """Save a gramplet's options to file""" |
| 63 | + self.save_options() |
| 64 | + self.gui.data = [self.ignore_tag] |
| 65 | + self.update() |
| 66 | + |
| 67 | + def on_load(self): |
| 68 | + """Load stored configuration data""" |
| 69 | + if len(self.gui.data) == 1: |
| 70 | + self.ignore_tag = self.gui.data[0] |
| 71 | + else: |
| 72 | + self.ignore_tag = '' |
| 73 | + |
44 | 74 | def db_changed(self):
|
| 75 | + """Update gramplet when database was changed""" |
45 | 76 | self.connect(self.dbstate.db, 'person-add', self.update)
|
46 | 77 | self.connect(self.dbstate.db, 'person-delete', self.update)
|
47 | 78 | self.connect(self.dbstate.db, 'person-update', self.update)
|
48 | 79 |
|
49 | 80 | def main(self):
|
| 81 | + """Main function of the Birthdays gramplet""" |
50 | 82 | self.set_text(_("Processing..."))
|
51 | 83 | database = self.dbstate.db
|
52 | 84 | personList = database.iter_people()
|
53 |
| - result = [] |
54 |
| - text = '' |
55 |
| - today = Today() |
| 85 | + self.result = [] |
| 86 | + |
| 87 | + # get ignore tag handle |
| 88 | + ignore_tag_handle = "" # No ignore handle selceted by user |
| 89 | + tag_name = self.option.get_value() |
| 90 | + tag_handles = database.get_tag_handles() |
| 91 | + for handle in tag_handles: |
| 92 | + tag = database.get_tag_from_handle(handle) |
| 93 | + if tag_name == tag.get_name(): |
| 94 | + # overwrite ignore_handle to user selction |
| 95 | + ignore_tag_handle = tag.get_handle() |
| 96 | + |
56 | 97 | for cnt, person in enumerate(personList):
|
57 |
| - birth_ref = person.get_birth_ref() |
58 |
| - death_ref = person.get_death_ref() |
59 |
| - if (birth_ref and not death_ref): |
60 |
| - birth = database.get_event_from_handle(birth_ref.ref) |
61 |
| - birth_date = birth.get_date_object() |
62 |
| - if birth_date.is_regular(): |
63 |
| - birthday_this_year = Date(today.get_year(), birth_date.get_month(), birth_date.get_day()) |
64 |
| - next_age = birthday_this_year - birth_date |
65 |
| - # (0 year, months, days) between now and birthday of this year (positive if passed): |
66 |
| - diff = today - birthday_this_year |
67 |
| - # about number of days the diff is: |
68 |
| - diff_days = diff[1] * 30 + diff[2] |
69 |
| - if next_age[0] < self.max_age: |
70 |
| - if diff_days <= 0: #not yet passed |
71 |
| - result.append((diff_days, next_age, birth_date, person)) |
72 |
| - else: #passed; add it for next year's birthday |
73 |
| - result.append((diff_days - 365, next_age[0] + 1, birth_date, person)) |
| 98 | + person_tag_handles = person.get_tag_list() |
| 99 | + if ignore_tag_handle in person_tag_handles: |
| 100 | + pass # ignore person |
| 101 | + else: # calculate age and days until birthday: |
| 102 | + self.__calculate(database, person) |
| 103 | + |
74 | 104 | # Reverse sort on number of days from now:
|
75 |
| - result.sort(key=lambda item: -item[0]) |
| 105 | + self.result.sort(key=lambda item: -item[0]) |
76 | 106 | self.clear_text()
|
77 |
| - for diff, age, date, person in result: |
| 107 | + |
| 108 | + # handle text shown in gramplet |
| 109 | + for diff, age, date, person in self.result: |
78 | 110 | name = person.get_primary_name()
|
79 |
| - self.append_text("%s: " % gramps.gen.datehandler.displayer.display(date)) |
80 |
| - self.link(name_displayer.display_name(name), "Person", person.handle) |
81 |
| - self.append_text(" (%s)\n" % age) |
| 111 | + displayer = gramps.gen.datehandler.displayer |
| 112 | + self.append_text("{}: ".format(displayer.display(date))) |
| 113 | + self.link(name_displayer.display_name(name), "Person", |
| 114 | + person.handle) |
| 115 | + self.append_text(" ({})\n".format(age)) |
82 | 116 | self.append_text("", scroll_to="begin")
|
| 117 | + |
| 118 | + def __calculate(self, database, person): |
| 119 | + """Calculate the age and days until birthday""" |
| 120 | + today = Today() |
| 121 | + birth_ref = person.get_birth_ref() |
| 122 | + death_ref = person.get_death_ref() |
| 123 | + if (birth_ref and not death_ref): |
| 124 | + birth = database.get_event_from_handle(birth_ref.ref) |
| 125 | + birth_date = birth.get_date_object() |
| 126 | + if birth_date.is_regular(): |
| 127 | + birthday_this_year = Date(today.get_year(), |
| 128 | + birth_date.get_month(), |
| 129 | + birth_date.get_day()) |
| 130 | + next_age = birthday_this_year - birth_date |
| 131 | + # (0 year, months, days) between now and birthday of this |
| 132 | + # year (positive if passed): |
| 133 | + diff = today - birthday_this_year |
| 134 | + # about number of days the diff is: |
| 135 | + diff_days = diff[1] * 30 + diff[2] |
| 136 | + if next_age[0] < self.max_age: |
| 137 | + if diff_days <= 0: # not yet passed |
| 138 | + self.result.append((diff_days, next_age, birth_date, |
| 139 | + person)) |
| 140 | + else: # passed; add it for next year's birthday |
| 141 | + self.result.append((diff_days - 365, |
| 142 | + next_age[0] + 1, |
| 143 | + birth_date, person)) |
0 commit comments