Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
forking pychallonge; some sql file cleanup
- Loading branch information
Showing
12 changed files
with
310 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
__version__ = "1.0.1" | ||
|
||
import tournaments, matches, participants | ||
from api import set_credentials, get_credentials, fetch, ChallongeException |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
import decimal | ||
import urllib | ||
import urllib2 | ||
try: | ||
from xml.etree import cElementTree as ElementTree | ||
except ImportError: | ||
from xml.etree import ElementTree | ||
|
||
|
||
CHALLONGE_API_URL = "api.challonge.com/v1/" | ||
|
||
_credentials = { | ||
"user": None, | ||
"api_key": None, | ||
} | ||
|
||
|
||
class ChallongeException(Exception): | ||
pass | ||
|
||
|
||
def set_credentials(username, api_key): | ||
"""Set the challonge.com api credentials to use.""" | ||
_credentials["user"] = username | ||
_credentials["api_key"] = api_key | ||
|
||
|
||
def get_credentials(): | ||
"""Retrieve the challonge.com credentials set with set_credentials().""" | ||
return _credentials["user"], _credentials["api_key"] | ||
|
||
|
||
def fetch(method, uri, params_prefix=None, **params): | ||
"""Fetch the given uri and return the contents of the response.""" | ||
params = urllib.urlencode(_prepare_params(params, params_prefix)) | ||
|
||
# build the HTTP request | ||
url = "https://%s/%s.xml" % (CHALLONGE_API_URL, uri) | ||
print "fetching url " + url | ||
if method == "GET": | ||
req = urllib2.Request("%s?%s" % (url, params)) | ||
else: | ||
req = urllib2.Request(url) | ||
req.add_data(params) | ||
req.get_method = lambda: method | ||
req.add_header("Accept", "application/xml"); | ||
req.add_header("Content-Type", "application/xml"); | ||
|
||
# use basic authentication | ||
user, api_key = get_credentials() | ||
auth_handler = urllib2.HTTPBasicAuthHandler() | ||
auth_handler.add_password( | ||
realm="Application", | ||
uri=req.get_full_url(), | ||
user=user, | ||
passwd=api_key | ||
) | ||
opener = urllib2.build_opener(auth_handler) | ||
|
||
try: | ||
response = opener.open(req) | ||
except urllib2.HTTPError, e: | ||
if e.code != 422: | ||
raise | ||
# wrap up application-level errors | ||
doc = ElementTree.parse(e).getroot() | ||
if doc.tag != "errors": | ||
raise | ||
errors = [e.text for e in doc] | ||
raise ChallongeException(*errors) | ||
return response | ||
|
||
|
||
def fetch_and_parse(method, uri, params_prefix=None, **params): | ||
"""Fetch the given uri and return the root Element of the response.""" | ||
doc = ElementTree.parse(fetch(method, uri, params_prefix, **params)) | ||
return _parse(doc.getroot()) | ||
|
||
|
||
def _parse(root): | ||
"""Recursively convert an Element into python data types""" | ||
import dateutil.parser | ||
if root.tag == "nil-classes": | ||
return [] | ||
elif root.get("type") == "array": | ||
return [_parse(child) for child in root] | ||
|
||
d = {} | ||
for child in root: | ||
type = child.get("type") or "string" | ||
|
||
if child.get("nil"): | ||
value = None | ||
elif type == "boolean": | ||
value = True if child.text.lower() == "true" else False | ||
elif type == "datetime": | ||
value = dateutil.parser.parse(child.text) | ||
elif type == "decimal": | ||
value = decimal.Decimal(child.text) | ||
elif type == "integer": | ||
value = int(child.text) | ||
else: | ||
value = child.text | ||
|
||
d[child.tag] = value | ||
return d | ||
|
||
|
||
def _prepare_params(dirty_params, prefix=None): | ||
"""Prepares parameters to be sent to challonge.com. | ||
The `prefix` can be used to convert parameters with keys that | ||
look like ("name", "url", "tournament_type") into something like | ||
("tournament[name]", "tournament[url]", "tournament[tournament_type]"), | ||
which is how challonge.com expects parameters describing specific | ||
objects. | ||
""" | ||
params = {} | ||
for k, v in dirty_params.iteritems(): | ||
if hasattr(v, "isoformat"): | ||
v = v.isoformat() | ||
elif isinstance(v, bool): | ||
# challonge.com only accepts lowercase true/false | ||
v = str(v).lower() | ||
|
||
if prefix: | ||
params["%s[%s]" % (prefix, k)] = v | ||
else: | ||
params[k] = v | ||
|
||
return params |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
from challonge import api | ||
|
||
|
||
def index(tournament, **params): | ||
"""Retrieve a tournament's match list.""" | ||
return api.fetch_and_parse( | ||
"GET", | ||
"tournaments/%s/matches" % tournament, | ||
**params) | ||
|
||
|
||
def show(tournament, match_id): | ||
"""Retrieve a single match record for a tournament.""" | ||
return api.fetch_and_parse( | ||
"GET", | ||
"tournaments/%s/matches/%s" % (tournament, match_id)) | ||
|
||
|
||
def update(tournament, match_id, **params): | ||
"""Update/submit the score(s) for a match.""" | ||
api.fetch( | ||
"PUT", | ||
"tournaments/%s/matches/%s" % (tournament, match_id), | ||
"match", | ||
**params) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
from challonge import api | ||
|
||
|
||
def index(tournament): | ||
"""Retrieve a tournament's participant list.""" | ||
return api.fetch_and_parse( | ||
"GET", | ||
"tournaments/%s/participants" % tournament) | ||
|
||
def create(tournament, name, **params): | ||
"""Add a participant to a tournament.""" | ||
params.update({"name": name}) | ||
|
||
return api.fetch_and_parse( | ||
"POST", | ||
"tournaments/%s/participants" % tournament, | ||
"participant", | ||
**params) | ||
|
||
|
||
def show(tournament, participant_id): | ||
"""Retrieve a single participant record for a tournament.""" | ||
return api.fetch_and_parse( | ||
"GET", | ||
"tournaments/%s/participants/%s" % (tournament, participant_id)) | ||
|
||
|
||
def update(tournament, participant_id, **params): | ||
"""Update the attributes of a tournament participant.""" | ||
api.fetch( | ||
"PUT", | ||
"tournaments/%s/participants/%s" % (tournament, participant_id), | ||
"participant", | ||
**params) | ||
|
||
|
||
def destroy(tournament, participant_id): | ||
"""Destroys or deactivates a participant. | ||
If tournament has not started, delete a participant, automatically | ||
filling in the abandoned seed number. | ||
If tournament is underway, mark a participant inactive, automatically | ||
forfeiting his/her remaining matches. | ||
""" | ||
api.fetch( | ||
"DELETE", | ||
"tournaments/%s/participants/%s" % (tournament, participant_id)) | ||
|
||
|
||
def randomize(tournament): | ||
"""Randomize seeds among participants. | ||
Only applicable before a tournament has started. | ||
""" | ||
api.fetch("POST", "tournaments/%s/participants/randomize" % tournament) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
from challonge import api | ||
|
||
|
||
def index(**params): | ||
"""Retrieve a set of tournaments created with your account.""" | ||
return api.fetch_and_parse("GET", "tournaments", **params) | ||
|
||
|
||
def create(name, url, tournament_type="single elimination", **params): | ||
"""Create a new tournament.""" | ||
params.update({ | ||
"name": name, | ||
"url": url, | ||
"tournament_type": tournament_type, | ||
}) | ||
|
||
return api.fetch_and_parse("POST", "tournaments", "tournament", **params) | ||
|
||
|
||
def show(tournament): | ||
"""Retrieve a single tournament record created with your account.""" | ||
return api.fetch_and_parse("GET", "tournaments/%s" % tournament) | ||
|
||
|
||
def update(tournament, **params): | ||
"""Update a tournament's attributes.""" | ||
api.fetch("PUT", "tournaments/%s" % tournament, "tournament", **params) | ||
|
||
|
||
def destroy(tournament): | ||
"""Deletes a tournament along with all its associated records. | ||
There is no undo, so use with care! | ||
""" | ||
api.fetch("DELETE", "tournaments/%s" % tournament) | ||
|
||
|
||
def publish(tournament): | ||
"""Publish a tournament, making it publically accessible. | ||
The tournament must have at least 2 participants. | ||
""" | ||
api.fetch("POST", "tournaments/publish/%s" % tournament) | ||
|
||
|
||
def start(tournament): | ||
"""Start a tournament, opening up matches for score reporting. | ||
The tournament must have at least 2 participants. | ||
""" | ||
api.fetch("POST", "tournaments/start/%s" % tournament) | ||
|
||
|
||
def reset(tournament): | ||
"""Reset a tournament, clearing all of its scores and attachments. | ||
You can then add/remove/edit participants before starting the | ||
tournament again. | ||
""" | ||
api.fetch("POST", "tournaments/reset/%s" % tournament) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,4 +21,3 @@ wsgiref==0.1.2 | |
whoosh==2.5.6 | ||
python-jsonschema-objects==0.0.15 | ||
iso8601==0.1.11 | ||
pychallonge==1.0.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters