Xo-get

From OLPC
Revision as of 01:28, 6 December 2007 by Crazy-chris (talk | contribs) (xo-get.py : most simple package installer)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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"
	
	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]

	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"

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