Skip to content

Commit f2c4871

Browse files
committed
Initial release.
1 parent be8dc6a commit f2c4871

File tree

4 files changed

+114
-0
lines changed

4 files changed

+114
-0
lines changed

Diff for: CHANGES.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
v1.0, 2017-01-09 -- Initial release.

Diff for: README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Flask-FastSpring
2+
3+
FastSpring API integration for Flask.

Diff for: flask_fastspring.py

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import requests
2+
3+
from flask import Markup, render_template_string
4+
5+
6+
class FastSpringAPIError(Exception):
7+
8+
def __init__(self, response):
9+
self.response = response
10+
11+
def __str__(self):
12+
template = 'FastSpring API {} at {} failed with status code {}:\n{}'
13+
return template.format(
14+
self.response.request.method,
15+
self.response.request.url,
16+
self.response.status_code,
17+
self.response.text)
18+
19+
20+
class FastSpring:
21+
22+
head_template = """\
23+
<script type="text/javascript">
24+
var fscSession = {{ session|tojson }};
25+
function fastspringOnPopupClosed(data) {
26+
if (!data) return;
27+
var xhr = new XMLHttpRequest();
28+
xhr.open("POST", "{{ webhook }}", true);
29+
xhr.setRequestHeader("Content-Type", "application/json");
30+
xhr.onreadystatechange = function() {
31+
if (xhr.readyState === XMLHttpRequest.DONE) {
32+
if (xhr.status === 200) {
33+
window.location.replace("{{ request.url }}");
34+
} else if (xhr.status === 201 || (301 <= xhr.status && xhr.status <= 303)) {
35+
window.location.replace(xhr.GetResponseHeader("Location"));
36+
} else {
37+
var message = "ERROR: Could not process order: " + data["reference"];
38+
console.log(message);
39+
alert(message);
40+
}
41+
}
42+
};
43+
xhr.send(JSON.stringify({
44+
"order_id": data["id"],
45+
"reference": data["reference"],
46+
"payload": {{ payload }}
47+
}));
48+
}
49+
</script>
50+
<script
51+
id="fsc-api"
52+
src="https://d1f8f9xcsvx3ha.cloudfront.net/sbl/0.7.2/fastspring-builder.min.js"
53+
type="text/javascript"
54+
data-popup-closed="fastspringOnPopupClosed"
55+
data-storefront="{{ storefront }}">
56+
</script>"""
57+
58+
def __init__(self, app=None):
59+
self.storefront = None
60+
self.username = None
61+
self.password = None
62+
if app is not None:
63+
self.init_app(app)
64+
65+
def init_app(self, app):
66+
app.extensions['fastspring'] = self
67+
self.storefront = app.config['FASTSPRING_STOREFRONT']
68+
self.username = app.config['FASTSPRING_USERNAME']
69+
self.password = app.config['FASTSPRING_PASSWORD']
70+
71+
def render_head(self, webhook, session=None, payload=None):
72+
html = render_template_string(
73+
self.head_template,
74+
storefront=self.storefront,
75+
webhook=webhook,
76+
session=session,
77+
payload=payload if payload is not None else 'null')
78+
return Markup(html)
79+
80+
def render_button(self, product):
81+
t = 'data-fsc-action="Add,Checkout" data-fsc-item-path-value="{}"'
82+
return Markup(t.format(product))
83+
84+
def fetch_order(self, order_id):
85+
return self.fetch('/orders/{}'.format(order_id))
86+
87+
def fetch_subscription(self, subscription_id):
88+
return self.fetch('/subscriptions/{}'.format(subscription_id))
89+
90+
def fetch(self, uri):
91+
response = requests.get(
92+
'https://api.fastspring.com/{}'.format(uri),
93+
auth=(self.username, self.password))
94+
if response.status_code != 200:
95+
raise FastSpringAPIError(response)
96+
data = response.json()
97+
if data['result'] != 'success':
98+
raise FastSpringAPIError(response)
99+
return data

Diff for: setup.py

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from setuptools import setup
2+
3+
setup(
4+
name='Flask-FastSpring',
5+
version='1.0',
6+
description='FastSpring API integration for Flask',
7+
py_modules=['flask_fastspring'],
8+
install_requires=[
9+
'Flask>=0.11',
10+
'requests>=2.12',
11+
])

0 commit comments

Comments
 (0)