Example #1
0
 def add_contacts(self, *nodes, **kwargs):
     context = kwargs.pop("context", None)
     if kwargs:
         raise TypeError("%r is ann invalid keyword argument for this function" % next(iter(kwargs.keys())))
     contacts = []
     for node in filter(bool, nodes):
         for typ in (Has_postal_address, Has_mobile, Has_fixed, Has_fax, Has_email):
             for link in node.links(outgoing & is_link(typ)):
                 self._is_not_empty()
                 label = ""
                 if isinstance(link, Has_postal_address):
                     self.add_address(link, link.postal)
                 elif isinstance(link, Has_email):
                     bullet = EMAIL_BULLET
                     cnode = link.email
                     contact = escape_xml(str(cnode).replace(" ", NBSP))
                     if isinstance(link, At_work):
                         if context != At_work:
                             label = str(qual_work).capitalize()
                     elif isinstance(link, At_home):
                         if context != At_home:
                             label = str(qual_home).capitalize()
                     if label:
                         label = "<i>" + label + "</i>"
                 else:
                     bullet = TELEPHONE_BULLET
                     cnode = link.tel
                     contact = "<b>" + escape_xml(str(link.tel.relative(self.local))) + "</b>"
                     if isinstance(link, Has_fixed):
                         if isinstance(link, At_work):
                             label = str(qual_work).capitalize()
                         elif isinstance(link, At_home):
                             label = str(qual_home).capitalize()
                         else:
                             label = str(multilang(en="Tel", es="Tlf"))
                     else:
                         if isinstance(link, Has_mobile):
                             label = str(multilang(en="Mob", es="Móv"))
                         else:
                             assert isinstance(link, Has_fax)
                             label = "Fax"
                         if isinstance(link, At_work):
                             label += " " + str(qual_work)
                         elif isinstance(link, At_home):
                             label += " " + str(qual_home)
                 comments = []
                 for n in cnode, link:
                     comment = getattr(n, "comment", None)
                     if comment:
                         comments.append(comment)
                 if comments:
                     comments = NBSP + "<i>" + "; ".join(escape_xml(str(c)) for c in comments) + "</i>"
                 else:
                     comments = ""
                 if label:
                     label += ": "
                 label = bullet + " " + label
                 contacts.append((label + contact).replace(" ", NBSP) + comments)
     self._para(" ".join(contacts), contacts_style)
Example #2
0
def dump_person(per, tree, seen=frozenset(), show_family=True, show_work=True,
                show_data=True):
    dump_comments(per, tree)
    if per.birthday():
        tree.add(multilang(en='Birthday', es='F.nac.'))
        tree.add(': ')
        tree.add(per.birthday())
        tree.nl()
    telephones(per, tree)
    dump_email(per, tree)
    dump_postal(per, tree)
    dump_residences(per, tree)
    # Avoid endless recursion in dump_family() and dump_organisation().
    seen = seen | set([per])
    if show_family:
        for link in per.links(outgoing & is_link(Belongs_to)):
            refonly = link.family in seen
            if refonly:
                tree.add('-> ')
                tree.add(next(link.family.sort_keys(tree.sort_mode)))
            else:
                tree.add('-- ')
                add_name(link.family, tree, link)
            tree.nl()
            sub = tree.sub()
            dump_comments(link, sub)
            telephones(link, sub)
            dump_email(link, sub)
            if not refonly:
                dump_family(link.family, sub, seen,
                            show_members=False, show_data=False)
    if show_work:
        for link in per.links(outgoing & is_link(Works_at)):
            refonly = link.org in seen
            if refonly:
                tree.add('-> ')
            else:
                tree.add('-- ')
            if link.position:
                tree.add(link.position, ', ')
            if refonly:
                tree.add(next(link.org.sort_keys(tree.sort_mode)))
            else:
                add_name(link.org, tree, link)
            tree.nl()
            sub = tree.sub()
            dump_comments(link, sub)
            telephones(link, sub)
            dump_email(link, sub)
            dump_postal(link, sub)
            if not refonly:
                dump_organisation(link.org, sub, seen,
                                  show_workers=False, show_data=False)
    if show_data:
        dump_data(per, tree)
Example #3
0
def telephone(link, tree, qual=None, comment=None, bold=False):
    if isinstance(link, Has_mobile):
        tree.add(multilang(en='Mob', es='Móv'))
    elif isinstance(link, Has_fax):
        tree.add('Fax')
    else:
        assert isinstance(link, Has_fixed)
        tree.add(multilang(en='Tel', es='Tlf'))
    if qual:
        tree.add(' ', qual)
    elif isinstance(link, At_work):
        tree.add(' ', qual_work)
    elif isinstance(link, At_home):
        tree.add(' ', qual_home)
    tree.add(': ')
    tree.set_wrapmargin()
    tree.add(link.tel.relative(tree.local), bold=bold)
    wrap_comments(link.tel, tree)
    wrap_comments(link, tree)
    if comment:
        tree.wrap(' -- ', comment)
Example #4
0
 def __init__(self, predicate, refs, local, page_size, sections):
     self.predicate = predicate
     self.refs = refs
     self.local = local
     self.page_size = page_size
     self.sections = sections
     self.section = 0
     best_paper_size = best_paper_margins = None
     best_n = 0
     best_np = None
     for psize, pmarg in [(paper_size, paper_margins), (rotated(paper_size), rotated(paper_margins))]:
         np = [None, None]
         for i in 0, 1:
             np[i] = int((psize[i] - pmarg[i] * 2 + self.gutter) / (self.page_size.size[i] + self.gutter))
         n = np[0] * np[1]
         if n > best_n:
             best_paper_size, best_paper_margins = psize, pmarg
             best_n = n
             best_np = np
     assert best_n >= 1
     assert best_paper_size
     frames = []
     for iy in range(best_np[1]):
         for ix in range(best_np[0]):
             frames.append(
                 CutFrame(
                     x1=best_paper_margins[0] + ix * (self.page_size.size[0] + self.gutter),
                     y1=best_paper_margins[1] + iy * (self.page_size.size[1] + self.gutter),
                     width=self.page_size.size[0],
                     height=self.page_size.size[1],
                     leftPadding=3 * mm + self.page_size.margin_left,
                     rightPadding=3 * mm,
                     topPadding=3 * mm,
                     bottomPadding=3 * mm,
                     showBoundary=True,
                 )
             )
     self.page_width = self.page_size.size[0] - 6 * mm - self.page_size.margin_left
     self.page = PageTemplate(frames=frames)
     self.doc = BookletDoc(
         None,
         initialSection=self.sections[self.section] if self.sections else "A-Z",
         headerLeft=time.strftime(r"%-d %b %Y"),
         headerRight=str(multilang(en="Page", es="Página")) + ' <seq id="page" />',
         pagesize=best_paper_size,
         pageTemplates=[self.page],
         leftMargin=0,
         rightMargin=0,
         topMargin=0,
         bottomMargin=0,
     )
     self.flowables = []
     self._keeptogether_stack = []
Example #5
0
        dump_data(org, tree)
    for link in org.links(outgoing & is_link(Has_department)):
        refonly = link.dept in seen
        if refonly:
            tree.add('-> ')
            tree.add(next(link.dept.sort_keys(tree.sort_mode)))
            tree.nl()
        else:
            dump_names(link.dept, tree, link)
        sub = tree.sub()
        dump_comments(link, sub)
        if not refonly:
            dump_organisation(link.dept, sub, seen, show_workers=show_workers,
                              show_data=show_data)

qual_home = multilang(en='home', es='casa')
qual_work = multilang(en='work', es='trab')

def dump_works_at(org, tree, seen):
    assert org in seen
    for link in sorted(org.links(incoming & is_link(Works_at))):
        refonly = link.person in seen
        if refonly:
            tree.add('-> ')
            tree.add(next(link.person.sort_keys(tree.sort_mode)))
            if link.position:
                tree.add(', ', link.position)
            tree.nl()
        else:
            tree.add('-- ')
            dump_names(link.person, tree, link)
Example #6
0
 def add_person(self, per, link=None, show_family=True, show_work=True):
     self.add_comments(per)
     if per.birthday():
         self._is_not_empty()
         self._para(str(multilang(en="Birthday", es="Fecha nac.")) + ": " + str(per.birthday()), birthday_style)
     self.indent += 1
     self.add_addresses(per)
     self.add_contacts(per, link)
     self.indent -= 1
     if show_family:
         for link in per.links(outgoing & is_link(Belongs_to)):
             # If this person's family has no top level entry, or has a top
             # level reference to this person, then list the family here.
             # Otherwise, just list a reference to the family.
             top = self.refs.get(link.family, per)
             if top is per:
                 self.add_names(link.family.names(), bullet=EM_DASH)
                 self.indent += 1
                 self.add_comments(link)
                 self.add_family(link.family, link, show_members=False)
                 self.indent -= 1
             else:
                 self.add_names(
                     [next(link.family.sort_keys())],
                     bullet=RIGHT_ARROW,
                     bold=False,
                     comments=self.all_comments(link),
                 )
                 self.indent += 2
                 self.add_contacts(link, context=At_home)
                 self.indent -= 2
     if show_work:
         for link in per.links(outgoing & is_link(Works_at)):
             position = ""
             if link.position:
                 self._is_not_empty()
                 position = escape_xml(str(link.position)) + ", "
             # If the organisation/residence where this person works has no
             # top level entry or has a top level reference to this person,
             # then list the organisation/residence here.  Otherwise, just
             # list a reference to its top level entry.
             top = self.refs.get(link.org, per)
             if top is per:
                 if isinstance(link.org, Residence):
                     self.indent += 1
                     self.add_address(link, link.org, prefix="<i>" + str(qual_work).capitalize() + ":</i> ")
                     self.indent -= 1
                 else:
                     self.add_names(link.org.names(), bullet=EM_DASH, prefix=position)
                     self.indent += 1
                     self.add_comments(link)
                     self.add_organisation(link.org, link, show_parents=True, show_workers=False)
                     self.indent -= 1
             else:
                 self.add_names(
                     [next(link.org.sort_keys())],
                     bullet=RIGHT_ARROW,
                     bold=False,
                     prefix=position,
                     comments=self.all_comments(link),
                 )
                 self.indent += 2
                 self.add_contacts(link, context=At_work)
                 self.indent -= 2
Example #7
0
contacts_style = ParagraphStyle(name="Contacts", fontName="Times-Roman", fontSize=9, leading=10)

address_style = ParagraphStyle(name="Address", fontName="Times-Roman", fontSize=9, leading=10)

header_style = ParagraphStyle(name="Header", fontName="Times-Bold", alignment=TA_CENTER)

header_left_style = ParagraphStyle(name="HeaderLeft", fontName="Times-Italic", fontSize=8, alignment=TA_LEFT, leading=0)

header_right_style = ParagraphStyle(
    name="HeaderRight", fontName="Times-Italic", fontSize=8, alignment=TA_RIGHT, leading=0
)

continue_style = ParagraphStyle(name="Continue", fontName="Times-Italic", fontSize=8, leading=9)


qual_home = multilang(en="home", es="casa")
qual_work = multilang(en="work", es="trab")
NBSP = "\u00a0"
EN_DASH = "\u2013"
EM_DASH = "\u2014"
RIGHT_ARROW = "\u2192"
BLACK_DIAMOND = "\u25c6"
HEAVY_VERTICAL_BAR = "\u275a"
EMAIL_BULLET = BLACK_DIAMOND_MINUS_WHITE_X = "\u2756"
TELEPHONE_BULLET = BLACK_TELEPHONE = "\u260e"


class Booklet(object):

    r"""A booklet object is used to construct a booklet of entries that is
    designed to be cut to size and bound in a filofax.