Excellent photos free to be reused

Looking for great photos for your next project or presentation? And you enjoy to be on the legal side of life? Check out this great websites with free stock photography!

Excellent quality: Pexels, Life of Pix, Stocksnap.io, Unsplash,
Gratisography (by Ryan McGuire).

Good quality: Cupcake.

Good, but…
A bit complicated to browse: Negative Space, Great shots food, but the licensing is not exactly clear: Foodies Feed.

And it’s all free to use via the Creative Commons Zero license (aka CC0). Even for commercial projects… and if you need even without attribution. Great stuff – truely free. 🙂

Sources: Slideshare blog and others.

Copying MongoDB from meteor.com

I started deploying my latest Meteor app umeedoo.net to my own VPS and wanted to use the data from my beta system hosted at umeedoo.meteor.com.
First of all, I was surprised how simple and easy it was to deploy using Meteor Up (MUP). Some weeks before, I spend an entire day on installing the Meteor environment on a Debian machine – now it’s less than 15 minutes! One caveat though, it did not work for me on Debian, I had to drop my previous Debian VM and replaced it with Ubuntu as MUP depends on Upstart and it seems rather tricky to replace Debian’s SysVinit with Upstart. Ok, different story, but a biiig thanks to Arunoda for the great work on MUP!!

So, how to db.copyDatabase(); the data from the original DB to yours?

The method signature is db.copyDatabase("[app-name]_meteor_com", "[your-db-name]", "[meteor-mongo-domain]", "[username]", "[password]");
I’ll assume “app” to be the app name for simplicity.
General approach: get the MongoDB URL, extract all the parameters above, log into your own MongoDB installation and use db.CopyDatabase(); to move the data over.

All commands need to be executed on the same machine. (FYI, the username and password get automatically generated and it did not work to get the URL on my machine and use the username and password on the server… strange though)
Thus, install Meteor on your server curl https://install.meteor.com/ | sh.
Then, get the MongoDB URL meteor mongo --url app.meteor.com
It will look like this mongodb://client-fd532e7d:683a9a4e-1604-5729-07fd-df1ba7dcbbf9@production-db-a2.meteor.io:27017/app_meteor_com
The parts are

  • username: client-fd532e7d
  • password: 683a9a4e-1604-5729-07fd-df1ba7dcbbf9
  • meteor-mongo-domain: production-db-a2.meteor.io:27017

Start a MongoDB CLI by typing mongo.
In my case, the database created by the app and MUP was called “admin” (i.e. [your-db-name]=”admin”). How to find yours? Use “show dbs” in the MongoDB CLI to see which one is yours.
Then write “use [your-db-name]” to switch to your DB.
And finally, using the data from above: db.copyDatabase("app_meteor_com", "admin", "production-db-a2.meteor.io:27017", "client-2fbeb6ef", "1bd44ece-b3fa-7d1b-0046-83b917927f35");
will copy the data over in a few seconds.
When I tried first, I got an error about a duplicate key (the deployed app had created some data already), dropping the entire DB fixed it. Also, the username and password are valid for a short time only, so maybe having to terminals open is a good idea.

References: Cloning MongoDB, Meteor dump, Clone DB from meteor.com, Copy DB from one server to another

Match.Optional for null

Securing my Meteor app, I came across a strange quirk of Match.Optional of the "check" package.
Example (in CoffeeScript)

Meteor.methods
  test: (x) -> check x, Match.Optional String

I expected the match to be successful when calling the method like this:

Meteor.call 'test', undefined

But instead, I got a "Match failed" exception. After debugging for a bit, it turned out that the undefined becomes a null when it arrives on the server.
Which is odd, of course—but also annoying as the check x, Match.Optional String fails for null (only undefined or String are acceptable).
To overcome this, here is a new Match.Optional that does the trick:

Match.OptionalOrNull = (pattern) -> Match.OneOf undefined, null, pattern

Also, I keep wondering: what’s the purpose of making Match.Optional fail on null in the first place?