User:Eleanorg/1.3/Dissolute Image/Code1
Make database of pixels
Splits up image into pixels with imageMagick, then inserts each one as a hash in a Mongo database. Shown here with dummy values for testing, imagemagick bits commented out.
#!/usr/bin/python
#-*- coding:utf-8 -*-
# this script grabs pixel data from imagemagick & creates the mongo database of pixels. to be run once with python.
import pymongo #the library that serves as python interface to mongo database system
from pymongo import Connection
#--------- create database -----------------------#
connection = Connection()
myDB = connection['pixelsDatabaseTest1']
collection = myDB.collection #tables in Mongo are called 'collections'. variable name on the left can be anything.
#--------- determine image dimensions-----------------------#
#image = "20by10PixelsSection1.png"
#sizeQuery = "identify -format '%w %h' " + image # system command gets image dimensions with ImageMagick
#size = os.popen(sizeQuery, 'r').read() # captures output of system call
#(width, height) = size.split() # splits ImageMagick output into separate column & row no's
#columns = int(width)
#rows = int(height)
columns = 5
rows = 2
#--------- assign pixel details to database-----------------#
# RUN ONCE ONLY
def getcolors ():
n = 0
for row in range (0, rows): # for each row in the image...
for column in range (0, columns): # for each column in the row...
# colorQuery = "convert " + image + " -format '%[pixel:p{" + str(column) + "," + str(row) + "}]' info:-"
# colorResult = os.popen(colorQuery, 'r').read() # makes & captures output of system call
# color = re.sub("\n", "", colorResult) # strips newline character from end of sys call result
color = "red"
n = (n + 1) # this counter increments by one on each loop, generating a unique pixel id
pixelID = str(n)
pixelName = "pixel" + pixelID # creates a unique name from the pixel ID, as a handle for this pixel in the database. warning: db has no qualms about creating duplicates if this code is run more than once; it assigns its own unique id string to each entry
#string = "I'm adopting pixel " + str(pixelID) + " at position " + str(column) + "," + str(row) + "; color " + color
pixelName = {'id': n , 'xpos': str(column) , 'ypos': str(row) , 'color': color, 'url': ""}
#print pixelName
collection.insert(pixelName) # insert this pixel into the db
getcolors()
Give user an unadopted pixel
Finds all the pixels in the db with no url associated. Picks one at random and gives it to the user, with an input form for them to enter the url where they have put it. #TODO needs to be made into a .cgi script.
#!/usr/bin/python
#-*- coding:utf-8 -*-
import pymongo, random
from pymongo import Connection
## grab a random unadopted pixel from the database and give user a unique string for it
connection = Connection()
myDB = connection['pixelDatabaseTest4']
#--------- some db queries for testing------------#
# print whole db thus:
#for entry in myDB.collection.find():
# print entry
#myDB.collection.update( {"id":"2"}, {"$set":{"url": "ovulation.com"}}) # update url of entry with id '2'
#print myDB.collection.find({"id": "2"})["color"]
#--------- generate pixel string ------------#
# find all empty urls in a loop:
unadopted = []
for entry in myDB.collection.find({"url": ""}):
unadopted.append(entry) # add this pixel's hash as an item to the 'unadopted' dictionary
howMany = len(unadopted) # find out how many items in 'unadopted' list
random = random.randint(0,howMany) # pick a random number in this range
pixelHash = unadopted[random] # ...and choose the pixel at this index
print pixelHash['color']
pixelString = "I'm adopting pixel " + pixelHash['id'] + " of 10,000 at position " + pixelHash['xpos'] + "," + pixelHash['ypos'] + " with color " + pixelHash['color']
print pixelString
#--------- print input form with pixel string ------------#
htmlHeader = """<!DOCTYPE html>
<html>
<head>
<title>Adopt a Pixel</title>
<link <link rel="stylesheet" href="../../pixels.css">
</head>
<body>"""
print "Content-Type: text/html"
print
print htmlHeader
print """
<div class="centred" style="margin-top:50px;">
Below is the unique identifier for your pixel.
Copy and paste it somewhere public on the interwebs, exactly as it appears:
</div>
<div class="container txt">
<span class="pixelString">""" +
pixelString +
"""</span>
</div>
<div class="centred" style="margin-top:50px;">
Then tell us the URL of the page where you pasted it:
</div>
<div class="container txt">
<form action="saveUrl.cgi" name="inputForm">
<span class="containerText">Paste url: </span>
<input name="url">
<input type="submit" value="OK">
</form>
</div>
<div class="centred">
Your pixel will appear in the image for as long as the text remains at this URL.
</div>
</body>
</html>"""
Verify the url submitted by user
Scrapes the url given by the user to see if the right pixel can be found there. If yes, that url gets associated with the appropriate pixel in the db so it no longer comes up for adoption.
- TODO how to submit the pixel string to server along with the user input, without user being able to tamper with it?
#!/usr/bin/python
#-*- coding:utf-8 -*-
import cgi, os, subprocess
import cgitb; cgitb.enable()
import pymongo
from pymongo import Connection
# recieves url from inputForm.html scrapes it to check if pixel has been put there correctly
# if yes = updates db entry for that pixel
# if no = throws error
#-------------- error / thank you messages ----------------#
htmlHeader = """<!DOCTYPE html>
<html>
<head>
<title>A form talking to a python script</title>
<link <link rel="stylesheet" href="../../pixels.css">
</head>
<body>
<div class="container txt" style="margin-top:100px;">"""
htmlFooter = """
</div>
</body>
</html>"""
error = """Sorry, your pixel details couldn't be found at that URL! <br />
<li>Did you paste it exactly as it appears here?</li>
<li>Is the page where you pasted it publicly accessible?</li>
"""
thankyou = """Thanks, URL submitted. <br />
Your pixel has been added to the image."""
#------------- get URL from input form -------------------#
form = cgi.FieldStorage() # Grabs whatever input comes from form
url = form.getvalue("url", "http://ox4.org/~nor/trials/hostedString.html") # assigns form's input to var 'url'. url on the right is a default value that will be printed for testing if nothing is recieved from the form
#TODO get unique pixel string along with the form. how?
# pat = 'unique pixel string'
#------------- scrape url for the specified pixel---------#
# if not found, throw error
# if found, print thankyou and update db
text = urllib2.urlopen(url).read() # reads page at the specified URL
pat = r"the correct pixel string" # pattern to be matched is the pixel string associated with input form
# string to be matched must be marked up with capture ()s thus: Pixel position:(\d\d\d).(\d\d\d)\;\ Color:(rgba\(.*\))
print "Content-Type: text/html"
print
print htmlHeader
if not re.search(pat, text): # if pattern 'pat' (ie unique pixel string) isn't matched within 'text'
print error # print error message to user
else:
print thankyou
connection = Connection()
myDB = connection['pixelDatabaseTest4']
collection = myDB.collection
collection.update( {"string":pat}, {"$set":{"url": url}}) # set pixel with string matching 'pat' to url given by user
print htmlFooter
#---------------- trigger pixelsCheckDb.py -----------#
command = "python pixelsCheckDB.py" # script called here must be executable!
os.popen(command, 'r').read()