Link

Snippets

Table of contents

  1. 1984.is: Updating a DNS entry
  2. Ansible: retrieve variables from a node
  3. ADB Cookbook
  4. b2: Update Cache-Control
  5. Bash: Block comment
  6. Bash: Beautifully reformating paragrapghs
  7. Bash: Check if script is already running
  8. Bash: Colorize cat output only if not followed by pipe (|)
  9. Bash: I/O Redirection
  10. Β Bash: Print executed command
  11. Bash: Remove special chars from var
  12. Bash: Substring
  13. Brave: Customizing β€œnew tab” page
  14. Brave: Enable picture in picture
  15. cat: Syntax highlighting/colorizing cat
  16. ccxt: Nasty but simple balance parsing
  17. ccxt.pro: ERROR: β€œFailed opening required β€˜vendor/autoload.php’” when installing on Sillicon Mac
  18. CDN: Checking resource integrity
  19. Cloudflare: Setting up a tunnel
    1. To run cloudflared as a service
    2. Potentially fix wrong plist file on MacOS
  20. Conbee II: Api notes
  21. cURL: Sending an e-mail
  22. dd: storage speed test (useful for testing external drives)
  23. Docker: Shitty problem which drives you nuts
  24. Docker: Traefik β€’ Parse specific service logs
    1. Looking for a specific referer
  25. Espurna: Flashing an ESP-01
  26. Espurna: Pulse API call
  27. Ethereum: Kovan testnet faucet
  28. Fonts: Downloading website fronts
  29. Git: Doing something before pushing with hooks
  30. Git: Merge a single file from a branch to another one
  31. Git: Post-merge hook example (run action after β€œgit pull)
  32. GnuPG: Encrypt and sign and then decrypt
  33. Β Go: go install xxx -> can’t load package: package github.com
  34. Go: Fetching all project dependencias at once
  35. Google Sheets: Timestamping a cell based on a specific sheet modification
  36. Hetzner: Proxmox Networking: Routed
  37. Jekyll: adding pngout support to image_optim
  38. Jekyll: Checking image_optim_pack settings
  39. Jekyll: Insensitive sort
  40. Jekyll: Raw code blocs
  41. Jekyll: rfc3986_parser.rb:21:in `split’: URI must be ascii only
  42. Kindle: Hacks Information
  43. jq: Query example
  44. Kindle 3: Flash fs and kernel on bricked device
  45. Kindle 3: Jailbreak
  46. Kindle 3: UsbNetwork
  47. Kindle 3: Full screen terminal
    1. Keyboard mapping
  48. locales: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
  49. macOS: Enable locate (mlocate / updatedb)
  50. macOS: Disable Spotlight
  51. macOS: Install cp210x drivers
  52. macOS: Install xcode
  53. macOS: Disable screen lock after Apple Remote Desktop Session ends
  54. macOS: Set environment variables for GUI apps
  55. Matplotlib: List plot config params
  56. Mikrotik: Port knocking
  57. Node: npm install error: no template named β€˜remove_cv_t’
  58. OpenWRT: ER-X read-only issue
  59. OSX: Install GNU core utils with default names (updated)
  60. OSX: Mounting Hetzner storagebox
  61. Pandas: Coloring positive / negative on cli
  62. Pandas: Column type definition (fast and easy)
  63. Pandas: From json object to DataFrame
  64. Pandas: Prevent output wrapping
  65. Pandas: Plotting cool donut charts
  66. Philips TV: Turning it on and off with python
  67. pipx: Run Python Applications in Isolated Environments
  68. pip: pip install gevent fails on MacOS M1 Sillicon
  69. PostgreSQL: Dump databases (backing up db)
  70. PostgreSQL: Kill active sessions
  71. PostgreSQL: 101 - psycopg2 class
  72. PostgreSQL: Error permission denied for table prices
  73. PostgreSQL: Restore previous dump
  74. PostgreSQL: Trigger data copy to transactional on insert/update
  75. PostgreSQL: Trigger timestamp update on insert
  76. Proxmox: Resizing KVM guest LV
  77. Proxmox Running tailscale inside of a LXC container
  78. Python: Assigning dynamic variable names
  79. Python: Binance balances to CSV
  80. Python: Cryptography fails to install
  81. Python: Disabling en enabling stdout output
  82. Python: Find element on dict_tuple
  83. Python: Fetch script execution path
  84. Python: IDLE can’t import Tkinter
  85. Python: Print numbers with at least X digits
  86. Python: Parsing arguments with argparse
    1. Initial setup
    2. Passing command line arguments
    3. Regular arguments ussage
    4. Advanced usage
  87. Python: Print imported modules version
  88. Python: Pretty print JSON
  89. Python: Print all declared variables
  90. Python: pyaudio fails to install on MacBook M1 (Sillicon)
  91. Python: pyenv not switching $PATH
  92. Python: RSA key pair generation
  93. Python: pip install nacl fails on MacBook M1 (Sillicon)
  94. Python: pip upgrading all packages at once
  95. Python: strftime reference cheatsheet
  96. Python: The Python ssl extension was not compiled. Missing the OpenSSL lib?
  97. Python: line 21: /usr/local/Cellar/pyenv/1.2.21/libexec/pyenv: No such file or directory
  98. Python Binance: Timestamp for this request was 1000ms ahead of the server’s time
  99. python-binance: API key & secret
  100. python-binance: Get price for each available pair
  101. python-binance: Updating all pairs on PostgreSQL
  102. Raspberry Pi: Getting ddcutil to work on RPi 4
  103. Raspberry Pi: Installing Python 3.8.1 + pyenv
  104. Raspberry Pi: Not booting when powering LCD through USB
  105. Raspberry Pi: Mounting filesystem over ssh
  106. Raspberry Pi: Setting up an Alfa AWUS036ACS 802.11ac adapter
  107. Raspberry Pi: UAS issues when using USB3.0 SSD drives
  108. Safari: Paywalls Bypass bookmarklet
  109. screen: Restarting a command inside a screen session
  110. sed: recursively replacing a string (gsed/sed)
  111. Silicon: Installing HDF5 / h5py on Mac Silicon Processors
  112. SSH: Exposing local service behind NAT through reverse SSH tunnel
  113. SSH: Using ProxyCommand
  114. SSH: Nasty reverse tunnel
  115. Solana: Managing Ledger Nano S with Solana CLI
  116. Solana: Stacking from Ledger S
  117. Telegram: Fetch chat id
  118. Telegram: Fetch last message
  119. Telegram: Python snippet for sending messages
  120. TkInter: Install on macOS
  121. Ubiquiti: Unifi client not detecting JDK
  122. Ubuntu: get network interfaces name
  123. Ubuntu: installing Eternal Terminal
  124. VSCodium: Create VSIX file from GitGub repo
  125. VSCodium: Enable VS Code Extensions Marketplace
  126. Wallabag: manually activating a user
  127. xbar: TOTP widget
  128. Yowsup: Installing, pathing and registering
  129. Yubikey: Enable/disable touch policy

1984.is: Updating a DNS entry

curl "https://api.1984.is/1.0/freedns/?apikey=<API KEY>&domain=<DOMAIN.COM>&ip=<IP ADDRESS>"

Keep in mind the DNS entry must already exists, otherwise this call will fail.


Ansible: retrieve variables from a node

ansible -m setup hal900.space.odyssey -i hosts/space-odissey/inventory | sed 's#.*SUCCESS =>##'

ADB Cookbook

Send text to TV:

atext ()
  {
    cleantext=$(echo "$@"|sed 's;Γ±;n;g');
    adb shell input text "${cleantext}" || adb kill-server;
    adb start-server;
    adb connect ${ANDROID_IP} && adb shell input text "${cleantext}"
  }
  • alias adb shell: alias atv='adb kill-server; adb start-server; adb connect ${ANDROID_IP}:5555; adb shell
  • Wake-up TV: adb shell input keyevent KEYCODE_WAKEUP
  • Play specific video onb YouTube: am start -a android.intent.action.VIEW -d https://www.youtube.com/watch?v=Fy1xQSiLx8U
  • Set volume to min (00): service call audio 3 i32 3 i32 0 i32
  • Set volume to max (60): service call audio 7 i32 3 i32 60 i32 0
ANDROID_IP="192.168.1.25"
# Connect to TV
adb kill-server; adb start-server; adb connect ${ANDROID_IP}:5555
# Set volume to 0
adb shell service call audio 3 i32 3 i32 0 i32
# Wake up TV
adb shell input keyevent KEYCODE_WAKEUP; sleep 10
# Open a YouTube video
adb am start -a android.intent.action.VIEW -d "https://www.youtube.com/watch?v=Fy1xQSiLx8U"
# Set volume to 25%
service call audio 7 i32 3 i32 15 i32 0
sleep 30
# Set volume to 50%
service call audio 7 i32 3 i32 50 i32 0


---

## **ARD**: Apple Remote Desktop session unresponsive

When an ARD session becomes unresponsive it may prevent new connections to be established.

As workaround, simply kill `screensharingd`.

```shell_session
sudo kill "$(netstat -vanp tcp|grep '.5900 '|awk '{print $9}'|head|sort -nr|uniq|head -1)"

or

sudo killall screensharingd

b2: Update Cache-Control

$ b2 update-bucket --bucketInfo '{"cache-control":"max-age=60"}' bucketName allPublic
{
    "accountId": "a11111111111111",
    "bucketId": "12345123451234512345",
    "bucketInfo": {
        "cache-control": "max-age=60"
    },
    "bucketName": "bucketName",
    "bucketType": "allPublic",
    "corsRules": [
        {
            "allowedHeaders": [
                "authorization",
                "range"
            ],
            "allowedOperations": [
                "b2_download_file_by_id",
                "b2_download_file_by_name"
            ],
            "allowedOrigins": [
                "https"
            ],
            "corsRuleName": "downloadFromAnyHttpsOrigin",
            "exposeHeaders": null,
            "maxAgeSeconds": 3600
        }
    ],
    "lifecycleRules": [],
    "options": [
        "s3"
    ],
    "revision": 5
}

Bash: Block comment

: <<'block_comment'
This is a
block comment
block_comment

Bash: Beautifully reformating paragrapghs

Example 1:

1. We the people of the United States.
2. In order to form a more perfect union.
3. Establish justice, ensure domestic
  tranquility.
4. Provide for the common defense

Becomes after par 37p13dh:

1. We the people of the
   United States.
2. In order to form a more
   perfect union.
3. Establish justice,
   ensure domestic
   tranquility.
4. Provide for the common
   defense

Example 2:

amc> The b option was added primarily to deal with
amc> this new style of quotation
amc> which became popular after Par 1.41 was released.
amc>
amc> Par still pays attention to body characters.
amc> Par should not mistake "Par" for part of the prefix.
amc> Par should not mistake "." for a suffix.

Becomes after par B=._A_ a 50bg:

amc> The b option was added primarily to
amc> deal with this new style of quotation
amc> which became popular after Par 1.41
amc> was released.
amc>
amc> Par still pays attention to body
amc> characters.  Par should not mistake
amc> "Par" for part of the prefix.  Par
amc> should not mistake "." for a suffix.

Bash: Check if script is already running

#!/bin/bash

# check if we are the only local instance
if [[ "`pidof -x $(basename $0) -o %PPID`" ]]; then
  echo "Script already running with PID `pidof -x $(basename $0) -o %PPID`"
 exit
fi

It can even be made a one-liner:

if [[ "`pidof -x $(basename $0) -o %PPID`" ]]; then exit; fi

Bash: Colorize cat output only if not followed by pipe (|)

In .bashrc or .bash_profile:

cat() {
  local command
  command='pygmentize -f terminal256 -O style=native -g'

  if [[ -t 1 ]]; then
      $command "$@"
  else
      command cat "$@"
  fi
}

Bash: I/O Redirection

The main idea to clear things up is this:

The redirections get applied from RIGHT to LEFT, opposite of the way English speakers normally read.

So this code:

command > filename 2>&1

redirects stderr to stdout first (2>&1) and then sends stdout(including the redirected stderr) to filename (> filename). Here is the ABSG explanation (Ch. 20).

This code:

command >>/dev/null 2>&1

redirects stderr and stdout to /dev/null … which means to nowhere. Things sent to /dev/null are not saved, cached, or remembered in any way.

They are just sent to β€˜nowhere’ and forgotten. This is a way of running programs and making sure they produce NO output and will never be seen on the command line or in a log file.


Β Bash: Print executed command

0 βœ“ $ exe ls -rtl $HOME | head -4
$ exe ls -rtl $HOME | head -4 ls -rtl /Users/steve
total 314159
-rw-------     1 steve  boss     314159 Jan 19  2019 conquer_the_world_v1.txt
-rw-------     1 steve  boss     314159 Jan 20  2019 conquer_the_world_good_OK_printThis.txt
0 βœ“ $
# Function to display commands
exe() { echo "\$ $@" ; "$@" ; }

Bash: Remove special chars from var

0 βœ“ $ VAR=1.2.3
0 βœ“ $ echo "${VAR//.}"
123
0 βœ“ $

Or just remove any special character:

0 βœ“ $ VAR=1.2.3-4_5POTATO
0 βœ“ $ echo $VAR
1.2.3-4_5POTATO
0 βœ“ $ echo ${VAR//[^[:alnum:]]/}
12345POTATO
0 βœ“ $

Bash: Substring

0 βœ“ steve@hal9000 ~ $ proportion="16:9"
0 βœ“ steve@hal9000 ~ $ echo ${proportion%:*}
16
0 βœ“ steve@hal9000 ~ $ echo ${proportion##*:}
9
0 βœ“ steve@hal9000 ~ $

Brave: Customizing β€œnew tab” page

Go to: brave://new-tab-page


Brave: Enable picture in picture

Go to: brave://flags/#enable-experimental-web-platform-features

Enable:

  • Experimental Web Platform features
  • Surfaces for videos
  • Picture in Picture

cat: Syntax highlighting/colorizing cat

First, install pygments:

# sudo apt-get install python3-pygments
Reading package lists... Done
Building dependency tree
Reading state information... Done
Suggested packages:
  python-pygments-doc ttf-bitstream-vera
The following NEW packages will be installed:
  python3-pygments
0 upgraded, 1 newly installed, 0 to remove and 92 not upgraded.
Need to get 579 kB of archives.
After this operation, 3246 kB of additional disk space will be used.
Get:1 https://mirror.hetzner.com/ubuntu/packages focal-updates/main amd64 python3-pygments all 2.3.1+dfsg-1ubuntu2.2 [579 kB]
Fetched 579 kB in 0s (2092 kB/s)
Selecting previously unselected package python3-pygments.
(Reading database ... 38524 files and directories currently installed.)
Preparing to unpack .../python3-pygments_2.3.1+dfsg-1ubuntu2.2_all.deb ...
Unpacking python3-pygments (2.3.1+dfsg-1ubuntu2.2) ...
Setting up python3-pygments (2.3.1+dfsg-1ubuntu2.2) ...

[0:1907] 09:57:48 Wed Oct 27 [root@tradelab-4gb-hel1:/dev/pts/0 +1]

Then set-up the following β€œalias”:

[0:1924] 10:02:38 Wed Oct 27 [root@tradelab-4gb-hel1:/dev/pts/0 +1] ~/freqtrade
# cat ~/.bashrc|egrep -B3 -A20 'pygmentize'

# Install http://pygments.org/download/ to use this improved cat!
cat() {
  if command -v pygmentize > /dev/null; then
    pygmentize $1 > /dev/null 2>&1
    if [ $? -eq 0 ]; then
      pygmentize $1
    else
      command cat $1
    fi
  else
    command cat $1
  fi
}

[0:1925] 10:02:55 Wed Oct 27 [root@tradelab-4gb-hel1:/dev/pts/0 +1] ~/freqtrade
#

ccxt: Nasty but simple balance parsing

balance_raw = binance.fetch_balance()

for k, v in balance_raw.items():
    for i, j in v.items():
        try:
            if float(j) > 0 and i.isupper():
                print(i, "balance:", j)
        except:
            pass

ccxt.pro: ERROR: β€œFailed opening required β€˜vendor/autoload.php’” when installing on Sillicon Mac

Error message:

Fatal error: main(): Failed opening required 'vendor/autoload.php' (include_path='.:') in /Users/steve/Documents/code/ccxt.pro/php/test/syntax.php on line 18

Fix:

[0:531] 12:39:14 Mon Oct 25 [steve@macbook.lan:/dev/ttys013 +1] ~/Documents/code/ccxt.pro
$ npm install ololog

changed 4 packages, and audited 435 packages in 7s

37 packages are looking for funding
  run `npm fund` for details
[...]
[0:529] 12:38:33 Mon Oct 25 [steve@macbook.lan:/dev/ttys013 +1] ~/Documents/code/ccxt.pro
$ composer install --ignore-platform-reqs
Installing dependencies from lock file (including require-dev)
Verifying lock file contents can be installed on current platform.
Package operations: 23 installs, 0 updates, 0 removals
  - Downloading symfony/polyfill-mbstring (v1.23.1)
  - Downloading pear/console_table (v1.3.1)
[...]
  - Installing recoil/kernel (1.0.3): Extracting archive
  - Installing recoil/react (1.0.2): Extracting archive
Generating autoload files
9 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

[0:530] 12:38:36 Mon Oct 25 [steve@macbook.lan:/dev/ttys013 +1] ~/Documents/code/ccxt.pro
$ composer require composer.json

Now you should be ready to install:

0:533] 12:40:41 Mon Oct 25 [steve@macbook.lan:/dev/ttys013 +1] ~/Documents/code/ccxt.pro
$ /Users/steve/.pyenv/versions/3.9.1/bin/python -m pip install python/Processing ./python
Requirement already satisfied: setuptools>=38.5.1 in /Users/steve/.pyenv/versions/3.9.1/lib/python3.9/site-packages (from ccxtpro==0.8.72) (49.2.1)
Requirement already satisfied: certifi>=2018.1.18 in /Users/steve/.pyenv/versions/3.9.1/lib/python3.9/site-packages (from ccxtpro==0.8.72) (2020.12.5)
[...]
Requirement already satisfied: pycparser in /Users/steve/.pyenv/versions/3.9.1/lib/python3.9/site-packages (from cffi>=1.12->cryptography>=2.6.1->ccxtpro==0.8.72) (2.20)
Installing collected packages: ccxtpro
  Found existing installation: ccxtpro 0.8.72
    Uninstalling ccxtpro-0.8.72:
      Successfully uninstalled ccxtpro-0.8.72
  Running setup.py install for ccxtpro ... done
Successfully installed ccxtpro-0.8.72
You are using pip version 18.1, however version 21.3.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

[0:534] 12:40:54 Mon Oct 25 [steve@macbook.lan:/dev/ttys013 +1] ~/Documents/code/ccxt.pro
$

CDN: Checking resource integrity

0 βœ“ steve@hal9000 ~ $ cat my-library.min.js | openssl dgst -sha384 -binary | openssl base64 -A
qlMqLZhXLZLzxOaFSx7Nx3+IHI2dhNZ2+o2HwD+/z2wONMHqwfxh2VWS1HOxGgJ9
0 βœ“ steve@hal9000 ~ $
<script
  src="/assets/js/my-library.min.js"
  crossorigin="anonymous"
  integrity="sha384-qlMqLZhXLZLzxOaFSx7Nx3+IHI2dhNZ2+o2HwD+/z2wONMHqwfxh2VWS1HOxGgJ9"
></script>

Cloudflare: Setting up a tunnel

Install client:

brew install cloudflare/cloudflare/cloudflared

Log in the cloudflare client:

cloudflared tunnel login

Create a new tunnel and save the tunnel id which resembles to this: XXXXXXXXX-11111-22HH22-87383-XXXXXXXX

cloudflared tunnel create potato

Double check:

cloudflared tunnel list

Create a config file named config.yaml like the following on ~/.cloudflared:

[0:515] 07:12:36 Tue Oct 26 [steve@macbook.lan:/dev/ttys006 +1] ~/.cloudflared
$ cat config.yaml
url: http://localhost:11111
tunnel: XXXXXXXXX-11111-22HH22-87383-XXXXXXXX
credentials-file: /Users/steve/.cloudflared/XXXXXXXXX-11111-22HH22-87383-XXXXXXXX.json

Set routing rules:

cloudflared tunnel route dns XXXXXXXXX-11111-22HH22-87383-XXXXXXXX potato.mydomain.com

Start the tunnel with cloudflared tunnel run and you’re good to go!

To run cloudflared as a service

cloudflared service install

Or just run it manually everytime with launchctl start com.cloudflare.cloudflared.

Potentially fix wrong plist file on MacOS

File /Library/LaunchDaemons/com.cloudflare.cloudflared.plist does by default carry a misconfigured param which prevents the service to start. Ensure the ProgramArguments looks like the one below:

<key>ProgramArguments</key>
<array>
  <string>/usr/local/bin/cloudflared</string>
  <string>tunnel</string>
  <string>run</string>
</array>

Conbee II: Api notes

Get configuration:

~ $ curl -X GET 172.99.99.99:40850/api/<API KEY>/config
{"UTC":"2020-02-05T23:53:59","apiversion":"1.16.0","backup":{"errorcode":0,"status":"idle"},"bridgeid":"00212EFFFF040971","datastoreversion":"60","devicename":"RaspBee","dhcp":true,"factorynew":false,"fwversion":"0x00000000","gateway":"172.30.33.1","internetservices":{"remoteaccess":"disconnected"},"ipaddress":"172.99.99.99","linkbutton":false,"localtime":"2020-02-06T00:53:59","mac":"02:42:ac:1e:21:03","modelid":"deCONZ","name":"Phoscon-GW","netmask":"255.255.254.0","networkopenduration":180,"panid":0,"portalconnection":"disconnected","portalservices":false,"portalstate":{"communication":"disconnected","incoming":false,"outgoing":false,"signedon":false},"proxyaddress":"none","proxyport":0,"replacesbridgeid":null,"rfconnected":false,"starterkitid":"","swupdate":{"checkforupdate":false,"devicetypes":{"bridge":false,"lights":[],"sensors":[]},"notify":false,"text":"","updatestate":0,"url":""},"swupdate2":{"autoinstall":{"on":false,"updatetime":""},"bridge":{"lastinstall":"2019-12-12T12:40:44","state":"noupdates"},"checkforupdate":false,"install":false,"lastchange":"","lastinstall":"","state":"noupdates"},"swversion":"2.5.72","timeformat":"24h","timezone":"Europe/Madrid","uuid":"fa488d75-d4f0-4115-8010-a0f2d1d86159","websocketnotifyall":true,"websocketport":8081,"whitelist":{"<API KEY>":{"create date":"2020-02-02T09:19:20","last use date":"2020-02-05T23:53:59","name":"Home Assistant"},"4EEAD724A8":{"create date":"2020-02-02T09:27:10","last use date":"2020-02-02T09:32:58","name":"Phoscon#B1156x803"},"A1D8210D14":{"create date":"2020-02-02T09:11:18","last use date":"2020-02-02T09:11:21","name":"Phoscon#B1156x803"},"ECA1166E78":{"create date":"2020-02-04T14:07:53","last use date":"2020-02-04T14:07:58","name":"Phoscon#B1145x803"}},"zigbeechannel":0}
~ $

Reset gateway:

~ $ curl -X POST 172.99.99.99:40850/api/<API KEY>/config/reset -H "Content-Type: application/json" -d '{"resetGW": true, "deleteDB": true}'

Reset password (only available during the first 10 minutes after gateway boots):

~ $ curl -X DELETE 172.99.99.99:40850/api/<API KEY>/config/reset/password
[{"error":{"address":"/config/reset/password","description":"method, DELETE, not available for resource, /config/reset/password","type":4}}]~ $
~ $

cURL: Sending an e-mail

curl --url 'smtps://<SMTPS FQDN>:465' \
    --ssl-reqd \
    --mail-from '<FROM EMAIL ADDRESS>' \
    --mail-rcpt '<TO EMAIL ADDRESS>' \
    --upload-file <ATTACHMENT> \
    --user '<USERNAME / EMAIL ADDRESS>:<PASSWORD>'

dd: storage speed test (useful for testing external drives)

Write speed:

dd if=/dev/zero of=/mnt/sda1/test.tmp bs=500K count=1024

Read speed:

dd if=/mnt/sda1/test.tmp of=/dev/null bs=500K count=1024

Docker: Shitty problem which drives you nuts

You’ve probably restarted the master and HC_Volume_3578474 wasn’t mounted on /var/lib/docker/overlay2, so docker started creating new volumes for local instances and complained about missing volumes.

cat /etc/fstab |Β grep HC_Volume_3578474
ls -l /var/lib/docker/overlay2
cd /var/lib/docker/overlay2
ls -l
cd ..
ls -l
mv overlay2 overlay2_bkp2
mount -a
cd overlay2

Docker: Traefik β€’ Parse specific service logs

cat access.log |jq '. | select(.ServiceName | contains("<SERVICE_NAME>"))'

Looking for a specific referer

tail -100f access.log |jq '. | select(.request_Referer | try contains("admin"))'

Espurna: Flashing an ESP-01

esptool.py --port /dev/cu.wchusbserial1410 erase_flash

## Chinese copies sometimes require to use an "inv.bin" build
esptool.py --port /dev/cu.wchusbserial1410 write_flash --flash_mode dout 0x00000 ~/Downloads/espurna-1.13.5-generic-esp01s-relay-40-inv.bin

Espurna: Pulse API call

http://<DEVICE_IP>/api/pulse/0?apikey=<API_KEY>&value=3

Ethereum: Kovan testnet faucet

https://gitter.im/kovan-testnet/faucet

Block explorer: https://kovan.etherscan.io/


Fonts: Downloading website fronts

0 βœ“ steve@hal9000 ~/Downloads $ for font in $(grep ' src:url(' <CSS_FILE_NAME>.css |
>     awk -F 'src\:url' '{print $2}' |
>     tr -d '();' |
>     rev |
>     cut -d'/' -f1 |
>     rev); do
>     msg_info "Downloading ${font}."
>     wget --quiet https://<FQDN>/fonts/woff/${font}
> done
awk: warning: escape sequence `\:' treated as plain `:'
 🌻  Downloading xxx.woff.
 🌻  Downloading xxx.woff.
     [...]
 🌻  Downloading xxx.woff.
0 βœ“ steve@hal9000 ~/Downloads $

Git: Doing something before pushing with hooks

$ cat .git/hooks/pre-commit
#!/bin/sh
pythonpath='/Users/steve/code/pythonlib/'

cp -p "${pythonpath}"/exchanges.py ./local_libs/.
cp -p /Users/steve/code/metrics/settings.py ./local_libs/settings.py

git add ./local_libs/*.py

exit 0
$

Git: Merge a single file from a branch to another one

Given the fact that we’re on a branch where we are missing a file we want to merge from a different branch.

[0:225] 01:14:20 Sat Oct 09 [steve@scheduler:/dev/pts/0 +1] ~/code/pythonlib
# git checkout --patch dev -- binance_dust.py
diff --git b/binance_dust.py a/binance_dust.py
new file mode 100644
index 0000000..f546035
--- /dev/null
+++ a/binance_dust.py
@@ -0,0 +1,83 @@
+from binance.client import Client
+import configparser
+import os
+from utils import colorize
[...]
+if __name__ == "__main__":
+  run()
\ No newline at end of file
(1/1) Apply this hunk to index and worktree [y,n,q,a,d,e,?]? y


[0:226] 01:14:42 Sat Oct 09 [steve@scheduler:/dev/pts/0 +1] ~/code/pythonlib
# ls -rtl
total 44
-rw-r--r-- 1 root root 4152 Oct  2 22:42 blockchain.py
-rwxr-xr-x 1 root root 1421 Oct  2 22:42 b2.py
-rw-r--r-- 1 root root  107 Oct  2 22:42 __init__.py
-rw-r--r-- 1 root root   98 Oct  2 22:42 requirements.txt
-rw-r--r-- 1 root root  233 Oct  2 22:42 colors.py
drwxr-xr-x 2 root root 4096 Oct  9 13:14 __pycache__
-rw-r--r-- 1 root root 2661 Oct  9 13:14 utils.py
-rwxr-xr-x 1 root root 6883 Oct  9 13:14 exchanges.py
-rw-r--r-- 1 root root 2048 Oct  9 13:14 binance_dust.py

[0:227] 01:14:43 Sat Oct 09 [steve@scheduler:/dev/pts/0 +1] ~/code/pythonlib
# git commit -m 'merged binance dust'
[main 500ed51] merged binance dust
 Committer: root <steve@scheduler.jobsinthecloud.com>
[0:228] 01:14:55 Sat Oct 09 [steve@scheduler:/dev/pts/0 +1] ~/code/pythonlib
# git push
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 2 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 1.09 KiB | 1.09 MiB/s, done.
Total 3 (delta 1), reused 1 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To github.com:wozniak/pythonlib.git
   3bc2ee4..500ed51  main -> main

[0:229] 01:14:58 Sat Oct 09 [steve@scheduler:/dev/pts/0 +1] ~/code/pythonlib
#

Git: Post-merge hook example (run action after β€œgit pull)

#!/bin/bash

for i in $(ps -ef|grep 'tweetscan.py' | grep -v grep |awk '{print $2}'); do
 kill -9 $i
 sleep 1
done

source ~/.bashrc; cd /home/pi/monitor; python3.8 tweetscan.py >> /home/pi/twitter_to_telegram.log

GnuPG: Encrypt and sign and then decrypt

Encrypting a file:

gpg2 --encrypt --sign --armor -r steve@hal9000.ack /tmp/file.tar.gz

Decrypting:

0 βœ“ steve@hal9000 /tmp $ gpg2 -d file.tar.gz.asc > file.tar.gz
gpg: anonymous recipient; trying secret key 0xXXXXXXXXXXXXXXXX ...
gpg: anonymous recipient; trying secret key 0xXXXXXXXXXXXXXXXX ...
gpg: anonymous recipient; trying secret key 0xXXXXXXXXXXXXXXXX ...
gpg: anonymous recipient; trying secret key 0xXXXXXXXXXXXXXXXX ...
gpg: anonymous recipient; trying secret key 0xXXXXXXXXXXXXXXXX ...
gpg: WARNING: cipher algorithm AES256 not found in recipient preferences
gpg: Note: key has been revoked
gpg: reason for revocation: No reason specified
gpg: okay, we are the anonymous recipient.
gpg: encrypted with RSA key, ID 0x0000000000000000
- gpg: Signature made Wed Jan 1 01:01:01 2059 CET
gpg:                using RSA key XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
gpg: Good signature from "Bill Gates <gates@windows.door>" [ultimate]
Primary key fingerprint: XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
0 βœ“ steve@hal9000 /tmp $

Β Go: go install xxx -> can’t load package: package github.com

If:

0 βœ“ steve@hal9000 ~ $ go install github.com/nomasters/killcord/killcord
can't load package: package github.com/nomasters/killcord/killcord: cannot find package "github.com/nomasters/killcord/killcord" in any of:
 /usr/local/Cellar/go/1.14.1/libexec/src/github.com/nomasters/killcord/killcord (from $GOROOT)
 /Users/steve/go/src/github.com/nomasters/killcord/killcord (from $GOPATH)
1 βœ— steve@hal9000 ~ $

Then:

1 βœ— steve@hal9000 ~ $ go get github.com/nomasters/killcord/
# github.com/nomasters/killcord/vendor/github.com/rjeczalik/notify
go/src/github.com/nomasters/killcord/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go:51:52: cannot use nil as type _Ctype_CFAllocatorRef in assignment
go/src/github.com/nomasters/killcord/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go:165:40: cannot use nil as type _Ctype_CFAllocatorRef in argument to _Cfunc_CFStringCreateWithCStringNoCopy
go/src/github.com/nomasters/killcord/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go:165:55: cannot use nil as type _Ctype_CFAllocatorRef in argument to _Cfunc_CFStringCreateWithCStringNoCopy
go/src/github.com/nomasters/killcord/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go:166:40: cannot use nil as type _Ctype_CFAllocatorRef in assignment
2 βœ— steve@hal9000 ~ $ go install github.com/nomasters/killcord/
# github.com/nomasters/killcord/vendor/github.com/rjeczalik/notify
go/src/github.com/nomasters/killcord/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go:51:52: cannot use nil as type _Ctype_CFAllocatorRef in assignment
go/src/github.com/nomasters/killcord/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go:165:40: cannot use nil as type _Ctype_CFAllocatorRef in argument to _Cfunc_CFStringCreateWithCStringNoCopy
go/src/github.com/nomasters/killcord/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go:165:55: cannot use nil as type _Ctype_CFAllocatorRef in argument to _Cfunc_CFStringCreateWithCStringNoCopy
go/src/github.com/nomasters/killcord/vendor/github.com/rjeczalik/notify/watcher_fsevents_cgo.go:166:40: cannot use nil as type _Ctype_CFAllocatorRef in assignment
2 βœ— steve@hal9000 ~ $

Go: Fetching all project dependencias at once

jobs@hal9000 ~/project_folder $ go get -u -v -f all
github.com/VictoriaMetrics/fastcache (download)
github.com/cespare/xxhash (download)
github.com/golang/snappy (download)
[...]

or just get the final package and let go resolve dependencies for you:

0 βœ“ jobs@hal9000 ~ $ go get github.com/arachnid/dnsprove
0 βœ“ jobs@hal9000 ~ $ cd dnsprove/bin/
0 βœ“ jobs@hal9000 ~/dnsprove/bin $ ./dnsprove
Usage: ./dnsprove [options] command
  -algorithms string
     a comma-separated list of supported digest algorithms (default "RSASHA1,RSASHA1-NSEC3-SHA1,RSASHA256")
  -gasprice float
     Gas price, in gwei (default 5)
[...]

Google Sheets: Timestamping a cell based on a specific sheet modification

function onEdit(e) {
var cellToStamp = "I17" ; // change to suit
var sheetToStamp = 'Portfolio Evolution'
var today = Utilities.formatDate(new Date(), "Europe/Madrid", "E HH:mm")
var editedSheetName = e.range.getSheet().getName();
if(editedSheetName === 'wks_portfoliotrack') {
    SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetToStamp).getRange(cellToStamp).setValue(today);
  }
}

Hetzner: Proxmox Networking: Routed

root@vm1 ~ # cat /etc/network/interfaces
# network interface settings; autogenerated
# Please do NOT modify this file directly, unless you know what
# you're doing.
#
# If you want to manage parts of the network configuration manually,
# please utilize the 'source' or 'source-directory' directives to do
# so.
# PVE will preserve these directives, but will NOT read its network
# configuration from sourced files, so do not attempt to move any of
# the PVE managed interfaces into external files!

source /etc/network/interfaces.d/*

auto lo
iface lo inet loopback

iface lo inet6 loopback

auto enp7s0
iface enp7s0 inet static
 address 65.21.xxx.xxx/26
 gateway 65.21.xxx.193
 netmask 255.255.255.0
 up route add -net 65.21.225.192 netmask 255.255.255.192 gw 65.21.225.193 dev enp7s0
# route 65.21.225.192/26 via 65.21.225.193
        post-up echo 1 > /proc/sys/net/ipv4/conf/eno1/proxy_arp


iface enp7s0 inet6 static
 address 2a01:4f9:xx:xxxxx::x/64
 gateway fexx::x

auto vmbr0
iface vmbr0 inet manual
 bridge-ports none
 bridge-stp off
 bridge-fd 0

auto vmbr1
iface vmbr1 inet static
    address 10.0.0.1
    netmask 255.255.255.0
    bridge_ports none
    bridge_stp off
    bridge_fd 0
    post-up echo 1 > /proc/sys/net/ipv4/ip_forward
    post-up iptables -t nat -A POSTROUTING -s '10.0.0.0/24' -o enp7s0 -j MASQUERADE
    post-down iptables -t nat -D POSTROUTING -s '10.0.0.0/24' -o enp7s0 -j MASQUERADE
    post-up iptables -t nat -A PREROUTING -i enp7s0 -p tcp --dport 1234 -j DNAT --to 10.0.0.5:22
    post-down iptables -t nat -D PREROUTING -i enp7s0 -p tcp --dport 1234 -j DNAT --to 10.0.0.5:22
root@vm1 ~ #

Guest network setup:

"Proxmox Guest Network Setup"


Jekyll: adding pngout support to image_optim

0 βœ“ steve@hal9000 ~/Downloads $
0 βœ“ steve@hal9000 ~/Downloads $ curl https://static.jonof.id.au/dl/kenutils/pngout-20150920-darwin.tar.gz > pngout.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 56968  100 56968    0     0  19554      0  0:00:02  0:00:02 --:--:-- 19549
0 βœ“ steve@hal9000 ~/Downloads $ tar -xzvf pngout.tar.gz
x pngout-20150920-darwin/
x pngout-20150920-darwin/pngout
x pngout-20150920-darwin/readme.txt
0 βœ“ steve@hal9000 ~/Downloads $ cd pngout-20150920-darwin
0 βœ“ steve@hal9000 ~/Downloads/pngout-20150920-darwin $ sudo cp pngout /usr/local/bin/.
0 βœ“ steve@hal9000 ~/Downloads/pngout-20150920-darwin $ which pngout
/usr/local/bin/pngout
0 βœ“ steve@hal9000 ~/Downloads $

Jekyll: Checking image_optim_pack settings

0 βœ“ steve@hal9000 ~/jekyll $ bundle exec image_optim --info
image_optim v0.26.5
config:
  verbose: true
nice: 10
threads: 8
pack: true
skip_missing_workers: true
allow_lossy: false
[...]
gif:
  gifsicle:
    interlace: false
    level: 3
    careful: false
  gifsicle:
    interlace: true
    level: 3
    careful: false
0 βœ“ steve@hal9000 ~/jekyll $

Jekyll: Insensitive sort

{%- assign tools = site.data.kanbantools | sort_natural:"Name" -%}
{% for tool in tools %}
{% if tool.Name %}

Jekyll: Raw code blocs

0 βœ“ steve@hal9000 ~/jekyll $ bundle exec image_optim --info
image_optim v0.26.5
config:
  verbose: true
nice: 10
threads: 8
pack: true
skip_missing_workers: true
allow_lossy: false
[...]
gif:
  gifsicle:
    interlace: false
    level: 3
    careful: false
  gifsicle:
    interlace: true
    level: 3
    careful: false
0 βœ“ steve@hal9000 ~/jekyll $

Jekyll: rfc3986_parser.rb:21:in `split’: URI must be ascii only

Edit .../versions/2.7.3/lib/ruby/gems/2.7.0/gems/jekyll-target-blank-2.0.0/lib/jekyll-target-blank.rb line 196:

Replace URI.parse(link).host != URI.parse(@site_url).host by URI.parse(URI.escape(link)).host != URI.parse(@site_url).host as follows:

  def external?(link)
    if link&.match?(URI.regexp(%w(http https)))
      #URI.parse(link).host != URI.parse(@site_url).host
      URI.parse(URI.escape(link)).host != URI.parse(@site_url).host
    end
  end

Kindle: Hacks Information

https://wiki.mobileread.com/wiki/Kindle_Hacks_Information


jq: Query example

[0:821] 10:10:06 Thu Sep 17 [steve@hal9000:/dev/ttys002 +1] ~/code/jekyll
$ curl 'https://ulu.finance/api/pool/pools?page=1&size=100&account=0x1234567890QWERTYUIOPASDFG' |jq '.data[] | select(.poolId=="stakingPoolV2")'
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 33428    0 33428    0     0  49303      0 --:--:-- --:--:-- --:--:-- 49231
{
  "poolId": "stakingPoolV2",
  "poolName": "ULU Staking Pool V2",
  "description": "ULU Staking Pool V2",
  "poolType": "StakingPool",
  "exchange": "",
  "poolState": "open",
  "rewardStartTime": 1600005600,
  "stat": {
    "totalStaked": 7422.209303213571,
    "totalStakedPercent": 0.11373670935069473,
    "underlyingTokens": [
      {
        "symbol": "ULU",
        "amount": 7422.209303213571,
        "address": "0x035bfe6057e15ea692c0dfdcab3bb41a64dd2ad4"
      }
    ],
    "tlv": 161079.16709069168,
    "tlvReturn": -0.12296538679803488,
    "tlvRatio": 0.044769424731879996,
    "yieldPer1000": 0.033257825663617,
    "yieldFreq": "hour",
    "roiPerHour": 0.07217720005313501,
    "roiPerDay": 1.7322528012752403,
    "roiPerYear": 632.2722724654626,
    "currentEpochReward": 900,
    "nextEpochReward": 0,
    "nextEpochTime": 1600609505,
    "userClaimable": 1.23456789,
    "userClaimed": 0,
    "userBalance": 1.123456789e-07,
    "userStaked": 12.23456,
    "userEstimated24hReward": 0.123456789
  },
  "contract": {
    "stakeTokenSymbol": "ULU",
    "stakeTokenAddress": "0x035bfe6057e15ea692c0dfdcab3bb41a64dd2ad4",
    "stakeTokenDecimal": 18,
    "distTokenSymbol": "ULU",
    "distTokenAddress": "0x035bfe6057e15ea692c0dfdcab3bb41a64dd2ad4",
    "distTokenDecimal": 18,
    "liquidityPoolAddress": "0x035bfe6057e15ea692c0dfdcab3bb41a64dd2ad4",
    "stakePoolAddress": "0xe2a1e9467b5d18f9cd7e7febd4d926dc519ecaee"
  }
}

[0:822] 10:10:22 Thu Sep 17 [steve@hal9000:/dev/ttys002 +1] ~/code/jekyll
$

Kindle 3: Flash fs and kernel on bricked device

0 βœ“ steve@hal9000 ~/kindle3 $ lsusb | grep Freescale
Bus 020 Device 003: ID 15a2:0030 Freescale Semiconductor, Inc. SE Blank RINGO

Check if device is being ready to be flashed:

0 βœ“ steve@hal9000 ~/kindle3 $ sudo k3flasher/k3flasher mx35to2_mmc.bin info
I: found suitable device
I: read info
I: got size 1048576 (probably wrong)
I: downloading 0x00000200 (=512) bytes, starting at 0x00040c00
I: DO NOT MAKE THE FOLLOWING INFORMATION PUBLIC!
I: if you need to discuss it in public, obfuscate
I: e.g. the second half of the numbers.
I: got device serial number <B00AXXXXXX>
I: got device Wifi MAC <28XXXXXXXXXXX>
0 βœ“ steve@hal9000 ~/kindle3

Flash fs and kernel:

0 βœ“ steve@hal9000 ~/kindle3 $
0 βœ“ steve@hal9000 ~/kindle3 $ sudo k3flasher/k3flasher mx35to2_mmc.bin program rootfs ./mmcblk0p1-3.4+jb+keys.img
I: found suitable device
E: wrong transfer length, wanted to receive 8 bytes but received 4 bytes.
I: above error can be ignored, it's due to the device being in ROM kernel mode
I: RAM kernel should be running now. Trying to re-open device: .
I: got it.
I: flashing 0x28a07000 (=681603072) bytes
I: writing 0x00200000 (=2097152) bytes to address 0x003c1000, waiting for completion...
I: wrote 0x00200000 (=2097152) bytes, waiting for completion...
I: flashed 0x00010000 (=65536) bytes
I: flashed 0x00020000 (=131072) bytes
[...]
0 βœ“ steve@hal9000 ~/kindle3 $ sudo k3flasher/k3flasher mx35to2_mmc.bin program kernel main_kernel-3.4.img
Password:
I: found suitable device
I: flashing 0x00211400 (=2167808) bytes
I: writing 0x00200000 (=2097152) bytes to address 0x00041000, waiting for completion...
I: wrote 0x00200000 (=2097152) bytes, waiting for completion...
I: flashed 0x00010000 (=65536) bytes
I: flashed 0x00020000 (=131072) bytes
[...]
0 βœ“ steve@hal9000 ~/kindle3 $ sudo k3flasher/k3flasher mx35to2_mmc.bin reset
I: found suitable device
I: resetting device.

Files:


Kindle 3: Jailbreak

Package: update_jailbreak_0.5.1_k3gb_install.bin

Just place it on the root folder an apply the standard update procedure.


Kindle 3: UsbNetwork

Package: Update_usbnetwork_0.57.N_k3gb_install.bin

Enable / disable usbNetwork:

;debugOn
~usbNetwork

Kindle 3: Full screen terminal

Package: kiterm-20110107fs.zip

In order to get it to automatically start after boot:

Make Kindle fs writable: mntroot rw

Save the following script under /etc/init.d/kiterm and make it executable chmod +x /etc/init.d/kiterm

#!/bin/sh
#/etc/init.d/kiterm
case "$1" in
  start)
    echo "Starting kiterm "
    /mnt/us/kiterm/myts.arm &
    ;;
  stop)
    echo "Stopping kiterm "
    killall myts.arm
    ;;
  *)
    echo "Usage: /etc/init.d/kiterm {start|stop}"
    exit 1
    ;;
esac
exit 0

Add a symlink on /etc/rc5.d:

# ln -s /etc/init.d/kiterm /etc/rc5.d/S97kiterm

Reboot the Kindle (Menu > Settings > Menu > Restart). You can now enter terminal mode anytime by pressing Shift, letting go, and pressing T. Exit terminal mode by pressing the Previous Page button on the left side of the Kindle.

Keyboard mapping

Ctrl = AA (aka Symbol)
Esc  = Left Next Page

.------------------------.     .----------------------.
| Key   Back  Back+Shift |     | Key   Alt  Alt+Shift |
+------------------------+     +----------------------+
|  Q      `        ~     |     |  Q     1      !      |
|  A     Tab   Back Tab  |     |  W     2      @      |
|  Z      <        >     |     |  E     3      #      |
|  U      -        _     |     |  R     4      $      |
|  I      =        +     |     |  T     5      %      |
|  O      [        {     |     |  Y     6      ^      |
|  P      ]        }     |     |  U     7      &      |
|  K      ;        :     |     |  I     8      *      |
|  L      '        "     |     |  O     9      (      |
| Del     \        |     |     |  P     0      )      |
|  .      ,        <     |     '----------------------'
| Sym     .        >     |
| Ret     /        ?     |
'------------------------'

Source: https://tinyapps.org/docs/kindle_standalone_terminal.html


locales: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)

Solution:

root@server:~# sudo locale-gen "en_US.UTF-8"
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
Generating locales (this might take a while)...
  en_US.UTF-8... done
Generation complete.

macOS: Enable locate (mlocate / updatedb)

WARNING: The locate database (/var/db/locate.database) does not exist.
To create the database, run the following command:

  sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist

Please be aware that the database can take some time to generate; once
the database has been created, this message will no longer appear.

macOS: Disable Spotlight

Due to fan continuously running, here is how to disable Spotlight:

sudo mdutil -i off -a
type your password if requested.
2020-09-14 11:48:43.091 mdutil[1010:20698] mdutil disabling Spotlight: / -> kMDConfigSearchLevelFSSearchOnly
        Indexing disabled.

To test and make sure indexing is off, try: sudo mdutil -s -a (-s is for β€œstatus” and -a means β€œshow all drives”), it should also say Indexing Disabled as well.

Later on, you can re-enable indexing with sudo mdutil -i on -a.


macOS: Install cp210x drivers


def cat
  puts 'I love cats'
end


macOS: Install xcode

xcode-select --install

macOS: Disable screen lock after Apple Remote Desktop Session ends

defaults write /Library/Preferences/com.apple.RemoteManagement RestoreMachineState -bool NO


macOS: Set environment variables for GUI apps

Edit /etc/launchd.conf as follows:

setenv PYTHONPATH /Documents/code/pythonlib

Load changes in your current session (without rebooting):

launchctl setenv PYTHONPATH ${HOME}/Documents/code/pythonlib/

Matplotlib: List plot config params

plt.rcParams.keys()
KeysView(RcParams({'_internal.classic_mode': False,
          'agg.path.chunksize': 0,
          'animation.avconv_args': [],
          'animation.avconv_path': 'avconv',
          'animation.bitrate': -1,
          (...)

Full list of accepted parameters:

agg.path.chunksize
animation.avconv_args
animation.avconv_path
animation.bitrate
animation.codec
animation.convert_args
animation.convert_path
animation.embed_limit
animation.ffmpeg_args
animation.ffmpeg_path
animation.frame_format
animation.html
animation.html_args
animation.writer
axes.autolimit_mode
axes.axisbelow
axes.edgecolor
axes.facecolor
axes.formatter.limits
axes.formatter.min_exponent
axes.formatter.offset_threshold
axes.formatter.use_locale
axes.formatter.use_mathtext
axes.formatter.useoffset
axes.grid
axes.grid.axis
axes.grid.which
axes.labelcolor
axes.labelpad
axes.labelsize
axes.labelweight
axes.linewidth
axes.prop_cycle
axes.spines.bottom
axes.spines.left
axes.spines.right
axes.spines.top
axes.titlepad
axes.titlesize
axes.titleweight
axes.unicode_minus
axes.xmargin
axes.ymargin
axes3d.grid
backend
backend_fallback
boxplot.bootstrap
boxplot.boxprops.color
boxplot.boxprops.linestyle
boxplot.boxprops.linewidth
boxplot.capprops.color
boxplot.capprops.linestyle
boxplot.capprops.linewidth
boxplot.flierprops.color
boxplot.flierprops.linestyle
boxplot.flierprops.linewidth
boxplot.flierprops.marker
boxplot.flierprops.markeredgecolor
boxplot.flierprops.markeredgewidth
boxplot.flierprops.markerfacecolor
boxplot.flierprops.markersize
boxplot.meanline
boxplot.meanprops.color
boxplot.meanprops.linestyle
boxplot.meanprops.linewidth
boxplot.meanprops.marker
boxplot.meanprops.markeredgecolor
boxplot.meanprops.markerfacecolor
boxplot.meanprops.markersize
boxplot.medianprops.color
boxplot.medianprops.linestyle
boxplot.medianprops.linewidth
boxplot.notch
boxplot.patchartist
boxplot.showbox
boxplot.showcaps
boxplot.showfliers
boxplot.showmeans
boxplot.vertical
boxplot.whiskerprops.color
boxplot.whiskerprops.linestyle
boxplot.whiskerprops.linewidth
boxplot.whiskers
contour.corner_mask
contour.negative_linestyle
datapath
date.autoformatter.day
date.autoformatter.hour
date.autoformatter.microsecond
date.autoformatter.minute
date.autoformatter.month
date.autoformatter.second
date.autoformatter.year
docstring.hardcopy
errorbar.capsize
examples.directory
figure.autolayout
figure.constrained_layout.h_pad
figure.constrained_layout.hspace
figure.constrained_layout.use
figure.constrained_layout.w_pad
figure.constrained_layout.wspace
figure.dpi
figure.edgecolor
figure.facecolor
figure.figsize
figure.frameon
figure.max_open_warning
figure.subplot.bottom
figure.subplot.hspace
figure.subplot.left
figure.subplot.right
figure.subplot.top
figure.subplot.wspace
figure.titlesize
figure.titleweight
font.cursive
font.family
font.fantasy
font.monospace
font.sans-serif
font.serif
font.size
font.stretch
font.style
font.variant
font.weight
grid.alpha
grid.color
grid.linestyle
grid.linewidth
hatch.color
hatch.linewidth
hist.bins
image.aspect
image.cmap
image.composite_image
image.interpolation
image.lut
image.origin
image.resample
interactive
keymap.all_axes
keymap.back
keymap.copy
keymap.forward
keymap.fullscreen
keymap.grid
keymap.grid_minor
keymap.help
keymap.home
keymap.pan
keymap.quit
keymap.quit_all
keymap.save
keymap.xscale
keymap.yscale
keymap.zoom
legend.borderaxespad
legend.borderpad
legend.columnspacing
legend.edgecolor
legend.facecolor
legend.fancybox
legend.fontsize
legend.framealpha
legend.frameon
legend.handleheight
legend.handlelength
legend.handletextpad
legend.labelspacing
legend.loc
legend.markerscale
legend.numpoints
legend.scatterpoints
legend.shadow
legend.title_fontsize
lines.antialiased
lines.color
lines.dash_capstyle
lines.dash_joinstyle
lines.dashdot_pattern
lines.dashed_pattern
lines.dotted_pattern
lines.linestyle
lines.linewidth
lines.marker
lines.markeredgecolor
lines.markeredgewidth
lines.markerfacecolor
lines.markersize
lines.scale_dashes
lines.solid_capstyle
lines.solid_joinstyle
markers.fillstyle
mathtext.bf
mathtext.cal
mathtext.default
mathtext.fallback_to_cm
mathtext.fontset
mathtext.it
mathtext.rm
mathtext.sf
mathtext.tt
patch.antialiased
patch.edgecolor
patch.facecolor
patch.force_edgecolor
patch.linewidth
path.effects
path.simplify
path.simplify_threshold
path.sketch
path.snap
pdf.compression
pdf.fonttype
pdf.inheritcolor
pdf.use14corefonts
pgf.preamble
pgf.rcfonts
pgf.texsystem
polaraxes.grid
ps.distiller.res
ps.fonttype
ps.papersize
ps.useafm
ps.usedistiller
savefig.bbox
savefig.directory
savefig.dpi
savefig.edgecolor
savefig.facecolor
savefig.format
savefig.frameon
savefig.jpeg_quality
savefig.orientation
savefig.pad_inches
savefig.transparent
scatter.edgecolors
scatter.marker
svg.fonttype
svg.hashsalt
svg.image_inline
text.antialiased
text.color
text.hinting
text.hinting_factor
text.latex.preamble
text.latex.preview
text.latex.unicode
text.usetex
timezone
tk.window_focus
toolbar
verbose.fileo
verbose.level
webagg.address
webagg.open_in_browser
webagg.port
webagg.port_retries
xtick.alignment
xtick.bottom
xtick.color
xtick.direction
xtick.labelbottom
xtick.labelsize
xtick.labeltop
xtick.major.bottom
xtick.major.pad
xtick.major.size
xtick.major.top
xtick.major.width
xtick.minor.bottom
xtick.minor.pad
xtick.minor.size
xtick.minor.top
xtick.minor.visible
xtick.minor.width
xtick.top
ytick.alignment
ytick.color
ytick.direction
ytick.labelleft
ytick.labelright
ytick.labelsize
ytick.left
ytick.major.left
ytick.major.pad
ytick.major.right
ytick.major.size
ytick.major.width
ytick.minor.left
ytick.minor.pad
ytick.minor.right
ytick.minor.size
ytick.minor.visible
ytick.minor.width
ytick.right

Mikrotik: Port knocking

/ip firewall filter
add action=add-src-to-address-list address-list=port:9999 address-list-timeout=20s chain=input dst-port=9999 protocol=tcp
add action=add-src-to-address-lis address-list=port:8888 address-list-timeout=20s chain=input dst-port=8888 protocol=tcp src-address-list=port:9999
add action=add-src-to-address-list address-list=secure address-list-timeout=2h chain=input dst-port=7777 protocol=tcp src-address-list=port:8888
add chain=input src-address-list=secure action=accept
add action=drop chain=input

Node: npm install error: no template named β€˜remove_cv_t’

Error message: error: no template named 'remove_cv_t' in namespace 'std'; did you mean 'remove_cv'?

Downgrade to Node v14 as follows:

brew install node@14
echo 'export PATH="/opt/homebrew/opt/node@14/bin:$PATH"' >> ~/.profile
export LDFLAGS="-L/opt/homebrew/opt/node@14/lib"
export CPPFLAGS="-I/opt/homebrew/opt/node@14/include"

OpenWRT: ER-X read-only issue

  • scp 'openwrt-19.07.5-ramips-mt7621-ubnt-erx-squashfs-sysupgrade.bin' root@192.168.1.1:/tmp/.
  • ssh root@192.168.1.1
  • cd /tmp && sysupgrade openwrt-19.07.5-ramips-mt7621-ubnt-erx-squashfs-sysupgrade.bin

OSX: Install GNU core utils with default names (updated)

First install the desired bianries with brew install gnu-sed grep coreutils.

Then, just updated your ~/.profile or ~/.bashrc files as follows:

PATH="$(brew --prefix coreutils)/libexec/gnubin:$PATH"
PATH="$(brew --prefix grep)/libexec/gnubin:$PATH"
export PATH="$(brew --prefix gnu-sed)/libexec/gnubin:$PATH"

OSX: Mounting Hetzner storagebox

sudo mkdir /Volumes/storagebox
sudo chown myUser /Volumes/storagebox
sudo mount_smbfs //u123456@u123456.your-storagebox.de/backup /Volumes/storagebox

Pandas: Coloring positive / negative on cli

from colorama import Back, Fore, Style

def color_red_green(val):
    if val >= 1:
        color = Fore.GREEN
    elif val > 0 and val <= 1:
        color = Fore.YELLOW
    else:
        color = Fore.RED

    return color + str('{:+f}'.format(val)) + Style.RESET_ALL


df_formatted["forecast"] = df_formatted["forecast"].apply(color_red_green)

Pandas: Column type definition (fast and easy)

dfs['pct_24h'] = price_pct_24h
dfs['pct_7dh'] = price_pct_7dh
dfs['pct_14d'] = price_pct_14d
dfs['pct_30d'] = price_pct_30d
dfs['pct_60h'] = price_pct_60h
dfs['pct_200h'] = price_pct_200h


convert_dict = {'pct_24h': int,
                'pct_7dh': int,
                'pct_14d': int,
                'pct_30d': int,
                'pct_60h': int,
                'pct_200h': int
                }

dfs = dfs.astype(convert_dict)

print(dfs.sort_values(by='trend10d', ascending=False))

Pandas: From json object to DataFrame

Json object:

data = binance.fetchClosedOrders(symbol='BAT/USDT')
print(data)

Expected output:

[{'info': {'symbol': 'BATUSDT', 'orderId': 51861967, 'orderListId': -1, 'clientOrderId': 'and_abcdefg123456789', 'price': '0.11600000', 'origQty': '99999.86000000', 'executedQty': '1000.86000000', 'cummulativeQuoteQty': '254.57576000', 'status': 'FILLED', 'timeInForce': 'GTC', 'type': 'LIMIT', 'side': 'BUY', 'stopPrice': '0.00000000', 'icebergQty': '0.00000000', 'time': 158413456553, 'updateTime': 158413456553
[...]
'timestamp': 1584702015871, 'datetime': '2012-03-11T11:00:15.871Z', 'lastTradeTimestamp': None, 'symbol': 'BAT/USDT', 'type': 'limit', 'side': 'buy', 'price': 0.1999, 'amount': 10000.31, 'cost': 349.999819, 'average': 0.9949, 'filled': 1282.31, 'remaining': 0.0, 'status': 'closed', 'fee': None, 'trades': None}]

Build a df out of that object:

df = pd.json_normalize(data)
print(df)

Expected output:

id      timestamp                  datetime lastTradeTimestamp  ...      info.time info.updateTime info.isWorking  info.origQuoteOrderQty
0  52640640  1581234567890  2020-03-01T00:38:36.523Z               None  ...  1581234567890   1581234567890           True              0.00000000
1  52640640  1581234567890  2020-03-01T00:42:29.278Z               None  ...  1581234567890   1581234567890           True              0.00000000
2  52640640  1581234567890  2020-03-01T00:43:30.898Z               None  ...  1581234567890   1581234567890           True              0.00000000
3  52640640  1581234567890  2020-03-01T00:36:39.273Z               None  ...  1581234567890   1581234567890           True              0.00000000
4  52640640  1581234567890  2020-03-01T00:25:53.478Z               None  ...  1581234567890   1581234567890           True              0.00000000
5  52640640  1581234567890  2020-03-01T00:29:59.884Z               None  ...  1581234567890   1581234567890           True              0.00000000

Pandas: Prevent output wrapping

pd.options.display.max_columns = None
pd.options.display.width=None

Pandas: Plotting cool donut charts

def plot_piechart(data, title, column_numbers, column_index):
    """
    Plots a preformated pie chart
        - data: dataframe
        - column_values: column name for quantitative values
        - column_index: column name for qualitative values
    """

    # Configure plot color map
    ''' colormaps:  https://matplotlib.org/examples/color/colormaps_reference.html
                    https://matplotlib.org/tutorials/colors/colormaps.html#kovesi-colormaps'''
    colors = plt.cm.GnBu(np.linspace(0.6, 1, len(data)))

    # Explode biggest value
    maxdata = max(data[column_numbers])
    mindata = min(data[column_numbers])
    explode = []

    for v in data[column_numbers]:
        if v == maxdata:
            explode.append(0.15)
        elif v == mindata:
            explode.append(0)
        else:
            explode.append(0)

    # Initialize plot
    plt.pie(data[column_numbers],
        counterclock=False,
        shadow=False,
        autopct='%.1f',
        textprops={'color':"white"},
        explode=explode)

    #Β Set inner circle size (0,0), radius
    circle=plt.Circle( (0,0), 0.25,
        color='white')

    plt.gca().add_artist(circle)

    # Set legend position and font size
    plt.legend(labels=data[column_index],
        bbox_to_anchor=(1,0.5),
        loc="center right",
        fontsize=10,
        bbox_transform=plt.gcf().transFigure)

    # Set plot title
    plt.title(title, fontsize=12)

    # Set plot colors
    plt.rcParams['axes.prop_cycle'] = cycler(color=colors)

    #Β Return plot
    return(plt.show())


plot_piechart()

Philips TV: Turning it on and off with python

import requests
import json
from requests.auth import HTTPDigestAuth

session = requests.Session()

body='{"key": "Standby"}'
tvip = '192.168.1.125'
user = '2g3HuRn5kPbGWcdj'
password = '5e3040b4a6a27b425fae246009e07318a7b7724651b64783c235d4fff2ae4d32'
to = 4

def off():
    requests.post("https://{}:1926/6/input/key".format(tvip), json=json.loads(body), auth=HTTPDigestAuth(user, password), verify=False, timeout=to)

def on():
    requests.post("http://{}:8008/apps/ChromeCast".format(tvip), verify=False, timeout=to)


off()

pipx: Run Python Applications in Isolated Environments

86% 2021-02-23 05:26:01   Steve-MBP in ~
β—‹ β†’ python3 -m pipx ensurepath
/Users/steve/.local/bin is already in PATH.
Success! Added /Users/steve/Library/Python/3.9/bin to the PATH environment variable.

Consider adding shell completions for pipx. Run 'pipx completions' for instructions.

You will need to open a new terminal or re-login for the PATH changes to take effect.

Otherwise pipx is ready to go! ✨ 🌟 ✨

86% 2021-02-23 05:26:13   Steve-MBP in ~
β—‹ β†’ pipx run spotdl https://open.spotify.com/track/54hpNTXc7oFbAb6Bikc03O?si=xfjn84MNSGORSP9c7zJa2A
Fetching Song...
Searching for: Najwa - Lento
100%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ|ETA: 00:00, ~min/song

87% 2021-02-23 05:27:59   Steve-MBP in ~

pip: pip install gevent fails on MacOS M1 Sillicon

Error message:

    Running setup.py install for gevent ... error
    ERROR: Command errored out with exit status 1:
[...]
pip-record-6pissa40/install-record.txt --single-version-externally-managed --compile --install-headers /opt/homebrew/include/python3.8/gevent Check the logs for full command output.

Try:

[0:573] 02:00:27 Mon Oct 25 [steve@macbook.lan:/dev/ttys013 +1] ~/code/speedy
$ /opt/homebrew/opt/python@3.8/bin/python3 -m pip install gevent --no-binary :all:
DEPRECATION: Configuring installation scheme with distutils config files is deprecated and will no longer work in the near future. If you are using a Homebrew or Linuxbrew Python, please see discussion at https://github.com/Homebrew/homebrew-core/issues/76621
Collecting gevent
  Using cached gevent-21.8.0.tar.gz (6.2 MB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
    Preparing wheel metadata ... done
Requirement already satisfied: greenlet<2.0,>=1.1.0 in /opt/homebrew/lib/python3.8/site-packages (from gevent) (1.1.2)
[...]
Building wheels for collected packages: gevent
  Building wheel for gevent (PEP 517) ... error
  ERROR: Command errored out with exit status 1:
[...]
e-output.txt )' returned non-zero exit status 1.
  ----------------------------------------
  ERROR: Failed building wheel for gevent
Failed to build gevent
ERROR: Could not build wheels for gevent which use PEP 517 and cannot be installed directly

If still fails add CPPFLAGS:

[0:576] 02:04:56 Mon Oct 25 [steve@macbook.lan:/dev/ttys013 +1] ~/code/speedy
$  CPPFLAGS="-DEV_PERIODIC_ENABLE=1" /opt/homebrew/opt/python@3.8/bin/python3 -m pip install gevent --no-binary :all:
DEPRECATION: Configuring installation scheme with distutils config files is deprecated and will no longer work in the near future. If you are using a Homebrew or Linuxbrew Python, please see discussion at https://github.com/Homebrew/homebrew-core/issues/76621



install -v --no-binary gevent gevent




---

## **PostgreSQL**: Create a new database & user

```sql
create database jeans_models;
create user jobs with encrypted password 'this_is_the_most_secure_password_ever_123';
grant all privileges on database jeans_models to jobs;

PostgreSQL: Dump databases (backing up db)

pg_dump -b -C --column-inserts --inserts --quote-all-identifiers -h $HOSTNAME -U $USER_NAME -d $DB_NAME -W -f $DB_NAME.sql

PostgreSQL: Kill active sessions

SELECT pid, pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = current_database() AND pid <> pg_backend_pid();

PostgreSQL: 101 - psycopg2 class

import psycopg2

class MyDatabase():
    def __init__(self, db="mydb", user="postgres"):
        self.conn = psycopg2.connect(database=db, user=user)
        self.cur = self.conn.cursor()

    def query(self, query):
        self.cur.execute(query)

    def close(self):
        self.cur.close()
        self.conn.close()

db = MyDatabase()
db.query("SELECT * FROM table;")
db.close()

PostgreSQL: Error permission denied for table prices

[Running] /usr/bin/env python3 "/Users/steve/conquertheforld/main.py"
Error permission denied for table nations

Solution:

ALTER TABLE "public"."nations" OWNER TO "steve";

PostgreSQL: Restore previous dump

psql -h localhost -p 5432 $DB_NAME -U $USER_NAME -W < $DB_NAME.sql

PostgreSQL: Trigger data copy to transactional on insert/update

Function definition, where:

  • fl_hist_portfolio is a transactional table.
  • coin, locked, free and updated are the fields to be updated on the transactional datastore.
  • NEW.coin, NEW.locked, NEW.free and NEW.updated refer to the new inserted data. sol
CREATE OR REPLACE FUNCTION fl_history_portfolio ()
RETURNS TRIGGER
AS
$$
BEGIN
  INSERT INTO fl_hist_portfolio
              (coin, locked, free, updated )
              VALUES (NEW.coin, NEW.locked, NEW.free, NEW.updated);
  RETURN NEW;
END;
$$
LANGUAGE plpgsql;

Trigger definition, where:

  • β€œAFTER INSERT OR UPDATE” will run the previous function after each insert or update.
  • fl_portfolio is de table we want this trigger to β€œmonitor”
CREATE TRIGGER portfolio_history
       AFTER INSERT OR UPDATE
       ON fl_portfolio
       FOR EACH ROW
       EXECUTE PROCEDURE fl_history_portfolio();

PostgreSQL: Trigger timestamp update on insert

CREATE OR REPLACE FUNCTION update_timestamp() RETURNS TRIGGER
LANGUAGE plpgsql
AS
$$
BEGIN
    NEW.updated = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$;

CREATE TRIGGER last_update
  BEFORE UPDATEw
  ON fl_portfolio
  FOR EACH ROW
  EXECUTE PROCEDURE update_timestamp();

Proxmox: Resizing KVM guest LV

Not needed for LXC containers!

Check if new device size has been applied:

steve@dockerhost:~/Superalgos/Docker$ sudo fdisk -l
[...]
GPT PMBR size mismatch (67108863 != 161480703) will be corrected by write.
The backup GPT table is not on the end of the device. This problem will be corrected by write.
Disk /dev/sda: 77 GiB, 82678120448 bytes, 161480704 sectors
Disk model: QEMU HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: CFEB7F82-35A0-47AF-8173-BE49754D8E71

Device       Start      End  Sectors Size Type
/dev/sda1     2048     4095     2048   1M BIOS boot
/dev/sda2     4096  2101247  2097152   1G Linux filesystem
/dev/sda3  2101248 67106815 65005568  31G Linux filesystem


Disk /dev/mapper/ubuntu--vg-ubuntu--lv: 30.102 GiB, 33281802240 bytes, 65003520 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
[...]

A similar entry should be presend on dmesg:

steve@dockerhost:~/Superalgos/Docker$ dmesg | grep sda
[...]
[    3.011860] EXT4-fs (sda2): mounted filesystem with ordered data mode. Opts: (null)
[  330.960346] sd 2:0:0:0: [sda] 161480704 512-byte logical blocks: (82.7 GB/77.0 GiB)
[  330.960404] sda: detected capacity change from 61203283968 to 82678120448

fdisk should report a size mismatch:

steve@dockerhost:~/Superalgos/Docker$ sudo fdisk -l /dev/sda
GPT PMBR size mismatch (67108863 != 161480703) will be corrected by write.
The backup GPT table is not on the end of the device. This problem will be corrected by write.
Disk /dev/sda: 77 GiB, 82678120448 bytes, 161480704 sectors
Disk model: QEMU HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: CFEB7F82-35A0-47AF-8173-BE49754D8E71

Device       Start      End  Sectors Size Type
/dev/sda1     2048     4095     2048   1M BIOS boot
/dev/sda2     4096  2101247  2097152   1G Linux filesystem
/dev/sda3  2101248 67106815 65005568  31G Linux filesystem

Resize the desired partition on that device:

steve@dockerhost:~/Superalgos/Docker$ sudo parted /dev/sda
GNU Parted 3.3
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print
Warning: Not all of the space available to /dev/sda appears to be used, you can fix the GPT to use all of the space (an extra 94371840 blocks) or continue with the current
setting?
Fix/Ignore? F
Model: QEMU QEMU HARDDISK (scsi)
Disk /dev/sda: 82.7GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start   End     Size    File system  Name  Flags
 1      1049kB  2097kB  1049kB                     bios_grub
 2      2097kB  1076MB  1074MB  ext4
 3      1076MB  34.4GB  33.3GB

(parted) resizepart 3 100%
(parted) quit
Information: You may need to update /etc/fstab.

Check if the new size is being properly reported by fdisk:

steve@dockerhost:~/Superalgos/Docker$ sudo fdisk -l /dev/sda
Disk /dev/sda: 77 GiB, 82678120448 bytes, 161480704 sectors
Disk model: QEMU HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: CFEB7F82-35A0-47AF-8173-BE49754D8E71

Device       Start       End   Sectors Size Type
/dev/sda1     2048      4095      2048   1M BIOS boot
/dev/sda2     4096   2101247   2097152   1G Linux filesystem
/dev/sda3  2101248 161480670 159379423  76G Linux filesystem

Resize the physical volume:

steve@dockerhost:~/Superalgos/Docker$ sudo pvresize /dev/sda3
  Physical volume "/dev/sda3" changed
  1 physical volume(s) resized or updated / 0 physical volume(s) not resized

steve@dockerhost:~/Superalgos/Docker$ sudo pvdisplay
  --- Physical volume ---
  PV Name               /dev/sda3
  VG Name               ubuntu-vg
  PV Size               <76.00 GiB / not usable 16.50 KiB
  Allocatable           yes
  PE Size               4.00 MiB
  Total PE              19455
  Free PE               11520
  Allocated PE          7935
  PV UUID               A0jdVL-0hkT-satt-BoOM-Zf3I-OwsH-h3gQT9

Resize the Logical Volume:

steve@dockerhost:~/Superalgos/Docker$ sudo lvresize --extents +100%FREE  --resizefs /dev/mapper/ubuntu--vg-ubuntu--lv
  Size of logical volume ubuntu-vg/ubuntu-lv changed from <31.00 GiB (7935 extents) to <76.00 GiB (19455 extents).
  Logical volume ubuntu-vg/ubuntu-lv successfully resized.
resize2fs 1.45.5 (07-Jan-2020)
Filesystem at /dev/mapper/ubuntu--vg-ubuntu--lv is mounted on /; on-line resizing required
old_desc_blocks = 4, new_desc_blocks = 10
The filesystem on /dev/mapper/ubuntu--vg-ubuntu--lv is now 19921920 (4k) blocks long.

Check if the LV size is bein properly reported at system level:

steve@dockerhost:~/Superalgos/Docker$ df -h
Filesystem                         Size  Used Avail Use% Mounted on
[...]
/dev/mapper/ubuntu--vg-ubuntu--lv   75G   29G   43G  40% /
[...]
steve@dockerhost:~/Superalgos/Docker$

Proxmox Running tailscale inside of a LXC container

root@proxmox:~# ls -l /dev/net/tun
crw-rw-rw- 1 root root 10, 200 Feb 12  2017 /dev/net/tun
root@proxmox:~# echo 'lxc.cgroup.devices.allow: c 10:200 rwm' >> /etc/pve/lxc/102.conf
root@proxmox:~# echo 'lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file' >> /etc/pve/lxc/102.conf
root@proxmox:~# pct enter 102
~ # apk add tailscale
~ # rc-update add tailscale
~ # echo 'net.ipv4.ip_forward = 1' | tee -a /etc/sysctl.conf
~ # echo 'net.ipv6.conf.all.forwarding = 1' | tee -a /etc/sysctl.conf
~ # sysctl -p /etc/sysctl.conf
~ # reboot
root@proxmox:~#

Python: Assigning dynamic variable names

  for token in BINANCE_TOKENS:
      globals()["%s_price" % token.lower()] = get_binance_usdt_ticker(token)
      print("%5s price is: %10s" % (token, str(globals()["%s_price" % token.lower()])) + " USD")

Python: Binance balances to CSV

import csv
import binance
from binance.client import Client
import configparser
import sys
import time
import array as arr

config = configparser.ConfigParser()
config.read('secrets.ini')

bnc_key = config.get("binance", "api_key")
bnc_sec = config.get("binance", "api_secret")
client = Client(bnc_key, bnc_sec)

clientAccount = client.get_account()

def csv_update_accountBalance():
    csv_filename="binance_portfolio.csv"
    with open(csv_filename, "w", newline='') as bnc_portfolio:
        wr = csv.writer(bnc_portfolio, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
        for balance in clientAccount["balances"]:
            asset = balance["asset"]
            locked = float(balance["locked"])
            free = float(balance["free"])
            total = sum((locked, free))
            data = (asset, locked, free, total)
            if total > 0:
                wr.writerow(data)

Python: Cryptography fails to install

Error code:

Collecting cryptography>=2.6.1
  Downloading cryptography-36.0.1.tar.gz (572 kB)
     |β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ| 572 kB 5.1 MB/s
  Installing build dependencies ... done
  Getting requirements to build wheel ... error
  ERROR: Command errored out with exit status 1:
   command: /Users/steve/.pyenv/versions/3.9.1/envs/ftx-cast/bin/python3.9 /Users/steve/.pyenv/versions/3.9.1/envs/ftx-cast/lib/python3.9/site-packages/pip/_vendor/pep517/_in_process.py get_requires_for_build_wheel /var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/tmpj3f_8iak
       cwd: /private/var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/pip-install-5rr4judb/cryptography
  Complete output (62 lines):

      =============================DEBUG ASSISTANCE=============================
      If you are seeing a compilation error please try the following steps to
      successfully install cryptography:
      1) Upgrade to the latest pip and try again. This will fix errors for most
         users. See: https://pip.pypa.io/en/stable/installing/#upgrading-pip
      2) Read https://cryptography.io/en/latest/installation/ for specific
         instructions for your platform.
      3) Check our frequently asked questions for more information:
         https://cryptography.io/en/latest/faq/
      4) Ensure you have a recent Rust toolchain installed:
         https://cryptography.io/en/latest/installation/#rust

      Python: 3.9.1
      platform: macOS-12.0.1-arm64-arm-64bit
      pip: n/a
      setuptools: 60.5.0
      setuptools_rust: 1.1.2
      =============================DEBUG ASSISTANCE=============================

  Traceback (most recent call last):
    File "/Users/steve/.pyenv/versions/3.9.1/envs/ftx-cast/lib/python3.9/site-packages/pip/_vendor/pep517/_in_process.py", line 280, in <module>
      main()
    File "/Users/steve/.pyenv/versions/3.9.1/envs/ftx-cast/lib/python3.9/site-packages/pip/_vendor/pep517/_in_process.py", line 263, in main
      json_out['return_val'] = hook(**hook_input['kwargs'])
    File "/Users/steve/.pyenv/versions/3.9.1/envs/ftx-cast/lib/python3.9/site-packages/pip/_vendor/pep517/_in_process.py", line 114, in get_requires_for_build_wheel
      return hook(config_settings)
    File "/private/var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/pip-build-env-068bxm92/overlay/lib/python3.9/site-packages/setuptools/build_meta.py", line 162, in get_requires_for_build_wheel
      return self._get_build_requires(
    File "/private/var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/pip-build-env-068bxm92/overlay/lib/python3.9/site-packages/setuptools/build_meta.py", line 143, in _get_build_requires
      self.run_setup()
    File "/private/var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/pip-build-env-068bxm92/overlay/lib/python3.9/site-packages/setuptools/build_meta.py", line 158, in run_setup
      exec(compile(code, __file__, 'exec'), locals())
    File "setup.py", line 39, in <module>
      setup(
    File "/private/var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/pip-build-env-068bxm92/overlay/lib/python3.9/site-packages/setuptools/__init__.py", line 155, in setup
      return distutils.core.setup(**attrs)
    File "/private/var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/pip-build-env-068bxm92/overlay/lib/python3.9/site-packages/setuptools/_distutils/core.py", line 109, in setup
      _setup_distribution = dist = klass(attrs)
    File "/private/var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/pip-build-env-068bxm92/overlay/lib/python3.9/site-packages/setuptools/dist.py", line 459, in __init__
      _Distribution.__init__(
    File "/private/var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/pip-build-env-068bxm92/overlay/lib/python3.9/site-packages/setuptools/_distutils/dist.py", line 293, in __init__
      self.finalize_options()
    File "/private/var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/pip-build-env-068bxm92/overlay/lib/python3.9/site-packages/setuptools/dist.py", line 837, in finalize_options
      ep(self)
    File "/private/var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/pip-build-env-068bxm92/overlay/lib/python3.9/site-packages/setuptools/dist.py", line 858, in _finalize_setup_keywords
      ep.load()(self, ep.name, value)
    File "/private/var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/pip-build-env-068bxm92/overlay/lib/python3.9/site-packages/cffi/setuptools_ext.py", line 219, in cffi_modules
      add_cffi_module(dist, cffi_module)
    File "/private/var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/pip-build-env-068bxm92/overlay/lib/python3.9/site-packages/cffi/setuptools_ext.py", line 49, in add_cffi_module
      execfile(build_file_name, mod_vars)
    File "/private/var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/pip-build-env-068bxm92/overlay/lib/python3.9/site-packages/cffi/setuptools_ext.py", line 25, in execfile
      exec(code, glob, glob)
    File "src/_cffi_src/build_openssl.py", line 76, in <module>
      ffi = build_ffi_for_binding(
    File "src/_cffi_src/utils.py", line 53, in build_ffi_for_binding
      ffi = build_ffi(
    File "src/_cffi_src/utils.py", line 73, in build_ffi
      ffi = FFI()
    File "/private/var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/pip-build-env-068bxm92/overlay/lib/python3.9/site-packages/cffi/api.py", line 48, in __init__
      import _cffi_backend as backend
  ImportError: dlopen(/private/var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/pip-build-env-068bxm92/overlay/lib/python3.9/site-packages/_cffi_backend.cpython-39-darwin.so, 0x0002): symbol not found in flat namespace '_ffi_prep_closure'
  ----------------------------------------
ERROR: Command errored out with exit status 1: /Users/steve/.pyenv/versions/3.9.1/envs/ftx-cast/bin/python3.9 /Users/steve/.pyenv/versions/3.9.1/envs/ftx-cast/lib/python3.9/site-packages/pip/_vendor/pep517/_in_process.py get_requires_for_build_wheel /var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/tmpj3f_8iak Check the logs for full command output.
WARNING: You are using pip version 20.2.3; however, version 21.3.1 is available.
You should consider upgrading via the '/Users/steve/.pyenv/versions/3.9.1/envs/ftx-cast/bin/python3.9 -m pip install --upgrade pip' command.

Solution:

$ brew install openssl@1.1 rust
Warning: openssl@1.1 1.1.1m is already installed and up-to-date.
To reinstall 1.1.1m, run:
  brew reinstall openssl@1.1
==> Downloading https://ghcr.io/v2/homebrew/core/rust/manifests/1.57.0_1
Already downloaded: /Users/steve/Library/Caches/Homebrew/downloads/5e9055ce02c980a2da1e31faca4b8569c4b98c2bc943718c4fd47e21e3ee5847--rust-1.57.0_1.bottle_manifest.json
==> Downloading https://ghcr.io/v2/homebrew/core/rust/blobs/sha256:7095ffb01f86d72954b4d97d0af33cd1920048e523145d02639c3
==> Downloading from https://pkg-containers.githubusercontent.com/ghcr1/blobs/sha256:7095ffb01f86d72954b4d97d0af33cd1920
######################################################################## 100.0%
==> Pouring rust--1.57.0_1.arm64_monterey.bottle.tar.gz
==> Caveats
Bash completion has been installed to:
  /opt/homebrew/etc/bash_completion.d
==> Summary
🍺  /opt/homebrew/Cellar/rust/1.57.0_1: 31,585 files, 777MB
==> Running `brew cleanup rust`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).

[0:523] 10:03:13 Tue Jan 18 [steve@macbook.lan:/dev/ttys014 +1] ~/code/ftx-cast
[0:500] 10:03:07 Tue Jan 18 [steve@macbook.lan:/dev/ttys019 +1] ~
$ env CRYPTOGRAPHY_SUPPRESS_LINK_FLAGS=1 LDFLAGS="$(brew --prefix openssl@1.1)/lib/libssl.a $(brew --prefix openssl@1.1)/lib/libcrypto.a" CFLAGS="-I$(brew --prefix openssl@1.1)/include" pip install cryptography
Requirement already satisfied: cryptography in ./.pyenv/versions/3.9.6/envs/covid/lib/python3.9/site-packages (36.0.1)
Requirement already satisfied: cffi>=1.12 in ./.pyenv/versions/3.9.6/envs/covid/lib/python3.9/site-packages (from cryptography) (1.15.0)
Requirement already satisfied: pycparser in ./.pyenv/versions/3.9.6/envs/covid/lib/python3.9/site-packages (from cffi>=1.12->cryptography) (2.21)
WARNING: You are using pip version 21.1.3; however, version 21.3.1 is available.
You should consider upgrading via the '/Users/steve/.pyenv/versions/3.9.6/envs/covid/bin/python3.9 -m pip install --upgrade pip' command.

[0:501] 10:03:18 Tue Jan 18 [steve@macbook.lan:/dev/ttys019 +1] ~

Python: Disabling en enabling stdout output

# Disabling any output.
def blockPrint():
    sys.stdout = open(os.devnull, 'w')
# Re-enabling output to stdout
def enablePrint():
    sys.stdout = sys.__stdout__

Python: Find element on dict_tuple

ticker_index = next(i for i, t in enumerate(list(tickers.items())) if t[0] == m)
ticker_values = list(tickers.items())[ticker_index][1]

Python: Fetch script execution path

print('sys.argv[0] =', sys.argv[0])
pathname = os.path.dirname(sys.argv[0])
print('path =', pathname)
print('full path =', os.path.abspath(pathname))

Python: IDLE can’t import Tkinter

Uninstall tcl-tk if installed:

brew uninstall --force tcl-tk
brew cleanup --force -s tcl-tk
brew cleanup --prune-prefix

Uninstall python:

pyenv uninstall 3.8.1

Set the necessary environment variables:

export PATH="/usr/local/opt/tcl-tk/bin:$PATH"      # You shoul add this one to your path on .bashrc or .bash_profile
export LDFLAGS="-L/usr/local/opt/tcl-tk/lib"
export CPPFLAGS="-I/usr/local/opt/tcl-tk/include"
export PKG_CONFIG_PATH="/usr/local/opt/tcl-tk/lib/pkgconfig"
export PYTHON_CONFIGURE_OPTS="--with-tcltk-includes='-I/usr/local/opt/tcl-tk/include' --with-tcltk-libs='-L/usr/local/opt/tcl-tk/lib -ltcl8.6 -ltk8.6'"

Install python back:

pyenv install 3.8.1

Test:

idle

and

python -m tkinter -c "tkinter._test()"


Python: Print numbers with at least X digits

def get_binance_usdt_ticker(coin):

    digits_to_show = 4

    global binance_tickers

    if binance_tickers == None:
        binance_tickers = requests.get("https://api.binance.com/api/v1/ticker/price")

    coindid = str(coin).upper() + "USDT"

    data = binance_tickers.json()

    for i in data:
        if i["symbol"] == coindid:
            price = float(i['price'])
            length_of_number = len(str(int(price)))

            if length_of_number >= digits_to_show:
                price = str(int(price))
            else:
                precision = ((digits_to_show - length_of_number))
                price = f"{price:.{precision}f}"

    return(price)

Python: Parsing arguments with argparse

Initial setup

import argparse

parser = argparse.ArgumentParser(description='How to use argparse?')

args = parser.parse_args()

Passing command line arguments

python3 argparse_2.py --a=5

import argparse

parser = argparse.ArgumentParser(description='A tutorial of argparse!')
parser.add_argument("--a")

args = parser.parse_args()
a = args.a
print(a)

If we don’t specify a value for a at the command line, then args.a will be None. We can solve this the following way:

import argparse

parser = argparse.ArgumentParser(description='A tutorial of argparse!')
parser.add_argument("--a", default=1, help="Using argparse!")

args = parser.parse_args()
a = args.a
print(a)

In this case, if we don’t pass a value for a through the command line, then its value will just default to 1.

By adding a string for the help variable we’re also able to print out a more robust description for each variable when applying --help:

usage: run.py [-h] [--a A]A tutorial of argparse!optional arguments:
  -h, --help  show this help message and exit
  --a A       This is the 'a' variable

Regular arguments ussage

mport argparse

parser = argparse.ArgumentParser(description='A tutorial of argparse!')
parser.add_argument("--a", default=1, type=int, help="This is the 'a' variable")
parser.add_argument("--name", default=None, type=str, help="Your name")

args = parser.parse_args()

Forces user to provide an input for a value, otherwise the script will throw an error and exit.

import argparse

parser = argparse.ArgumentParser(description='A tutorial of argparse!')
parser.add_argument("--a", default=1, type=int, help="This is the 'a' variable")
parser.add_argument("--name", required=True, type=str, help="Your name")

args = parser.parse_args()

If we supply a value for the --name argument then all is well! If we don’t, we’ll get an error message like this:

usage: run.py [-h] [--a A] --name NAME
run.py: error: the following arguments are required: --name

We can also limit the possible values for a particular command line argument using the choices argument.

import argparse

parser = argparse.ArgumentParser(description='A tutorial of argparse!')
parser.add_argument("--a", default=1, type=int, help="This is the 'a' variable")
parser.add_argument("--education",
                    choices=["highschool", "college", "university", "other"],
                    required=True, type=str, help="Your name")

args = parser.parse_args()

ed = args.education

if ed == "college" or ed == "university":
    print("Has degree")
elif ed == "highschool":
  print("Finished Highschool")
else:
    print("Does not have degree")

Now if we enter any value that’s in our choices list, the code will run just fine and take in our education argument.

usage: run.py [-h] [--a A] --education {highschool,college,university,other}
run.py: error: argument --education: invalid choice: '5' (choose from 'highschool', 'college', 'university', 'other')

Advanced usage

The action argument allows us to specify some action we want our Argument Parser to take.

import argparse

parser = argparse.ArgumentParser(description='A tutorial of argparse!')
parser.add_argument("--a", action="store_true", help="This is the 'a' variable")
parser.add_argument("--b", action="store_const", const=10,
                    help="This is the 'b' variable")

args = parser.parse_args()
a = args.a
b = args.b

print(a)
print(b)

Define a set of parser command line arguments which are mutually exclusive.

import argparse

parser = argparse.ArgumentParser(description='A tutorial of argparse!')
group = parser.add_mutually_exclusive_group(required=True)

group.add_argument('--a', action='store_true', help="This is the 'a' variable")
group.add_argument('--b', action='store_true', help="This is the 'b' variable")

args = parser.parse_args()
a = args.a
b = args.b

print(a)
print(b)

This won’t allow to send a and b at the same time like this: python3 argparse_8.py --a --b


Python: Print imported modules version

ipykernel._version 5.1.3
re 2.2.1
json 2.0.9
[...]
matplotlib 3.1.2
PIL._version 6.2.1
PIL 6.2.1
cffi 1.13.2
PIL.Image 6.2.1
  
def imports_version():
    """
    Print imported modules and its version
    Source: https://stackoverflow.com/a/50396275
    """

    import sys
    for module in sys.modules:
        try:
            print(module,sys.modules[module].__version__)
        except:
            try:
                if  type(modules[module].version) is str:
                    print(module,sys.modules[module].version)
                else:
                    print(module,sys.modules[module].version())
            except:
                try:
                    print(module,sys.modules[module].VERSION)
                except:
                    pass

imports_version()

Python: Pretty print JSON

def print_pretty_json(raw_json):

    from pygments import highlight
    from pygments.formatters.terminal256 import Terminal256Formatter
    from pygments.lexers.web import JsonLexer

    colorful = highlight(
        json.dumps(json_data, indent=4, sort_keys=True),
        lexer=JsonLexer(),
        formatter=Terminal256Formatter(style="monokai")
    )

    print(colorful)

Python: Print all declared variables

local_vars = list(locals().items())
for var, obj in local_vars:
    print(var, obj)

Python: pyaudio fails to install on MacBook M1 (Sillicon)

Encountered error:

      src/_portaudiomodule.c:29:10: fatal error: 'portaudio.h' file not found
      #include "portaudio.h"
               ^~~~~~~~~~~~~
      197 warnings and 1 error generated.
      error: command '/usr/bin/clang' failed with exit code 1
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
error: legacy-install-failure

Γ— Encountered error while trying to install package.
╰─> pyaudio

note: This is an issue with the package mentioned above, not pip.
hint: See above for output from the failure.

Solution:

$ brew install portaudio
$ python -m pip install --global-option='build_ext' --global-option='-I/opt/homebrew/Cellar/portaudio/19.7.0/include' --global-option='-L/opt/homebrew/Cellar/portaudio/19.7.0/lib' pyaudio
WARNING: Disabling all use of wheels due to the use of --build-option / --global-option / --install-option.
Collecting pyaudio
  Using cached PyAudio-0.2.11.tar.gz (37 kB)
  Preparing metadata (setup.py) ... done
Skipping wheel build for pyaudio, due to binaries being disabled for it.
Installing collected packages: pyaudio

Python: pyenv not switching $PATH

Issue: Virutalenv should use 3.9.7 but $PATH remains unchanged:

[0:297] 05:18:14 Tue Nov 23 [steve@virualmac.lan:/dev/ttys000 +1] ~
$ python -V
Python 2.7.16

[0:298] 05:18:19 Tue Nov 23 [steve@virualmac.lan:/dev/ttys000 +1] ~
$ pyenv activate wa
(wa)
[0:299] 05:18:24 Tue Nov 23 [steve@virualmac.lan:/dev/ttys000 +1] ~
$ python -V
Python 2.7.16
(wa)
[0:300] 05:18:29 Tue Nov 23 [steve@virualmac.lan:/dev/ttys000 +1] ~
$ pyenv virtualenvs
  3.9.7/envs/wa (created from /Users/steve/.pyenv/versions/3.9.7)
* wa (created from /Users/steve/.pyenv/versions/3.9.7)
(wa)
[0:301] 05:18:37 Tue Nov 23 [steve@virualmac.lan:/dev/ttys000 +1] ~
$

Solution: Remove any existant pyenv entry on your .bashrc / .bash_profile and add the following:

export PYENV_VIRTUALENV_DISABLE_PROMPT=1
export PYENV_ROOT=/Users/steve/.pyenv   # get yours with 'echo "$(pyenv root)"'
export PATH="$PYENV_ROOT/bin:$PATH"

if which pyenv > /dev/null; then
    eval "$(pyenv init --path)"     # this only sets up the path stuff
    eval "$(pyenv init -)"          # this makes pyenv work in the shell
fi
if which pyenv-virtualenv-init > /dev/null; then
    eval "$(pyenv virtualenv-init - bash)"
fi

Python: RSA key pair generation

# -*- coding: utf-8 -*-

import binascii
import os
import sys

from Crypto.Cipher import PKCS1_OAEP
from Crypto.Protocol.KDF import PBKDF2
from Crypto.PublicKey import RSA

private_key_path = './private_rsa.key'
public_key_path = './public_rsa.pub'

password = 'SuperPassword'
salt = 'CqhetUYjMnkaWTARz7ygmfjP9cbrxLaHwedWMNenfX9k4WEeAPKeTKMAmxPeTPMgoVwatfovV4icFqUibAqAHKUFxgMdPqnbznNR'

# bigger count = harder to bruteforce
master_key = PBKDF2(password, salt, count=100000)


def my_rand(n):
    my_rand.counter += 1
    return PBKDF2(master_key, "my_rand:%d" % my_rand.counter, dkLen=n, count=1)


def gen_key():
    my_rand.counter = 0

    key = RSA.generate(4096, randfunc=my_rand)

    private, public = key.exportKey('PEM'), key.publickey().exportKey('PEM')

    with open(private_key_path, 'w') as private_file:
        os.chmod(private_key_path, 0o0600)
        private_file.write(key.exportKey('PEM').decode())
    with open(public_key_path, 'w') as public_file:
        public_file.write(key.publickey().exportKey('OpenSSH').decode())


gen_key()

Python: pip install nacl fails on MacBook M1 (Sillicon)

Error message:


Building wheels for collected packages: pynacl
  Building wheel for pynacl (pyproject.toml) ... error
  ERROR: Command errored out with exit status 1:
  [...]
  checking build system type... Invalid configuration `arm64-apple-darwin20.6.0': machine `arm64-apple' not recognized
  configure: error: /bin/sh /private/var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/pip-install-ka7rjz60/pynacl_073ab76c5f084754b415c13485496898/src/libsodium/build-aux/config.sub arm64-apple-darwin20.6.0 failed
  [...]
  subprocess.CalledProcessError: Command '['/private/var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/pip-install-ka7rjz60/pynacl_073ab76c5f084754b415c13485496898/src/libsodium/configure', '--disable-shared', '--enable-static', '--disable-debug', '--disable-dependency-tracking', '--with-pic', '--prefix', '/private/var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/pip-install-ka7rjz60/pynacl_073ab76c5f084754b415c13485496898/build/temp.macosx-11-arm64-3.8']' returned non-zero exit status 1.
  ----------------------------------------
  ERROR: Failed building wheel for pynacl
Failed to build pynacl
ERROR: Could not build wheels for pynacl, which is required to install pyproject.toml-based projects

Solution:

$ brew install libsodium
$ ln -s /opt/homebrew/Cellar/libsodium/1.0.18_1/lib/libsodium.a /usr/local/lib/libsodium.a
$ SODIUM_INSTALL=system LIBSODIUM_MAKE_ARGS=-j8 python3.8 -m pip install pynacl
DEPRECATION: Configuring installation scheme with distutils config files is deprecated and will no longer work in the near future. If you are using a Homebrew or Linuxbrew Python, please see discussion at https://github.com/Homebrew/homebrew-core/issues/76621
Collecting pynacl
  Using cached PyNaCl-1.4.0.tar.gz (3.4 MB)
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Requirement already satisfied: cffi>=1.4.1 in /opt/homebrew/lib/python3.8/site-packages (from pynacl) (1.14.5)
Requirement already satisfied: six in /opt/homebrew/lib/python3.8/site-packages (from pynacl) (1.16.0)
Requirement already satisfied: pycparser in /opt/homebrew/lib/python3.8/site-packages (from cffi>=1.4.1->pynacl) (2.20)
Building wheels for collected packages: pynacl
  Building wheel for pynacl (pyproject.toml) ... done
  Created wheel for pynacl: filename=PyNaCl-1.4.0-cp38-cp38-macosx_11_0_arm64.whl size=99572 sha256=9465d47f53ef40e8c73620cbb738a2f7984d6dfe3b75ee109966642565f22a1e
  Stored in directory: /Users/steve/Library/Caches/pip/wheels/10/23/c0/f42041fbad88c47b268b6119919130b407b48e24b41a349684
Successfully built pynacl
Installing collected packages: pynacl
  DEPRECATION: Configuring installation scheme with distutils config files is deprecated and will no longer work in the near future. If you are using a Homebrew or Linuxbrew Python, please see discussion at https://github.com/Homebrew/homebrew-core/issues/76621
DEPRECATION: Configuring installation scheme with distutils config files is deprecated and will no longer work in the near future. If you are using a Homebrew or Linuxbrew Python, please see discussion at https://github.com/Homebrew/homebrew-core/issues/76621
Successfully installed pynacl-1.4.0
$

Python: pip upgrading all packages at once

pip list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1  | xargs -n1 pip install

Python: strftime reference cheatsheet

Code Example Description
%a Sun Weekday as locale’s abbreviated name.
%A Sunday Weekday as locale’s full name.
%w 0 Weekday as a decimal number, where 0 is Sunday and 6 is Saturday.
%d 08 Day of the month as a zero-padded decimal number.
%-d 8 Day of the month as a decimal number. (Platform specific)
%b Sep Month as locale’s abbreviated name.
%B September Month as locale’s full name.
%m 09 Month as a zero-padded decimal number.
%-m 9 Month as a decimal number. (Platform specific)
%y 13 Year without century as a zero-padded decimal number.
%Y 2013 Year with century as a decimal number.
%H 07 Hour (24-hour clock) as a zero-padded decimal number.
%-H 7 Hour (24-hour clock) as a decimal number. (Platform specific)
%I 07 Hour (12-hour clock) as a zero-padded decimal number.
%-I 7 Hour (12-hour clock) as a decimal number. (Platform specific)
%p AM Locale’s equivalent of either AM or PM.
%M 06 Minute as a zero-padded decimal number.
%-M 6 Minute as a decimal number. (Platform specific)
%S 05 Second as a zero-padded decimal number.
%-S 5 Second as a decimal number. (Platform specific)
%f 000000 Microsecond as a decimal number, zero-padded on the left.
%z +0000 UTC offset in the form Β±HHMM[SS[.ffffff]] (empty string if the object is naive).
%Z UTC Time zone name (empty string if the object is naive).
%j 251 Day of the year as a zero-padded decimal number.
%-j 251 Day of the year as a decimal number. (Platform specific)
%U 36 Week number of the year (Sunday as the first day of the week) as a zero padded decimal number. All days in a new year preceding the first Sunday are considered to be in week 0.
%W 35 Week number of the year (Monday as the first day of the week) as a decimal number. All days in a new year preceding the first Monday are considered to be in week 0.
%c Sun Sep 8 07:06:05 2013 Locale’s appropriate date and time representation.
%x 09/08/13 Locale’s appropriate date representation.
%X 07:06:05 Locale’s appropriate time representation.
%% % A literal β€˜%’ character.

Python: The Python ssl extension was not compiled. Missing the OpenSSL lib?

Issue:

$ pyenv install 3.9.6
python-build: use openssl@1.1 from homebrew
python-build: use readline from homebrew
Downloading Python-3.9.6.tar.xz...
-> https://www.python.org/ftp/python/3.9.6/Python-3.9.6.tar.xz
Installing Python-3.9.6...
python-build: excluding `/opt/homebrew/opt/coreutils/libexec/gnubin' from PATH
python-build: use tcl-tk from homebrew
python-build: use readline from homebrew
python-build: use zlib from xcode sdk

ERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?

Please consult to the Wiki page to fix the problem.
https://github.com/pyenv/pyenv/wiki/Common-build-problems

BUILD FAILED (OS X 12.0.1 using python-build 20180424)

Inspect or clean up the working tree at /var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/python-build.20211126015409.2011
Results logged to /var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/python-build.20211126015409.2011.log

Last 10 log lines:
   $ensurepip --root=/ ; \
 fi
Looking in links: /var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/tmpc0agtatg
Processing /private/var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/tmpc0agtatg/setuptools-56.0.0-py3-none-any.whl
Processing /private/var/folders/tj/mmpfbvxn0vx7735hrw7189_c0000gn/T/tmpc0agtatg/pip-21.1.3-py3-none-any.whl
Installing collected packages: setuptools, pip
  WARNING: The scripts pip3 and pip3.9 are installed in '/Users/steve/.pyenv/versions/3.9.6/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
  NOTE: The current PATH contains path(s) starting with `~`, which may not be expanded by all applications.
Successfully installed pip-21.1.3 setuptools-56.0.0

Solution:

$ brew uninstall openssl && brew install openssl && CFLAGS="-I$(brew --prefix openssl)/include" LDFLAGS="-L$(brew --prefix openssl)/lib" pyenv install 3.9.6
Uninstalling /opt/homebrew/Cellar/openssl@3/3.0.0_1... (6,415 files, 27.8MB)

Warning: The following openssl@3 configuration files have not been removed!
If desired, remove them manually with `rm -rf`:
  /opt/homebrew/etc/openssl@3
  /opt/homebrew/etc/openssl@3/cert.pem
  /opt/homebrew/etc/openssl@3/ct_log_list.cnf
  /opt/homebrew/etc/openssl@3/ct_log_list.cnf.dist
  /opt/homebrew/etc/openssl@3/misc
  /opt/homebrew/etc/openssl@3/misc/CA.pl
  /opt/homebrew/etc/openssl@3/misc/tsget
  /opt/homebrew/etc/openssl@3/misc/tsget.pl
  /opt/homebrew/etc/openssl@3/openssl.cnf
  /opt/homebrew/etc/openssl@3/openssl.cnf.dist

Warning: The following may be openssl@3 configuration files and have not been removed!
If desired, remove them manually with `rm -rf`:
  /opt/homebrew/etc/openssl@1.1
==> Downloading https://ghcr.io/v2/homebrew/core/openssl/3/manifests/3.0.0_1
######################################################################## 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/openssl/3/blobs/sha256:a63be68c6f59f218794b6beef367cc137887c1c9efec5facaad53beed9db4d51
==> Downloading from https://pkg-containers.githubusercontent.com/ghcr1/blobs/sha256:a63be68c6f59f218794b6beef367cc137887c1c9efec5facaad53beed9db4d51?se=2021-11-26T
######################################################################## 100.0%
==> Pouring openssl@3--3.0.0_1.arm64_monterey.bottle.tar.gz
==> Caveats
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in
  /opt/homebrew/etc/openssl@3/certs

and run
  /opt/homebrew/opt/openssl@3/bin/c_rehash

openssl@3 is keg-only, which means it was not symlinked into /opt/homebrew,
because macOS provides LibreSSL.

If you need to have openssl@3 first in your PATH, run:
  echo 'export PATH="/opt/homebrew/opt/openssl@3/bin:$PATH"' >> /Users/steve/.bash_profile

For compilers to find openssl@3 you may need to set:
  export LDFLAGS="-L/opt/homebrew/opt/openssl@3/lib"
  export CPPFLAGS="-I/opt/homebrew/opt/openssl@3/include"

For pkg-config to find openssl@3 you may need to set:
  export PKG_CONFIG_PATH="/opt/homebrew/opt/openssl@3/lib/pkgconfig"

==> Summary
🍺  /opt/homebrew/Cellar/openssl@3/3.0.0_1: 6,415 files, 27.7MB
python-build: use openssl@1.1 from homebrew
python-build: use readline from homebrew
Installing Python-3.9.6...
python-build: excluding `/opt/homebrew/opt/coreutils/libexec/gnubin' from PATH
python-build: use tcl-tk from homebrew
python-build: use readline from homebrew
python-build: use zlib from xcode sdk
Installed Python-3.9.6 to /Users/steve/.pyenv/versions/3.9.6

You have new mail in /var/mail/steve

[0:517] 02:00:01 Fri Nov 26 [steve@macbook.lan:/dev/ttys032 +1] ~/code/pylips
$

Python: line 21: /usr/local/Cellar/pyenv/1.2.21/libexec/pyenv: No such file or directory

08% 2021-03-05 12:49:59 ⌚  Steve-MBP in /usr/local/Cellar/pyenv
β—‹ β†’ python --version
/Users/steve/.pyenv/shims/python: line 21: /usr/local/Cellar/pyenv/1.2.21/libexec/pyenv: No such file or directory

10% 2021-03-05 12:50:18 ⌚  Steve-MBP in /usr/local/Cellar/pyenv
β—‹ β†’ export PATH="$(pyenv root)/libexec/pyenv:$PATH"

10% 2021-03-05 12:50:21 ⌚  Steve-MBP in /usr/local/Cellar/pyenv
β—‹ β†’ python --version
/Users/steve/.pyenv/shims/python: line 21: /usr/local/Cellar/pyenv/1.2.21/libexec/pyenv: No such file or directory

10% 2021-03-05 12:50:22 ⌚  Steve-MBP in /usr/local/Cellar/pyenv
β—‹ β†’ pyenv rehash

10% 2021-03-05 12:50:40 ⌚  Steve-MBP in /usr/local/Cellar/pyenv
β—‹ β†’ python --version
Python 3.8.5

Python Binance: Timestamp for this request was 1000ms ahead of the server’s time


95% 2021-03-07 01:06:57 ⌚  Steve-MBP in ~/Documents/code/binance_api
Β± |master ?:1 βœ—| β†’ /Users/steve/.pyenv/versions/3.8.5/bin/python /Users/steve/Documents/code/binance_api/main.py
WARNING:root:[BINANCE_API_ERROR][CODE: "-1021"][MESSAGE: "Timestamp for this request was 1000ms ahead of the server's time."]
{'code': -1021, 'msg': "Timestamp for this request was 1000ms ahead of the server's time."}

95% 2021-03-07 01:07:51 ⌚  Steve-MBP in ~/Documents/code/binance_api
Β± |master ?:2 βœ—| β†’ sudo sntp -sS pool.ntp.org
Password:
sntp 4.2.8p15@1.3728-o Sun Nov 15 06:11:24 UTC 2020 (1)
kod_init_kod_db(): Cannot open KoD db file /var/db/ntp-kod: No such file or directory
2021-03-07 01:08:26.784085 (-0100) -1.254732 +/- 0.846401 pool.ntp.org 162.159.200.123 s3 no-leap

95% 2021-03-07 01:08:48 ⌚  Steve-MBP in ~/Documents/code/binance_api
Β± |master ?:2 βœ—| β†’ sudo touch /var/db/ntp-kod

95% 2021-03-07 01:08:50 ⌚  Steve-MBP in ~/Documents/code/binance_api
Β± |master ?:2 βœ—| β†’ sudo chown root:wheel /var/db/ntp-kod

95% 2021-03-07 01:08:50 ⌚  Steve-MBP in ~/Documents/code/binance_api
$ sudo sntp -sS pool.ntp.org
sntp 4.2.8p15@1.3728-o Sun Nov 15 06:11:24 UTC 2020 (1)
2021-03-07 01:13:07.787012 (-0100) +0.000188 +/- 0.014438 pool.ntp.org 51.38.162.10 s2 no-leap

python-binance: API key & secret

bnc_key = config.get("binance", "api_key")
bnc_sec = config.get("binance", "api_secret")
client = Client(bnc_key, bnc_sec)

python-binance: Get price for each available pair

for asset in client.get_all_tickers():
    print(asset["symbol"], asset["price"])

Expected output:

ETHBTC 0.01931200
LTCBTC 0.00661200
BNBBTC 0.00207770
NEOBTC 0.00127700
QTUMETH 0.01155700
EOSETH 0.02162500
[...]

python-binance: Updating all pairs on PostgreSQL

Connection config:

conn = psycopg2.connect(dbname=db_name,
                        host=db_host,
                        port='5432',
                        user=db_user,
                        password=db_pass
                        )
conn.set_session(autocommit=True)

Function:

def db_update_price(pair, price, exchange):
    cur = conn.cursor()
    cur.execute("INSERT INTO prices (pair, price, source, updatetime) VALUES (%s, %s, %s, now()) \
        ON CONFLICT (pair) DO \
            UPDATE SET (pair, price, source, updatetime) = (EXCLUDED.pair, EXCLUDED.price, EXCLUDED.source, EXCLUDED.updatetime)",
                (pair, price, exchange))
    cur.close()

Loop:

for asset in client.get_all_tickers():
    print(asset["symbol"], asset["price"])
    db_update_price(asset["symbol"], asset["price"], "BINANCE")

Raspberry Pi: Getting ddcutil to work on RPi 4

  • make sure you are at least on firmware 5.10 - this is now mainstream, so sudo apt update && sudo apt upgrade will be sufficient.
  • In /boot/config.txt look for the [pi4] section and set replace dtoverlay=vc4-fkms-v3d with dtoverlay=vc4-kms-v3d
  • In /etc/modules add i2c_dev
  • Reboot
  • Install ddcutil - sudo apt install ddcutil
  • Done

Check if everything is working and your monitor is detected: ddcutil detect The output should be similar to this

Display 1
I2C bus: /dev/i2c-12
EDID synopsis:
Mfg id: BNQ
Model: BenQ GW2270
Serial number: AAF03393019
Manufacture year: 2015
EDID version: 1.3
VCP version: 2.1

Find out what commands you can run on your monitor: ddcutil capabilities Check the command overview page for how to read and write your monitor parameters.


Raspberry Pi: Installing Python 3.8.1 + pyenv

Installing dependencies:

sudo apt-get install -y build-essential tk-dev libncurses5-dev libncursesw5-dev libreadline6-dev libdb5.3-dev libgdbm-dev libsqlite3-dev libssl-dev libbz2-dev libexpat1-dev liblzma-dev zlib1g-dev libffi-dev tar wget vim

Fetch pyenv:

git clone https://github.com/pyenv/pyenv.git ~/.pyenv

Define environment variables:

echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc && echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc

Source new vars:

source ~/.bashrc

Install python 3.8.1:

pyenv install 3.8.1

Raspberry Pi: Not booting when powering LCD through USB

Not the best soution but this will serve as workaround.

Append the following lines to /boot/config.txt:

# Use HDMI mode even if no HDMI monitor is detected
hdmi_force_hotplug=1

# avoids the rainbow splash screen on boot
disable_splash=1

# wait for given number of seconds in start.elf before loading kernel. delay = 1000 * boot_delay + boot_delay_ms. Default 1
boot_delay=3

# removes the warning overlay. (low power)
avoid_warnings=1

# when adding this line the USB power manager will change its output current limit (for all 4 USB ports combined) from 600mA to double that, 1200mA.
max_usb_current=1

Raspberry Pi: Mounting filesystem over ssh

sshfs pi@192.168.1.15:/home/pi ~/pi -ovolname=mount

Raspberry Pi: Setting up an Alfa AWUS036ACS 802.11ac adapter

🍰 pi@cutiepie:~/rtl8812au $ sudo wget http://downloads.fars-robotics.net/wifi-drivers/install-wifi -O /usr/bin/install-wifi
--2021-09-15 00:00:21--  http://downloads.fars-robotics.net/wifi-drivers/install-wifi
Resolving downloads.fars-robotics.net (downloads.fars-robotics.net)... 82.68.133.179
Connecting to downloads.fars-robotics.net (downloads.fars-robotics.net)|82.68.133.179|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 22262 (22K)
Saving to: β€˜/usr/bin/install-wifi’

/usr/bin/install-wifi                      100%[=======================================================================================>]  21.74K  48.8KB/s    in 0.4s

2021-09-15 00:00:22 (48.8 KB/s) - β€˜/usr/bin/install-wifi’ saved [22262/22262]

🍰 pi@cutiepie:~/rtl8812au $ sudo chmod +x /usr/bin/install-wifi
🍰 pi@cutiepie:~/rtl8812au $ sudo /usr/bin/install-wifi

 *** Raspberry Pi wifi driver installer by MrEngman.
 *** Performing self-update
 *** Relaunching after update

 *** Raspberry Pi wifi driver installer by MrEngman.

Your current kernel revision = 5.10.52-v7l+
Your current kernel build    = #1441

Checking for a wifi module to determine the driver to install.

Your wifi module is Bus 001 Device 004: ID 0bda:0811 Realtek Semiconductor Corp.

And it uses the 8812au driver.


Your Pi revision number is c03111
You have a Pi 4 v1.1
Checking for a 8812au wifi driver module for your current kernel.
There is a driver module available for this kernel revision.
Downloading the 8812au driver, 8812au-5.10.52-v7l-1441.tar.gz.
Installing the 8812au driver.

Installing driver config file 8812au.conf.
mv 8812au.conf /etc/modprobe.d/.
Installing driver module 8812au.ko.
install -p -m 644 8812au.ko /lib/modules/5.10.52-v7l+/kernel/drivers/net/wireless
Loading and running the 8812au driver, 8812au.ko.
🍰 pi@cutiepie:~/rtl8812au $ sudo reboot

Raspberry Pi: UAS issues when using USB3.0 SSD drives

When facing similar errors to the following ones:

Dec  9 23:53:45 dappnodepi kernel: [ 1498.121254] sd 0:0:0:0: [sda] tag#0 uas_eh_abort_handler 0 uas-tag 14 inflight: CMD IN
Dec  9 23:53:45 dappnodepi kernel: [ 1498.121265] sd 0:0:0:0: [sda] tag#0 CDB: opcode=0x28 28 00 29 41 17 b8 00 04 00 00
Dec  9 23:53:45 dappnodepi kernel: [ 1498.139999] scsi host0: uas_eh_device_reset_handler start
Dec  9 23:53:45 dappnodepi kernel: [ 1498.268722] usb 2-2: reset SuperSpeed Gen 1 USB device number 2 using xhci_hcd
Dec  9 23:53:45 dappnodepi kernel: [ 1498.293280] scsi host0: uas_eh_device_reset_handler success

Look for the USD3.0 SSD disk device and vendor id:

Dec  9 23:27:38 dappnodepi kernel: [    1.493488] usb 2-2: new SuperSpeed Gen 1 USB device number 2 using xhci_hcd
Dec  9 23:27:38 dappnodepi kernel: [    1.514823] usb 2-2: New USB device found, idVendor=152d, idProduct=1561, bcdDevice= 2.04
Dec  9 23:27:38 dappnodepi kernel: [    1.514884] usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Dec  9 23:27:38 dappnodepi kernel: [    1.514910] usb 2-2: Product: SABRENT
Dec  9 23:27:38 dappnodepi kernel: [    1.514931] usb 2-2: Manufacturer: SABRENT
Dec  9 23:27:38 dappnodepi kernel: [    1.514953] usb 2-2: SerialNumber: DB9876543214E
Dec  9 23:27:38 dappnodepi kernel: [    1.528438] scsi host0: uas

And edit /boot/cmdline.txt adding usb-storage.quirks=152d:1561:u as follows:

usb-storage.quirks=152d:1561:u console=serial0,115200 console=tty1 root=PARTUUID=a44bd8c9-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

Safari: Paywalls Bypass bookmarklet

javascript:javascript:(function()%7Bvar%20url%20=%20location.href;window.open('https://12ft.io/'+url,'_blank');%7D)();

screen: Restarting a command inside a screen session

alias k='screen -X -S sol quit; screen -dmS sol; screen -S sol -p 0 -X stuff "cd ~/grid_bot && python3 bot.py\n"; tail -100f grid_bot/trades.log'

or:

alias l="screen -xR loop . ~/.envi"
alias r='pkill -if "/usr/bin/SCREEN -dmS looper /root/code/tradingtools/looper.sh"; source /root/.envi; /bin/bash -c ". /root/.envi; /usr/bin/screen -dmS looper /root/code/tradingtools/looper.sh"; l'

sed: recursively replacing a string (gsed/sed)

gfind -type f -print0 | gxargs -0 gsed -i 's|string_to_be_replaced|new_string|g'

Silicon: Installing HDF5 / h5py on Mac Silicon Processors

$ brew reinstall hdf5
$ export HDF5_export HDF5_DIR="$(brew --prefix hdf5)"
$ python3 pip ^Cp install --no-binary=h5py h5py
$ python3 -m pip install pip install --no-binary=h5py h5py
Defaulting to user installation because normal site-packages is not writeable
Collecting h5py
  Downloading h5py-3.6.0.tar.gz (384 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 384.2/384.2 KB 6.9 MB/s eta 0:00:00
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Requirement already satisfied: numpy>=1.14.5 in ./Library/Python/3.8/lib/python/site-packages (from h5py) (1.22.2)
Building wheels for collected packages: h5py
  Building wheel for h5py (pyproject.toml) ... done
  Created wheel for h5py: filename=h5py-3.6.0-cp38-cp38-macosx_10_14_arm64.whl size=2509979 sha256=5870a12d86bf4714807803869acbe865d09c2ec82f5391f63840e914b04ebd45
  Stored in directory: /Users/steve/Library/Caches/pip/wheels/81/65/ba/4c85d3d8d3361decacd56de44da71a84d213e8f3d43100e868
Successfully built h5py
Installing collected packages: h5py
Successfully installed h5py-3.6.0

SSH: Exposing local service behind NAT through reverse SSH tunnel

  1. Start flask on you local machine:
[0:685] 01:41:49 Mon Oct 18 [steve@macbook.local:/dev/ttys003 +1] ~/nextcloud/jekyll
$ /Users/steve/.pyenv/shims/python /Users/steve/Documents/code/webhook/main.py
 * Serving Flask app 'main' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
  1. Set GatewayPorts to yes on remote host and restart sshd:
[0:257] 01:43:31 Mon Oct 18 [root@remote:/dev/pts/0 +1] ~
# grep GatewayPorts /etc/ssh/sshd_config
GatewayPorts yes
[0:256] 01:40:35 Mon Oct 18 [root@remote:/dev/pts/0 +1] ~
# service ssh restart
  1. Start a tunnel pointing 7654 on remote host to 5000 on your local machine:
ssh -N root@remote.com -R 7654:localhost:5000
  1. Test if the flask service on your local is now accessible through remote.com on port 7654:

From any machine on the Internet:

curl -X POST "http://remote.com:7654/webhook" -H "Content-Type: application/json" --data '{"action": "notification"}'

Expected output on your local service:

$ /Users/steve/.pyenv/shims/python /Users/steve/Documents/code/webhook/main.py
 * Serving Flask app 'main' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
received data:  {'action': 'notification'}
button returned:, gave up:true
None
127.0.0.1 - - [18/Oct/2021 01:46:13] "POST /webhook HTTP/1.1" 200 -

SSH: Using ProxyCommand

On ~/.ssh/config:

Host grid
  Hostname grid.domain.com
  User root
  ProxyCommand ssh -q root@bastion.domain.com nc -q0 192.168.1.40 22

SSH: Nasty reverse tunnel

On the node within nated / firewalled network:

while true; do ssh -N -4 -p 22 -R 11111:localhost:22 user@host_in_cloud.com; sleep 5; done &

On the reachable host:

ssh -p 11111 pi@localhost

Keep in mind you can still do it worse –> /etc/rc.local


Solana: Managing Ledger Nano S with Solana CLI

Fetch your public key (aka. address):

0 βœ“ steve@hal9000 ~/crypto/market $ solana-keygen pubkey usb://ledger?key=0
9pT8PT000jttqy4XXiE7000gYwWz1JjdkQUk0003ch8S

Check account balance:

0 βœ“ steve@hal9000 ~/crypto/market $ solana balance 9pT8PT000jttqy4XXiE7000gYwWz1JjdkQUk0003ch8S
1 SOL

Send SOL from a Ledger Nano S:

0 βœ“ steve@hal9000 ~/crypto/market/tradingview $ solana transfer XXXXAAAXXXDESTINATIONADDRESSXXXXAAAXXX 5000.33 --keypair usb://ledger?key=0
Waiting for your approval on Ledger hardware wallet usb://ledger/ABCDEFGHI1234567890ABCDEF
βœ… Approved
ABCDEFGHI1234567890ABCDEFABCDEFGHI1234567890ABCDEFABCDEFGHI1234567890ABCDEFABCDEFGHI1234567890ABCDEF
0 βœ“ steve@hal9000 ~/crypto/market/tradingview $

Solana: Stacking from Ledger S

Generate a new wallet which will be dedicated to stacking:

$ solana-keygen new --no-passphrase -o stake-account.json
Wrote new keypair to stake-account.json
=========================================================================
pubkey: STACKING_WALLET_PUBKEY
=========================================================================
Save this seed phrase to recover your new keypair:
climb climb climb climb climb climb climb climb climb climb climb climb
=========================================================================

Deposit the tokens you want to stake on the new wallet and set authorities

$ solana create-stake-account --from usb://ledger?key=0 stake-account.json 10 \
  --stake-authority usb://ledger?key=0 --withdraw-authority usb://ledger?key=0 \
  --fee-payer usb://ledger?key=0

Waiting for your approval on Ledger hardware wallet usb://ledger/DONTFEELLIKESHARINGTHISNEITHER
βœ… Approved

Signature: DONTFEELLIKESHARINGTHISNEITHERDONTFEELLIKESHARINGTHISNEITHER

Check stake status:

$ solana stake-account STACKING_WALLET_PUBKEY

Balance: 10 SOL
Rent Exempt Reserve: 0.00292929 SOL
Stake account is undelegated
Stake Authority: LEDGER_PUBKEY
Withdraw Authority: LEDGER_PUBKEY
Lockup Timestamp: 1970-01-01T00:00:00Z (UnixTimestamp: 0)
Lockup Epoch: 0
Lockup Custodian: 11111111111111111111111111111111

Delegate stake:

  • BxFf75Vtzro2Hy3coFHKxFMZo5au8W7J8BmLC3gCMotU is the validator vote account.
  • STACKING_WALLET_PUBKEY is your stacking wallet account.
$ solana delegate-stake --stake-authority usb://ledger?key=0 STACKING_WALLET_PUBKEY BxFf75Vtzro2Hy3coFHKxFMZo5au8W7J8BmLC3gCMotU --fee-payer usb://ledger?key=0
Waiting for your approval on Ledger hardware wallet usb://ledger/sbvAuRAzvURi5TjHsbvAuRAzpRqqkaYvsbvAuRAzV15X
βœ… Approved

Signature: ivdBKZmyC8jRLvexs1kMqDAC2GVjLUhYmyC8jRLvexs1kgqJC2GVjLUhYoLawBAij3ZmyC8jRLvexs1kpzhcxnvj

At this point your stake should be delegated to the chosen validator:

$ solana stake-account STACKING_WALLET_PUBKEY
Balance: 10000 SOL
Rent Exempt Reserve: 0.0099999 SOL
Delegated Stake: 10000 SOL
Active Stake: 0 SOL
Activating Stake: 10000 SOL
Stake activates starting from epoch: 53
Delegated Vote Account Address: BxFf75Vtzro2Hy3coFHKxFMZo5au8W7J8BmLC3gCMotU
Stake Authority: LEDGER_PUBKEY
Withdraw Authority: LEDGER_PUBKEY
Lockup Timestamp: 1970-01-01T00:00:00Z (UnixTimestamp: 0)
Lockup Epoch: 0
Lockup Custodian: 11111111111111111111111111111111

Your stake will be taken into consideration starting epoch 53 according to the previous output.

Deactivate stake:

$ solana deactivate-stake --stake-authority usb://ledger?key=0 STACKING_WALLET_PUBKEY --fee-payer usb://ledger?key=0
Waiting for your approval on Ledger hardware wallet usb://ledger/DONTFEELLIKESHARINGTHISNEITHER
βœ… Approved

Signature: DONTFEELLIKESHARINGTHISNEITHERDONTFEELLIKESHARINGTHISNEITHER

Withdrawing stake:

$ solana withdraw-stake STACKING_WALLET_PUBKEY LEDGER_PUBKEY 10000 --fee-payer usb://ledger?key=0 --withdraw-authority usb://ledger?key=0
Waiting for your approval on Ledger hardware wallet usb://ledger/AAAT2vURFFFTjHsBBBuRAzpRqqkCCCw54MLDDD1EEE
βœ… Approved

Signature: AAAAAAAAAAnnJNoxU2aSNAV3HG4wRTULBBBBBBBBB3xXE7Lz6xUEDCCCCCCAedpsYpZNsz8eVDDDDDDDD

Telegram: Fetch chat id

0 βœ“ $ telegram_token='12345678910:ABCDEFGHSJDHFabcdefg12345'
0 βœ“ $ curl --silent https://api.telegram.org/bot${telegram_token}/getUpdates | jq '.result[].message.chat.id'
987654321
0 βœ“ $

Telegram: Fetch last message

0 βœ“ $ telegram_token='12345678910:ABCDEFGHSJDHFabcdefg12345'
0 βœ“ $ curl --silent https://api.telegram.org/bot${telegram_token}/getUpdates | jq '.result[].message.text'
"testing."
0 βœ“ $

Telegram: Python snippet for sending messages

import requests

def telegram_bot_sendtext(bot_message):

   bot_token = ''
   bot_chatID = ''
   send_text = 'https://api.telegram.org/bot' + bot_token + '/sendMessage?chat_id=' + bot_chatID + '&parse_mode=Markdown&text=' + bot_message

   response = requests.get(send_text)

   return response.json()


test = telegram_bot_sendtext("Testing Telegram bot")
print(test)

TkInter: Install on macOS

Uninstall current python version:

pyenv uninstall 3.8.1
pyenv: remove /Users/steveobs/.pyenv/versions/3.8.1? y
0 βœ“ ~/script/ $

Set proper env variables and re-install python:

0 βœ“ steve@hal9000 ~/script $ env \
>   PATH="$(brew --prefix tcl-tk)/bin:$PATH" \
>   LDFLAGS="-L$(brew --prefix tcl-tk)/lib" \
>   CPPFLAGS="-I$(brew --prefix tcl-tk)/include" \
>   PKG_CONFIG_PATH="$(brew --prefix tcl-tk)/lib/pkgconfig" \
>   CFLAGS="-I$(brew --prefix tcl-tk)/include" \
>   PYTHON_CONFIGURE_OPTS="--with-tcltk-includes='-I$(brew --prefix tcl-tk)/include' --with-tcltk-libs='-L$(brew --prefix tcl-tk)/lib -ltcl8.6 -ltk8.6'" \
>   pyenv install 3.8.1
python-build: use openssl@1.1 from homebrew
python-build: use readline from homebrew
Installing Python-3.8.1...
python-build: use readline from homebrew
python-build: use zlib from xcode sdk
Installed Python-3.8.1 to /Users/steveobs/.pyenv/versions/3.8.1

0 βœ“ steve@hal9000 ~/script $

Ubiquiti: Unifi client not detecting JDK

Link a java installation to the Unifi.app:

sudo ln -s /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/ /Applications/UniFi.app/Contents/PlugIns/adoptopenjdk-8.jdk

The next step is to tell the Unifi.app which edit the Info.plist:

sudo vim /Applications/UniFi.app/Contents/Info.plist

Add the JVMRuntime after the JVMOptions:

<key>JVMRuntime</key>
<string>adoptopenjdk-8.jdk</string>

Ubuntu: get network interfaces name

steve@hal9000:~# find /sys/class/net -type l -not -lname '*virtual*' -printf '%f\n'
eth0
ens10
steve@hal9000:~#

Ubuntu: installing Eternal Terminal

sudo apt-get install -y software-properties-common && sudo add-apt-repository -y ppa:jgmath2000/et && sudo apt-get update && sudo apt-get install -y et && sudo service et restart

VSCodium: Create VSIX file from GitGub repo

npm install -g vsce
git clone https://github.com/leifcr/pine-script-syntax-highlighting
cd pine-script-syntax-highlighting/
vsce package

VSCodium: Enable VS Code Extensions Marketplace

Edit /Applications/VSCodium.app/Contents/Resources/app/product.json and edit the extensionsGallery section as follows:

Original:

  "extensionsGallery": {
    "serviceUrl": "https://open-vsx.org/vscode/gallery",
    "itemUrl": "https://open-vsx.org/vscode/item"
  }

Updated to use the VS Code Marketplace as extension provider:

  "extensionsGallery": {
    "serviceUrl": "https://marketplace.visualstudio.com/_apis/public/gallery",
    "cacheUrl": "https://vscode.blob.core.windows.net/gallery/index",
    "itemUrl": "https://marketplace.visualstudio.com/items"
  },
  "linkProtectionTrustedDomains": ["https://open-vsx.org", "https://marketplace.visualstudio.com", "https://vscode.blob.core.windows.net"],

Old version follows:

  "extensionsGallery": {
    "serviceUrl": "https://marketplace.visualstudio.com/_apis/public/gallery",
    "itemUrl": "https://marketplace.visualstudio.com/items"
  }

Wallabag: manually activating a user

cd /var/www/wallabag
bin/console fos:user:activate <username> --env=prod

Expected output:

steve@hal9000:~$ docker exec -it 123ABC123ABC /bin/sh
/var/www/wallabag # bin/console fos:user:activate bluejeans --env=prod
User "bluejeans" has been activated.
/var/www/wallabag #

xbar: TOTP widget

#!/bin/bash

# <xbar.title>Authenticator</xbar.title>
# <xbar.version>v0.1</xbar.version>
# <xbar.author>Gunasekaran Namachivayam</xbar.author>
# <xbar.author.github>gunasekar</xbar.author.github>
# <xbar.desc>This plugin will generate the TOTP tokens and allows to copy them to clipboard</xbar.desc>

# Hack for language not being set properly and unicode support
export LANG="${LANG:-en_US.UTF-8}"

# update the key value pairs as per your requirement
# Key - for your reference to identify a TOTP Account
# Value - base32 secret key corresponding to the TOTP Account
totp_secrets=(
        "Binance:XXXXXXXXXX:chart"
        "GitHub:AAAAAAAAAAAAAAA:bulb"
  )

totp_secrets_sorted=($(printf '%s\n' "${totp_secrets[@]}"|sort))

# oath-toolkit needs to be installed. Use 'brew install oath-toolkit'
# update the appropriate path of oathtool binary below
oathtool="/opt/homebrew/bin/oathtool"

FONT="size=12 font=OperatorMono-Book trim=true"

function get-totp {
  $oathtool --totp -b "$1"
}

if [[ "$1" == "copy" ]]; then
  echo -n "$(echo -n "$2")" | pbcopy
  exit
fi

echo "πŸ¦„"
echo '---'
echo "Clear Clipboard | $FONT bash='$0' param1=copy param2=' ' terminal=false"
echo "---"


for secret in "${totp_secrets_sorted[@]}" ; do
    #KEY="${secret%%:*}"
    #VALUE="${secret##*:}"
    KEY=$(echo $secret|cut -d':' -f1)
    VALUE=$(echo $secret|cut -d':' -f2)
    EMOJI=":$(echo $secret|cut -d':' -f3):"

    if [[ ${EMOJI} == "::" ]]; then
      EMOJI=":recycle:"
    fi

    token=$( get-totp "$VALUE" )
    echo "$(printf "%s %-12s %-8s" $EMOJI $KEY $token) | $FONT bash='$0' param1=copy param2='$token' terminal=false"
done

Yowsup: Installing, pathing and registering

Install Yowsup through the following command as any other will fail:

python3 -m pip install pip install https://files.pythonhosted.org/packages/95/1e/2ca683a638f25a022f68b522db68924f06501db2f695bbf5738d2038af02/yowsup-3.3.0.tar.gz

Update some package files as in this commit: https://github.com/tgalal/yowsup/pull/3127/files

Run the registration process as follows:

$  yowsup-cli registration -r sms --config-phone 34XXXXXXXXX --config-cc 34 --config-sim_mcc 214 --config-sim_mnc 01
E 2022-04-19 23:05:33,781 yowsup.config.manager - Could not find a config for profile=34XXXXXXXXX, paths checked: 34XXXXXXXXX:/Users/steve/Library/Application Support/yowsup/34XXXXXXXXX/config.yo:/Users/steve/Library/Application Support/yowsup/34XXXXXXXXX/config.json
yowsup-cli  v3.2.1
yowsup      v3.3.0


Copyright (c) 2012-2019 Tarek Galal
http://www.openwhatsapp.org

This software is provided free of charge. Copying and redistribution is
encouraged.

If you appreciate this software and you would like to support future
development please consider donating:
http://openwhatsapp.org/yowsup/donate


W 2022-04-19 23:05:33,881 yowsup.common.http.warequest - Passing Config to WARequest is deprecated, pass a YowProfile instead
I 2022-04-19 23:05:35,402 yowsup.common.http.warequest - b'{"flash_type":0,"length":6,"login":"34XXXXXXXXX","method":"sms","notify_after":86400,"retry_after":64,"sms_wait":64,"status":"sent","voice_wait":64}\n'
status: b'sent'
length: 6
method: b'sms'
retry_after: 64
login: b'34XXXXXXXXX'
sms_wait: 64
voice_wait: 64


$ yowsup-cli registration --register 292202 --config-phone 34XXXXXXXXX
yowsup-cli  v3.2.1
yowsup      v3.3.0


Copyright (c) 2012-2019 Tarek Galal
http://www.openwhatsapp.org

This software is provided free of charge. Copying and redistribution is
encouraged.

If you appreciate this software and you would like to support future
development please consider donating:
http://openwhatsapp.org/yowsup/donate


W 2022-04-19 23:07:32,542 yowsup.common.http.warequest - Passing Config to WARequest is deprecated, pass a YowProfile instead
I 2022-04-19 23:07:35,850 yowsup.common.http.warequest - b'{"login":"34XXXXXXXXX","security_code_set":false,"status":"ok","type":"new"}\n'
{
    "__version__": 1,
    "cc": "34",
    "client_static_keypair": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX==",
    "expid": "XXXXXXXXXXXXXXXXXXXXX==",
    "fdid": "XXXXXX-XXXX-XXXX-XXXXX-XXXXXXX",
    "id": "XXXXXXXXXXXXXXXXXXXXXXXXXXX=",
    "login": "34XXXXXXXXX",
    "mcc": "000",
    "mnc": "000",
    "phone": "34XXXXXXXXX",
    "sim_mcc": "214",
    "sim_mnc": "01"
}
status: b'ok'
login: b'34XXXXXXXXX'
type: b'new'

[0:582] 11:07:36 Tue Apr 19 [steve@macbook.local:/dev/ttys003 +1] ~

Yubikey: Enable/disable touch policy

enc:  encryption
sig:  signature
aut:  authentication

Enable:   on
Disable:  off

Example:

0 βœ“ steve@hal9000 ~ $ ykman openpgp set-touch sig on
Enter admin PIN:
Set touch policy of signature key to on? [y/N]: y
0 βœ“ steve@hal9000 ~ $