Browse files

first commit

  • Loading branch information...
0 parents commit dee38a32b8948294b6b7b1d4f5d86c6a49f32a77 @alexksikes committed Jan 5, 2009
165 LICENSE
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
0 app/__init__.py
No changes.
0 app/controllers/__init__.py
No changes.
16 app/controllers/public.py
@@ -0,0 +1,16 @@
+# Author: Alex Ksikes
+
+import web
+import mimetypes
+
+class public:
+ def GET(self):
+ try:
+ file_name = web.ctx.path.split('/')[-1]
+ web.header('Content-type', mime_type(file_name))
+ return open('.' + web.ctx.path, 'rb').read()
+ except IOError:
+ raise web.notfound()
+
+def mime_type(filename):
+ return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
38 app/controllers/wikitrivia.py
@@ -0,0 +1,38 @@
+# Author: Alex Ksikes
+
+import web
+import config
+
+from app.models import questions
+from app.models import score
+from app.models import categories
+from config import view
+
+class index:
+ def GET(self):
+ score.reset_score()
+ return view.layout(view.front_page(categories.get_categories()))
+
+class quiz:
+ def GET(self):
+ i = web.input(category='')
+ if not categories.is_valid_category(i.category):
+ return web.seeother('/')
+
+ question = questions.get_random_question(i.category)
+
+ category, category_name = i.category, categories.get_category_name(i.category)
+ return view.layout(view.question(question, score.get_score(), category, category_name),
+ title='Wikitrivia - ' + category_name)
+
+class answer:
+ def POST(self):
+ i = web.input(category='', answer='', guess='', wiki_url='', score=0)
+
+ success = questions.is_correct_guess(i.guess, i.answer)
+ cscore = i.score
+ if success:
+ cscore = score.update_score(cscore)
+
+ category_name = categories.get_category_name(i.category)
+ return view.layout(view.score(cscore, i, success), title='Wikitrivia - ' + category_name)
65 app/lib.py
@@ -0,0 +1,65 @@
+# Author: Alex Ksikes
+
+import re, urllib, pycurl, cStringIO, string
+from lxml import etree
+
+def yahoo_search(query, start, results):
+ appid = 'qw87vZXV34Fv5NbIhOHEleK5iL9RTgripE68mWDbEbry7KtyvUWZ6eyHq3uUU_HTFMg-'
+ url = 'http://search.yahooapis.com/WebSearchService/V1/webSearch?appid=%s&query=%s&results=%s&start=%s' % \
+ (appid, urllib.quote(query), results, start)
+ xml = parse_xml(dnl(url))
+
+ results = []
+ for r in xml.findall('Result'):
+ result = {}
+ for f in ['Title', 'Summary', 'Url']:
+ result[f.lower()] = r.findtext(f)
+ results.append(result)
+
+ return results
+
+def parse_xml(txt):
+ xml = re.sub('xmlns\s*=\s*["\'].*?["\']', ' ', txt) # we remove the xmlns for simplicity
+ return etree.fromstring(xml, parser=etree.XMLParser(resolve_entities=False))
+
+def curl_init():
+ curl = pycurl.Curl()
+ curl.setopt(pycurl.USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)")
+ #curl.setopt(pycurl.CONNECTTIMEOUT, 3)
+ #curl.setopt(pycurl.TIMEOUT, 30)
+ return curl
+
+# TODO: some urls such as http://en.wikipedia.org/wiki/List_of_Tamil-language_films return garbage for some reason.
+def open_url(curl, url, referer = None):
+ curl.setopt(pycurl.URL, url)
+ if referer:
+ curl.setopt(pycurl.REFERER, referer)
+
+ f = cStringIO.StringIO()
+ curl.setopt(pycurl.WRITEFUNCTION, f.write)
+ curl.perform()
+
+ html = f.getvalue()
+ f.close()
+ return html
+
+def dnl(url, referer = None):
+ c = curl_init()
+ return open_url(c, url, referer)
+
+def capitalize_first(str):
+ if not str:
+ str = ''
+ return ' '.join(map(string.capitalize, str.lower().split()))
+
+# we may want to use this in order to preserve some of html of wikipedia
+def strip_tags(html, ignore_tags='<b>|<i>|&#?\w+;'):
+ skip_p = re.compile(ignore_tags, re.I)
+ def fixup(m):
+ text = m.group(0)
+ if skip_p.match(text):
+ return text
+ if text[:1] == "<" or text[:1] == "&" or text[:2] == "&#":
+ return ""
+ return text
+ return re.sub("(?s)<[^>]*>|&#?\w+;", fixup, text)
0 app/models/__init__.py
No changes.
25 app/models/cache.py
@@ -0,0 +1,25 @@
+# Author: Alex Ksikes
+
+import web
+from config import db
+
+# TODO: - This is inefficient compared to
+# SELECT * FROM `table` WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `table` ) ORDER BY id LIMIT 1;
+def get_random_question(category):
+ """Get a random quiz question from the cache."""
+ return web.listget(
+ db.select('wikitrivia_cache',
+ vars=dict(category=category),
+ where='category = $category', limit=1, order='rand()'), 0, False)
+
+def set_question(question):
+ """Set a quiz question in the cache."""
+ if not get_question(question):
+ db.insert('wikitrivia_cache', **question)
+
+def get_question(question):
+ """Get a specific question from the cache."""
+ return web.listget(
+ db.select('wikitrivia_cache',
+ vars=dict(url=wiki_url),
+ where='wiki_url = $url', limit=1), 0, False)
55 app/models/categories.py
@@ -0,0 +1,55 @@
+# Author: Alex Ksikes
+
+lang = 'en'
+base_query = '/wiki/ site:' + lang + '.wikipedia.org -disambiguation -"up to conform" -"a stub" \
+-"is the * day" -"was a * year" -"list of years"'
+
+yahoo_queries = dict(
+ comics = '"comic books" OR "comic book" OR "manga" OR "comics" OR "graphic novel"',
+ movies = 'tv OR movie OR movies OR cinema OR actor OR actress OR director',
+ scifi = '"science fiction" OR "sci fi"',
+ sports = 'baseball OR football OR basketball OR sport OR sports',
+ blogs = '"web log" OR blog OR blogging OR waxy OR weblog OR blogger OR weblogs OR "boing boing"',
+ politics = 'political politician',
+ art = 'painter OR painting',
+ science = 'physics OR chemistry OR math OR astronomy OR medicine OR science',
+ food = 'food OR dish OR recipe OR drink OR cocktail',
+ literature = 'author OR writer novel',
+ programming = 'programming OR programmer',
+ geography = '"is a city" OR "is a country"',
+ music = 'singer OR band OR pop',
+ philosophy = 'philosopher',
+ fantasy = 'fantasy OR "lord of the rings" -"final fantasy"',
+ animals = 'animal family',
+ computers = 'computer OR internet',
+ games = '"computer game" OR "video game" OR "pc game" OR "amiga 500" OR atari OR c64',
+ cars = 'car',
+ detectives = '"miss marple" OR "secret agent" OR "austin powers" OR detective OR "sherlock holmes" OR "james bond" OR "inspector clouseau" OR "agatha christie" OR "conan doyle"',
+ legends = '"fairy tale" OR "urban legend" OR "conspiracy theory" OR scam OR spoof OR fake',
+ crime = 'murder OR criminal OR mafia OR assassination OR thief',
+ search = '"search engine" OR seo OR google -groups.google -maps.google',
+ searchde = 'suchmaschine -groups.google -maps.google',
+ misc = 'wikipedia',
+)
+
+def get_yahoo_query(category):
+ """Get a search query to return a random wikipedia article."""
+ return yahoo_queries[category] + ' ' + base_query
+
+def get_categories():
+ """Return a list of categories for the quiz."""
+ return [('comics', 'Comics'), ('movies', 'Movies'), ('sports', 'Sports'), ('scifi', 'Sci-fi'),
+ ('blogs', 'Blogs'), ('politics', 'Politics'), ('science', 'Science'), ('literature', 'Literature'),
+ ('music', 'Music'), ('art', 'Art'), ('geography', 'Geography'), ('programming', 'Programming'),
+ ('food', 'Food'), ('philosophy', 'Philosophy'), ('fantasy', 'Fantasy'), ('animals', 'Animals'),
+ ('computers', 'Computers'), ('games', 'Video&nbsp;Games'), ('cars', 'Cars'),
+ ('detectives', 'Detectives'), ('legends', 'Legends'), ('crime', 'Crime'), ('misc', 'Misc.')]
+
+def get_category_name(category):
+ """Return the pretty name of a category."""
+ for c, c_name in get_categories():
+ if c == category:
+ return c_name
+
+def is_valid_category(category):
+ return category in yahoo_queries.keys()
91 app/models/questions.py
@@ -0,0 +1,91 @@
+# Author: Alex Ksikes
+
+# TODO:
+# - We should probably have a class Question
+
+import web
+
+from app import lib
+from app.models import cache
+from app.models import categories
+
+import random, re
+from lxml import etree
+
+question_range = 1000
+snippet_size = 350
+with_images_only = False
+max_trials = 3
+use_cache = True
+
+def get_random_question(category, trials=max_trials):
+ """Get a random quiz question using wikipedia."""
+ # no more trials we failed so fetch from the cache
+ if trials == 0:
+ return use_cache and cache.get_random_question(category)
+
+ # maybe we have exhausted all queries from yahoo
+ url = get_random_wiki_url(category)
+ if not url:
+ return use_cache and cache.get_random_question(category)
+
+ # maybe xml parsing failed or the question we got is no good
+ question = make_question(url, category)
+ if not question or not is_question_valid(question):
+ return get_random_question(category, trials-1)
+
+ # if we got here it is that we have a question so save it
+ if use_cache and question.image_url:
+ cache.set_question(question)
+
+ return question
+
+def get_random_wiki_url(category):
+ """Use yahoo to get a random wikipedia url."""
+ wiki_url = ''
+ if categories.yahoo_queries.has_key(category):
+ query = categories.get_yahoo_query(category)
+ wiki_url = web.listget(
+ lib.yahoo_search(query, random.randint(0, question_range), 1), 0, {}).get('url', '')
+ return wiki_url
+
+def make_question(url, category):
+ """Create the random question from wikipedia."""
+ try:
+ article = lib.dnl(url, referer='http://en.wikipedia.org/')
+ xml = lib.parse_xml(article)
+ except:
+ return False
+ raise 'Either can\'t download the wikipedia article or can\'t parse it.'
+
+ answer = xml.findtext('.//h1').encode('utf-8')
+ snippet = ''
+ for p in xml.xpath('//div[@id="bodyContent"]/p'):
+ snippet += etree.tostring(p, method='text', encoding='utf-8').strip() + ' '
+# snippet += lib.strip_tags(etree.tostring(p)) + '\n'
+ snippet = snippet[0:snippet_size].replace('\n', '<br />').decode('utf-8')
+ snippet = re.sub('\[\d+\]', '', snippet)
+
+ snippet_secret = snippet
+ for a in answer.split():
+ p = re.compile(r'\b%s\b' % re.escape(a), re.I)
+ snippet_secret = p.sub('<strong class="depleted">' + '?' * len(a) + '</strong>', snippet_secret)
+
+ image_url = web.listget(
+ xml.xpath('//img[@class="thumbimage"]//@src'), 0, '')
+
+ return web.storage(
+ dict(answer=answer, snippet_secret=snippet_secret, category=category,
+ snippet=snippet, wiki_url=url, image_url=image_url))
+
+def is_question_valid(question):
+ """Return True if the generated question is valid."""
+ if with_images_only and not question.image_url:
+ return False
+ return 'class="depleted"' in question.snippet_secret and len(question.snippet) == snippet_size
+
+def is_correct_guess(guess, answer):
+ """Check the user's guess in a pretty lenient way."""
+ guess, answer = map(lambda x:
+ re.sub('[^a-zA-Z0-9\s]', '', x.lower().strip().encode('ascii', 'ignore')).split(), (guess, answer))
+ return len([c for c in answer if c in guess]) >= (len(answer) / 2 or 1)
14 app/models/score.py
@@ -0,0 +1,14 @@
+# Author: Alex Ksikes
+
+import web
+
+def reset_score():
+ web.setcookie('score', 0)
+
+def update_score(cscore):
+ cscore = 10 + int(cscore)
+ web.setcookie('score', cscore)
+ return cscore
+
+def get_score():
+ return int(web.cookies(score=0).score)
8 app/views/front_page.html
@@ -0,0 +1,8 @@
+$def with (categories)
+
+<p><strong>Choose a category:</strong></p>
+<p class="categories">
+$for (category, category_name) in categories:
+ <a href="/quiz/?category=$category">$:category_name</a>&nbsp;\
+ $if not loop.last: |
+</p>
31 app/views/layout.html
@@ -0,0 +1,31 @@
+$def with (page, title='WikiTrivia')
+
+$# TODO: - see for how to change the title in template inheritance
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <title>$title</title>
+ <link rel="stylesheet" href="/public/default.css" type="text/css" media="screen, print, projection" />
+ <script type="text/javascript" src="/public/default.js"></script>
+</head>
+<body onload="delayContinue(3)">
+
+<div class="content">
+
+<h1><a href="/"><img src="/public/logo.jpg" alt="" /><br />WikiTrivia</a></h1>
+
+$:page
+
+<p class="footer">
+<em>WikiTrivia, the trivia game <strong>freshly generated from <a href="http://www.wikipedia.org">Wikipedia</a></strong> articles.</em><br />
+By Alex Ksikes (concept and <a href='http://github.com/alexksikes/wikitrivia/tree/master'>programming</a>) and Philipp Lenssen (programming)<br />
+&copy; May 2005 - 2009 -
+<small><a href='mailto:alexandre.ksikes@gmail.com?subject=Wikitrivia'>Feedback</a> -
+<a href='http://groups.google.com/group/wikitrivia'>Discuss</a> -
+<a href='http://github.com/alexksikes/wikitrivia/tree/master'>Source code</a></small>
+</p>
+</div>
+
+</body>
+</html>
49 app/views/question.html
@@ -0,0 +1,49 @@
+$def with (question, score, category, category_name)
+
+$# TODO: - Get the question name
+
+<p id="loading">Loading article from Wikipedia...</p>
+
+$if question:
+ <p class="snippet">
+ $if question.image_url:
+ <img class="thumb" src="$question.image_url" alt="" />
+ <br /><br />
+ $:question.snippet_secret ...
+ </p>
+
+ <form action="/answer" name="theform" method="post">
+ <div>
+ <p><em>What is being talked about in the quote from Wikipedia?</em></p>
+ <input type="text" name="guess" size="40" value="$question.answer[0]" />
+
+ <input type="hidden" name="score" value="$score" />
+ <input type="hidden" name="answer" value="$question.answer" />
+ <input type="hidden" name="wiki_url" value="$question.wiki_url" />
+ <input type="hidden" name="category" value="$category" />
+ <input type="hidden" name="category_name" value="$category_name" />
+ <br />
+
+ <span id="pleaseWait">Please wait...</span>
+
+ <input type="submit" value="Guess" id="continueButton" />
+ </div>
+ </form>
+$else:
+ <p>Question could not be loaded at the moment &#8211; please <a href=''>try again</a> or try later. I'm working to resolve this.</p>
+
+<div class="ad">
+ <script type="text/javascript"><!--
+ google_ad_client = "pub-1431948349807205";
+ /* 468x60, created 1/5/09 */
+ google_ad_slot = "8422565837";
+ google_ad_width = 468;
+ google_ad_height = 60;
+ //-->
+ </script>
+ <script type="text/javascript"
+ src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
+ </script>
+</div>
+
+<p class="changeCategory">Playing $:category_name | <a href="/">More categories...</a></p>
40 app/views/score.html
@@ -0,0 +1,40 @@
+$def with (score, question, success)
+
+$if success:
+ <p class="right">
+ <strong>You are right!
+ <br />The answer is "<a href="$question.wiki_url">$question.answer</a>". </strong>(+10 points)
+ <br /><span class="points">Points: $score</span>
+ </p>
+$else:
+ <p class="wrong">
+ <em>Your answer "$question.guess" is wrong.</em>
+ <br />The right answer was "<a href="$question.wiki_url">$question.answer</a>".
+ <br /><span style="font-size: 90%">(Strange answers? <a href="http://groups.google.com/group/wikitrivia">Discuss</a>.)</span>
+ </p>
+
+<form action="/quiz" method="get">
+ <div>
+ <br />
+ <span id="pleaseWait">Please wait...</span>
+
+ <input type="hidden" name="category" value="$question.category" />
+ <input type="submit" value="Continue" id="continueButton" />
+ </div>
+</form>
+
+<div class="ad">
+
+<script type="text/javascript"><!--
+google_ad_client = "pub-1431948349807205";
+/* 468x60, created 1/5/09 */
+google_ad_slot = "8422565837";
+google_ad_width = 468;
+google_ad_height = 60;
+//-->
+</script>
+<script type="text/javascript"
+src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
+</script>
+
+</div>
25 application.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+# Author: Alex Ksikes
+
+# TODO :
+# - move to production server
+# - add google ads
+# - domain name wikitrivia.net, contact wade for .com
+# - add analytics
+# - add testimonials
+
+import web
+import config
+import app.controllers
+
+urls = (
+ '/?', 'app.controllers.wikitrivia.index',
+ '/quiz/?', 'app.controllers.wikitrivia.quiz',
+ '/answer/?', 'app.controllers.wikitrivia.answer',
+ '/public/.+', 'app.controllers.public.public',
+)
+
+app = web.application(urls, globals())
+
+if __name__ == "__main__":
+ app.run()
16 config.py
@@ -0,0 +1,16 @@
+import web, os
+
+# connect to database
+db = web.database(dbn='mysql', db='wikitrivia', user='', passwd='')
+
+# in development debug error messages and reloader
+web.config.debug = True
+
+# in develpment template caching is set to false
+cache = False
+
+# set global base template
+view = web.template.render('app/views', cache=cache)
+
+# used to encrypt the answer
+encryption_key = 'mi$ey'
135 public/default.css
@@ -0,0 +1,135 @@
+body
+{
+ background-color: #fff;
+ color: #000;
+ font-family: arial, helvetica, sans-serif;
+}
+
+a
+{
+ color: #34a;
+}
+
+h1
+{
+ font-size: 30px;
+ text-align: center;
+ letter-spacing: -1px;
+ color: #aaa;
+}
+
+h1 a
+{
+ color: #aaa;
+ text-decoration: none;
+}
+
+.content
+{
+ width: 500px;
+ margin-left: auto;
+ margin-right: auto;
+ text-align: center;
+}
+
+.depleted
+{
+ color: white;
+ background-color: #ccc;
+}
+
+.subDepleted
+{
+}
+
+.right,
+.wrong
+{
+ margin-top: 50px;
+ margin-bottom: 50px;
+}
+
+.right
+{
+ color: green;
+}
+
+.wrong
+{
+ color: red;
+}
+
+.footer
+{
+ font-size: 90%;
+ border-top: 1px solid gray;
+ margin-top: 10px;
+ padding-top: 3px;
+ line-height: 19px;
+}
+
+.footer em {
+ font-weight: bold;
+}
+
+.snippet
+{
+ margin-bottom: 30px;
+}
+
+.points
+{
+ color: #ccc;
+ font-size: 40px;
+ letter-spacing: -2px;
+ font-weight: bold;
+}
+
+.categories
+{
+ font-size: 140%;
+ margin-bottom: 40px;
+ line-height: 40px;
+}
+
+.changeCategory
+{
+ margin-top: 60px;
+}
+
+a img
+{
+ border: 0;
+}
+
+.ad
+{
+ margin-top: 30px;
+}
+
+#continueButton
+{
+ visibility: hidden;
+}
+
+#pleaseWait
+{
+ font-size: 90%;
+ font-style: italic;
+}
+
+.thumb
+{
+}
+
+.german
+{
+ font-size: 75%;
+}
+
+#loading
+{
+ color: #999;
+ font-size: 90%;
+ font-style: italic;
+}
44 public/default.js
@@ -0,0 +1,44 @@
+function delayContinue(nSeconds)
+{
+ nSeconds = 0;
+ hideLr("loading");
+ setTimeout("showContinue()", nSeconds * 1000);
+}
+
+function showContinue()
+{
+ var elm;
+
+ elm = document.getElementById("pleaseWait");
+ if (elm) {
+ elm.style.display = "none";
+ }
+
+ elm = document.getElementById("continueButton");
+ if (elm) {
+ elm.style.visibility = "visible";
+ }
+
+ setFocus();
+}
+
+function hideLr(id)
+{
+ var elm;
+ elm = document.getElementById(id);
+ if (elm) {
+ elm.style.display = "none";
+ }
+}
+
+function setFocus() {
+ if (document.theform != undefined) {
+ document.theform.guess.focus();
+ }
+ else {
+ elm = document.getElementById("continueButton");
+ if (elm) {
+ elm.focus();
+ }
+ }
+}
BIN public/logo.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 schema.sql
@@ -0,0 +1,10 @@
+create table wikitrivia_cache (
+ id int(11) not null auto_increment primary key,
+ category varchar(100),
+ answer varchar(150),
+ wiki_url varchar(250) not null unique,
+ image_url varchar(250),
+ snippet text,
+ snippet_secret text,
+ index(wiki_url)
+) type=InnoDB; charset utf8;
5 sync.py
@@ -0,0 +1,5 @@
+# Author: Alex Ksikes
+import os
+
+cmd = "rsync -Puzav --exclude='config.py' --exclude='.bzr' dana:/wikitrivia/scripts/"
+os.system(cmd)

0 comments on commit dee38a3

Please sign in to comment.