diff options
Diffstat (limited to 'resumejson_converter')
-rw-r--r-- | resumejson_converter/__init__.py | 0 | ||||
-rw-r--r-- | resumejson_converter/filters.py | 38 | ||||
-rw-r--r-- | resumejson_converter/generators/__init__.py | 0 | ||||
-rw-r--r-- | resumejson_converter/generators/html.py | 41 | ||||
-rw-r--r-- | resumejson_converter/generators/pdf.py | 35 | ||||
-rw-r--r-- | resumejson_converter/utils/__init__.py | 0 | ||||
-rw-r--r-- | resumejson_converter/utils/json.py | 54 | ||||
-rw-r--r-- | resumejson_converter/utils/templates.py | 25 |
8 files changed, 193 insertions, 0 deletions
diff --git a/resumejson_converter/__init__.py b/resumejson_converter/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/resumejson_converter/__init__.py diff --git a/resumejson_converter/filters.py b/resumejson_converter/filters.py new file mode 100644 index 0000000..f15ee63 --- /dev/null +++ b/resumejson_converter/filters.py @@ -0,0 +1,38 @@ +from datetime import datetime +from babel.dates import format_date + +import resumejson_converter.utils.templates as utemplates + + +def dateedit(startDate, endDate): + startDateTime = datetime.strptime(startDate, '%Y-%m-%d') + if endDate == "": + return "{:%Y} - Auj.".format(startDateTime) + else: + endDateTime = datetime.strptime(endDate, '%Y-%m-%d') + diffDate = endDateTime - startDateTime + if startDateTime.strftime("%Y") == endDateTime.strftime("%Y"): + return "{:%Y}".format(startDateTime) + else: + return "{:%Y} - {:%Y}".format(startDateTime, endDateTime) + + +def datediff(title, startDate, endDate, showDiff=True): + if showDiff and endDate != "": + startDateTime = datetime.strptime(startDate, '%Y-%m-%d') + endDateTime = datetime.strptime(endDate, '%Y-%m-%d') + diffDate = endDateTime - startDateTime + period = utemplates.td_format(diffDate).split(',')[0] + return "{} - {}".format(title, period) + else: + return "{}".format(title) + + +def birthday(date): + date = datetime.strptime(date, '%Y-%m-%d') + return format_date(date, format='long', locale='fr') + + +def clean(phone): + phone = [phone[num:num+2] for num in range(0, len(phone), 2)] + return " ".join(phone) diff --git a/resumejson_converter/generators/__init__.py b/resumejson_converter/generators/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/resumejson_converter/generators/__init__.py diff --git a/resumejson_converter/generators/html.py b/resumejson_converter/generators/html.py new file mode 100644 index 0000000..57df871 --- /dev/null +++ b/resumejson_converter/generators/html.py @@ -0,0 +1,41 @@ +import os.path as path +import sys +import codecs +import logging + +import jinja2 + +import resumejson_converter.filters as filters + + +def generate(resume, template, out_path): + try: + logging.info("HTML generation...") + templates_path = path.dirname(template) + template_name = path.basename(template) + env = jinja2.Environment( + loader=jinja2.FileSystemLoader(templates_path), + autoescape=jinja2.select_autoescape(['hmtl', 'xml']), + ) + env.filters['dateedit'] = filters.dateedit + env.filters['datediff'] = filters.datediff + env.filters['birthday'] = filters.birthday + env.filters['clean'] = filters.clean + try: + template = env.get_template(template_name) + except jinja2.exceptions.TemplateNotFound: + logging.exception("File not found: '{}'!" + .format(template)) + sys.exit(1) + html = template.render(dict(resume=resume)) + except jinja2.exceptions.TemplateSyntaxError as e: + logging.exception("Syntax error in template file '{}' line {}: {}" + .format(e.name, e.lineno, e.message)) + sys.exit(1) + else: + logging.info("HTML generation done.") + if out_path: + file = codecs.open(out_path, "w", "utf-8-sig") + file.write(html) + file.close + return html diff --git a/resumejson_converter/generators/pdf.py b/resumejson_converter/generators/pdf.py new file mode 100644 index 0000000..de3e880 --- /dev/null +++ b/resumejson_converter/generators/pdf.py @@ -0,0 +1,35 @@ +import sys +import logging + +import pdfkit + + +def generate(html): + logging.info("PDF generation...") + + pdf_output_path = "out/out.pdf" + + import os + if not os.path.exists("out"): + os.makedirs("out", exist_ok=True) + + try: + config = pdfkit.configuration(wkhtmltopdf='/usr/bin/wkhtmltopdf') + options = { + 'quiet': '', + 'page-size': 'A4', + 'margin-top': '0in', + 'margin-right': '0in', + 'margin-bottom': '0in', + 'margin-left': '0in', + 'encoding': "UTF-8", + } + pdfkit.from_string( + html, + pdf_output_path, + configuration=config, + options=options) + except (IOError, OSError) as e: + logging.exception("Something append: {}".format(e)) + else: + logging.info("PDF generated at {}".format(pdf_output_path)) diff --git a/resumejson_converter/utils/__init__.py b/resumejson_converter/utils/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/resumejson_converter/utils/__init__.py diff --git a/resumejson_converter/utils/json.py b/resumejson_converter/utils/json.py new file mode 100644 index 0000000..f3ce3d1 --- /dev/null +++ b/resumejson_converter/utils/json.py @@ -0,0 +1,54 @@ +import sys +import logging +import json + +from jsonresume import Resume +from jsonresume.exceptions import InvalidResumeError + + +class JsonObject(object): + """ + All work for this function go to + https://dev.to/mandrewcito/nested-json-to-python-object--5ajp + """ + def __init__(self, json): + jsonDict = dict(json) + + for key, val in jsonDict.items(): + setattr(self, key, self.compute_attr_value(val)) + + def compute_attr_value(self, value): + if type(value) is list: + return [self.compute_attr_value(x) for x in value] + elif type(value) is dict: + return JsonObject(value) + else: + return value + + +def load(json_filepath): + try: + logging.info("JSON parsing...") + with open(json_filepath, 'r') as f: + resume_json = json.load(f) + except IOError: + msg = "Json file could not be loaded. Perhaps file path: \n\ + [{}] is incorrect".format(json_filepath) + logging.exception(msg) + sys.exit(1) + except ValueError: + logging.exception( + "Json file could not be loaded. The syntax is not valid.") + sys.exit(1) + else: + resume = Resume(resume_json) + try: + resume.validate() + except InvalidResumeError: + msg = "The json resume don't respect standard. Check: \n\ + https://jsonresume.org/schema/." + logging.exception(msg) + sys.exit(1) + else: + logging.info("JSON parsing done.") + return JsonObject(resume_json) diff --git a/resumejson_converter/utils/templates.py b/resumejson_converter/utils/templates.py new file mode 100644 index 0000000..b22b4b2 --- /dev/null +++ b/resumejson_converter/utils/templates.py @@ -0,0 +1,25 @@ + + +def td_format(td_object): + """ + based on https://stackoverflow.com/a/13756038 + """ + seconds = int(td_object.total_seconds()) + periods = [ + ('an', 60*60*24*365), + ('mois', 60*60*24*30), + ('semaine', 60*60*24*7), + ('jour', 60*60*24), + ('heure', 60*60), + ('minute', 60), + ('seconde', 1) + ] + + strings = [] + for period_name, period_seconds in periods: + if seconds > period_seconds: + period_value, seconds = divmod(seconds, period_seconds) + has_s = 's' if period_value > 1 and period_name != "mois" else '' + strings.append("%s %s%s" % (period_value, period_name, has_s)) + + return ", ".join(strings) |