Xo-get

From OLPC
Revision as of 01:54, 6 December 2007 by Crazy-chris (talk | contribs) (link to correct repo)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

XO-Get is a very simple package-installer for the olpc xo-laptop.

xo-get.py update
xo-get.py list     [categories/category_name]
xo-get.py search   tag/activity_name
xo-get.py install  activity_name

xo-get.py

#! /usr/bin/env python
import os
import sys
import urllib2
import sqlite3

class Activity:
	name = u""
	desc = u""
	xo_url = u""
	category = u""
	tags = u""

class Database:
	db_path = ""
	db_filename = "activities.db"
	cur = "";
	con = "";
	
	def __init__(self, db_path):
		self.db_path = db_path
		
		# Change Directory
		try: os.mkdir(self.db_path)
		except: pass
		os.chdir(self.db_path)

		# Init DB
		create_db = True
		if os.path.isfile(self.db_filename): create_db = False

		print "- Loading db [%s/%s]:" % (self.db_path, self.db_filename),
		self.con = sqlite3.connect(self.db_filename)
		self.cur = self.con.cursor()
		self.cur.execute("-- types unicode")

		if create_db:
			# Setup New Database
			self.cur.execute("CREATE TABLE 'activities' ('id' INTEGER PRIMARY KEY AUTOINCREMENT, 'name' VARCHAR( 100 ) NOT NULL, 'desc' VARCHAR( 355 ) NOT NULL, 'xo_url' VARCHAR( 255 ) NOT NULL, 'category' VARCHAR( 255 ) NOT NULL, 'tags' VARCHAR( 255 ) NOT NULL);")
			self.con.commit()
			print "created"
		else:
			print "ok"
			
#		q = "SELECT * FROM activities WHERE 1"
#		print self.query(q)

	def query(self, q):
		dataList = []
		self.cur.execute(q)
		data = self.cur.fetchall()
		if data: dataList = [list(row) for row in data]
		return dataList

	def commit(self, q):
		self.cur.execute(q)
		self.con.commit()
			
class XOGet:
#	domain = "http://wiki.laptop.org"
#	path = "/go/Xo-get/Repository"

	domain = "http://www.olpcaustria.org"
	path = "/mediawiki/index.php/Xo-get/Repository"
	
	localpath = "%s/%s" % (os.path.expanduser( '~' ), ".xo_get")

	def __init__(self):
		print
		print "  xo-get"
		print "  ======"

		if len(sys.argv) == 1:
			print "  use: - update\n       - list    {categories / [category_name]} \n       - search  [activity_name] / [tag]\n       - install [activity_name]"
			sys.exit(0)
		
		# Loading DB
		self.db = Database(self.localpath)

		if sys.argv[1] == "update": self.update()
		if sys.argv[1] == "list": self.list()
		if sys.argv[1] == "search": self.search()
		if sys.argv[1] == "install": self.install()

	def list(self):
		print
		q = "SELECT name, desc, category, tags FROM activities WHERE 1"
		print "- Listing",
		if len(sys.argv) > 2:
			if sys.argv[2] == "categories":
				print "Categories:"
				q = "SELECT DISTINCT category FROM activities WHERE 1 ORDER BY category ASC"
				res = self.db.query(q)
				for r in res:
					print "  -",r[0]
				return True
			else:
				print "Category '%s'" % sys.argv[2]
				q = "%s AND category LIKE '%s'" % (q, sys.argv[2])
		else:
			print "All Activities"

		q = "%s%s" % (q, " ORDER BY category ASC, name ASC")
		res = self.db.query(q)
		spaces = 18
		spaces2 = 8
		for r in res:
			print "   - [%s]" % r[2], " " * (spaces2 - len(r[2])), r[0], "." * (spaces - len(r[0])), r[1]
		print

	def search(self):
		print
		if len(sys.argv) > 2:
			s = sys.argv[2].replace(" ", "_")
			print "- Results for '%s':" % s
			
			q = "SELECT name, desc, category FROM activities WHERE tags LIKE '%s%s%s' OR name LIKE '%s%s%s'" % ('%', s, '%', '%', s, '%')
			res = self.db.query(q)

			spaces = 18
			spaces2 = 8
			for r in res:
				print "   - [%s]" % r[2], " " * (spaces2 - len(r[2])), r[0], "." * (spaces - len(r[0])), r[1]
		else:
			print "- Please supply query-string (eg: 'xo-get search quiz')"

		print

	def install(self, s = None):
		print
		if s == None:
			if len(sys.argv) > 2:
				s = sys.argv[2].replace(" ", "_")
			else:
				print "- Plase supply an activity_name (eg: 'xo-get install xo_imagequiz')"
				print
				return False
		
		print "- Installing Activity '%s'" % s
		q = "SELECT xo_url FROM activities WHERE name='%s'" % s
		res = self.db.query(q)
		
		# No xo_url means no found activity
		if len(res) == 0:
			print "   - No matching name found."
			q = "SELECT name FROM activities WHERE name LIKE '%s'" % s
			res = self.db.query(q)
			if len(res) == 0:
				print "   - Nothing found. Please try 'xo-get search'"
				print
				return False
			else:
				print "   - Found quite similar name: '%s'" % res[0][0]

				# Only Upper/Lowercase Problem
				if s.lower() == res[0][0].lower(): 
					self.install(res[0][0])
					return True					
				
				# Else Ask
				i = ""
				while i != 'y' and i != 'n':
					print "   - use this? [y/n]",
					i = raw_input()
					
				if i == "y": 
					self.install(res[0][0])
					return True
				else:
					return False
		
		i = ""
		while i != 'y' and i != 'n':
			print "- Do you want to proceed? [y/n]",
			i = raw_input()
			
		if i == "n": return False

		# Okay, we have the xo_url
		url = res[0][0]
		fn = "%s/%s" % (self.localpath, res[0][0][res[0][0].rindex('/')+1:])
#		print "- %s => %s" % (url, fn)
		print "- Download => %s" % (fn)
		xo = urllib2.urlopen(url).read()
		f = open(fn, "w")
		f.write(xo)

		print "- Starting Installation"
		os.system("sugar-install-bundle %s" % fn)
		print "- Activity installed!"
		print 
		
	def update(self):
		print
		print "- update from %s%s" % (self.domain, self.path)

 		content = urllib2.urlopen("%s%s" % (self.domain, self.path)).read()
 		content = content[content.index('<table border="0"'):]

content = content[:content.index('')]

		print "- clearing database:",
		self.db.commit("DELETE FROM activities WHERE 1")
		print "ok"

		print "- adding activities:",

content_arr = content.split("") act_count = 0 for act_html in content_arr: # Extract Activities if act_html.count("") > 0:

				# Add Activity

act_html = act_html.replace("", "") act_html = act_html.replace("", "") a = Activity() act_html_arr = act_html.split("")

				# Name				
				a.name = act_html_arr[1].strip().replace(" ", "_")
				if a.name.count('">') > 0:
					a.name = a.name[a.name.index('">')+2:]
					a.name = a.name[:a.name.index('<')]
				
				if a.name != "":
					# XO Url
					a.xo_url = act_html_arr[2].strip()
					a.xo_url = a.xo_url[a.xo_url.index("http:"):]
					if a.xo_url.count('"') > 0: a.xo_url = a.xo_url[:a.xo_url.index('"')]
	
					# DESC
					a.desc = act_html_arr[3].strip()
	
					# DESC
					a.category = act_html_arr[4].strip()
	
					# DESC
					a.tags = act_html_arr[5].strip()
				
					q = "INSERT INTO activities (name, xo_url, desc, category, tags) VALUES ('%s', '%s', '%s', '%s', '%s')" % (a.name, a.xo_url, a.desc, a.category, a.tags)
					act_count += 1
#					print q
					self.db.commit(q)
#					print
		
		print act_count
		print "- xo-get is now up-to-date"
		print

if __name__ == "__main__":
	xoget = XOGet()