#!/home/hvgarnett/local/bin/python
import sys
from flup.server.fcgi_fork import WSGIServer
import cgi
import xml.dom
import xml.dom.minidom
import urllib2
from random import randrange
from cgi import parse_qs

def dispatch_redirect(url,responder):
 responder('302 Found',[('Content-Type','text/html'),('Location',str(url))])
 return """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Metal Gear?</title>
<meta http-equiv="REFRESH" content="0;url=%s"></HEAD>
<BODY>
<a href="%s">Where there's smoke...</a>
</BODY>
</HTML>
"""%(str(url),str(url))

def dispatch_forward(url,responder):
 remotes = None
 try:
  remotes = urllib2.urlopen(url)
 except:
  responder('400 Bad Request',[('Content-Type','text/plain')])
  yield "The chosen URL, %s, failed to be opened for some reason." % url
  return
 else:
  try:
   headers = remotes.info()
   responder('200 OK',[(header,headers[header]) for header in headers.keys()])
   chunk = remotes.read(4096)
   while len(chunk):
    yield chunk
    chunk = remotes.read(4096)
   return
  except:
   yield "TRANSFER INTERRUPTED during read of " + str(url)
   return

howto = """'Surprise!' - a dynamically chosen image, based on context and chance
Usage
http://doomfacebook.determinismsucks.net/surprise/img1[+img2+condition[...]]
Each "img" represents a Tinypic image, by server and id, separated by + signs.
So for example, http://i50.tinypic.com/11aeozq.gif is "i50+11aeozq".
Now that Tinypic has dropped global support, imgur is also supported; 
"imgur+HBYwK.gif" translates to "http://imgur.com/HBYwK.gif".

The first image is the default one.
Then, you can add any number of "surprise" images, each of which has a
condition in which it might appear.
If the condition begins with "r", then the image might appear at random.
The rest of the condition is then a number specifying how rare the image
should be (on a 1/n chance).
If the condition begins with "k", then the image will appear depending
on the page that links to it.
We'll check the page for the rest of the condition, and if we find that
keyword there, the special image will be displayed.
If none of the conditions are met, the default image is displayed.

As a complete example:
http://doomfacebook.determinismsucks.net/surprise/i50+11aeozq+i49+20klgre+r10+i49+16bbssj+kUSERPICRED
This one will go through the following steps:
* There's a 1 in 10 chance that http://i49.tinypic.com/20klgre will be
  selected.
* If that doesn't happen, then it will check the page displaying the image
  for the string "USERPICRED". If that string can be found on the page or
  in its source code, http://i49.tinypic.com/16bbssj will be selected.
* If neither of those happen, http://i50.tinypic.com/11aeozq will be
  selected.
"""


def urlmaker(a,b):
 if a=="imgur":
  return "http://imgur.com/%s"%(b)
 else:
  return "http://%s.tinypic.com/%s.png"%(a,b)

def test(environ,responder):
 #if environ.has_key("QUERY_STRING") and environ["QUERY_STRING"][:9]=="resource=":
 # 
 # responder('200 OK',[('Content-Type',)])
 #else:
 if environ.has_key("REDIRECT_URL"):
  input = environ["REDIRECT_URL"].split("/surprise/",1)[-1]
  try:
   input_fields = input.split("+")
   default_url = urlmaker(*input_fields[:2])
   addtl_imgs = input_fields[2:]
   while len(addtl_imgs) >= 3:
    try:
     url_part_a, url_part_b, condition = addtl_imgs[:3]
     url = urlmaker(url_part_a,url_part_b)
     if condition[0] == "k":
      if environ.has_key("HTTP_REFERER"):
       #We were referred and a key was specified. Check it.
       try:
        referer_filelike = urllib2.urlopen(environ["HTTP_REFERER"])
        if referer_filelike.read(40960).replace("+k"+condition[1:],"").find(condition[1:]) > -1:
         #Key was found in the first 40k of the file.
         yield dispatch_redirect(url,responder)
         return
        referer_filelike.close()
       except: #Again, if the referrer is invalid, just continue.
        pass
     elif condition[0] == "r":
      try:
       rarity = int(condition[1:])
       if rarity and not randrange(rarity): #If rarity is a valid int and 1/rarity chance is hit, send special.
        yield dispatch_redirect(url,responder)
        return
      except: #If anything goes wrong here, we don't care. Just move on.
       pass
    except:
     pass
    addtl_imgs = addtl_imgs[3:]
   yield dispatch_redirect(default_url,responder)
   return
  except:
   responder('400 Bad Request',[('Content-Type','text/plain')])
   yield howto
 else:
  responder('400 Bad Request',[('Content-Type','text/plain')])
  yield howto

WSGIServer(test).run()

