Parcourir la source

Add an Elixir-based output generation

theenglishway (time) il y a 2 ans
commit
1a61756e63

+ 1 - 0
.gitignore

@@ -0,0 +1 @@
+cv_gen/lib/templates/output.html

+ 4 - 0
cv_gen/.formatter.exs

@@ -0,0 +1,4 @@
+# Used by "mix format"
+[
+  inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
+]

+ 26 - 0
cv_gen/.gitignore

@@ -0,0 +1,26 @@
+# The directory Mix will write compiled artifacts to.
+/_build/
+
+# If you run "mix test --cover", coverage assets end up here.
+/cover/
+
+# The directory Mix downloads your dependencies sources to.
+/deps/
+
+# Where third-party dependencies like ExDoc output generated docs.
+/doc/
+
+# Ignore .fetch files in case you like to edit your project deps locally.
+/.fetch
+
+# If the VM crashes, it generates a dump, let's ignore it too.
+erl_crash.dump
+
+# Also ignore archive artifacts (built via "mix archive.build").
+*.ez
+
+# Ignore package tarball (built via "mix hex.build").
+cv_gen-*.tar
+
+# Temporary files, for example, from tests.
+/tmp/

+ 21 - 0
cv_gen/README.md

@@ -0,0 +1,21 @@
+# CvGen
+
+**TODO: Add description**
+
+## Installation
+
+If [available in Hex](https://hex.pm/docs/publish), the package can be installed
+by adding `cv_gen` to your list of dependencies in `mix.exs`:
+
+```elixir
+def deps do
+  [
+    {:cv_gen, "~> 0.1.0"}
+  ]
+end
+```
+
+Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
+and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
+be found at <https://hexdocs.pm/cv_gen>.
+

+ 15 - 0
cv_gen/lib/cv_gen.ex

@@ -0,0 +1,15 @@
+defmodule CvGen do
+  @moduledoc """
+  Documentation for `CvGen`.
+  """
+  @template_file "lib/templates/cv.html.eex"
+  @data_file "lib/templates/cv.json"
+  @output_file "lib/templates/output.html"
+
+  def generate do
+    with raw_data <- File.read!(@data_file),
+         {:ok, assigns} <- Jason.decode(raw_data, keys: :atoms),
+         res <- EEx.eval_file(@template_file, assigns: assigns),
+         do: File.write!(@output_file, res)
+  end
+end

+ 292 - 0
cv_gen/lib/templates/cv.html.eex

@@ -0,0 +1,292 @@
+<%= inspect(@basics) %>
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+  <meta charset="UTF-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>Document</title>
+  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css" integrity="sha512NhSC1YmyruXifcj/KFRWoC561YpHpc5Jtzgvbuzx5VozKpWvQ+4nXhPdFgmx8xqexRcpAglTj9sIBWINXa8x5w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
+  <style>
+    @import url(https://fonts.googleapis.com/css?family=Open+Sans:400,600,700,800);
+    @charset "utf-8";
+
+    @-webkit-viewport {
+      width: device-width;
+    }
+
+    @-moz-viewport {
+      width: device-width;
+    }
+
+    @-ms-viewport {
+      width: device-width;
+    }
+
+    @-o-viewport {
+      width: device-width;
+    }
+
+    @viewport {
+      width: device-width;
+    }
+
+    html {
+      background-color: rgb(51, 73, 96);
+    }
+
+    * {
+      box-sizing: border-box;
+    }
+
+    body {
+      width: 80ch;
+      margin-top: 2em;
+      margin-bottom: 2em;
+      margin-right: auto;
+      margin-left: auto;
+      padding: 1em;
+      background-color: white;
+      font-family: 'Open Sans', Arial, Tahoma;
+      font-weight: 400;
+    }
+
+    ol,
+    ul {
+      list-style: none;
+    }
+
+    dl {
+      display: grid;
+      grid-template-columns: auto 1fr;
+    }
+
+    dt {
+      grid-column: 1/2;
+    }
+
+    dd {
+      grid-column: 2/3;
+    }
+
+    #basics {
+      display: grid;
+      justify-items: center;
+    }
+
+    #basics>h1,
+    #basics>h2 {
+      text-transform: uppercase;
+    }
+
+    data.name::after {
+      content: attr(value);
+    }
+
+    data.position[lang="fr"]::after {
+      content: 'Poste: ' attr(value);
+    }
+
+    data.position[lang="en"]::after {
+      display: none;
+    }
+
+    dt.work_location+dd::before,
+    data.work_location::after {
+      content: '🏢 ' attr(value);
+    }
+
+    dt.location::after,
+    data.location::after {
+      content: '🏠 ' attr(value);
+    }
+
+    time::after {
+      content: attr(datetime);
+    }
+
+    li h1,
+    li h2,
+    li h3 {
+      font-weight: 500;
+    }
+
+    .achievement {
+      font-size: 0.6em;
+    }
+
+    #skills .tools::after {
+      content: "Outils";
+    }
+  </style>
+</head>
+
+<body>
+  <div id="basics">
+    <h1><%= @basics.name %></h1>
+    <h2><%= @basics.label %></h2>
+
+    <dl>
+      <dt class="location">Lieu</dt>
+      <dd><%= @basics.location.city %></dd>
+    </dl>
+  </div>
+
+  <div id="work">
+    <h1>Expériences professionnelles</h1>
+    <ol>
+      <%= for work <- @work do %> <li>
+        <div>
+          <h1><%= work.name %></h1>
+
+          <dl>
+            <dt class="position" lang="fr">Poste</dt>
+            <dd lang="fr"><%= work.position %></dd>
+            <dt class="start_date">Date début</dt>
+            <dd><time class="start_date" datetime="<%= work.startDate %>"></time></dd>
+            <dt class="end_date">Date fin</dt>
+            <dd><time class="end_date" datetime="<%= work.endDate %>"></time></dd>
+            <dt class="work_location"></dt>
+            <dd>Paris</dd>
+          </dl>
+        </div>
+        </li>
+      <% end %>
+      <li>
+        <div>
+          <h1>Parrot</h1>
+
+          <dl>
+            <dt class="position" lang="fr">Poste</dt>
+            <dd lang="fr">Ingénieur logiciel embarqué</dd>
+            <dt class="start_date">Date début</dt>
+            <dd><time class="start_date" datetime="2014-09"></time></dd>
+            <dt class="end_date">Date fin</dt>
+            <dd><time class="end_date" datetime="2017-05"></time></dd>
+            <dt class="work_location"></dt>
+            <dd>Paris</dd>
+          </dl>
+
+          <p class="summary" lang="en">
+            Development and architecture on Parrot's drones software (Bebop Drone, Bebop Drone 2.0, Minidrones)
+          </p>
+
+          <ul class="achievement">
+          </ul>
+        </div>
+      </li>
+
+      <li>
+        <div>
+          <h1>CEA</h1>
+
+          <dl>
+            <dt class="position" lang="fr">Poste</dt>
+            <dd lang="fr">Ingénieur chercheur</dd>
+            <dt class="start_date">Date début</dt>
+            <dd><time class="start_date" datetime="2009-11"></time></dd>
+            <dt class="end_date">Date fin</dt>
+            <dd><time class="end_date" datetime="2014-08"></time></dd>
+            <dt class="work_location"></dt>
+            <dd>Saclay</dd>
+          </dl>
+
+          <p class="summary" lang="en">
+            R&D works on PharOS, a safe embedded RTOS for automotive (now Asterios, promoted by KRONO-SAFE company), and
+            on safe and secure hypervision
+          </p>
+
+          <ul class="achievement">
+            <li>
+              <h1 lang="en">Industrialization of PharOS</h1>
+              <h2 lang="en">Micro-kernel porting on PowerPC and ARM embedded targets, and POSIX simulator</h2>
+              <h2 lang="en">Development of a dual-core version of the micro-kernel for an automotive demonstrator</h2>
+              <h2 lang="en">Design of a new architecture of the micro-kernel wrt portability on different hardware
+                targets and distribution of task scheduling (centralized or distributed)</h2>
+              <h2 lang="en">Participation to the CEA / KRONO-SAFE joint laboratory for the technological transfer</h2>
+            </li>
+
+            <li>
+              <h1 lang="en">Prototype of an automated memory protection system for PharOS</h1>
+              <h2 lang="en">PharOS implements spatial isolation of user tasks / system tasks</h2>
+              <h2 lang="en">On embedded targets without a MMU, this is achieved via manual configuration of a Memory
+                Protection Unit whose capacity is limited</h2>
+              <h2 lang="en">This prototype used graph theory techniques to automatize generation of code that would be
+                executed on context switches and ensure the spatial isolation</h2>
+            </li>
+
+            <li>
+              <h1 lang="en">Safe and secure hypervision</h1>
+              <h2 lang="en">Adaptation to a proprietary security-oriented hypervisor</h2>
+              <h2 lang="en">CEA project leader on a collaborative project of hardware / software co-design of a secure
+                many-core chip</h2>
+            </li>
+          </ul>
+        </div>
+      </li>
+    </ol>
+  </div>
+
+  <div id="skills">
+    <h1>Compétences</h1>
+
+    <ul>
+      <li>
+        <h1>Backend</h1>
+        <ul>
+          <li>Elixir</li>
+          <li>Python</li>
+          <li>Django</li>
+          <li>HTTP</li>
+          <li>Rest</li>
+        </ul>
+      </li>
+      <li>
+        <h1 class="tools"></h1>
+        <ul>
+          <li>Git</li>
+          <li>Linux</li>
+          <li>Python</li>
+        </ul>
+      </li>
+    </ul>
+  </div>
+
+  <div id="education">
+    <h1>Formation</h1>
+
+    <ol>
+      <li>
+        <h1>PLATO Créateurs</h1>
+
+        <dl>
+          <dt class="location"></dt>
+          <dd>Versailles</dd>
+        </dl>
+      </li>
+      <li>
+        <h1>Ecole nationale supérieure de l'Electronique et de ses Applications</h1>
+        <h2>Diplôme d'ingénieur, Mécatronique & Electronique Embarquée 2006 - 2009</h2>
+        <p>
+          Generalist formation in electronics : analog and digital electronics, software, signal processing, control
+          theory, …
+          Last-year specialization in « Mechatronics and Complex Systems », which has a focus on embedded systems,
+          system modeling and mechanics</p>
+      </li>
+    </ol>
+  </div>
+
+  <div id="languages">
+    <h1>Langues</h1>
+
+    <ul>
+      <li>Français (langue maternelle)</li>
+      <li>English (fluent)</li>
+      <li>Português</li>
+      <li>Deutsch</li>
+    </ul>
+  </div>
+</body>
+
+</html>

+ 142 - 0
cv_gen/lib/templates/cv.json

@@ -0,0 +1,142 @@
+{
+    "basics": {
+        "name": "John Doe",
+        "label": "Programmer",
+        "image": "",
+        "email": "john@gmail.com",
+        "phone": "(912) 555-4321",
+        "url": "https://johndoe.com",
+        "summary": "A summary of John Doe…",
+        "location": {
+            "address": "2712 Broadway St",
+            "postalCode": "CA 94115",
+            "city": "San Francisco",
+            "countryCode": "US",
+            "region": "California"
+        },
+        "profiles": [
+            {
+                "network": "Twitter",
+                "username": "john",
+                "url": "https://twitter.com/john"
+            }
+        ]
+    },
+    "work": [
+        {
+            "name": "Company",
+            "position": "President",
+            "url": "https://company.com",
+            "startDate": "2013-01-01",
+            "endDate": "2014-01-01",
+            "summary": "Description…",
+            "highlights": [
+                "Started the company"
+            ]
+        }
+    ],
+    "volunteer": [
+        {
+            "organization": "Organization",
+            "position": "Volunteer",
+            "url": "https://organization.com/",
+            "startDate": "2012-01-01",
+            "endDate": "2013-01-01",
+            "summary": "Description…",
+            "highlights": [
+                "Awarded 'Volunteer of the Month'"
+            ]
+        }
+    ],
+    "education": [
+        {
+            "institution": "University",
+            "url": "https://institution.com/",
+            "area": "Software Development",
+            "studyType": "Bachelor",
+            "startDate": "2011-01-01",
+            "endDate": "2013-01-01",
+            "score": "4.0",
+            "courses": [
+                "DB1101 - Basic SQL"
+            ]
+        }
+    ],
+    "awards": [
+        {
+            "title": "Award",
+            "date": "2014-11-01",
+            "awarder": "Company",
+            "summary": "There is no spoon."
+        }
+    ],
+    "certificates": [
+        {
+            "name": "Certificate",
+            "date": "2021-11-07",
+            "issuer": "Company",
+            "url": "https://certificate.com"
+        }
+    ],
+    "publications": [
+        {
+            "name": "Publication",
+            "publisher": "Company",
+            "releaseDate": "2014-10-01",
+            "url": "https://publication.com",
+            "summary": "Description…"
+        }
+    ],
+    "skills": [
+        {
+            "name": "Web Development",
+            "level": "Master",
+            "keywords": [
+                "HTML",
+                "CSS",
+                "JavaScript"
+            ]
+        }
+    ],
+    "languages": [
+        {
+            "language": "English",
+            "fluency": "Native speaker"
+        }
+    ],
+    "interests": [
+        {
+            "name": "Wildlife",
+            "keywords": [
+                "Ferrets",
+                "Unicorns"
+            ]
+        }
+    ],
+    "references": [
+        {
+            "name": "Jane Doe",
+            "reference": "Reference…"
+        }
+    ],
+    "projects": [
+        {
+            "name": "Project",
+            "description": "Description…",
+            "highlights": [
+                "Won award at AIHacks 2016"
+            ],
+            "keywords": [
+                "HTML"
+            ],
+            "startDate": "2019-01-01",
+            "endDate": "2021-01-01",
+            "url": "https://project.com/",
+            "roles": [
+                "Team Lead"
+            ],
+            "entity": "Entity",
+            "type": "application"
+        }
+    ]
+}

+ 27 - 0
cv_gen/mix.exs

@@ -0,0 +1,27 @@
+defmodule CvGen.MixProject do
+  use Mix.Project
+
+  def project do
+    [
+      app: :cv_gen,
+      version: "0.1.0",
+      elixir: "~> 1.14",
+      start_permanent: Mix.env() == :prod,
+      deps: deps()
+    ]
+  end
+
+  # Run "mix help compile.app" to learn about applications.
+  def application do
+    [
+      extra_applications: [:logger, :eex]
+    ]
+  end
+
+  # Run "mix help deps" to learn about dependencies.
+  defp deps do
+    [
+      {:jason, "~> 1.4"}
+    ]
+  end
+end

+ 3 - 0
cv_gen/mix.lock

@@ -0,0 +1,3 @@
+%{
+  "jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"},
+}