User:Eleanorg/1.3/Dissolute Image/Code1: Difference between revisions
Line 136: | Line 136: | ||
[[User:Eleanorg/1.3/Dissolute Image/Code/verify input | code experiments on verifying user input]] | [[User:Eleanorg/1.3/Dissolute Image/Code/verify input | code experiments on verifying user input]] | ||
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. | 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. | ||
as of 18 June. Not yet working. | |||
<source lang="python"> | <source lang="python"> | ||
#!/usr/bin/python | #!/usr/bin/python | ||
#-*- coding:utf-8 -*- | #-*- coding:utf-8 -*- | ||
import cgi | import cgi | ||
import cgitb; cgitb.enable() | import os, subprocess, re, urllib2 | ||
#import cgitb; cgitb.enable() | |||
import pymongo | import pymongo | ||
from pymongo import Connection | from pymongo import Connection | ||
Line 180: | Line 181: | ||
form = cgi.FieldStorage() # Grabs whatever input comes from 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 | #string = form.getvalue("pixel") | ||
#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 | |||
#------------- scrape url | |||
# if not found, throw error | #------------- print html header--------------------------# | ||
#print "Content-Type: text/html" | |||
# print | |||
# print htmlHeader | |||
#------------ define splitting function-------------------# | |||
# to split user's string into a hash which can be verified against the one in db | |||
def splitString (stg) : | |||
pat = re.compile("(\w{1,4}=[^;]+);?") # captures each foo=blah pair in the string, separated by ;s | |||
cap = pat.findall(stg) # cap variable contains all four captures - id, x, y, color (if valid) | |||
# put captures into a hash for this pixel | |||
myhash = {} | |||
for s in cap : | |||
k,v = s.split('=') # splits each capture on the = into key and value | |||
myhash[k] = v # puts new k/v pair into hash with these values | |||
# return hash so it can be compared with that in the db | |||
try : | |||
myhash['x'] and myhash['y'] and myhash['col'] and myhash['idNo'] | |||
except: | |||
return # missing parameter! return nothing | |||
return myhash # returns a hash as above, accessed thus: paramGet(stg)['x'] etc | |||
#------------- scrape and check the url -----------------# | |||
# if correct string not found, throw error | |||
# if found, print thankyou and update db | # if found, print thankyou and update db | ||
# connect to db for verification, and possible updating | |||
connection = Connection() | |||
myDB = connection['pixelDbQuery1'] | |||
collection = myDB.collection | |||
# for testing: | |||
string = r"x=123;y=345;col=(255,255,255);idNo=ObjectId('4fdb5b75ed9c8d4743000000')" # TODO regex breaks because the string contains python syntax which can't be escaped as it's coming from user | |||
#string = "kitten" | |||
url = "http://ox4.org/~nor/trials/hostedString.html" | |||
text = urllib2.urlopen(url).read() # reads page at the specified URL | text = urllib2.urlopen(url).read() # reads page at the specified URL | ||
pat | #print text | ||
# string | if not re.search(string, text): # if pattern 'pat' (ie unique pixel string) isn't matched within 'text' | ||
print " | # print error # print error message to user | ||
print | print "sorry, couldnt scrape ur string" | ||
print | else: | ||
split = splitString(string) # calls split string function, passing it the string recieved from the input form, and assigns it to var 'split' | |||
if split: | |||
# check db to see if ID exists | |||
idNo = split['idNo'] | |||
print idNo # get idNo according to the has of user's string | |||
pixelHash = myDB.collection.find({"_id": idNo}) # TODO this grabs a cursor object - what I want is the hash iteslf so I can access its keys | |||
print pixelHash | |||
if pixelHash: # TODO getting false positive here - this pixel doesn't exist in db but script says it does! | |||
# check if attributes from string recieved (xpos, ypos + colour) match attributes for that ID in DB? | |||
print "yes, that pixel id exists in db" | |||
# now do verification against db: | |||
# split['x'] should == pixelHash['x'] etc | |||
# split['idNo'] should == pixelHash['id'] << remember you're not allowed 'id' as a hash key in python | |||
# if all 4 attributes are the same: | |||
# print hurrah and | |||
# update db: collection.update( {"string":pat}, {"$set":{"url": url}}) # set pixel with string matching 'pat' to url given by user | |||
else: | |||
print "sorry, that pixel id doesnt exist" | |||
# if yes: | |||
# print thank you | |||
# trigger drawing script | |||
# else print error | |||
else: | |||
# print error | |||
print "sorry, couldnt split your string into a hash" | |||
#print thankyou | |||
print htmlFooter | #print htmlFooter | ||
</source> | </source> | ||
Revision as of 12:32, 18 June 2012
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.
import os, re
import pymongo #the library that serves as python interface to mongo database system
from pymongo import Connection
#--------- create database -----------------------#
connection = Connection()
myDB = connection['pixelDbQuery1']
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)
#--------- assign pixel details to database-----------------#
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
pixelName = {'xpos': str(column), 'ypos': str(row), 'color': color }
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
code experiments on verifying user input 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.
as of 18 June. Not yet working.
#!/usr/bin/python
#-*- coding:utf-8 -*-
import cgi
import os, subprocess, re, urllib2
#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
#string = form.getvalue("pixel")
#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
#------------- print html header--------------------------#
#print "Content-Type: text/html"
# print
# print htmlHeader
#------------ define splitting function-------------------#
# to split user's string into a hash which can be verified against the one in db
def splitString (stg) :
pat = re.compile("(\w{1,4}=[^;]+);?") # captures each foo=blah pair in the string, separated by ;s
cap = pat.findall(stg) # cap variable contains all four captures - id, x, y, color (if valid)
# put captures into a hash for this pixel
myhash = {}
for s in cap :
k,v = s.split('=') # splits each capture on the = into key and value
myhash[k] = v # puts new k/v pair into hash with these values
# return hash so it can be compared with that in the db
try :
myhash['x'] and myhash['y'] and myhash['col'] and myhash['idNo']
except:
return # missing parameter! return nothing
return myhash # returns a hash as above, accessed thus: paramGet(stg)['x'] etc
#------------- scrape and check the url -----------------#
# if correct string not found, throw error
# if found, print thankyou and update db
# connect to db for verification, and possible updating
connection = Connection()
myDB = connection['pixelDbQuery1']
collection = myDB.collection
# for testing:
string = r"x=123;y=345;col=(255,255,255);idNo=ObjectId('4fdb5b75ed9c8d4743000000')" # TODO regex breaks because the string contains python syntax which can't be escaped as it's coming from user
#string = "kitten"
url = "http://ox4.org/~nor/trials/hostedString.html"
text = urllib2.urlopen(url).read() # reads page at the specified URL
#print text
if not re.search(string, text): # if pattern 'pat' (ie unique pixel string) isn't matched within 'text'
# print error # print error message to user
print "sorry, couldnt scrape ur string"
else:
split = splitString(string) # calls split string function, passing it the string recieved from the input form, and assigns it to var 'split'
if split:
# check db to see if ID exists
idNo = split['idNo']
print idNo # get idNo according to the has of user's string
pixelHash = myDB.collection.find({"_id": idNo}) # TODO this grabs a cursor object - what I want is the hash iteslf so I can access its keys
print pixelHash
if pixelHash: # TODO getting false positive here - this pixel doesn't exist in db but script says it does!
# check if attributes from string recieved (xpos, ypos + colour) match attributes for that ID in DB?
print "yes, that pixel id exists in db"
# now do verification against db:
# split['x'] should == pixelHash['x'] etc
# split['idNo'] should == pixelHash['id'] << remember you're not allowed 'id' as a hash key in python
# if all 4 attributes are the same:
# print hurrah and
# update db: collection.update( {"string":pat}, {"$set":{"url": url}}) # set pixel with string matching 'pat' to url given by user
else:
print "sorry, that pixel id doesnt exist"
# if yes:
# print thank you
# trigger drawing script
# else print error
else:
# print error
print "sorry, couldnt split your string into a hash"
#print thankyou
#print htmlFooter
Check database for accuracy
This script is triggered every time a new pixel is adopted (should maybe be run more regularly tho - cron job?). It scrapes each pixel's url in the db and removes it if the correct string is no longer found there.
Draw new image
For every pixel in the db which has a url associated, a pixel is drawn onto the original blank image. Maybe this should be merged with script above - so checking & drawing are done at once? Saves looping thru db more times than necessary. (If url is valid, draw on pixel. If not, remove url from db.)