The branch, dharma has been updated
via d754deb91e502c1eb99bce506c5913d0b64daa9a (commit)
from 8fd256e7e7eb4b100a79667383e4cd52b584f79a (commit)
- Log -----------------------------------------------------------------
http://xbmc.git.sourceforge.net/git/gitweb.cgi?p=xbmc/scripts;a=commit;h=d754deb91e502c1eb99bce506c5913d0b64daa9a
commit d754deb91e502c1eb99bce506c5913d0b64daa9a
Author: amet <[email protected]>
Date: Tue Apr 19 13:03:17 2011 +0400
[script.moviequiz] -v0.3.2
- Improved support for XBMC Eden nightly builds
- Added support for Cinema Experience integration
- Use fanart instead of movie clips where relevant
- Improved data selection for some questions
- Added icons for replaying movie clip and exiting the game
- Removed 'When was episode first aired?' question as it's too difficult
- Removed French translation as it was outdated
diff --git a/script.moviequiz/addon.xml b/script.moviequiz/addon.xml
index 7e05626..14fb22c 100644
--- a/script.moviequiz/addon.xml
+++ b/script.moviequiz/addon.xml
@@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="script.moviequiz"
name="Movie Quiz"
- version="0.3.1"
+ version="0.3.2"
provider-name="twinther [[email protected]]">
<requires>
<import addon="xbmc.python"/>
<import addon="script.module.pysqlite" version="2.5.6"/>
<import addon="script.module.myconnpy" version="0.3.2"/>
+ <import addon="script.module.elementtree" version="1.2.7"/>
</requires>
<extension point="xbmc.python.script" library="addon.py"/>
<extension point="xbmc.addon.metadata">
diff --git a/script.moviequiz/changelog.txt b/script.moviequiz/changelog.txt
index 844e1ba..9e02fcd 100644
--- a/script.moviequiz/changelog.txt
+++ b/script.moviequiz/changelog.txt
@@ -1,3 +1,12 @@
+[B]Version 0.3.2 - 2011-04-17[/B]
+- Improved support for XBMC Eden nightly builds
+- Added support for Cinema Experience integration
+- Use fanart instead of movie clips where relevant
+- Improved data selection for some questions
+- Added icons for replaying movie clip and exiting the game
+- Removed 'When was episode first aired?' question as it's too difficult
+- Removed French translation as it was outdated
+
[B]Version 0.3.1 - 2011-03-27[/B]
- Added support for XBMC Eden nightly builds
- Fixed Imdb data download
diff --git a/script.moviequiz/quizlib/db.py b/script.moviequiz/quizlib/db.py
index 8f1782c..07fa07b 100644
--- a/script.moviequiz/quizlib/db.py
+++ b/script.moviequiz/quizlib/db.py
@@ -1,8 +1,17 @@
from elementtree import ElementTree
-from pysqlite2 import dbapi2 as sqlite3
+from xml.parsers.expat import ExpatError
+
import os
import xbmc
import mysql.connector
+import glob
+
+try:
+ # Used by Eden/external python
+ from sqlite3 import dbapi2 as sqlite3
+except:
+ # Used by Dharma/internal python
+ from pysqlite2 import dbapi2 as sqlite3
__author__ = 'twinther'
@@ -154,10 +163,9 @@ class SQLiteDatabase(Database):
found = True
db_file = None
- candidates = [
- 'MyVideos48.db', # Eden
- 'MyVideos34.db' # Dharma
- ]
+ # Find newest MyVideos.db and use that
+ candidates = glob.glob(settings['host'] + '/MyVideos*.db')
+ list.sort(candidates, reverse=True)
if settings.has_key('name') and settings['name'] is not None:
candidates.insert(0, settings['name'] + '.db') # defined in
settings
@@ -172,7 +180,7 @@ class SQLiteDatabase(Database):
return
xbmc.log("Connecting to SQLite database file: %s" % db_file)
- self.conn = sqlite3.connect(db_file)
+ self.conn = sqlite3.connect(db_file, check_same_thread = False)
self.conn.row_factory = self._sqlite_dict_factory
xbmc.log("SQLiteDatabase opened")
@@ -224,19 +232,23 @@ def _loadSettings():
advancedSettings =
xbmc.translatePath('special://userdata/advancedsettings.xml')
if os.path.exists(advancedSettings):
f = open(advancedSettings)
- doc = ElementTree.fromstring(f.read())
+ xml = f.read()
f.close()
-
- if doc.findtext('videodatabase/type') is not None:
- settings['type'] = doc.findtext('videodatabase/type')
- if doc.findtext('videodatabase/host') is not None:
- settings['host'] = doc.findtext('videodatabase/host')
- if doc.findtext('videodatabase/name') is not None:
- settings['name'] = doc.findtext('videodatabase/name')
- if doc.findtext('videodatabase/user') is not None:
- settings['user'] = doc.findtext('videodatabase/user')
- if doc.findtext('videodatabase/pass') is not None:
- settings['pass'] = doc.findtext('videodatabase/pass')
+ try:
+ doc = ElementTree.fromstring(xml)
+
+ if doc.findtext('videodatabase/type') is not None:
+ settings['type'] = doc.findtext('videodatabase/type')
+ if doc.findtext('videodatabase/host') is not None:
+ settings['host'] = doc.findtext('videodatabase/host')
+ if doc.findtext('videodatabase/name') is not None:
+ settings['name'] = doc.findtext('videodatabase/name')
+ if doc.findtext('videodatabase/user') is not None:
+ settings['user'] = doc.findtext('videodatabase/user')
+ if doc.findtext('videodatabase/pass') is not None:
+ settings['pass'] = doc.findtext('videodatabase/pass')
+ except ExpatError:
+ xbmc.log("Unable to parse advancedsettings.xml")
return settings
-
\ No newline at end of file
+
diff --git a/script.moviequiz/quizlib/gui.py b/script.moviequiz/quizlib/gui.py
index f09031c..f89f59f 100644
--- a/script.moviequiz/quizlib/gui.py
+++ b/script.moviequiz/quizlib/gui.py
@@ -1,5 +1,7 @@
import threading
import os
+import re
+
import xbmc
import xbmcgui
@@ -10,6 +12,10 @@ from strings import *
__author__ = 'twinther'
+# Constants from [xbmc]/xbmc/guilib/Key.h
+ACTION_PARENT_DIR = 9
+ACTION_PREVIOUS_MENU = 10
+
class MenuGui(xbmcgui.WindowXML):
C_MENU_MOVIE_QUIZ = 4001
C_MENU_TVSHOW_QUIZ = 4002
@@ -78,7 +84,7 @@ class MenuGui(xbmcgui.WindowXML):
self.getControl(self.C_MENU_COLLECTION_TRIVIA).setLabel(label)
def onAction(self, action):
- if action.getId() == 9 or action.getId() == 10:
+ if action.getId() == ACTION_PARENT_DIR or action.getId() ==
ACTION_PREVIOUS_MENU:
self.close()
def onClick(self, controlId):
@@ -119,6 +125,8 @@ class MenuGui(xbmcgui.WindowXML):
class QuizGui(xbmcgui.WindowXML):
C_MAIN_FIRST_ANSWER = 4000
C_MAIN_LAST_ANSWER = 4003
+ C_MAIN_REPLAY = 4010
+ C_MAIN_EXIT = 4011
C_MAIN_CORRECT_SCORE = 4101
C_MAIN_INCORRECT_SCORE = 4103
C_MAIN_QUESTION_COUNT = 4104
@@ -138,6 +146,7 @@ class QuizGui(xbmcgui.WindowXML):
C_MAIN_CORRECT_VISIBILITY = 5002
C_MAIN_INCORRECT_VISIBILITY = 5003
C_MAIN_LOADING_VISIBILITY = 5005
+ C_MAIN_REPLAY_BUTTON_VISIBILITY = 5007
def __init__(self, xmlFilename, scriptPath, addon, type, questionLimit =
-1, maxRating = None, interactive = True):
@@ -149,6 +158,12 @@ class QuizGui(xbmcgui.WindowXML):
self.maxRating = maxRating
self.interactive = interactive
+ path = self.addon.getAddonInfo('path')
+ if self.type == question.TYPE_TV:
+ self.defaultBackground = os.path.join(path, 'resources', 'skins',
'Default', 'media', 'quiz-background-tvshows.png')
+ else:
+ self.defaultBackground = os.path.join(path, 'resources', 'skins',
'Default', 'media', 'quiz-background.png')
+
self.database = db.connect()
self.player = player.TenSecondPlayer(database=self.database)
self.question = question.Question(self.database, None, None, None)
@@ -156,7 +171,9 @@ class QuizGui(xbmcgui.WindowXML):
self.score = {'correct': 0, 'wrong': 0}
self.maxRating = None
- if self.type == question.TYPE_MOVIE and
self.addon.getSetting('movie.rating.limit.enabled') == 'true':
+ if maxRating is not None:
+ self.maxRating = maxRating
+ elif self.type == question.TYPE_MOVIE and
self.addon.getSetting('movie.rating.limit.enabled') == 'true':
self.maxRating = self.addon.getSetting('movie.rating.limit')
elif self.type == question.TYPE_TV and
self.addon.getSetting('tvshow.rating.limit.enabled') == 'true':
self.maxRating = self.addon.getSetting('tvshow.rating.limit')
@@ -166,35 +183,40 @@ class QuizGui(xbmcgui.WindowXML):
try :
xbmcgui.lock()
if self.type == question.TYPE_TV:
- self.getControl(self.C_MAIN_MOVIE_BACKGROUND).setVisible(False)
+
self.getControl(self.C_MAIN_MOVIE_BACKGROUND).setImage(self.defaultBackground)
finally:
xbmcgui.unlock()
self._setup_question()
def close(self):
- if hasattr(self, 'player') and self.player.isPlaying():
+ if self.player and self.player.isPlaying():
self.player.stop()
# TODO self.database.close()
xbmcgui.WindowXML.close(self)
def onAction(self, action):
- if action.getId() == 9 or action.getId() == 10:
+ if action.getId() == ACTION_PARENT_DIR or action.getId() ==
ACTION_PREVIOUS_MENU:
self._game_over()
self.close()
+
def onClick(self, controlId):
if not self.interactive:
return # ignore
- if hasattr(self, 'question') and (controlId >=
self.C_MAIN_FIRST_ANSWER or controlId <= self.C_MAIN_LAST_ANSWER):
+ if self.question and (controlId >= self.C_MAIN_FIRST_ANSWER and
controlId <= self.C_MAIN_LAST_ANSWER):
answer = self.question.getAnswer(controlId -
self.C_MAIN_FIRST_ANSWER)
self._handle_answer(answer)
self._setup_question()
+ elif controlId == self.C_MAIN_EXIT:
+ self._game_over()
+ elif controlId == self.C_MAIN_REPLAY:
+ self.player.replay()
#noinspection PyUnusedLocal
def onFocus(self, controlId):
- self._update_thumb()
+ self._update_thumb(controlId)
def _game_over(self):
if self.interactive:
@@ -225,10 +247,10 @@ class QuizGui(xbmcgui.WindowXML):
button = self.getControl(self.C_MAIN_FIRST_ANSWER + idx)
if idx >= len(answers):
button.setLabel('')
- button.setEnabled(False)
+ button.setVisible(False)
else:
button.setLabel(answers[idx].text, textColor='0xFFFFFFFF')
- button.setEnabled(True)
+ button.setVisible(True)
if not self.interactive and answers[idx].correct:
# highlight correct answer
@@ -237,50 +259,40 @@ class QuizGui(xbmcgui.WindowXML):
self._update_thumb()
self._update_stats()
+ print self.question.getFanartFile()
+ if self.question.getFanartFile() is not None and
os.path.exists(self.question.getFanartFile()):
+
self.getControl(self.C_MAIN_MOVIE_BACKGROUND).setImage(self.question.getFanartFile())
+ else:
+
self.getControl(self.C_MAIN_MOVIE_BACKGROUND).setImage(self.defaultBackground)
+
correctAnswer = self.question.getCorrectAnswer()
if self.question.getDisplay() == question.DISPLAY_VIDEO:
- self.show(self.C_MAIN_VIDEO_VISIBILITY)
- self.hide(self.C_MAIN_PHOTO_VISIBILITY)
- self.hide(self.C_MAIN_QUOTE_VISIBILITY)
- self.hide(self.C_MAIN_THREE_PHOTOS_VISIBILITY)
+ self._changeVisibility(video = True)
xbmc.sleep(1500) # give skin animation time to execute
self.player.playWindowed(self.question.getVideoFile(),
correctAnswer.idFile)
elif self.question.getDisplay() == question.DISPLAY_PHOTO:
self.getControl(self.C_MAIN_PHOTO).setImage(self.question.getPhotoFile())
-
- self.hide(self.C_MAIN_VIDEO_VISIBILITY)
- self.show(self.C_MAIN_PHOTO_VISIBILITY)
- self.hide(self.C_MAIN_QUOTE_VISIBILITY)
- self.hide(self.C_MAIN_THREE_PHOTOS_VISIBILITY)
+ self._changeVisibility(photo = True)
elif self.question.getDisplay() == question.DISPLAY_QUOTE:
-
self.getControl(self.C_MAIN_QUOTE_LABEL).setText(self.question.getQuoteText())
-
- self.hide(self.C_MAIN_VIDEO_VISIBILITY)
- self.hide(self.C_MAIN_PHOTO_VISIBILITY)
- self.show(self.C_MAIN_QUOTE_VISIBILITY)
- self.hide(self.C_MAIN_THREE_PHOTOS_VISIBILITY)
+ quoteText = self.question.getQuoteText()
+ quoteText = self._obfuscateQuote(quoteText)
+ self.getControl(self.C_MAIN_QUOTE_LABEL).setText(quoteText)
+ self._changeVisibility(quote = True)
elif self.question.getDisplay() == question.DISPLAY_NONE:
- self.hide(self.C_MAIN_VIDEO_VISIBILITY)
- self.hide(self.C_MAIN_PHOTO_VISIBILITY)
- self.hide(self.C_MAIN_QUOTE_VISIBILITY)
- self.hide(self.C_MAIN_THREE_PHOTOS_VISIBILITY)
+ self._changeVisibility()
elif self.question.getDisplay() == question.DISPLAY_THREE_PHOTOS:
self.getControl(self.C_MAIN_PHOTO_1).setImage(self.question.getPhotoFile(0))
self.getControl(self.C_MAIN_PHOTO_2).setImage(self.question.getPhotoFile(1))
self.getControl(self.C_MAIN_PHOTO_3).setImage(self.question.getPhotoFile(2))
-
- self.hide(self.C_MAIN_VIDEO_VISIBILITY)
- self.hide(self.C_MAIN_PHOTO_VISIBILITY)
- self.hide(self.C_MAIN_QUOTE_VISIBILITY)
- self.show(self.C_MAIN_THREE_PHOTOS_VISIBILITY)
+ self._changeVisibility(threePhotos = True)
if not self.interactive:
# answers correctly in ten seconds
- threading.Timer(3.0, self._answer_correctly).start()
+ threading.Timer(10.0, self._answer_correctly).start()
self.getControl(self.C_MAIN_LOADING_VISIBILITY).setVisible(False)
@@ -311,10 +323,10 @@ class QuizGui(xbmcgui.WindowXML):
def _handle_answer(self, answer):
if answer is not None and answer.correct:
self.score['correct'] += 1
- self.show(self.C_MAIN_CORRECT_VISIBILITY)
+ self.getControl(self.C_MAIN_CORRECT_VISIBILITY).setVisible(False)
else:
self.score['wrong'] += 1
- self.show(self.C_MAIN_INCORRECT_VISIBILITY)
+ self.getControl(self.C_MAIN_INCORRECT_VISIBILITY).setVisible(False)
if self.player.isPlaying():
self.player.stop()
@@ -328,6 +340,10 @@ class QuizGui(xbmcgui.WindowXML):
else:
self.getControl(self.C_MAIN_FIRST_ANSWER +
idx).setLabel(textColor='0x88888888')
+ if self.question.getDisplay() == question.DISPLAY_QUOTE:
+ # Display non-obfuscated quote text
+
self.getControl(self.C_MAIN_QUOTE_LABEL).setText(self.question.getQuoteText())
+
xbmc.sleep(3000)
def _update_stats(self):
@@ -341,11 +357,12 @@ class QuizGui(xbmcgui.WindowXML):
label.setLabel('')
- def _update_thumb(self):
+ def _update_thumb(self, controlId = None):
if self.question is None:
return # not initialized yet
- controlId = self.getFocusId()
+ if controlId is None:
+ controlId = self.getFocusId()
if controlId >= self.C_MAIN_FIRST_ANSWER or controlId <=
self.C_MAIN_LAST_ANSWER:
answer = self.question.getAnswer(controlId -
self.C_MAIN_FIRST_ANSWER)
coverImage = self.getControl(self.C_MAIN_COVER_IMAGE)
@@ -360,14 +377,34 @@ class QuizGui(xbmcgui.WindowXML):
coverImage.setVisible(False)
def _hide_icons(self):
- self.hide(self.C_MAIN_CORRECT_VISIBILITY)
- self.hide(self.C_MAIN_INCORRECT_VISIBILITY)
+ """Visibility is inverted in skin
+ """
+ self.getControl(self.C_MAIN_CORRECT_VISIBILITY).setVisible(True)
+ self.getControl(self.C_MAIN_INCORRECT_VISIBILITY).setVisible(True)
+
+ def _changeVisibility(self, video = False, photo = False, quote = False,
threePhotos = False):
+ """Visibility is inverted in skin
+ """
+ self.getControl(self.C_MAIN_VIDEO_VISIBILITY).setVisible(not video)
+ self.getControl(self.C_MAIN_PHOTO_VISIBILITY).setVisible(not photo)
+ self.getControl(self.C_MAIN_QUOTE_VISIBILITY).setVisible(not quote)
+ self.getControl(self.C_MAIN_THREE_PHOTOS_VISIBILITY).setVisible(not
threePhotos)
+
+ self.getControl(self.C_MAIN_REPLAY_BUTTON_VISIBILITY).setVisible(video)
+
+ def _obfuscateQuote(self, quote):
+ names = list()
+ for m in re.finditer('(.*?\:)', quote):
+ name = m.group(1)
+ if not name in names:
+ names.append(name)
+
+ for idx, name in enumerate(names):
+ repl = '#%d:' % (idx + 1)
+ quote = quote.replace(name, repl)
- def show(self, controlId):
- self.getControl(controlId).setVisible(False) # Visibility is inverted
in skin
+ return quote
- def hide(self, controlId):
- self.getControl(controlId).setVisible(True) # Visibility is inverted
in skin
class ClapperDialog(xbmcgui.WindowXMLDialog):
diff --git a/script.moviequiz/quizlib/imdb.py b/script.moviequiz/quizlib/imdb.py
index de6ebc7..b77d74e 100644
--- a/script.moviequiz/quizlib/imdb.py
+++ b/script.moviequiz/quizlib/imdb.py
@@ -10,22 +10,44 @@ import xbmc
import xbmcgui
import xbmcaddon
-
class Imdb(object):
+ ACTOR_PATTERN = re.compile('^([^\t\(]+)( \([^\)]+\))?\t.*?$')
+
QUOTES_LIST = 'quotes.list'
- FILES = [
- {'name' : QUOTES_LIST, 'url' :
'http://ftp.sunet.se/pub/tv+movies/imdb/quotes.list.gz'}
- ]
+ QUOTES_URL = 'http://ftp.sunet.se/pub/tv+movies/imdb/quotes.list.gz'
+ ACTORS_LIST = 'actors.list'
+ ACTORS_URL = 'http://ftp.sunet.se/pub/tv+movies/imdb/actors.list.gz'
def __init__(self, listsPath):
self.path = listsPath
- def downloadFiles(self, progressCallback):
- for file in self.FILES:
- self._downloadGzipFile(file['url'], file['name'], progressCallback)
-
+ actorsPath = os.path.join(self.path, self.ACTORS_LIST)
+ if os.path.exists(actorsPath):
+ f = open(actorsPath)
+ self.actorsData = f.read()
+ f.close()
+ else:
+ self.actorsData = None
+
+
+ def downloadFiles(self, progressCallback = None):
+ self._downloadGzipFile(self.QUOTES_URL, self.QUOTES_LIST,
progressCallback)
+ self._downloadGzipFile(self.ACTORS_URL, self.ACTORS_LIST,
progressCallback, self._postprocessActorNames)
- def _downloadGzipFile(self, url, destination, progressCallback):
+
+ def _postprocessActorNames(self, line):
+ m = self.ACTOR_PATTERN.search(line)
+ if m is not None:
+ lastnameFirstname = m.group(1).strip()
+ parts = lastnameFirstname.split(', ', 2)
+ if len(parts) == 2:
+ firstnameLastname = "%s %s\n" % (parts[1], parts[0])
+ return firstnameLastname
+
+ return ''
+
+
+ def _downloadGzipFile(self, url, destination, progressCallback = None,
postprocessLineCallback = None):
"""
Downloads a gzip compressed file and extracts it on the fly.
@@ -38,6 +60,8 @@ class Imdb(object):
file = open(os.path.join(self.path, destination), 'wb')
decompressor = zlib.decompressobj(16+zlib.MAX_WBITS)
+ partialLine = None
+ previousLine = None
contentReceived = 0
contentLength = int(response.info()['Content-Length'])
while True:
@@ -46,40 +70,50 @@ class Imdb(object):
break
contentReceived += len(chunk)
decompressedChunk = decompressor.decompress(chunk)
- file.write(decompressedChunk)
- percentage = int(contentReceived * 100 / contentLength)
- if not progressCallback(contentReceived, contentLength,
percentage):
- break
+ if postprocessLineCallback is not None:
+ if partialLine is not None:
+ decompressedChunk = partialLine + decompressedChunk
+ partialLine = None
+
+ lines = decompressedChunk.splitlines(True)
+ processedChunk = ''
+
+ for line in lines:
+ if line[-1:] == '\n': # We have a complete line
+ processedLine = postprocessLineCallback(line)
+ if processedLine != previousLine and processedLine !=
'':
+ previousLine = processedLine
+ processedChunk += processedLine
+ else: # partial line
+ partialLine = line
+ file.write(processedChunk)
+
+ else:
+ file.write(decompressedChunk)
+
+ if progressCallback is not None:
+ percentage = int(contentReceived * 100 / contentLength)
+ if not progressCallback(contentReceived, contentLength,
percentage):
+ break
file.close()
response.close()
- def getRandomQuote(self, movie, obfuscate = True):
+ def getRandomQuote(self, movie, maxLength = None):
quotes = self._parseMovieQuotes(movie)
if quotes is None:
return None
- quote = quotes[random.randint(0, len(quotes)-1)]
- quote = self._filterAndCleanup(quote)
- if obfuscate:
- quote = self.obfuscateQuote(quote)
-
- return quote
-
- def obfuscateQuote(self, quote):
- names = list()
- for m in re.finditer('(.*?\:)', quote):
- name = m.group(1)
- if not name in names:
- names.append(name)
-
- print names
- for idx, name in enumerate(names):
- repl = '#%d:' % (idx + 1)
- quote = quote.replace(name, repl)
+ quote = None
+ retries = 0
+ while retries < 10:
+ retries += 1
+ quote = quotes[random.randint(0, len(quotes)-1)]
+ if maxLength is None or len(quote) < maxLength:
+ break
- print "Quote: %s" % quote
+ quote = self._filterAndCleanup(quote)
return quote
@@ -91,7 +125,6 @@ class Imdb(object):
pattern = '\n# %s [^\n]+\n(.*?)\n\n#' % movie
path = os.path.join(self.path, self.QUOTES_LIST)
-
if os.path.exists(path):
f = open(path)
@@ -110,6 +143,14 @@ class Imdb(object):
xbmc.log("%s does not exists, has it been downloaded yet?" %
self.QUOTES_LIST)
return None
+ def isActor(self, name):
+ if self.actorsData is not None:
+ m = re.search('^%s$' % name, self.actorsData, re.MULTILINE)
+ return m is not None
+ else:
+ # if we don't have data all actors are Female
+ return False
+
if __name__ == '__main__':
# this script is invoked from addon settings
diff --git a/script.moviequiz/quizlib/player.py
b/script.moviequiz/quizlib/player.py
index d62ed8b..43a2127 100644
--- a/script.moviequiz/quizlib/player.py
+++ b/script.moviequiz/quizlib/player.py
@@ -18,12 +18,23 @@ class TenSecondPlayer(xbmc.Player):
xbmc.Player.__init__(self)
xbmc.log(">> TenSecondPlayer.__init__()")
self.tenSecondTimer = None
- self.startTime = None
self.database = database
self.bookmark = None
self.startingPlayback = False
+ self.replaying = False
+ self.lastFile = None
+ self.lastIdFile = None
+ self.lastStartTime = None
+
+ def replay(self):
+ xbmc.log(">> TenSecondPlayer.replay()")
+ if self.lastFile is not None:
+ self.replaying = True
+ self.playWindowed(self.lastFile, self.lastIdFile)
+ self.replaying = False
+
def stop(self):
"""
Cancels the Timer in case it's active and stars a new Timer for a
delayed stop.
@@ -56,6 +67,13 @@ class TenSecondPlayer(xbmc.Player):
"""
xbmc.log(">> TenSecondPlayer.playWindowed()")
self.startingPlayback = True
+
+ self.lastFile = file
+ self.lastIdFile= idFile
+
+ if not self.replaying:
+ self.lastStartTime = None
+
if self.tenSecondTimer is not None:
#self.stop()
self.tenSecondTimer.cancel()
@@ -119,12 +137,16 @@ class TenSecondPlayer(xbmc.Player):
def onPlayBackStarted(self):
xbmc.log(">> TenSecondPlayer.onPlayBackStarted()")
- totalTime = self.getTotalTime()
- # find start time, ignore first 10% and last 20% of movie
- self.startTime = random.randint(int(totalTime * 0.1), int(totalTime *
0.8))
+ if self.lastStartTime is not None:
+ startTime = self.lastStartTime
+ else:
+ totalTime = self.getTotalTime()
+ # find start time, ignore first 10% and last 20% of movie
+ startTime = random.randint(int(totalTime * 0.1), int(totalTime *
0.8))
+ self.lastStartTime = startTime
- xbmc.log(">> Playback from %d secs. to %d secs." % (self.startTime,
self.startTime + 10))
- self.seekTime(self.startTime)
+ xbmc.log(">> Playback from %d secs. to %d secs." % (startTime,
startTime + 10))
+ self.seekTime(startTime)
self.tenSecondTimer = threading.Timer(10.0, self.onTenSecondsPassed)
self.tenSecondTimer.start()
diff --git a/script.moviequiz/quizlib/question.py
b/script.moviequiz/quizlib/question.py
index 66b15be..f1560b4 100644
--- a/script.moviequiz/quizlib/question.py
+++ b/script.moviequiz/quizlib/question.py
@@ -38,11 +38,15 @@ class Answer(object):
self.coverFile = thumb.getCachedVideoThumb(path, filename)
class Question(object):
+ ADDON = xbmcaddon.Addon(id = 'script.moviequiz')
+ IMDB = imdb.Imdb(ADDON.getAddonInfo('profile'))
+
def __init__(self, database, display, maxRating, onlyWatchedMovies):
self.database = database
self.answers = list()
self.text = None
self.videoFile = None
+ self.fanartFile = None
self.photos = list()
self.quoteText = None
@@ -61,9 +65,9 @@ class Question(object):
return self.answers
def getAnswer(self, idx):
- if idx < len(self.answers):
+ try:
return self.answers[idx]
- else:
+ except IndexError:
return None
def getCorrectAnswer(self):
@@ -96,6 +100,12 @@ class Question(object):
def getQuoteText(self):
return self.quoteText
+ def setFanartFile(self, path, filename = None):
+ self.fanartFile = thumb.getCachedVideoFanart(path, filename)
+
+ def getFanartFile(self):
+ return self.fanartFile
+
def _get_movie_ids(self):
movieIds = list()
for movie in self.answers:
@@ -222,7 +232,6 @@ class ActorNotInMovieQuestion(MovieQuestion):
""" % (self._get_max_rating_clause(),
self._get_watched_movies_clause()))
# try to find an actor with a cached photo (if non are found we bail
out)
for row in rows:
- print row['strActor']
photoFile = thumb.getCachedActorThumb(row['strActor'])
if os.path.exists(photoFile):
actor = row
@@ -270,7 +279,7 @@ class WhatYearWasMovieReleasedQuestion(MovieQuestion):
WhatYearWasMovieReleasedQuestion
"""
def __init__(self, database, maxRating, onlyWatchedMovies):
- MovieQuestion.__init__(self, database, DISPLAY_VIDEO, maxRating,
onlyWatchedMovies)
+ MovieQuestion.__init__(self, database, DISPLAY_NONE, maxRating,
onlyWatchedMovies)
row = self.database.fetchone("""
SELECT mv.idFile, mv.c00 AS title, mv.c07 AS year, mv.strPath,
mv.strFileName
@@ -303,7 +312,8 @@ class WhatYearWasMovieReleasedQuestion(MovieQuestion):
self.answers.append(a)
self.text = strings(Q_WHAT_YEAR_WAS_MOVIE_RELEASED, row['title'])
- self.setVideoFile(row['strPath'], row['strFileName'])
+# self.setVideoFile(row['strPath'], row['strFileName'])
+ self.setFanartFile(row['strPath'], row['strFileName'])
class WhatTagLineBelongsToMovieQuestion(MovieQuestion):
@@ -311,7 +321,7 @@ class WhatTagLineBelongsToMovieQuestion(MovieQuestion):
WhatTagLineBelongsToMovieQuestion
"""
def __init__(self, database, maxRating, onlyWatchedMovies):
- MovieQuestion.__init__(self, database, DISPLAY_VIDEO, maxRating,
onlyWatchedMovies)
+ MovieQuestion.__init__(self, database, DISPLAY_NONE, maxRating,
onlyWatchedMovies)
row = self.database.fetchone("""
SELECT mv.idMovie, mv.idFile, mv.c00 AS title, mv.c03 AS tagline,
mv.strPath, mv.strFileName
@@ -339,7 +349,8 @@ class WhatTagLineBelongsToMovieQuestion(MovieQuestion):
random.shuffle(self.answers)
self.text = strings(Q_WHAT_TAGLINE_BELONGS_TO_MOVIE, row['title'])
- self.setVideoFile(row['strPath'], row['strFileName'])
+# self.setVideoFile(row['strPath'], row['strFileName'])
+ self.setFanartFile(row['strPath'], row['strFileName'])
class WhoDirectedThisMovieQuestion(MovieQuestion):
@@ -347,7 +358,7 @@ class WhoDirectedThisMovieQuestion(MovieQuestion):
WhoDirectedThisMovieQuestion
"""
def __init__(self, database, maxRating, onlyWatchedMovies):
- MovieQuestion.__init__(self, database, DISPLAY_VIDEO, maxRating,
onlyWatchedMovies)
+ MovieQuestion.__init__(self, database, DISPLAY_NONE, maxRating,
onlyWatchedMovies)
row = self.database.fetchone("""
SELECT idActor, a.strActor, mv.idFile, mv.c00 AS title,
mv.strPath, mv.strFileName
@@ -373,7 +384,8 @@ class WhoDirectedThisMovieQuestion(MovieQuestion):
random.shuffle(self.answers)
self.text = strings(Q_WHO_DIRECTED_THIS_MOVIE, row['title'])
- self.setVideoFile(row['strPath'], row['strFileName'])
+# self.setVideoFile(row['strPath'], row['strFileName'])
+ self.setFanartFile(row['strPath'], row['strFileName'])
class WhatStudioReleasedMovieQuestion(MovieQuestion):
@@ -381,7 +393,7 @@ class WhatStudioReleasedMovieQuestion(MovieQuestion):
WhatStudioReleasedMovieQuestion
"""
def __init__(self, database, maxRating, onlyWatchedMovies):
- MovieQuestion.__init__(self, database, DISPLAY_VIDEO, maxRating,
onlyWatchedMovies)
+ MovieQuestion.__init__(self, database, DISPLAY_NONE, maxRating,
onlyWatchedMovies)
row = self.database.fetchone("""
SELECT s.idStudio, s.strStudio, mv.idFile, mv.c00 AS title,
mv.strPath, mv.strFileName
@@ -394,11 +406,11 @@ class WhatStudioReleasedMovieQuestion(MovieQuestion):
a.setCoverFile(row['strPath'], row['strFileName'])
self.answers.append(a)
- # todo only select movie studios
otherAnswers = self.database.fetchall("""
SELECT s.idStudio, s.strStudio
FROM studio s
WHERE s.idStudio != ?
+ AND s.idStudio IN (SELECT idStudio FROM studiolinkmovie)
ORDER BY random() LIMIT 3
""", row['idStudio'])
for movie in otherAnswers:
@@ -408,7 +420,8 @@ class WhatStudioReleasedMovieQuestion(MovieQuestion):
random.shuffle(self.answers)
self.text = strings(Q_WHAT_STUDIO_RELEASED_MOVIE, row['title'])
- self.setVideoFile(row['strPath'], row['strFileName'])
+# self.setVideoFile(row['strPath'], row['strFileName'])
+ self.setFanartFile(row['strPath'], row['strFileName'])
class WhatActorIsThisQuestion(MovieQuestion):
@@ -447,10 +460,17 @@ class WhatActorIsThisQuestion(MovieQuestion):
actors = self.database.fetchall("""
SELECT a.idActor, a.strActor
FROM actors a, actorlinkmovie alm WHERE a.idActor = alm.idActor
AND a.idActor != ?
- ORDER BY random() LIMIT 3
+ ORDER BY random() LIMIT 50
""", actor['idActor'])
+
+ # Check gender
+ actorGender = self.IMDB.isActor(actor['strActor'])
+
for actor in actors:
- self.answers.append(Answer(False, actor['idActor'],
actor['strActor']))
+ if self.IMDB.isActor(actor['strActor']) == actorGender:
+ self.answers.append(Answer(False, actor['idActor'],
actor['strActor']))
+ if len(self.answers) == 4:
+ break
random.shuffle(self.answers)
self.text = strings(Q_WHAT_ACTOR_IS_THIS)
@@ -461,7 +481,7 @@ class WhoPlayedRoleInMovieQuestion(MovieQuestion):
WhoPlayedRoleInMovieQuestion
"""
def __init__(self, database, maxRating, onlyWatchedMovies):
- MovieQuestion.__init__(self, database, DISPLAY_VIDEO, maxRating,
onlyWatchedMovies)
+ MovieQuestion.__init__(self, database, DISPLAY_NONE, maxRating,
onlyWatchedMovies)
row = self.database.fetchone("""
SELECT alm.idActor, a.strActor, alm.strRole, mv.idMovie, mv.c00 AS
title, mv.strPath, mv.strFileName, mv.c14 AS genre
@@ -497,7 +517,8 @@ class WhoPlayedRoleInMovieQuestion(MovieQuestion):
self.text = strings(Q_WHO_VOICES_ROLE_IN_MOVIE) % (role,
row['title'])
else:
self.text = strings(Q_WHO_PLAYS_ROLE_IN_MOVIE) % (role,
row['title'])
- self.setVideoFile(row['strPath'], row['strFileName'])
+# self.setVideoFile(row['strPath'], row['strFileName'])
+ self.setFanartFile(row['strPath'], row['strFileName'])
class WhatMovieIsThisQuoteFrom(MovieQuestion):
@@ -506,10 +527,6 @@ class WhatMovieIsThisQuoteFrom(MovieQuestion):
"""
def __init__(self, database, maxRating, onlyWatchedMovies):
MovieQuestion.__init__(self, database, DISPLAY_QUOTE, maxRating,
onlyWatchedMovies)
- # todo limit length of quotes
- addon = xbmcaddon.Addon(id = 'script.moviequiz') # TODO
- i = imdb.Imdb(addon.getAddonInfo('profile'))
-
rows = self.database.fetchall("""
SELECT mv.idMovie, mv.c00 AS title, mv.c07 AS year, mv.strPath,
mv.strFileName
FROM movieview mv
@@ -520,7 +537,7 @@ class WhatMovieIsThisQuoteFrom(MovieQuestion):
quoteText = None
row = None
for r in rows:
- quoteText = i.getRandomQuote(r['title'])
+ quoteText = Question.IMDB.getRandomQuote(r['title'], maxLength =
256)
if quoteText is not None:
row = r
@@ -556,7 +573,6 @@ class WhatMovieIsNewestQuestion(MovieQuestion):
"""
def __init__(self, database, maxRating, onlyWatchedMovies):
MovieQuestion.__init__(self, database, DISPLAY_NONE, maxRating,
onlyWatchedMovies)
- # todo make sure not to select one of the 3 oldest movies
row = self.database.fetchone("""
SELECT mv.idMovie, mv.idFile, mv.c00 AS title, mv.strPath,
mv.strFileName, mv.c07 AS year
FROM movieview mv
@@ -575,6 +591,9 @@ class WhatMovieIsNewestQuestion(MovieQuestion):
%s %s
ORDER BY random() LIMIT 3
""" % (self._get_max_rating_clause(),
self._get_watched_movies_clause()), row['year'])
+ if len(movies) < 3:
+ raise QuestionException("Less than 3 movies found; bailing out")
+
for movie in movies:
a = Answer(False, movie['idMovie'], movie['title'])
a.setCoverFile(movie['strPath'], movie['strFileName'])
@@ -752,6 +771,7 @@ class WhatTVShowIsThisQuestion(TVQuestion):
random.shuffle(self.answers)
self.text = strings(Q_WHAT_TVSHOW_IS_THIS)
self.setVideoFile(row['strPath'], row['strFileName'])
+# self.setFanartFile(row['strPath'], row['strFileName'])
class WhatSeasonIsThisQuestion(TVQuestion):
@@ -790,6 +810,8 @@ class WhatSeasonIsThisQuestion(TVQuestion):
self.text = strings(Q_WHAT_SEASON_IS_THIS) % row['title']
self.setVideoFile(row['strPath'], row['strFileName'])
+# self.setFanartFile(row['strPath'], row['strFileName'])
+
class WhatEpisodeIsThisQuestion(TVQuestion):
"""
@@ -831,48 +853,7 @@ class WhatEpisodeIsThisQuestion(TVQuestion):
self.text = strings(Q_WHAT_EPISODE_IS_THIS) % row['title']
self.setVideoFile(row['strPath'], row['strFileName'])
-
-
-class WhenWasEpisodeFirstAiredQuestion(TVQuestion):
- """
- WhenWasEpisodeFirstAiredQuestion
- """
-
- def __init__(self, database, maxRating, onlyWatchedMovies):
- TVQuestion.__init__(self, database, DISPLAY_VIDEO, maxRating,
onlyWatchedMovies)
-
- row = self.database.fetchone("""
- SELECT ev.idFile, ev.c00 AS episodeTitle, ev.c12 AS season, ev.c13
AS episode, ev.c05 AS firstAired, tv.c00 AS title, ev.idShow, ev.strPath,
ev.strFileName,
- (SELECT COUNT(DISTINCT c13) FROM episodeview WHERE
idShow=ev.idShow) AS episodes
- FROM episodeview ev, tvshowview tv
- WHERE ev.idShow=tv.idShow AND episodes > 2 AND ev.c05 != '' AND
ev.strFileName NOT LIKE '%%.nfo'
- %s %s
- ORDER BY random() LIMIT 1
- """ % (self._get_watched_episodes_clause(),
self._get_max_rating_clause()))
- a = Answer(True, row['episode'], self._format_date(row['firstAired']),
row['idFile'])
- a.setCoverFile(row['strPath'], row['strFileName'])
- self.answers.append(a)
-
- # Fill with random episodes from this show
- shows = self.database.fetchall("""
- SELECT ev.c00 AS episodeTitle, ev.c12 AS season, ev.c13 AS
episode, ev.c05 AS firstAired
- FROM episodeview ev
- WHERE ev.idShow = ? AND ev.c12 = ? AND ev.c13 != ? AND ev.c05 !=
'' AND ev.strFileName NOT LIKE '%%.nfo'
- ORDER BY random() LIMIT 3
- """, (row['idShow'], row['season'], row['episode']))
- for show in shows:
- a = Answer(False, show['episode'],
self._format_date(show['firstAired']))
- a.setCoverFile(row['strPath'], row['strFileName'])
- self.answers.append(a)
-
- self.answers = sorted(self.answers, key=lambda answer: int(answer.id))
-
- self.text = strings(Q_WHEN_WAS_EPISODE_FIRST_AIRED) %
(self._get_episode_title(row['season'], row['episode'], row['episodeTitle']),
row['title'])
- self.setVideoFile(row['strPath'], row['strFileName'])
-
- def _format_date(self, dateString):
- d = time.strptime(dateString, '%Y-%m-%d')
- return time.strftime(strings(Q_FIRST_AIRED_DATEFORMAT), d)
+# self.setFanartFile(row['strPath'], row['strFileName'])
class WhenWasTVShowFirstAiredQuestion(TVQuestion):
"""
@@ -880,12 +861,12 @@ class WhenWasTVShowFirstAiredQuestion(TVQuestion):
"""
def __init__(self, database, maxRating, onlyWatchedMovies):
- TVQuestion.__init__(self, database, DISPLAY_VIDEO, maxRating,
onlyWatchedMovies)
+ TVQuestion.__init__(self, database, DISPLAY_NONE, maxRating,
onlyWatchedMovies)
row = self.database.fetchone("""
SELECT ev.idFile, ev.c12 AS season, ev.c13 AS episode, ev.c05 AS
firstAired, tv.c00 AS title, ev.idShow, ev.strPath, ev.strFileName
FROM episodeview ev, tvshowview tv
- WHERE ev.idShow=tv.idShow AND ev.c12 = 1 AND ev.c13 != 0 AND
ev.c05 != '' AND ev.strFileName NOT LIKE '%%.nfo'
+ WHERE ev.idShow=tv.idShow AND ev.c12 != 0 AND ev.c13 = 1 AND
ev.c05 != '' AND ev.strFileName NOT LIKE '%%.nfo'
%s %s
ORDER BY random() LIMIT 1
""" % (self._get_watched_episodes_clause(),
self._get_max_rating_clause()))
@@ -916,7 +897,9 @@ class WhenWasTVShowFirstAiredQuestion(TVQuestion):
self.answers.append(a)
self.text = strings(Q_WHEN_WAS_TVSHOW_FIRST_AIRED) % (row['title'] + '
- ' + self._get_season_title(row['season']))
- self.setVideoFile(row['strPath'], row['strFileName'])
+# self.setVideoFile(row['strPath'], row['strFileName'])
+ self.setFanartFile(row['strPath'])
+
class WhoPlayedRoleInTVShowQuestion(TVQuestion):
"""
@@ -972,8 +955,10 @@ def getRandomQuestion(type, database, maxRating,
onlyWatchedMovies):
"""
subclasses = []
if type == TYPE_MOVIE:
+ #noinspection PyUnresolvedReferences
subclasses = MovieQuestion.__subclasses__()
elif type == TYPE_TV:
+ #noinspection PyUnresolvedReferences
subclasses = TVQuestion.__subclasses__()
random.shuffle(subclasses)
diff --git a/script.moviequiz/quizlib/thumb.py
b/script.moviequiz/quizlib/thumb.py
index de4468d..9ff6f8b 100644
--- a/script.moviequiz/quizlib/thumb.py
+++ b/script.moviequiz/quizlib/thumb.py
@@ -3,25 +3,31 @@ import os
__author__ = 'tommy'
-def getCachedThumb(file):
- if file[0:8] == 'stack://':
- commaPos = file.find(' , ')
- file = file[8:commaPos].strip()
+def _getFilename(path, filename = None):
+ if filename is not None and filename[0:8] == 'stack://':
+ commaPos = filename.find(' , ')
+ file = filename[8:commaPos].strip()
+ elif filename is not None:
+ file = os.path.join(path, filename)
+ else:
+ file = path
+
+ return file
- crc = xbmc.getCacheThumbName(file.lower())
+def _getCachedThumb(path, filename = None):
+ crc = xbmc.getCacheThumbName(_getFilename(path, filename).lower())
return xbmc.translatePath('special://profile/Thumbnails/Video/%s/%s' %
(crc[0], crc))
def getCachedVideoThumb(path, filename):
- if filename[0:8] == 'stack://':
- videoFile = filename
- else:
- videoFile = os.path.join(path, filename)
-
- return getCachedThumb(videoFile)
+ return _getCachedThumb(path, filename)
+
+def getCachedVideoFanart(path, filename):
+ crc = xbmc.getCacheThumbName(_getFilename(path, filename).lower())
+ return xbmc.translatePath('special://profile/Thumbnails/Video/Fanart/%s' %
crc)
def getCachedActorThumb(name):
- return getCachedThumb('actor' + name)
+ return _getCachedThumb('actor' + name)
def getCachedSeasonThumb(path, label):
"""
@@ -30,7 +36,7 @@ def getCachedSeasonThumb(path, label):
for English this can be Specials, Season 1, Season 10, etc
"""
- return getCachedThumb('season' + path + label)
+ return _getCachedThumb('season' + path + label)
def getCachedTVShowThumb(path):
- return getCachedThumb(path)
\ No newline at end of file
+ return _getCachedThumb(path)
\ No newline at end of file
diff --git a/script.moviequiz/resources/language/Danish/strings.xml
b/script.moviequiz/resources/language/Danish/strings.xml
index eb584e6..045b310 100644
--- a/script.moviequiz/resources/language/Danish/strings.xml
+++ b/script.moviequiz/resources/language/Danish/strings.xml
@@ -13,7 +13,6 @@
<string id="30007">%e. %B %Y</string><!-- episode first aired date format:
http://docs.python.org/library/time.html#time.strftime -->
<string id="30008">[B]Indlæser[/B]</string>
-
<!-- Menu -->
<string id="30100">Spil Film Quiz</string>
<string id="30101">Spil TV Quiz</string>
@@ -56,7 +55,6 @@
<string id="30455">Hvem spiller [B]%s[/B] i [B]%s[/B]?</string><!-- 1st %s
is role, 2nd %s is tvshow title -->
<string id="30456">Hvem ligger stemme til [B]%s[/B] i
[B]%s[/B]?</string><!-- 1st %s is role, 2nd %s is movie title -->
-
<!-- Settings strings -->
<string id="30500">Generelt</string>
<string id="30501">Film</string>
diff --git a/script.moviequiz/resources/language/English/strings.xml
b/script.moviequiz/resources/language/English/strings.xml
index 137757b..0000bf5 100644
--- a/script.moviequiz/resources/language/English/strings.xml
+++ b/script.moviequiz/resources/language/English/strings.xml
@@ -31,7 +31,6 @@
<string id="30122">%d seasons</string><!-- %d is season count -->
<string id="30123">%d episodes</string><!-- %d is episodes count -->
-
<!-- Movie Questions -->
<string id="30400">What movie is this?</string>
<string id="30401">What movie is [B]%s[/B] not in?</string><!-- %s is
actor name -->
diff --git a/script.moviequiz/resources/language/German/strings.xml
b/script.moviequiz/resources/language/German/strings.xml
index 00a49aa..216e3ff 100644
--- a/script.moviequiz/resources/language/German/strings.xml
+++ b/script.moviequiz/resources/language/German/strings.xml
@@ -12,6 +12,7 @@
<string id="30006">Staffel %d</string>
<string id="30007">%B %e, %Y</string><!-- episode first aired date format:
http://docs.python.org/library/time.html#time.strftime -->
<string id="30008">[B]Lade...[/B]</string>
+
<!-- Menu -->
<string id="30100">Movie Quiz spielen</string>
<string id="30101">TV Quiz spielen</string>
diff --git
a/script.moviequiz/resources/skins/Default/720p/script-moviequiz-main.xml
b/script.moviequiz/resources/skins/Default/720p/script-moviequiz-main.xml
index bd76a9c..88e4793 100644
--- a/script.moviequiz/resources/skins/Default/720p/script-moviequiz-main.xml
+++ b/script.moviequiz/resources/skins/Default/720p/script-moviequiz-main.xml
@@ -30,25 +30,37 @@
<control type="label" id="5006">
<description>visibility marker for three photos group</description>
</control>
+ <control type="label" id="5007">
+ <description>visibility marker for replay button</description>
+ </control>
<!-- Background -->
- <control type="image" id="4501">
- <description>TV Quiz background</description>
+ <control type="image" id="4500">
+ <description>Background</description>
<posx>0</posx>
<posy>0</posy>
<width>1280</width>
<height>720</height>
- <texture>quiz-background-tvshows.png</texture>
+ <texture>quiz-background.png</texture>
</control>
- <control type="image" id="4500">
- <description>Movie Quiz background</description>
+
+ <control type="image">
+ <description>Glasspane for question and answers</description>
<posx>0</posx>
- <posy>0</posy>
+ <posy>484</posy>
<width>1280</width>
- <height>720</height>
- <texture>quiz-background.png</texture>
+ <height>256</height>
+ <texture>quiz-background-glass.png</texture>
+ </control>
+ <control type="image">
+ <description>Glasspane for score</description>
+ <posx>10</posx>
+ <posy>10</posy>
+ <width>215</width>
+ <height>145</height>
+ <texture>quiz-background-glass.png</texture>
</control>
<!-- photo group -->
@@ -357,9 +369,9 @@
<!-- Answer buttons -->
<control type="button" id="4000">
<description>Answer 1</description>
- <posx>182</posx>
+ <posx>222</posx>
<posy>540</posy>
- <width>1075</width>
+ <width>955</width>
<height>40</height>
<textoffsetx>8</textoffsetx>
<textoffsety>4</textoffsety>
@@ -369,12 +381,23 @@
<texturenofocus />
<onup>4003</onup>
<ondown>4001</ondown>
+ <onright>4010</onright>
+ </control>
+ <control type="image">
+ <description>Red square</description>
+ <posx>192</posx>
+ <posy>550</posy>
+ <width>20</width>
+ <height>20</height>
+ <texture>quiz-white-square.png</texture>
+ <colordiffuse>ffff0000</colordiffuse>
+ <visible>Control.IsVisible(4000)</visible>
</control>
<control type="button" id="4001">
<description>Answer 2</description>
- <posx>182</posx>
+ <posx>222</posx>
<posy>580</posy>
- <width>1075</width>
+ <width>955</width>
<height>40</height>
<textoffsetx>8</textoffsetx>
<textoffsety>4</textoffsety>
@@ -384,12 +407,23 @@
<texturenofocus />
<onup>4000</onup>
<ondown>4002</ondown>
+ <onright>4010</onright>
+ </control>
+ <control type="image">
+ <description>Green square</description>
+ <posx>192</posx>
+ <posy>590</posy>
+ <width>20</width>
+ <height>20</height>
+ <texture>quiz-white-square.png</texture>
+ <colordiffuse>ff00ff00</colordiffuse>
+ <visible>Control.IsVisible(4001)</visible>
</control>
<control type="button" id="4002">
<description>Answer 3</description>
- <posx>182</posx>
+ <posx>222</posx>
<posy>620</posy>
- <width>1075</width>
+ <width>955</width>
<height>40</height>
<textoffsetx>8</textoffsetx>
<textoffsety>4</textoffsety>
@@ -399,12 +433,23 @@
<texturenofocus />
<onup>4001</onup>
<ondown>4003</ondown>
+ <onright>4011</onright>
+ </control>
+ <control type="image">
+ <description>Yellow square</description>
+ <posx>192</posx>
+ <posy>630</posy>
+ <width>20</width>
+ <height>20</height>
+ <texture>quiz-white-square.png</texture>
+ <colordiffuse>ffffff00</colordiffuse>
+ <visible>Control.IsVisible(4002)</visible>
</control>
<control type="button" id="4003">
<description>Answer 4</description>
- <posx>182</posx>
+ <posx>222</posx>
<posy>660</posy>
- <width>1075</width>
+ <width>955</width>
<height>40</height>
<textoffsetx>8</textoffsetx>
<textoffsety>4</textoffsety>
@@ -414,9 +459,64 @@
<texturenofocus />
<onup>4002</onup>
<ondown>4000</ondown>
+ <onright>4011</onright>
+ </control>
+ <control type="image">
+ <description>Blue square</description>
+ <posx>192</posx>
+ <posy>670</posy>
+ <width>20</width>
+ <height>20</height>
+ <texture>quiz-white-square.png</texture>
+ <colordiffuse>ff0000ff</colordiffuse>
+ <visible>Control.IsVisible(4003)</visible>
+ </control>
+
+ <control type="button" id="4010">
+ <description>Replay video</description>
+ <posx>1177</posx>
+ <posy>540</posy>
+ <width>80</width>
+ <height>80</height>
+ <texturefocus>quiz-button-background.png</texturefocus>
+ <texturenofocus />
+ <onup>4011</onup>
+ <ondown>4011</ondown>
+ <onleft>4000</onleft>
+ <visible>Control.IsVisible(5007)</visible>
+ </control>
+ <control type="image">
+ <description>Replay video image</description>
+ <posx>1190</posx>
+ <posy>553</posy>
+ <width>54</width>
+ <height>54</height>
+ <texture>quiz-button-replay.png</texture>
+ <animation effect="fade" start="100" end="33" time="400"
condition="!Control.IsVisible(5007)">Conditional</animation>
+ </control>
+ <control type="button" id="4011">
+ <description>Exit quiz</description>
+ <posx>1177</posx>
+ <posy>620</posy>
+ <width>80</width>
+ <height>80</height>
+ <texturefocus>quiz-button-background.png</texturefocus>
+ <texturenofocus />
+ <onup>4010</onup>
+ <ondown>4010</ondown>
+ <onleft>4002</onleft>
+ </control>
+ <control type="image">
+ <description>Exit quiz image</description>
+ <posx>1190</posx>
+ <posy>633</posy>
+ <width>54</width>
+ <height>54</height>
+ <texture>quiz-button-exit.png</texture>
</control>
<control type="image">
+ <description>Correct answer</description>
<posx>1085</posx>
<posy>35</posy>
<width>150</width>
@@ -427,6 +527,7 @@
<animation effect="slide" start="200,0"
time="1000">Visible</animation>
</control>
<control type="image">
+ <description>Wrong answer</description>
<posx>1085</posx>
<posy>35</posy>
<width>150</width>
diff --git
a/script.moviequiz/resources/skins/Default/media/quiz-background-tvshows.png
b/script.moviequiz/resources/skins/Default/media/quiz-background-tvshows.png
index 3feb730..252e4a1 100644
Binary files
a/script.moviequiz/resources/skins/Default/media/quiz-background-tvshows.png
and
b/script.moviequiz/resources/skins/Default/media/quiz-background-tvshows.png
differ
diff --git a/script.moviequiz/resources/skins/Default/media/quiz-background.png
b/script.moviequiz/resources/skins/Default/media/quiz-background.png
index 9328dc9..d608c15 100644
Binary files
a/script.moviequiz/resources/skins/Default/media/quiz-background.png and
b/script.moviequiz/resources/skins/Default/media/quiz-background.png differ
diff --git a/script.moviequiz/todo.txt b/script.moviequiz/todo.txt
index f600eb5..236c450 100644
--- a/script.moviequiz/todo.txt
+++ b/script.moviequiz/todo.txt
@@ -1,9 +1,7 @@
TODOs and suggestions in no particular order
-- Add support for non-interactive execution to run from Cinema Experience
- DVD ISO's plays menu instead of movie
- Add support for global statistics, eg. "lifetime" correct/incorrect answers
and such
-- Use fanart instead of movie (fallback / option in settings)
Movie Question suggestions:
* Which actor was also in movie xy besides actor z?
-----------------------------------------------------------------------
Summary of changes:
script.moviequiz/addon.xml | 3 +-
script.moviequiz/changelog.txt | 9 ++
script.moviequiz/quizlib/db.py | 50 +++++---
script.moviequiz/quizlib/gui.py | 125 ++++++++++++-------
script.moviequiz/quizlib/imdb.py | 109 +++++++++++-----
script.moviequiz/quizlib/mq_ce_play.py | 27 ++++
script.moviequiz/quizlib/player.py | 34 ++++-
script.moviequiz/quizlib/question.py | 119 ++++++++----------
script.moviequiz/quizlib/thumb.py | 34 +++--
.../resources/language/Danish/strings.xml | 2 -
.../resources/language/English/strings.xml | 1 -
.../resources/language/French/strings.xml | 25 ----
.../resources/language/German/strings.xml | 1 +
.../skins/Default/720p/script-moviequiz-main.xml | 133 +++++++++++++++++---
.../Default/media/quiz-background-tvshows.png | Bin 1331700 -> 1535996
bytes
.../skins/Default/media/quiz-background.png | Bin 1230462 -> 1447692
bytes
.../skins/Default/media/quiz-button-exit.png | Bin 0 -> 1164 bytes
.../skins/Default/media/quiz-button-icons.xcf | Bin 0 -> 8060 bytes
.../skins/Default/media/quiz-button-replay.png | Bin 0 -> 1267 bytes
.../skins/Default/media/quiz-white-square.png | Bin 0 -> 177 bytes
script.moviequiz/todo.txt | 2 -
21 files changed, 443 insertions(+), 231 deletions(-)
create mode 100644 script.moviequiz/quizlib/mq_ce_play.py
delete mode 100644 script.moviequiz/resources/language/French/strings.xml
create mode 100644
script.moviequiz/resources/skins/Default/media/quiz-button-exit.png
create mode 100644
script.moviequiz/resources/skins/Default/media/quiz-button-icons.xcf
create mode 100644
script.moviequiz/resources/skins/Default/media/quiz-button-replay.png
create mode 100644
script.moviequiz/resources/skins/Default/media/quiz-white-square.png
hooks/post-receive
--
Scripts
------------------------------------------------------------------------------
Benefiting from Server Virtualization: Beyond Initial Workload
Consolidation -- Increasing the use of server virtualization is a top
priority.Virtualization can reduce costs, simplify management, and improve
application availability and disaster protection. Learn more about boosting
the value of server virtualization. http://p.sf.net/sfu/vmware-sfdev2dev
_______________________________________________
Xbmc-addons mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/xbmc-addons