489 lines
15 KiB
Python
489 lines
15 KiB
Python
# -*- coding: utf-8 -*-
|
|
# vStream https://github.com/Kodi-vStream/venom-xbmc-addons
|
|
|
|
import xbmcvfs
|
|
|
|
from resources.lib.handler.inputParameterHandler import cInputParameterHandler
|
|
from resources.lib.util import QuotePlus, Unquote
|
|
from resources.lib.comaddon import dialog, addon, VSlog, VSPath
|
|
|
|
SITE_IDENTIFIER = 'cDb'
|
|
SITE_NAME = 'DB'
|
|
|
|
try:
|
|
from sqlite3 import dbapi2 as sqlite
|
|
VSlog('SQLITE 3 as DB engine for db')
|
|
except:
|
|
from pysqlite2 import dbapi2 as sqlite
|
|
VSlog('SQLITE 2 as DB engine for db')
|
|
|
|
class cDb:
|
|
|
|
DB = 'special://home/userdata/addon_data/plugin.video.vstream/vstream.db'
|
|
# important seul xbmcvfs peux lire le special
|
|
try:
|
|
REALDB = VSPath(DB).decode('utf-8')
|
|
except AttributeError:
|
|
REALDB = VSPath(DB)
|
|
|
|
def __init__(self):
|
|
|
|
try:
|
|
if not xbmcvfs.exists(self.DB):
|
|
self.db = sqlite.connect(self.REALDB)
|
|
self.db.row_factory = sqlite.Row
|
|
self.dbcur = self.db.cursor()
|
|
self._create_tables()
|
|
return
|
|
except:
|
|
VSlog('Error: Unable to write to %s' % self.REALDB)
|
|
pass
|
|
|
|
try:
|
|
self.db = sqlite.connect(self.REALDB)
|
|
self.db.row_factory = sqlite.Row
|
|
self.dbcur = self.db.cursor()
|
|
except:
|
|
VSlog('Error: Unable to access to %s' % self.REALDB)
|
|
pass
|
|
|
|
def __del__(self):
|
|
''' Cleanup db when object destroyed '''
|
|
try:
|
|
self.dbcur.close()
|
|
self.db.close()
|
|
except Exception:
|
|
pass
|
|
|
|
def _create_tables(self):
|
|
|
|
# sql_create2 = 'DROP TABLE history'
|
|
|
|
''' Create table '''
|
|
sql_create = "CREATE TABLE IF NOT EXISTS history ("\
|
|
"addon_id integer PRIMARY KEY AUTOINCREMENT, "\
|
|
"title TEXT, "\
|
|
"disp TEXT, "\
|
|
"icone TEXT, "\
|
|
"isfolder TEXT, "\
|
|
"level TEXT, "\
|
|
"lastwatched TIMESTAMP "", "\
|
|
"UNIQUE(title)"\
|
|
");"
|
|
self.dbcur.execute(sql_create)
|
|
|
|
sql_create = "CREATE TABLE IF NOT EXISTS resume ("\
|
|
"addon_id integer PRIMARY KEY AUTOINCREMENT, "\
|
|
"title TEXT, "\
|
|
"hoster TEXT, "\
|
|
"point TEXT, "\
|
|
"UNIQUE(title, hoster)"\
|
|
");"
|
|
self.dbcur.execute(sql_create)
|
|
|
|
sql_create = "CREATE TABLE IF NOT EXISTS watched ("\
|
|
"addon_id integer PRIMARY KEY AUTOINCREMENT, "\
|
|
"title TEXT, "\
|
|
"site TEXT, "\
|
|
"UNIQUE(title, site)"\
|
|
");"
|
|
self.dbcur.execute(sql_create)
|
|
|
|
sql_create = "CREATE TABLE IF NOT EXISTS favorite ("\
|
|
"addon_id integer PRIMARY KEY AUTOINCREMENT, "\
|
|
"title TEXT, "\
|
|
"siteurl TEXT, "\
|
|
"site TEXT, "\
|
|
"fav TEXT, "\
|
|
"cat TEXT, "\
|
|
"icon TEXT, "\
|
|
"fanart TEXT, "\
|
|
"UNIQUE(title, site)"\
|
|
");"
|
|
self.dbcur.execute(sql_create)
|
|
|
|
sql_create = "CREATE TABLE IF NOT EXISTS download ("\
|
|
"addon_id integer PRIMARY KEY AUTOINCREMENT, "\
|
|
"title TEXT, "\
|
|
"url TEXT, "\
|
|
"path TEXT, "\
|
|
"cat TEXT, "\
|
|
"icon TEXT, "\
|
|
"size TEXT,"\
|
|
"totalsize TEXT, "\
|
|
"status TEXT, "\
|
|
"UNIQUE(title, path)"\
|
|
");"
|
|
self.dbcur.execute(sql_create)
|
|
|
|
VSlog('Table initialized')
|
|
|
|
# Ne pas utiliser cette fonction pour les chemins
|
|
def str_conv(self, data):
|
|
if isinstance(data, str):
|
|
# Must be encoded in UTF-8
|
|
try:
|
|
data = data.decode('utf8')
|
|
except AttributeError:
|
|
pass
|
|
import unicodedata
|
|
data = unicodedata.normalize('NFKD', data).encode('ascii', 'ignore')
|
|
|
|
try:
|
|
data = data.decode('string-escape') # ATTENTION: provoque des bugs pour les chemins a cause du caractere '/'
|
|
except:
|
|
pass
|
|
|
|
return data
|
|
|
|
# ***********************************
|
|
# History fonctions
|
|
# ***********************************
|
|
|
|
def insert_history(self, meta):
|
|
|
|
# title = Unquote(meta['title']).decode('ascii', 'ignore')
|
|
title = self.str_conv(Unquote(meta['title']))
|
|
disp = meta['disp']
|
|
icon = 'icon.png'
|
|
|
|
try:
|
|
ex = 'INSERT INTO history (title, disp, icone) VALUES (?, ?, ?)'
|
|
self.dbcur.execute(ex, (title, disp, icon))
|
|
self.db.commit()
|
|
VSlog('SQL INSERT history Successfully')
|
|
except Exception as e:
|
|
if 'UNIQUE constraint failed' in e.message:
|
|
ex = "UPDATE history set title = '%s', disp = '%s', icone= '%s' WHERE title = '%s'" % (title, disp, icon, title)
|
|
self.dbcur.execute(ex)
|
|
self.db.commit()
|
|
VSlog('SQL UPDATE history Successfully')
|
|
VSlog('SQL ERROR INSERT')
|
|
pass
|
|
|
|
def get_history(self):
|
|
sql_select = 'SELECT * FROM history'
|
|
|
|
try:
|
|
self.dbcur.execute(sql_select)
|
|
# matchedrow = self.dbcur.fetchone()
|
|
matchedrow = self.dbcur.fetchall()
|
|
return matchedrow
|
|
except Exception:
|
|
VSlog('SQL ERROR EXECUTE')
|
|
return None
|
|
|
|
def del_history(self):
|
|
from resources.lib.gui.gui import cGui
|
|
oGui = cGui()
|
|
oInputParameterHandler = cInputParameterHandler()
|
|
if oInputParameterHandler.exist('searchtext'):
|
|
sql_delete = "DELETE FROM history WHERE title = '%s'" % (oInputParameterHandler.getValue('searchtext'))
|
|
else:
|
|
sql_delete = 'DELETE FROM history;'
|
|
|
|
try:
|
|
self.dbcur.execute(sql_delete)
|
|
self.db.commit()
|
|
dialog().VSinfo(addon().VSlang(30041))
|
|
oGui.updateDirectory()
|
|
return False, False
|
|
except Exception:
|
|
VSlog('SQL ERROR DELETE')
|
|
return False, False
|
|
|
|
# ***********************************
|
|
# Watched fonctions
|
|
# ***********************************
|
|
|
|
def insert_watched(self, meta):
|
|
title = meta['title']
|
|
if not title:
|
|
return
|
|
|
|
site = QuotePlus(meta['site'])
|
|
ex = 'INSERT INTO watched (title, site) VALUES (?, ?)'
|
|
self.dbcur.execute(ex, (title, site))
|
|
try:
|
|
self.db.commit()
|
|
VSlog('SQL INSERT watched Successfully')
|
|
except Exception:
|
|
VSlog('SQL ERROR INSERT')
|
|
pass
|
|
|
|
def get_watched(self, meta):
|
|
title = meta['title']
|
|
if not title:
|
|
return None
|
|
|
|
sql_select = "SELECT * FROM watched WHERE title = '%s'" % title
|
|
|
|
try:
|
|
self.dbcur.execute(sql_select)
|
|
# matchedrow = self.dbcur.fetchone()
|
|
matchedrow = self.dbcur.fetchall()
|
|
|
|
if matchedrow:
|
|
return 1
|
|
return 0
|
|
except Exception:
|
|
VSlog('SQL ERROR EXECUTE')
|
|
return None
|
|
|
|
def del_watched(self, meta):
|
|
title = meta['title']
|
|
if not title:
|
|
return
|
|
|
|
sql_select = "DELETE FROM watched WHERE title = '%s'" % title
|
|
try:
|
|
self.dbcur.execute(sql_select)
|
|
self.db.commit()
|
|
return False, False
|
|
except Exception:
|
|
VSlog('SQL ERROR EXECUTE')
|
|
return False, False
|
|
|
|
# ***********************************
|
|
# Resume fonctions
|
|
# ***********************************
|
|
|
|
def insert_resume(self, meta):
|
|
title = self.str_conv(meta['title'])
|
|
site = QuotePlus(meta['site'])
|
|
# hoster = meta['hoster']
|
|
point = meta['point']
|
|
ex = "DELETE FROM resume WHERE hoster = '%s'" % site
|
|
self.dbcur.execute(ex)
|
|
ex = 'INSERT INTO resume (title, hoster, point) VALUES (?, ?, ?)'
|
|
self.dbcur.execute(ex, (title, site, point))
|
|
|
|
try:
|
|
self.db.commit()
|
|
VSlog('SQL INSERT resume Successfully')
|
|
except Exception:
|
|
VSlog('SQL ERROR INSERT')
|
|
pass
|
|
|
|
def get_resume(self, meta):
|
|
# title = self.str_conv(meta['title'])
|
|
site = QuotePlus(meta['site'])
|
|
|
|
sql_select = "SELECT * FROM resume WHERE hoster = '%s'" % site
|
|
|
|
try:
|
|
self.dbcur.execute(sql_select)
|
|
# matchedrow = self.dbcur.fetchone()
|
|
matchedrow = self.dbcur.fetchall()
|
|
return matchedrow
|
|
except Exception:
|
|
VSlog('SQL ERROR EXECUTE')
|
|
return None
|
|
|
|
def del_resume(self, meta):
|
|
site = QuotePlus(meta['site'])
|
|
|
|
sql_select = "DELETE FROM resume WHERE hoster = '%s'" % site
|
|
|
|
try:
|
|
self.dbcur.execute(sql_select)
|
|
self.db.commit()
|
|
return False, False
|
|
except Exception:
|
|
VSlog('SQL ERROR EXECUTE')
|
|
return False, False
|
|
|
|
|
|
# ***********************************
|
|
# Bookmark fonctions
|
|
# ***********************************
|
|
|
|
def insert_bookmark(self, meta):
|
|
|
|
title = self.str_conv(meta['title'])
|
|
siteurl = QuotePlus(meta['siteurl'])
|
|
|
|
try:
|
|
sIcon = meta['icon'].decode('UTF-8')
|
|
except:
|
|
sIcon = meta['icon']
|
|
|
|
try:
|
|
ex = 'INSERT INTO favorite (title, siteurl, site, fav, cat, icon, fanart) VALUES (?, ?, ?, ?, ?, ?, ?)'
|
|
self.dbcur.execute(ex, (title, siteurl, meta['site'], meta['fav'], meta['cat'], sIcon, meta['fanart']))
|
|
|
|
self.db.commit()
|
|
|
|
dialog().VSinfo(addon().VSlang(30042), meta['title'])
|
|
VSlog('SQL INSERT favorite Successfully')
|
|
except Exception as e:
|
|
if 'UNIQUE constraint failed' in e.message:
|
|
dialog().VSinfo(addon().VSlang(30043), meta['title'])
|
|
VSlog('SQL ERROR INSERT')
|
|
pass
|
|
|
|
def get_bookmark(self):
|
|
|
|
sql_select = 'SELECT * FROM favorite'
|
|
|
|
try:
|
|
self.dbcur.execute(sql_select)
|
|
# matchedrow = self.dbcur.fetchone()
|
|
matchedrow = self.dbcur.fetchall()
|
|
return matchedrow
|
|
except Exception:
|
|
VSlog('SQL ERROR EXECUTE')
|
|
return None
|
|
|
|
def del_bookmark(self, sSiteUrl='', sMovieTitle='', sCat = '', sAll = False):
|
|
|
|
sql_delete = None
|
|
|
|
# Tous supprimer
|
|
if sAll:
|
|
sql_delete = 'DELETE FROM favorite;'
|
|
|
|
# Supprimer un bookmark selon son titre
|
|
elif sMovieTitle:
|
|
siteUrl = QuotePlus(sSiteUrl)
|
|
title = self.str_conv(sMovieTitle)
|
|
title = title.replace("'", r"''")
|
|
sql_delete = "DELETE FROM favorite WHERE siteurl = '%s' AND title = '%s'" % (siteUrl, title)
|
|
|
|
# Supprimer un bookmark selon son url
|
|
elif sSiteUrl:
|
|
siteUrl = QuotePlus(sSiteUrl)
|
|
sql_delete = "DELETE FROM favorite WHERE siteurl = '%s'" % siteUrl
|
|
|
|
# Supprimer toute une catégorie
|
|
elif sCat:
|
|
sql_delete = "DELETE FROM favorite WHERE cat = '%s'" % sCat
|
|
|
|
|
|
if sql_delete:
|
|
from resources.lib.gui.gui import cGui
|
|
try:
|
|
self.dbcur.execute(sql_delete)
|
|
self.db.commit()
|
|
update = self.db.total_changes
|
|
|
|
if not update and sSiteUrl and sMovieTitle:
|
|
# si pas trouvé, on essaie sans le titre, seulement l'URL
|
|
return self.del_bookmark(sSiteUrl)
|
|
|
|
dialog().VSinfo(addon().VSlang(30044))
|
|
cGui().updateDirectory()
|
|
return False, False
|
|
except Exception:
|
|
VSlog('SQL ERROR EXECUTE')
|
|
return False, False
|
|
|
|
# ***********************************
|
|
# Download fonctions
|
|
# ***********************************
|
|
|
|
def insert_download(self, meta):
|
|
|
|
title = self.str_conv(meta['title'])
|
|
url = QuotePlus(meta['url'])
|
|
sIcon = QuotePlus(meta['icon'])
|
|
sPath = meta['path']
|
|
|
|
ex = 'INSERT INTO download (title, url, path, cat, icon, size, totalsize, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?)'
|
|
self.dbcur.execute(ex, (title,url, sPath,meta['cat'],sIcon, '', '', 0))
|
|
|
|
try:
|
|
self.db.commit()
|
|
VSlog('SQL INSERT download Successfully')
|
|
dialog().VSinfo(addon().VSlang(30042), meta['title'])
|
|
except Exception:
|
|
VSlog('SQL ERROR INSERT')
|
|
pass
|
|
|
|
def get_download(self, meta=''):
|
|
|
|
if meta == '':
|
|
sql_select = 'SELECT * FROM download'
|
|
else:
|
|
url = QuotePlus(meta['url'])
|
|
sql_select = "SELECT * FROM download WHERE url = '%s' AND status = '0'" % url
|
|
|
|
try:
|
|
self.dbcur.execute(sql_select)
|
|
matchedrow = self.dbcur.fetchall()
|
|
return matchedrow
|
|
except Exception:
|
|
VSlog('SQL ERROR EXECUTE')
|
|
return None
|
|
|
|
def clean_download(self):
|
|
|
|
sql_select = "DELETE FROM download WHERE status = '2'"
|
|
|
|
try:
|
|
self.dbcur.execute(sql_select)
|
|
self.db.commit()
|
|
return False, False
|
|
except Exception:
|
|
VSlog('SQL ERROR EXECUTE')
|
|
return False, False
|
|
|
|
def reset_download(self, meta):
|
|
|
|
url = QuotePlus(meta['url'])
|
|
sql_select = "UPDATE download SET status = '0' WHERE status = '2' AND url = '%s'" % url
|
|
|
|
try:
|
|
self.dbcur.execute(sql_select)
|
|
self.db.commit()
|
|
return False, False
|
|
except Exception:
|
|
VSlog('SQL ERROR EXECUTE')
|
|
return False, False
|
|
|
|
def del_download(self, meta):
|
|
|
|
if len(meta['url']) > 1:
|
|
url = QuotePlus(meta['url'])
|
|
sql_select = "DELETE FROM download WHERE url = '%s'" % url
|
|
elif len(meta['path']) > 1:
|
|
path = meta['path']
|
|
sql_select = "DELETE FROM download WHERE path = '%s'" % path
|
|
else:
|
|
return
|
|
|
|
try:
|
|
self.dbcur.execute(sql_select)
|
|
self.db.commit()
|
|
return False, False
|
|
except Exception:
|
|
VSlog('SQL ERROR EXECUTE')
|
|
return False, False
|
|
|
|
def cancel_download(self):
|
|
sql_select = "UPDATE download SET status = '0' WHERE status = '1'"
|
|
try:
|
|
self.dbcur.execute(sql_select)
|
|
self.db.commit()
|
|
return False, False
|
|
except Exception:
|
|
VSlog('SQL ERROR EXECUTE')
|
|
return False, False
|
|
|
|
def update_download(self, meta):
|
|
|
|
path = meta['path']
|
|
size = meta['size']
|
|
totalsize = meta['totalsize']
|
|
status = meta['status']
|
|
|
|
sql_select = "UPDATE download set size = '%s', totalsize = '%s', status= '%s' WHERE path = '%s'" % (size, totalsize, status, path)
|
|
|
|
try:
|
|
self.dbcur.execute(sql_select)
|
|
self.db.commit()
|
|
return False, False
|
|
except Exception:
|
|
VSlog('SQL ERROR EXECUTE')
|
|
return False, False
|