Pat David Avatar
ABOUT ARCHIVE
Theme

Good Design

With deference to Dieter Rams (and courtesy of Vitsoe), his 10 principles for good design. This list is worth revisiting every now and then.

Good design is innovative

The possibilities for innovation are not, by any means, exhausted. Technological development is always offering new opportunities for innovative design. But innovative design always develops in tandem with innovative technology, and can never be an end in itself.

Good design makes a product useful

A product is bought to be used. It has to satisfy not only functional, but also psychological and aesthetic criteria. Good design emphasizes the usefulness of a product whilst disregarding anything that could detract from it.

Good design is aesthetic

The aesthetic quality of a product is integral to its usefulness because products we use every day affect our person and our well-being. But only well-executed objects can be beautiful.

Good design makes a product understandable

It clarifies the product’s structure. Better still, it can make the product talk. At best, it is self-explanatory.

Good design is unobtrusive

Products fulfilling a purpose are like tools. They are neither decorative objects nor works of art. Their design should therefore be both neutral and restrained, to leave room for the user’s self-expression.

Good design is honest

It does not make a product more innovative, powerful or valuable than it really is. It does not attempt to manipulate the consumer with promises that cannot be kept.

Good design is long-lasting

It avoids being fashionable and therefore never appears antiquated. Unlike fashionable design, it lasts many years – even in today’s throwaway society.

Good design is thorough down to the last detail

Nothing must be arbitrary or left to chance. Care and accuracy in the design process show respect towards the user.

Good design is environmentally-friendly

Design makes an important contribution to the preservation of the environment. It conserves resources and minimizes physical and visual pollution throughout the lifecycle of the product.

Good design is as little design as possible

Less, but better – because it concentrates on the essential aspects, and the products are not burdened with non-essentials.

Back to purity, back to simplicity.


These principles are available licensed under CC-BY-NC-ND 4.0 from Vitsoe.


Filed under: design

Ubuntu SSH Ads (motd)

Much to the chagrin of my friend darix, I run an Ubuntu server at home for various things like Nextcloud and Plex. (Chagrin because it’s not openSUSE… yet.) I had installed the previous Long Term Support (LTS) version, 16.04 because I just need the thing to run and be solid. The time had come for a new LTS release and I figured I might as well sit down and get upgraded to 18.04.

Mostly you hear from people when things go wrong, and this time I thought it’d be nice to say something from a positive view. I upgraded over SSH and everything went super smoothly. Awesome! There was one small hiccup with SSH not being enabled when I rebooted the first time but it was quickly sorted out.

The funnier part was some weird news updates being shown in my Message of the Day (motd) when I logged into the machine. I think I’ve seen a few people calling them “ads”, but really what happens is the motd scripts pull news from a URL to show you. Here’s what mine looked like:

Welcome to Ubuntu 18.04.1 LTS (GNU/Linux 4.15.0-32-generic x86_64)

Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2       913G  745G  122G  86% /

 * Read about Ubuntu updates for L1 Terminal Fault Vulnerabilities
   (L1TF).

   - https://ubu.one/L1TF

 * Check out 6 great IDEs now available on Ubuntu. There may even be
   something worthwhile there for those crazy EMACS fans ;)

   - https://bit.ly/6-cool-IDEs

 * Canonical Livepatch is available for installation.
   - Reduce system reboots and improve kernel security. Activate at:
     https://ubuntu.com/livepatch

0 packages can be updated.
0 updates are security updates.

The issue some folks have is with the first couple of bullet points (and a bit.ly link? Really?).

Taking a look in /etc/update-motd.d/50-motd-news and right at the top of the file Dustin was kind enough to tell us he insisted on transparency for this:

##############################################################################
# This program could be rewritten in C or Golang for faster performance.
# Or it could be rewritten in Python or another higher level language
# for more modularity.
# However, I've insisted on shell here for transparency!
#                                                                     - Dustin
##############################################################################

Remove the News

Also at the top of that file is the clue on fixing this for your installation. The key is to modify the file /etc/default/motd-news and change ENABLED=1 to ENABLED=0:

# Enable/disable the dynamic MOTD news service
# This is a useful way to provide dynamic, informative
# information pertinent to the users and administrators
# of the local system
ENABLED=0

Et voilà!


Filed under: ubuntu, linux, ssh

Goodbye Google Analytics

I was outlining some ideas for an article I want to write concerning online privacy and connections to the recent Facebook fiasco. Part of the outline had me talking about the “middleman” layer that many big services like Facebook and Google created through their free offerings like ads, webfonts, comments, and social sharing options. I started mentioning this in a post from last year. I won’t go into that detail here (yet), but something that really struck home for me was the use of Google Analytics.

For those not in the know, Google Analytics is a way to track users on a website for reporting and insights. We used to do this manually by analyzing the logs from the webserver. Then Google made it trivially easy to get great looking reports of the data automatically by simply including a small piece of JavaScript in our pages. It can even show this data in real time. Which is, as my friend Alex Prokoudine points out: “just jerking off” (*at least for small projects like this blog).

Dashboard view Dashboard view users

What this really boils down to is (and I’ll cover this in more depth in the article I alluded to): I’ve given Google direct access to all of my users and their browsing habits on my site.

Faust und Mephisto, Stich von Tony Johannot
Ok Faust, simply add this tiny snippet of JavaScript and you’ll get all of these wonderful analytics! Easy-peasy!

It’s insidious because it’s dead-simple to set up, and it gives you a nice little jolt of satisfaction watching your traffic flowing in (trickling, in my case). Mesmerizing. Cunning. Dirty.

This is not exactly news to many, but I figured it might be for a few people. If it helps raise awareness in even one person of what’s really going on then I’d say this post has done its job. I’d rather not give Google a hand tracking users across the entire web.

I’m done with Google Analytics.

So long, and thanks for all the fish.

Matomo website

There is a Free Software option for user analytics that we use over on PIXLS.US called Matomo (previously, Piwik) that I will continue to use here. This means that I control all of the data and don’t allow any middleman to see what you’re up to (well, me and one of the pixls sysadmins, andabata, who runs the service for us). I will also start manually analyzing my server logs offline when I need more accurate statistics to look at.

Stay tuned for something a little more in-depth where I ramble on more about tracking and the sneaky middle layer of snooping that these services have built up in the name of convenience and apathy.


Filed under: Google, privacy

Switching Themes

I got the bug recently to finally do something that’s been annoying me for some time: set up a dark theme for this website that is user selectable and that will persist.

Normally I prefer the white background (default) that I originally designed but I understand that some prefer a dark background. When it’s in the evening and I want to write/edit a new post (like I’m doing right now) so do I. When it’s daytime, though, I prefer to be back on the white background.

The Dark (Style)

Creating a dark version of the site is relatively easy. I originally styled things sparingly here to keep it light and simple.

The Dark by Lemony Snicket - I love reading this book to my kids (you should hear me do the voice for the dark).

With plenty of thanks to past-Pat for being proactive there aren’t many rules to change to make a dark theme work. Here they are:

body, hr:after {
    background-color: #222;
    color: #ccc;
}

h1, h2, h3, h4, h5 {
    color: #eee;
}

code, pre {
    background-color: #111;
}

That’s pretty much it. I set the body background-color and color to dark versions (the hr:after is for the new horizontal rules I added a few days ago).

The headings are slightly brighter than the body text (just like how they’re slightly darker in the light theme) and the code blocks use a darker background. The link text colors were tweaked from looking at the Solarized color scheme by Ethan Schoonover so they were already on the path to being used in either light or dark versions and didn’t need modification.

I went with a more neutral dark gray background vs. the slightly blue-tinted Solarized background because I didn’t want the background to clash with any photos I share.

Applying the Styles

The application of these styles was pretty straightforward. I had all of the main styles for the site load first (in the document <head>), where I set the dark theme as part of my default styles. Immediately after these default styles, I added a new <style> element that actually set the colors to the light theme version.

I did it this way because later I will talk about the JavaScript I use to switch the styles as well as add persistence for whatever a visitor chooses. This way if a user has JavaScript disabled they will get the light theme by default.

The pseudo code for my styles now looks like this:

<head>
<style>
    ... default styles for everything
    {dark theme rules}
</style>

<style id='lightcss'>
    {light theme rules}
</style>

This will make sense a little later.

Inverting Colors

As an aside, while looking around at others works to see if I was missing something, I came across an awesome method for creating a dark version of a website. It’s in the blog post A Theme Switcher over on the Inclusive Components site and it’s an elegant use of the invert filter.

The post is well worth a read, but the general gist is to use the invert filter to invert all of the colors on a site. They explicitly give a background color to the :root html element, and then trickle it down to all other elements on the page through the * selector (so you don’t end up with white text on a white background). A little selector magic to avoid images and videos and you have a very tersely implemented theme inversion!

Here is the final CSS they used:

:root { 
   background-color: #fefefe;
   filter: invert(100%);
}

* { 
   background-color: inherit;
}

img:not([src*=".svg"]), video {  
   filter: invert(100%);
}

Wonderful! I almost went this route as well, but my colors are not quite set to be how I’d like them as straight inversions. I will keep this in my bag of tricks for later though!

Theme Switching

I now needed a way to allow visitors to use this new theme. A small bit of JavaScript at the end of my pages takes care of enabling/disabling the default light theme colors:

    document.getElementById('theme').addEventListener("click", function() {
        light = document.getElementById('lightcss');
        if( light.disabled == true ){
            light.disabled = false;
            localStorage.removeItem("theme");
        }else{
            light.disabled = true;
            localStorage.setItem("theme", "dark");
        }
    });

I attach an event listener to a link on the page (see the “Theme” button in my header). Targeting the lightcss style element, we can toggle it through the disabled attribute. This might seem odd if you’ve done this before.

Normally you’d probably consider setting the dark/light rules and applying them to a class. Then you’d toggle them by adding/removing the classes. While this works great, it tends to be slightly problematic when used for applying stored user preferences…

The Persistence of Memory

You’ll notice in the previous JavaScript snippet the lines that set/remove a localStorage parameter theme. This allows me to remember what theme the user wants.

Persistence of Memory by Salvador Dali.

Another small piece of JavaScript in the <head> allows me to check for the setting:

if( localStorage.getItem('theme') == 'dark' ){
    document.getElementById("lightcss").disabled = true;
}

This could be done with cookies as well but many folks might have them turned off for security reasons.

This helps get around the problem of using a class to switch styles. If the setting is for the dark theme, it needs to be applied before the page has a chance to load (and show a flash of the white theme). Using the disabled attribute we can set (well, unset) these styles before the page has a chance to render.

Give It a Try

Whew! That was a mouthful. Well, go ahead and give it a try if you’d like! In my header under my name and main site links you should now find a “THEME” link that will swap things around for you. Let me know if anything seems wonky.


Filed under: HTML, CSS, theme

Installing Adobe Digital Editions on Linux with WINE

This post is a little more esoteric, but in the spirit of helping others from the future we’re gonna dive into this.

Wisdom of the Ancients
I’ll stop posting relevant xkcd comics when Randall stops making relevant xkcd comics…

I picked up an Amazon Kindle Paperwhite over a year ago, and I have been tearing through books at an alarming rate. In the course of finding more books to read I did what I’ve always done for as long as I can remember: visit my local library.

Side note: Please, please, please support your local libraries. It’s like supporting net-neutrality in meatspace!

I immediately ran into a bit of a disconnect between my rapidly advancing digital life and the reality of digital books.

The problem lies in how we can borrow and checkout digital books. Currently, there are mainly two big systems in place for digital library lending, Bibliotheca’s CloudLibrary and Rakuten Overdrive. As is often the case in modern computing, anything not Apple or Microsoft is relegated to the rubbish bin. As a Linux user, this is not ideal for me.

Neither of these software solutions have a Linux option.

Wine Is Not an Emulator

Luckily for Linux users, there’s the project to run Windows applications on various POSIX-compliant operating systems: Wine.

I won’t go into using CloudLibrary, as it’s not the focus of this post. It actually installs just fine all on it’s own in Wine so it’s a non-issue.

Overdrive is the real problem here. Rather, it’s use of Adobe Digital Editions (ADE) as the means for checking out books. (The actual interface for Overdrive at the library is a website.) For other purposes that I won’t go into here right now, I need to be able to use an older version of ADE. Specifically ADE 2.0.1.

I spent some time researching if the application would work over at the App Database for Wine. The instructions there didn’t really work for me, but there were some other posts in places like the MobileRead wiki where I was able to gain some more insights as well. Overall it took a good few hours of searching and playing to finally arrive at a working installation of ADE 2.0.1 with Wine on Linux.

If you’re still reading this far I can only assume that you need to get this installed as well. Let’s do it!

Installing

I have successfully installed ADE 2.0.1 on a fresh installation of Ubuntu 18.04. You’ll need to be comfortable in your shell to do this, no graphical installer for these steps (sorry).

To start, you’ll need a couple of downloads for later:

I just downloaded these directly into my home directory for easy reference later.

You’ll also need to install Wine. I just went ahead and used the package from my distro: wine-3.0 (Ubuntu 3.0-1ubuntu1). You’ll also want a helper script for setting things up automatically in Wine called winetricks, and I also needed cabextract to be able to extract files from a Windows .cab file.

In my case I just did:

$ sudo apt install wine-stable winetricks cabextract

Wine installs everything into it’s own directories that you tell it to (referred to as a prefix). You can easily tell it which prefix to use by setting this in your shell before you run a command. In my examples below I will be installing ADE into it’s own prefix in my home directory called ~/.adewine.

  1. Set up a new 32-bit prefix with Wine.
    You need to setup a fresh install into it’s own prefix, and tell Wine to make it a 32-bit environment:

     $ WINEPREFIX=~/.adewine WINEARCH=win32 winecfg  
    

    You can also tell Wine to use this prefix for all subsequent commands:

     $ export WINEPREFIX=~/.adewine
    
  2. Now you need to install corefonts and windowscodecs:

     $ winetricks -q corefonts && winetricks -q windowscodecs
    

    At this point, I originally found some errors where Wine wasn’t picking up the windowscodecs.dll being installed. I was seeing a bunch of errors like:

    000d:err:module:import_dll Library windowscodecs.dll (which is needed by L"C:\\windows\\system32\\winemenubuilder.exe") not found
    

    I found that I could fix this by manually copying them to the correct location:

    1. Extract all the files from ~/.cache/winetricks/windowscodecs/wic_x86_enu.exe
       $ cd ~/.cache/winetricks/windowscodecs/
       $ cabextract -d tmp wic_x86_enu.exe
      
    2. Copy windowscodecs.dll and windowscodecsext.dll into ~/.adewine/drive_c/windows/system32/:
      $ cd tmp/
      $ cp windowscodecs* ~/.adewine/drive_c/windows/system32/
      $ cd ~/
      
  3. Install the Full .NET 3.5SP1 installer you downloaded previously:

     $ wine dotnetfx35.exe
    
  4. Finally, you can install Adobe Digital Editions 2.0.1 normally:

     $ wine ADE_2.0_Installer.exe
    

Et voilà!

That’s it! If there were no errors you should now be able to run Adobe Digital Editions 2.0.1:

$ WINEPREFIX=~/.adewine wine .adewine/drive_c/Program\ Files/Adobe/Adobe\ Digital\ Editions\ 2.0/DigitalEditions.exe
Adobe Digital Editions 2.0.1 in Wine

Filed under: Linux, Wine, ebooks

If—

If you can keep your head when all about you
 Are losing theirs and blaming it on you,
If you can trust yourself when all men doubt you,
 But make allowance for their doubting too;
If you can wait and not be tired by waiting,
 Or being lied about, don’t deal in lies,
Or being hated, don’t give way to hating,
 And yet don’t look too good, nor talk too wise:

If you can dream—and not make dreams your master;
 If you can think—and not make thoughts your aim;
If you can meet with Triumph and Disaster
 And treat those two impostors just the same;
If you can bear to hear the truth you’ve spoken
 Twisted by knaves to make a trap for fools,
Or watch the things you gave your life to, broken,
 And stoop and build ’em up with worn-out tools:

If you can make one heap of all your winning
 And risk it on one turn of pitch-and-toss
And lose, and start again at your beginning
 And never breathe a word about your loss
If you can force your heart and nerve and sine
 To serve your turn long after they are gone,
And so hold on when there is nothing in yo
 Except the Will which says to them: ‘Hold on!’

If you can talk with crowds and keep your virtue,
 Or walk with Kings—nor lose the common touch
If neither foes nor loving friends can hurt you
 If all men count with you, but none too much
If you can fill the unforgiving minut
 With sixty seconds’ worth of distance run,
Yours is the Earth and everything that’s in it,
 And—which is more—you’ll be a Man, my son!


Rudyard Kipling
Rewards and Fairies, 1910


Filed under: Kipling, poem

Password Management

The virtue of being forgetful

I suck at passwords. To be fair, so does everyone else. Everyone else being bad at passwords doesn’t help me, though. It only increases my awareness every time I hear about the latest data-breach, password leak, or programming error.

The thing is, I know what I should be doing, but the one-two punch of laziness and procrastination constantly seem to beat me into submission.

xkcd: Password Strength
Relevant xkcd. Yes, I know it’s old. Yes, it’s still perfectly valid: math is math.

I know I should be:

The problem is that doing those things is hard. I rely on muscle-memory helping me with passwords that I have to use multiple times every day. I have trouble remembering my anniversary date, much less the complex password for a website I log into once per quarter (October 25th in case my wife is reading). I can measure some of my password ages in years.

Password Reuse
An even scarier relevant xkcd

Sure, I can abuse the “Forgot Password?” button on any of the myriad of sites I might visit and forget about, but that wreaks havoc when I have accounts tied to apps. Particularly mobile/phone apps.

Luckily, there is a solution.

Password Managers

I avoided using a password manager for a long time. I’m not really sure why. Partially out of paranoia and FUD, and probably a bit of worry in giving up control over so many logins. The trick was to realize that I’d be able to replace all of my usernames+passwords with a single master password.

I had a couple of convenience factors that I needed to be available before I could make the switch, though:

There are several well-regarded options for password managers out there, including popular ones like LastPass and 1Password but they’re not Free Software.

KeePassXC

KeePassXC Logo

After a big of digging I finally heard enough good comments about KeePassXC that I figured it was worth a shot. After about two months of using it, my main thought is: why on earth did I wait so long to do this?

The project is Free Software (GPL) and was forked from KeePassX due to stalled response from its single maintainer.

It keeps your passwords in a local encrypted file (AES, Twofish, ChaCha20). They’ve got clients for all the major OS and there’s an iOS app (MiniKeePass (iTunes), also GPL). There’s also a browser extension that communicates with the client allowing access to passwords right in the browser, securely. If the URL is listed with my database entry, it prompts to fill in the username/password for me when I visit the site.

It’s now trivially easy for me to make all of my passwords quite complex (or at least with a nice high entropy of at least 90bits or more). If I’m really concerned about possibly having to manually enter the password somewhere else, I can make arbitrarily long and random passphrases as well (i.e., cold riverbank outcome shrubbery display stoplight upfront).

What’s great is that thanks to my new Nextcloud server, I keep the password file there to sync with all of my machines (even my iPhone). It’s also wild to see just how many logins/passwords you accumulate in your digital life (I’m up to about 65 unique entries at the moment - and most of those would have been variations or the same password not too long ago!).

KeePassXC Browser Integration

The most important part of making this a frictionless adoption is having integration with your browser. Luckily the KeePassXC team have created browser extensions for both Chrome and Firefox to make it trivially easy to use. With the extension installed you can just visit a site and if you have an entry for it in KeePassXC it will prompt you to automatically fill in the username and password.

There’s a Chrome extension as well as a Firefox extension available. They both allow for encrypted message passing between the browser and the KeyPassXC application. This is similar to having the browser remember passwords for you but with the benefit of being cross-browser compatible if you need that sort of thing as well as allowing you to store arbitrary passwords for things not related to a web login.

The extension also offers to add usernames/passwords for you if it’s for a site that is not currently in the database, which is a nice touch.

Easy on the Brain

Ultimately what this means is that my cognizant load can be reduced by quite a bit. I only need to remember one good passphrase/password. In the case of my phone, I can even let biometrics manage that for me. All while my actual passwords can be much more complex and safer.

If you want to take a huge burden off your digital life while making your world more secure at the same time, I’d highly recommend checking out a password manager (seriously, KeePassXC has been great but go with whatever you’re comfortable with).

Addendum

It was pointed out to me after publishing this by @older@mastodon.host on Mastodon that KeePassXC is one of the tools that the EFF recommends for Surveillance Self Defense (this entire site is well worth a read).


Filed under: KeePassXC, password

Nextcloud

I finally got around to setting up my own Nextcloud!

I’ve been a file-syncing service user for a long time. There’s just so much convenience in services like Dropbox and Google Drive. File syncing and access across all of my computers and devices is awesome. The ability to automatically backup all of my phone photos to the account is also awesome.

However… Only having 7GB of available space is not awesome. Relying on a third party to control and protect my data is not awesome. Between space and privacy, I certainly didn’t want to take advantage of automatic photo syncing (particularly with all of the associated metadata and geodata for each image). The theory is great, but the implementation leaves a little to be desired, especially if you care about privacy (which I’ve written about previously).

Uses

My normal uses for a file-syncing service are pretty typical, I think. I’m a big fan of being able to continue computing how I want no matter which machine I happen to be on (work, home, laptop, etc…).

I’ll use it as a temporary file sharing location for quick and easy access (for myself between computers as well as for others). This is particularly helpful when collaborating on something or sharing quick mockups or images with friends and family.

I use Calibre to manage my ebook library, so I keep the entire folder structure there. This gives me access to the library from any other computer, particularly handy when I just need to add more books or transfer them to my devices.

I also finally switched to using a password manager, KeePassXC. It keeps your passwords in an encrypted file, and to maximize its usefulness I need access to the password file on all of my devices, so I’ve been keeping the file on my old Dropbox account.

Really, my main two complaints about using an existing service like Dropbox or Google Drive is storage space and privacy. Luckily, rolling my own service using Nextcloud on my own server solves both of those problems while keeping all of the other advantages.

Enter Nextcloud

I already have a server (Ubuntu 16.04) at home I use for Plex. There’s not a huge load on this server usually, so I figured I’d go ahead and add Nextcloud to the mix.

Nextcloud webpage screenshot

This was way simpler than you might think (though less simple than using the snap). I basically followed the excellent guide from Jason Bayton on installing Nextcloud with:

As Jason writes in the beginning of his page, after completing the guide I had:

patdavid.net Nextcloud login

The project has a client for all major operating systems including my phone (iOS), and appears to have feature parity for the most part (or at least the parts I’m most interested in, anyway). Including the all-important phone-photos automatic upload. Selective sync is one of those features that’s a must-have for me (no need to sync all of those phone photos to all of my other clients).

The web interface is quite nice, and pretty snappy once the caches are built (even when trying to view directories of images in a ‘gallery-style’).

There’s a pretty nice app store available for different ways to extend your installation. One of my favorites is the Notes app that provides a nice, distraction-free writing interface that’s markdown aware.

Overall the setup was a breeze (and, dare I say it, fun?). That’s one less intrusion into my digital life, and one more way for me to take back a little control…


Filed under: Nextcloud, storage, sync

Libre Graphics World

Writing is hard. Just look at the post dates for my own blog posts to see what I mean. It takes discipline and hard work to put together any sort of non-trivial writing. If the topic is about a community as diverse and loosely collected as Free Software projects then the effort is exponential. Most Free Software projects don’t have a media/public relations person to interact with.

Libre Graphics World Logo

Today I wanted to talk briefly about both a writer and a PR person: Alexandre Prokoudine and what he’s doing over at Libre Graphics World.

Alex is the main PR person for GIMP and he’s also the guy I turn to when I need or want to publish something for the project. This is just one hat he wears (there’s many others), but those aren’t the reason I’m writing about him today.

LGW header image

Today I’m referring to his work as a journalist. Alex created Libre Graphics World back in 2009 to cover the rather diverse ecosystem of Free Software for creative professionals. The value in reporting at LGW is the time and research spent not only digging out the most interesting bits of news, but also taking the time to interview people in the projects. The reporting is nicely in-depth and explores various aspects of issues beyond simply copying the changelogs (see his recent article on the recent fork of Valentina, Seamly2D as an example of the depth and background provided in his articles or his awesome review of features for the GIMP 2.9.2 release).

I think this type of reporting and community highlights is extremely important to a healthy Free Software ecosystem. Especially one that focuses on projects for creatives and that spans so many genres.

Alex recently stopped running ads on the site and has now switched over to using Patreon to fund his activities. I think this is a great time to head over to his Patreon page and throw a few dollars a month to help him do what he does! Every little bit helps!


Filed under: LGW, writing

darktable

Happy New Year!

Way back in May of 2017 I made my first commit to start a new project for some friends of mine. Seven months later and we were finally able to publicly push the results: a new website for the awesome folks at darktable! (I already published a post about this on the darktable blog.)

darktable logo
Read more...

← Older Posts