Resizing images before upload

An article, posted 28 days ago filed in , , , & .

The resolution of photo's increases every year. And while some of that information may be worthy of retaining, not all is. High resolution images come at a price. Not only storage, but, especially in a mobile context, also data transfer. In this post I explain how you could create an uploader that fixes this.

The old form

Traditionally your form would look something like this:

`
  Upload image:
  
  
`

If you want to be forgiving to your end users (and not requiring them to manually resize the images themselves) you could configure your server to accept files > 20MB and resize the images server side.

However, to save bandwidth you you might want to resize the images just before uploading.

Enter canvas

To manipulate pixels we need a canvas. So we need a canvas element.

Note: Canvas support is barely an issue, but if things don’t work we’ll write to code as such that the traditional form submit will continue to work

...

Continue reading...

A developer’s status update: Test driven deadlock

An article, posted about 2 months ago filed in , , , , , , , , , & .

No worries, I do value testing. But test driven? It depends.

The last few weeks I’ve been working off and on building a crawler. The thing triggers a series of scheduled tasks that could run in parallel, generating (possibly) tasks (that are consequently scheduled again in their own task-specific queue) on its own and so on. The end goal is structured copies of external resources (read: webpages). But I’ve been stuck close to the start for quite a while, setting up the base architecture using the test driven development approach. And I’m failing, it’s going too slow :(

Small victories

Like many developers, this is not my first parser/crawler. But this time I wanted to make a GoodParser™. Make it more extensible, and flexible and foremost robust, building in fault-tolerance from start. But I’m not getting near the end result and it is frustrating.

The TDD-school says make small victories, and oh yes, I had my sheer number of victories already. But the end is nowher…

Continue reading...

Eat your own dogfood

An article, posted 2 months ago filed in , , , & .

Just a small note that I've made some improvements to my SocialLinker-gem lately and while I've been using it on a few sites already, I wasn't using it on my very own blog. Today I found some time to change exactly that: you've got to eat your own dog food. If you want to have a taste of it: murb/social_linker (if you're a ruby-dev) or just click the share icons below :)

Image CC-licensed BY: Sh4rp_i

Continue reading...

Should I use React or Angular?

An article, posted 3 months ago filed in , , , , , & .

To put it in some context: these days recruiters call you whether you know this or that framework. Well not really, really well. But it is just JavaScript. Or ECMAScript (or a flavour of it by Microsoft called TypeScript). But above all it is just a tool to get stuff done. Not every job needs a bulldozer. And besides the bulldozers React and Angular there is Vue.js and plenty more. Choose your tools wisely.

Continue reading...

Twitter launches a new web app

An article, posted 3 months ago filed in , , , , , , , , , & .

Targeted at those with low spec phones, Twitter today launched Twitter Lite, a product build on a modern suite of technologies that should be ring a bell with most front-enders today.

The new Twitter frontend is built using React (nb. made by Facebook), Redux, Normalizr, Globalize, Babel, Webpack, Jest, WebdriverIO, and Yarn (they have written about how they built it.

It is a good thing to see a large company not giving up on the open web. I’ve added the new Twitter Lite app to my phone (running iOS) and see if it can replace the native app (as I did with Facebook before). My first impression is pretty good. Most importantly, as promised: it loads faster, even without support for ServiceWorkers (while iOS 1.0 only allowed for web apps, its level of support is kind of bleak when compared to the efforts made by Google and Firefox). It could use some animation …

Continue reading...

Internet Explorer End Of Life

An article, posted 3 months ago filed in , & .

A short note (to myself), because the information is shattered:

Internet Explorer 11 is the only version of Internet Explorer to be supported after April 11th this year. Until then IE9 might still be running supported on machines on Microsoft Extended Support program.

The facts:

Should we worry?

According to the Wikipedia usage stats, IE11 (the latest version) is actually the most used version of Internet Explorer (repr…

Continue reading...

Schatten in een Agile wereld

An article, posted 3 months ago filed in , , & .

Inschatten wat de kosten moeten zijn is lastig. Vaak wijzen mensen in een agile omgeving op de driehoek Scope, Resources en Schedule. Je kunt niet Scope (wat je bouwt), Resources (wat je ervoor nodig hebt) én Schedule (de planning) vastzetten. Wanneer je Scope en Schedule vastzet kun je er wellicht extra geld tegenaan gooien. Op eenzelfde manier kan er ook voor gekozen worden om juist de planning los te laten en/of de scope. Alle drie zaken zeker en vast gaat niet. Maar toch, we willen een idee: wat gaat het kosten en wanneer is ‘het’ (het geplande) af?

Planningspoker

Scrummers doen hun schattingen met het spelen van planningspoker. Deelnemers aan een planningssessie werpen kaarten op tafel waarmee ze uitdrukking geven aan hoe zwaar ze een taak achtten t.o.v. een referentietaak met kaarten die genummerd zijn volgens de Fibonacci(-achtige) reeks. De grotere getallen liggen verder uit elkaar en geven daarbij ook uitdrukking aan een grotere mate van onzekerheid.

Je ku…

Continue reading...

PostgreSQL CSV import

An article, posted 4 months ago filed in , , & .

Since I always forget (database management isn't my day-job): a short guide on how to quickly import large datasets in TXT or CSV into PostgreSQL. For smaller sets I still use ruby and FasterCSV to import the set, but nothing beats native DB imports in terms of speed. And speed doesn't matter when importing a few megabytes of data, but it certainly matters when it gets more than that.

In this example I'll use my current use-case, importing a large Drive-Time Matrix table, with drive times and distances between two postal codes. The head of the TXT file is formatted as such:

"Frompc4","Topc4","Time","Distance"
"1011","1011",0,0
"1011","1012",6,1737
"1011","1013",9,3378
"1011","1014",13,6056
"1011","1015",10,3198
"1011","1016",10,3112
"1011","1017",6,1706
"1011","1018",5,1791
"1011","1019",7,3146

Now let's assume we want to import this in a table 'DTM' with the following columns: from_pc (integer), to_pc (integer), time (in…

Continue reading...

Technische schuld

An article, posted 5 months ago filed in , , , , , , & .

De software wereld zit vol met Engelse begrippen. “Technical Debt” is ook zo’n begrip. Maar wat is het?

Een dag geleden zag ik dit bericht waarin Technical Debt werd vergeleken met een continue slecht gestapeld Tetris spel. Een rake vergelijking: als je niet oppast wordt de technische structuur van een applicatie een stapeling op zichzelf oplosbare problemen, maar vormt het in z’n geheel een nagenoeg niet te redden constructie.

Maar waar hebben we het dan over?

Technische schuld wijkt af van financiële schuld. Om financiële schuld te maken moet je geld lenen van een ander. Technische schuld ontstaat doordat er geen tijd wordt gestoken in het goed op orde maken van de techniek. Zo is het een goede gewoonte om kritische zaken en/of zaken die erg foutgevoelig zijn in de applicatie te voorzien van automatische tests (“kan die rol wel/niet bij die gegevens?”, “gaat het ook goed als hier een negatief getal …

Continue reading...

Phoenix’ Channels

An article, posted 6 months ago filed in , , , , , , , , , , & .

I started exploring Phoenix for one thing only: Channels (or actually fast real time communication over websockets). In this post I explore how to use them (yes this is a follow up of My first Phoenix-app-post).

Preparing for the authentication problem

Websockets don’t pass session cookies. Because we don't have access to these we need to transfer the user's identity in a different way. One of the recommendations I found was passing a user_token using a ``-tag (adjusting templates/layout/app.html.eex):

We can access this with a simple query selector in javascript:

document.querySelector("meta[name=user_token]").content

But that’s for later. Let’s move to the server side, since we need something to connect to, a Socket.

Socket

In our default project there is alrea…

Continue reading...

My first Phoenix app

An article, posted 6 months ago filed in , , , , , , , , & .

Some time ago I actually initiated my very first Phoenix app, but was a bit disappointed by the lack of a rich box of gems (like that of ruby's) and/or I didn't have the time to invest heavily in researching all the possibilities. One of my new year resolution was to actively pursue more knowledge, hence I'm giving it a second shot.

Why Phoenix?

I'm a full-stack Rails developer, but I needed real time messaging. That is not something Rails is typically good at (although it works), but Elixir (with its Erlang base) is well known for, even in the ruby community. Phoenix wraps Elixir in a nice Rails-like package ready for web and API development.

Requirements

  • Authentication
  • Broadcasting filtered messages based on tags
  • Writing messages

Preparation

  1. Install Elixir (macOS & homebrew: brew install elixir) and make sure you have [node.js](https://nodejs.or…

Continue reading...

Op meer kennis!

An article, posted 6 months ago filed in , , , , , , & .

Dit is er weer één in de serie van murb’s nieuwjaarsredes ;)

Als ik aan de toekomst denk, overkomt mij een vreemd soort gevoel. Enerzijds gaat het mij goed af. Ik heb de allerliefste vriendin en beschik over tal van mogelijkheden en vrijheden. Anderzijds voelt het alsof het nog even flink fout zal gaan. Al lijken de prognoses allemaal weer de gunstige kant op te gaan, er hangt een zweem van onzekerheid over.

Want is deze economische opleving niet allemaal gebaseerd op die kwantitatieve versoepeling waardoor er veel goedkoop geld beschikbaar is gekomen voor banken om uit te lenen? Die extreem lage rente die de huizenprijzen weer tot recordhoogtes heeft doen laten stijgen (en zo de huizenbezitters weer (voor nu?) uit het slop trekt (en het ‘logisch’ maakt dat de huren navenant stijgen))? En hoe gaat dat straks als ook Europa wordt geregeerd door rechts-extremisten, zoals Geert Wilders en Le Pen? Wordt er dan nog wel werk gemaakt van e…

Continue reading...

Facebook is the sender

An article, posted 7 months ago filed in , , , , , , , , & .

TLDR; Without the control and true freedom of speech we should regard Facebook as nothing but a attention draining casino made for people with fear of missing out. Equally so, we should consider it as an active sender as it actively modifies what is being said and consumed. And hold it responsible as such.

Probably most of us have felt fear of missing out. So we try too keep up with too many sources of information and entertainment. Facebook et al. promise to help us by filtering information. It is well described in for example the Facebook guidelines of how their newsfeed algorithm is supposed to function.

The filtering one gets is based on the behaviours of others. It is based on the often correct premise that the more people agree that something is 'worth sharing' or ‘worth interacting with’ makes it more 'worth showing’. Especially amongst ‘like-minded’ (actually: l…

Continue reading...

ActionCable and authentication with Devise (2/2)

An article, posted 9 months ago filed in , , , , , , & .

This is a short follow up on the previous article in which the ActionCable basics were explained. We can now add some level of authentication. Authentication is a bit harder than simply registering some before_action’s, but it is perfectly doable, especially if you've survived the previous tutorial.

From the official Action Cable guide we can simply reuse the full connection.rb template:

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user
 
    def connect
      self.current_user = find_verified_user
    end
 
    protected
      def find_verified_user
        if current_user = User.find_by(id: cookies.signed[:user_id])
          current_...

Continue reading...

Getting started with Rails ActionCable (1/2)

An article, posted 9 months ago filed in , , , , , , & .

As the lead developer at HeerlijkZoeken.nl I wanted to try the new Rails ActionCable technology for a new feature: shopping lists. The idea is that you can walk in a store or on a market, mark an ingredient as checked when you add it to your (physical) basket and continue shopping. ActionCable can make the experience nicer because it, based on WebSockets, allows for real time notifying other viewers and editors of the same shopping list. No more shouting around in the supermarket: I’ve got the milk! Sure, nothing essential, but I needed an excuse ;)

(Note that we recently migrated from Rails 4, so not everything was in place in our app, just ignore the bits Rails already made for you; everything has been tested with Rails 5.0.0.1)

Getting the basics right

To start: You need a web server that can open multiple threads, so if you’re still using Webrick in development (which can’t rece…

Continue reading...

murb blog