#!/usr/bin/python

import gtk
import os
from os.path import join, getsize
import string
import time
import thread,threading
import sys
#Regular expressions
import re

gtk.gdk.threads_init() 

class Yaouh:
	def __init__(self):
		self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
		self.window.set_title('Yaouh!')
		self.window.set_default_size(480,640)
		self.pbarmsg=" "
		self.print_win(self)
		
		self.window.connect("destroy", gtk.main_quit)
		self.window.show_all()

	def print_win(self, widget, data=None):
		button_quit = gtk.Button()
		image = gtk.Image()
		image.set_from_stock('gtk-quit', gtk.ICON_SIZE_DND)
		button_quit.add(image)
		button_quit.connect_object("clicked", gtk.Widget.destroy, self.window)
		button_quit.set_property('border-width', 5)
		
		self.button_update = gtk.Button()
		image = gtk.Image()
		image.set_from_stock(gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_DND)
		self.button_update.add(image)
		self.button_update.connect_object("clicked", self.init_thread, self.window)
		self.button_update.set_property('border-width', 5)
		
		minuccilogo = gtk.Image()
		minuccilogo.set_from_file("/usr/share/yaouh/icons/yaouh.png")
		
		text = gtk.Label("Updating your TangoGPS Maps")
		hr = gtk.HSeparator()
		text_about = gtk.Label("If you like this program send me a email\nto: gecco@napodano.com\nor send a sms\nto: +393288232457")
		text_10x = gtk.Label("Thanks to:\nFlorian Schweikert and Amygos for code\nFacs, Djdas, Kelvan, Helge Hafting,\nRisto H. Kuppa, William Kenworthy\nfor suggests.\nFor donate http://minucci.net/openmoko.php")
		self.pbar = gtk.ProgressBar()
		
		self.pbarmsg=self.pbarmsg + "\nChose a repository and start update..."
		self.pbar.set_text(self.pbarmsg)
		self.box = gtk.VBox(False, 0)
		self.box.pack_start(text, False, True, 5)
		self.box.pack_start(self.pbar, False, True, 5)
		self.box.pack_start(hr, False, False, 5)
		self.box.pack_start(text_about, True, True, 5)
		self.box.pack_end(text_10x, True, True, 5)
		
		self.combo = gtk.ComboBox()
		self.store = gtk.ListStore(str)
		self.combo.set_model(self.store)
		combo_rend = gtk.CellRendererText()
		self.combo.pack_start(combo_rend, True)
		self.combo.add_attribute(combo_rend, 'text', 0)

		self.maps = self.parse_gconf()

		self.maps.pop(0)
		for text in self.maps:
			self.combo.append_text(text[0])
		self.combo.set_active(0)

		self.table = gtk.Table(5, 1, homogeneous=False)
		self.table.attach(self.button_update, 0, 1, 0, 1)
		self.table.attach(minuccilogo, 0, 1, 0, 1)
		self.table.attach(self.combo, 0, 1, 1, 2)
		self.table.attach(self.box, 0, 1, 2, 4)
		self.table.attach(button_quit, 0, 1, 4, 5)
		
		self.window.add(self.table)
		self.window.show_all()
		
	def init_thread(self, parent):
		t = thread.start_new_thread(self.up_progressbar, ()) 
	
	def create_url(self, url, root, file, invert):
		root = root.split("/")
		x = root[len(root)-1]
		y = file
		z = root[len(root)-2]
		if invert:
			return url.replace("%d", x, 1).replace("%d", y, 1).replace("%d", z, 1)
		else:
			return url.replace("%d", z, 1).replace("%d", x, 1).replace("%d", y, 1)

	def parse_gconf(self):
		f = open(os.path.expanduser("~/.gconf/apps/tangogps/%gconf.xml"), "r")
		file_content = f.read()
		data = string.split(file_content, '>\n')
		f.close()
		n = len(data)
		j=0

		sterm = "<stringvalue>"
		substr = "http://"
		maps = [[]]
		while j < n:
			if string.find(data[j], sterm) != -1 and len(string.split(data[j], "|")) == 4:
				out = string.split(data[j], "|")
				dir = out[2]
				url = out[1].replace("&amp;", "\&")
				invert = out[3][:1]
				map_name = out[0].strip()[len(sterm):]
				if url.find(substr) != -1:
					maps.append([map_name, url, dir, invert])
			else:
				dir = "/home/root/Maps/OSM/"
			j+=1
		
		return maps

	def up_progressbar(self):
		self.button_update.destroy()
		
		maps = self.maps
		
		m = int(self.combo.get_active())		

		try:
			dir = maps[m][2]
		except:
			sys.stderr.write("[ERROR] some problem with maps-array")

		self.pbar.set_text("Counting tiles...\n")
		
		comando="cd "+ dir + "; find . -type f -name *png | wc -l"
		
		e=os.popen(comando)
		tot= e.read() 
		tot= tot.replace("\n", "")
		
		if int(tot) == 0:			self.pbar.set_fraction(1)
			self.pbarmsg="Operation complete. 0 files updated."			self.pbar.set_text(self.pbarmsg)
		else:
			c=0
			i=0
			ip=(1.0/int(tot))
			p=0
			plain_url = maps[m][1]
			invert = int(maps[m][3])

			#For weeding out non-png files that otherwise
			#causes lengthy 404's from the server.
			png_regex = re.compile( r".*png$" )

			for root, dirs, files in os.walk(dir):
				#print "DEBUGGING"
				#print plain_url
				#print root
				#print files
				com_curl = "curl -q -A yaouh -f -I -s"
				com_md5 ="cd " + root + " ; md5sum"
				n_files = 0
				for name in files:
					if png_regex.search(name):
						url = self.create_url(plain_url, root, name[:name.find('.')], invert)
						com_curl += " " + url
						com_md5 += " " + name
						n_files += 1
				if n_files == 0: 
					continue
				com_curl += " | cut -d \\\" -f 2 -s"
				com_md5 += " | cut -d \" \" -f 1"
				#DEBUGGING
				#print com_curl
				curl=os.popen(com_curl)
				c_etags=curl.read()
				#DEBUGGING
				#print c_etags
				#print com_md5
				md5=os.popen(com_md5)
				m_etags=md5.read()
				#DEBUGGING
				#print m_etags

				get_files = 0
				com_get = "cd " + root + " ; curl -q -A yaouh -f -s -O " + self.create_url(plain_url, root, "{", invert)
				#workaround, removes extraneous ".png":
				com_get = com_get[0:len(com_get)-4]
				for cs, ms, name in zip(c_etags.split(), m_etags.split(), files):
					#DEBUGGING
					#print cs + " =?= " + ms
					if cs != ms:
						#DEBUGGING
						#print "diff!"
						if get_files>0:
							com_get += ","
						get_files += 1
						com_get += name


				i += n_files
				p += n_files*ip
				if get_files > 0: 				
					c += get_files
					com_get += "}"
					#DEBUGGING
					#print com_get
					self.command_wget = com_get
					self.thread_wget(self)

				self.pbar.set_fraction(p)
				self.pbar.set_text(str(i) + "/" + str(tot) + " files\n" + str(c) + " updated")

			self.pbar.set_fraction(1)
			self.pbarmsg=str(c) + " files updated on " + str(maps[m][0]) + " repository"
			self.pbar.set_text(self.pbarmsg)
		
		self.table.destroy()
		self.print_win(self)
	
	def thread_wget(self, parent):
		t = thread.start_new_thread(self.wget, ())
		
	def wget(self):
		os.popen(self.command_wget)
	
	def destroy(self, widget, data=None):
		gtk.main_quit()
	
	def main(self):
		gtk.main()
	
if __name__ == "__main__":
	yaouh = Yaouh()
	yaouh.main()
