From 3a3cee3d317087340c14f15fa90d53ffec4a616e Mon Sep 17 00:00:00 2001 From: Brian (bex) Exelbierd Date: Sep 13 2019 12:14:59 +0000 Subject: Add new card designs Finally implement the replacement horizontal and new vertical designs by @mleonova https://pagure.io/design/issue/531 Note: This adds SVG templates which we do text replacement on this has the side effect of making new cards easier This also moves from optparse to argparse --- diff --git a/fedora_business_cards/frontend/cmdline.py b/fedora_business_cards/frontend/cmdline.py index 07bb002..f5e378c 100644 --- a/fedora_business_cards/frontend/cmdline.py +++ b/fedora_business_cards/frontend/cmdline.py @@ -19,13 +19,12 @@ ### """ -Command-line interface to business card generator. Takes no arguments; uses -optparser.OptionParser instead. +Command-line interface to business card generator. """ from copy import copy import decimal -import optparse +import argparse import sys from fedora_business_cards import common @@ -33,104 +32,74 @@ from fedora_business_cards import export # hah from fedora_business_cards import generators -def check_decimal(option, opt, value): - """ - Checks that value can be converted to a decimal.Decimal object. - """ - try: - return decimal.Decimal(value) - except decimal.InvalidOperation: - return optparse.OptionValueError("option %s: invalid decimal value: %s" - % (opt, value)) - - -class NewOptionClass(optparse.Option): - """ - Replacement Option class for OptionParser that includes decimal type. - """ - TYPES = optparse.Option.TYPES + ("decimal",) - TYPE_CHECKER = copy(optparse.Option.TYPE_CHECKER) - TYPE_CHECKER["decimal"] = check_decimal - - def main(): """ Call this to make things happen. """ # Setup option parser - parser = optparse.OptionParser(option_class=NewOptionClass) - parser.usage = "%prog [options] GENERATOR" + parser = argparse.ArgumentParser() # General options - parser.add_option("--list-generators", dest="showgen", default=False, - action="store_true", help="display list of generators") + parser.add_argument("--list-generators", dest="showgen", default=False, + action="store_true", help="display list of generators") # Size options - size_group = optparse.OptionGroup(parser, "Size options") - size_group.add_option("--height", dest="height", - default=decimal.Decimal("2"), type="decimal", - help="business card height (default: 2)") - size_group.add_option("--width", dest="width", - default=decimal.Decimal("3.5"), type="decimal", - help="business card width (default: 3.5)") - size_group.add_option("--bleed", dest="bleed", type="decimal", - default=decimal.Decimal("0"), help="extra space " - "around card, often requested by printers " - "(default: 0)") - size_group.add_option("--inch", dest="unit", default="in", const="in", - action="store_const", - help="units are specified in inches (default)") - size_group.add_option("--mm", dest="unit", default="in", const="mm", - action="store_const", - help="units are specified in millimeters") + size_group = parser.add_argument_group("Size options") + size_group.add_argument("--height", dest="height", + default=decimal.Decimal("2"), type=decimal.Decimal, + help="business card height (default: 2)") + size_group.add_argument("--width", dest="width", + default=decimal.Decimal("3.5"), type=decimal.Decimal, + help="business card width (default: 3.5)") + size_group.add_argument("--bleed", dest="bleed", type=decimal.Decimal, + default=decimal.Decimal("0"), help="extra space " + "around card, often requested by printers " + "(default: 0)") + size_group.add_argument("--inch", dest="unit", default="in", const="in", + action="store_const", + help="units are specified in inches (default)") + size_group.add_argument("--mm", dest="unit", default="in", const="mm", + action="store_const", + help="units are specified in millimeters") # Output options - out_group = optparse.OptionGroup(parser, "Output options") - out_group.add_option("-d", "--dpi", dest="dpi", default=300, type="int", - help="DPI of exported file") - out_group.add_option("--pdf", dest="output", default="png", const="pdf", - action="store_const", help="Export as PDF") - out_group.add_option("--png", dest="output", default="png", const="png", - action="store_const", help="Export as PNG (default)") - out_group.add_option("--svg", dest="output", default="png", const="svg", - action="store_const", help="Export as SVG") - out_group.add_option("--eps", dest="output", default="png", const="eps", - action="store_const", help="Export as EPS") - out_group.add_option("--cmyk-pdf", dest="output", default="png", - const="cmyk_pdf", action="store_const", - help="Export as PDF with CMYK color (if the generator" - " supports it)") + out_group = parser.add_argument_group("Output options") + out_group.add_argument("-d", "--dpi", dest="dpi", default=300, type=int, + help="DPI of exported file") + out_group.add_argument("--pdf", dest="output", default="png", const="pdf", + action="store_const", help="Export as PDF") + out_group.add_argument("--png", dest="output", default="png", const="png", + action="store_const", help="Export as PNG (default)") + out_group.add_argument("--svg", dest="output", default="png", const="svg", + action="store_const", help="Export as SVG") + out_group.add_argument("--eps", dest="output", default="png", const="eps", + action="store_const", help="Export as EPS") + out_group.add_argument("--cmyk-pdf", dest="output", default="png", + const="cmyk_pdf", action="store_const", + help="Export as PDF with CMYK color (if the generator" + " supports it)") - # Finish setting up option parser - parser.add_option_group(size_group) - parser.add_option_group(out_group) # Check for generator-specific option groups + subparsers = parser.add_subparsers(metavar='GENERATOR',dest='generator', required='--list-generators' not in sys.argv) for module_name in generators.__all__: try: module = common.recursive_import( 'fedora_business_cards.generators.%s' % module_name) generator = module.generator - option_group = generator.extra_options(parser) - if option_group: - parser.add_option_group(option_group) + generator.extra_options(subparsers) except ImportError: pass # Parse arguments - (options, args) = parser.parse_args() + options = parser.parse_args() if options.showgen: print("Generators: %s" % ', '.join(generators.__all__)) sys.exit() - if len(args) != 1: - parser.print_help() - parser.set_usage(optparse.SUPPRESS_USAGE) - parser.error("Exactly one argument (the generator) is required") - # Import the generator we care abuot try: module = common.recursive_import('fedora_business_cards.generators.%s' - % args[0]) + % options.generator) except ImportError: - parser.error("Generator '%s' does not exist or is broken" % args[0]) + parser.error("Generator '%s' does not exist or is broken" % options.generator) gen = module.generator(options) # collect information from user if necessary diff --git a/fedora_business_cards/generators/__init__.py b/fedora_business_cards/generators/__init__.py index c878737..6d35aa6 100644 --- a/fedora_business_cards/generators/__init__.py +++ b/fedora_business_cards/generators/__init__.py @@ -58,4 +58,4 @@ class BaseGenerator(object): return None -__all__ = ('fedora',) +__all__ = ('fedora','fedora-vertical','fedora-horizontal') diff --git a/fedora_business_cards/generators/fedora-horizontal.py b/fedora_business_cards/generators/fedora-horizontal.py new file mode 100644 index 0000000..8d2036f --- /dev/null +++ b/fedora_business_cards/generators/fedora-horizontal.py @@ -0,0 +1,145 @@ +### +# fedora-business-cards - for rendering Fedora contributor business cards +# Copyright (C) 2012 Red Hat, Inc. and others. +# Primary maintainer: Brian Exelbierd +# +# This program 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; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +### + +""" +Generator for the Fedora horizontal business card layout. + +https://fedoraproject.org/wiki/Business_cards + +https://pagure.io/design/issue/531 +""" + +import sys +import string +import importlib.resources as pkg_resources +import argparse +from decimal import Decimal +from getpass import getpass +from xml.dom import minidom +from builtins import input + +from fedora_business_cards import __version__ +from fedora_business_cards import common +from fedora_business_cards.generators import BaseGenerator +from fedora_business_cards import templates # relative-import the *package* containing the card templates + +AccountSystem = \ + common.recursive_import('fedora.client.fas2', True).AccountSystem + +FEDORA_LOGO_VIEWBOX = '100 100 707.776 215.080' + + +class FedoraHorizontalGenerator(BaseGenerator): + rgb_to_cmyk = { + (60, 110, 180): (1, .46, 0, 0), + (41, 65, 114): (1, .57, 0, .38), + (0, 0, 0): (0, 0, 0, 1), + (255, 255, 255): (0, 0, 0, 0), + } + + @staticmethod + def extra_options(parser): + option_group = parser.add_parser('fedora-horizontal', help='Fedora horizontal business cards') + option_group.add_argument('-u', '--username', dest='username', + default='', help='If set, use a different name' + ' than the one logged in with to fill out' + ' business card information') + return option_group + + def collect_information(self): + # ask for FAS login + print("Login to FAS:") + username = input("Username: ") + password = getpass() + + # get information from FAS + fas = AccountSystem(username=username, password=password, + useragent='fedora-business-cards/%s' % __version__) + if self.options.username: + username = self.options.username + userinfo = fas.person_by_username(username) + + # set business card fields + self.fields['name'] = userinfo["human_name"] + self.fields['title'] = "Fedora Project Contributor" + self.fields['lines'] = [''] * 6 + self.fields['lines'][0] = '%s@fedoraproject.org' % username + self.fields['lines'][1] = 'fedoraproject.org' + next_line = 2 + if userinfo['ircnick']: + self.fields['lines'][next_line] = '%s on irc.freenode.net' % \ + userinfo['ircnick'] + next_line += 1 + next_line += 1 # blank line + + if userinfo['gpg_keyid'] == None: + gpg = '' + else: + gpg = "GPG: %s" % userinfo['gpg_keyid'] + self.fields['lines'][next_line] = gpg + + # ask user to edit information + def cmdline_card_line(data): + return "| %s%s |" % (data, ' ' * (59 - len(data))) + + done_editing = False + while not done_editing: + print("Current business card layout:") + print(" +" + "-" * 61 + "+") + print(" n " + cmdline_card_line(self.fields['name'])) + print(" t " + cmdline_card_line(self.fields['title'])) + print(" " + cmdline_card_line('')) + for i in range(6): + print((" %i " % i) + cmdline_card_line(self.fields['lines'][i])) + print(" " + cmdline_card_line('')) + print(" " + cmdline_card_line('')) + print(" " + cmdline_card_line('fedora' + ' ' * 19 + \ + 'FREEDOM. FRIENDS. ' + 'FEATURES. FIRST.')) + print(" +" + "-" * 61 + "+") + lineno = input("Enter a line number to edit, or [y] to accept: ") + if lineno == "" or lineno == "y": + done_editing = True + elif lineno in ['n', 't', '0', '1', '2', '3', '4', '5']: + newdata = input("Enter new data for line %s: " % lineno) + if lineno == 'n': + self.fields['name'] = newdata + elif lineno == 't': + self.fields['title'] = newdata + elif lineno in ['0', '1', '2', '3', '4', '5']: + self.fields['lines'][int(lineno)] = newdata + + def generate_front(self): + card_template = string.Template(pkg_resources.read_text(templates, 'fedora-horizontal-front.svg-template')) + biz_card = card_template.safe_substitute({'NAME': self.fields['name'], + 'TITLE': self.fields['title'], + 'Line0': self.fields['lines'][0], + 'Line1': self.fields['lines'][1], + 'Line2': self.fields['lines'][2], + 'Line3': self.fields['lines'][3], + 'Line4': self.fields['lines'][4], + 'Line5': self.fields['lines'][5], + }) + return biz_card + + def generate_back(self): + return pkg_resources.read_text(templates, 'fedora-back.svg-template') + +generator = FedoraHorizontalGenerator diff --git a/fedora_business_cards/generators/fedora-vertical.py b/fedora_business_cards/generators/fedora-vertical.py new file mode 100644 index 0000000..bb6fe63 --- /dev/null +++ b/fedora_business_cards/generators/fedora-vertical.py @@ -0,0 +1,141 @@ +### +# fedora-business-cards - for rendering Fedora contributor business cards +# Copyright (C) 2012 Red Hat, Inc. and others. +# Primary maintainer: Brian Exelbierd +# +# This program 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; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +### + +""" +Generator for the Fedora vertical business card layout. + +https://fedoraproject.org/wiki/Business_cards + +https://pagure.io/design/issue/531 +""" + +import sys +import string +import importlib.resources as pkg_resources +import argparse +from decimal import Decimal +from getpass import getpass +from xml.dom import minidom +from builtins import input + +from fedora_business_cards import __version__ +from fedora_business_cards import common +from fedora_business_cards.generators import BaseGenerator +from fedora_business_cards import templates # relative-import the *package* containing the card templates + +AccountSystem = \ + common.recursive_import('fedora.client.fas2', True).AccountSystem + +FEDORA_LOGO_VIEWBOX = '100 100 707.776 215.080' + + +class FedoraVerticalGenerator(BaseGenerator): + rgb_to_cmyk = { + (60, 110, 180): (1, .46, 0, 0), + (41, 65, 114): (1, .57, 0, .38), + (0, 0, 0): (0, 0, 0, 1), + (255, 255, 255): (0, 0, 0, 0), + } + + @staticmethod + def extra_options(parser): + option_group = parser.add_parser('fedora-vertical', help='Fedora vertical business cards') + option_group.add_argument('-u', '--username', dest='username', + default='', help='If set, use a different name' + ' than the one logged in with to fill out' + ' business card information') + return option_group + + def collect_information(self): + # ask for FAS login + print("Login to FAS:") + username = input("Username: ") + password = getpass() + + # get information from FAS + fas = AccountSystem(username=username, password=password, + useragent='fedora-business-cards/%s' % __version__) + if self.options.username: + username = self.options.username + userinfo = fas.person_by_username(username) + + # set business card fields + self.fields['name'] = userinfo["human_name"] + self.fields['title'] = "Fedora Project Contributor" + self.fields['lines'] = [''] * 5 + self.fields['lines'][0] = '%s@fedoraproject.org' % username + self.fields['lines'][1] = 'fedoraproject.org' + next_line = 2 + if userinfo['ircnick']: + self.fields['lines'][next_line] = '%s on irc.freenode.net' % \ + userinfo['ircnick'] + next_line += 1 + next_line += 1 # blank line + + # Short GPG is insecure lets omit it + #if userinfo['gpg_keyid'] == None: + # gpg = '' + #else: + # gpg = "GPG: %s" % userinfo['gpg_keyid'] + # self.fields['lines'][next_line] = gpg + + # ask user to edit information + def cmdline_card_line(data): + return "| %s%s |" % (data, ' ' * (35 - len(data))) + + done_editing = False + while not done_editing: + print("Current business card layout:") + print("Vertical cards don't hold much data ...:") + print(" +" + "-" * 37 + "+") + print(" n " + cmdline_card_line(self.fields['name'])) + print(" t " + cmdline_card_line(self.fields['title'])) + print(" " + cmdline_card_line('')) + for i in range(5): + print((" %i " % i) + cmdline_card_line(self.fields['lines'][i])) + print(" +" + "-" * 37 + "+") + lineno = input("Enter a line number to edit, or [y] to accept: ") + if lineno == "" or lineno == "y": + done_editing = True + elif lineno in ['n', 't', '0', '1', '2', '3', '4', '5']: + newdata = input("Enter new data for line %s: " % lineno) + if lineno == 'n': + self.fields['name'] = newdata + elif lineno == 't': + self.fields['title'] = newdata + elif lineno in ['0', '1', '2', '3', '4', '5']: + self.fields['lines'][int(lineno)] = newdata + + def generate_front(self): + card_template = string.Template(pkg_resources.read_text(templates, 'fedora-vertical-front.svg-template')) + biz_card = card_template.safe_substitute({'NAME': self.fields['name'], + 'TITLE': self.fields['title'], + 'Line0': self.fields['lines'][0], + 'Line1': self.fields['lines'][1], + 'Line2': self.fields['lines'][2], + 'Line3': self.fields['lines'][3], + 'Line4': self.fields['lines'][4], + }) + return biz_card + + def generate_back(self): + return pkg_resources.read_text(templates, 'fedora-back.svg-template') + +generator = FedoraVerticalGenerator diff --git a/fedora_business_cards/generators/fedora.py b/fedora_business_cards/generators/fedora.py index 037664f..c0dec30 100644 --- a/fedora_business_cards/generators/fedora.py +++ b/fedora_business_cards/generators/fedora.py @@ -25,9 +25,9 @@ https://fedoraproject.org/wiki/Business_cards """ import sys +import argparse from decimal import Decimal from getpass import getpass -from optparse import OptionGroup from xml.dom import minidom from builtins import input @@ -51,11 +51,11 @@ class FedoraGenerator(BaseGenerator): @staticmethod def extra_options(parser): - option_group = OptionGroup(parser, "Options for fedora") - option_group.add_option('-u', '--username', dest='username', - default='', help='If set, use a different name' - ' than the one logged in with to fill out' - ' business card information') + option_group = parser.add_parser('fedora', help='Fedora original horizontal business cards') + option_group.add_argument('-u', '--username', dest='username', + default='', help='If set, use a different name' + ' than the one logged in with to fill out' + ' business card information') return option_group def collect_information(self): diff --git a/fedora_business_cards/templates/__init__.py b/fedora_business_cards/templates/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/fedora_business_cards/templates/__init__.py diff --git a/fedora_business_cards/templates/fedora-back.svg-template b/fedora_business_cards/templates/fedora-back.svg-template new file mode 100644 index 0000000..2c7c253 --- /dev/null +++ b/fedora_business_cards/templates/fedora-back.svg-template @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fedora_business_cards/templates/fedora-horizontal-front.svg-template b/fedora_business_cards/templates/fedora-horizontal-front.svg-template new file mode 100644 index 0000000..eb6cc47 --- /dev/null +++ b/fedora_business_cards/templates/fedora-horizontal-front.svg-template @@ -0,0 +1,1792 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FREEDOM. FRIENDS. FEATURES. FIRST. + $NAME + $TITLE + $Line0$Line1$Line3$Line4$Line5 + + FREEDOM. FRIENDS. FEATURES. FIRST. + + Brian "bex" Exelbierd + Fedora Community Action & Impact Coordinator + + bex@fedoraproject.orggetfedora.orgbexelbie on irc.freenode.net+420-606055-877 / +1-919-414-8915GPG key ID: EEE88888 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fedora_business_cards/templates/fedora-vertical-front.svg-template b/fedora_business_cards/templates/fedora-vertical-front.svg-template new file mode 100644 index 0000000..4153b1d --- /dev/null +++ b/fedora_business_cards/templates/fedora-vertical-front.svg-template @@ -0,0 +1,439 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + FREEDOM. FRIENDS. FEATURES. FIRST. + + $NAME + $TITLE + + $Line0$Line1$Line2$Line3$Line4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/setup.py b/setup.py index f0190ff..c1a5989 100644 --- a/setup.py +++ b/setup.py @@ -9,6 +9,8 @@ setup( author_email = 'bexelbie@redhat.com', url = 'https://fedoraproject.org/wiki/Business_cards', + include_package_data=True, + entry_points = { 'console_scripts': [ ('fedora-business-cards = '