Exemplo n.º 1
0
def fix(ctx, thing):
    """ Run bulk data fix commands """
    directory = Directory(ctx.obj['config'].path('data:path',
                                                 'directory.json'))

    # Fix relationships structure
    if thing == "relationships":
        for fam in directory.families():
            for person in fam.members():
                new_rels = []
                for rel in person.relationships:
                    new_rels.append({
                        'type': rel['type'].capitalize(),
                        'name': rel['name']
                    })

                person.relationships = new_rels
        directory.save()
    # Fix email addr -- set to None if none
    elif thing == "email":
        for fam in directory.families():
            for person in fam.members():
                if person.email == "N/A":
                    person.email = None
        directory.save()
    elif thing == "add_notes":
        directory.save()
    elif thing == "family_member_to_list":
        directory.save()
    elif thing == "directory_to_list":
        directory.save()
    elif thing == "format":
        directory.save()
    else:
        print("I'm sorry Dave, I'm afraid I can't fix %s!" % (thing))
Exemplo n.º 2
0
def photos(ctx):
    """ List members who either don't have a photo or their photo it too small. """
    config = ctx.obj['config']
    directory = Directory(config.path('data:path', 'directory.json'))

    missing = []
    too_small = []
    for family in directory.families():
        for member in family.members():
            if not member.photo or member.photo == 'unknown.jpeg':
                missing.append(member.name)
            else:
                # print config.path('data:path','photos',member.photo)
                img = Image.open(
                    config.path('data:path', 'photos', member.photo))
                size = img.size
                if size[0] < 300 or size[1] < 300:
                    too_small.append(member.name)

    print("----- Missing Photo -----")
    for name in missing:
        print(name)

    print("\n")

    print("----- Photo Too Small -----")
    for name in too_small:
        print(name)
Exemplo n.º 3
0
class Exporter:
    def __init__(self, data_path):
        # Read Directory Data
        self.__data_path = data_path
        self.__directory = Directory(F"{data_path}/directory.json")

    def export_markdown(self, filename):
        with open(F"{self.__data_path}/{filename}.md", "w") as output:

            output.write("# Massey's Chapel UMC - Member Directory\n\n")

            # Family -> Members -> Person
            for family in self.__directory.families():
                output.write(F"## {family.name}\n")
                output.write(F"""{family.address}
{family.city}, {family.state} {family.zip}
\n""")

                for member in family.members():
                    bday = "N/A" if member.birthday == None else datetime.strftime(
                        member.birthday, "%b %d")
                    email = "N/A" if member.email == None else member.email

                    phone = "N/A"
                    if len(member.phone) > 0:
                        phones = []
                        for type, num in member.phone.items():
                            phones.append(F"{type}: {num}")
                        phone = " | ".join(phones)

                    person = "* %-25s\t%s\t%-25s\t%s\n" % (member.name, bday,
                                                           email, phone)
                    output.write(person)

                output.write("\n")
Exemplo n.º 4
0
class PrintDirectory:
    FONT = "Times-Roman"
    FONT_BOLD = "Times-Bold"

    SIDE_LEFT = 0
    SIDE_RIGHT = 1
    MAX_MEMBERS_PER_SIDE = 3

    def __init__(self, data_path, file_name):
        self.__data_path = data_path

        # Create and Prep page
        self.__pdf = Canvas("%s/%s.pdf" % (data_path, file_name),
                            pagesize=landscape(letter),
                            pageCompression=0)

        # Read Directory Data
        self.__directory = Directory("%s/directory.json" % (data_path))

    def render(self, **kwargs):
        if kwargs.get("bdays_only", False):
            self.render_bdays()
        else:
            self.render_title()
            self.render_bdays()
            self.render_families()

        # Save PDF
        self.__pdf.save()

    def render_title(self):
        x = 4.0 * inch
        y = 8.0 * inch

        # Border
        self.__pdf.setStrokeColorRGB(0, 0, 0)
        self.__pdf.setFillColor(lightgrey)
        self.__pdf.roundRect(3.0 * inch,
                             7.4 * inch,
                             5 * inch,
                             1 * inch,
                             10,
                             fill=1)

        # Top Title
        self.__pdf.setFillColorRGB(0, 0, 0)
        self.__pdf.setFont(PrintDirectory.FONT, 32)
        self.__pdf.drawString(x, y, "Massey's Chapel")
        self.__pdf.drawString(x - (.75 * inch), y - (.50 * inch),
                              "United Methodist Church")

        # Church Photo
        photo = "%s/photos/title_photo.jpg" % (self.__data_path)
        self.__pdf.drawImage(photo,
                             1.0 * inch,
                             1.25 * inch,
                             width=650,
                             height=434)

        # Bottom - Sub-title
        x = 4.25 * inch
        y = .75 * inch
        self.__pdf.setFont(PrintDirectory.FONT, 24)
        self.__pdf.drawString(x, y, "Member Directory")
        self.__pdf.drawString(
            x, y - (.35 * inch),
            datetime.strftime(datetime.now(), "~~~ %B %Y ~~~"))

        self.__pdf.showPage()

    def render_bdays(self):
        # Month placement adjustment
        placement = [0, 0, 0, 0, 0, 0, 0, 0, 0, .15 * inch, 0, 0]
        bdays = [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}]

        for family in self.__directory.families():
            for person in family.members():
                if person.birthday:
                    month = person.birthday.month
                    day = person.birthday.day
                    name = person.name

                    bucket = bdays[month].get(day, [])
                    if not bucket:
                        bdays[month][day] = bucket
                    bucket.append(name)

        self.__pdf.setFillColorRGB(0, 0, 0)
        self.__pdf.setFont(PrintDirectory.FONT, 24)
        self.__pdf.drawString(4.85 * inch, 8.2 * inch, "Birthdays")

        # Vertical Line Down Center
        self.__pdf.setStrokeColorRGB(0, 0, 0)
        self.__pdf.line(5.5 * inch, 0.10 * inch, 5.5 * inch, 8.0 * inch)

        origin_x = 0.5 * inch
        origin_y = 7.75 * inch
        width = 2.25 * inch
        height = 2.5 * inch
        row = 1

        for num, month in enumerate(bdays):
            if not month:
                continue

            if num % 2 != 0:
                # ODD
                offset = row - 1
                pos_x = origin_x
                pos_y = (origin_y - (offset * height)) + placement[num - 1]
                # print "ODD - %d] x:%d y:%d" % (num, pos_x,pos_y)
            else:
                # EVEN
                offset = row - 1
                row += 1
                if row > 3:
                    row = 1
                pos_x = origin_x + width
                pos_y = (origin_y - (offset * height)) + placement[num - 1]
                # print "EVEN - %d] x:%d y:%d" % (num, pos_x,pos_y)

            if num > 6:
                pos_x += 5.5 * inch

            self.__pdf.setFont(PrintDirectory.FONT_BOLD, 9)
            header = self.__pdf.beginText(pos_x, pos_y)
            header.textLine("~~~ %s ~~~" %
                            (datetime(1900, num, 1).strftime("%B").upper()))
            self.__pdf.drawText(header)

            self.__pdf.setFont(PrintDirectory.FONT, 9)
            info = self.__pdf.beginText(pos_x, pos_y - 0.15 * inch)
            for day in sorted(month.keys()):
                names = month.get(day)
                for n in names:
                    info.textLine("%02d) %s" % (day, n))

            self.__pdf.drawText(info)

        self.__pdf.showPage()

    def render_families(self):
        side_it = itertools.cycle(
            (PrintDirectory.SIDE_LEFT, PrintDirectory.SIDE_RIGHT))

        families = self.__directory.families()
        family_index = 0
        family_count = len(families)
        while family_index < family_count:
            # Vertical Line Down Center
            self.__pdf.setStrokeColorRGB(0, 0, 0)
            self.__pdf.line(5.5 * inch, 0.10 * inch, 5.5 * inch, 8.4 * inch)

            # Render the Family
            family1 = families[family_index]
            family_index += 1
            family1_args = {}
            family1_side = next(side_it)

            family2_args = {}
            family2_side = next(side_it)
            if len(family1.members()) > PrintDirectory.MAX_MEMBERS_PER_SIDE:
                family1_args = {
                    'm_start': 0,
                    'm_end': PrintDirectory.MAX_MEMBERS_PER_SIDE
                }
                family2 = family1
                family2_args = {
                    'm_start': PrintDirectory.MAX_MEMBERS_PER_SIDE + 1,
                    'm_end': PrintDirectory.MAX_MEMBERS_PER_SIDE * 2,
                    'family_cont': True
                }
            else:
                if family_index < family_count:
                    family2 = families[family_index]
                    # Don't start rendering a 2 page side family on the LEFT
                    if len(family2.members()
                           ) > PrintDirectory.MAX_MEMBERS_PER_SIDE:
                        family2 = None
                    else:
                        family_index += 1
                else:
                    family2 = None

            self.render_family(family1, family1_side, **family1_args)
            if family2:
                self.render_family(family2, family2_side, **family2_args)

            # End the Page
            self.__pdf.showPage()

    def render_family(self, family, side, **kwargs):
        left_margin = 0
        right_margin = 0
        if side == PrintDirectory.SIDE_LEFT:
            left_margin = .25 * inch
            right_margin = 5.5 * inch
        elif side == PrintDirectory.SIDE_RIGHT:
            left_margin = 5.5 * inch + .25 * inch
            right_margin = 11 * inch
        else:
            raise ValueError("Invalid value [%s] for 'side' parameter." %
                             (side))

        # Family Name
        self.__pdf.setFont(PrintDirectory.FONT, 18)
        draw_pos = {'x': left_margin, 'y': 8.125 * inch}
        self.__pdf.drawString(draw_pos['x'], draw_pos['y'], family.name)

        # Family Address
        if not kwargs.get('family_cont', False):
            self.__pdf.setFont(PrintDirectory.FONT, 16)
            draw_pos['y'] -= .20 * inch
            addr = self.__pdf.beginText(draw_pos['x'], draw_pos['y'])
            addr.setLeading(15)
            addr.textLine(family.address)
            addr.textLine("%s, %s %s" %
                          (family.city, family.state, family.zip))
            self.__pdf.drawText(addr)

        # Family Name/Address Divider
        self.__pdf.setStrokeColorRGB(.5, .5, .5)
        self.__pdf.line(left_margin, 7.5 * inch, right_margin - (0.25 * inch),
                        7.5 * inch)

        # Member Photo, Info
        photo_dir = "%s/photos" % (self.__data_path)
        pos_x = left_margin
        pos_y = 5.35 * inch

        all_members = family.members()
        m_start = kwargs.get('m_start', 0)
        m_end = kwargs.get('m_end', len(all_members))

        members = all_members[m_start:m_end + 1]
        for person in members:
            self.render_person(person, pos_x, pos_y, photo_dir)
            pos_x += 2.80 * inch
            if pos_x >= right_margin:
                pos_x = left_margin
                pos_y = 1.90 * inch

    def render_person(self, person, pos_x, pos_y, photo_dir):
        # Photo
        photo_name = person.photo if person.photo else 'unknown.jpeg'
        photo = "%s/%s" % (photo_dir, photo_name)
        self.__pdf.drawImage(photo, pos_x, pos_y, width=150, height=150)

        # Info
        info = self.__pdf.beginText(pos_x, pos_y - .25 * inch)

        # Name
        info.setFont(PrintDirectory.FONT, 16)
        info.textLine(person.name)

        info.setFont(PrintDirectory.FONT, 12)

        # Bday
        date_str = "N/A"
        if person.birthday:
            date_str = datetime.strftime(person.birthday, "%b %d")
        info.textLine("Birthday: %s" % date_str)

        # Email
        email_addr = person.email if person.email else "N/A"
        info.textLine("Email: %s" % email_addr)

        # Phones
        if person.phone:
            for type, number in person.phone.items():
                info.textLine("%s: %s" % (type.capitalize(), number))

        # Relationships
        if person.relationships:
            if len(person.relationships) > 2:
                spouse = None
                children = []
                for rel in person.relationships:
                    if rel['type'] == 'Spouse':
                        spouse = rel['name']
                    elif rel['type'] == 'Child':
                        children.append(rel['name'])

                text_lines = []
                if spouse:
                    text_lines.append("Spouse: %s" % (spouse))
                if children:
                    batch1 = children[:2]
                    batch2 = children[2:]

                    text_lines.append("Children: %s" % (", ".join(batch1)))
                    if batch2:
                        text_lines.append("                %s" %
                                          (", ".join(batch2)))

                if text_lines:
                    info.textLine("_________________________")
                    for line in text_lines:
                        info.textLine(line)
            else:
                info.textLine("_________________________")
                for rel in person.relationships:
                    info.textLine("%s: %s" % (rel['type'], rel['name']))

        self.__pdf.drawText(info)