Category Archives: Uncategorized

Ad Blocking with ddwrt

This was done on Asus RT-AC68U, running DD-WRT v3.0-r41686 std (12/10/19)

Let’s start with the script. This downloads two adlists and combines them into one. Then we’re restarting the service to pick up the changes. The reason for using curl instead of wget is because wget refused to work with https on my ddwrt build 🤷.

wget -qO /tmp/mvps
curl -k|grep "^" >> /tmp/mvps
killall -HUP dnsmasq
stopservice dnsmasq && startservice dnsmasq

Go to Administration -> Commands. Paste it in there and execute “Run Commands”.

Then, use the same command but execute it as Save Startup. Why? Well, I wanted to use a cron scheduler to run the script on a regular basis, but it just refused to work. Thus, I’m just scheduling a weekly reboot, which will trigger this command to update the ad lists 🤷

All you have left is to enable DNSMasq and Local DNS in Services tab. Then in the Additional Dnsmasq options add this:


Then go to Administration->Keep Alive and schedule a weekly/monthly reboot. Although, if the cron is broken in your build, this may not work either (to check, you can ssh to your router and check the timestamp on the /tmp/mvps file). In that case, you may just have to manually rerun the script from time to time to get the latest ad list.

Update 2020: I finally switched to pfsense and using pfBlockerNG provides a much better experience. Pi-hole is another great option – also much better than tinkering with dd-wrt.

Setting up a cron job on Mac

In this example, we’re setting up a job, which will run at 08:00 am daily and clean rails logs

Step 1 – create a file with what we want to run (


cd ~/code/rails_project
/Users/username/.rbenv/shims/bundle exec rake log:clear

Setp 2 – set up the cron scheduler:

$ env EDITOR=vim crontab -e

# Add the line to run the script at 8am daily:

0 8 * * * sh ~/scripts/ >/tmp/stdout.log 2>/tmp/stderr.log

Phoenix and Ecto. First Steps

Valid as of Phoenix 1.2

Show routes:
mix phoenix.routes

Generating resources:
mix phoenix.gen.html Post posts –no-model
mix phoenix.gen.json Post posts


  • :string
  • :integer
  • :map
  • :binary_id
  • :float
  • :boolean

Writing Queries
Two ways

  1. Query
    import Ecto.Query
    from p in context.Posts
    where p.Title.Contains("Stuff")
    select p;
  2. Expression
    |> where(titlle: "Stuff")
    |> limit(1)

Making changes –
changeset = Post.changeset(post, %{title: “updated”})

Generate migration:
mix ecto.gen.migration [migration_name] -r [repo]

Generate schema:
mix phoenix.gen.model [Schema] [table] [fields] -r [repo]

Run/Rollback migration
mix ecto.migrate -r [repo]
mix ecto.rollback -r [repo]

Generate migration:
Does not generate schema module:
mix ecto.gen.migration [migration_name] -r [repo]

Generates both schema model and a migration:
mix phoenix.gen.model [Schema] [table] [fields] -r [repo]

To avoid specifying repo all the time:
config :my_app, ecto_repos: [MyApp.Repo]

Setting up Elixir with Atom on Linux

Sublime is a pretty nice editor for working with Elixir, but I just can’t get the autocomplete plugin to work. So, giving Atom a try.

Install the following packages:

atom-elixir –
language-elixir –
linter (apm install linter) –
linter-elixirc –
script –

I use script to build within Atom (shift-ctrl-b). The only issue is that it seems to use the top-level folder of your project as a base path. So, if you try to do something like Code.load_file(“file.exs”) in one of your nested directories, it’ll try to load it from the top level directory.

Addendum for Mac
brew install elixir
brew install erlang

Set elixir path for autocomplete-elixir (if using Atom):

Parsing jQuery Unobtrusive Validation Parameters

Client-side parsing of unubtrusive jQuery validation parameters. Assuming we are setting up an unobtrusive validator named “validatorname” and want to pass “parameterfromserver” from the the server:

$.validator.unobtrusive.adapters.add('validatorname', ['parameterfromserver'], function(options) {
	options.rules['validatorname'] = {
		parameterfromserver: options.params['parameterfromserver']
	options.messages['validatorname'] = options.message;
$.validator.addMethod('validatorname', function(value, element, parameters) {
	var hereIsOurParameter = parameters.parameterfromserver;

One Hand Typing

If you have to type with one hand, AutoHotkey is a free option to turn your regular keyboard into a half mirror keyboard, where each key on one side is mirrored to the other (activate it by pressing Space key first).

Here’s a script, copied from AutoHotkey forum with slight modifications:

#SingleInstance, force
; Half-QWERTY: One-handed Typing - version 3a
; HalfKeyboard invented by Matias Corporation between 1992 and 1996
; Originally coded in AutoHotkey by jonny in 2004
; Many thanks to Chris for helping him out with this script.
; Capslock hacks and `~ remap to '" by Watcher
; This implementation was done by mbirth in 2007
; version 3a script, mod by hugov:
; 2008-10-31:
; - mixed with "Capitalize letters after 1 second hold" at request of Calibran
; just tested very briefly so try at your own peril :-)

KeyIsDown = 0
UpperDelay = 300
UpperDelay *= -1

RegRead KLang, HKEY_CURRENT_USER, Keyboard Layout\Preload, 1
StringRight KLang, KLang, 4
If (!KLang)
KLang := A_Language

If (KLang = "0407") {
; 0407 DE_de QWERTZ mirror set
original := "^12345qwertasdfgyxcvb"
mirrored := "ß09876poiuzölkjh-.,mn"
} Else If (KLang = "040c" || KLang = "040C") {
; 040c FR_fr AZERTY mirror set
original := "²&é" . """" . "'(azertqsdfgwxcvb" ; split up string for better
mirrored := ")àç" . "_" . "è-poiuymlkjh!:;,n" ; human readability
} Else {
; 0409 US_us QWERTY mirror set
original := "``" . "12345qwertasdfgzxcvb" ; split up string for better
mirrored := "'" . "09876poiuy;lkjh/.,mn" ; human readability

; Now define all hotkeys
Loop % StrLen(original)
c1 := SubStr(original, A_Index, 1)
c2 := SubStr(mirrored, A_Index, 1)
Hotkey Space & %c1%, DoHotkey
Hotkey Space & %c2%, DoHotkey
Hotkey %c1%, KeyDown
Hotkey %c1% UP, KeyUP
Hotkey %c2%, KeyDown ;
Hotkey %c2% UP, KeyUP ;


; This key may help, as the space-on-up may get annoying, especially if you type fast.
Control & Space::Suspend

; Not exactly mirror but as close as we can get, Capslock enter, Tab backspace.
Space & CapsLock::Send {Enter}
Space & Tab::Send {Backspace}

; If spacebar didn't modify anything, send a real space keystroke upon release.
+Space::Send {Space}
Space::Send {Space}

; General purpose
StartTime := A_TickCount
StringRight ThisKey, A_ThisHotkey, 1
i1 := InStr(original, ThisKey)
i2 := InStr(mirrored, ThisKey)
If (i1+i2 = 0) {
MirrorKey := ThisKey
} Else If (i1 > 0) {
MirrorKey := SubStr(mirrored, i1, 1)
} Else {
MirrorKey := SubStr(original, i2, 1)

Modifiers := ""
If (GetKeyState("LWin") || GetKeyState("RWin")) {
Modifiers .= "#"
If (GetKeyState("Control")) {
Modifiers .= "^"
If (GetKeyState("Alt")) {
Modifiers .= "!"
If (GetKeyState("Shift") + GetKeyState("CapsLock", "T") = 1) {
; only add if Shift is held OR CapsLock is on (XOR) (both held down would result in value of 2)
Modifiers .= "+"

If (KeyIsDown < 1 or ThisKey <> LastKey)
KeyIsDown := True
LastKey := ThisKey
Send %Modifiers%{%MirrorKey%}
SetKeyDelay, 65535
SetTimer, ReplaceWithUpperMirror, %UpperDelay%


IfWinNotExist, HalfKeyboard - permanent keyboard layout
Gui, +Owner +Toolwindow +AlwaysOnTop
Gui, Add, picture, x0 y0 w310 h104, %A_ScriptDir%\halfkeyboard_help.png
Gui, Show, w310 h104 NA, HalfKeyboard - permanent keyboard layout
Menu, Tray, Check, &Show Keyboard layout
Gosub, GuiClose

Menu, Tray, UnCheck, &Show Keyboard layout
Gui, Destroy


If (KeyIsDown < 1 or Key <> LastKey)
KeyIsDown := True
LastKey := Key
Send %Key%
SetKeyDelay, 65535
SetTimer, ReplaceWithUpper, %UpperDelay%

SetTimer, ReplaceWithUpper, Off
SetTimer, ReplaceWithUpperMirror, Off
KeyIsDown := False

SetKeyDelay, -1
Send {Backspace}+%LastKey%

SetKeyDelay, -1
Send {Backspace}+%MirrorKey%