Over the last month or so i've had to kick out a lot of betas for a project. Seeing as i use the fantastic Test Flight. I have to change the version number before i upload each build otherwise Test Flight will overwrite an existing build which is the last thing that we want.
I don't think anyone actually enjoys editing a plists, whether its in Xcode plist editor or the down and dirty XML. So has a result it was the perfect opportunity to get familiar with xcode's build process, and how to tie external scripts into it.
I use 3 segment version numbers (1.1.1), where the first digit is the major version, second digit is the minor version, and the 3rd digit is the build. For the benefit of the team, i wanted to have the latest commit hash in the build number so that people could quickly reference it and know whats going on.
With some direction from this post by Duane Sibilly i was able to hack together the below.
The musing and sometimes not so wise words of Jonathan Dalrymple, Global Traveller, Programmer, Financial Rocket Scientist, Conspiracy Theorist, Part-time comedian, full-time funny man and whatever else i randomly decide to do.
Showing posts with label python. Show all posts
Showing posts with label python. Show all posts
Saturday, July 30, 2011
Friday, May 08, 2009
It's over!
Quick post to mention that i've finished my degree! more importantly i that i can get back to doing what i love, writing code (and playing FM).
Heres some extremely basic python for transforming a simple list of CRLF separated values into a sql statement.
Nothing special.
Off to china on sunday!!
再见
Heres some extremely basic python for transforming a simple list of CRLF separated values into a sql statement.
def main():
fh = open('list.txt')
sql = open('sqlDump.txt','w')
i = 0
for line in fh:
statement = "INSERT INTO table (name) VALUES ('%s');\r" % line.rstrip()
sql.write( statement )
fh.close()
sql.close()
if __name__ == '__main__':
main()
Nothing special.
Off to china on sunday!!
再见
Wednesday, July 23, 2008
OSS: Python webpage link checker
Another piece of python to go. Nothing special, but something fairly useful that i've thrown together.
The following code samples are released under the terms of the GPL 2.0
It's URL link checker, it's not fully recursive (working on it, they don't teach recursive algorithms on my course). But checks all the anchor tags on the given page, returning warnings and the like depending on what it finds.
Usage: To use this just run it like so "python [scriptname]"
It will then ask for the url of the page you wish to check, and then it will print a report, like so.

Python
Quote of the Day
Realizations, Andorra here i come
It's URL link checker, it's not fully recursive (working on it, they don't teach recursive algorithms on my course). But checks all the anchor tags on the given page, returning warnings and the like depending on what it finds.
Usage: To use this just run it like so "python [scriptname]"
It will then ask for the url of the page you wish to check, and then it will print a report, like so.

Python
#Link Checker
#Brazen attempt to write one in 15 minutes
# Jonathan Dalrymple
# July 15,2008
# Start 11:52
# End 12:35
import httplib
import sgmllib
import re
#HTML Parser
class LinkChecker( sgmllib.SGMLParser ):
def __init__(self, verbose = 0):
sgmllib.SGMLParser.__init__( self, verbose )
self.linkList = []
self.inLink = False
self.lastHref = None
self.hostName = None
print 'Parsing file...'
def parse( self, fileStr ):
self.feed( fileStr )
self.close()
def start_a( self, attr ):
#Show user that the parser is working
#print '*'
self.inLink = True
for name, val in attr:
if name == 'href':
self.lastHref = val
def end_a( self):
self.inLink = False
def handle_data(self, str):
if self.inLink:
tmp = self.__parseUrl( self.lastHref )
self.linkList.append( (str,tmp['host'],tmp['path']) )
def __parseUrl( self, str ):
ret = {}
#slice of preceeding http
#if str[0:7] == 'http://':
# str = str[7:len(str)]
# Extract path regex "\w+\.(\w*)\.(\w{2}\.)?(\w{2,3})"
m = re.compile("\w+\.(\w*)\.(\w{2}\.)?(\w{2,3})").match( str )
if m == None:
#print 'Error in handle url, regex failed'
ret['host'] = None
ret['path'] = str
else:
ret['host'] = m.string[0:m.end()]
if m.end() <> ret['path'] = str[ m.end(): len(str) ] else: ret['path'] = None
return ret #Check link def __checkLink( self, displayName, host = None, path = '/' ): if host == None: host = self.hostName
#slice path and determine if it is a full url reqObj = httplib.HTTPConnection( host, 80 )
#print '---Requesting %s' % url+path reqObj.request('get', path )
response = reqObj.getresponse()
if response.status == 200: retVal = "SUCCESS |%s returned %d" % (displayName, response.status ) elif response.status == 404: retVal = "FAILURE |%s returned %d, (%s)" % (displayName, response.status, path ) else: retVal = "WARNING |%s returned %d, (%s)" % (displayName, response.status, path )
return retVal def testUrlParser( self, list ): for u in list: print '--' + str(self.__parseUrl( u )) def runReport( self, urlStr ): urlDict = self.__parseUrl( urlStr )
if urlDict != None: self.hostName = urlDict['host'] req = httplib.HTTPConnection(urlDict['host'], 80)
req.request('get',urlDict['path']) response = req.getresponse()
if response.status == 200:
htmlStr = response.read()
self.parse( htmlStr )
print "%d links found" % len( self.linkList )
for v in self.linkList: #print v print self.__checkLink( v[0], v[1], v[2] ) else: print "Download Request for %s failed: %d" % ( response.reason, response.status)
def main():
#urlStr = "http://www.google.co.uk/search?hl=en&q=bar&btnG=Google+Search&meta=" urlStr = raw_input('Url you wish to check:') if urlStr != None: bar = LinkChecker() #foo = ('www.google.com','http://www.google.com','http://docs.python.org/lib/lib.html','docs.python.org/test') #bar.testUrlParser( foo ) bar.runReport( urlStr )
if __name__ == '__main__': main()Quote of the Day
I now finally understand why those guys buy £100,000 cars, only to sit in traffic. It's because they remember the days of running for the train, only to find that it's standing room only and their new best friend is a significantly taller gentleman's (or lady!!) armpit and or sweaty back.
Realizations, Andorra here i come
Saturday, June 21, 2008
Facebook Chat
Labels:
Applications,
facebook,
idea,
Programming,
projects,
python
Sunday, May 18, 2008
Snake in the torrents ...
I decided to branch out last week and use python seriously for the first time.
Turns out it is as good as all the praise it gets. This conversion was round about the same time i switched to Transmission for my torrenting needs as the jre + azuerus don't do my memory usage any real favours. The main thing that i love about azuerus was the fact that i could have it subscribe to a rss feed and download "linux iso's" automatically. Coupled with the fact that everyones favourite release group, EZTV provides there releases in the RSS form, it was perfect. However the plugin stopped working correctly about a month ago and i've been forced to actually operate my torrent client, gasp!
Anyways, while having a shower (Yes, i come up with concepts in the shower), i thought maybe i can replicate that functionality using python! Transmission has a feature that makes it scan a folder for torrents, so in theory i would simply need to do the following ...
Turns out it is as good as all the praise it gets. This conversion was round about the same time i switched to Transmission for my torrenting needs as the jre + azuerus don't do my memory usage any real favours. The main thing that i love about azuerus was the fact that i could have it subscribe to a rss feed and download "linux iso's" automatically. Coupled with the fact that everyones favourite release group, EZTV provides there releases in the RSS form, it was perfect. However the plugin stopped working correctly about a month ago and i've been forced to actually operate my torrent client, gasp!
Anyways, while having a shower (Yes, i come up with concepts in the shower), i thought maybe i can replicate that functionality using python! Transmission has a feature that makes it scan a folder for torrents, so in theory i would simply need to do the following ...
- Read a list of files/shows
- extract the respective links from a rss/xml feed
- calculate which ones are the most recent
- download the torrent files
- Python 2.5.1
- OS X 10.5
- Atom RSS source feed (Mininova)
My plan to schedule it as a cron job and sit back and watch.
Lastly to create the config file, just open your favourite text editor and list your tv shows, delimited using return, mine looks like this
It's not case sensitive, so don't panic.
Python
#Channel 0.1
# Jonathan Dalrymple
# May 17th, 2008
from xml.etree import ElementTree as ET
import os
import shutil
import sqlite3
import urllib
currentDirectory = os.path.dirname( os.path.abspath( __file__ ))
#Create SQL
dbConn = sqlite3.connect( os.path.join( currentDirectory,"torrentsDB") )
#Create the new table
sql = "DROP TABLE IF EXISTS torrents"
dbConn.execute( sql )
sql = """
CREATE TABLE IF NOT EXISTS torrents (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
date TEXT,
url TEXT
)
"""
dbConn.execute( sql )
dbConn.commit()
#Get XML file
response = urllib.urlretrieve( "http://www.mininova.org/rss.xml?user=eztv" )
shutil.copyfile(response[0], os.path.join( currentDirectory,"rssSource.xml") )
xmlFile = os.path.join( currentDirectory, "rssSource.xml" )
try:
tree = ET.parse( xmlFile )
selection = tree.getiterator('item')
i = 0
#For each item tag
for element in selection:
#Get the request elements from the selection
title = element.findtext('title')
date = element.findtext('pubDate')
enclosure = element.find('enclosure').attrib['url']
sql = "INSERT INTO torrents (title, date, url ) VALUES ( '%s','%s','%s')" % (title, date, enclosure)
dbConn.execute( sql )
i += 1
#Commit records
dbConn.commit()
print '%d Torrents have been processed and added to the database' % (i)
except Exception, inst:
print 'Parse Error: %s' % (inst)
#Read the config file for the shows
configFile = file("shows.txt")
shows = configFile.readlines()
#Get the url for the show
print "The following torrents where found ..."
for show in shows:
dataSet = dbConn.cursor()
dataSet.execute( "SELECT title, url FROM torrents WHERE title LIKE '%" + show.rstrip() +"%' ORDER BY id DESC LIMIT 1" )
row = dataSet.fetchone()
#Test to ensure that a record exists
if type(row) == type(tuple()):
try:
print row[0]
#download the torrent file
response = urllib.urlretrieve( row[1] )
newFilename = os.path.join (currentDirectory, show + ".torrent")
#Move from the temp folder
shutil.copyfile( response[0], newFilename )
except Exception, inst:
print 'Download Error: %s' % (inst)
print 'Complete'
Lastly to create the config file, just open your favourite text editor and list your tv shows, delimited using return, mine looks like this
Lost
Battlestar Galactica
House
Cops
American Dad
It's not case sensitive, so don't panic.
Subscribe to:
Posts (Atom)
