-
Loading
Hackernews
\  /       Växlande molnighet
   _ /"".-.     +8(5) °C       
     \_(   ).   ↗ 6 m/s        
     /(___(__)  10 km          
                0.0 mm         
                                                       ┌─────────────┐                                                       
┌──────────────────────────────┬───────────────────────┤  tis 09 dec ├───────────────────────┬──────────────────────────────┐
│            Morgon            │         Eftermiddag   └──────┬──────┘      Kväll            │             Natt             │
├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤
│               Molnigt        │               Molnigt        │      .-.      Lätt duggregn  │      .-.      Lätt regn      │
│      .--.     +7(4) °C       │      .--.     +8(5) °C       │     (   ).    +8(6) °C       │     (   ).    +8(5) °C       │
│   .-(    ).   ↗ 5-9 m/s      │   .-(    ).   ↗ 4-7 m/s      │    (___(__)   ↑ 3-7 m/s      │    (___(__)   ↑ 4-8 m/s      │
│  (___.__)__)  10 km          │  (___.__)__)  10 km          │     ‘ ‘ ‘ ‘   2 km           │     ‘ ‘ ‘ ‘   9 km           │
│               0.0 mm | 0%    │               0.0 mm | 0%    │    ‘ ‘ ‘ ‘    0.6 mm | 100%  │    ‘ ‘ ‘ ‘    0.9 mm | 100%  │
└──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘
                                                       ┌─────────────┐                                                       
┌──────────────────────────────┬───────────────────────┤  ons 10 dec ├───────────────────────┬──────────────────────────────┐
│            Morgon            │         Eftermiddag   └──────┬──────┘      Kväll            │             Natt             │
├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤
│  _`/"".-.     Områden med re…│    \  /       Växlande molni…│    \  /       Växlande molni…│    \  /       Växlande molni…│
│   ,\_(   ).   +9(5) °C       │  _ /"".-.     +9(6) °C       │  _ /"".-.     +8(4) °C       │  _ /"".-.     +8(4) °C       │
│    /(___(__)  ↗ 7-13 m/s     │    \_(   ).   ↗ 6-11 m/s     │    \_(   ).   ↗ 6-11 m/s     │    \_(   ).   ↗ 8-13 m/s     │
│      ‘ ‘ ‘ ‘  10 km          │    /(___(__)  10 km          │    /(___(__)  10 km          │    /(___(__)  10 km          │
│     ‘ ‘ ‘ ‘   0.0 mm | 63%   │               0.0 mm | 0%    │               0.0 mm | 0%    │               0.0 mm | 0%    │
└──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘
                                                       ┌─────────────┐                                                       
┌──────────────────────────────┬───────────────────────┤  tor 11 dec ├───────────────────────┬──────────────────────────────┐
│            Morgon            │         Eftermiddag   └──────┬──────┘      Kväll            │             Natt             │
├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤
│    \  /       Växlande molni…│      .-.      Lätt duggregn  │    \  /       Växlande molni…│               Molnigt        │
│  _ /"".-.     +7(3) °C       │     (   ).    +8(3) °C       │  _ /"".-.     +8(3) °C       │      .--.     +7(3) °C       │
│    \_(   ).   ↗ 9-15 m/s     │    (___(__)   ↗ 8-13 m/s     │    \_(   ).   → 10-16 m/s    │   .-(    ).   → 8-13 m/s     │
│    /(___(__)  10 km          │     ‘ ‘ ‘ ‘   2 km           │    /(___(__)  10 km          │  (___.__)__)  10 km          │
│               0.0 mm | 0%    │    ‘ ‘ ‘ ‘    0.3 mm | 100%  │               0.0 mm | 0%    │               0.0 mm | 0%    │
└──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘
Links
Location Tracker
Hemma - 5 months ago
2025-06-17T20:06:12+02:00
Blog Posts
How to efficiently use entr
1 year ago

https://jvns.ca/blog/2020/06/28/entr/

Hannes Nevalainen
Install gleam from brew
1 year ago
brew install gleam --HEAD 

# upgrade like this

brew upgrade gleam --fetch-HEAD
Hannes Nevalainen
WiFi QR Codes
1 year ago

Make a QR code that till connect to a wifi network.

WIFI:S:<SSID>;T:<WEP|WPA|blank>;P:<PASSWORD>;H:<true|false|blank>;;
Hannes Nevalainen
entr(0)
2 years ago

Entr is a command-line utility that allows users to run arbitrary commands when files change. It adheres to the principle of separation of concerns and offers several advantages over utilities such as find or ls. Entr can recognize files by their contents and skip directories such as .git. The restart option starts the utility as a background process that does not have access to STDIN, allowing keyboard input to be provided using a FIFO. The directory watch option (-d) was added to react to events when a new file is added to a directory. Entr has some architectural limitations, such as not being able to use the -r flag with an interactive task, and closing STDIN to raise an error instead. It also processes files in a specific way, such as monitoring one file at a time using the /_ shortcut. Users can extend and enhance the capabilities of this shortcut by emulating rsync or make.

Entr can be used in various ways, such as:

  • Rebuilding a project if sources change ($ ls | entr make)
  • Running tests if the build was successful ($ ls | entr -s 'make && make test')
  • Starting a server block until any of the listed files change ($ ls *.rb | entr -r ruby main.rb)
  • Restarting services with a timeout ($ ls app | entr -r timeout -k 5 0 ./app)
  • Watching for new files in a directory ($ ls -d src/*.py | entr -d ./setup.py)

Entr has several implementation details, such as:

  • The -r flag cannot be used with an interactive task.
  • Closing STDIN on the child allows entr to accept keyboard input.
  • If entr were to close its own file descriptor to STDIN, there is no reliable and immediate way to determine when the child has terminated in order to restore keyboard input.
  • The / shortcut for entr was intended as a means of saving typing in the case where you are monitoring one file at a time ($ echo schema.sql | entr psql -f/).
  • Entr will detect if something changed in your tree, but another tool should handle building source or copying files.

Tuning options for entr include raising the maximum number of watches on BSD, MacOS, and Linux.

ENTR(1)                     General Commands Manual                    ENTR(1)

NAME
     entr – run arbitrary commands when files change

SYNOPSIS
     entr [-acdnprsz] utility [argument /_ ...]

DESCRIPTION
     A list of files provided on standard input, and the utility is executed
     using the supplied arguments if any of them change.  entr waits for the
     child process to finish before responding to subsequent file system
     events.  A TTY is also opened before entering the watch loop in order to
     support interactive utilities.

     The arguments are as follows:

     -a      Respond to all events which occur while the utility is running.
             Without this option, entr consolidates events in order to avoid
             looping.  This option has no effect in conjunction with the -r
             flag.

     -c      Clear the screen before invoking the utility specified on the
             command line.  Specify twice to erase the scrollback buffer.

     -d      Track the directories of regular files provided as input and exit
             if a new file is added.  This option also enables directories to
             be specified explicitly.  If specified twice, all new entries to
             a directory are recognized, otherwise files with names beginning
             with ‘.’ are ignored.

     -n      Run in non-interactive mode.  In this mode entr does not attempt
             to read from the TTY or change its properties.

     -p      Postpone the first execution of the utility until a file is
             modified.

     -r      Reload a persistent child process.  As with the standard mode of
             operation, a utility which terminates is not executed again until
             a file system or keyboard event is processed.  SIGTERM is used to
             terminate the utility before it is restarted.  A process group is
             created to prevent shell scripts from masking signals.  entr
             waits for the utility to exit to ensure that resources such as
             sockets have been closed.  Control of the TTY is not transferred
             to the child process.

     -s      Evaluate the first argument using the interpreter specified by
             the SHELL environment variable.  If standard output is a TTY, the
             name of the shell and exit code is printed after each invocation.

     -z      Exit after the utility completes.  When combined with -r the
             utility will be restarted again only in response to commands or
             file system events.

     The first argument named /_ is replaced with the absolute path of the
     first file to trigger an event.  The first file under watch is used as
     the default.  If the -s option is used, the name of the first file to
     trigger an event can be read from $0.

COMMANDS
     entr listens for keyboard input and responds to the following commands:

     ⟨space⟩  Execute the utility immediately.  If the -r option is set this
              will terminate and restart the child process as if a file change
              event had occurred.

     q        Quit; equivalent pressing ⟨control-C⟩.

ENVIRONMENT
     PAGER         Set to /bin/cat by default to prevent interactive utilities
                   from waiting for keyboard input if output does not fit on
                   the screen.

     SHELL         Specify the shell to use with the -s flag.  The default is
                   /bin/sh.

     EV_TRACE      Print file system event messages.

EXIT STATUS
     If the -z flag is set and the utility is successfully executed, the
     status of the child process is returned.  If the child process was
     terminated by a signal, the exit status is the signal number plus 128.

     entr normally returns one of the following values:

           0       Normal termination after receiving SIGINT
           1       No regular files were provided as input or an error
                   occurred
           2       A file was added to a directory and the directory watch
                   option was specified

EXAMPLES
     Rebuild a project if source files change, limiting output to the first 20
     lines:

           $ find src/ | entr -s 'make | head -n 20'

     Launch and auto-reload a node.js server:

           $ ls *.js | entr -r node app.js

     Clear the screen and run a query after the SQL script is updated:

           $ echo my.sql | entr -cp psql -f /_

     Rebuild project if a source file is modified or added to the src/
     directory:

           $ while sleep 0.1; do ls src/*.rb | entr -d make; done

     Auto-reload a web server, or terminate if the server exits

           $ ls * | entr -rz ./httpd

macOS 14.4                     November 17, 2023                    macOS 14.4
Hannes Nevalainen
RAM DIsks on OSX
4 years ago
diskutil erasevolume HFS+ "RAMDisk" `hdiutil attach -nomount ram://2048`

Script for creating RAM Disks

#!/bin/bash

# From http://tech.serbinn.net/2010/shell-script-to-create-ramdisk-on-mac-os-x/
#

ARGS=2
E_BADARGS=99

if [ $# -ne $ARGS ] # correct number of arguments to the script;
then
  echo " "
  echo "To create a RAMDISK -> Usage: `basename $0` create SIZE_IN_MB"
  echo "To delete a RAMDISK -> Usage: `basename $0` delete DISK_ID"
  echo " "
  echo "Currently this script only supports one RAMDISK. Will update soon."
  echo "DISK_ID can be shown with 'mount'. usually /dev/disk* where * is a number"
  echo " "
  echo " "
  exit $E_BADARGS
fi

if [ "$1" = "create" ]
then
  echo "Create ramdisk..."
  RAMDISK_SIZE_MB=$2
  RAMDISK_SECTORS=$((2048 * $RAMDISK_SIZE_MB))
  DISK_ID=$(hdiutil attach -nomount ram://$RAMDISK_SECTORS)
  echo "Disk ID is :" $DISK_ID
  diskutil erasevolume HFS+ "ramdisk" ${DISK_ID}
fi

if [ "$1" = "delete" ]
then
  echo "Delete/unmount ramdisk $2"
  umount -f $2
  hdiutil detach $2
fi

https://eshop.macsales.com/blog/46348-how-to-create-and-use-a-ram-disk-with-your-mac-warnings-included/ https://gist.github.com/rxin/5085564

Hannes Nevalainen
How to connect to your printers webcam
4 years ago
http://<ip address of your 3D printer>:8080/?action=stream
Hannes Nevalainen
The only thing you need
5 years ago
defmodule ParamSchema do
  defmodule ValidationHelpers do
    def validate_subset1(changeset, key, values) do
      Ecto.Changeset.get_field(changeset,  key)
      |> case do
        nil -> changeset
        selected_values ->
          Enum.split_with(selected_values, &Enum.member?(values,  &1))
          |> IO.inspect(label: "hello")

          changeset
      end
    end
  end

  defmodule ValidationError do
    defexception message: "Validation error", errors: [], changeset: nil
  end

  defmacro __using__(_opts) do
    quote do
      use Ecto.Schema
      import Ecto.Changeset
      import ParamSchema.ValidationHelpers
      @primary_key false

      def create(params), do: ParamSchema.create(__MODULE__, params)
      def create!(params), do: ParamSchema.create!(__MODULE__, params)

      def changeset(data, params), do: ParamSchema.changeset(__MODULE__, data, params)

      def validate(changeset) do
        changeset
      end

      defoverridable validate: 1
    end
  end

  def create(module, params) do
    changeset(module, struct(module), params)
    |> build_return()
  end

  def create!(module, params) do
    case create(module, params) do
      {:ok, input} -> input
      {:error, error} -> raise %{error | message: "ValidationError: #{inspect(error.errors)}" }
    end
  end

  def changeset(module, data, params) when is_list(params),
    do: changeset(module, data, Map.new(params))

  def changeset(module, data, params) do
    embeds = module.__schema__(:embeds)
    fields = module.__schema__(:fields) -- embeds

    Ecto.Changeset.cast(data, params, fields)
    |> cast_embeds(embeds)
    |> module.validate()
  end

  def build_return(%{valid?: true} = changeset) do
    {:ok, Ecto.Changeset.apply_changes(changeset)}
  end

  def build_return(%{valid?: false} = changeset) do
    {:error, %ValidationError{errors: extract_errors(changeset), changeset: changeset}}
  end

  def extract_errors(%{valid?: false} = changeset) do
    embedded_errors =
      Enum.filter(changeset.types, fn
        {_, {:embed, _embed}} -> true
        _ -> false
      end)
      |> Enum.map(&elem(&1, 0))
      |> Enum.map(fn key ->
        embed_errors =
          Ecto.Changeset.get_change(changeset, key)
          |> extract_errors()

        {key, embed_errors}
      end)
      |> Enum.reject(&match?({_, []}, &1))

    Map.new(changeset.errors ++ embedded_errors)
  end

  def extract_errors(_), do: []

  defp cast_embeds(changeset, []), do: changeset

  defp cast_embeds(changeset, [embed | embeds]) do
    changeset
    |> Ecto.Changeset.cast_embed(embed)
    |> cast_embeds(embeds)
  end
end
Hannes Nevalainen
Bad engineering is not a bug
6 years ago
01:51 UTC
UTC
02:51 CET
Europe/Stockholm
03:51 EET
Europe/Bucharest
20:51 EST
America/New_York
17:51 PST
America/Los_Angeles
09:51 HKT
Asia/Hong_Kong
09:51 PST
Asia/Manila