Open phpstorm:// uri:s using xdg-open in Linux

I couldn’t get this to work properly on my Linux box; so I wrote a litte script that parses the uri scheme and launches phpstorm.

Script

<?php
$arg = $argv[1];
$parts = parse_url($arg);
$query = $parts['query'];
parse_str($query, $output);
$file = $output['file'];
$line = $output['line'];
$cmd = '/usr/bin/phpstorm --line ' . $line . ' ' . $file;
exec($cmd);

Then create a new file in ~/.local/share/applications/phpstorm-protocol.desktop

[Desktop Entry]
Name=PhpStorm Protocol Handler
Exec=/path/to/the/script %u
Terminal=false
Type=Application
MimeType=x-scheme-handler/phpstorm

Make it available, run:

update-desktop-database

and then register it with xdg-open

xdg-mime default phpstorm-protocol.desktop x-scheme-handler/phpstorm

Now, when you click a phpstorm:// link in your browser choose to open it with xdg-open.

Firefox lpr workaround

For some reason unknown to mankind, Firefox doesn’t allow you to print via lpr any more.

It used to be that if you had lpr enabled on the line gtk-print-backends= in your ~/.config/gtk-3.0/settings.ini, you would be able to print directly to lpr.

But recently (I’m using Firefox 60 at the moment) this doesn’t work.

After this workaround I only kept ”file” in my settings.ini.

[Settings]
gtk-print-backends=file

Workaround

My workaround was to create a simple script that watches a folder, if it finds a PDF, print it using lpr and then remove the file.

Then a simple systemd user script to get it running in the background.

The ”printy” script

Most beautiful bash script ever.

#!/usr/bin/env bash

PRINTDIR="/tmp/printy"

mkdir -p "$PRINTDIR"

while true; do 
  sleep 2

  for file in "$PRINTDIR"/*.pdf; do
    if [ -f "$file" ]; then
      cat "$file" | lpr -l && rm "$file"
    fi
  done
done

Change PRINTDIR to where you’ll print PDF:s to from Firefox.

systemd unit script

[Unit]
Description=Fucked up Firefox printing workaround script

[Service]
ExecStart=/home/ogg/bin/printy
Restart=always
RestartSec=2

[Install]
WantedBy=default.target

Save file in ~/.config/systemd/user/printy.service.

To keep the script running after you login/logout and reboot. Enable ”lingering” in systemd.

As root, run: systemctl enable-linger ogg

Then enable and start the script:

systemctl --user enable printy

and

systemctl --user start printy

Conclusion

If you do the above, whenever you need to print anything from Firefox, use ”Print to file” and place the PDF in /tmp/printy (if you use my script above).

Logga elförbrukning på ett lite annorlunda sätt

Alla sätt är bra utom de dåliga, eller?

Nedan finner ni ett litet knasigt exempel hur man kan logga data från en mätare utan möjlighet för extern avläsning annat än att titta på den med gluggarna man har i huvudet. Kan dock bli lite tråkigt i längden, så varför inte automatisera det hela lite.

Ingredienser

Vad jag använder mig av är 1 liten hård sak (kameratelefon), 1 stor hård sak (dator som kör FreeBSD) samt 4 mjuka saker:

  • En utdömd mobiltelefon med shysst kamera (en Nexus 5X i mitt fall (men den första prototypen använde jag en Nexus 7, funkade minst lika bra, dock lite klumpig och stor). Huvudsaken är att den kör Android.
  • En android app som heter IP Webcam Pro (kostar en dryg tjuga men det finns även en gratisvariant för extrema snåljåpar).
  • imagemagick – för att manipulera bilden lite innan jag läser den med ssocr.
  • ssocr – OCR mjukvara specifikt utvecklad för att läsa av displayer.
  • En dator som kör ett vettigt operativsystem, jag kör FreeBSD och för en gångs skull fanns ssocr i repot.

Nexus 5X

Bra telefon. Kanske lite overkill, men kollegan som köper ny telefon oftare än jag köper nya kalsonger (kanske även byter) hade en över med kasst batteri.

Går nog att få tag på en bättre begagnad kameratelefon för en 50-lapp och uppåt om man letar lite.

IP Webcam Pro

Kompetent liten app som gör din android enhet till en fullfjädrad webcam. Programmet har stöd för live video. Kan med några tillägg också själv ta kort och skicka upp ex. filer till en server. Inget jag använde mig av då det även har stöd att ta kort med curl. Pluspoäng på det. I mitt fall använder jag mig av den odokumenterade(?) URL:en http://x.x.x.x:8080/photoaf.jpg som gör att blixten fungerar och jag antar också kör autofocus.

Köp appen här eller om du är snål

ImageMagick

Gammal goding som kan allt. Eller varför inte prova fork:en GraphicsMagick.

Om jag ska vara ärlig så borde egentligen ssocr klara biffen utan bildmanipulation. Men, eftersom jag började pilla med att få till en bra bild till alla andra OCR program jag provade innan, och då lämpade sig ImageMagick bra.

ImageMagickGraphicsMagick

ssocr

Varför ssocr och inget annat OCR program? Provade ett par innan, tog alldeles för lång tid att få fart på dom. Hittade ssocr som verkade vara skrivet precis för att lösa mitt problem, funkade på en gång.

Källkod finns på GitHub

En dator

Mer cpu desto bättre. Har inte provat köra imagemagick med en massa filter på en raspberry pi, men det går säkert alldeles utmärkt om man kan leva med att det tar 15 sekunder att manipulera varje kort.

Förslag på lämplig dator

Prototyp 1

Nexus 7 hängandes i en hängsnara gjord av Cat6-kabel. Kanske inte världens mest stabila montering, men den fungerade.

Nexus 7:an saknar dock blixt på kameran; så den var värdelös i mörker.

Prototyp 2

Något stabilare upphängning gjord av en överbliven hyllkonsoll från IKEA, en Gorilla Pod knockoff från Kina och ett universal fäste med 1/4″ gäng.

Drog ett par skruv i taket bara och hängde upp skiten. Bor i ett gammalt hus med orenoverad källare, spelar mindre roll hur det ser ut =D.

Exempel på bildmanipulerings flöde

Ta ett kort

Börjar med att ta ett nytt kort. Som jag skrev tidigare, använder photoaf.jpg för att få blixten att fungera med IP Webcam Pro.

curl -s http://x.x.x.x:8080/photoaf.jpg -o original.jpg

Beskär bilden

Efter det så croppar jag bilden med ImageMagicks convert kommando.

convert original.jpg -crop 845x200+1710+1848 crop.jpg

Öka kontrasten

När det är klart ökar jag kontrasten en smula. ”Pris för stiligaste cli kommandot går 2017 till….”

convert crop.jpg +contrast +contrast +contrast +contrast +contrast +contrast +contrast +contrast +contrast +contrast level.png

Konvertera till svart/vitt

För att få tydligare siffror för ssocr, gör om till svartvitt.

convert level.png -threshold 42% threshold.gif

Skala om bilden

Av nån anledning så funkade ssocr nästan utan tweaks bäst med en bildstorlek som var ungefär lika som deras exempel. Så, skalar om bilden innan ssocr för göra sitt.

convert -resize 230 threshold.gif resize.png

Och till sist: gör om bilden till text med ssocr

ssocr -d 7 -t 10 resize.png
0077941

Voilá. Sen är det bara att logga på. Jag kör en gång var 15:e minut.

Efter att ha kört ett nästan ett dygn, så verkar jag göra av med strax under 1kWh per timme när jag kör pelletsbrännaren. Inte en blekaste om det är mkt eller lite; men det ska bli intressant att se hur väder/vind/utetemperatur och knasiga manicker som tar kort på elmätaren 4 gånger i timmen, påverkar elförbrukningen framöver.

Flashing in the dark

What to do when grub os-prober fails to detect Windows

  1. Find out your Windows partitions UUID
    $ sudo blkid /dev/sda2
  2. Add a custom entry to /etc/grub.d/40_custom
    menuentry "Windows" --class windows --class os {
       insmod ntfs
       search --no-floppy --set=root --fs-uuid <UUID>
       ntldr /bootmgr
    }

    Replace <UUID> with UUID in step 1.

  3. Update your grub config
    $ sudo update-grub
    
    or
    
    $ sudo grub-mkconfig > /boot/grub/grub.cfg

Use Let’s Encrypt SSL certificate on Mikrotik RouterOS

These are step by step instructions how to import and use a Let’s Encrypt SSL certificate on your Mikrotik routerboard.

There are a number of Let’s Encrypt clients out there. But my favourite so far is acme.sh by . The only requirement is a shell. Works fine running as a unprivileged user as well.

In the steps below, I’m using DNS validation, but of course you can use web based as well.

In that case forward a port to the computer running acme.sh and use –standalone and –httpport (if you use a non standard port) instead of –dns.

Installation

  1. Download and install acme.sh. Or, if you’re in ”dont-really- care-what-i-download-and-run”-mode:
    $ curl https://get.acme.sh | sh
  2. Then issue a new certificate:
    $ acme.sh --issue --dns -d router.mydomain.com
  3. Add the TXT record displayed to your DNS. Look for this:
    Domain: '_acme-challenge.router.mydomain.com' 
    TXT value: 'iamNo7r3alIaHacK3rbutItc4nBfunM3ss1nGaroUnD'
  4. After you’ve added your TXT record, issue a renewal:
    $ acme.sh --renew -d router.mydomain.com                                                                                                              [205/397] 
    [thu 12 jan. 2017 20:06:09 CET] Renew: 'router.mydomain.com' 
    [thu 12 jan. 2017 20:06:09 CET] Single domain='router.mydomain.com' 
    [thu 12 jan. 2017 20:06:09 CET] Getting domain auth token for each domain 
    [thu 12 jan. 2017 20:06:09 CET] Verifying:router.mydomain.com 
    [thu 12 jan. 2017 20:06:14 CET] Success 
    [thu 12 jan. 2017 20:06:14 CET] Verify finished, start to sign. 
    [thu 12 jan. 2017 20:06:15 CET] Cert success.
  5. Install your cert. And yes, you should specify the same file for –capath and –certpath.
    $ acme.sh --installcert -d router.mydomain.com \
              --capath /home/ogg/certs/router.mydomain.com.cer \
              --certpath /home/ogg/certs/router.mydomain.com.cer \
              --keypath /home/ogg/certs/router.mydomain.com.key
    [thu 12 jan. 2017 20:18:03 CET] Installing cert to:/home/ogg/certs/router.mydomain.com.cer
    [thu 12 jan. 2017 20:18:03 CET] Installing CA to:/home/ogg/certs/router.mydomain.com.cer
    [thu 12 jan. 2017 20:18:03 CET] Installing key to:/home/ogg/certs/router.mydomain.com.key

    You now have two files to upload to your Mikrotik device. router.mydomain.com.cer and router.mydomain.com.cer.

  6. Upload the two files to your Mikrotik. I’m assuming you have ssh enabled and can login.
    $ scp router.mydomain.com.key kutersv16-sw1:router.mydomain.com.key
    router.mydomain.com.key                              100% 1337     1.6KB/s   00:00
    $ scp router.mydomain.com.cer kutersv16-sw1:router.mydomain.com.cer
    router.mydomain.com.cer                              100% 8888     1.6KB/s   00:00
  7. SSH into your router and import the certificates
    /certificate import file-name=router.mydomain.com.cer
    /certificate import file-name=router.mydomain.com.key
    

    you can then verify they’re imported. Remember the name of your certificate (used in the last step).

    /certificate print
    Flags: K - private-key, D - dsa, L - crl, C - smart-card-key, A - authority, I - issued, R - revoked, E - expired, T - trusted
     #        NAME                       COMMON-NAME                 SUBJECT-ALT-NAME         FINGERPRINT                   
     0 K    T router.mydomain.com.cer_0  router.mydomain.com         DNS:router.mydomain.com  133713371337133713371337133...
     1   L  T router.mydomain.com.cer_1  Let's Encrypt Authority X3                           713371337133713371337133713...
  8. Final step, tell your www-ssl service to use the certificate.
    /ip service set www-ssl certificate=router.mydomain.com.cer_0

And that’s it!

acme.sh already have set up a cronjob for you doing the renewal. You can then use a shell script to automatically upload after renewal. To do so, point to that script –reload-cmd <scriptpath> for it to be run after renewal.

On the Mikrotik side, you can write a script that checks if there are any certs to import, import them. You can then run this using the Scheduler. Maybe once a day/week or so to make sure you never have outdated certificates.

Example scripts

install_cert.rsc
upload.bash

Hairpin NAT example

Here is an example config to configure a hairpin NAT on Mikrotik.

In this example I have a webserver on 192.168.88.80 and my Mikrotik router is on 192.168.88.1. After adding these rules I can access my webserver via my public IP from inside the LAN. Which is a nice feature.


/ip firewall nat
add action=masquerade chain=srcnat comment="default configuration" out-interface=ether01-WAN to-addresses=0.0.0.0
add action=masquerade chain=srcnat comment="hairpin nat" dst-address=!192.168.88.1 src-address=192.168.88.0/24
... other NAT rules
add action=dst-nat chain=dstnat comment="Forward port 80 to webserver on 192.168.88.80" dst-address=!192.168.88.1 dst-address-type=local dst-port=80 protocol=tcp \
to-addresses=192.168.88.80 to-ports=80

More information can be found here.

Use dnsmasq to resolve tld

When I develop webstuff, I sometimes use a vagrant box for the development. This is how I use dnsmasq to resolve all domains ending with <insert tld here> to one and the same IP (be it your local IP or that of, in my case, a vagrant box).

First. Install dnsmasq.

/etc/dnsmasq.conf

# listen only to this IP
listen-address=127.0.0.1

# file with dns servers
resolv-file=/etc/resolv.dnsmasq.conf

# resolve all .app tlds to this IP
address=/.app/192.168.10.10

/etc/resolv.dnsmasq.conf

Using this, you can use more than three servers (in Linux the max is 3, see /usr/include/resolv.h).

nameserver 10.0.0.47
nameserver 8.8.8.8
nameserver 8.8.4.4

/etc/resolv.conf

And finally use your dnsmasq server in your resolv.conf file.

nameserver 127.0.0.1

Whitelist senders in amavis

If you scan your outgoing mail, there may be times you don’t want check for spam on outgoing mail from a specific adress.

In that case, create a file listing the adresses you wish to whitelist, eg. /etc/amavisd.whitelist.

Then add the following rule to your amavisd.conf file.

read_hash(\%whitelist_sender, '/etc/amavisd.whitelist');
@whitelist_sender_maps = (\%whitelist_sender);

$interface_policy{'10026'} = 'VIRUSONLY';
$policy_bank{'VIRUSONLY'} = { # mail from the pickup daemon
 bypass_spam_checks_maps => ['@whitelist_sender_maps'], # don't spam-check this mail
 bypass_banned_checks_maps => ['@whitelist_sender_maps'], # don't banned-check this mail
 bypass_header_checks_maps => ['@whitelist_sender_maps'], # don't header-check this mail
};

The result being that you get virus checks but no spam checking. The headers are still added but look like:

X-Virus-Scanned: amavisd-new at mail.mrrobot.com
X-Spam-Flag: NO
X-Spam-Score: 0
X-Spam-Level:
X-Spam-Status: No, score=x required=6.2 WHITELISTED tests=[]
	autolearn=unavailable

and not like before

X-Virus-Scanned: amavisd-new at mail.mrrobot.com
X-Spam-Flag: YES
X-Spam-Score: 7.025
X-Spam-Level: *******
X-Spam-Status: Yes, score=7.025 required=6.2 tests=[BAYES_40=-0.001,
	DNS_FROM_AHBL_RHSBL=2.699, FSL_HELO_NON_FQDN_1=0.001,
	HELO_LOCALHOST=3.828, MISSING_MID=0.497, RCVD_IN_SORBS_DUL=0.001]
	autolearn=no

Tested on amavisd-new-2.8.0.

Alesis Multimix Firewire 12

I own an old (really old in technology years) Alesis MultiMix Firewire 12. It’s a pretty decent mixer with a firewire interface which allows you to record up to 12 channels simultaneously. It was my first ”semi- professional” audio interface and it served me well. Up until it got old (or more probable is that I ”upgraded” to something fancier).

Anyway. I was reading a forum post over at Alesis, and saw more than one thread with complaints that there are no recent drivers for this board.

I hadn’t used my Multimix Firewire 12 in years, so I took it out of the closet and plugged it in. Again, no drivers availble. But, what the hell. I downloaded the latest ones from Alesis ”legacy” page (they’re released in 2011 i think) and installed them. The installation went just fine. No smoke or anything. Kind of disappointing.

Anyway, after a reboot. I have managed to use it without hiccup for an hour or so. And it is rock solid. I tried Propellerheads Reason with 64 samples buffer size and works just fine. The input latency I get is about 3ms. Which is really good.

Alesis Multimix driverI have not tried recording multiple tracks at once. But one channel works just fine. No clipping, pops, and whatnot I remembered I occasionally had with this board back in the day when I didn’t have a ”supercomputer” and ran Windows.

On a side note. If you actually run the driver installer it clearly says under requirements, ”Mac OS X 10.7.0 or higher”. Last I checked, 10.10.5 (which I’m on as I’m writing this) is ”higher” =D.

Maybe I also should mention I’m *not* using Apple hardware. I’m on a ”hackintosh” I built about 3-4 years ago. So your milage may vary, of course.

But, to all folks complaining. Do less complaining and more experimenting. You could actually end up surprised and the drivers might actually ”just work”.

I for sure am going to use this board more, since I’ve had some trouble with my Motu 828mk3 lately with lockups and freezes when just mixing. And the Motu is still ”supported” and has drivers dated October 2014. But I’m not complaining. I know I’m on my own when I run a Hackintosh.

Postfix byta ut trasig avsändaradress i mailkö

Så, jag, erhm, ”glömde” ändra avsändaradress på en av våra servrar häromdagen vilket resulterade i en massa post på e-postservern som lagda på kö eftersom avsändande domän inte existerade. Här är hur jag ordnade det.

Först, skapade jag en map fil där du anger den adressen du vill byta ut mot den korrekta adressen som så:

vim /etc/postfix/sender_canonical
sender@oldomain.nx  sender@newexistingdomain.com

kör

postmap /etc/postfix/sender_canonical

lägg sedan till följande i /etc/postfix/main.cf

sender_canonical_maps = hash:/etc/postfix/sender_canonical

efter det, ladda om postfix

service postfix reload

köa om alla köade mail (eller använd -i för att köa om ett specifict id)

postqueue -f

sen kan du flusha kön om du inte vill vänta

postfix flush

och det var det! Nu kommer alla mail som hade den felaktiga avsändardomänen skickas iväg!