Skip to content

Instantly share code, notes, and snippets.

@lordscales91
Created January 3, 2016 14:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lordscales91/a501b794f38455c5320c to your computer and use it in GitHub Desktop.
Save lordscales91/a501b794f38455c5320c to your computer and use it in GitHub Desktop.
This is a Python3 compatible version of SolveMedia's official Python library. https://portal.solvemedia.com/portal/help/pub/python/
# Copyright (c) 2009 by Jeff Weisberg
# Author: Jeff Weisberg
# Created: 2009-Jun-25 13:18 (EDT)
# Function: python solvemedia interface
#
# $Id$
# Python3 compatibility implemented by lordscales91
# with the help of the six compatibility layer
import six
from six.moves import urllib # @UnresolvedImport Ignore flag for Eclipse PyDev
import hashlib
# solvemedia servers:
ADCOPY_API_HTTP = "http://api.solvemedia.com"
ADCOPY_API_HTTPS = "https://api-secure.solvemedia.com"
ADCOPY_VERIFY_HTTP = "http://verify.solvemedia.com/papi/verify"
ADCOPY_SIGNUP_HTTP = "http://api.solvemedia.com/public/signup"
# create solvemedia object:
# c = libsolvemedia.Solvemedia( ckey, vkey, hkey )
# ckey - your solvemedia api ckey
# vkey - your solvemedia api vkey
# hkey - your solvemedia api hkey
#
# c.get_html( errorp, usessl )
# get html for the solvemedia widget
# errorp - display an error message on the widget
# usessl - use ssl
#
# c.check_answer( remoteip, challenge, response )
# check the user's answer
# remoteip - the user's IP address
# challenge - the solvemedia puzzle challenge id
# response - the user's answer
# util methods for Python3 compatibility:
def safe_concat(*items):
"""
Safe method for concatenating strings with bytestrings
"""
result = ''
for item in items:
if not isinstance(item, six.string_types):
item = item.decode()
result += item
return result
def force_string(value):
if not isinstance(value, six.string_types):
value = value.decode()
return value
def force_bytes(value):
if isinstance(value, six.string_types):
return value.encode()
return value
class SolveMedia:
def __init__(self, ckey, vkey, hkey):
self.ckey = ckey
self.vkey = vkey
self.hkey = hkey
def get_html(self, errorp=False, usessl=False):
if usessl:
server = ADCOPY_API_HTTPS
else:
server = ADCOPY_API_HTTP
if errorp:
param = ";error=1"
else:
param = ""
html = """
<!-- start solvemedia puzzle widget -->
<script type="text/javascript"
src="%(baseurl)s/papi/challenge.script?k=%(ckey)s%(param)s">
</script>
<noscript>
<iframe src="%(baseurl)s/papi/challenge.noscript?k=%(ckey)s%(param)s"
height="300" width="500" frameborder="0"></iframe><br>
<textarea name="adcopy_challenge" rows="3" cols="40">
</textarea>
<input type="hidden" name="adcopy_response"
value="manual_challenge">
</noscript>
<!-- end solvemedia puzzle widget -->
""" % {
'ckey': self.ckey,
'baseurl': server,
'param': param,
}
return html
def check_answer(self, remoteip, challenge, response):
data = urllib.parse.urlencode({'privatekey': self.vkey,
'remoteip': remoteip,
'challenge': challenge,
'response': response})
req = urllib.request.Request(
ADCOPY_VERIFY_HTTP,
force_bytes(data), {
'User-Agent': 'solvemedia-python-client',
})
try:
resp = urllib.request.urlopen(req)
except:
return {'is_valid': False, 'error': 'server error'}
line = resp.read().splitlines()
# validate message authenticator
if self.hkey:
base = safe_concat(line[0], challenge, self.hkey)
hash_check = hashlib.sha1(force_bytes(base)).hexdigest()
if hash_check != force_string(line[2]):
return {'is_valid': False, 'error': 'hash-fail'}
if force_string(line[0]) == 'true':
return {'is_valid': True}
else:
return {'is_valid': False, 'error': line[1]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment