How to create temporary directory in Python

Minimal example:

import tempfile
tempdir = tempfile.mkdtemp()
print(tempdir) # prints e.g. /tmp/tmpvw0936nd

tempfile.mkdtemp() will automatically create that directory. The directory will not automatically be deleted!

Custom prefix (recommended):

import tempfile
tempdir = tempfile.mkdtemp(prefix="myapplication-")
print(tempdir) # prints e.g. /tmp/myapplication-ztcy6s2w

 

Posted by Uli Köhler in Python

What does Delivery Status Notification ‘550 5.1.1 User unknown (in reply to RCPT TO command)’ mean?

Problem:

You are trying to send an E-Mail but you receive a Delivery Status notification response like this:

This is the mail system at host techoverflow.net.

I'm sorry to have to inform you that your message could not
be delivered to one or more recipients. It's attached below.

For further assistance, please send mail to postmaster.

If you do so, please include this problem report. You can
delete your own text from the attached returned message.

                   The mail system

<john.miller@recipient.com>: host mail.recpient.com[213.216.0.1] said: 550 5.1.1 User
    unknown (in reply to RCPT TO command)

Solution:

If the response contains a line like this:

<john.miller@recipient.com>: host mail.recpient.com[213.216.0.1] said: 550 5.1.1 User unknown (in reply to RCPT TO command)

it means that the recipient’s email address (check the start of the line – in this case it’s john.miller@recipient.com) does not exist. Most likely

  • You used a wrong or mis-spelled email adress (check the address for typos) or
  • the person you sent the mail to doesn’t exist any more at the company you’re trying to send the mail to
  • the domain does not match – e.g. company.com instead of company.net – or copmany.net instead of company.net

Note that if you sent the email to multiple recipients (e.g. using CC), the other recipients will have received the mail if you don’t get a separate status notification or they are listed in that Delivery status notification as well. Note that one Delivery status notification E-Mail might have multiple 550 5.1.1 User unknown lines, so be sure to check the Delivery status notification carefully.

Note that in some cases it will take a couple of minutes until the Delivery status notification arrives in your Inbox, or it might end up in your Spam folder, so be sure to check there as well.

Tip: In case you don’t have another E-Mail address at the company you’re trying to send E-Mails to, try these addresses:

  • info@company.com
  • sales@company.com
  • webmaster@company.com

or check the company’s Imprint or Privacy page, which often contains an active E-Mail address.

Posted by Uli Köhler in E-Mail

How to re-encode your Audiobooks as Opus

Opus is a modern high-efficiency audio codec that is especially suited to encode speech with very low bitrates.

Therefore, it’s a good fit to compress your Audiobook library so it consumes much less space.

First, choose a bitrate for Opus. I recommend to use 24kbit/s (24k) for general use, or 32 kbit/s (32k) if you want to have higher quality audio, e.g. if you are listening using good-quality headphones.

You can use ffmpeg directly by using this syntax:

ffmpeg -i <input file> -c:a libopus -b:a bitrate <output file>

but I recommend to use this shell function instead:

function audioToOpus { ffmpeg -i "$2" -c:a libopus -b:a "$1" "${2%.*}.opus" ; }

Copy & paste it into your shell, then call it like this:

audioToOpus <bitrate> <input file>

Example:

audioToOpus 24k myaudiobook.mp3

This command will create myaudiobook.opus. myaudiobook.mp3 will not be deleted automatically.

In case you want to have this function available permanently, add the function definition to your ~/.bashrc or ~/.zshrc, depending on which shell you use.

Posted by Uli Köhler in Audio, Linux

How to disable syntax highlighting in nano

To temporarily disable syntax highlighting in GNU nano, use the -Ynone option:

Instead of

nano myfile.php

use

nano -Ynone myfile.php

In order to permanently disable nano syntax highlighting, run this command:

echo "alias nano='nano -Ynone'" >> ~/.$(echo $SHELL | rev | cut -d/ -f1 | rev)rc
source ~/.$(echo $SHELL | rev | cut -d/ -f1 | rev)rc # Reload immediately

This will add nano -Ynone as an alias for nano into your .bashrc or .zshrc

Posted by Uli Köhler in Linux

How I fixed my Arduino ISP ‘Device signature = …’ errors

Problem:

I was trying to program my Arduino using an AVRISP MK II programmer, but every time I tried to program it (using avrdude or the Arduino software), I encountered errors like this:

avrdude: stk500v2_command(): command failed
avrdude: stk500v2_program_enable(): bad AVRISPmkII connection status: MOSI fail, RST fail, SCK fail, Target reverse inserted
avrdude: initialization failed, rc=-1
avrdude: AVR device initialized and ready to accept instructions
avrdude: Device signature = 0xb058e2
avrdude: Expected signature for ATmega2560 is 1E 98 01
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.

Solution:

In my case, the reason for this issue was that there was a shield connected to the SPI bus.

Since the SPI bus on the Arduino is shared with the ICSP header for In-System Programming (ISP), which is the protocol used by external programmers for programming AVR chips, connecting anything else to the SPI bus may cause issues.

Try to disconnect anything from the SPI bus. If the CS (chip select) signal of the extra device on the SPI bus is low, it might interfere with the communication with the AVR chip!

Posted by Uli Köhler in Arduino

How to fix Arduino ‘U8glib.h: No such file or directory’

Problem:

You want to compile an Arduino sketch, but you see an error message like

In file included from sketch/ultralcd.cpp:96:0:
ultralcd_impl_DOGM.h:46:20: error: U8glib.h: No such file or directory
compilation terminated.
exit status 1
U8glib.h: No such file or directory

Solution:

In Arduino, click on the Tools menu, then click on Manage libraries. Now enter u8glib into the search bar an press Enter.

Scroll down to the U8glib library, hover over it with your mouse and click Install on the bottom right. Now the error should be gone.

Posted by Uli Köhler in Arduino

How to disable InsecureRequestWarning: Unverified HTTPS request is being made.

If you use requests or urllib3, requests with SSL verification disabled will print this warning:

/usr/local/lib/python3.6/dist-packages/urllib3/connectionpool.py:851: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)

If you want to disable this warning and you can’t just enable verification, add this code

import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

at the top of your Python file.

Posted by Uli Köhler in Python

Fixing Octave string compare

Problem:

You want to compare two strings in Octave like myString == "foobar" but you see an error message like

error: myscript.m: mx_el_eq: nonconformant arguments (op1 is 1x25, op2 is 1x6)
error: called from
    myscript.m at line 26 column 1

Solution:

You can’t compare strings using == in Octave!

Use strcmp like this: Instead of myString == "foobar" use

strcmp(myString, "foobar") == 1

 

Posted by Uli Köhler in Octave

How to get current shell name (e.g. bash/zsh) on Linux

To get just the name of the shell, e.g. bash or zsh, use

echo $SHELL | rev | cut -d/ -f1 | rev

Example:

$ echo $SHELL | rev | cut -d/ -f1 | rev
bash

To get the full path of the current shell executable, use

echo $SHELL

Example:

$ echo $SHELL
/bin/zsh

 

Posted by Uli Köhler in Linux

Installing apt packages using cloud-init

This cloud-init example installs nginx on Debian- or Ubuntu- based systems:

packages:
- nginx

If you want to enable upgrading packages, use:

package_upgrade: true
packages:
- nginx

 

Posted by Uli Köhler in Cloud, cloud-init

How to fix docker-compose start ERROR: No containers to start

Problem:

When running docker-compose start, you see an error message like this:

Starting mongodb     ... error
Starting myapp       ... error

ERROR: No containers to start

Solution:

In order to start your containers, use docker-compose up, instead of docker-compose start!

Posted by Uli Köhler in Container, Docker

The super-simple docker-compose cheatsheet

Run these commands in the directory (or git repo) where docker-compose.yml is located!

Start all services

docker-compose up -d

-d means run in background (= daemonize).

Stop all services

docker-compose down

Restart all services

docker-compose restart

Update containers

docker-compose pull
docker-compose restart

View logs

docker-compose logs

To view and follow use

docker-compose logs -f

 

Start a specific service (and all the services it depends on)

docker-compose start myservice

Show info about which container images are being used

docker-compose images
Posted by Uli Köhler in Container, Docker

How to install automated certbot/LetsEncrypt renewal in 30 seconds

Let’s Encrypt currently issues certificates for 3 months at a time only. For many users, this mandates automated renewal of Let’s Encrypt certificates, however many manuals how to install automated renewals on ordinary Linux servers are needlessly complicated.

I created a systemd-timer based daily renewal routine using TechOverflow’s Simple systemd timer generator.

Quick install using

wget -qO- https://techoverflow.net/scripts/install-renew-certbot.sh | bash

This is the script which automatically creates & installs both systemd config files.

#!/bin/sh
# This script installs automated certbot renewal onto systemd-based systems.
# It requires that certbot is installed in /usr/bin/certbot!
# This needs to be run using sudo!

cat >/etc/systemd/system/RenewCertbot.service <<EOF
[Unit]
Description=RenewCertbot

[Service]
Type=oneshot
ExecStart=/usr/bin/certbot renew
WorkingDirectory=/tmp
EOF

cat >/etc/systemd/system/RenewCertbot.timer <<EOF
[Unit]
Description=RenewCertbot

[Timer]
OnCalendar=daily
Persistent=true

[Install]
WantedBy=timers.target
EOF

# Enable and start service
systemctl enable RenewCertbot.timer && sudo systemctl start RenewCertbot.timer

To view logs, use

journalctl -xfu RenewCertbot.service

To view the status, use

sudo systemctl status RenewCertbot.timer

To immediately run a renewal, use

sudo systemctl start RenewCertbot.service
Posted by Uli Köhler in Linux, nginx

How to make TopoDS_Face from gp_Pnts

OCCUtils provides Face::FromPoints() to linearly connect a set of gp_Pnt points and make a face from the resulting edges:

#include <occutils/Face.hxx>

using namespace OCCUtils;

gp_Pnt p1, p2, p3; // Your points!

TopoDS_Face face = Face::FromPoints({p1, p2, p3});

Face::FromPoints() will automatically remove duplicate consecutive points and connect the last point to the first point.

Note that if there are not enough unique points (you need at least 3 unique points to make a valid face!), Face::FromPoints() will return a TopoDS_Face where .IsNull() is true.

Posted by Uli Köhler in OpenCASCADE

Converting vector of TopoDS_Face to vector of TopoDS_Shape in OpenCASCADE

OCCUtils provides Shapes::FromFaces  to convert a std::vector<TopoDS_Face> to a std::vector<TopoDS_Shape> in OpenCASCADE:

#include <occutils/Shape.hxx>

using namespace OCCUtils;

std::vector<TopoDS_Face> faces = /* ... */;
std::vector<TopoDS_Shape> shapes = Shapes::FromFaces(faces);

In case you need to do it manually without using OCCUtils, use this snippet:

#include <algorithm>

// Create return vector
std::vector<TopoDS_Shape> shapes;
shapes.reserve(faces.size());
// Do the copying
std::copy(faces.begin(), faces.end(), std::back_inserter(shapes));

 

Posted by Uli Köhler in OpenCASCADE

Converting vector of TopoDS_Solid to vector of TopoDS_Shape in OpenCASCADE

OCCUtils provides Shapes::FromSolids  to convert a std::vector<TopoDS_Solid> to a std::vector<TopoDS_Shape> in OpenCASCADE:

#include <occutils/Shape.hxx>

using namespace OCCUtils;

std::vector<TopoDS_Solid> solids = /* ... */;
std::vector<TopoDS_Shape> shapes = Shapes::FromSolids(solids);

In case you need to do it manually without using OCCUtils, use this snippet:

#include <algorithm>

// Create return vector
std::vector<TopoDS_Shape> shapes;
shapes.reserve(solids.size());
// Do the copying
std::copy(solids.begin(), solids.end(), std::back_inserter(shapes));

 

Posted by Uli Köhler in OpenCASCADE

Python subprocess.check_output(): Set working directory

If you have code that uses subprocess.check_output() to call a command like

subprocess.check_output("ls .", shell=True)

you can use the cwd=... argument of subprocess.check_output() to define the working directory. Example:

subprocess.check_output("ls .", cwd="../", shell=True)

cwd means change working directory and is interpreted relative to the current working directory. However, you can also use absolute paths:

subprocess.check_output("ls .", cwd="/etc/", shell=True)

 

Posted by Uli Köhler in Python

Minimal nginx WebSocket reverse-proxy example

If you have a nginx config clause like

location /app/ {
    proxy_pass http://app-server;
}

you can easily make it reverse-proxy Websocket connections as well by adding these clauses inside location { ... }:

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";

Full example:

location /app/ {
    proxy_pass http://app-server;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "Upgrade";
}

 

Posted by Uli Köhler in nginx

Minimal local nginx setup using Docker

If you have not installed Docker, see our guide at How to install docker and docker-compose on Ubuntu in 30 seconds

1. Create your nginx config file (my-nginx.conf). This is a template that reverse proxys TechOverflow:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    location / {
        proxy_pass https://techoverflow.net;
        proxy_http_version 1.1;
    }
}

3. Start nginx using docker:

docker run -it -p 80:80 --rm -v $(pwd)/my-nginx.conf:/etc/nginx/conf.d/default.conf nginx:latest

4. Go to http://localhost and see the result!

Explanation of the docker command:

  • docker run -it: Create a new docker container and run it in interactive mode (i.e. it will not run in the background, once you kill the command, nginx will exit)
  • -p 80:80: Makes port 80 of the nginx server (the standard HTTP port) available on the host’s port 80. The first 80 is the host port whereas the second port 80 is the container’s port.
  • --rm: Once the container is stopped, delete it!
  • -v $(pwd)/my-nginx.conf:/etc/nginx/conf.d/default.conf: Map my-nginx.conf in the current directory ($(pwd)) to /etc/nginx/conf.d/default.conf on the container.
  • nginx:latest: In the container run the official nginx image from DockerHub in the latest version.

Explanation of the nginx config file:

  • server { ... }: Everything inside this blog will belong together. You can
  • listen 80 default_server; Listen on port 80 (the standard HTTP port) and make this the default server, i.e. respond to any domain name that does not have any other server configured.
  • listen [::]:80 default_server; Same as the previous line, but for IPv6. [::] means: Listen on all IPv6 addresses.
  • location / { ... }: Everything inside this block is valid for any URL starting with / i.e. any URL at all. In clauses like location /app { ... } the content of the clause would be valid for URLs starting with /app only, e.g. http://localhost/app/ or http://localhost/app/dashboard.
  • proxy_pass https://techoverflow.net; Redirect requests to the current location (/) to the server https://techoverflow.net using a reverse proxy.
  • proxy_http_version 1.1; This sets the HTTP version that nginx uses to make the requests to https://techoverflow.net. This is not always neccessary but might increase compatibility.
Posted by Uli Köhler in Docker, nginx

Python bottle minimal redirect example

To redirect in bottle, use this snippet:

response.status = 303
response.set_header('Location', 'https://techoverflow.net')

303 is the HTTP response code See Other. In certain applications you might want to use 301 (permanent redirect) or 307 (temporary redirect) instead.

Full example:

#!/usr/bin/env python3
from bottle import route, run, response

@route('/')
def redirect():
    response.status = 303
    response.set_header('Location', 'https://techoverflow.net')

run(host='localhost', port=9000)

 

Posted by Uli Köhler in Python