Blog posts • Sep 10, 2014 08:28 GMT
The new Network feature on Mynewsdesk will introduce a lot of new ways you can manage a contact. For instance, adding social media profiles and links to each contact.
To keep the user input as easy as possible, we wanted people to basically just paste urls and then it would be parsed into social media profile objects it possible (we use some of them to fetch content from their API). Pasting links works well for social media profiles that aren't username heavy, like Facebook, but not for Twitter or Instagram, which is very username heavy, so the logical way to add a new profile for them would be to add a provider and username only.
We built this logic about a month prior to today, but needed it for two apps in our infrastructure, so we've been converting it and extending it to a gem, which we've published to rubygems today.
Here's how it works.
parser = SocialMediaParser.parse "https://www.facebook.com/teamcoco" => #<SocialMediaParser::SocialMedia::Facebook:0x007fe014ef0f78 @url="https://www.facebook.com/teamcoco"> parser.username => "teamcoco" parser.provider => "facebook" parser.url => "https://www.facebook.com/teamcoco"
If you instead want to construct a profile using provider and username options, you can use this
parser = SocialMediaParser.parse provider: "twitter", username: "fallontonight" => #<SocialMediaParser::SocialMedia::Twitter:0x007fe40ab08330 @provider="twitter", @username="fallontonight"> parser.url => "https://www.twitter.com/fallontonight"
When there's not enough input provided for SocialMediaParser to extract a valid profile, it will just return a Link object
parser = SocialMediaParser.parse url: "http://www.mynewsdesk.com" => #<SocialMediaParser::Link:0x007fe40ab9b770 @url="http://www.mynewsdesk.com"> parser.url => "http://www.mynewsdesk.com" parser.username => nil
That's it, really. We hope to find this useful to someone!
Parse social media attributes from url or construct url from attributes
Blog posts • Sep 01, 2014 07:20 GMT
This post is here to help you get started.
For this post, we are going to create a Todo Application, using vanilla JS so that we can test everything.
The final app demo is here : http://b2l.github.io/todo-app/html/todo.html
And the application code is here : https://github.com/b2l/todo-app
Before we get started, let's create the project directory and jump into it :
mkdir todo-app cd todo-app
This project is really basic, so we won’t set up any assets compilation.
We will just have an html entry point that will load any file we need.
We will use the following libraries to test the application :
- Mocha (test framework)
- ChaiJs (assertion library)
- selenium webdriver (from the selenium website: "Selenium automates browsers. That's it!")
Let's install them :
npm install -D mocha chai selenium-webdriver
Mocha provide a Command Line Interface that makes it easier to launch tests, so install it:
npm install -g mocha
Selenium work by having a java application that control the browser. You, as a client, connect to this web server and send it some command.
To use selenium, we need the selenium java server. Download it from here : selenium standalone server
We will need the path to the jar file you just downloaded.
Let’s create a structure for this.
mkdir html mkdir css mkdir js mkdir tests
Let's create our first test.
Our todo application will manage a list of todos. So we want to be able to :
- create a todo
- get a todo
- get all todos
- update a todo
- remove a todo
- mark a todo as done
- mark a todo as not done
Here is a part of our test file :
Before looking at the implementation, let's run the test :
Ok mocha complains that the file ../js/Todos.js doesn't exist. Let's create it now :
Run tests again :
And we are done !
The test workflow with selenium is as follow :
- Run the selenium server
- Create a client with options
- Execute command
Everything is a command, or an action, from asking selenium for a node matching a selector to clicking somewhere or closing the browser.
The first point can be achieved in different ways, either by a script which manages the server, or we can start / stop it from the test.
We will use the second option, here is the file to initialize the server :
I won't go through the todo-application implementation because it's not the point of this article.
If you want to follow this step by step, just copy the css, html and js directories. Run our application :
python -m SimpleHTTPServer
You can test your application here : http://localhost:8000/html/todo.html
Here is the interface test :
To run the interface test, we can use the same command as before :
Before we run the test: if you are a user of tmux (screen should have the same issue), please note that you will have to attach the selenium server to the user space as describe here : http://borkweb.com/story/chromedriver-doesnt-run-in-tmux
You can see a chrome browser starting in background and interacting with our application. Awesome !
There you are ! We have extracted and tested the domain part of the application (the Todos model) and we have test that the interface work properly too. You now have a small setup for testing your frontend application.
Blog posts • Jun 13, 2013 12:33 GMT
Sometimes when working with Rails objects with relationships in memory, strange things can happen. You can edit the attribute of some object and when accessing it using a relationship, the changes will be gone. It has to do with in-memory objects and how ActiveRecord handles them. But there is a way to make sure you always work with the same object.
inverse_of is a Rails relationship option that will optimize object loading and can be really helpful when you're working with object in memory a lot. It's not very well documented, so I thought I'd write a small blog post about it.
The setup:Setup gist
If I were to open up a console and add a Post with two Comments, I could then do this:
The last few lines does seem weird, doesn't it? I was banging my head quite a bit after discovering this. But here's
inverse_of to the rescue! Please note the pluralization of
comments, it maps to how the inversed relationship will be used.
inverse_of will trigger ActiveRecord to optimize object handling. In other words, it will use the same in-memory object when it's the same object and accessing it the way the inverse_of relationship has been configued.
It has a few limitations and you can read some more about it in the Ruby on Rails documentation.
Blog posts • Mar 04, 2013 15:31 GMT
A few weeks ago Github released Boxen, a “tool for automating and managing Macs at GitHub”. At Mynewsdesk, with more than ten developers and a handful of projects, we can see the need for this kind of software. When summed up, many days have been spent trying to get developer laptops back in a working state for one reason or the other. We also had a lot of smart configurations, custom hacks, different versions of databases, sometimes shared with some collegues but without a central repository of collaboration for this kind of configurations.
At Mynewsdesk we’re using Chef for setting up and configuring our server environment. Boxen didn’t feel like a perfect fit for us, since it’s based on Puppet. Puppet and Chef are the two main competitors in this area of operating system configuration management.
To solve this we’re now presenting Chefup. The pipe dream of Chefup (and Boxen) is to be able to install a full developer machine with a single command. But more than that it also provides a way of keeping the machine in a working state, with all key components fully documented. As a bonus this can all be done without running sudo and wreak havoc with your system. Some cookbooks may themselves run
sudo though, such as
Firstly, this is still beta software! Please make a backup of your machine before running it and be prepared for massive losses of data, corrupted files and possibly the plague. Report any bugs to The Chefup Issue Tracker.
- To begin with, clone our open source project from Github;
git clone git://github.com/mynewsdesk/chefup.git
If you still don’t have git installed you may want to
That will get you a version without the
.gitdirectory but you can make a proper clone later on, when you have access to git.
- To be able to compile you also need to install XCode from App Store.You’ll need to agree to the license by running;
- Now create a
Cheffile. That’s a list of external Chef cookbooks to be installed.
cp Cheffile.example Cheffile
If you work at Mynewsdesk and have access to our private repos you may uncomment the
chef-mynewsdeskrepo to setup our apps.
- After this you want to decide exactly what Chefup will install for you. This is done in the
node.jsonfile. An example is provided for you so you want to begin with copying it.
cp node.json.example node.json
Now have a look at that file. In the header you enter your personal data in form of name and email. Then you choose where you want to keep your code, where the default is
After that have a look at the run list. That’s a list of packages, or cookbooks in Chef terminology.
- Now, logged in as your normal user, run;
This will install the
dmgcookbooks and any cookbooks listed in the run list in
node.json. If you have
chefup-binin your run list you will have chefup in your $PATH after the first run, so it will be enough to just run
Any backups of overwritten files are kept in
tmp/backup. Any installed apps (with an .app suffix) will be installed in
~/Applicationsto avoid needing root permissions.
Living with Chefup
After the installation it is safe and even encouraged to run
chefupas often as you want. It will then overwrite any changes you made to the Chefup controlled files. Therefore, if you install for example the bash cookbook you will not want to edit
~/.bashrcmanually any more. Custom changes will instead be put in
~/.rc.d/. More information may be found in the
README.mdof the respective cookbooks under
site-cookbooks, such as
If you miss something, feel free to add a cookbook. Either as a new git repo and adding it to
Cheffile. It will then be installed to
cookbooks in the next run. Or by cloning the chefup-repo, adding cookbooks to
site-cookbooks. Then please feel free to send a pull request to have it added to the official repo, if it could be of use to others.
Blog posts • May 31, 2012 08:56 GMT
We have two lab days per month here at Mynewsdesk and one thing that never seems to stop receiving love is our chatbot Flower (for the Flowdock service). To keep the tradition alive I have now added a new command to the bot: The Steve Jobs boom command!
!boom in the chat and the bot will play a random clip of when Steve Jobs says boom through the office speakers.
Blog posts • May 29, 2012 09:32 GMT
At Mynewsdesk we develop Ruby on Rails applications and the developers may use any text editor they like. This has led to a myriad of different editors in use, from Textmate and Sublime Text to Emacs and Vim. Personally I prefer the Vim editor and have been a user since 15+ years.
There are many ways to approach and learn Vim but surprisingly few tutorials have a closer look at the main concepts of Vim. I think understanding these takes away some of the confusion when using the editor.
Vim has six basic modes; normal, visual, select, insert, command-line and ex-mode. These are basically different states of the editor and a basic cause of confusion for many users.
When starting up the editor it’s in normal mode, which means that most unmodified keys execute a command, rather than inputting text as in most other editors. This makes sense, since most of the time in an editor you don’t really enter text, rather you navigating, moving, changing and searching text.
To enter text you have to enter the insert mode, to select text you enter visual mode etc. There are also six more additional modes which are variations of the basic modes. Read more about the modes by typing :help vim-modes.
There are a bunch of registers, which could be compared to temporary variables in a programming language. All the registers has a one character long name and to use them you prefix them with a double quotation mark, such as "- or "x.
Some of these registers are updated by Vim itself, such as "/ that contain the last search and other are user updatable, such as "a to "z. You may also use these by prefixing a command in normal mode with a register, such as "/p for outputting last search or "ayy for copying current line into the a-register.
Read more about the registers by typing :help registers.
Buffers and Windows
A buffer is a file loaded into the memory of the editor. This would not be of big use without a way to actually view and edit it, and that is done in a window. There is not a 1:1 relationship between them though, a buffer may have one or more windows attached to it (called an active buffer) or no window at all (a hidden buffer), and a window may be with or without a buffer.
When started Vim shows one window but they may be split vertically or horizontally into more windows. You may then move around between them or move around the windows, resize them, open different buffers in them etc. There are ways to run commands in all open buffers, to hide them, remove them from the buffer list, unload them from memory and more.
The buffers may be listed with the command :buffers and you may read more about them and windows by typing :help buffers.
A quite recent addition to Vim is tabpages, added in Vim 7. A tabpage is a collection of one or more windows. This is a nice way to open a buffer, without changing the current window setup. It may for example be used when temporarily opening up another project with another set of files.
It may cause some confusion that the window splits lives in the the tab, rather than each split having its own set of tabs as in some other editors, but used as mentioned above it’s one of the strengths of Vim tabpages.
Read more about the modes by typing :help tabpage.
This has touched some of the basic concepts that are most commonly used. There are also a bunch of other really useful ones, such as folds, quickfixes, undo branches, text objects and tags. These and much more is described in the Vim help, please go ahead and navigate it with the :help command.
Blog posts • May 23, 2012 12:55 GMT
Writing correct, nice and to-the-point commit messages is not always easy. Sometimes when we have a lot of changes to commit, it's easy to write some nonsence just to have it commited and pushed before clocking out at the end of the day. Or sometimes we're just being a bit lazy or unimaginative.
Like these ones.
- fix for site fuckup (Jun 10, 2011)
- added old css (Nov 9, 2011)
- Fixed weird issue with subdomains (Oct 20, 2011)
A good commit message can sometimes save us the time of having to read the code or do a git bisect to understand where a bug might have originated. If done properly over a period of time, the red thread of the features also becomes apparent.
And then there are some that are just weird.
- ooooo, this HURT! (Feb 7, 2011)
- Always write about what the code changes, not what you have done (e.g. never start with "Added ...")
- Always write in present
- Capitalize the first row, without periods, and try not to exceed 50 characters (I'm not a nazi on this)
- Don't be hesitant to add an explanation as to why the changes have been made (on the third row, leaving the second blank). In fact, if you're thinking about it, that's probably a good sign that you need to do it.
Here are some of my personal Mynewsdesk Hall of Fame commits:
- don't negate, that is a negation (Nov 2, 2011)
- undefined fucking method (Jan 19, 2012)
- Pizza! (Dec 15, 2011)
Update: As requested by @patrikstenmark, here's a few examples of good commit messages:
- Acceptance test for access signup process (May 21, 2012)
In this commit, we added a capybara acceptance spec file with two tests. There wasn't any need to write that we added it, there hardly ever is.
- Kundo iframe needs transparency attribute in IE (March 29, 2012)
We use iframe based Kundo for support to our customers on top of a div with a background image. We added an attribute to the iframe to allow it to be transparent in IE. Being such a small change, we simply wrote why the change was made.
- Refactor weekly recipients to dashboard email to own class (May 7, 2012)
A refactoring commit that broke out some logic for our weekly summary email into its own module. Small commit message that is to-the-point and no messing about.
Writing correct, nice and to-the-point commit messages is not always easy. Here's my take on it.
About Mynewsdesk Devcorner
Get to know whats happening in the development team of Mynewsdesk