There’s a feature in vim of editing files over scp, built in since vim 7.1 (originially the now baked in netrw plugin).
This feature uses scp to copy a local version of the remote file over scp, edit it with vim, and with each save connect via scp and save it to the remote location.
This allows you to edit remote files with your own tailored vim instance (plugin galore!).
The problem is the connection is not reused, and it’s really slow when vim (scp) connects for each write.
To solve that, save this script and chmod a+x it..
This Saturday (8th of December, 2012), was the second Global Coderetreat, and I was amongst the lucky ones to participate from Tel Aviv.
The event was epic, 30-ish geeks pairing up to 45 minutes of hacking sessions on Conway’s Game Of Life.
And that was just in Tel Aviv, about 3500 people worldwide took part in this Geekathon.
The last session I teamed up with Roy Rothenberg and Pablo Klijnjan (Yes that last name is in Klingon), both my day to day teammates at work.
We had this idea of making a Telnet version of Game Of Life, inspired by the Telnet Nyan Cat ( telnet miku.acm.uiuc.edu ).
We hacked together a working Python version in that session, that I thought would be hilarous if it was available online.
We used a very simply Telnet server using Python’s socket module and most of the time was spent understanding how the f#!@#k to clear the screen:
Clear telnet screen, works for console as well
1
self.conn.send(chr(27)+"[2J")#chr(27) == <ESC>
The problem with the Python version we hacked together was that if you connected more than one Telnet client, it would crash.
During the session we looked at using Twisted to improve the Telnet server, but we had a crappy connection and it took ages for it to download.
Yesterday when I looked at improving the code to make it available online (yes I didn’t delete that sessions’ code :$), I had a look at some Twisted Telnet implementations, but the code was to Twisted for me.
Reactor this, Factory that. No thanks.
So, I decided to hipster up and try it in nodejs, initially setting a 45 minute target as one of the sessions we did at Coderetreat.
Getting up the Telnet server was easy, a quick npm search telnet found me wez-telnet.
Writing the coffeescript version of The Game Of Life took me most of the time.
I used Mocha as testing framework, which is very smooth.
Writing the game and telnet server took me about 55 minutes (while multitasking other stuff).
I tested the Telnet server by connecting from 10 clients from different machines in our network, seem to not even flicker.
When I connected via ConnectBot on my Android, it crashed the server.
So, before putting it up online, I needed some kind of daemon that restarts the server if (when) it crashes.
This was easy with forever.
Here’s the entire package.json with the scripts for testing, testing continuously, starting and stopping daemon:
After installing Ubuntu 12.10, I got annoyed by the amount of unneeded software installed, especially the commercial lenses, offering me to buy something for every program I want to launch.
I tried Unity for about two weeks, until I decided I have to change to something else.
I used Gnome 3 with Fedora for a while before, and I really like the native multiscreen support available, that allows you to have a second monitor that doesn’t change when you switch workspace.
I missed the diagonal workspace switches from Gnome 2 (and Unity), but it was a pleasant desktop.
About two monts ago I noticed the Ubuntu Minimal CD, which is a bare boned text only installation, which is similar to the Ubuntu Server installation, just with less packages.
I decided I’d try to “Arch”-up a bare boned Ubuntu installation with the Mini CD, using Gnome 3 as desktop.
Installing it is a breeze, after some next next wizard that’s to similar to the Ubuntu server to write about, I had a text based distro up and running.
One small caveat though, defining Wifi during the installation sucks, do install it while plugged in to an ethernet connection..
Before installing the GUI, I enabled the Gnome 3 PPA, to be up to date with the latest Gnome 3.6 packages held back by Ubuntu:
Then you need to edit /etc/network/interfaces and disable your eth0 connection (Will be managed by Gnome Network), just remember NOT to restart the networking service..
Install the following to get Gnome 3 up and running:
Installing Gnome 3 Components
123
sudo apt-get install -y gnome-shell gnome-network-admin gnome-terminal \gnome-alsamixer gnome-bluetooth gnome-tweak-tool network-manager-gnome \file-roller #add your stuff here like git tmux vim-gnome..
And you’re good to go, with a snappy non bloated desktop available.
If you want some extra default apps, you can add --install-suggests to the apt-get command, but it’s not needed.
Github notifications are great, but if you are a part of any organization,
it quickly get’s overrun with repositories that you aren’t necessarly active with’s notifications, making it hard to filter the important bug reports on you own repos.
To unsubscribe to all repositories in an organization, open up your watching page (Login first of course).
Copy the gist below and replace THEORG with the organization you wish to unwatch it’s repositories.
Run it, and you’re not watching any more repositories from that organization.
Live Reload is an awesome Mac app and browser extension which reloads your browser automagically when editing a file.
Needless to save, it’s a bliss, never to {CMD,ctrl} + R again.
For those of us who are Mac less, the App is of course not available.
Ruby to the rescue!
Let’s say you have these classes in a python file:
And you want to write some simple unit tests for them, typically you’d do something like this:
running them with nosetests -v will get you the following result:
nosetests -v test_components_verbose
12345678910
user@host:gist-3731389|‹master› ⇒ nosetests -v test_components_verbose.pyTest that initialized is set. ... okTest A class constructor set something. ... okTest that initialized is set. ... okTest B class constructor sets something. ... ok----------------------------------------------------------------------Ran 4 tests in 0.001sOK
Although that might seem ok, there’s some code duplication here that is really annnoying.
If ClassA where to inherit ClassB this would seem even more over verbose..
So, how’d you typically approach a problem like this in any OOP environment?
But of course, inheritance..
Say that we create a base test class, and let TestA and TestB inherit that class, wouldn’t that be cool?
base_test_class.py
12345678910111213141516171819202122
fromunittestimportTestCaseclassBaseTestClass(TestCase):""" Base test class for the two components. """component=Nonedeftest_something(self):""" Test a component constructor sets something. """comp=self.component()self.assertTrue(hasattr(comp,"something"))deftest_initialized(self):""" Test that initialized is set. """comp=self.component()self.assertEquals(comp.initialized,True)
test_components.py
12345678910111213
frombase_test_classimportBaseTestClassfromcomponentsimportAClass,BClassclassTestA(BaseTestClass):""" Test the A class. """component=AClassclassTestB(BaseTestClass):""" Test the B class. """component=BClass
Running nosetest -v now should work right?
nosetests -v test_components
12345678910111213141516171819202122232425262728
user@host:gist-3731389|‹master› ⇒ nosetests test_components -vBaseTestClass : Test that initialized is set. ... ERRORtest_something (test_components.BaseTestClass) ... ERRORTest that initialized is set. ... okTest a component constructor sets something. ... okTest that initialized is set. ... okTest a components constructor sets something. ... ok======================================================================ERROR: BaseTestClass : Test that initialized is set.----------------------------------------------------------------------Traceback (most recent call last): File "/media/data/Code/Tests/gist-3731389/base_test_class.py", line 37, in test_initializedcomp=self.component()TypeError:'NoneType'objectisnotcallable ====================================================================== ERROR: test_something (test_components.BaseTestClass) ---------------------------------------------------------------------- Traceback (most recent call last): File "/media/data/Code/Tests/gist-3731389/base_test_class.py", line 30, in test_something comp = self.component() TypeError: 'NoneType' object is not callable ---------------------------------------------------------------------- Ran 6 tests in 0.001s FAILED (errors=2)
OY VEI!
So what happened here?
Since the base class and the test classes (in the end) inherits unittest.TestCase, and BaseTestClass was importerted to test_components.py, they’re run automagically by nose.
Have no fear, we’re in the magic unicorn world of python, there’s a magic property that fixes this:
base_test_class.py
123456789101112
fromunittestimportTestCaseclassBaseTestClass(TestCase):""" Base test class for the two components. """__test__=False#important, makes sure tests are not run on base classcomponent=None...#rest of file
Note that you need to explicitly set __test__ to True in the child classes.
Running nosetests -v test_components again should yield the following result:
nosetests -v test_componets“`
12345678910
user@host:gist-3731389|‹master› ⇒ nosetests test_components -vTest that initialized is set. ... okTest a component constructor sets something. ... okTest that initialized is set. ... okTest a component constructor sets something. ... ok----------------------------------------------------------------------Ran 4 tests in 0.001sOK
Ok, works, but still, there’s something bothering in the log output.
How can you tell which component where tested?
It’s a bit unverbose-ish..
Adding a bit more python magic and voila :
Running nosetests -v now shows the following stunning (!) result:
nosetests -v test_components
12345678910
user@host:gist-3731389|‹master› ⇒ nosetests test_components -vTestA : Test that initialized is set. ... okTestA : Test AClass constructor sets something. ... okTestB : Test that initialized is set. ... okTestB : Test BClass constructor sets something. ... ok----------------------------------------------------------------------Ran 4 tests in 0.001sOK
w00t!
So what have we got here?
We’ve overridden shortDescription and prefixed with the current class which is running.
We’ve even added a possibility to add the component name in the docstring for string formatting, which might be just a little bit too much if you want to make a generic base class..
A little more than a year ago, I started working at XIV (IBM).
The change was rather dramatic in terms of technologies that I work with.
I went from being a .NET web developer to a python developer, dealing with a lot if IT and system.
Furthermore, I stopped working on a Mac (this is do miss), and have almost not touched windows for the entire year (which I haven’t missed at all).
The workstation (laptop) I have is running Linux, I started with Ubuntu 10.10, and was with Ubuntu up until 12.04 when I switched to Fedora (17).
My day to day work is usually in a fullscreen terminal, vim’ing away, pimped with tmux of course.
I’ve had problems with XOrg, some stuff hanged and other “typical” Linux issues you hear of, but whatever I needed was usually a package away, and in worse case, a compilation away.
I’ve always liked “the unix way” where you have a collection of tools, which each do their own thing awesome, and can interact with any other tool doing it’s own special thing.
I could never have imaging what a powerful toolset this brings. I’ve been more efficient with simple bash scripts than with writing entire .NET programs.
To summarize, I feel that my efficience has improved vastly, and that I can’t really imagine working in a non nix environment.
Wouldn’t complain if I were on a Mac of course ;)
So what are you waiting for? Start vim’ing on a nix machine ASAP! And don’t forget to use tmux!
It’s a great article which I highly recommend to read.
The part that specifically interested me was turning JSON into JSONP compatible calls, usable both for proxying remote / local apis that doesn’t supply JSONP functionality and for simple to padd local static JSON files.
What bothered me though was the fact that the name of the method to pad into the JSON response was hard coded.
When you use jQuery to do an ajax request, you add ?callback=? to your url, which will be replaced by a random function name, E.g: callback=jQuery123123.
To achieve the same with nginx, I modified the snippet:
Modified to handle callback variable
12345678
location/json/{#can be any location of courseif($arg_callback){echo_before_body'$arg_callback(';echo_after_body');';}#proxy or remote heretry_files$uri$uri//index.html;}
Now if we take a simple JSON file:
Sample JSON
1234
{"aa":"bb","cc":123}
And call nginx to fetch it via the location we configured in the snippet above, with the url http://server.com/json/sample.json?callback=Ahoy we’d get:
If you use your unix mail spool/box with any type of fetchmail (ahem fetchnotes), on rare occasions, the mail box might be corrupted, typically missing a single starting character.
Thunderbird will fail miserably without any explanations, and Mutt will complain that the mailbox is invalid.
Open the mailbox (/var/mail/$USER usually) in your favorite editor (vim of course), and have a look at the beginning of the file:
It should start like this:
12345678910
From username Sun Jul 8 11:30:04 2012
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=UTF-8
From: "" <some@mail.com>
To: "My Name" <my@mail.com>
Subject: =?UTF-8?Q?Some Title?=
Date: Sun, 8 Jul 2012 14:28:32 +0300 (IDT)
Message-ID: <462381293.437.1341746912677.mail.user@host>
MIME-Version: 1.0
... (Rest of mail)
If your mail file is corrupted, you’ll see that it simply lacks the first “F” character:
12345678910
rom username Sun Jul 8 11:30:04 2012
Content-Transfer-Encoding: 7bit
Content-Type: text/plain; charset=UTF-8
From: "" <some@mail.com>
To: "My Name" <my@mail.com>
Subject: =?UTF-8?Q?Some Title?=
Date: Sun, 8 Jul 2012 14:28:32 +0300 (IDT)
Message-ID: <462381293.437.1341746912677.mail.user@host>
MIME-Version: 1.0
... (Rest of mail)
Add that “F” character and Thunderbird won’t fail, and mutt will load.
A silly problem with an even more dumber solution.