Jekyll2023-03-16T13:26:30+00:00https://lejenome.tik.tn/feed.xmlMoez Bouhlel [lejenome] WebsiteMoez Bouhlel (lejenome) website for latest updates. Hire me as a consultant at https://lejenome.tik.tn/resumeMoez BouhlelGithub push webhook implementation2017-07-30T00:00:00+00:002017-07-30T00:00:00+00:00https://lejenome.tik.tn/post/github-push-webhook-implementation<p>GitHub and Bitbucket provide webhooks support to notify external services when
certain events happen with a repository. The most commonly used webhook event
is <code class="language-plaintext highlighter-rouge">push</code>.</p>
<p>The following code is a PHP implementation of GitHub webhook that will update
a repository clone and execute required deployment code when a new commit was
pushed.</p>
<script src="https://gist.github.com/lejenome/2ee7f1f47b9800140c57b51c1474439f.js"></script>
<p>After adding this file to your server, you need to make the following changes
before adding the webhook to GitHub:</p>
<ul>
<li>Sett <code class="language-plaintext highlighter-rouge">SECRET_TOKEN</code> to a randomly generated token. You can use this
command to generate a truly random secure token on Linux:</li>
</ul>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">head</span> /dev/urandom | <span class="nb">tr</span> <span class="nt">-dc</span> A-Za-z0-9 | <span class="nb">head</span> <span class="nt">-c</span> 40
</code></pre></div></div>
<ul>
<li>Change <code class="language-plaintext highlighter-rouge">$commands</code> list to matches your need for every repository. An
example of updating both a static website repository and a Django based
application repository is provided on the code above as a reference.</li>
<li>Add write access to the process running PHP (FastCGI, mod_php, …) which is
mostly either running within the group <code class="language-plaintext highlighter-rouge">www-data</code> or <code class="language-plaintext highlighter-rouge">www</code> depending on
the Linux distribution running on your server.</li>
<li>If your repository is private, generate an ssh key and add the pubkey as a
read-only deployment key to your repository settings. This key should be
generated using the same user as the PHP process.</li>
</ul>
<p>Finally, add a webhook to your repository settings. Make sure to set the
content type to <code class="language-plaintext highlighter-rouge">application/json</code> and the secret to the secret token you
have already generated.</p>Moez BouhlelGitHub and Bitbucket provide webhooks support to notify external services when certain events happen with a repository. The most commonly used webhook event is push.Boot physical Windows inside Qemu guest machine2017-02-14T00:00:00+00:002017-02-14T00:00:00+00:00https://lejenome.tik.tn/post/boot-physical-windows-inside-qemu-guest-machine<p>Recently, I needed to set up a new Windows system for use in an Internship
project. Like the old setup which was described in an <a href="/post/dualboolt-guest-window-machine">older post</a>, I needed to
have access to the same Windows from inside <em>Qemu</em> and from dual-boot for
performance reasons. But instead of requiring to install Windows two times
(once directly on PC as host and the other inside <em>Qemu</em>) which caused some
issues including slow filesystem operations when booting as the host system, I
did an update to setup instructions this time.</p>
<p>For the virtual machine, we will use <em>Qemu/KVM</em> with <em>Ovmf</em> EFI bios.</p>
<p>First, Install Windows directly on your PC then reboot back to Linux. Check
that <code class="language-plaintext highlighter-rouge">loop</code> and <code class="language-plaintext highlighter-rouge">linear</code> modules are loaded:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>modprobe loop
<span class="nb">sudo </span>modprobe linear
</code></pre></div></div>
<p>Now, we need to create a virtual RAID disk for <em>Qemu</em> that will hold our physical
Windows partition. As we will use GPT partitions table schema, we will allocate
few megabytes <code class="language-plaintext highlighter-rouge">efi1</code> for GPT metadata (34 Sectors) and for EFI partition
before Windows partition and one megabyte <code class="language-plaintext highlighter-rouge">efi2</code> after Windows partition for
GPT secondary metadata (even we need just 34 Sectors, we will use one megabyte
for best RAID performance)</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">dd </span><span class="k">if</span><span class="o">=</span>/dev/zero <span class="nv">of</span><span class="o">=</span>efi1 <span class="nv">bs</span><span class="o">=</span>1M <span class="nv">count</span><span class="o">=</span>100
<span class="nb">dd </span><span class="k">if</span><span class="o">=</span>/dev/zero <span class="nv">of</span><span class="o">=</span>efi2 <span class="nv">bs</span><span class="o">=</span>1M <span class="nv">count</span><span class="o">=</span>1
</code></pre></div></div>
<p>Now that we have <code class="language-plaintext highlighter-rouge">efi1</code> file of 100 MB (100 * 1M) and <code class="language-plaintext highlighter-rouge">efi2</code> of 1 MB. Next,
we create loopback devices from both files:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>losetup <span class="nt">-f</span> efi1
<span class="nb">sudo </span>losetup <span class="nt">-f</span> efi2
</code></pre></div></div>
<p>We will assume that the assigned devices are <code class="language-plaintext highlighter-rouge">/dev/loop0</code> and <code class="language-plaintext highlighter-rouge">/dev/loop1</code>
for <code class="language-plaintext highlighter-rouge">efi1</code> and <code class="language-plaintext highlighter-rouge">efi2</code> respectively. To check the assigned devices, type:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>losetup <span class="nt">-a</span>
</code></pre></div></div>
<p>Next, we will merge the loopback devices and the real Windows partition into a
single linear RAID disk image (We will assume that the windows partition is
<code class="language-plaintext highlighter-rouge">/dev/sda2</code>):</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>mdadm <span class="nt">--build</span> <span class="nt">--verbose</span> /dev/md0 <span class="nt">--chunk</span><span class="o">=</span>512 <span class="nt">--level</span><span class="o">=</span>linear <span class="nt">--raid-devices</span><span class="o">=</span>3 /dev/loop0 /dev/sda2 /dev/loop1
</code></pre></div></div>
<p>Time to create the partitions table of the new RAID disk reusing the same
physical Windows partition. For this step, we will use <em>parted</em> utility. You
can use another tool of your choice.</p>
<p>Partition your virtual RAID disk:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>parted /dev/md0
<span class="o">(</span>parted<span class="o">)</span> unit s
<span class="o">(</span>parted<span class="o">)</span> mktable gpt
<span class="o">(</span>parted<span class="o">)</span> mkpart primary fat32 2048 204799 <span class="c"># depends on size of efi1 file</span>
<span class="o">(</span>parted<span class="o">)</span> mkpart primary ntfs 204800 <span class="nt">-2049</span> <span class="c"># depends on size of efi1 and efi2 files</span>
<span class="o">(</span>parted<span class="o">)</span> <span class="nb">set </span>1 boot on
<span class="o">(</span>parted<span class="o">)</span> <span class="nb">set </span>1 esp on
<span class="o">(</span>parted<span class="o">)</span> <span class="nb">set </span>2 msftdata on
<span class="o">(</span>parted<span class="o">)</span> name 1 EFI
<span class="o">(</span>parted<span class="o">)</span> name 2 Windows
<span class="o">(</span>parted<span class="o">)</span> quit
</code></pre></div></div>
<p>Your final layout will have 2 partitions; Windows partition <code class="language-plaintext highlighter-rouge">/dev/md0p2</code> and
EFI partition <code class="language-plaintext highlighter-rouge">/dev/md0p1</code>. The EFI partition needs to be formatted.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>mkfs.msdos <span class="nt">-F</span> 32 <span class="nt">-n</span> EFI /dev/md0p1
</code></pre></div></div>
<p>Now let add Windows boot entry to the virtual RAID disk.</p>
<p>Boot to Windows live DVD from inside <em>Qemu</em> virtual machine with <code class="language-plaintext highlighter-rouge">/dev/md0</code> as
disk after changing <code class="language-plaintext highlighter-rouge">/dev/md0</code> owner to the current user and installing
<em>Ovmf</em> EFI bios, which in my case, it is available at
<code class="language-plaintext highlighter-rouge">/usr/share/ovmf/ovmf_x64.bin</code>.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">chown</span> <span class="nv">$USER</span>:<span class="nv">$USER</span> /dev/md0 <span class="c"># We need to change the owner of md0</span>
qemu-system-x86_64 <span class="se">\</span>
<span class="nt">-bios</span> /usr/share/ovmf/ovmf_x64.bin <span class="se">\</span>
<span class="nt">-drive</span> <span class="nv">file</span><span class="o">=</span>/dev/md0,media<span class="o">=</span>disk,format<span class="o">=</span>raw <span class="se">\</span>
<span class="nt">-cpu</span> host <span class="nt">-enable-kvm</span> <span class="nt">-m</span> 2G <span class="se">\</span>
<span class="nt">-cdrom</span> /path/to/windows.iso
</code></pre></div></div>
<p>Press <code class="language-plaintext highlighter-rouge">Shift+F10</code> when Windows installer starts to open the terminal. We need
to assign a letter to EFI volume (partition).</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>diskpart
DISKPART> list disk
DISKPART> <span class="k">select </span>disk 0 <span class="c"># Select the disk</span>
DISKPART> list volume <span class="c"># Find EFI volume (partition) number</span>
DISKPART> <span class="k">select </span>volume 2 <span class="c"># Select EFI volume</span>
DISKPART> assign <span class="nv">letter</span><span class="o">=</span>B <span class="c"># Assign B: to EFI volume</span>
DISKPART> <span class="nb">exit</span>
</code></pre></div></div>
<p>Finally, we create BCD boot entry for Windows partition on the same terminal.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>bcdboot C:<span class="se">\W</span>indows /s B: /f ALL
</code></pre></div></div>
<p>Now, you are ready to boot to Windows from inside <em>Qemu</em>.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>qemu-system-x86_64 <span class="se">\</span>
<span class="nt">-bios</span> /usr/share/ovmf/ovmf_x64.bin <span class="se">\</span>
<span class="nt">-drive</span> <span class="nv">file</span><span class="o">=</span>/dev/md0,media<span class="o">=</span>disk,format<span class="o">=</span>raw <span class="se">\</span>
<span class="nt">-cpu</span> host <span class="nt">-enable-kvm</span> <span class="nt">-m</span> 2G
</code></pre></div></div>
<p>After each Linux system reboot, you need to create the loopback devices, merge
the partitions into the RAID disk and change the owner of the device before
launching the virtual machine. You can find <a href="https://github.com/lejenome/dotfiles/blob/master/bin/ws">the script I use</a> as a reference.</p>
<p>Credit to <a href="https://wiki.archlinux.org/index.php/QEMU#Simulate_virtual_disk_with_MBR_using_linear_RAID">Arch Linux Wiki</a>. Enjoy!</p>Moez BouhlelRecently, I needed to set up a new Windows system for use in an Internship project. Like the old setup which was described in an older post, I needed to have access to the same Windows from inside Qemu and from dual-boot for performance reasons. But instead of requiring to install Windows two times (once directly on PC as host and the other inside Qemu) which caused some issues including slow filesystem operations when booting as the host system, I did an update to setup instructions this time.Simple feedback form implementation for static websites2016-10-05T00:00:00+00:002016-10-05T00:00:00+00:00https://lejenome.tik.tn/post/slack-feedback-form<p>Recently, I wanted to add a feedback form to my résumé page to help my friends
review it. I was using GitHub pages to host my static website and I didn’t
want to host the server-side of the feedback on a different server. So I was
looking for a simple solution that works well with my static website. Most of
the available ones were either paid or have too many unneeded features.</p>
<p>At the end, I decided to use my <a href="https://slack.com/">Slack</a> team to receive
feedbacks. It does not require any third-party library or any server-side code.
And it’s simple to implement:</p>
<ol>
<li>Create a Slack team if you don’t have one.</li>
<li>Add an <a href="https://api.slack.com/incoming-webhooks">Incoming Webhook</a> URL to
a channel on your team. It’s a simple URL that you can send feedback to.</li>
<li>Finally, add your client-side implementation. This is a simple one:</li>
</ol>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><form</span> <span class="na">id=</span><span class="s">"feedback"</span><span class="nt">></span>
<span class="nt"><textarea</span> <span class="na">name=</span><span class="s">"text"</span> <span class="na">required</span><span class="nt">></textarea></span>
<span class="nt"><input</span> <span class="na">type=</span><span class="s">"submit"</span> <span class="na">value=</span><span class="s">"send feedback"</span><span class="nt">></input></span>
<span class="nt"></form></span>
</code></pre></div></div>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">let</span> <span class="nx">form</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="dl">"</span><span class="s2">feedback</span><span class="dl">"</span><span class="p">);</span>
<span class="nx">form</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="dl">"</span><span class="s2">submit</span><span class="dl">"</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">e</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span>
<span class="nx">fetch</span><span class="p">(</span><span class="nx">YOUR_WEBHOOK_URL</span><span class="p">,</span> <span class="p">{</span>
<span class="na">method</span><span class="p">:</span> <span class="dl">"</span><span class="s2">POST</span><span class="dl">"</span><span class="p">,</span> <span class="c1">// You should use POST method</span>
<span class="na">body</span><span class="p">:</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span>
<span class="na">text</span><span class="p">:</span> <span class="nx">form</span><span class="p">.</span><span class="nx">text</span><span class="p">.</span><span class="nx">value</span><span class="p">,</span> <span class="c1">// the feedback message</span>
<span class="na">parse</span><span class="p">:</span> <span class="dl">"</span><span class="s2">none</span><span class="dl">"</span><span class="p">,</span> <span class="c1">// tell Slack it's not a formated text</span>
<span class="p">});</span>
<span class="p">});</span>
<span class="p">});</span>
</code></pre></div></div>
<h2 id="improvements">Improvements:</h2>
<p>You can add more entries to the send JSON. Check Slack
<a href="https://api.slack.com/methods/chat.postMessage">documentation</a> for more
details. The most useful ones are <code class="language-plaintext highlighter-rouge">username</code> and <code class="language-plaintext highlighter-rouge">icon_emoji</code>.</p>
<p>You can set a different <code class="language-plaintext highlighter-rouge">username</code> and a different <code class="language-plaintext highlighter-rouge">icon_emoji</code> entry for
every page. For example, you send this JSON from your résumé page:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"text"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"THE FEEDBACK MESSAGE"</span><span class="p">,</span><span class="w">
</span><span class="nl">"parse"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"none"</span><span class="p">,</span><span class="w">
</span><span class="nl">"username"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">"resume"</span><span class="p">,</span><span class="w">
</span><span class="nl">"icon_emoji"</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="s2">":briefcase:"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>Moez BouhlelRecently, I wanted to add a feedback form to my résumé page to help my friends review it. I was using GitHub pages to host my static website and I didn’t want to host the server-side of the feedback on a different server. So I was looking for a simple solution that works well with my static website. Most of the available ones were either paid or have too many unneeded features.(FSSOTC) Recommendations For IT Students2016-10-04T00:00:00+00:002016-10-04T00:00:00+00:00https://lejenome.tik.tn/post/useful-links<p>This is a list of useful websites and tools to check for Computer Science
students.</p>
<h1 id="challenges">Challenges:</h1>
<h2 id="algorithms-and-programming">Algorithms and Programming</h2>
<ul>
<li><a href="https://www.hackerrank.com/">HackerRank</a> : Different-level exercises for many domains and challenges.</li>
<li><a href="https://projecteuler.net/">Project Euler</a> : Algorithms challenges, you can find them on
<a href="https://www.hackerrank.com/projecteuler">ProjectEuler+</a> challenge on HackerRank too.</li>
</ul>
<h2 id="system-development-and-administration">System development and administration</h2>
<ul>
<li><a href="http://eudyptula-challenge.org/">The Eudyptula Challenge</a> : Series of programming exercises for Linux kernel
development.</li>
</ul>
<h2 id="other">Other</h2>
<ul>
<li><a href="http://devpost.com/hackathons">DevPost</a> : Online and in-person challenges with prizes to win.</li>
</ul>
<h1 id="tutorials">Tutorials:</h1>
<ul>
<li><a href="http://www.developpez.com">Developpez.com</a> : Club des développeurs et IT pro.</li>
</ul>
<h1 id="e-learning">E-learning:</h1>
<ul>
<li><a href="https://www.coursera.org/">Coursera</a></li>
<li><a href="https://www.edx.org">Edx</a></li>
<li><a href="https://www.codecademy.com/">Codecademy</a></li>
<li><a href="https://www.udacity.com/">Udacity</a></li>
<li><a href="https://lagunita.stanford.edu/">Stanford Online Lagunita</a></li>
<li><a href="http://ocw.mit.edu/">MIT OpenCourseWare</a></li>
</ul>
<h1 id="usefull-tools">Usefull tools:</h1>
<ul>
<li><a href="https://github.com">GitHub</a> : #1 Online project hosting service.</li>
<li><a href="https://c9.io/">Could9</a> : Full-featured development environment, in the cloud.</li>
<li><a href="https://zealdocs.org/">Zeal</a> : offline documentation for 195+ programming languages and APIs.</li>
<li><a href="http://devdocs.io/">DevDocs</a> : Online APIs documentation.</li>
</ul>
<h1 id="freelancer--money">Freelancer & Money:</h1>
<ul>
<li><a href="https://www.topcoder.com">TopCoder</a></li>
<li><a href="https://www.upwork.com/">UpWork</a></li>
<li><a href="https://www.freelancer.com/">Freelancer</a></li>
</ul>
<h1 id="cv">CV:</h1>
<ul>
<li><a href="https://www.linkedin.com/">LinkedIn</a></li>
<li><a href="https://stackoverflow.com/story">StackOverFlow Story</a></li>
</ul>Moez BouhlelThis is a list of useful websites and tools to check for Computer Science students.Physical boot to virtual EFI Windows machine2016-09-15T00:00:00+00:002016-09-15T00:00:00+00:00https://lejenome.tik.tn/post/dualboolt-guest-window-machine<p><strong>Update:</strong> A new version of the article with better solution is available
<a href="/post/boot-physical-windows-inside-qemu-guest-machine">here</a>.</p>
<p>Even Linux is my main system, I frequently need to use Windows for school
homework when Mono does not support desired features. Running Windows inside a
virtual machine may has limits especially when running Visual Studio on the
guest machine. The best solution was to
set up a single windows system accessible from both the virtual machine and
from the physical dual boot.</p>
<p>For the virtual machine, we will use <em>Qemu/KVM</em> with <em>Virtio</em> devices and a disk
partition for Windows.</p>
<p>First, you need to install Windows on your PC to get the boot entry with right
configurations (I couldn’t find a workaround BCD boot entry issue other than
this one). Then reboot to your Linux system to reinstall Windows on the same
partition but using the virtual machine this time.</p>
<p>Before we start, check that <code class="language-plaintext highlighter-rouge">loop</code> and <code class="language-plaintext highlighter-rouge">linear</code> modules are loaded:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>modprobe loop
<span class="nb">sudo </span>modprobe linear
</code></pre></div></div>
<p>Because the virtual machine needs a whole disk with both the Windows partition
and the EFI partition, We need to create a virtual RAID. Let’s create a small
file to hold the EFI partition:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">dd </span><span class="k">if</span><span class="o">=</span>/dev/zero <span class="nv">of</span><span class="o">=</span>efi <span class="nv">count</span><span class="o">=</span>200000
</code></pre></div></div>
<p>Now you have <code class="language-plaintext highlighter-rouge">efi</code> file of 100 MB (200000 * 512 Bytes). Next, we create a
loopback device from the file:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>losetup <span class="nt">-f</span> efi
</code></pre></div></div>
<p>It will assign the first available loopback device to the file. We will assume
that the assigned device is <code class="language-plaintext highlighter-rouge">/dev/loop0</code>. To check the assigned device:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>losetup <span class="nt">-a</span>
</code></pre></div></div>
<p>Next, we will merge the loopback device and the real Windows partition into a
single linear RAID disk image (We will assume that the windows partition is
<code class="language-plaintext highlighter-rouge">/dev/sda2</code>):</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>mdadm <span class="nt">--build</span> <span class="nt">--verbose</span> /dev/md0 <span class="nt">--chunk</span><span class="o">=</span>16 <span class="nt">--level</span><span class="o">=</span>linear <span class="nt">--raid-devices</span><span class="o">=</span>2 /dev/loop0 /dev/sda2
</code></pre></div></div>
<p>Time to create the partitions table of the new RAID disk with reusing the same
physical Windows partition. For this step, we will use <em>parted</em> utility. You
can use other tools on your own. We need to get the size of real Windows
partition on sectors.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>parted /dev/sda unit s print
</code></pre></div></div>
<p>Partition your virtual RAID disk:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>parted /dev/md0
<span class="o">(</span>parted<span class="o">)</span> unit s
<span class="o">(</span>parted<span class="o">)</span> mktable gpt
<span class="o">(</span>parted<span class="o">)</span> mkpart primary ntfs <span class="nt">-WINDOW_PARITION_SIZE</span> <span class="nt">-1</span>
<span class="o">(</span>parted<span class="o">)</span> mkpart primary fat32 0 <span class="nt">-WINDOW_PARITION_SIZE</span>
<span class="o">(</span>parted<span class="o">)</span> quit
</code></pre></div></div>
<p>Your final layout will have 2 partitions; Windows partition <code class="language-plaintext highlighter-rouge">/dev/md0p1</code> and
EFI partition <code class="language-plaintext highlighter-rouge">/dev/md0p2</code>. You may get few warning messages when
creating partitions, ignore them. The new partitions need to be formatted.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>mkfs.ntfs <span class="nt">-f</span> <span class="nt">-L</span> Windows <span class="nt">-C</span> /dev/md0p1
<span class="nb">sudo </span>mkfs.msdos <span class="nt">-F</span> 32 <span class="nt">-n</span> EFI /dev/md0p2
</code></pre></div></div>
<p>Now, you are ready to launch the virtual machine and reinstall Windows. Change
<code class="language-plaintext highlighter-rouge">/dev/md0</code> owner to the same user <em>Qemu</em> is running as and install <em>ovmf</em> EFI
bios for <em>Qemu</em>, in my case, it will be available at
<code class="language-plaintext highlighter-rouge">/usr/share/ovmf/ovmf_x64.bin</code>.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>qemu-system-x86_64 <span class="se">\</span>
<span class="nt">-enable-kvm</span> <span class="se">\</span>
<span class="nt">-bios</span> /usr/share/ovmf/ovmf_x64.bin <span class="se">\</span>
<span class="nt">-drive</span> <span class="nv">file</span><span class="o">=</span>/dev/md0,media<span class="o">=</span>disk,format<span class="o">=</span>raw <span class="se">\</span>
<span class="nt">-netdev</span> user,id<span class="o">=</span>windowsnic,hostname<span class="o">=</span>windowshost <span class="se">\</span>
<span class="nt">-device</span> virtio-net,netdev<span class="o">=</span>windowsnic <span class="se">\</span>
<span class="nt">-cpu</span> host <span class="se">\</span>
<span class="nt">-m</span> 2G <span class="se">\</span>
<span class="nt">-vga</span> qxl <span class="se">\</span>
<span class="nt">-usbdevice</span> tablet
</code></pre></div></div>
<p>Adapt <em>Qemu</em> script to your use case. You may need to download and install
<a href="https://fedoraproject.org/wiki/Windows_Virtio_Drivers">Virtio drivers</a> on your guest machine. After each reboot, you need to create
the loopback device, merge the two partitions into the RAID disk and change the
owner of the device.</p>
<p>Credit to <a href="https://wiki.archlinux.org/index.php/QEMU#Simulate_virtual_disk_with_MBR_using_linear_RAID">Arch Linux Wiki</a>. Enjoy!</p>Moez BouhlelUpdate: A new version of the article with better solution is available here.(FSSOTC) Python Training – Get Ready2016-02-09T00:00:00+00:002016-02-09T00:00:00+00:00https://lejenome.tik.tn/post/python-101-training-get-ready<p>This is our checklist for any member interested to join the training:</p>
<h1 id="tools">Tools</h1>
<h2 id="for-windows-users">For Windows Users</h2>
<ul>
<li>Python 3.5 (<a href="https://www.python.org/ftp/python/3.5.1/python-3.5.1-amd64.exe">64bit</a>)
(<a href="https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe]">32bit</a>)</li>
<li><a href="https://desktop.github.com/">GitHub Desktop</a></li>
<li><a href="https://git-for-windows.github.io/">Git For Windows</a> (optional but recommended)</li>
</ul>
<p>You can choose your preferred Text Editor or IDE to write python code, or you
can pick one from our recommendation list:</p>
<ul>
<li><a href="https://www.jetbrains.com/pycharm-edu/">PyCharm</a></li>
<li>IDLE3 (already integrated with Python installer)</li>
<li>Visual Studio + Python Tools extension</li>
<li><a href="http://ninja-ide.org/home/">Ninja-IDE</a></li>
<li><a href="http://www.pydev.org/">PyDev</a></li>
<li><a href="https://netbeans.org/">Netbeans</a> >= 8.1 + Python plugin</li>
</ul>
<h2 id="for-linux-ubuntu-users">For Linux (Ubuntu) Users</h2>
<ul>
<li>Python 3 (should be already installed, use python3 command instead of python)</li>
<li>Git</li>
</ul>
<p>You can choose your preferred Text Editor or IDE or one of our suggestion list:</p>
<ul>
<li>PyCharm</li>
<li>Vim / emacs / nano / ed (or cat command if you want)</li>
<li>IDLE3</li>
<li>Ninga-IDE</li>
<li>Netbeans >= 8.1 + Python plugin</li>
<li>IPython3 (Jupyter console)</li>
</ul>
<h1 id="other-we-will-keep-it-for-saturday">Other (We will keep it for Saturday)</h1>
<p>We will use the Django Framework in the training. To install Django, you need to
use the pip command (already integrated on Python Windows installer, or install
python3-pip for Ubuntu users). Launch your console (cmd on Windows), and run:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip <span class="nb">install </span>Django
</code></pre></div></div>
<h1 id="requirements">Requirements</h1>
<p>We will use GitHub to host our projects code. To be able
to join the development, every member is required to create a GitHub account and
email his profile link to <a href="mailto:fssotc@gmail.com">fssotc@gmail.com</a>.</p>
<p>Keep in mind that GitHub is #1 code hosting service and you will mostly keep
using it outside our training on future.</p>
<h1 id="learning-sources">Learning Sources</h1>
<h2 id="python-3">Python 3</h2>
<ul>
<li><a href="https://openclassrooms.com/courses/apprenez-a-programmer-en-python">Open Class Room Python Tutorial</a>
(French)</li>
<li>
<p><a href="https://docs.python.org/3/">Python Official Documentation</a>:</p>
<ul>
<li><a href="https://docs.python.org/3/tutorial/index.html">Python Official Tutorial</a></li>
<li><a href="https://docs.python.org/3/library/index.html">Official Library Reference</a></li>
</ul>
</li>
</ul>
<h2 id="django">Django</h2>
<ul>
<li><a href="https://openclassrooms.com/courses/developpez-votre-site-web-avec-le-framework-django">Open Class Room Django Tutorial</a>
(French)</li>
<li>
<p><a href="https://docs.djangoproject.com/en/1.9/">Django Official Documentation</a>:</p>
<ul>
<li><a href="https://docs.djangoproject.com/en/1.9/intro/overview/">Django Official Tutorial</a></li>
</ul>
</li>
</ul>
<h2 id="git">Git</h2>
<ul>
<li><a href="https://try.github.io/">GitHub Tutorial</a></li>
<li><a href="https://openclassrooms.com/courses/manage-your-code-with-git-and-github">Open Class Room Git Tutorial</a></li>
<li><a href="https://git-scm.com/doc">Git Official Documentation</a></li>
</ul>
<h2 id="html5--css3">HTML5 & CSS3</h2>
<ul>
<li><a href="https://openclassrooms.com/courses/apprenez-a-creer-votre-site-web-avec-html5-et-css3">Open Class Room HTML5 Tutorial</a>
(French)</li>
<li>
<p><a href="https://developer.mozilla.org/en-US/">Mozilla Developer Network</a>:</p>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web">Web Docs</a></li>
</ul>
</li>
<li><a href="http://v4-alpha.getbootstrap.com/getting-started/introduction/">Bootstrap 4 Doc</a></li>
</ul>
<h2 id="javascript">JavaScript</h2>
<ul>
<li><a href="https://openclassrooms.com/courses/dynamisez-vos-sites-web-avec-javascript">Open Class Room JavaScript Tutorial</a>
(French)</li>
<li>
<p><a href="https://developer.mozilla.org/en-US/">Mozilla Developer Network</a>:</p>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript">JavaScript Guide</a></li>
</ul>
</li>
<li>
<p><a href="https://angular.io/docs/ts/latest/">Angular 2 Doc</a>:</p>
<ul>
<li><a href="https://angular.io/docs/ts/latest/quickstart.html">Quick Start</a></li>
<li><a href="https://angular.io/docs/ts/latest/quickstart.html">Guide</a></li>
</ul>
</li>
</ul>Moez BouhlelThis is our checklist for any member interested to join the training:(Syteup) creating a basic plugin, segment as an example2014-11-04T00:00:00+00:002014-11-04T00:00:00+00:00https://lejenome.tik.tn/post/syteup-creating-basic-plugin-segment<p>Here, we will add Segment support to Syteup.</p>
<p>Segment is “a customer data hub”. It makes it easy to integrate third-party
tools (analytics, advertising,…) to your application throw an all-in-one
single library.</p>
<p>To add Segment plugin support to Syteup, we need just 3 simple steps:</p>
<p>1- create <code class="language-plaintext highlighter-rouge">plugins/segment.js</code> plugin code file that will export the plugin
module to the window object:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nb">window</span><span class="p">)</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">use strict</span><span class="dl">"</span><span class="p">;</span>
<span class="kd">function</span> <span class="nx">setupSegment</span><span class="p">(</span><span class="nx">settings</span><span class="p">)</span> <span class="p">{</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">analytics</span> <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">analytics</span> <span class="o">||</span> <span class="p">[];</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">analytics</span><span class="p">.</span><span class="nx">methods</span> <span class="o">=</span> <span class="p">[</span>
<span class="dl">"</span><span class="s2">identify</span><span class="dl">"</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">group</span><span class="dl">"</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">track</span><span class="dl">"</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">page</span><span class="dl">"</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">pageview</span><span class="dl">"</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">alias</span><span class="dl">"</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">ready</span><span class="dl">"</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">on</span><span class="dl">"</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">once</span><span class="dl">"</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">off</span><span class="dl">"</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">trackLink</span><span class="dl">"</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">trackForm</span><span class="dl">"</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">trackClick</span><span class="dl">"</span><span class="p">,</span>
<span class="dl">"</span><span class="s2">trackSubmit</span><span class="dl">"</span>
<span class="p">];</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">analytics</span><span class="p">.</span><span class="nx">factory</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">method</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">args</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">slice</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="nx">arguments</span><span class="p">);</span>
<span class="nx">args</span><span class="p">.</span><span class="nx">unshift</span><span class="p">(</span><span class="nx">method</span><span class="p">);</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">analytics</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">args</span><span class="p">);</span>
<span class="k">return</span> <span class="nb">window</span><span class="p">.</span><span class="nx">analytics</span><span class="p">;</span>
<span class="p">};</span>
<span class="p">};</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o"><</span> <span class="nb">window</span><span class="p">.</span><span class="nx">analytics</span><span class="p">.</span><span class="nx">methods</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">key</span> <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">analytics</span><span class="p">.</span><span class="nx">methods</span><span class="p">[</span><span class="nx">i</span><span class="p">];</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">analytics</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">analytics</span><span class="p">.</span><span class="nx">factory</span><span class="p">(</span><span class="nx">key</span><span class="p">);</span>
<span class="p">}</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">analytics</span><span class="p">.</span><span class="nx">load</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="dl">"</span><span class="s2">analytics-js</span><span class="dl">"</span><span class="p">))</span>
<span class="k">return</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">script</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="dl">"</span><span class="s2">script</span><span class="dl">"</span><span class="p">);</span>
<span class="nx">script</span><span class="p">.</span><span class="nx">type</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">text/javascript</span><span class="dl">"</span><span class="p">;</span>
<span class="nx">script</span><span class="p">.</span><span class="nx">id</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">analytics-js</span><span class="dl">"</span><span class="p">;</span>
<span class="nx">script</span><span class="p">.</span><span class="k">async</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="nx">script</span><span class="p">.</span><span class="nx">src</span> <span class="o">=</span> <span class="p">(</span><span class="dl">"</span><span class="s2">https:</span><span class="dl">"</span> <span class="o">===</span> <span class="nb">document</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">protocol</span> <span class="p">?</span> <span class="dl">"</span><span class="s2">https://</span><span class="dl">"</span> <span class="p">:</span> <span class="dl">"</span><span class="s2">http://</span><span class="dl">"</span><span class="p">)</span> <span class="o">+</span> <span class="dl">"</span><span class="s2">cdn.segment.com/analytics.js/v1/</span><span class="dl">"</span> <span class="o">+</span> <span class="nx">key</span> <span class="o">+</span> <span class="dl">"</span><span class="s2">/analytics.min.js</span><span class="dl">"</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">first</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementsByTagName</span><span class="p">(</span><span class="dl">"</span><span class="s2">script</span><span class="dl">"</span><span class="p">)[</span><span class="mi">0</span><span class="p">];</span>
<span class="nx">first</span><span class="p">.</span><span class="nx">parentNode</span><span class="p">.</span><span class="nx">insertBefore</span><span class="p">(</span><span class="nx">script</span><span class="p">,</span> <span class="nx">first</span><span class="p">);</span>
<span class="p">};</span>
<span class="c1">// Add a version to keep track of what's in the wild.</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">analytics</span><span class="p">.</span><span class="nx">SNIPPET_VERSION</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">2.0.9</span><span class="dl">"</span><span class="p">;</span>
<span class="c1">// Load Analytics.js with your key, which will automatically</span>
<span class="c1">// load the tools you've enabled for your account. Boosh!</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">analytics</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="nx">settings</span><span class="p">[</span><span class="dl">"</span><span class="s2">write_key</span><span class="dl">"</span><span class="p">]);</span>
<span class="c1">// Make the first page call to load the integrations. If</span>
<span class="c1">// you'd like to manually name or tag the page, edit or</span>
<span class="c1">// move this call however you'd like.</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">analytics</span><span class="p">.</span><span class="nx">page</span><span class="p">({</span> <span class="na">title</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Syteup</span><span class="dl">"</span> <span class="p">});</span>
<span class="p">}</span>
<span class="nb">window</span><span class="p">.</span><span class="nx">segmentPlugin</span> <span class="o">=</span> <span class="p">{</span> <span class="na">setup</span><span class="p">:</span> <span class="nx">setupSegment</span> <span class="p">};</span>
<span class="p">}(</span><span class="nb">window</span><span class="p">));</span>
</code></pre></div></div>
<p>what we did is to add segment code (copied from segment tutorial) into the
<code class="language-plaintext highlighter-rouge">setupSegment</code> function, then we export it as <code class="language-plaintext highlighter-rouge">setup</code> item on the plugin module
which should be named <code class="language-plaintext highlighter-rouge">segmentPlugin</code>. As you note, the user depending write_key
is read from the <code class="language-plaintext highlighter-rouge">settings</code> object of the plugin which will be added on the
third step.</p>
<p>2- we add a script tag to the <code class="language-plaintext highlighter-rouge">index.html</code> file that will load the plugin code.</p>
<p>the script tag should be included in the plugins section just before
<code class="language-plaintext highlighter-rouge">js/plugins.js</code> tag and it should be loaded on defer mode</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><script </span><span class="na">defer</span> <span class="na">src=</span><span class="s">"plugins/segment.js"</span><span class="nt">></script></span>
</code></pre></div></div>
<p>3- Finally, we add the plugin settings to the configuration file <code class="language-plaintext highlighter-rouge">config.json</code></p>
<p>option to turn on/off the plugin inside the <code class="language-plaintext highlighter-rouge">plugins</code> option:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">plugins</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">segment</span><span class="dl">"</span><span class="p">:</span> <span class="kc">true</span>
<span class="p">}</span>
</code></pre></div></div>
<p>the plugin settings object that includes all user depending settings (here we
will need the user’s write_key) on the <code class="language-plaintext highlighter-rouge">plugins_settings option</code>:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">plugins_settings</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">segment</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">write_key</span><span class="dl">"</span><span class="p">:</span> <span class="dl">"</span><span class="s2">?????????</span><span class="dl">"</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>All Done! we are ready to test our plugin.</p>
<p>Don’t be lazy, and send me a pull request with your plugins code and other
patches to
<a href="https://github.com/lejenome/syteup">https://github.com/lejenome/syteup</a> !</p>Moez BouhlelHere, we will add Segment support to Syteup.Syteup Introduction2014-11-01T00:00:00+00:002014-11-01T00:00:00+00:00https://lejenome.tik.tn/post/syteup-readme<p><strong>Syteup</strong> (a complete rewrite of <a href="https://github.com/rigoneri/syte">Syte</a>) is a
really simple but powerful packaged personal site that has social integrations
like GitHub, Dribbble, Instagram, Tumblr, Wordpress,
Linkedin, Last.fm, SoundCloud, Bitbucket, StackOverflow, Flickr.</p>
<h1 id="demo">Demo</h1>
<p>You can see Syteup in action on <a href="http://lejenome.github.io/syteup/demo">here</a>.</p>
<h2 id="social-integrations">Social Integrations</h2>
<h3 id="blog">Blog</h3>
<p>Syteup use <a href="http://tumblr.com">Tumblr</a>, <a href="http://wordpress.com/">Wordpress.com</a>
or <a href="https://www.blogger.com/">Blogger</a> for blogging and your blog will be the
primary page of the site.</p>
<p><img src="https://github.com/lejenome/syteup/raw/master/docs/imgs/screenshot-blog-wordpress.png" alt="Syteyp Wordpress" /></p>
<h3 id="social-services">Social Services</h3>
<p>Suteup currently support many different social services:</p>
<p><strong><a href="https://github.com/">Github</a></strong></p>
<p><img src="https://github.com/lejenome/syteup/raw/master/docs/imgs/screenshot-github.png" alt="Syteyp Github" /></p>
<p><strong><a href="https://www.flickr.com/">Flickr</a></strong></p>
<p><img src="https://github.com/lejenome/syteup/raw/master/docs/imgs/screenshot-flickr.png" alt="Syteyp Flickr" /></p>
<p><strong><a href="https://soundcloud.com/">SoundCloud</a></strong></p>
<p><img src="https://github.com/lejenome/syteup/raw/master/docs/imgs/screenshot-soundcloud.png" alt="Syteyp SoundCloud" /></p>
<p><strong><a href="http://www.last.fm/">Last.fm</a></strong></p>
<p><img src="https://github.com/lejenome/syteup/raw/master/docs/imgs/screenshot-lastfm.png" alt="Syteyp Last.fm" /></p>
<p><strong><a href="http://stackoverflow.com/">StackOverflow</a></strong></p>
<p><img src="https://github.com/lejenome/syteup/raw/master/docs/imgs/screenshot-stackoverflow.png" alt="Syteyp StackOverflow" /></p>
<p><strong><a href="https://bitbucket.org/">Bitbucket</a></strong></p>
<p><img src="https://github.com/lejenome/syteup/raw/master/docs/imgs/screenshot-bitbucket.png" alt="Syteyp Bitbucket" /></p>
<p><strong><a href="https://dribbble.com/">Dribbble</a></strong></p>
<p><img src="https://github.com/lejenome/syteup/raw/master/docs/imgs/screenshot-dribbble.png" alt="Syteyp Dribbble" /></p>
<p><strong><a href="http://instagram.com/">Instagram</a></strong></p>
<p><img src="https://github.com/lejenome/syteup/raw/master/docs/imgs/screenshot-instagram.png" alt="Syteyp Instagram" /></p>
<p><strong><a href="https://www.youtube.com/">Youtube</a></strong></p>
<p><img src="https://github.com/lejenome/syteup/raw/master/docs/imgs/screenshot-youtube.png" alt="Syteyp Youtube" /></p>
<p><strong><a href="https://www.linkedin.com/">LinkedIn</a></strong></p>
<p><img src="https://github.com/lejenome/syteup/raw/master/docs/imgs/screenshot-linkedin.png" alt="Syteyp LinkedIn" /></p>
<p><strong><a href="https://www.facebook.com/">Facebook</a></strong></p>
<p><img src="https://github.com/lejenome/syteup/raw/master/docs/imgs/screenshot-facebook.png" alt="Syteyp Facebook" /></p>
<p><strong><a href="https://plus.google.com/">Google+</a></strong></p>
<p><img src="https://github.com/lejenome/syteup/raw/master/docs/imgs/screenshot-gplus.png" alt="Syteyp Google+" /></p>
<p>Some other services integration is planed. For more up to date list of currently
supported services and planed services isavailable on
<a href="https://github.com/lejenome/syteup/tree/master/TODO.md">TODO.md</a> file.</p>
<p>NOTE: Some services can not be supported as accessing them from client side will
give crackers full access to your account (e.g: Twitter, Foursquare) or the service provider does not support
server side requirements (e.g: neither SOP nor jsonp are supported by Steam,…),
if you want them to be implemented, ask the service provider to supported limited
permission access tokens or other needed requirements.</p>
<h2 id="installation">Installation</h2>
<p>Syteup dose not require any specific server side future as it is server-less
moder HTML5 webapp.</p>
<p>First, you need to setup Syteup requirements by runnig the following commands:</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm <span class="nb">install
</span>bower update
</code></pre></div></div>
<p>then, you needs to rename
<a href="https://github.com/lejenome/syteup/tree/master/src/config.json.sample">src/config.json.sample</a>
file to <code class="language-plaintext highlighter-rouge">config.json</code> and customize it for your needs as explained on the
flowing section then run</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npm run dist
</code></pre></div></div>
<p>which will update the
<a href="https://github.com/lejenome/syteup/blob/master/dist/">dist/</a>
folder with your new settings. Then copy the contents of <a href="https://github.com/lejenome/syteup/blob/master/dist/">dist/</a>
folder to you server and then everything is ready.</p>
<p>You can also use make command for custom src and dist folder and config file
too.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code>make <span class="nt">-j1</span> <span class="nv">SRC</span><span class="o">=</span>~/syteup/src <span class="nv">DIST</span><span class="o">=</span>/srv/website/www <span class="nv">CONF</span><span class="o">=</span>~/my_config.json
</code></pre></div></div>
<h2 id="setup">Setup</h2>
<p><strong>IN PROGRESS</strong></p>
<h3 id="general-setup">General Setup</h3>
<p>Change all avatars images on <a href="https://github.com/lejenome/syteup/raw/master/src/imgs">src/imgs</a> folder (pic.png, favicon.ico,
apple-touch-icon*.png) by your avatar images with same sizes.</p>
<p>Setup the options of <code class="language-plaintext highlighter-rouge">fields</code> object on <code class="language-plaintext highlighter-rouge">config.json</code> file</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">fields</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">username</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// the pseudonym (nickname) you mostly known by</span>
<span class="dl">"</span><span class="s2">realname</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// your complete real name</span>
<span class="dl">"</span><span class="s2">description</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// a very short 'About Me' line</span>
<span class="dl">"</span><span class="s2">url</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// the url of your website</span>
<span class="dl">"</span><span class="s2">contact</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">email</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// your email</span>
<span class="dl">"</span><span class="s2">mobile</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// [optional] your phone number e.g: (216) 00000000</span>
<span class="dl">"</span><span class="s2">tel</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// [optional] your telephone number e.g: (216) 00000000</span>
<span class="dl">"</span><span class="s2">fax</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// [optional] your fax number e.g: (216) 1111111</span>
<span class="dl">"</span><span class="s2">address</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// [optional] just a short address e.g: Texas, USA</span>
<span class="dl">"</span><span class="s2">pgp_url</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// [optional] url of your public pgp key file on your site e.g: /pubkey.asc</span>
<span class="dl">"</span><span class="s2">fingerprint</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// [optional] your pgp key fingerprint e.g: 3A1D ADDD 332D 2EFB F816 21C3 84D8 5721 7365 9C9D</span>
<span class="dl">"</span><span class="s2">ssh_url</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span> <span class="c1">// [optional] your ssh public certificate file url on your site e.g: /id_rsa.pub</span>
<span class="p">}</span>
</code></pre></div></div>
<h3 id="blog-setup">Blog Setup</h3>
<p>Set <code class="language-plaintext highlighter-rouge">blog_platform</code> to the bloggin platform that you will use, availbale platforms
are <strong>“tumblr”</strong> and <strong>“blogger”</strong> and <strong>“wordpress”</strong>.</p>
<p>Next, you need to setup the options of the choosen platform on the
<code class="language-plaintext highlighter-rouge">blogs_settings.<platform_name></code> object as follow:</p>
<h4 id="wordpress">Wordpress</h4>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">wordpress</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">blog_url</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// the url of your wordpress.com blog</span>
<span class="dl">"</span><span class="s2">tag_slug</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span> <span class="c1">// [optional] tags of posts to import (space separated)</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="blogger">Blogger</h4>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">blogger</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">blog_url</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// your blog url</span>
<span class="dl">"</span><span class="s2">blog_id</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// your blog id number (you can use https://developers.google.com/apis-explorer/#p/blogger/v3/blogger.blogs.getByUrl)</span>
<span class="dl">"</span><span class="s2">api_key</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// your api key (See Below)</span>
<span class="dl">"</span><span class="s2">tag_slug</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span> <span class="c1">// [optional] tags of posts to import (comma separated)</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Steps to get your <code class="language-plaintext highlighter-rouge">api_key</code> are explained on the youtube section below.</p>
<h4 id="tumblr">Tumblr</h4>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">tumblr</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">blog_url</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// your blog url</span>
<span class="dl">"</span><span class="s2">api_key</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// your api key (See Below)</span>
<span class="dl">"</span><span class="s2">tag_slug</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span> <span class="c1">// [optional] tag of posts to import (just one tag)</span>
<span class="p">}</span>
</code></pre></div></div>
<p>To get your <code class="language-plaintext highlighter-rouge">api_key</code>, register a new app <a href="https://www.tumblr.com/oauth/register">here</a>
with any name and your website url as the default callback url. The “OAuth
Consumer Key” of the application is your <code class="language-plaintext highlighter-rouge">api_key</code>.</p>
<h3 id="services-setup">Services Setup</h3>
<p>For every service you would to enable, you should set <code class="language-plaintext highlighter-rouge">services.<service_name></code> on
<code class="language-plaintext highlighter-rouge">config.json</code> file to <code class="language-plaintext highlighter-rouge">true</code> and setup it options object
<code class="language-plaintext highlighter-rouge">services_settings.<service_name></code> on same file.</p>
<p>Disabled services can safely removed from booth <code class="language-plaintext highlighter-rouge">services</code> and
<code class="language-plaintext highlighter-rouge">services_settings</code> objects on the config file.</p>
<h4 id="github">Github</h4>
<p>enable <code class="language-plaintext highlighter-rouge">services.github</code> and configure <code class="language-plaintext highlighter-rouge">services_settings.github</code> as follow:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">github</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">username</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span> <span class="c1">// your username</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="stackoverflow">StackOverflow</h4>
<p>enable <code class="language-plaintext highlighter-rouge">services.stackoverflow</code> and configure <code class="language-plaintext highlighter-rouge">services_settings.stackoverflow</code> as follow:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">stackoverflow</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">username</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// your username</span>
<span class="dl">"</span><span class="s2">user_id</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span> <span class="c1">// your user id number</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="flickr">Flickr</h4>
<p>enable <code class="language-plaintext highlighter-rouge">services.flickr</code> and configure <code class="language-plaintext highlighter-rouge">services_settings.flickr</code> as follow:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">flickr</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">username</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// your username</span>
<span class="dl">"</span><span class="s2">user_id</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span> <span class="c1">// your user id (you can get it from http://idgettr.com/)</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="bitbucket">Bitbucket</h4>
<p>enable <code class="language-plaintext highlighter-rouge">services.bitbucket</code> and configure <code class="language-plaintext highlighter-rouge">services_settings.bitbucket</code> as follow:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">bitbucket</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">username</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// your username</span>
<span class="dl">"</span><span class="s2">show_forks</span><span class="dl">"</span><span class="p">:</span> <span class="nb">Boolean</span> <span class="c1">// show number of forks (It require a http request for every repository</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="soundcloud">SoundCloud</h4>
<p>enable <code class="language-plaintext highlighter-rouge">services.soundcloud</code> and configure <code class="language-plaintext highlighter-rouge">services_settings.soundcloud</code> as follow:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">soundcloud</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">username</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// your username</span>
<span class="dl">"</span><span class="s2">client_id</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// your client_id (See Below)</span>
<span class="dl">"</span><span class="s2">show_artwork</span><span class="dl">"</span><span class="p">:</span> <span class="nb">Boolean</span><span class="p">,</span> <span class="c1">// show tracks artworks</span>
<span class="dl">"</span><span class="s2">player_color</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span> <span class="c1">// color of tracks player</span>
<span class="p">}</span>
</code></pre></div></div>
<p>To get an <code class="language-plaintext highlighter-rouge">client_id</code>, register an app <a href="http://soundcloud.com/you/apps">here</a>
with any name you want, after you accept their Developer Policies, you get your
Client ID.</p>
<h4 id="lastfm">Last.fm</h4>
<p>enable <code class="language-plaintext highlighter-rouge">services.lastfm</code> and configure <code class="language-plaintext highlighter-rouge">services_settings.lastfm</code> as follow:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">lastfm</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">username</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// your username</span>
<span class="dl">"</span><span class="s2">api_key</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span> <span class="c1">// your api key (See Below)</span>
<span class="p">}</span>
</code></pre></div></div>
<p>To get an <code class="language-plaintext highlighter-rouge">api_key</code>, register a non comercial account
<a href="http://www.last.fm/api/account/create">here</a> with any name and a small
description, then you will get your API Key.</p>
<h4 id="dribbble">Dribbble</h4>
<p>enable <code class="language-plaintext highlighter-rouge">services.dribbble</code> and configure <code class="language-plaintext highlighter-rouge">services_settings.dribbble</code> as follow:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">dribbble</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">username</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span> <span class="c1">// your username</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="youtube">Youtube</h4>
<p>enable <code class="language-plaintext highlighter-rouge">services.youtube</code> and configure <code class="language-plaintext highlighter-rouge">services_settings.youtube</code> as follow:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">youtube</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">username</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// your username</span>
<span class="dl">"</span><span class="s2">api_key</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span> <span class="c1">// your api key (See Below)</span>
<span class="p">}</span>
</code></pre></div></div>
<p>To get an <code class="language-plaintext highlighter-rouge">api_key</code>, create a project
<a href="https://console.developers.google.com/">here</a> with any name then click “Enable
an API” and enable the API you need (“YouTube Data API v3” for YouTube,
“Blogger API v3” for Blogger, “Google+ API” for Google+). Then on “Cendentials”
tab, click “Create a new Key” then “Browser Key” and enter your website url then
“Create” to get your API KEY.</p>
<h4 id="google">Google+</h4>
<p>enable <code class="language-plaintext highlighter-rouge">services.gplus</code> and configure <code class="language-plaintext highlighter-rouge">services_settings.gplus</code> as follow:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">gplus</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">user_id</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// your user id number</span>
<span class="dl">"</span><span class="s2">api_key</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span> <span class="c1">// your api key (See Below)</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Steps to get your <code class="language-plaintext highlighter-rouge">api_key</code> are explained on the youtube section above.</p>
<h4 id="facebook">Facebook</h4>
<p>enable <code class="language-plaintext highlighter-rouge">services.facebook</code> and configure <code class="language-plaintext highlighter-rouge">services_settings.facebook</code> as follow:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">facebook</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">username</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// your username</span>
<span class="dl">"</span><span class="s2">access_token</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span> <span class="c1">// your access token key (See Below)</span>
<span class="p">}</span>
</code></pre></div></div>
<p>to get you read only <code class="language-plaintext highlighter-rouge">access_token</code>, create a web application
<a href="https://developers.facebook.com/quickstarts/?platform=web">here</a>. Then, choose
it from “Application” menu from this
<a href="https://developers.facebook.com/tools/explorer/">page</a> and click “Get Access
Token” and select booth “user_activities”, “user_about_me” and “user_status”.
After confirming, you will get your final <code class="language-plaintext highlighter-rouge">access_token</code> on the Access Token
field.</p>
<h4 id="instagram">Instagram</h4>
<p>enable <code class="language-plaintext highlighter-rouge">services.instagram</code> and configure <code class="language-plaintext highlighter-rouge">services_settings.instagram</code> as follow:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">instagram</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">username</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// your username</span>
<span class="dl">"</span><span class="s2">access_token</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// your access token key (TODO: NEED MORE DOCUMENTATION)</span>
<span class="dl">"</span><span class="s2">user_id</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span> <span class="c1">// your user id number</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="linkedin">LinkedIn</h4>
<p>enable <code class="language-plaintext highlighter-rouge">services.linkedin</code> and configure <code class="language-plaintext highlighter-rouge">services_settings.linkedin</code> as follow:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">linkedin</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">username</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// your username</span>
<span class="dl">"</span><span class="s2">access_token</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span> <span class="c1">// your access token key (See Below)</span>
<span class="p">}</span>
</code></pre></div></div>
<p>To get your read only <code class="language-plaintext highlighter-rouge">access_token</code>, register a new app
<a href="https://www.linkedin.com/secure/developer">here</a>. Select “r_basicprofile” and
“r_fullprofile” as your default scopes and add
<code class="language-plaintext highlighter-rouge">http://lejenome.me/tests/syteup-settings/linkedin.html?client_id=<YOUR_API_KEY>&client_secret=<YOUR_SECRET_API></code>
to “OAuth 2.0 Redirect URLs” after replacing the two parameters with your
API Key and your Secret Key. Then use this
<a href="http://lejenome.me//tests/syteup-settings/linkedin.html">link</a> to request your access token.</p>
<h3 id="plugins-setup">Plugins setup</h3>
<p>Enabling a plugin depend on the type of plugin, either it’s a generic plugin or
a blog plugin. For generic plugins, set <code class="language-plaintext highlighter-rouge">plugins.<plugin_name></code> to <code class="language-plaintext highlighter-rouge">true</code>. and
for blogs plugins, set <code class="language-plaintext highlighter-rouge">blogs_settings.plugins.<plugin_name></code> to <code class="language-plaintext highlighter-rouge">true</code>.</p>
<p>Settings of every plugin are availbale on the <code class="language-plaintext highlighter-rouge">plugins_settings.<plugin_name></code>
object on <code class="language-plaintext highlighter-rouge">config.json</code> file as follow:</p>
<h4 id="disqus">Disqus</h4>
<p>This plugin will enable disqus comments on every post. Just
enable <code class="language-plaintext highlighter-rouge">blogs_settings.plugins.disqus</code> and configure <code class="language-plaintext highlighter-rouge">plugins_settings.disqus</code> as follow:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">disqus</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">url</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// [optional] your disqus profile url</span>
<span class="dl">"</span><span class="s2">shortname</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// your username</span>
<span class="dl">"</span><span class="s2">just_count</span><span class="dl">"</span><span class="p">:</span> <span class="nb">Boolean</span> <span class="c1">// [optional] just show the number of comments instead of the 'Show Comments' buttons</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="sharethis">ShareThis</h4>
<p>This plugin will add ShareThis widget to every post. Just
enable <code class="language-plaintext highlighter-rouge">blogs_settings.plugins.sharethis</code> and configure <code class="language-plaintext highlighter-rouge">plugins_settings.sharethis</code>
as follow:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">sharethis</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">publisher_key</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span> <span class="c1">// your key</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="rss">RSS</h4>
<p>This plugin will add RSS entry that any browser can subscribe to. Just
enable <code class="language-plaintext highlighter-rouge">plugins.rss</code> and configure <code class="language-plaintext highlighter-rouge">plugins_settings.rss</code> as follow:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">rss</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">url</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span> <span class="c1">// the url of your rss feed file or an external rss feed from your blog platform</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="google-analytics">Google Analytics</h4>
<p>This plugin will enable Google Analytics tracking. Just
enable <code class="language-plaintext highlighter-rouge">plugins.google_analytics</code> and configure <code class="language-plaintext highlighter-rouge">plugins_settings.google_analytics</code>
as follow:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">google_analytics</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">tracking_id</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span> <span class="c1">// your tracking id e.g: UA-XXXXXXX-2</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="woopra">Woopra</h4>
<p>This plugin will enable Woopra tracking. Just
enable <code class="language-plaintext highlighter-rouge">plugins.woopra</code> and configure <code class="language-plaintext highlighter-rouge">plugins_settings.woopra</code> as follow:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">woopra</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">tracking_domain</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span><span class="p">,</span> <span class="c1">// TODO</span>
<span class="dl">"</span><span class="s2">idle_timeout</span><span class="dl">"</span><span class="p">:</span> <span class="nb">Number</span><span class="p">,</span> <span class="c1">// TODO</span>
<span class="dl">"</span><span class="s2">include_query</span><span class="dl">"</span><span class="p">:</span> <span class="nb">Boolean</span> <span class="c1">// TODO</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="segment">Segment</h4>
<p>This plugin will enable Segment services. Just
enable <code class="language-plaintext highlighter-rouge">plugins.segment</code> and configure <code class="language-plaintext highlighter-rouge">plugins_settings.segment</code> as follow:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">segment</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">write_key</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span> <span class="c1">// your write key</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="gratipay-widget">Gratipay Widget</h4>
<p>This plugin will add Gratupay widget bollow the navigation menu. Just
enable <code class="language-plaintext highlighter-rouge">plugins.gratipay_widget</code> and configure <code class="language-plaintext highlighter-rouge">plugins_settings.gratipay_widget</code>
as follow:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="dl">"</span><span class="s2">gratipay_widget</span><span class="dl">"</span><span class="p">:</span> <span class="p">{</span>
<span class="dl">"</span><span class="s2">username</span><span class="dl">"</span><span class="p">:</span> <span class="nb">String</span> <span class="c1">// your gratipay username</span>
<span class="p">}</span>
</code></pre></div></div>Moez BouhlelSyteup (a complete rewrite of Syte) is a really simple but powerful packaged personal site that has social integrations like GitHub, Dribbble, Instagram, Tumblr, Wordpress, Linkedin, Last.fm, SoundCloud, Bitbucket, StackOverflow, Flickr.