Redirecting output from Fabric

August 16, 2011
Current (1.2.0) release of Fabric doesn't have any logging implemented, which means usual redirects like this one won't work:

$ fab dummy > outfile
...blabla...
IOError: [Errno 25] Inappropriate ioctl for device
Piping doesn't work either:

$ fab dummy | less
...blabla...
IOError: [Errno 22] Invalid argument
Current workaround is to pass pty=False to your function. Example:

def dummy():
  run('cat /proc/loadavg', pty=False)

Using Google Latitude to print current location

August 1, 2011

Updated version


#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# latitude.py
#
# Copyright (c) 2011 Ruslan Valiyev
# ruslan@valiyev.com
#
import time
import urllib2
import simplejson as json
from geopy import geocoders

#
# Get your own keys at:
# http://code.google.com/apis/latitude/v1/getting_started.html#prereqs-getkey
# http://code.google.com/apis/maps/signup.html
#
GOOGLE_LATITUDE_KEY = 'your_key_goes_here'
GOOGLE_API_KEY = 'your_key_goes_here'
GOOGLE_URL = 'http://www.google.com/latitude/apps/badge/api?user=%s&type=json'

#
# Getting data in JSON
#
class GLatitude:
  def __init__(self,uid):
    self.uid=uid
  def getLocationData(self):
    return json.load(urllib2.urlopen(GOOGLE_URL % self.uid))
  def getCoords(self):
    return self.getLocationData()['features'][0]['geometry']['coordinates']
  def getTime(self):
    return self.getLocationData()['features'][0]['properties']['timeStamp']

#
# Convert epoch to human time
#
def TimeConvert(epoch):
  return time.strftime('%d %b %Y %H:%M', time.localtime(epoch))


def main():
  g = geocoders.Google(GOOGLE_API_KEY)
  gl = GLatitude(GOOGLE_LATITUDE_KEY)

  myLocation = gl.getCoords()
  myLocation.reverse()

  return TimeConvert(gl.getTime()), g.reverse(myLocation)

if __name__ == '__main__':
    print main()
Sample output:

>>> import latitude
>>> latitude.main()
('04 Aug 2011 08:42', (u'A1 motorway, 1218 Grand-Saconnex, Switzerland',
(46.239181299999998, 6.1208168000000001)))
PS. Don't forget to grab the latest version of geopy.

Xcode 4.1 fails to install on clean OS X 10.7

July 31, 2011

I've been having issues setting up (now) free Xcode 4.1, downloaded from App Store.

The installer would simply hang saying "Installing files..." (screenshot)

Most of related problems I read about on Apple Support Communities were apperently solved by killing the ItunesHelper process and fixing disk permissions, but this wasn't the solution in my case.
Proof 1: ItunesHelper not running (screenshot)
Proof 2: Disk permissions are fixed (screenshot)

After some debugging, I noticed /var/log/install.log was complaining about "my.target.systemversion.ProductVersion", which made me end up editing a file called iPhoneSDKSL.dist

So, here's how I fixed it and got it installed.

After downloading Xcode, go to Applications. Copy the entire "Install Xcode" to, say, your Desktop.

Go to Desktop, right-click on "Install Xcode" and go to "Show Package Contents". Navigate to Contents/Resources.

Right-click on Xcode.mpkg and go to "Show Package Contents". Go to Contents and open iPhoneSDKSL.dist in TextEdit. Find the following code block:


//10.7 or above
if( system.compareVersions(my.target.systemVersion.ProductVersion, '10.7') == -1 )
{
my.result.type = 'Fatal';
my.result.message = system.localizedStringWithFormat('ERROR_OSVER', '10.7');
return(false);
}

return true;

Comment the code like this:

//10.7 or above
// if( system.compareVersions(my.target.systemVersion.ProductVersion, '10.7') == -1 )
//{
//my.result.type = 'Fatal';
//my.result.message = system.localizedStringWithFormat('ERROR_OSVER', '10.7');
//return(false);
//}
 
return true;

Save the file and quit TextEdit.

Now head back to "Desktop/Install Xcode/Contents/Resources" and double-click the Xcode.mpkg icon. The installation should work this time (screenshot) & (screenshot).

osx and xcode

Sticking with Google

July 29, 2011
Now the blog (and other stuff like my valiyev.com mail) is running on Google App Engine, but it's also managed by Google Apps! Isn't it nice of Google to provide all this for free?

$ host blog.valiyev.com
blog.valiyev.com is an alias for ghs.google.com.
ghs.google.com is an alias for ghs.l.google.com.
ghs.l.google.com has address 209.85.227.121
ghs.l.google.com has IPv6 address 2a00:1450:8002::79

Voipbuster balance monitoring

July 29, 2011
Script to check Voipbuster balance. If it goes below 1€, an email will be sent.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# voipcheck.py
#
# Copyright (c) 2011 Ruslan Valiyev
# ruslan@valiyev.com
#
import urllib
import urllib2
import BeautifulSoup
import smtplib
from email.MIMEText import MIMEText

smtpserver = 'smtp.foo.com'
smtpfrom = 'server@valiyev.com'
smtpto = ['linuxoid@gmail.com']
username = 'voipbusteruser'
password = 'voipbusterpass'
url = 'https://www.voipbuster.com/myaccount'
login = url+'/index.php?part=tplogin'

o = urllib2.build_opener(urllib2.HTTPCookieProcessor())
urllib2.install_opener(o)
data = urllib.urlencode({'user' : username, 'pass' : password})
f = o.open(login, data)
s = f.read()
f.close()

q = o.open(url+'/calls.php')
s = BeautifulSoup.BeautifulSoup(q.read())
balance = s.findAll('b')[1].string.replace(' ', '').replace('€', '').replace(' ', '').replace('\n', '')

if float(balance) < 1:
  subj = 'Voipbuster balance for %s is low!' % (username)
  msg_text = 'Current balance: %s euros.' % str(balance)
  msg = MIMEText(msg_text)
  msg['Subject'] = subj
  s = smtplib.SMTP()
  s.connect(smtpserver)
  s.sendmail(smtpfrom, smtpto, msg.as_string())
  s.close()