Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

first commit

  • Loading branch information...
commit 0eff8772690726d2a3b25081b32cbf62d3c25346 0 parents
Joël Franusic authored
2  .gitignore
... ... @@ -0,0 +1,2 @@
  1 +venv
  2 +*.pyc
1  Procfile
... ... @@ -0,0 +1 @@
  1 +web: python app.py
10,921 animated-gifs
10,921 additions, 0 deletions not shown
35 app.py
... ... @@ -0,0 +1,35 @@
  1 +import os
  2 +import random
  3 +import urllib
  4 +import json
  5 +from flask import Flask, request, Response, url_for, render_template
  6 +app = Flask(__name__)
  7 +data = []
  8 +
  9 +
  10 +def load_data():
  11 + file = open('animated-gifs', 'ro')
  12 + for line in file.readlines():
  13 + data.append(line.strip())
  14 +
  15 +
  16 +@app.route("/random")
  17 +def random():
  18 + callback = request.args.get('callback')
  19 + choice = random.choice(data)
  20 + rv = json.dumps({'image': choice})
  21 + if callback:
  22 + rv = "%s(%s)" % (callback, rv)
  23 + return Response(rv, mimetype='application/json')
  24 +
  25 +
  26 +@app.route("/")
  27 +def index():
  28 + return render_template('index.html', url=url_for('random', _external=True))
  29 +
  30 +
  31 +if __name__ == "__main__":
  32 + port = int(os.environ.get('PORT', 5000))
  33 + load_data()
  34 + app.debug = True
  35 + app.run(host='0.0.0.0', port=port)
8 command.sh
... ... @@ -0,0 +1,8 @@
  1 +# Run these commands by hand:
  2 +#
  3 +# This is a huge file. Over 7 GiB in size.
  4 +# $ curl -O http://dumps.wikimedia.org/commonswiki/latest/commonswiki-latest-image.sql.gz
  5 +# This takes about 10 minutes
  6 +# $ zcat commonswiki-latest-image.sql.gz | sed -e 's/),/),\n/g' | grep frameCount | python process.py > found-images
  7 +# $ cat found-images | grep -v '.png' | grep -v ' ' | grep -vi masturba | grep -vi scrotum > animated-gifs
  8 +cat $0
67 parse.py
... ... @@ -0,0 +1,67 @@
  1 +#!/usr/bin/env python
  2 +# http://pypi.python.org/pypi/phpserialize
  3 +import sys
  4 +import csv
  5 +import StringIO
  6 +
  7 +class LineReader:
  8 + def __init__(self):
  9 + self.line = ''
  10 + self.seperator = "\n"
  11 + self.window = []
  12 +
  13 + def add(self, character):
  14 + self.window.append(character)
  15 + self.line += character
  16 + ###print "'%s'" % self.line
  17 + if len(self.window) > len(self.seperator):
  18 + self.window.pop(0)
  19 +
  20 + def found_line(self):
  21 + if ''.join(self.window) == self.seperator:
  22 + rv = self.line
  23 + self.line = ''
  24 + return rv
  25 + else:
  26 + return False
  27 +
  28 +def process(row):
  29 + if len(row) < 8:
  30 + return False
  31 + if not row[7] == "'image'":
  32 + return False
  33 + if not row[8] == "'gif'":
  34 + return False
  35 + # print [row[0],row[7],row[8]]
  36 + # print row
  37 + return True
  38 +
  39 +
  40 +
  41 +
  42 +reader = LineReader()
  43 +inside_insert = False
  44 +search = 'INSERT INTO `image` VALUES'
  45 +while True:
  46 + c = sys.stdin.read(1)
  47 + if not len(c) > 0:
  48 + break
  49 + reader.add(c)
  50 + line = reader.found_line()
  51 + if len(reader.line) > len(search) and reader.line.startswith(search):
  52 + inside_insert = True
  53 + reader.line = ''
  54 + reader.seperator = '),'
  55 + if not inside_insert:
  56 + continue
  57 + if not line:
  58 + continue
  59 +
  60 + # strip out '(' at beginning and '),' at end
  61 + string = line[1:-2]
  62 + # print line[1:-2]
  63 + string_array = string.split(',')
  64 + rv = process(string_array)
  65 + if rv == True:
  66 + print line
  67 +
6 requirements.txt
... ... @@ -0,0 +1,6 @@
  1 +Flask==0.9
  2 +Jinja2==2.6
  3 +Werkzeug==0.8.3
  4 +distribute==0.6.24
  5 +phpserialize==1.3
  6 +wsgiref==0.1.2
97 templates/index.html
... ... @@ -0,0 +1,97 @@
  1 +<html>
  2 +<head>
  3 + <title>Every animated GIF on Wikipedia</title>
  4 + <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
  5 +<style type="text/css">
  6 +table { height: 100%; width: 100%; }
  7 +#center { align: center; }
  8 +#gif { text-align: center; vertical-align: middle; }
  9 +#title { text-align: center; }
  10 +#title a:link { color: black; text-decoration: none; }
  11 +#title a:hover { color: blue; text-decoration: underline; }
  12 +#title, #footer, #credits { height: 1px; }
  13 +#footer { text-align: center; margin: 0px;}
  14 +#footer ul { margin: 0px; }
  15 +#footer ul li { display: inline; margin: 5px; }
  16 +#title a { font-size: 2em; }
  17 +#gif img { max-width: 800px; max-height: 400px; }
  18 +</style>
  19 +</head>
  20 +<body>
  21 +<table><!-- forgive me Father, for I have sinned -->
  22 + <tr><td id="title"></td></tr>
  23 + <tr><td id="center"><div id="gif" onclick="load_random_image();"></div></td></tr>
  24 + <tr><td id="footer"><ul id="usage"></ul></td>
  25 + <tr><td id="credits">Created by <a href="http://joel.franusic.com">Joel Franusic</a>.</td>
  26 +</table>
  27 + <script>
  28 + window.addEventListener("hashchange", on_hash_change, false);
  29 + var current_filename = "";
  30 +
  31 + function filename_only(url) {
  32 + var rv = url.split(":")[2];
  33 + rv = rv.replace(/_/g, " ");
  34 + rv = rv.replace(".gif","");
  35 + rv = rv.replace(/-/g, " ");
  36 + rv = decodeURIComponent(rv);
  37 + return rv;
  38 + }
  39 +
  40 + function load_image_by_filename(filename) {
  41 + current_filename = filename;
  42 + location.hash = filename;
  43 +
  44 + var url = 'http://en.wikipedia.org/w/api.php?' +
  45 + 'action=query&prop=imageinfo' +
  46 + '&format=json&iiprop=url' +
  47 + '&list=imageusage&iutitle=File:' +
  48 + filename +
  49 + '&titles=File:' +
  50 + filename +
  51 + '&callback=?';
  52 + $.getJSON(url, function(data) {
  53 + var img_url = data.query.pages['-1'].imageinfo[0].url;
  54 + var img_description_url = data.query.pages['-1'].imageinfo[0].descriptionurl;
  55 + var img_name = filename_only(img_description_url);
  56 + $("#gif").empty().append($("<img/>").attr("src", img_url));
  57 + $("#title").empty().append($("<a/>").attr("href", img_description_url).append(img_name));
  58 + $("#usage").empty();
  59 + if(data.query.imageusage) {
  60 + $.each(data.query.imageusage, function(index, value) {
  61 + $("#usage").append('<li><a href="http://en.wikipedia.org/wiki/' + value.title + '">' + value.title + '</a></li>');
  62 + });
  63 + }
  64 + });
  65 + }
  66 +
  67 + function load_random_image() {
  68 + $.getJSON("http://bob.fihn.net:5000/pick?callback=?", function(data) {
  69 + load_image_by_filename(data.image)
  70 + });
  71 + }
  72 +
  73 + function on_hash_change() {
  74 + var hash_value = location.hash;
  75 + hash_value = hash_value.replace('#', '');
  76 +
  77 + if(hash_value !== current_filename) {
  78 + load_image_by_filename(hash_value);
  79 + }
  80 + }
  81 +
  82 + $(function() {
  83 + $(document).keyup(function(evt) {
  84 + if (evt.keyCode == 32) {
  85 + load_random_image();
  86 + }
  87 + })
  88 + });
  89 +
  90 + if(location.hash !== "") {
  91 + on_hash_change();
  92 + } else {
  93 + load_random_image();
  94 + }
  95 +</script>
  96 +</body>
  97 +</html>

0 comments on commit 0eff877

James Dunne

You probably want to avoid JSONP nowadays in favor of Access-Control-Allow-Origin: * header. Makes things easier by allowing you to use XmlHttpRequest instead of the <script src="/path/to/jsonp?callback=cb"></script> hacks.

Joël Franusic

Hey, thanks! I honestly didn't even consider doing that - I just did what I needed to get it working with jQuery ... this is CORS right?

James Dunne

Yes I think that's another name for it. It was only until recently that I thought JSONP was the latest way to do this but CORS is much much better.

Please sign in to comment.
Something went wrong with that request. Please try again.