diff options
| author | eug-vs <eugene@eug-vs.xyz> | 2021-08-13 21:55:06 +0300 | 
|---|---|---|
| committer | eug-vs <eugene@eug-vs.xyz> | 2021-08-13 21:55:06 +0300 | 
| commit | 9a10c387c6b82b75365ba516c128eb1ff2f3639f (patch) | |
| tree | eae835acc1187af45d195eba007f0bbd1589febe | |
| parent | 21ac2bdd8805eb72e11acc6d16a228edf7a446fc (diff) | |
| download | eug-vs-xyz-9a10c387c6b82b75365ba516c128eb1ff2f3639f.tar.gz | |
feat: add CircleCI article
| -rw-r--r-- | blog/2021-07-15.md | 141 | ||||
| -rw-r--r-- | blog/index.md | 1 | ||||
| -rw-r--r-- | public/emoji/benzin.svg | 108 | ||||
| -rw-r--r-- | public/emoji/brave.svg | 1 | ||||
| -rw-r--r-- | public/emoji/circleci.svg | 54 | ||||
| -rw-r--r-- | public/stickerpicker.png | bin | 0 -> 60292 bytes | |||
| -rw-r--r-- | public/wojak-brainchair.jpg | bin | 0 -> 77785 bytes | |||
| -rw-r--r-- | style.css | 4 | 
8 files changed, 308 insertions, 1 deletions
| diff --git a/blog/2021-07-15.md b/blog/2021-07-15.md new file mode 100644 index 0000000..f53009e --- /dev/null +++ b/blog/2021-07-15.md @@ -0,0 +1,141 @@ +# CircleCI :circleci: in daily life: how I improved Matrix stickerpicker + +[CircleCI](https://circleci.com) is a great tool that everyone seems to skip and I don't know exactly why. +I'm gonna quickly show you how I've automated adding stickers to the [Matrix](https://matrix.org) messenger. + +## What is CircleCI? +`CircleCI` is a cloud platform that can run automated jobs when different events occur. The most common use-case is +running tests in the cloud when you push a commit to the `GitHub` repo. But the possibilities are endless, +you can literally automate everything with it - I even used it to compile `.exe` file **in the cloud** and include +a **zipped binary** into the release package. Don't ask me why I had to compile `.exe`, better ask why the guys from my +University **made a deal with** [**the Devil**](https://microsoft.com). + +## Matrix +[Matrix](https://matrix.org) is a messaging protocol which I'm currently trying to replace **Telegram** with. +It's in itself a separate topic for discussion, but what's important for today is that **Matrix** lacks such +a huge collection of stickers as there is in **Telegram**. I'm a big fan of **Wojak** stickers and many other ones, +so I had to do something about it. + + + +### Matrix Stickerpicker +Stickers work in a slightly weird way in **Matrix**.  Basically you have to deploy your own sticker "server" +(*don't worry, it's just a static site*) where you can add your stickers - it will be used as a widget inside your client. + +There's an amazing tool for that - [stickerpicker](https://github.com/maunium/stickerpicker). It's written in `Python` and the author +of course took care of the import feature - you can provide a link to a **Telegram** sticker pack - it will re-upload it +to your `Matrix` server and then generate a web UI using GitHub Pages that you can integrate as a widget in your client. Your friends +can use it too. + +The problem is that each time you want to add new sticker pack to your collection you have to run a `Python` script. +I'm lazy and I don't wanna do that - so let's automate it! + +## Automation +Main idea of my solution is to have a single plaintext file `telegram-packs.txt` which will contain links to all +sticker packs I import from **Telegram**. Then every time I update it `CircleCI` will run a job that will run this `Python` script for me. Deadly simple. + +This approach ships with few bonuses by default: + - You can edit the file from anywhere (even from phone :laughing:) + - If someone from your friends uses your stickers collection and wants to add a new pack, they simply have to open a PR which adds the pack URL to `telegram-packs.txt`. + +There are two problems of running this `Python` script automatically: + - You have to log into your `Matrix` account + - You have to log into your `Telegram` account + +### Config +Here's my fork of the repo: https://github.com/eug-vs/stickerpicker + +`CircleCI` is fully controlled by a config file `.circleci/config.yml`. It uses `YAML` which is really picky about indentation, so be careful with that. + +Ok so let's start outlining our job, we'll be using default CircleCI `Python` image: +```YAML +defaults: &defaults +  working_directory: ~/repo +  docker: +    - image: cimg/python:3.9.5 + +jobs: +  upload_stickers: +    <<: *defaults +    steps: +``` + +The `defaults` part might look scary, but you could just move everything from defaults directly under `upload_stickers` job. +Defaults are useful when you have multiple jobs, and I planned to have 2 initially. Let's now move to the `steps`: +```YAML +      - checkout + +      - run: +          name: Install python dependencies +          command: pip3 install . +``` +Obviously we checkout our code first, and then install all the dependencies for our `Python` script. + +Now let's solve the first problem we found. Instead of logging into `Matrix` manually, you can supply a `config.json` file with your credentials. So I prepared a template for this file (`config.template.json`): +```JSON +{"homeserver": "$HOMESERVER", "user_id": "$USER_ID", "access_token": "$ACCESS_TOKEN"} +``` +You might think how am I gonna put the actual variables in here? Well, there's a tool for that called `envsubst`. It does exactly what you think - substitutes environment variable names with the actual values. +We will put the actual values of `$HOMESERVER`, `$USER_ID` and `$ACCESS_TOKEN` in our `CircleCI` environment (as secrets), and the template can be safely pushed to the GitHub repo. + +There's a little problem - `envsubst` is not installed in the image that we use (`cimg/python:3.9.5`). Solution to it is [orbs](https://circleci.com/developer/orbs) - basically plugins for your CircleCI needs. +Let's add `envsubst` orb at the top of our config: +```YAML +orbs: +  envsubst: sawadashota/envsubst@1.1.0 +``` + +Now back to the steps. Let's install the tool and use it to generate our `config.json`: +```YAML +      - envsubst/install + +      - run: +          name: Create config.json from template +          command: envsubst < config.template.json > config.json +``` + +Ok so we can now login into `Matrix`, but what about `Telegram`? The script uses `Telethon` package under the hood which works with a `sticker-import.session` file. This is basically an `SQL` database, and I don't really +wanna mess around with creating it from scratch (*although I could!*). Instead, I will just encrypt it with `GPG` and push to the repo. That's just me being lazy, but you know, that is what automation is about! +Of course, someone could try to decrypt my `Telethon` session since it's now publicly available, but I can just revoke it at any time. I will probably improve this at some point, but now it's not a big deal for me. + +Our next steps in config will be to decrypt the session and finally pipe our `telegram-packs.txt` to the script using `xargs`: +```YAML +      - run: +          name: Decrypt telethon session +          command: gpg --batch --passphrase $PASSPHRASE --decrypt sticker-import.session.gpg > sticker-import.session + +      - run: +          name: Reupload and install stickers +          command: cat telegram-packs.txt | xargs sticker-import +``` + +At this point, the stickers are uploaded to the server, but the UI is updated via it's own `.json` file which contains information about uploaded stickers. It's already updated by the script, we just have to push it to our repo. +For that I've created a new SSH key and added it to `CircleCI` secrets so that it can push commits to my repository. So the final steps would be: +```YAML +      - add_ssh_keys + +      - run: +          name: Add github to known_hosts +          command: | +            mkdir -p ~/.ssh +            ssh-keyscan github.com >> ~/.ssh/known_hosts +      - run: +          name: Commit stickerpack JSON's +          command: | +            git config --global user.email "eug-vs@keemail.me" +            git config --global user.name "eug-vs" +            git add . +            git commit -m "feat: add stickerpacks with CircleCI [ci skip]" +            git push -u +``` + +The `[ci skip]` flag tells Circle to avoid running on this commit, otherwise it would have to run once again since we pushed a new commit with it. + +One thing that I didn't mention is that I did not actually +need to check the **new** packs in the `telegram-packs.txt` - the script is actually smart enough to skip already existing ones. Otherwise I would have to use `git diff` to find only the new ones. + +And that's it! Now every time I add new URLs to the `telegram-packs.txt`, they will automatically appear in my widget within a minute or so. Enjoy your stickers! + + + +You can find full version of the config here: https://github.com/eug-vs/stickerpicker/blob/master/.circleci/config.yml diff --git a/blog/index.md b/blog/index.md index 5108fd3..8176128 100644 --- a/blog/index.md +++ b/blog/index.md @@ -4,5 +4,6 @@  ### July +- [CircleCI :circleci: in daily life: how I improved Matrix stickerpicker](2021-07-15.md)  - [What's wrong with Numerology](2021-07-03.md)  - [My plans for this website](2021-07-02.md) diff --git a/public/emoji/benzin.svg b/public/emoji/benzin.svg new file mode 100644 index 0000000..be5b465 --- /dev/null +++ b/public/emoji/benzin.svg @@ -0,0 +1,108 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg +   xmlns:dc="http://purl.org/dc/elements/1.1/" +   xmlns:cc="http://creativecommons.org/ns#" +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" +   xmlns:svg="http://www.w3.org/2000/svg" +   xmlns="http://www.w3.org/2000/svg" +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" +   width="128" +   height="148" +   viewBox="0 0 33.866666 39.158334" +   version="1.1" +   id="svg838" +   inkscape:version="0.92.4 (5da689c313, 2019-01-14)" +   sodipodi:docname="icon.svg"> +  <defs +     id="defs832" /> +  <sodipodi:namedview +     id="base" +     pagecolor="#ffffff" +     bordercolor="#666666" +     borderopacity="1.0" +     inkscape:pageopacity="0.0" +     inkscape:pageshadow="2" +     inkscape:zoom="1.979899" +     inkscape:cx="6.1279585" +     inkscape:cy="-8.3014472" +     inkscape:document-units="mm" +     inkscape:current-layer="layer1" +     showgrid="false" +     inkscape:window-width="1850" +     inkscape:window-height="1016" +     inkscape:window-x="70" +     inkscape:window-y="27" +     inkscape:window-maximized="1" +     units="px" /> +  <metadata +     id="metadata835"> +    <rdf:RDF> +      <cc:Work +         rdf:about=""> +        <dc:format>image/svg+xml</dc:format> +        <dc:type +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> +        <dc:title></dc:title> +      </cc:Work> +    </rdf:RDF> +  </metadata> +  <g +     inkscape:label="Layer 1" +     inkscape:groupmode="layer" +     id="layer1" +     transform="translate(0,-257.84165)"> +    <g +       id="g1434" +       transform="matrix(0.37628092,0,0,0.37628092,22.053442,178.70523)"> +      <path +         inkscape:export-filename="/home/eug-vs/Documents/Projects/react-benzin/src/assets/icon.svg.png" +         transform="rotate(-150,58.946792,68.460286)" +         inkscape:export-ydpi="36.122967" +         inkscape:export-xdpi="36.122967" +         inkscape:transform-center-y="3.4957186" +         inkscape:transform-center-x="0.20210213" +         d="M 0.45641909,-93.617205 -23.89006,-135.78654 l 24.34647889,-42.16934 48.69295911,0 24.346479,42.16934 -24.346479,42.169334 z" +         inkscape:randomized="0" +         inkscape:rounded="0" +         inkscape:flatsided="true" +         sodipodi:arg2="2.6179939" +         sodipodi:arg1="2.0943951" +         sodipodi:r2="24.346479" +         sodipodi:r1="48.692959" +         sodipodi:cy="-135.78654" +         sodipodi:cx="24.802898" +         sodipodi:sides="6" +         id="path4554" +         style="fill:none;fill-opacity:1;stroke:#ffa726;stroke-width:5.66499996;stroke-miterlimit:3.5;stroke-dasharray:none;stroke-opacity:1" +         sodipodi:type="star" /> +      <g +         inkscape:export-filename="/home/eug-vs/Documents/Projects/react-benzin/src/assets/icon.svg.png" +         inkscape:export-ydpi="36.122967" +         inkscape:export-xdpi="36.122967" +         transform="translate(-45.866168,397.4575)" +         id="g4921"> +        <circle +           style="fill:#ffa726;fill-opacity:1;stroke:#000000;stroke-width:0.25526616;stroke-opacity:0" +           id="circle4912" +           cx="13.032428" +           cy="-135.63423" +           r="14.182178" /> +        <circle +           r="14.182178" +           cy="-152.1581" +           cx="41.652004" +           id="circle4914" +           style="fill:#ffa726;fill-opacity:1;stroke:#000000;stroke-width:0.25526616;stroke-opacity:0" /> +        <circle +           style="fill:#ffa726;fill-opacity:1;stroke:#000000;stroke-width:0.25526616;stroke-opacity:0" +           id="circle4916" +           cx="41.652004" +           cy="-119.11036" +           r="14.182178" /> +      </g> +    </g> +  </g> +</svg> diff --git a/public/emoji/brave.svg b/public/emoji/brave.svg new file mode 100644 index 0000000..8a59702 --- /dev/null +++ b/public/emoji/brave.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg"  viewBox="0 0 48 48" width="48px" height="48px"><path fill="#ff651f" d="M41,13l1,4l-4.09,16.35c-0.59,2.35-2.01,4.41-4.01,5.79l-8.19,5.68c-0.51,0.36-1.11,0.53-1.71,0.53	c-0.6,0-1.2-0.17-1.71-0.53l-8.19-5.68c-2-1.38-3.42-3.44-4.01-5.79L6,17l1-4l-1-2l3.25-3.25c1.05-1.05,2.6-1.44,4.02-0.99	c0.04,0.01,0.07,0.02,0.1,0.03L14,7l4-4h12l4,4l0.65-0.22c0.83-0.28,1.7-0.27,2.5,0c0.58,0.19,1.13,0.51,1.58,0.95	c0.01,0.01,0.01,0.01,0.02,0.02L42,11L41,13z"/><path fill="#f4592b" d="M38.73,7.73L33,11l-9,2l-9-3l-2.07-2.07c-0.56-0.56-1.41-0.74-2.15-0.44L8.67,8.33l0.58-0.58	c1.05-1.05,2.6-1.44,4.02-0.99c0.04,0.01,0.07,0.02,0.1,0.03L14,7l4-4h12l4,4l0.65-0.22c0.83-0.28,1.7-0.27,2.5,0	C37.73,6.97,38.28,7.29,38.73,7.73z"/><path fill="#fff" d="M32.51,23.49c-0.3,0.3-0.38,0.77-0.19,1.15l0.34,0.68c0.22,0.45,0.34,0.94,0.34,1.44	c0,0.8-0.29,1.57-0.83,2.16l-0.66,0.74c-0.32,0.21-0.72,0.23-1.04,0.05l-5.23-2.88c-0.59-0.4-0.6-1.27-0.01-1.66l3.91-2.66	c0.48-0.28,0.63-0.89,0.35-1.37l-1.9-3.16C27.28,17.46,27.45,17.24,28,17l6-3h-5l-3,0.75c-0.55,0.14-0.87,0.7-0.72,1.24l1.46,5.09	c0.14,0.51-0.14,1.05-0.65,1.22l-1.47,0.49c-0.21,0.07-0.41,0.11-0.62,0.11c-0.21,0-0.42-0.04-0.63-0.11l-1.46-0.49	c-0.51-0.17-0.79-0.71-0.65-1.22l1.46-5.09c0.15-0.54-0.17-1.1-0.72-1.24L19,14h-5l6,3c0.55,0.24,0.72,0.46,0.41,0.98l-1.9,3.16	c-0.28,0.48-0.13,1.09,0.35,1.37l3.91,2.66c0.59,0.39,0.58,1.26-0.01,1.66l-5.23,2.88c-0.32,0.18-0.72,0.16-1.04-0.05l-0.66-0.74	C15.29,28.33,15,27.56,15,26.76c0-0.5,0.12-0.99,0.34-1.44l0.34-0.68c0.19-0.38,0.11-0.85-0.19-1.15l-4.09-4.83	c-0.83-0.99-0.94-2.41-0.26-3.51l3.4-5.54c0.27-0.36,0.75-0.49,1.17-0.33l2.62,1.05c0.48,0.19,0.99,0.29,1.49,0.29	c0.61,0,1.23-0.14,1.79-0.42c0.75-0.38,1.57-0.57,2.39-0.57s1.64,0.19,2.39,0.57c1.03,0.51,2.22,0.56,3.28,0.13l2.62-1.05	c0.42-0.16,0.9-0.03,1.17,0.33l3.4,5.54c0.68,1.1,0.57,2.52-0.26,3.51L32.51,23.49z"/><path fill="#fff" d="M29.51,32.49l-4.8,3.8c-0.19,0.19-0.45,0.29-0.71,0.29s-0.52-0.1-0.71-0.29l-4.8-3.8	c-0.24-0.24-0.17-0.65,0.13-0.8l4.93-2.47c0.14-0.07,0.29-0.1,0.45-0.1s0.31,0.03,0.45,0.1l4.93,2.47	C29.68,31.84,29.75,32.25,29.51,32.49z"/><path fill="#ed4d01" d="M41,13l1,4l-4.09,16.35c-0.59,2.35-2.01,4.41-4.01,5.79l-8.19,5.68c-0.51,0.36-1.11,0.53-1.71,0.53	V10.36L25,12h7v-2l5.15-3.22c0.59,0.19,1.15,0.52,1.6,0.97L42,11L41,13z"/><path fill="#f5f5f5" d="M32.51,23.49c-0.3,0.3-0.38,0.77-0.19,1.15l0.34,0.68c0.22,0.45,0.34,0.94,0.34,1.44	c0,0.8-0.29,1.57-0.83,2.16l-0.66,0.74c-0.32,0.21-0.72,0.23-1.04,0.05l-5.23-2.88c-0.59-0.4-0.6-1.27-0.01-1.66l3.91-2.66	c0.48-0.28,0.63-0.89,0.35-1.37l-1.9-3.16C27.28,17.46,27.45,17.24,28,17l6-3h-5l-3,0.75c-0.55,0.14-0.87,0.7-0.72,1.24l1.46,5.09	c0.14,0.51-0.14,1.05-0.65,1.22l-1.47,0.49c-0.21,0.07-0.41,0.11-0.62,0.11V9.63c0.82,0,1.64,0.19,2.39,0.57	c1.03,0.51,2.22,0.56,3.28,0.13l2.62-1.05c0.42-0.16,0.9-0.03,1.17,0.33l3.4,5.54c0.68,1.1,0.57,2.52-0.26,3.51L32.51,23.49z"/><path fill="#f5f5f5" d="M29.51,32.49l-4.8,3.8c-0.19,0.19-0.45,0.29-0.71,0.29v-7.46c0.16,0,0.31,0.03,0.45,0.1l4.93,2.47	C29.68,31.84,29.75,32.25,29.51,32.49z"/></svg>
\ No newline at end of file diff --git a/public/emoji/circleci.svg b/public/emoji/circleci.svg new file mode 100644 index 0000000..e66e45c --- /dev/null +++ b/public/emoji/circleci.svg @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  --> + +<svg +   version="1.1" +   id="Layer_1" +   x="0px" +   y="0px" +   viewBox="0 0 103.8 105.2" +   enable-background="new 0 0 200 200" +   xml:space="preserve" +   inkscape:version="1.1 (c4e8f9ed74, 2021-05-24)" +   sodipodi:docname="circleci.svg" +   width="103.8" +   height="105.2" +   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" +   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" +   xmlns="http://www.w3.org/2000/svg" +   xmlns:svg="http://www.w3.org/2000/svg" +   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" +   xmlns:cc="http://creativecommons.org/ns#" +   xmlns:dc="http://purl.org/dc/elements/1.1/"><metadata +     id="metadata13"><rdf:RDF><cc:Work +         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type +           rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs +     id="defs11" /><sodipodi:namedview +     pagecolor="#ffffff" +     bordercolor="#666666" +     borderopacity="1" +     objecttolerance="10" +     gridtolerance="10" +     guidetolerance="10" +     inkscape:pageopacity="0" +     inkscape:pageshadow="2" +     inkscape:window-width="1294" +     inkscape:window-height="950" +     id="namedview9" +     showgrid="false" +     fit-margin-top="0" +     fit-margin-left="0" +     fit-margin-right="0" +     fit-margin-bottom="0" +     inkscape:zoom="1.2088054" +     inkscape:cx="50.876674" +     inkscape:cy="22.749732" +     inkscape:window-x="48" +     inkscape:window-y="80" +     inkscape:window-maximized="1" +     inkscape:current-layer="Layer_1" +     inkscape:pagecheckerboard="0" /><path +     style="fill:#ffffff" +     inkscape:connector-curvature="0" +     id="path7" +     d="m 38.6,52.6 c 0,-6.9 5.6,-12.5 12.5,-12.5 6.9,0 12.5,5.6 12.5,12.5 0,6.9 -5.6,12.5 -12.5,12.5 C 44.2,65.2 38.6,59.5 38.6,52.6 Z M 51.1,0 C 26.5,0 5.9,16.8 0.1,39.6 0.1,39.8 0,39.9 0,40.1 c 0,1.4 1.1,2.5 2.5,2.5 l 21.2,0 c 1,0 1.9,-0.6 2.3,-1.5 l 0,0 C 30.4,31.6 39.9,25 51.1,25 66.3,25 78.7,37.4 78.7,52.6 78.7,67.8 66.3,80.2 51.1,80.2 40,80.2 30.4,73.6 26,64.1 l 0,0 c -0.4,-0.9 -1.3,-1.5 -2.3,-1.5 l -21.2,0 c -1.4,0 -2.5,1.1 -2.5,2.5 0,0.2 0,0.3 0.1,0.5 5.8,22.8 26.4,39.6 51,39.6 29.1,0 52.7,-23.6 52.7,-52.7 C 103.8,23.5 80.2,0 51.1,0 Z" /></svg> diff --git a/public/stickerpicker.png b/public/stickerpicker.pngBinary files differ new file mode 100644 index 0000000..a8ebcd8 --- /dev/null +++ b/public/stickerpicker.png diff --git a/public/wojak-brainchair.jpg b/public/wojak-brainchair.jpgBinary files differ new file mode 100644 index 0000000..d6b5c3e --- /dev/null +++ b/public/wojak-brainchair.jpg @@ -67,7 +67,6 @@ code {  pre {    margin: 1em 0;    overflow: auto; -  border: 1px solid rgba(255, 255, 255, 0.12);    padding: 16px 8px;  }  pre code { @@ -78,6 +77,9 @@ pre code {    overflow: visible;    border-radius: 4px;  } +div.sourceCode { +  border: 1px solid rgba(255, 255, 255, 0.12); +}  hr {    background-color: #1a1a1a;    border: none; | 
