Regenerating Shotwell thumbnails

When reinstalling, upgrading or moving settings, thumbnails may be missing in Shotwell. The problem can look like this:

shotwell_missing_thumbs

Each time you import photos, Shotwell will generate thumbnails in two different sizes. If you loose them, you have the problem that they are regenerated on-demand, everytime you scroll by an image. That stinks.

Requirements

You need to do apt-get install sqlite3 imagemagick to fetch requirements.

Source

Here’s a script that will regenerate everything, and it’s tested on Shotwell 0.18.0. View / fork Gist souce.

#!/bin/bash
# Based on http://gagor.pl/2014/01/regenerate-thumbnails-in-shotwell-for-last-month/
THUMB_ROOT=~/.cache/shotwell/thumbs
# Remove " > date('now','start of month','-1 month')" if you want to re-generate everything
sqlite3 ~/.local/share/shotwell/data/photo.db \
  "select id||' '||filename from PhotoTable where date(timestamp,'unixepoch','localtime') > date('now','start of month','-1 month') order by timestamp desc" |
while read id filename; do
  tf1=$(printf $THUMB_ROOT/thumbs128/thumb%016x.jpg $id);
  tf2=$(printf $THUMB_ROOT/thumbs360/thumb%016x.jpg $id);
  if [ -e "$tf1" ]
  then
    echo "Skipping $filename"
  else
    echo -n "Generating thumb for $filename";
    #echo $tf1
    convert "$filename" -quality 60 -auto-orient -thumbnail 128x128 $tf1
    convert "$filename" -quality 60 -auto-orient -thumbnail 360x360 $tf2
    echo
  fi
done

Nokia 301 on Wammu / Gammu

I had an older Nokia and got a new one which I needed to upload my phone book to. In order to connect to Nokia 301 from Gammu, plug the phone in with a USB cable and select the “Modem” option on the phone. The others won’t work.

Wammu is a GTK frontend to Gammu. You can use for various tasks, but I found that restoring my backup through Wammu failed (even though the file was created with Wammu), while using the commandline tool Gammu directly worked.

Firstly, use the command “gammu-detect” and find the line that reads something with “Nokia”, most likely the first line. It will contain something like:

[gammu]
device = /dev/ttyACM3
name = Nokia Nokia_301_Dual_SIM
connection = at

Put this info in your file ~/.gammurc. You then use this command to backup a file created from either Wammu or Gammu:

gammu -s 0 restore ~/Desktop/nokia.backup

The 0 denotes that we are using the 0th section of the configuration file, so if you don’t have any other configurations, simply leave the 0.

Ubuntu 14.04 Trusty with DNS server and NetworkManager (disabling dnsmasq)

I’ve badly been looking for a way to both run an internal network server on eth0 and connecting to any kind of internet device, be it on wlan0 or a USB dongle.

That way, I can be online and browsing documentation, downloading new stuff etc. on the server but not depend on a static configuration but still use Network Manager for its intended purpose.

In /etc/NetworkManager/NetworkManager.conf, uncomment the dnsmasq option like so, because Network Manager’s dnsmasq blocks listening to these ports if you want to run your own DNS server:

# dns=dnsmasq

But that’s not all! We need /etc/resolv.conf to be updated with the external DNS providers that Network Manager discovers. This can be achieved by removing resolvconf which automatically alters /etc/resolv.conf.

apt-get remove resolvconf

There, done! Now add static configurations in /etc/networks/interfaces.d/ or /etc/networks/interfaces and let Network Manager handle your WLAN interfaces.

Ubuntu, Kickstart, preseeding, and Wireless (WLAN)

I have been trying to get an automated network install running. The starting point is a Kickstart (Kickseed) setup that works fine on LAN. Problem is: Computers do not do PXE netbooting from WLAN, and secondly that the debian installer was not configuring the network correctly. But the steps are very simple.

  1. Get mini.iso, basically the same kernel and initrd that the netbooter is running
  2. Put it on a usb drive to boot the computer (laptop) from: sudo dd if=/path/to/mini.iso of=/dev/[usb device] bs=4096
  3. Make sure that your wireless access point is not protected, just make an open one, we call it UBUNTU-INSTALL
  4. Test that you can connect to it and that the repository is working
  5. Now, boot from the USB drive and press TAB to add boot options: ks=http://1.2.3.4/ks.cfg ksdevice=wlan0 netcfg/wireless_essid=UBUNTU-INSTALL
  6. In order to add your changes to mini.iso, you need to unpack the whole filesystem and edit txt.cfg which is a file that syslinux is using to display the menu.

Changing mini.iso

Tools like UCK do not work for the mini.iso file because it’s not using stuff like Casper. So you need to create a custom boot image the hard way:

$ mkdir iso
$ sudo mount -o loop -t iso9660 mini.iso iso
$ cp -R iso custom
$ sudo chmod 600 custom/txt.cfg
$ sudo nano custom/txt.cfg
$ sudo mkisofs -r -V "Custom Ubuntu Netboot image" -cache-inodes -J -l -b isolinux.bin -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -o custom.iso custom-iso
$ sudo umount /media/USB-DRIVE # Remember to unmount before writing the usb
$ sudo dd if=custom.iso of=/dev/[YOU USB DRIVE] bs=4096

Limiting choices in a ModelAdmin list_filter

So, you need to limit choices, because the list of related choices is too long? Then do NOT use limit_choices_to parameter on the ForeignKey! Why? Because you risk having options missing in your forms, deleting relations unknowingly.

For instance, consider that you have the following case, expressed in pseudo code:

ModelClass.related_instance = models.ForeignKey(MyRelatedModel, limit_choices_to = {'active': True}, blank=True, null=True)
object = <ModelClass instance>
object.related_instance = <MyRelatedModel instance>
object.related_instance.active = False

If you edit object, you will see an admin form where <MyRelatedModel instance> is not selectable! Hence, you will risk editing and loosing data without knowing it.

So your best bet is to stop using limit_choices_to and instead define a filter. Luckily, it’s quite easy. It’s not beautiful, though, since admin.filters.RelatedFieldListFilter does not offer a method to overwrite.

Here is an example:

class RelatedFilter(admin.filters.RelatedFieldListFilter):
    def __init__(self, *args, **kwargs):
        super(RelatedFilter, self).__init__(*args, **kwargs)
        self.lookup_choices = [
            (x.id, x) for x in
                models.RelatedModel.objects.filter(status='active')
        ]
 
class MyModelAdmin(admin.ModelAdmin):
 
    list_filter = (('related_field', RelatedFilter), 'other_related_field')