Skip to main content

QuteBrowser and LastPass

2 min read

I've been using QuteBrowser for the past 2 days (more on that later), and the only thing I missed so far was a LastPass integration.

Now, QuteBrowser does not come with a plugin store like Firefox or Chrome, but it is still possible to use LastPass with it.

First we need to install lastpass-cli and login to the service. I'm running Manjaro Linux on my laptop so I use yaourt :

yaourt lasstpass-cli

Now we login to Lastpass :

lpass login <email@domain.tld>

A prompt pops-up, asking for your master password. If everything went right, the CLI should responds with

Success: Logged in as <email@domain.tld>.

Since we're good to go, we can now download the QuteBrowser userscripts :

mkdir -p $/.local/share/qutebrowser/userscripts && cd $_

wget https://raw.githubusercontent.com/welps/qutebrowser/9a85796ac30ef33218dd7dee9db6a3c28364f668/misc/us...

chmod +x qute-lastpass

The script is installed. We can restart QuteBrowser by typing :restart.

Now everytime you need to find your login/password for a given page type :spawn --userscript qute-lastpass

Troubleshooting

Process stderr:
Traceback (most recent call last):
File "/home/cedric/.local/share/qutebrowser/userscripts/qute-lastpass", line 50, in <module>
import tldextract
ModuleNotFoundError: No module named 'tldextract'

Solution : pip install tldextract --user

FileNotFoundError: [Errno 2] No such file or directory: 'lpass': 'lpass'

Solution : install lastpass-cli

FileNotFoundError: [Errno 2] No such file or directory: 'rofi': 'rofi'

Solution : install rofi

Ton premier jour d'école

3 min read

C'était ton premier jour d'école, aujourd'hui. Je n'aurais manqué ça pour rien au monde.

J'ai mal dormi cette nuit, remplis de doutes, d'incertitudes et de questions. Jusqu'à présent, nous t'avions gardé rien que pour nous, et désormais, tu aurais ta propre petite vie, en dehors de la maison. J'ai passé une bonne partie de la nuit à me demander si nous t'avions bien préparé.

Tu t'es réveillé de bonne humeur ce matin, tu as pris ton lait, tes céréales, et regardé un épisode des Pyjamasques. Je t'ai encore expliqué ce qui allait se passer, ta maman aussi. Je n'étais pas tout à fait sûr que tu comprenais bien toutes les implications que ça avait, mais tu es resté stoïque.

Quand l'heure de partir est arrivée, je n'en menais pas large. Toi par contre, tu as été brave. Très brave. Bien plus que je ne pouvais l'être. Dans la voiture, tu m'as demandé la vraie chanson. Tu parlais bien sûr de Californication. La vraie chanson, pas la berceuse que je te fais écouter le soir avant de dormir.

Nous sommes arrivés à l'école, ton petit cartable sur le dos, tu as traversé la cours en regardant tout autour de toi. Calme et silencieux, comme souvent, tu te contentais d'observer ce qui t'entourait. A l'intérieur, nous t'avons montré ton porte-manteau, ton prénom y était écrit à côté d'un dessin de petite voiture. Tu as déposé tes affaires avant de me montrer la petite cuisine, dans le couloir.

Enfin nous sommes entrés en classe. Tu as déposé ta collation et ta gourde dans le tiroir à ton nom, puis tu t'es précipité vers le garage des petites voitures. Tu étais à la fête : plein de jouets dans une salle remplie d'enfants. Intérieurement, je fondais en larmes de voir mon petit bonhomme devenir un grand, mais il ne fallait rien laisser transparaître.

Alors je me suis tu. Je t'ai souris, je me suis accroupi pour regarder de plus près le jouet que tu me montrais. Quand vint l'heure de partir, maman t'as expliqué que nous te laissions là, jouer avec tes nouveaux amis, mais qu'elle viendrait te rechercher un peu plus tard. Tu as hoché la tête, en disant "oui". Tu nous a pris dans tes bras, fait un bisou, puis tu t'es dirigé vers la fenêtre pour nous faire "coucou".

Nous nous sommes éloignés sans pour autant quitter l'école tout de suite. Je t'ai vu revenir à la fenêtre quelques minutes plus tard. Tu as regardé un petit moment, puis, ne nous voyant pas, tu es retourné dans l'espace de jeu.

C'était un moment dur pour ta maman et moi, mais bien heureusement, il a semblé bien plus facile pour toi. J'ai hâte de rentrer à la maison, ce soir, et de t'entendre me raconter ta journée.

 

Mutt + ProtonMail

4 min read

Il y a maintenant plusieurs semaines que j'utilise ProtonMail. Bien que rassembler mes 7 adresses précédentes sur une seule m'a grandement simplifié la vie, je ne suis toujours pas satisfait des clients disponibles. Sous Linux, seul Thunderbird est actuellement disponible, à moins d'utiliser de webmail - ce que je fais pour l'instant.

Il y a quelques années, j'avais testé Mutt un peu comme un jeu. La raison pour laquelle j'avais arrêté de l'utiliser était justement le nombre d'adresse que je devais gérer : l'outil était certes intéressant, mais difficile à utiliser avec autant de compte.

Maintenant que j'ai résolu ce problème, j'avais envie de redonner une chance à ce client minimaliste et, par la même occasion, voir s'il était possible de faire cohabiter Mutt et ProtonMail.

Installation et premier lancement

Pour installer mutt, il suffit d'installer le paquet du même nom :

sudo apt install mutt

En lancant pour la première fois la commande mutt, je reçois une erreur :

/var/mail/cedric: Aucun fichier ou dossier de ce type (errno = 2)

Je crée le fichier en question et je lui donne les permissions nécessaire à mon utilisateur :

sudo mkdir -p /var/mail/$(whoami)
sudo chown $(whoami):$(whoami) /var/mail/$(whoami)

J'en profite pour initialiser le fichier de configuration .muttrc

vim ~/.muttrc
set realname = "Your Name"
set header_cache =~/.mutt/cache/headers
set certificate_file =~/.mutt/certificates
set message_cachedir =~/.mutt/cache/bodies

Lancer une nouvelle fois la commande mutt, ne donne plus d'erreur.

[caption id="attachment_4409" align="alignnone" width="1024"] Premier écran du logiciel Mutt - un client mail en ligne de commande. Au moins, c'est épuré :-)[/caption]

Configuration de mutt

Note : je pars du principe que le Bridge pour Linux est installé et lancé.

J'ajoute au fichier de configuration .muttrc les lignes suivantes:

# "+" substitutes for `folder`
set mbox_type=Maildir
set folder=/var/mail/cedric/
set spoolfile=+INBOX
set record=+Sent
set postponed=+Drafts
set trash=+Trash
set mail_check=2 # seconds

# smtp
source ~/docs/keys/mail
set smtp_url=smtp://$my_user:$my_pass@127.0.0.1:1025
set ssl_force_tls
set ssl_starttls

Et dans le fichier ~/docs/keys/mail:

set my_user=EMAIL
set my_pass=MOT_DE_PASSE_DU_BRIDGE

Installation et configuration de OfflineIMAP

J'installe OfflineIMAP :

sudo pip install offlineimap

Puis je crée un fichier de configuration .offlineimaprc :

[general]
accounts = main

[Account main]
localrepository = main-local
remoterepository = main-remote

# full refresh, in min
autorefresh = 0.2

# quick refreshs between each full refresh
quick = 10

# update notmuch index after sync
postsynchook = notmuch new


[Repository main-local]
type = Maildir
localfolders = /var/mail/cedric

# delete remote mails that were deleted locally
sync_deletes = yes


[Repository main-remote]
type = IMAP
remoteport = 1143
remotehost = 127.0.0.1
remoteuser = EMAIL
remotepass = MOT_DE_PASSE_DU_BRIDGE
keepalive = 60
holdconnectionopen = yes

# delete local mails that were deleted on the remote server
expunge = yes

# sync only these folders
folderfilter = lambda foldername: foldername in ['INBOX', 'Archive', 'Sent']

# is broken, but connecting locally to bridge so should be ok
ssl = no

On lance la commande offlineimap, et, si tout s'est bien passé, on peut commencer à voir la progression de la synchronisation avec ProtonMail :

OfflineIMAP 7.2.1
  Licensed under the GNU GPL v2 or any later version (with an OpenSSL exception)
imaplib2 v2.57 (bundled), Python v2.7.14, OpenSSL 1.0.2g  1 Mar 2016
Account sync main:
 *** Processing account main
 Establishing connection to 127.0.0.1:1143 (main-remote)
 Creating folder INBOX[main-local]
 Creating new Local Status db for main-local:INBOX
 Creating folder Archive[main-local]
 Creating new Local Status db for main-local:Archive
 Creating folder Sent[main-local]
 Creating new Local Status db for main-local:Sent
Folder Archive [acc: main]:
 Syncing Archive: IMAP -> Maildir
Folder INBOX [acc: main]:
 Syncing INBOX: IMAP -> Maildir
Folder Archive [acc: main]:
 Copy message UID 1 (1/263) main-remote:Archive -> main-local:Archive
Folder INBOX [acc: main]:
 Copy message UID 1 (1/49) main-remote:INBOX -> main-local:INBOX
Folder Archive [acc: main]:
 Copy message UID 2 (2/263) main-remote:Archive -> main-local:Archive
Folder INBOX [acc: main]:
 Copy message UID 2 (2/49) main-remote:INBOX -> main-local:INBOX

Il ne reste plus maintenant qu'à relancer la commande mutt pour visualiser ses mails.

[caption id="attachment_4413" align="alignnone" width="1024"]Mutt est maintenant configuré pour fonctionner avec ProtonMail L'interface de Mutt une fois la configuration terminée[/caption]

Langserver.org

1 min read

" The Language Server protocol is used between a tool (the client) and a language smartness provider (the server) to integrate features like auto complete, go to definition, find all references and alike into the tool "

My Url Is

1 min read

"My Url Is features a new guest every two weeks to talk about how they got involved with the IndieWeb and what hopes, goals and aspirations they have for the community and for their website. The guests are a combination of those both new to the IndieWeb and those who have helped build it from the beginning."

I Need A Budget - Using YNAB with belgian bank accounts

1 min read

I recently discovered that budgeting might not be as boring as I thought. Better yet, budgeting might help me achieve my goals in life.

The problem is in this pre-PSD2/XS2A world, syncing my bank accounts with YNAB is a real pain and I tried to automate the process to the best that I could.

Current workflow :

  • Downloading my accounts statements in CSV from by bank (BNP Paribas Fortis) (manual - i tried to automate this step with iMacros for Firefox, but failed)
  • Parsing the CSV and converting it to a valid OFX file via https://csvconverter.biz/ (semi-manual, but at least i've got the file just right)
  • Import each file to YNAB through drag'n'drop (manual, but easy)

I started using YNAB only a week ago, I'll probably have a lot more to say about it in the next few months.

Identifier une régression grâce à git-bisect

3 min read

Enfer et damnation, vous venez de constater un bug dans votre code. Évidemment, il est difficile de savoir à quel moment cette régression est apparue et en trouver l'origine pourrait nous permettre de comprendre et donc de résoudre le bug.

Heureusement, git-bisect vient à votre secours, pour peu de savoir l'utiliser.

On commence donc par signifier à git que nous sommes dans un état "mauvais" du code :

git bisect bad

Vous devez démarrer avec "git bisect start"
Souhaitez-vous que je le fasse pour vous [Y/n] ? y

Il faut maintenant remonter suffisamment longtemps dans l'historique dans l'objectif de trouver l'état du code ou la régression constatée n'existait pas. Un petit git log devrait suffire à identifier le commit-id correspondant.

git checkout <commit-id>

Après avoir vérifié que la régression n'existait pas dans cet état du code, on signifie à git-bisect qu'on a une sous la main une version du code correcte.

git bisect good
Bissection : 132 révisions à tester après cette (à peu près 7 étapes)
[<commit-id>] <commit-message>

En retour, git-bisect nous donne le nombre de révisions à tester (ici : 132), et le nombre d'étapes estimées avant d'obtenir le nom du coupable (ici : 7). Enfin, git-bisect à effectué un checkout automatique sur un autre <commit-id> et attend vos instructions.

Il ne reste qu'a tester le code et à donner comme instruction soit un git bisect good, soit un git bisect bad en fonction du résultat observé. L'opération sera plus ou moins longue en fonction du nombre de commits à tester.

➜  webapp git:(6ae90d246) git bisect good
Bissection : 132 révisions à tester après cette (à peu près 7 étapes)
[49cbe40d5cb63b9f2a036560190983b2848d6df0] Merge branch 'master' into deploy/staging
➜  webapp git:(49cbe40d5) ✗ git bisect good
Bissection : 66 révisions à tester après cette (à peu près 6 étapes)
[dc9c093633ca9af720ae560b01ff455d4bd4fb51] <commit-message>
➜  webapp git:(dc9c09363) ✗ git bisect good
Bissection : 33 révisions à tester après cette (à peu près 5 étapes)
[4f8b4fd5f7ecb71141510823e89f3d941f6d892b] <commit-message>
➜  webapp git:(4f8b4fd5f) git bisect bad
Bissection : 16 révisions à tester après cette (à peu près 4 étapes)
[0e5acfb262de5f692f8383cd51fe5c4bed729b92] <commit-message>
➜  webapp git:(0e5acfb26) git bisect good
Bissection : 7 révisions à tester après cette (à peu près 3 étapes)
[7623848ffee8d72429623e3b5fb8fb1a8040aeed] <commit-message>
➜  webapp git:(7623848ff) ✗ git bisect good
Bissection : 4 révisions à tester après cette (à peu près 2 étapes)
[50f6b9ebf42ff5cda83d33d4489e944829f87c56] <commit-message>
➜  webapp git:(50f6b9ebf) ✗ git bisect good
Bissection : 2 révisions à tester après cette (à peu près 1 étape)
[d763c0336e13cbc91befbe853194dd077775e6cd] <commit-message>
➜  webapp git:(d763c0336) git bisect good
Bissection : 0 révision à tester après cette (à peu près 1 étape)
[c1af98fc24e031d0d87a567caa7615c0c2c3d66c] <commit-message>
➜  webapp git:(c1af98fc2) git bisect bad
Bissection : 0 révision à tester après cette (à peu près 0 étape)
[026f9bf37555815c0efc9dfb16e90473faacf48f] <commit-message>

Une fois la dernière étape passé, git-bisect vous donne l'identité du coupable :

git bisect bad
026f9bf37555815c0efc9dfb16e90473faacf48f is the first bad commit

Pour terminer, nous pouvons revenir à l'état initial du code (HEAD)

git bisect reset