Spendflow, an application I’ve been developing on and off over the past year, is now open-source. What is perhaps more interesting is that it’s a Meteor application developed in CoffeeScript. Although Meteor is gaining traction and nearing 1.0, there are still not that many published applications built in Meteor.
I hope Spendflow will be a good example of how to structure a Meteor application of its kind (or that community feedback will soon make it so).
I released another simple module on drupal.org the other day called Internationalization SSO. If you determine the site language from the domain used to access it, and you use different top-level domains (e.g. example.com, example.es, example.fr), this module makes life a little easier for you by logging users into all of the language sites when they log into any of them.
But even with novelty projects, there are things to be learned, and this project has exposed me to npm modules I probably otherwise never would have used. I’m going to go over a few of the architectural highlights (npm and not) in no particular order.
After you npm install lefnire, typing lefnire runs him.
If you said, “ASCII art?” you would be correct. This was a friend’s idea, and it’s become a staple of the application.
API integration with the superagent and github modules
Currently, lefnire.js is lightly integrated with the HabitRPG and GitHub APIs. The HabitRPG API integration uses straight superagent requests. The GitHub API calls use github.
When you say something containing “habit down,” he makes an API call to https://habitrpg.com/api/v1/status to check.
When you ask him by his IRC name (I’ll be getting to IRC stuff in a second), he queries the GitHub API to find out the number of issues labeled “critical” for HabitRPG on GitHub.
IRC integration with the node-irc module
What would an automaton be without being able to log on to IRC and interact? lefnire.js uses node-irc to accomplish this. The library is pretty robust and follows Node.js patterns well. This is a fantastic example of an application that thrives on asynchronous execution. When you ask him if “habit is down,” and it is, that thread of execution will block. However, it won’t stop the bot from responding, thanks to the event listener model implemented by node-irc.
Mood and the Sentimental module
Another interesting feature is a rudimentary implementation of mood, which is basically just a number between 0 and 30 (0’s the best). This doesn’t do too much yet. It affects his behavior a little bit. The number of GitHub criticals is the baseline metric.
This is then adjusted up or down by how positive or negative Sentimental analyzes the up to the 30 most recent GitHub Events from lefnire to be. This is mostly issue comments, pull requests comments, and commit messages.
When lefnire is in-channel, it also adjusts mood based on Sentimental text analysis of what he says.
No database yet, so everything except what I can retrieve again through API calls is lost if I ctrl-C the bot and stop it.
Those are the main highlights of the current implementation. A lot of things are planned. I doubt anyone would want to contribute to this, but I’d certainly be excited to receive some pull requests.
I just left a comment in the Field Collection issue queue and thought it’d be good to spread it more widely; maybe people need this fix.
For anyone still getting burned by this bug (or for that matter getting burned by using Node Clone on nodes with field collections), first apply my previous patch (or bderubinat’s, but I haven’t tested that one). That will stop further damage.
To repair your previous entries and ensure that, for example, removing a field collection entry doesn’t remove it from other nodes from which you didn’t want it removed, you can implement this script I’ve detailed in a gist: https://gist.github.com/wizonesolutions/5567549
It will give new item_ids to field collection items that it detects as appearing more than once. All my testing has indicated this is safe, but if not, please leave a comment on the gist. I hope this helps someone.
I released a new module for Drupal a couple days ago called Internationalization 404. This module helps you automatically use Content Translation-translated localized language versions of your 404, 403, and home pages.
Normally, you have to install Internationalization Variables (i18n_variable) and separately configure the options for these pages per-language. This module saves you time and automatically sends visitors to the correct page. Should you decide to use specific language versions with i18n_variable, this module will respect that configuration and not interfere.
All you have to do is enable the module for it to start working. No configuration required. Disable it to turn off the functionality.
The README file explains in good detail how to use it.
Come on, just tell me how to use it
OK, here’s the quick version (you need NPM installed, which you get with Node.js):
npm install -g habitrpg-todo-sync
It will tell you what to do from there.
You might be interested in running
to do a full synchronization of your tasks. By default, it only retrieves the last week of them.
Don’t synchronize everything
You may not want to get all your tasks. habitrpg-todo-sync can make use of Remember the Milk’s advanced search interface (ever tried typing something like addedWithin: 1 week ago in their search box?). Here’s how:
habitsync –filter=”list:Name of Your List”
You can do anything you can do with their interface.
And you can combine command-line options:
habitsync -a –filter=”list:Smart List You Want To Sync”
Run on a schedule
You can run it manually or add it to cron. I have this in my crontab, which runs it every hour against beta.habitrpg.com (which is often more likely to be working). To put it in yours, you generally run
If you haven’t been following any of the calendars listing DrupalCamps, you may have missed the arrangement that’s coming up in Gothenburg, Sweden in a couple weeks. This wouldn’t be surprising, since it’s being marketed in Swedish. People of all languages are welcome, however, so I thought I’d somewhat rehash the post I made in Norwegian.
The camp’s pitch is: “A one-day conference focused on the Drupal CMS. Come along and learn more about Drupal and the web, and have a great day in Gothenburg in late Spring.”
Sessions are here: http://summer2013.drupalcamp.se/program/sessions
As with most DrupalCamp sites, volunteer work lies behind the site you see. A lot of people contributed really great work. Fantastic designs and solid development resulted in the site you see today. I was also involved, mostly behind the scenes. I helped with server administration, Git coordination, transferring the site to another server, and mostly with coordinating the web team’s efforts. It was the first time I had spent as much time helping organize a DrupalCamp (and I’ve been to quite a few; I’ve even volunteered at a couple).
If you’re in Europe or in the area, I encourage you to check it out. You can follow them on Twitter at @DrupalGBG.
This morning I ran into an issue with my Vagrant upgrade (I went from 1.0.7 to 1.2.1) that took me a few hours to figure out. I did, however, solve it in the end and thought it’d be useful to share how. It’s an easy fix.
First, the error I was getting was:
The box ‘boxname’ could not be found.
(where boxname was the actual name of the box, e.g. precise32)
The box did show up when I ran vagrant box list, so I knew that it should have been working.
After trying an assortment of things, including converting my Vagrantfile configuration to the version 2 format and trying to use the box in a fresh directory and with a fresh Vagrantfile, I decided to try re-adding the precise32 box that Vagrant provides. I did that, and then typed vagrant init precise32d. (I had called it precise32d.) This worked fine. I deduced that there must have been some change in the box itself. So I fired up DiffMerge.
DiffMerge told me that there weren’t any files it could compare. This, I discovered, was because everything in the new box I had downloaded was under a virtualbox directory. A-ha! I was on to something. I looked in that directory and saw these files:
Vagrantfile box.ovf box-disk1.vmdk metadata.json
Wait, metadata.json? That wasn’t in my existing box’s folder at all! What could be in there, I wondered?
$ cat virtualbox/metadata.json
Ah. So it’s relying on this to figure out the provider, since Vagrant 1.1+ has the concept of providers other than VirtualBox. That explained a lot. The simplest fix is just as you may suppose:
To eliminate the potential for human error, we’ll use an existing metadata.json file. Run:
Recently, I used a tool that spoke of “forwarding” my SSH session to the server and thus avoiding needing to copy my private key to the server in order to be able to access Git repositories or other servers where I log in by public key.
If you manage your keys at all, you can immediately see the allure here.
The configuration is ridiculously easy. Put this in your $HOME/.ssh/config file* (Windows users, check PuTTY settings; it can probably do this too).
You can, of course, combine this with other options such as HostName and User.
I tested it with Fill PDF Service:
(The Git repository is password-protected, and my Git setup uses SSH for authentication by default.)
I got back: Already up to date.
I used to be prompted for my password, but that’s yesterday’s news…quite literally.
Extra tip: If no one else uses your computer, you can put ForwardAgent yes on its own line. This will forward your agent to all servers you connect to. I’m not an SSH expert, but as far as I know, ssh-agent is designed to be extremely secure. The main risk is if someone is using your computer directly, but that applies to most things. SSH Agent sessions are restricted to the current user session via environment variables (so no one can simply switch to you on a server to get access).
It blew me away how easy it is to get this going. 2013 is the year of SSH agent forwarding for me. Hope this helps!
* If the file doesn’t exist, create it. Make sure the permissions on the .ssh directory are 600 (drwx——).