aboutsummaryrefslogtreecommitdiff
path: root/resumejson_converter
diff options
context:
space:
mode:
Diffstat (limited to 'resumejson_converter')
-rw-r--r--resumejson_converter/__init__.py0
-rw-r--r--resumejson_converter/filters.py38
-rw-r--r--resumejson_converter/generators/__init__.py0
-rw-r--r--resumejson_converter/generators/html.py41
-rw-r--r--resumejson_converter/generators/pdf.py35
-rw-r--r--resumejson_converter/utils/__init__.py0
-rw-r--r--resumejson_converter/utils/json.py54
-rw-r--r--resumejson_converter/utils/templates.py25
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)