matrix-send me a notification!

When you are working in the console of an Un*x system you always have the possibility of using some kind of notification system to warn you when a task has completed. Quite typically, that would involve an email that could arrive to your box’ local inbox or, if you have a mail agent properly configure, to some other inbox in the Internet.

With the arriving of the Instant Messaging systems you could somehow move from the good old email notification to some other fancy service. That has been my prefered method for quite a while since I understand email as a “non-instant” messaging system. Basically, I do not want to get instant notifications when a mail arrives. Add to that the hassle of setting some kind of filter criteria to get the notifications only for specific mail rules and the not yet universally supported IMAP4 push method, instead of pulling for newly arrived mail …

Anyway, long story short, for some time now we are using [matrix] as our Instant Messaging service at Igalia so, why not getting notifications there when a task is completed?

Yes, you have guessed correctly, that’s possible and, actually, it’s very easy to set up, specially with the help of matrix-send.

First, you need an account that will send you the notification(s). Ideally, that would be a bot user, but it could be any account. Then, you have get an access token with such user so you can interact with the matrix server from the command line as if it would be any other ordinary matrix client. Finally, you need to create a chat room between that user and your own in order to keep the communication ongoing. All this is explained in matrix’ client-server API documentation but, to make things easier, it would go as follows:

$ curl -XPOST -d '{"user":"", "password":"", "type":"m.login.password"}' "https:///_matrix/client/r0/login"
{
    "access_token": "",
    "device_id": "",
    "home_server": "",
    "user_id": "@:"
}

This will give you the needed access-token.

Now, from your regular matrix client, invite the bot user to a conversation in a new room. Check in the configuration of the new room for its internal ID. It would be something like
!<internal-id>:<home-server>.

Then, accept such invitation from the command line:

$ curl -XPOST -d '{}' "https:///_matrix/client/r0/rooms/%21:/join?access_token="
{
    "room_id": "!:"
}

All that is left is to configure matrix-send and start using it. Mind you, I’ve done a small addition that it has not been merged yet so I would just clone from my fork.

The configuration file would look like this:

$ cat ~/.config/matrix-send/config.ini
[DEFAULT]
endpoint=https:///_matrix/
access_token=
channel_id=!:
msgtype=m.text

The interesting addition from my own is the msgtype field. By default, in matrix-send its value is m.notice which, depending on the configuration, quite typically won’t trigger a notification in your matrix client.

All that is left is to make matrix-send executable and test it:

$ chmod +x /matrix-send.py
$ /matrix-send.py "Hello World!"

How to use Debian’s reportbug with Evolution

Update: since reportbug 7.7.0 and Debian bullseye, it is now possible to specific your Mail User Agent (MUA) adding the proper option in the ~/.reportbugrc file. For example:

$ cat ~/.reportbugrc
[...]
mua xdg-email

If you don’t have the xdg-email tool from the xdg-utils package installed, you can directly specify the MUA application, like in mua evolution.


This is mostly a note pad for myself with quick instructions about how to create a bug report for Debian and edit it and send it with Evolution.

reportbug is Debian’s tool for sending bug reports. Although it is a nice tool that automatizes most of this process, it only supports some email clients for the final steps of editing the message (and send it). Among these programs is not Evolution, my preferred mail application.

Fortunately, there is a way to work around this problem. The way of doing it is by placing the mbox file created by reportbug into Evolution’s local Drafts folder. As we can read on its manual, Evolution stores the user’s data files at $HOME/.local/share/evolution.

By doing a simple check around that path, we can conclude the following solution: first, we generate the bug report and place the output in the proper location, as in this command:

$ reportbug -o ~/.local/share/evolution/mail/local/.Drafts/new/reportbug-mail.mbox

After finishing walking through reportbug‘s wizard, the only action left is launching Evolution and opening a new email that has appeared in the local Drafts folder, finish editing it (attaching files, etc.) and send it.

Adding subtitles to a video

This is mostly a note pad for myself with quick instructions about how to add subtitles streams to an existent video.

Although I’m personally more in favor of using Ogg, reality is that Matroska is the one that is getting the biggest support among the Open Source container formats and it also has a great deal of features.

Also, because of widespread adoption, in spite of not having a really formal syntax and many features, SubRip is my chosen format for subtitles.

Now, I’m the owner of a Samsung 3D SmartTV which allows external SubRip .srt files. However, it also supports Matroska files with embedded subtitles and having the subtitles in the same container than the audio and video streams have some advantages. The main one is that I would be able to play such file through UPnP, with subtitles included, meanwhile that’s not possible with some UPnP servers if the subtitles are in a different file than the video. That’s the case, for example, with BubbleUPnP for Android, which I use from a tablet.

Anyway, enough introduction.

For creating a Matroska file from an existing video and a SubRip file I would use the MKVToolNix package. In a Debian based system you can install it with the following command:

root$ apt-get install mkvtoolnix

In order to merge video and a subtitles (actually, many multiple streams), the proper command for this would be mkvmerge. Its usage is quite straight forward:

$ mkvmerge -o el_ministerio_del_tiempo_-_s01e01_-_el_ministerio_del_tiempo_-_with-lang-codes.mkv el_ministerio_del_tiempo_-_s01e01_-_el_ministerio_del_tiempo.mp4 --language 0:spa el_ministerio_del_tiempo_-_s01e01_-_el_ministerio_del_tiempo.srt --default-track 0
mkvmerge v7.1.0 ('Good Love') 64bit built on Jul 28 2014 11:58:03
'el_ministerio_del_tiempo_-_s01e01_-_el_ministerio_del_tiempo.srt': Using the demultiplexer for the format 'SRT subtitles'.
'el_ministerio_del_tiempo_-_s01e01_-_el_ministerio_del_tiempo.mp4' track 0: Using the output module for the format 'AVC/h.264'.
'el_ministerio_del_tiempo_-_s01e01_-_el_ministerio_del_tiempo.mp4' track 1: Using the output module for the format 'AAC'.
'el_ministerio_del_tiempo_-_s01e01_-_el_ministerio_del_tiempo.srt' track 0: Using the output module for the format 'text subtitles'.
The file 'el_ministerio_del_tiempo_-_s01e01_-_el_ministerio_del_tiempo_-_with-lang-codes.mkv' has been opened for writing.
'el_ministerio_del_tiempo_-_s01e01_-_el_ministerio_del_tiempo.mp4' track 0: Extracted the aspect ratio information from the MPEG-4 layer 10 (AVC) video data and set the display dimensions to 1024/576.
Progress: 100%
The cue entries (the index) are being written...
Muxing took 42 seconds.

That’s basically it. With this command we will get, from a .mp4 and a .srt file, a .mkv file with both merged together. Now, if we would be wanting to add more languages we could have done something like this:

$ mkvmerge -o el_ministerio_del_tiempo_-_s01e01_-_el_ministerio_del_tiempo_-_with-lang-codes.mkv el_ministerio_del_tiempo_-_s01e01_-_el_ministerio_del_tiempo.mp4 --language 0:spa el_ministerio_del_tiempo_-_s01e01_-_el_ministerio_del_tiempo-es.srt --language 1:eng el_ministerio_del_tiempo_-_s01e01_-_el_ministerio_del_tiempo-en.srt --default-track 0
...

This way we would be having Spanish and English subtitles, and the former would be the default one.

For more information, just check mkvmerge’s manual.

Adding a cover tag to an audio file

This is mostly a note pad for myself with quick instructions about how to add a “cover” tag to audio files.

I usually add covers to every individual audio file from my albums so I can nicely see them when playing the file either in my computer or mobile. Often, I just use the fantastic Ex Falso application not just to add more advanced tags to my audio files but also for downloading covers from different providers.

Whenever I cannot easily find the cover I’m looking for, I would just scan it and finally save it as a 500×500 pixels JPEG file named as cover.jpg in the same directory than the audio files.

Having this into account, let’s see how to embed the cover as a tag.

MP3 or, rather, id3 tags

For id3 tags I would use the eyeD3 tool. It can be done as easily as running:

$ eyeD3 --add-image=cover.jpg:FRONT_COVER *.mp3

OGG Vorbis

In the case of OGG Vorbis files I follow a little bit more complex steps. I’m sure I could just simplify this in a single step but, by now, I’m too lazy to spend 5 minutes improving this O:)

First, I would add the cover into an individual OGG Vorbis file using the EasyTag application. I could just save the same cover on every file but I wanted to show how to do that in batch mode from the command line.

Therefore, as I said, I just save the cover into and individual file an extract all the tags from such file using the vorbiscomment tool:

$ vorbiscomment -l .oga > comments.txt

Then, I would modify the comments.txt file so it will only contain the needed art cover tags and append them to the rest of the files:

$ vorbiscomment -a -c comments.txt .oga

Hopefully, I will update this in the future with a single command to do it in a go and will also review how to be able to just link the proper cover from the audio files. Also, I will try to explain the logic for the naming of the covers in the local directory without having to add the tag to any file so crawlers like Tracker will just do the work for us.

Enjoy!

Extract, cut, join and merge audio and video streams

This is mostly a note pad for myself with quick instructions about how to extract, cut, join and merge audio and video streams.

In Igalia we often hold meetings with several parties attending remotely. The easy setting of such meetings usually involve a shared desktop through VNC and a SIP call in a multi user room hold in our Asterisk installation.

When some of my Igalian mates cannot attend we may want to record the meeting so they can play it later. Fortunately, GNOME Shell provides integrated desktop recording out of the box and we have Asterisk set to record automatically our calls in specific multi user rooms.

So, all what it is left after a meeting is just to get both files, edit them slightly and sync them to merge them in a single multimedia container.

Usually, I would use Kdenlive in my video editing tasks. However, Kdenlive doesn’t support “video edition” without re-encoding and I would really like not to re-encode the whole stuff. Specially, the video stream. Therefore, I still will use Kdenlive for the task of syncing both streams and looking for the cutting points for both, the video and the audio file.

For most of this “without re-encoding” actions I will use the great avconv tool.

First, I will cut the video in the time 00:07:45 as starting point and 02:05:20 as ending point:

$ avconv -i screencast.webm -c:v copy -ss 00:07:45 -t 02:05:20 cut-screencast.mkv

This command basically demuxes the WebM container and extract the video stream between those two points to mux it again into a Matroska container.

Then, I will cut the audio in the starting point 00:02:13 and ending point 01:59:48. For editing OGG files we can use Oggscissors or OGG Video Tools’ oggCut .

You won’t find Oggscissors in Debian (the distribution I use). Therefore, you will have to download it and install pyvorbis and pyogg and, maybe, modify slightly the script to use the proper python interpreter. You can install the missing packages like this:

root$ apt-get install python-pyvorbis

Once with Oggscissors working, we can get the interesting audio chunk like:

$ oggscissors.py --from=133 --upto=7188 conf-call.ogg cut-confcall.ogg

or, with oggCut, like:

$ oggCut -s 133000 -e 7188000 conf-call.ogg cut-conf-call.ogg

It may happen that we actually want to extract the audio from another video file. This has happened to us, eventually, when wanting to use the audio from a synced file into another video with higher quality.

We will also use avconv for this:

$ avconv -i synced-video.ogv -map 0:1 -c:a copy synced-audio-output.ogg

It may also happen that we want to join a couple of OGG files since our SIP conf-calls sometimes have hiccups. With Oggscissors this will be done as follows:

$ oggscissors.py --join first.ogg second.ogg joint-output.ogg

With oggCat this will be done like:

$ oggCat joint-output.ogg first.ogg second.ogg

Finally, we will merge or mux the resulting video and audio files into a single media container. Again, with avconv this will be done like:

$ avconv -i final-screencast-conf-call.mkv -i cut-conf-call.ogg -c copy cut-screencast.mkv

Following the examples above this will result in a Matroska video file which contains a VP8 video stream and a Vorbis audio stream.

Hope you find this useful!

Switching between nouveau and the nVIDIA proprietary OpenGL driver in (Debian) GNU/Linux

So lately I’ve been devoting my time in Igalia around the GNU/Linux graphics stack focusing, more specifically, in Mesa, the most popular open-source implementation of the OpenGL specification.

When working in Mesa and piglit, its testing suite, quite often you would like to compare the results obtained when running a specific OpenGL code with one driver or another.

In the case of nVIDIA graphic cards we have the chance of comparing the default open source driver provided by Mesa, nouveau, or the proprietary driver provided by nVIDIA. For installing the nVIDIA driver you will have to run something like:

root$ apt-get install linux-headers nvidia-driver nvidia-kernel-dkms nvidia-xconfig nvidia-kernel-amd64

Changing from one driver to another involves several steps so I decided to create a dirty script for helping with this.

The actions done by this script are:

  1. Instruct your X Server to use the adequate X driver.
    These instructions apply to the X.org server only.
    When using the default nouveau driver in Debian, the X.org server is able to configure itself automatically. However, when using the nVIDIA driver you most probably will have to instruct the proper settings to X.org.
    nVIDIA provides the package nvidia-xconfig. This package provides a tool of the same name that will generate a X.org configuration file suitable to work with the nVIDIA X driver:

    root$ nvidia-xconfig 
    
    WARNING: Unable to locate/open X configuration file.
    
    Package xorg-server was not found in the pkg-config search path.
    Perhaps you should add the directory containing `xorg-server.pc'
    to the PKG_CONFIG_PATH environment variable
    No package 'xorg-server' found
    New X configuration file written to '/etc/X11/xorg.conf'
    

    I have embedded this generated file into the provided custom script since it is suitable for my system:

        echo 'Section "ServerLayout"
        Identifier     "Layout0"
        Screen      0  "Screen0"
        InputDevice    "Keyboard0" "CoreKeyboard"
        InputDevice    "Mouse0" "CorePointer"
    EndSection
    
    Section "Files"
    EndSection
    
    Section "InputDevice"
        # generated from default
        Identifier     "Mouse0"
        Driver         "mouse"
        Option         "Protocol" "auto"
        Option         "Device" "/dev/psaux"
        Option         "Emulate3Buttons" "no"
        Option         "ZAxisMapping" "4 5"
    EndSection
    
    Section "InputDevice"
        # generated from default
        Identifier     "Keyboard0"
        Driver         "kbd"
    EndSection
    
    Section "Monitor"
        Identifier     "Monitor0"
        VendorName     "Unknown"
        ModelName      "Unknown"
        HorizSync       28.0 - 33.0
        VertRefresh     43.0 - 72.0
        Option         "DPMS"
    EndSection
    
    Section "Device"
        Identifier     "Device0"
        Driver         "nvidia"
        VendorName     "NVIDIA Corporation"
    EndSection
    
    Section "Screen"
        Identifier     "Screen0"
        Device         "Device0"
        Monitor        "Monitor0"
        DefaultDepth    24
        SubSection     "Display"
            Depth       24
        EndSubSection
    EndSection
    ' > /etc/X11/xorg.conf
    

    I would recommend you to substitute this with another configuration file generated with nvidia-xconfig on your system.

  2. Select the proper GLX library.
    Fortunately, Debian provides the alternatives mechanism to select between one or the other.

    ALTERNATIVE=""
    

        ALTERNATIVE="/usr/lib/mesa-diverted"
    

        ALTERNATIVE="/usr/lib/nvidia"
    

    update-alternatives --set glx "${ALTERNATIVE}"
    
  3. Black list the module we don’t want the Linux kernel to load on start up.
    Again, in Debian, the nVIDIA driver package installs the file /etc/nvidia/nvidia-blacklists-nouveau.conf that is linked, then, from /etc/modprobe.d/nvidia-blacklists-nouveau.conf instructing that the open source nouveau kernel driver for the graphic card should be avoided.
    When selecting nouveau, this script removes the soft link creating a new file which, instead of black listing nouveau’s driver, does it for the nVIDIA proprietary one:

        rm -f /etc/modprobe.d/nvidia-blacklists-nouveau.conf
        echo "blacklist nvidia" > /etc/modprobe.d/nouveau-blacklists-nvidia.conf
    

    When selecting nVIDIA, the previous file is removed and the soft link is restored.

  4. Re-generate the image used in the inital booting.
    This will ensure that we are using the proper kernel driver from the beginning of the booting of the system:

    update-initramfs -u
    

With these actions you will be already able to switch your running graphic driver.

You will switch to nouveau with:

root$ /alternate-nouveau-nvidia.sh nouveau
update-alternatives: using /usr/lib/mesa-diverted to provide /usr/lib/glx (glx) in manual mode
update-initramfs: Generating /boot/initrd.img-3.17.0

nouveau successfully set. Reboot your system to apply the changes ...

And to the nVIDIA proprietary driver with:

root$ /alternate-nouveau-nvidia.sh nvidia
update-alternatives: using /usr/lib/nvidia to provide /usr/lib/glx (glx) in manual mode
update-initramfs: Generating /boot/initrd.img-3.17.0

nvidia successfully set. Reboot your system to apply the changes ...

It is recommended to reboot the system although theoretically you could unload the kernel driver and restart the X.org server. The reason is that it has been reported that unloading the nVIDIA kernel driver and loading a different one is not always working correctly.

I hope this will be helpful for your hacking time!

Side tabs in Empathy

Going quickly to the interesting part.

If you happen to use Ubuntu Saucy 13.10 and would like to have side tabs in Empathy, just write the following commands:


$ sudo add-apt-repository ppa:tanty/ppa

If, in addition to be using Ubuntu Saucy 13.10 you are using also GNOME3 Team’s PPA, you will need to run the following command:


$ sudo add-apt-repository ppa:tanty/gnome3

Finally, update your repositories, upgrade empathy and set the proper configuration:


$ sudo apt-get update && sudo apt-get install empathy
...
$ gsettings set org.gnome.Empathy.conversation tab-position 'left'

After this, you can just open the chat window in a new Empathy running instance and you should see something like this:

Side tabs in Empathy by ::Tanty::
Side tabs in Empathy, a screenshot by ::Tanty:: on Flickr.

Motivation

I’m a long time user of Jabber and Empathy. I use it for every day’s communications and, in Igalia, we have several internal rooms in which we coordinate ourselves. Because of the amount of rooms in which I am as a regular basis, Empathy’s chat window is unable to display the tabs of each of them in the top bar of the conversations.

This forces me either to split in different windows or just to navigate among them every now and then to check if there is any interesting update. Quite annoying 🙂 .

Some time ago, #586145 was filed requesting the possibility of having the chat room tabs not only displayed on top but also in other positions, specially in the side.

Hence, I decided to take the existing patch and perform some small changes to the work done by Neil Roberts in order to be able to have these side tabs.

With this new feature, you can change the position of the tabs just by changing a setting, as the position property is bond to it. If you want to set the tabs at ‘top’, ‘left’, ‘bottom’ or ‘right’, you should run, respectively:


$ gsettings set org.gnome.Empathy.conversation tab-position 'top'
$ gsettings set org.gnome.Empathy.conversation tab-position 'left'
$ gsettings set org.gnome.Empathy.conversation tab-position 'bottom'
$ gsettings set org.gnome.Empathy.conversation tab-position 'right'

Now, I’ve uploaded a new version of the patch and I’m waiting to pass the review process and land it.

This is a tiny enhancement on top of the great work that several GNOME developers have done in Empathy over the years. However, it is really making a difference to me so I’ve decided to share it quickly in case someone else would find it useful since it will take a while to come into the main distributions. Hence, I’ve ported it to the Empathy version I’m using in the Ubuntu Saucy 13.10 running on my desktop.

If you want to give it a try, just follow the instructions I’ve written at the beginning of this post.

Final notes

In addition to Empathy, you will be able to find in my PPAs:

  • A working (and custom) version of the faulty official icecc package with patches fixing LP#1182491.
  • A custom version of webkitgtk with patches fixing WK#115650 which will speed up opening new tabs in Web.

Enjoy!

Update: I’ve added recently empathy patched versions also for Ubuntu Trusty 14.04.

Update 2: I’ve added recently empathy patched versions also for Ubuntu Utopic 14.10.

Quickly publishing in your Ubuntu PPA

This is more a note pad for myself with quick instructions about how to upload a (usually patched) package to my own PPAs.

Patching an existing package

First thing is downloading the sources of the package from the repository that is providing the buggy binary package installed in my system.

For example, when patching webkitgtk, if my installed package is from a vanilla Ubuntu release, I only have to check that I have the source from the official Ubuntu repositories. However, if my installed package is from another PPA, I will have to check that I have the source from it or, if not, I would have to download the needed packages manually. Let’s assume my installed package is coming from the GNOME3 Team Ubuntu PPA:

$ cd ~/ppa/ && mkdir -p webkitgtk/gnome3 && cd webkitgtk/gnome3
$ apt-get source webkitgtk
Reading package lists... Done
Building dependency tree
Reading state information... Done
NOTICE: 'webkitgtk' packaging is maintained in the 'Git' version control system at:
git://git.debian.org/git/pkg-webkit/webkit.git
Need to get 9,440 kB of source archives.
Get:1 http://ppa.launchpad.net/gnome3-team/gnome3/ubuntu/ saucy/main webkitgtk 2.3.2-1ubuntu6~saucy1 (tar) [9,353 kB]
Get:2 http://ppa.launchpad.net/gnome3-team/gnome3/ubuntu/ saucy/main webkitgtk 2.3.2-1ubuntu6~saucy1 (diff) [82.2 kB]
Get:3 http://ppa.launchpad.net/gnome3-team/gnome3/ubuntu/ saucy/main webkitgtk 2.3.2-1ubuntu6~saucy1 (dsc) [4,577 B]
Fetched 9,440 kB in 3s (2,769 kB/s)
gpgv: Signature made Sun 22 Dec 2013 01:34:25 AM EET using RSA key ID 153ACABA
gpgv: Can't check signature: public key not found
dpkg-source: warning: failed to verify signature on ./webkitgtk_2.3.2-1ubuntu6~saucy1.dsc
dpkg-source: info: extracting webkitgtk in webkitgtk-2.3.2
dpkg-source: info: unpacking webkitgtk_2.3.2.orig.tar.xz
dpkg-source: info: unpacking webkitgtk_2.3.2-1ubuntu6~saucy1.debian.tar.gz
dpkg-source: info: applying 02_notebook_scroll.patch
dpkg-source: info: applying aarch64.patch
dpkg-source: info: applying fix-ppc.diff
dpkg-source: info: applying fix-aarch64.patch
dpkg-source: info: applying remove-use-lockfree-threadsaferefcounted.patch
dpkg-source: info: applying no-jit-build-failure.patch
dpkg-source: info: applying 0001-GTK-Fails-to-build-with-freetype-2.5.1.patch
dpkg-source: info: applying disable-jit-harder.patch
dpkg-source: info: applying fix-llint-c-loop.patch
dpkg-source: info: applying fix-armv7.patch
dpkg-source: info: applying bugzilla_clear_surface.patch
dpkg-source: info: applying ppc64el.patch
$ cd webkitgtk-2.3.2

Just in case, something I like to do is to add the code from the downloaded package to a local git:

$ git init
$ git add *
$ git commit -m "Initial commit"
...

Then, it is time to apply the needed changes to the source code. This is the reason why git comes handy, in case these changes are not trivial and they need actually some more work. When we are done with the changes, we have to add them to the debian package as an additional patch to the original source. We use dpkg-source for this:

$ dpkg-source --commit
dpkg-source: info: local changes detected, the modified files are:
 webkitgtk-2.3.2/Source/WebKit2/GNUmakefile.am
 webkitgtk-2.3.2/Source/WebKit2/GNUmakefile.list.am
 webkitgtk-2.3.2/Source/WebKit2/Shared/Plugins/Netscape/NetscapePluginModule.h
 webkitgtk-2.3.2/Source/WebKit2/Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp
 webkitgtk-2.3.2/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.cpp
 webkitgtk-2.3.2/Source/WebKit2/UIProcess/Plugins/gtk/PluginInfoCache.h
 webkitgtk-2.3.2/Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp
Enter the desired patch name: 0001-GTK-WK2-Blocks-when-fetching-plugins-information.patch
...

We enter the patch name and the description of the changes:

$ cat debian/patches/0001-GTK-WK2-Blocks-when-fetching-plugins-information.patch
Description: [GTK][WK2] Blocks when fetching plugins information
 https://bugs.webkit.org/show_bug.cgi?id=115650
 .
 Patch by Carlos Garcia Campos.
 Reviewed by Gustavo Noronha Silva.
 .
 Use a persistent cache to store the plugins metadata to avoid
 having to load all the plugins everytime a plugin is used for the
 first time.
 .
 * GNUmakefile.am:
 * GNUmakefile.list.am:
 * Shared/Plugins/Netscape/NetscapePluginModule.h:
 * Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp:
 (WebKit::NetscapePluginModule::parseMIMEDescription): Make this
 method public.
 (WebKit::NetscapePluginModule::buildMIMEDescription): Added this
 helper to build the MIME description string.
 * UIProcess/Plugins/gtk/PluginInfoCache.cpp: Added.
 (WebKit::PluginInfoCache::shared):
 (WebKit::PluginInfoCache::PluginInfoCache):
 (WebKit::PluginInfoCache::~PluginInfoCache):
 (WebKit::PluginInfoCache::saveToFileIdleCallback):
 (WebKit::PluginInfoCache::saveToFile):
 (WebKit::PluginInfoCache::getPluginInfo):
 (WebKit::PluginInfoCache::updatePluginInfo):
 * UIProcess/Plugins/gtk/PluginInfoCache.h: Added.
 * UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp:
 (WebKit::PluginInfoStore::getPluginInfo): Check first if we have
 metadata of the plugin in the cache and update the cache if we
 loaded the plugin to get its metadata.
...

Finally, we modify the release information adding or increasing the non-maintainer digit. For example, in this case the downloaded source version was 2.3.2-1ubuntu6~saucy1, so I’m setting 2.3.2-1ubuntu6~saucy1.1. Also, remember to provide the proper distribution name or to modify it when writing down the log of the changes. In this case, we are using saucy. Check also that you are using the proper email for the log. In my PPAs I use my personal one:

$ DEBEMAIL="my@personal.email" dch -n -D saucy
$ cat debian/changelog
webkitgtk (2.3.2-1ubuntu6~saucy1.1) saucy; urgency=low

  * Fixes #115650:
    - debian/patches/0001-GTK-WK2-Blocks-when-fetching-plugins-information.patch

 -- Andres Gomez   Wed, 19 Mar 2014 14:26:19 +0200
...

With this, we are done modifying the source of the package.

Importing patch alternative

Maybe this is a cleaner and quicker way of patching the downloaded sources. Instead of modifying the sources and running dpkg-source –commit, we can just import an existent patch that would apply on the source code.

To do this, we just have to run:

$ quilt import //my_patch.patch

This will also work in Debian packages for which version dpkg-source –commit won’t work. In addition, is the quickest way to reuse a patch from a package in a previous Ubuntu distribution into a newer one, for example.

From here we will retake the same steps than above to add the release information.

Building the source package

We just have to take into account that, when you have more than one GPG key available, the signature of the package will fail during the process, as in:

$ debuild -S -rfakeroot
...
Finished running lintian.
Now signing changes and any dsc files...
 signfile webkitgtk_2.3.2-1ubuntu6~saucy1.1.dsc Andres Gomez 
gpg: skipped "Andres Gomez ": secret key not available
gpg: /tmp/debsign.vhpVY32w/webkitgtk_2.3.2-1ubuntu6~saucy1.1.dsc: clearsign failed: secret key not available
debsign: gpg error occurred!  Aborting....
debuild: fatal error at line 1280:
running debsign failed

Hence, you have to provide the key id to use in the -k parameter.

In addition, if the sources used for the package are not coming from one of the official Ubuntu repositories you will need to provide also the sources when uploading to the PPA. For this, you have to pass the -sa parameter. For the used example, as we are taking the source from the GNOME3 Team Ubuntu PPA, we will pass this parameter as in:

$ debuild -S -sa -rfakeroot -k3FEA1034

While for other packages which we modify directly from the sources of the official packages provided by Ubuntu, we just use:

$ debuild -S -rfakeroot -k3FEA1034

Optional local build

A local build is not really necessary but it will tell you if your applied changes are breaking or not the compilation of the package.

The best way of doing a trustful local build is using pbuilder.

When using pbuilder we have to be sure that we are using the proper packages not only from Ubuntu’s official repositories but also from the PPAs our target PPA depends on and also our own PPA itself.

I’ve already created the tarballs with the chroot distributions for my own PPAs. However, in order to show an example, we would be using a line like the following one for creating a new tarball for my gnome3 PPA which depends in my ppa PPA and also in GNOME3 Team’s gnome3 PPA:

$ sudo pbuilder --create --distribution saucy --mirror "http://fi.archive.ubuntu.com/ubuntu/" --othermirror "deb http://fi.archive.ubuntu.com/ubuntu/ saucy restricted universe multiverse|deb http://fi.archive.ubuntu.com/ubuntu/ saucy-updates main restricted universe multiverse|deb http://fi.archive.ubuntu.com/ubuntu/ saucy-proposed main restricted universe multiverse|deb http://fi.archive.ubuntu.com/ubuntu/ saucy-security main restricted universe multiverse|deb http://archive.canonical.com/ubuntu saucy partner|deb http://ppa.launchpad.net/gnome3-team/gnome3/ubuntu trusty main|deb http://ppa.launchpad.net/tanty/ppa/ubuntu saucy main|deb http://ppa.launchpad.net/tanty/gnome3/ubuntu saucy main" --basetgz //saucy-gnome3.tgz --buildplace //build --aptcache  "//aptcache/"

I make use of the <path_to_base_pbuilder> because by default it is all done at /var and I do not always have enough space there.

Once created, and following our example, we would be building our package for the target gnome3 PPA as follows:

$ sudo pbuilder --build --mirror "http://fi.archive.ubuntu.com/ubuntu/" --othermirror "deb http://fi.archive.ubuntu.com/ubuntu/ saucy main restricted universe multiverse|deb http://fi.archive.ubuntu.com/ubuntu/ saucy-updates main restricted universe multiverse|deb http://fi.archive.ubuntu.com/ubuntu/ saucy-proposed main restricted universe multiverse|deb http://fi.archive.ubuntu.com/ubuntu/ saucy-security main restricted universe multiverse|deb http://archive.canonical.com/ubuntu saucy partner|deb http://ppa.launchpad.net/gnome3-team/gnome3/ubuntu trusty main|deb http://ppa.launchpad.net/tanty/ppa/ubuntu saucy main|deb http://ppa.launchpad.net/tanty/gnome3/ubuntu saucy main" --basetgz //saucy-gnome3.tgz --buildplace //build --aptcache  "//aptcache/" ../webkitgtk_2.3.2-1ubuntu6~saucy1.1.dsc

Now, it is just a matter of waiting and checking the results.

Uploading to your PPA

The final step is uploading the package with the new changes to your PPA.

I actually have one sandbox PPA per each stable PPA. These PPAs are not intended for the general users but for being able to play with the changes until I feel they are stable enough to be published in the stable PPAs. Hence, I have 4 PPAs:

  • ppa: Where I keep changes from official Ubuntu packages that are useful to me.
  • ppa-next: Not intended for general users. Where I keep unstable packages with the changes that I will move to the ppa one once I feel they are stable enough.
  • gnome3: Where I keep changes on packages which source has been obtained from the GNOME3 Team PPA.
  • gnome3-next: Not intended for general users. Where I keep unstable packages with the changes that I will move to the gnome3 one once I feel they are stable enough.

With this, during the first cycles of development I will be uploading the changes to my unstable PPAs before uploading them to the stables. For this example, I would be uploading first to the gnome3-next one:

$ dput ppa:tanty/gnome3-next ../webkitgtk_2.3.2-1ubuntu6~saucy1.1_source.changes

Once I’m happy enough I would be uploading the changes to the stable PPA:

$ dput -f ppa:tanty/gnome3 ../webkitgtk_2.3.2-1ubuntu6~saucy1.1_source.changes

The -f flag is avoid the error that is triggered when there is already a “log” file from a previous upload with dput of a certain “.changes” package.

With this, you only have to wait for the package to be built on the PPA bots, upload your repositories and upgrade:

$ sudo apt-get update && sudo apt-get upgrade

Enjoy your newly patched package!

What’s up with the scrollbar?

First, it was Ubuntu which innovated in the scrollbars creating a nice overlay, but making them unusable for those like me using a track pointer or a mouse without wheel.

Now, with GTK-3.0, the scrollbars have also changed their default behavior and when clicking above or below, the scrollbar moves immediately to that position.

Again, this makes it unusable unless you have a wheel in your mouse or have another fancy way of scrolling, like a touch pad.

I’m nowadays a proud owner of a Lenovo X220 and I use the track pointer included disabling the annoying touch pad thanks to the Touchpad Indicator GNOME extension. I say “annoying” because, when using the track pointer, I tend to touch every now and the the touch pad with unpredictable results.

So, with the new behavior and without the possibility of scrolling with a mouse wheel or a touch pad, viewports with a long extension are really difficult to browse with the pointer. This is the case for several of my mail folders in Evolution. As a result, I was getting nuts.

Therefore, I wanted to go back to the old behavior. This is: when clicking above the bar it would mean “PgUp” and when clicking below “PgDown”.

Fortunately, GTK-3.0 provides a way of tuning this. You have to add an option to its “settings.ini” file. If you want to apply it system wide, you will do it in “/etc/gtk-3.0/settings.ini” while if you want only to affect an user, you will do it in “~/.config/gtk-3.0/settings.ini”.

This is how it looks like:

Hope this helps to someone else! 🙂

Introducing Facerecognition Resetter Plugin for the Nokia N9

As my mate Simón was writing short time ago in his post Announcing the Gallery Tilt Shift plugin for the Nokia N9, we got published at Igalia some plugins for enhancing the experience of the built-in Gallery application in the N9/N950 through the Nokia Store: Enlarge & Shrink Plugin, Gallery Tilt Shift Plugin, and Facerecognition Resetter Plugin.

The Enlarge & Shrink Plugin is a filter developed by Antía Puentes for the built-in Gallery application which applies a radial distortion to a picture featuring an enlarge or shrink effect (also known as punch or pinch).

The Gallery Tilt Shift Plugin is a filter developed by Simón Pena for the built-in Gallery application which makes a picture look like a miniature.

Finally, Facerecognition Resetter Plugin was developed by me. It is a add-on for the built-in Gallery application which is not a real filter for the pictures. Instead, it is just a way of forcing the deletion or un/protection of the face recognition database through its usage from Gallery. The main reason for doing this is a well known bug in the face recognition feature.

If you are experiencing that the the N9 is not recognizing faces any more or it is not giving any more suggestions just install Facerecognition Resetter Plugin and click on the “Protect” button. You want to do this even if you are not suffering this problem since this will prevent it from appearing in the future.

BTW, comments and reviews in the Nokia Store will be welcomed 😀

But, specifically, why would we want to reset or un/protect the face recognition database? Or, actually, what the heck is that face recognition database? Let’s get to the beginning.

When Nokia released the PR1.2 update for the Harmattan platform they included a new feature which made the N9 to be the first smartphone with integrated automated face recognition.

This feature, when activated, let the Gallery or Camera application to automatically recognize faces on the pictures stored in the device, showing a white bubble with a question mark on top of the region detected as a face.

Clicking on such bubble you would be able to select one of your contacts to be assigned as the detected face.

The algorithm would be even learning as the user selected and assigned faces to contacts so at some point it would be also suggesting the proper contact for the detected faces. The user, then, would only have to double tap on the suggestion bubble to confirm such contact.

Everything seemed great but after a while, some users started to complain that this feature eventually stopped working. Either it was not suggesting anyone, when there were people tagged in a big number of pictures or it was just not recognizing faces any more.

As with any software, the face recognition feature contains bugs and this problem was the consequence of one that Nokia has not yet fixed to the current date.

The technical explanation is that the algorithm that performs the face detection relies in SQLite to store its learning parameters and contacts. This database is located at:

/home/user/.local/share/gallerycore/data/faces.db

This file and its directory are protected through the usage of the AEGIS “powered” gallerycoredata-user user and gallerycoredata-users group. Also, the file permissions mask for them are 070 in the case of the directory and 060 in the case of the file.

When doing transactions to the database file the SQLite driver may create some temporal files as the journal one, to be able to recover the database under disaster. This journal file gets the UID and GID of the running process and the permissions from a combination of the permissions of the original database file and the running process’ umask. As a consequence, the journal file usually has the permissions mask 040.

While using the Camera or Gallery application the SQLite file is open. Whether a disaster may happen, although we hold the journal file, the owner of that file is not able to read it. Hence, the SQLite database remains useless for the processes with the same UID than the owner of the journal file, even when they belong to the same group than that file.

What it happen afterwards is that the SQLite database remained waiting to be “recovered” using the journal file but as the journal could not be read, the face recognition algorithm could not provide the learned information and suggest contacts any more. The solution for this would have been as easy as to change the file permissions of the journal file but this is not even possible for the root user since only the gallerycore-user user and those belonging to the gallerycore-users group were allowed through AEGIS to read and change the files on the parent directory of the database file.

Hence, the only way of being able to do a hack that would solve this problem was that the actual application doing such changes would be either Gallery or Camera. Fortunately, Gallery had the possibility of being extended through plugins and that’s the reason why Facerecognition Resetter is such.

Following, you can watch a video featuring an usage introduction tutorial and a detailed explanation of its usage below it.

The plugin shows 3 buttons for its corresponding actions:

  • Reset the database: As simple as that. It will delete the directory and files containing all the information gathered through the face recognition algorithm. From that on, the face recognition feature will start to work again but the learning gotten previously and powering the suggestions will be lost.
  • Protect the database: This will correct the permissions of the directories and files containing all the information gathered through the face recognition algorithm. From that on, the face recognition feature will start to work again and the suggestions would have the learning gotten previously. The problem will not show up in the future ever again but the database will remain protected and only usable through Gallery and Camera (or any other application with the proper AEGIS tokens).
  • Unprotect the database: This will correct the permissions of the directories and files containing all the information gathered through the face recognition algorithm. From that on, the face recognition feature will start to work again and the suggestions would have the learning gotten previously. The problem will not show up in the future ever again and the database will be available to any other application that would like to make use of it.

The permissions get corrected when un/protecting since the plugin sets the SGID bit to the parent directory of the database file so any other files created under it will belong to the same group than the directory and not to the GID of the running process that created that file. Also, the database will have now the 660 mask so any temporal file created by the SQLite drive will attempt to keep the same mask.

And with this, we can keep enjoying the usage of the face recognition feature of the N9 and go to celebrate it with some beers!!! 😀

This and the other plugins are Open Source, so you can go to their page at GitHub: Enlarge & Shrink, Gallery Tilt Shift and Facerecognition Resetter

Also, don’t forget to take a look at all the applications published by Igalia at the Nokia Store

Download Facerecognition Resetter Plugin from Nokia Store