Skip to content

November of 2022

Introduction

  • New: Add the donation information.

Activism

Environmentalism

Life Management

Task Management

OpenProject

  • New: Introduce OpenProject.

    OpenProject is an Open source project management software.

    The benefits over other similar software are:

    The things I don't like are:

    • Data can be exported as XML or CSV but it doesn't export everything. You have access to the database though, so if you'd like a better extraction of the data you in theory can do a selective dump of whatever you need.
    • It doesn't yet have tag support. You can meanwhile add the strings you would use as tags in the description, and then filter by text in description.
    • There is no demo instance where you can try it. It's easy though to launch a Proof of Concept environment yourself if you already know docker-compose.
    • Even thought the Community (free) version has many features the next aren't:
      • Status boards: you can't have Kanban boards that show the state of the issues as columns. You can make it yourself through a Basic board and with the columns as the name of the state. But when you transition an issue from state, you need to move the issue and change the property yourself. I've thought of creating a script that works with the API to do this automatically, maybe through the webhooks of the openproject, but it would make more sense to spend time on pydo.
      • Version boards: Useful to transition issues between sprints when you didn't finish them in time. Probably this is easily solved through bulk editing the issues.
      • Custom actions looks super cool, but as this gives additional value compared with the competitors, I understand it's a paid feature.
      • Display relations in the work package list: It would be useful to quickly see which tasks are blocked, by whom and why. Nothing critical though.
      • Multiselect custom fields: You can only do single valued fields. Can't understand why this is a paid feature.
      • 2FA authentication is only an Enterprise feature.
      • OpenID and SAML are an enterprise feature.

    Also included:

  • New: Web based task manager.

    Life happened and the development of pydo has fallen behind in my priority list. I've also reached a point where simplest one is no longer suitable for my workflow because:

    • I loose a lot of time in the reviews.
    • I loose a lot of time when doing the different plannings (year, trimester, month, week, day).
    • I find it hard to organize and refine the backlog.

    As pydo is not ready yet and I need a solution that works today better than the simplest task manager, I've done an analysis of the state of the art of self-hosted applications of all of them the two that were more promising were Taiga and OpenProject.

    Finally I chose OpenProject.

  • New: Deal with big number of tasks.

    As the number of tasks increase, the views of your work packages starts becoming more cluttered. As you can't fold the hierarchy trees it's difficult to efficiently manage your backlog.

    I've tried setting up a work package type that is only used for the subtasks so that they are filtered out of the view, but then you don't know if they are parent tasks unless you use the details window. It's inconvenient but having to collapse the tasks every time it's more cumbersome. You'll also need to reserve the selected subtask type (in my case Task) for the subtasks.

  • New: Sorting work package views.

    They are sorted alphabetically, so the only way to sort them is by prepending a number. You can do 0. Today instead of Today. It's good to do big increments between numbers, so the next report could be 10. Backlog. That way if you later realize you want another report between Today and Backlog, you can use 5. New Report and not rename all the reports.

  • New: Pasting text into the descriptions.

    When I paste the content of the clipboard in the description, all new lines are removed (\n), the workaround is to paste it inside a code snippet.

Coding

Languages

PDM

  • Correction: Solve circular dependencies by manual constraining.

    It also helps to run pdm update with the -v flag, that way you see which are the candidates that are rejected, and you can put the constrain you want. For example, I was seeing the next traceback:

    pdm.termui: Conflicts detected:
      pyflakes>=3.0.0 (from <Candidate autoflake 2.0.0 from https://pypi.org/simple/autoflake/>)
      pyflakes<2.5.0,>=2.4.0 (from <Candidate flake8 4.0.1 from unknown>)
    

    So I added a new dependency to pin it:

    [tool.pdm.dev-dependencies]
    dependencies = [
        # Until flakeheaven supports flake8 5.x
        # https://github.com/flakeheaven/flakeheaven/issues/132
        "flake8>=4.0.1,<5.0.0",
        "pyflakes<2.5.0",
    ]
    

    If none of the above works, you can override them:

    [tool.pdm.overrides]
    "importlib-metadata" = ">=3.10"
    
  • New: Suggest to use pydeps.

    If you get lost in understanding your dependencies, you can try using pydeps to get your head around it.

Configure Docker to host the application

  • New: Attach a docker to many networks.

    You can't do it through the docker run command, there you can only specify one network. However, you can attach a docker to a network with the command:

    docker network attach network-name docker-name
    

Click

  • New: File System Isolation.

    For basic command line tools with file system operations, the CliRunner.isolated_filesystem() method is useful for setting the current working directory to a new, empty folder.

    from click.testing import CliRunner
    from cat import cat
    
    def test_cat():
        runner = CliRunner()
        with runner.isolated_filesystem():
            with open("hello.txt", "w") as f:
                f.write("Hello World!")
    
            result = runner.invoke(cat, ["hello.txt"])
            assert result.exit_code == 0
            assert result.output == "Hello World!\n"
    

    Pass temp_dir to control where the temporary directory is created. The directory will not be removed by Click in this case. This is useful to integrate with a framework like Pytest that manages temporary files.

    def test_keep_dir(tmp_path):
        runner = CliRunner()
    
        with runner.isolated_filesystem(temp_dir=tmp_path) as td:
            ...
    

Pytest

  • New: The tmp_path fixture.

    You can use the tmp_path fixture which will provide a temporary directory unique to the test invocation, created in the base temporary directory.

    tmp_path is a pathlib.Path object. Here is an example test usage:

    def test_create_file(tmp_path):
        d = tmp_path / "sub"
        d.mkdir()
        p = d / "hello.txt"
        p.write_text(CONTENT)
        assert p.read_text() == CONTENT
        assert len(list(tmp_path.iterdir())) == 1
        assert 0
    
  • Correction: Deprecate the tmpdir fixture.

    Warning: Don't use tmpdir use tmp_path instead because tmpdir uses py which is unmaintained and has unpatched vulnerabilities.

Python Snippets

  • Correction: Deprecate tmpdir in favour of tmp_path.
  • New: Pad integer with zeros.

    >>> length = 1
    >>> print(f'length = {length:03}')
    length = 001
    
  • New: Pathlib make parent directories if they don't exist.

    pathlib.Path("/tmp/sub1/sub2").mkdir(parents=True, exist_ok=True)
    

    From the docs:

    • If parents is true, any missing parents of this path are created as needed; they are created with the default permissions without taking mode into account (mimicking the POSIX mkdir -p command).

    • If parents is false (the default), a missing parent raises FileNotFoundError.

    • If exist_ok is false (the default), FileExistsError is raised if the target directory already exists.

    • If exist_ok is true, FileExistsError exceptions will be ignored (same behavior as the POSIX mkdir -p command), but only if the last path component is not an existing non-directory file.

  • New: Pathlib touch a file.

    Create a file at this given path.

    pathlib.Path("/tmp/file.txt").touch(exist_ok=True)
    

    If the file already exists, the function succeeds if exist_ok is true (and its modification time is updated to the current time), otherwise FileExistsError is raised.

    If the parent directory doesn't exist you need to create it first.

    global_conf_path = xdg_home / "autoimport" / "config.toml"
    global_conf_path.parent.mkdir(parents=True)
    global_conf_path.touch(exist_ok=True)
    
  • New: Pad a string with spaces.

    >>> name = 'John'
    >>> name.ljust(15)
    'John           '
    
  • New: Get hostname of the machine.

    Any of the next three options:

    import os
    
    os.uname()[1]
    
    import platform
    
    platform.node()
    
    import socket
    
    socket.gethostname()
    

pythonping

  • New: Introduce pythonping.

    pythonping is simple way to ping in Python. With it, you can send ICMP Probes to remote devices like you would do from the terminal.

    Warning: Since using pythonping requires root permissions or granting cap_net_raw capability to the python interpreter, try to measure the latency to a server by other means such as using requests.

Selenium

  • New: Disable loading of images.

    You can pass options to the initialization of the chromedriver to tweak how does the browser behave. To get a list of the actual prefs you can go to chrome://prefs-internals, there you can get the code you need to tweak.

    options = ChromeOptions()
    options.add_experimental_option(
        "prefs",
        {
            "profile.default_content_setting_values.images": 2,
        },
    )
    

Typer

  • New: Create a --version command.

    You could use a callback to implement a --version CLI option.

    It would show the version of your CLI program and then it would terminate it. Even before any other CLI parameter is processed.

    from typing import Optional
    
    import typer
    
    __version__ = "0.1.0"
    
    def version_callback(value: bool) -> None:
        """Print the version of the program."""
        if value:
            print(f"Awesome CLI Version: {__version__}")
            raise typer.Exit()
    
    def main(
        version: Optional[bool] = typer.Option(
            None, "--version", callback=version_callback, is_eager=True
        ),
    ) -> None:
        ...
    
    if __name__ == "__main__":
        typer.run(main)
    
  • New: Testing.

    Testing is similar to click testing, but you import the CliRunner directly from typer:

    from typer.testing import CliRunner
    
  • New: Introduce sponsorship analysis.

    It may arrive the moment in your life where someone wants to sponsor you. There are many sponsoring platforms you can use, each has their advantages and disadvantages.

    • Liberapay.
    • Ko-fi.
    • Buy me a coffee.
    • Github Sponsor.
    [Liberapay][3] [Ko-fi][4] [Buy Me a Coffee][6] [Github Sponsor][7]
    Non-profit [Yes][1] No No No! (Microsoft!)
    Monthly fee No No No No
    Donation Commission 0% 0% 5% Not clear
    Paid plan No [Yes][5] No No
    Payment Processors Stripe, Paypal Stripe, Paypal Stripe, Standard Payout Stripe
    One time donations [Possible but not user friendly][2] Yes Yes Yes
    Membership Yes Yes Yes Yes
    Shop/Sales No Yes No No
    Based in France ? United States United States?
    + Pay delay Instant Instant Instant
    User friendliness OK Good Good Good

    Liberapay is the only non-profit recurrent donations platform. It's been the most recommended platform from the people I know from the open-source, activist environment.

    Ko-fi would be my next choice, as they don't do commissions on the donations and they support more features (that I don't need right now) than Liberapay.

DevOps

  • New: Introduce Ombi.

    Ombi is a self-hosted web application that automatically gives your shared Jellyfin users the ability to request content by themselves! Ombi can be linked to multiple TV Show and Movie DVR tools to create a seamless end-to-end experience for your users.

    If Ombi is not for you, you may try Overseerr.

Infrastructure Solutions

AWS Savings plan

  • New: Introduce AWS Savings plan.

    Saving plans offer a flexible pricing model that provides savings on AWS usage. You can save up to 72 percent on your AWS compute workloads.

    !!! note "Please don't make Jeff Bezos even richer, try to pay as less money to AWS as you can."

Continuous Integration

  • New: Introduce MDFormat.

    MDFormat is an opinionated Markdown formatter that can be used to enforce a consistent style in Markdown files. Mdformat is a Unix-style command-line tool as well as a Python library.

    The features/opinions of the formatter include:

    • Consistent indentation and whitespace across the board
    • Always use ATX style headings
    • Move all link references to the bottom of the document (sorted by label)
    • Reformat indented code blocks as fenced code blocks
    • Use 1. as the ordered list marker if possible, also for noninitial list items.

    It's based on the markdown-it-py Markdown parser, which is a Python implementation of markdown-it.

  • New: Issues.

Hardware

CPU

  • Correction: Add GPU advice on shopping tips.

    • Check that the CPU has GPU if you don't want to use an external graphic card. Otherwise the BIOS won't start.

Pedal PC

  • New: Introduce Pedal PC.

    The Pedal PC idea gathers crazy projects that try to use the energy of your pedaling while you are working on your PC. The most interesting is PedalPC, but still crazy.

    Pedal-Power is another similar project, although it looks unmaintained.

Operating Systems

Linux

Linux Snippets

  • New: Df and du showing different results.

    Sometimes on a linux machine you will notice that both df command (display free disk space) and du command (display disk usage statistics) report different output. Usually, df will output a bigger disk usage than du.

    The du command estimates file space usage, and the df command shows file system disk space usage.

    There are many reasons why this could be happening:

  • New: Clean up docker data.

    To remove unused docker data you can run docker system prune -a. This will remove:

    • All stopped containers
    • All networks not used by at least one container
    • All images without at least one container associated to them
    • All build cache

    Sometimes that's not enough, and your /var/lib/docker directory still weights more than it should. In those cases:

    • Stop the docker service.
    • Remove or move the data to another directory
    • Start the docker service.

    In order not to loose your persisted data, you need to configure your dockers to mount the data from a directory that's not within /var/lib/docker.

aleph

  • New: Introduce Aleph.

    Aleph is a tool for indexing large amounts of both documents (PDF, Word, HTML) and structured (CSV, XLS, SQL) data for easy browsing and search. It is built with investigative reporting as a primary use case. Aleph allows cross-referencing mentions of well-known entities (such as people and companies) against watchlists, e.g. from prior research or public datasets.

  • New: Problems accessing redis locally.

    If you're with the VPN connected, turn it off.

  • New: PDB behaves weird.

    Sometimes you have two traces at the same time, so each time you run a PDB command it jumps from pdb trace. Quite confusing. Try to c the one you don't want so that you're left with the one you want. Or put the pdb trace in a conditional that only matches one of both threads.

elasticsearch

  • New: Searching documents.

    We use HTTP requests to talk to ElasticSearch. A HTTP request is made up of several components such as the URL to make the request to, HTTP verbs (GET, POST etc) and headers. In order to succinctly and consistently describe HTTP requests the ElasticSearch documentation uses cURL command line syntax. This is also the standard practice to describe requests made to ElasticSearch within the user community.

    An example HTTP request using CURL syntax looks like this:

    curl -XPOST "https://localhost:9200/_search" -d' { "query": { "match_all": {} }
    }'
    
  • New: Get documents that match a string.

    curl \
        -H 'Content-Type: application/json' \
        -XPOST "https://localhost:9200/_search" \
        -d' { "query": { "query_string": {"query": "test company"} }}'
    

ferdium

  • New: Introduce ferdium.

    Ferdium is a desktop application to have all your services in one place. It's similar to Rambox, Franz or Ferdi only that it's maintained by the community and respects your privacy.

finnix

  • New: Introduce finnix.

    Finnix is a live Linux distribution specialized in the recovery, maintenance, testing of systems.

VSCodium

  • New: Introduce VSCodium.

    VSCodium are binary releases of VS Code without MS branding/telemetry/licensing.

Android

Android Tips

  • New: Extend the life of your battery.

    Research has shown that keeping your battery charged between 0% and 80% can make your battery's lifespan last 2x longer than when you use a full battery cycle from 0-100%.

    As a non root user you can install Accubattery (not in F-droid :( ) to get an alarm when the battery reaches 80% so that you can manually unplug it. Instead of leaving the mobile charge in the night and stay connected at 100% a lot of hours until you unplug, charge it throughout the day.

GrapheneOS

  • New: Introduce GrapheneOS.

    GrapheneOS is a private and secure mobile operating system with Android app compatibility. Developed as a non-profit open source project.

  • New: Introduce GrapheneOS.

    GrapheneOS is a private and secure mobile operating system with great functionality and usability. It starts from the strong baseline of the Android Open Source Project (AOSP) and takes great care to avoid increasing attack surface or hurting the strong security model. GrapheneOS makes substantial improvements to both privacy and security through many carefully designed features built to function against real adversaries. The project cares a lot about usability and app compatibility so those are taken into account for all of our features.

Arts

Maker

Redox

  • New: Introduce Redox.

    Redox is an awesome Do It Yourself mechanical keyboard

  • New: Installation instructions.

    First flash:

    Download the hex from the via website

    Try to flash it many times reseting the promicros.

    sudo avrdude -b 57600 -p m32u4 -P /dev/ttyACM0 -c avr109 -D -U flash:w:redox_rev1_base_via.hex
    

    Once the write has finished install via:

    https://github.com/the-via/releases/releases

    Reboot the computer

    Launch it with via-nativia.

Other