Copy all but some properties of an object in ES6

Since I started playing with ES6 about half a year ago I really came to love the new syntax, as it provides a much more python-ish feel to Javascript development.

One of the functions I like the most is the awesome Object.assign().

You can use it for all sorts of things:

const oldObject = { foo: 'bar', baz: 42 };
// (shallow) copy an object
const newObject = Object.assign({}, oldObject);
// overwrite some values
const overwritten = Object.assign({}, oldObject, { foo: 'fighters' });
// overwritten is { foo: 'fighters', baz: 42 }
// merge objects
const other = { luftballons: 99 };
const merged = Object.assign({}, oldObject, other);
// merged is { foo: 'bar', baz: 42, luftballons: 99 }

and more awesomeness that you can find, as always, on the MDN site.

One thing that I found out today that made my day better is that you can use Object.assign() to copy an object except for some of its properties.

const oldObject = { foo: 'bar', baz: 42 };
const noFoo = Object.assign({}, oldObject, { foo: undefined });
// noFoo is { baz: 42 }

As easy as that!

I find myself doing this kind of operation quite often, namely when I decorate some object generated from JSON retrieved from a server and want to send it back after changing it client-side. This syntax makes it oh-so-simple!

IntelliJ Idea adds tags when typing ‘t

This was quite annoying, especially since I failed at googling a cure for it.

What happens: whenever you type “'t” in a comment on a Java file in Idea followed by a whitespace, it gets replaced with “<></>“, and whatever you type after that is added as if it were an HTML tag pair.

If you actually pause after typing “'t” (which I don’t know why it’s something I never did until now), you’ll notice IntelliJ’s auto-complete popup telling you what’s going on:

popup

It turns out that “t” is the shortcut for “tag pair”, which might be awesome for HTML coding, but it’s not as nice when you’re writing comments.

To disable that, go to Settings/Editor/Live Templates/, expand the html/xml line, and uncheck t (tag pair). Hit OK, and it’s gone!

After upgrading, Jenkins doesn’t start: org.xml.sax.saxparseexception: premature end of file

I recently upgraded my Jenkins installation using Debian’s package manager, and to my surprise… Jenkins wouldn’t start!

The error logged in /var/log/jenkins/jenkins.log looked like this:

WARNING: Failed startup of context w.{,file:/var/cache/jenkins/war/},/var/cache/jenkins/war
org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Premature end of file.

followed by a Java stack trace. I noticed a suspicious line in that stack trace:

at org.eclipse.jetty.webapp.MetaData.setWebXml(MetaData.java:170)

interesting. It looked like something was wrong with Jenkins’ web.xml, so I checked /var/cache/jenkins/war/WEB-INF/web.xml and, surprise surprise… it was empty!

I unpacked an old jenkins.war that I had, and copied its web.xml over, restarting the service. A-ha! The logged error changed. Unfortunately, it still wouldn’t start, but it made me look for “jenkins corrupted /var/cache” which finally lead me to this bug report.

“Dang!” – I thought – “is that it?”.

Moved the old /var/cache/jenkins away, created a new empty directory, and set user jenkins as its owner:

mv /var/cache/jenkins ~/var-cache-jenkins-back
mkdir /var/cache/jenkins
chown -R jenkins:jenkins /var/cache/jenkins
service jenkins start

sonofa… it worked!

Fix out of sync subtitles with Angular

In what seems to be a never ending series of posts on how to fix out of sync subtitles… here’s how to do it using Angular! 🙂

First things first: here’s a link to the webpage that you can use to fix your out of sync subtitles. Just go there and follow the instructions, it’s really easy. Trust me, I’m the author 😛

A little background on why I made that page. About a year and a half ago I started toying around with AngularJS, because we decided to re-write the SketchTogether HTML client in it. Since I’m mostly taking care of the server side of the app, I spent a lot more time reading Angular code than writing it; even if I think I got the basic concepts relatively quickly, I wanted to have some first-hand experience with the library to really grasp what it means to develop an app with it, even if just a basic one.

Since back in those days I was fiddling with a toy python script to fix out of sync subtitles, I decided that it could have been fun to do the same thing in Angular. I wrote a rough implementation of the script’s functionality in about two weeks of my off time (about 10 very fragmented hours all in all, and I must say I was happy with it, considering how Angular is known for its steep learning curve), and left it there. Fast forward to 4 months ago, I decided to make it look a little prettier, and publish it on GitHub. And then, it took me 4 more months to find the time to write this blog post about it on a Sunday night 😛

My experience with Angular so far has been positive. For one thing, it’s not as hard to create a non-trivial webpage with it as most people want you to believe. Data binding can get you pretty far, and it’s relatively straightforward (one basic thing that left me wondering though is the from-dashed-to-camelCase directive name auto-conversion… that felt a bit like unneeded magic to me).

It does get a bit convoluted when your application grows and you want to add some piece of functionality that’s like 4 lines of code in jQuery, but which takes a new directive definition, changes to the HTML, and maybe a new scope, just to follow the Angular way. But then again, it could be my limited knowledge of the library (which I intend to keep expanding, because there’s so much to learn!).

As with most things Javascript, there tends to be an oversupply of sub-libraries to do pretty much anything. For subslider.js, for example, I found a lot of angular plugins to take care of pagination, with no clear winner. The same applies for drag-and-drop support (which in the end was implemented as a directive in the app). It really takes some time to simply understand which of the many plugins suits you best… just look at how many plugins are listed by ngmodules!

Oh, and one last thing. The “there should be a dot in your model” rule should be re-stated everywhere in the documentation. Once you really understand what it is about, you experience one of the major bumps in the famous “feelings about angular over time” graph from this post 🙂

A template to create log4j Logger objects in Eclipse

In my (server) Java apps, I usually use log4j to keep logs. These days, I actually use SLF4J as a proxy for log4j, mostly because the framework I’m using (Vert.x) uses it.

Over the years I’ve tuned my log format to only store the information I care about, and nothing more than that:

<PatternLayout pattern="[%d{HH:mm:ss.SSS}] %p %c{3} - %m%n" />

so I have a timestamp, the log level (%p), the class name with up to 3 levels of package hierarchy (%c{3}), and the new-line-terminated message (%m%n).

A sample line:

[11:39:36.667] TRACE redis.redis_client.RedisDecoder - received new MultiBulkReply

This format requires a Logger object in all classes that need logging, which requires quite a bit of boilerplate code, e.g.:

private static final Logger LOGGER = LoggerFactory
    .getLogger(SlackRouter.class);

You quickly grow tired of typing all of that. But worry not! Eclipse comes to the rescue!

Setup an Eclipse Template

I created a template that does the work for me: now, all I have to do to add a new Logger object is type log, hit Ctrl + space, and select “Insert logger”.

Just like this:

Adding a Logger

Note that typing “log4” instead of “log” only gives you one option, saving 2 precious key strokes! 😛

Here’s how to set it up for your Eclipse.

  1. Open your Eclipse Preferences menu
  2. Type “java editor templates” in the search bar
    uno
  3. Hit the “New” button
  4. Set “log4j” as name (or whatever you want the shortcut to be), add a description, paste this in the “Pattern” field:
    ${:import(org.slf4j.Logger,org.slf4j.LoggerFactory)}
    private static final Logger LOGGER = LoggerFactory.getLogger(${enclosing_type}.class);
    

    and hit “OK”
    tre

  5. That’s it!

    If you’re not using SLF4J, all you need to do is change the import code to include the actual class you use.

Find the most recent file/folder in a folder with Java 8

A simple snippet that shows how Java 8 lambdas can be really nice to replace operations that used to require a lot of boilerplate in earlier versions of Java.

If you want to find the most recent file or subfolder in a folder with Java 8, here’s what you need to do:

Path parentFolder = Paths.get("path", "to", "your", "file");

Optional<File> mostRecentFileOrFolder =
    Arrays
        .stream(parentFolder.toFile().listFiles())
        .max(
            (f1, f2) -> Long.compare(f1.lastModified(),
                f2.lastModified()));

if (mostRecentFolder.isPresent()) {
    File mostRecent = mostRecentFileOrFolder.get();
    System.out.println("most recent is " + mostRecent.getPath());
} else {
    System.out.println("folder is empty!");
}

The very nice thing is that you can take advantage of the flexibility of Java 8 streams to either make the operation parallel (just throw in a parallel() call after Arrays.stream()), or to filter results according to other criteria.

For example, if you’re only interested in one type of child elements (a file or a folder), you could…

// if you're only interested in files...
Optional<File> mostRecentFile =
    Arrays
        .stream(parentFolder.toFile().listFiles())
        .filter(f -> f.isFile())
        .max(
            (f1, f2) -> Long.compare(f1.lastModified(),
                f2.lastModified()));

// if you're interested in folders...
Optional<File> mostRecentFolder =
    Arrays
        .stream(parentFolder.toFile().listFiles())
        .filter(f -> f.isDirectory())
        .max(
            (f1, f2) -> Long.compare(f1.lastModified(),
                f2.lastModified()));

A simple script to delete multiple keys from redis all at once

When developing, you sometimes want to delete a bunch of redis keys all at once. The KEYS command gets half of the job done, but what’s missing is a convenient way to wire it to the DEL command.

In these cases, (again, when developing, as the KEYS command is check-all-keys-in-database-slow) I often rely on this script:

#!/bin/bash
#
# A simple script to delete a bunch of keys from redis all at once.
#
# Don't use it in production!!!1!1!one

read -p "redis port to connect to? [6379] " redis_port

if [[ "${redis_port}" == "" ]]; then
    redis_port="6379"
fi

if [[ ${redis_port} =~ ^[0-9]+$ ]]; then
    while true; do
        read -p "keys to delete (wildcard accepted, e.g. user:foo:bar:*): " pattern
        # read all keys into a white space separated array
        IFS=$'\r\n' GLOBIGNORE='*' :; matches=($(redis-cli --raw -p ${redis_port} keys "${pattern}"))

        # list all matches
        echo "Matching keys:"
        matching_keys=0
        for line in ${matches[@]}; do
            echo $line
            matching_keys=$((matching_keys+1))
        done

        if [[ "${matching_keys}" -eq 0 ]]; then
            echo "No keys match your query, nothing to do."
        else
            read -p "Keys that will be deleted: ${matching_keys}. Really delete? [y/N] " confirm
            case ${confirm} in
                [yY]*)
                    echo -n "Keys deleted: "
                    redis-cli --raw -p ${redis_port} del "${matches[@]}"
                    ;;
            esac
        fi
    done
else
    echo 'must specify a valid port number'
    exit 1
fi

The nice thing about it is that it shows you what keys will be deleted before deleting them, so you have a chance of not screwing up your own DB! 🙂

Use it at will, but please, don’t use it in production!

Usage is straightforward, just chmod +x the script, and call it. Use Ctrl-C to exit the script.