# Path: Managers/DBManager.py
# class DBManager (object):
# 	def __init__(self):
# 		self.docsetDBLocation = 'Docsets/docsets.db'
# 		self.migrationDBLocation = '.migrations.db'
# 		self.connection = None
# 		self.SetupDocsetDB()
# 		self.SetMigrationDB()
# 				
# 	def SetupDocsetDB(self):
# 		self.connection = sqlite3.connect(self.docsetDBLocation)
# 		c = self.connection.cursor()
# 		c.execute('CREATE TABLE IF NOT EXISTS docsets(ID INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT NOT NULL, Path TEXT NOT NULL, Type TEXT NOT NULL, Icon TEXT NOT NULL, Version REAL NULL, OtherData TEXT NOT NULL);')
# 		self.connection.commit()
# 		
# 	def SetMigrationDB(self):
# 		self.migrationconnection = sqlite3.connect(self.migrationDBLocation)
# 		mc = self.migrationconnection.cursor()
# 		mc.execute('CREATE TABLE IF NOT EXISTS migrations(ID INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT NOT NULL, Completed BOOLEAN NOT NULL)')
# 		self.migrationconnection.commit()
# 		
# 	def RunQueryOnDocsetDB(self, query):
# 		self.connection = sqlite3.connect(self.docsetDBLocation)
# 		c = self.connection.cursor()
# 		c.execute(query)
# 		self.connection.commit()
# 	
# 	def DocsetInstalled(self, name, path, type, icon, version, otherdata = ''):
# 		c = self.connection.cursor()
# 		c.execute('INSERT INTO docsets (Name, Path, Type, Icon, Version, OtherData) VALUES (?,?,?,?,?,?)',(name,path,type,icon,version,otherdata,))
# 		self.connection.commit()
# 	
# 	
# 	def DocsetRemoved(self, id):
# 		c = self.connection.cursor()
# 		c.execute('DELETE FROM docsets WHERE ID = (?)',(id,))
# 		self.connection.commit()
# 	
# 	def InstalledDocsets(self):
# 		return self.connection.execute('SELECT * FROM docsets').fetchall()
# 	
# 	def InstalledDocsetsByType(self, type):
# 		return self.connection.execute('SELECT * FROM docsets WHERE type = (?) ORDER BY name COLLATE NOCASE ASC, version DESC', (type,)).fetchall()
# 	
# 	def AddMigration(self, name, completed = False):
# 		records = self.migrationconnection.execute('SELECT * FROM migrations WHERE Name like (?)',(name,)).fetchall()
# 		if len(records) == 0:
# 			c = self.migrationconnection.cursor()
# 			c.execute('INSERT INTO migrations (Name, Completed) VALUES (?,?)',(name,completed,))
# 			self.migrationconnection.commit()
# 	
# 	def UpdateMigration(self, name, completed):
# 		records = self.migrationconnection.execute('SELECT * FROM migrations WHERE Name like (?)',(name,)).fetchall()
# 		if len(records) > 0:
# 			c = self.migrationconnection.cursor()
# 		
# 			c.execute('UPDATE migrations SET Completed = (?) WHERE name like (?)',(completed,name,))
# 			self.migrationconnection.commit()
# 	
# 	def GetMigration(self, name):
# 		record = self.migrationconnection.execute('SELECT * FROM migrations WHERE Name like (?)',(name,)).fetchone()
# 		return record 
# 
# Path: Managers/TypeManager.py
# class TypeManager (object):
# 	def __init__(self, typeIconPath):
# 		self.typeIconPath = typeIconPath
# 		self.types = self.__setup()
# 		
# 	def __setup(self):
# 		with open('types.json') as json_data:
# 			data = json.load(json_data)
# 			types = []
# 			for ty in data:
# 				t = Type()
# 				t.name = ty['name']
# 				t.plural = ty['plural']
# 				if 'aliases' in ty:
# 					t.aliases = ty['aliases']
# 				t.icon = self.__getTypeIconWithName(ty['name'])
# 				types.append(t)
# 			return types
# 			
# 	def __getTypeIconWithName(self, name):
# 		imgPath = os.path.join(os.path.abspath('.'), self.typeIconPath, name+'.png')
# 		if not os.path.exists(imgPath):
# 			imgPath = os.path.join(os.path.abspath('.'), self.typeIconPath, 'Unknown.png')
# 		return ui.Image.named(imgPath)
# 	
# 	def getTypeForName(self, name):
# 		for type in self.types:
# 			if type.name == name:
# 				return type
# 		for type in self.types:
# 			if name in type.aliases:
# 				return type
# 
# Path: Utilities/LogThread.py
# class LogThread(threading.Thread):
# 	"""LogThread should always e used in preference to threading.Thread.
# 	
# 	The interface provided by LogThread is identical to that of threading.Thread,
# 	however, if an exception occurs in the thread the error will be logged
# 	(using logging.exception) rather than printed to stderr.
# 	
# 	This is important in daemon style applications where stderr is redirected
# 	to /dev/null.
# 	
# 	"""
# 	def __init__(self, **kwargs):
# 		super().__init__(**kwargs)
# 		self._real_run = self.run
# 		self.run = self._wrap_run
# 		
# 	def _wrap_run(self):
# 		try:
# 			self._real_run()
# 		except Exception as e:
# 			console.hide_activity()
# 			console.alert('Error occured', str(e)
# 			+ '\n\n Please close application and start again', 'Ok', hide_cancel_button=True)


import json
import os
import ui
import requests
import xml.etree.cElementTree
import threading
import ui
import time
import math
import tarfile
import plistlib
import console
import sqlite3
import shutil	
import copy	
from urllib.parse import urlparse
from os.path import splitext, basename
from objc_util import ns, ObjCClass
from Managers import DBManager, TypeManager
from Utilities import LogThread
from distutils.version import LooseVersion

class Docset(object):
	def __init__(self):
		self.displayName = ''
		self.downloaded = False
		
class DocsetManager (object):
	def __init__(self, iconPath, typeIconPath, serverManager):

# Path: Managers/DBManager.py
# class DBManager (object):
# 	def __init__(self):
# 		self.docsetDBLocation = 'Docsets/docsets.db'
# 		self.migrationDBLocation = '.migrations.db'
# 		self.connection = None
# 		self.SetupDocsetDB()
# 		self.SetMigrationDB()
# 				
# 	def SetupDocsetDB(self):
# 		self.connection = sqlite3.connect(self.docsetDBLocation)
# 		c = self.connection.cursor()
# 		c.execute('CREATE TABLE IF NOT EXISTS docsets(ID INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT NOT NULL, Path TEXT NOT NULL, Type TEXT NOT NULL, Icon TEXT NOT NULL, Version REAL NULL, OtherData TEXT NOT NULL);')
# 		self.connection.commit()
# 		
# 	def SetMigrationDB(self):
# 		self.migrationconnection = sqlite3.connect(self.migrationDBLocation)
# 		mc = self.migrationconnection.cursor()
# 		mc.execute('CREATE TABLE IF NOT EXISTS migrations(ID INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT NOT NULL, Completed BOOLEAN NOT NULL)')
# 		self.migrationconnection.commit()
# 		
# 	def RunQueryOnDocsetDB(self, query):
# 		self.connection = sqlite3.connect(self.docsetDBLocation)
# 		c = self.connection.cursor()
# 		c.execute(query)
# 		self.connection.commit()
# 	
# 	def DocsetInstalled(self, name, path, type, icon, version, otherdata = ''):
# 		c = self.connection.cursor()
# 		c.execute('INSERT INTO docsets (Name, Path, Type, Icon, Version, OtherData) VALUES (?,?,?,?,?,?)',(name,path,type,icon,version,otherdata,))
# 		self.connection.commit()
# 	
# 	
# 	def DocsetRemoved(self, id):
# 		c = self.connection.cursor()
# 		c.execute('DELETE FROM docsets WHERE ID = (?)',(id,))
# 		self.connection.commit()
# 	
# 	def InstalledDocsets(self):
# 		return self.connection.execute('SELECT * FROM docsets').fetchall()
# 	
# 	def InstalledDocsetsByType(self, type):
# 		return self.connection.execute('SELECT * FROM docsets WHERE type = (?) ORDER BY name COLLATE NOCASE ASC, version DESC', (type,)).fetchall()
# 	
# 	def AddMigration(self, name, completed = False):
# 		records = self.migrationconnection.execute('SELECT * FROM migrations WHERE Name like (?)',(name,)).fetchall()
# 		if len(records) == 0:
# 			c = self.migrationconnection.cursor()
# 			c.execute('INSERT INTO migrations (Name, Completed) VALUES (?,?)',(name,completed,))
# 			self.migrationconnection.commit()
# 	
# 	def UpdateMigration(self, name, completed):
# 		records = self.migrationconnection.execute('SELECT * FROM migrations WHERE Name like (?)',(name,)).fetchall()
# 		if len(records) > 0:
# 			c = self.migrationconnection.cursor()
# 		
# 			c.execute('UPDATE migrations SET Completed = (?) WHERE name like (?)',(completed,name,))
# 			self.migrationconnection.commit()
# 	
# 	def GetMigration(self, name):
# 		record = self.migrationconnection.execute('SELECT * FROM migrations WHERE Name like (?)',(name,)).fetchone()
# 		return record 
# 
# Path: Managers/TypeManager.py
# class TypeManager (object):
# 	def __init__(self, typeIconPath):
# 		self.typeIconPath = typeIconPath
# 		self.types = self.__setup()
# 		
# 	def __setup(self):
# 		with open('types.json') as json_data:
# 			data = json.load(json_data)
# 			types = []
# 			for ty in data:
# 				t = Type()
# 				t.name = ty['name']
# 				t.plural = ty['plural']
# 				if 'aliases' in ty:
# 					t.aliases = ty['aliases']
# 				t.icon = self.__getTypeIconWithName(ty['name'])
# 				types.append(t)
# 			return types
# 			
# 	def __getTypeIconWithName(self, name):
# 		imgPath = os.path.join(os.path.abspath('.'), self.typeIconPath, name+'.png')
# 		if not os.path.exists(imgPath):
# 			imgPath = os.path.join(os.path.abspath('.'), self.typeIconPath, 'Unknown.png')
# 		return ui.Image.named(imgPath)
# 	
# 	def getTypeForName(self, name):
# 		for type in self.types:
# 			if type.name == name:
# 				return type
# 		for type in self.types:
# 			if name in type.aliases:
# 				return type
# 
# Path: Utilities/LogThread.py
# class LogThread(threading.Thread):
# 	"""LogThread should always e used in preference to threading.Thread.
# 	
# 	The interface provided by LogThread is identical to that of threading.Thread,
# 	however, if an exception occurs in the thread the error will be logged
# 	(using logging.exception) rather than printed to stderr.
# 	
# 	This is important in daemon style applications where stderr is redirected
# 	to /dev/null.
# 	
# 	"""
# 	def __init__(self, **kwargs):
# 		super().__init__(**kwargs)
# 		self._real_run = self.run
# 		self.run = self._wrap_run
# 		
# 	def _wrap_run(self):
# 		try:
# 			self._real_run()
# 		except Exception as e:
# 			console.hide_activity()
# 			console.alert('Error occured', str(e)
# 			+ '\n\n Please close application and start again', 'Ok', hide_cancel_button=True)


# Path: Managers/DocsetManager.py
import json
import os
import ui
import requests
import xml.etree.cElementTree
import threading
import ui
import time
import math
import tarfile
import plistlib
import console
import sqlite3
import shutil	
import copy	
from urllib.parse import urlparse
from os.path import splitext, basename
from objc_util import ns, ObjCClass
from Managers import DBManager, TypeManager
from Utilities import LogThread
from distutils.version import LooseVersion


class Docset(object):
	def __init__(self):
		self.displayName = ''
		self.downloaded = False
		
class DocsetManager (object):
	def __init__(self, iconPath, typeIconPath, serverManager):

		self.typeManager = TypeManager.TypeManager(typeIconPath)