Add GAN samples.
Reviewed in http://codereview.appspot.com/4867056/ Index: samples/gan/ccoffers/offers.py =================================================================== new file mode 100644
This commit is contained in:
126
samples/gan/ccoffers/offers.py
Normal file
126
samples/gan/ccoffers/offers.py
Normal file
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/python2.4
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2011 Google Inc.
|
||||
|
||||
"""Sample for retrieving credit-card offers from GAN."""
|
||||
|
||||
__author__ = 'leadpipe@google.com (Luke Blanshard)'
|
||||
|
||||
import gflags
|
||||
import httplib2
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import stat
|
||||
import sys
|
||||
|
||||
from django.conf import settings
|
||||
from django.template import Template, Context
|
||||
from django.template.loader import get_template
|
||||
|
||||
from apiclient.discovery import build
|
||||
from oauth2client.file import Storage
|
||||
from oauth2client.client import OAuth2WebServerFlow
|
||||
from oauth2client.tools import run
|
||||
|
||||
settings.configure(DEBUG=True, TEMPLATE_DEBUG=True,
|
||||
TEMPLATE_DIRS=('.'))
|
||||
|
||||
|
||||
FLAGS = gflags.FLAGS
|
||||
|
||||
# Set up a Flow object to be used if we need to authenticate. This
|
||||
# sample uses OAuth 2.0, and we set up the OAuth2WebServerFlow with
|
||||
# the information it needs to authenticate. Note that it is called
|
||||
# the Web Server Flow, but it can also handle the flow for native
|
||||
# applications <http://code.google.com/apis/accounts/docs/OAuth2.html#IA>
|
||||
# The client_id client_secret are copied from the API Access tab on
|
||||
# the Google APIs Console <http://code.google.com/apis/console>. When
|
||||
# creating credentials for this application be sure to choose an Application
|
||||
# type of "Installed application".
|
||||
FLOW = OAuth2WebServerFlow(
|
||||
client_id='767567128246-ti2q06i1neqm5boe2m1pqdc2riivhk41.apps.googleusercontent.com',
|
||||
client_secret='UtdXI8nKD2SEcQRLQDZPkGT9',
|
||||
scope='https://www.googleapis.com/auth/gan.readonly',
|
||||
user_agent='gan-ccoffers-sample/1.0')
|
||||
|
||||
# The gflags module makes defining command-line options easy for
|
||||
# applications. Run this program with the '--help' argument to see
|
||||
# all the flags that it understands.
|
||||
gflags.DEFINE_enum('logging_level', 'DEBUG',
|
||||
['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
|
||||
'Set the level of logging detail.')
|
||||
|
||||
gflags.DEFINE_enum("output_type", 'STDOUT', ['BOTH', 'HTML', 'STDOUT'],
|
||||
'Set how to output the results received from the API')
|
||||
|
||||
gflags.DEFINE_string('credentials_filename', 'offers.dat',
|
||||
'File to store credentials in', short_name='cf')
|
||||
|
||||
gflags.DEFINE_multistring('advertiser', None,
|
||||
'If given, advertiser we should run as')
|
||||
|
||||
|
||||
def usage(argv):
|
||||
print 'Usage: %s <publisher-id>\n%s' % (argv[0], FLAGS)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main(argv):
|
||||
# Let the gflags module process the command-line arguments
|
||||
try:
|
||||
argv = FLAGS(argv)
|
||||
except gflags.FlagsError, e:
|
||||
raise e
|
||||
usage(argv)
|
||||
|
||||
if len(argv) != 2:
|
||||
usage(argv)
|
||||
publisher = argv[1]
|
||||
|
||||
# Set the logging according to the command-line flag
|
||||
logging.getLogger().setLevel(getattr(logging, FLAGS.logging_level))
|
||||
|
||||
# If the Credentials don't exist or are invalid run through the native client
|
||||
# flow. The Storage object will ensure that if successful the good
|
||||
# Credentials will get written back to a file.
|
||||
storage = Storage(FLAGS.credentials_filename)
|
||||
credentials = storage.get()
|
||||
if credentials is None or credentials.invalid:
|
||||
credentials = run(FLOW, storage)
|
||||
|
||||
# Create an httplib2.Http object to handle our HTTP requests and authorize it
|
||||
# with our good Credentials.
|
||||
http = httplib2.Http()
|
||||
http = credentials.authorize(http)
|
||||
|
||||
service = build('gan', 'v1beta1', http=http)
|
||||
|
||||
ccOffers = service.ccOffers()
|
||||
|
||||
# Retrieve the relevant offers.
|
||||
list_call = ccOffers.list(publisher=publisher,
|
||||
# TODO(leadpipe): add back when advertiser is repeated
|
||||
# advertiser=FLAGS.advertiser,
|
||||
projection='full')
|
||||
list = list_call.execute()
|
||||
list['publisher'] = publisher
|
||||
|
||||
if FLAGS.output_type in ["BOTH", "HTML"]:
|
||||
template = get_template('offers_template.html')
|
||||
context = Context(list)
|
||||
|
||||
fname = '%s.html' % publisher
|
||||
out = open(fname, 'w')
|
||||
out.write(template.render(context).encode('UTF-8'))
|
||||
os.fchmod(out.fileno(), stat.S_IROTH|stat.S_IRGRP|stat.S_IRUSR|stat.S_IWUSR)
|
||||
out.close()
|
||||
|
||||
print 'Wrote %s' % fname
|
||||
|
||||
if FLAGS.output_type in ["BOTH", "STDOUT"]:
|
||||
print json.dumps(list, sort_keys=True, indent=4)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
||||
99
samples/gan/ccoffers/offers_template.html
Normal file
99
samples/gan/ccoffers/offers_template.html
Normal file
@@ -0,0 +1,99 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Credit Card Offers for Publisher {{ publisher }}</title>
|
||||
<style>
|
||||
h2 {
|
||||
margin: 3ex 0 1ex;
|
||||
}
|
||||
td.cardName {
|
||||
padding-bottom: 2ex;
|
||||
}
|
||||
td {
|
||||
vertical-align: top;
|
||||
overflow: auto;
|
||||
}
|
||||
tr.details td {
|
||||
padding: 0 3ex;
|
||||
}
|
||||
td pre {
|
||||
margin: 3ex 3em;
|
||||
width: 500px;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function toggleDisplay(id) {
|
||||
el = document.getElementById(id);
|
||||
if (el.style.display == "none") {
|
||||
el.style.display = "block"
|
||||
} else {
|
||||
el.style.display = "none"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Credit Card Offers for Publisher {{ publisher }}</h1>
|
||||
<table>
|
||||
{% for item in items %}
|
||||
<tr>
|
||||
<td colspan=3 class="cardName">
|
||||
<h2>{{ item.cardName }}</h2>
|
||||
{{ item.network }} from {{ item.issuer }} - <a href="{{ item.trackingUrl }}">Click to apply</a>
|
||||
- <a href="javascript:toggleDisplay('pre{{forloop.counter}}');">debug</a>
|
||||
<tr class="details">
|
||||
<td>
|
||||
{% if item.imageUrl %}
|
||||
<img src="{{ item.imageUrl }}" title="Image from GAN" />
|
||||
{% endif %}
|
||||
{% if item.logoUrl %}
|
||||
<img src="{{ item.logoUrl }}" title="Image from AdConnect" />
|
||||
{% endif %}
|
||||
{% if item.disclaimer %}
|
||||
<div>{{ item.disclaimer }}</div>
|
||||
{% endif %}
|
||||
<td>
|
||||
<div>APR: {{ item.aprDisplay }}</div>
|
||||
<div>Annual Fee: {{ item.annualFeeDisplay }}</div>
|
||||
<div>Grace Period: {{ item.gracePeriodDisplay }}</div>
|
||||
<div>Late Payment Fee: {{ item.latePaymentFee }}</div>
|
||||
<div>Credit Rating: {{ item.creditRatingDisplay }}</div>
|
||||
<td>
|
||||
{% if item.introAprDisplay %}
|
||||
<div>Intro APR: {{ item.introAprDisplay }}</div>
|
||||
{% endif %}
|
||||
{% if item.balanceTransferAprDisplay %}
|
||||
<div>Balance Transfer APR: {{ item.balanceTransferAprDisplay }}</div>
|
||||
{% endif %}
|
||||
{% if item.balanceTransferFeeDisplay %}
|
||||
<div>Balance Transfer Fee: {{ item.balanceTransferFeeDisplay }}</div>
|
||||
{% endif %}
|
||||
{% if item.cashAdvanceAprDisplay %}
|
||||
<div>Cash Advance APR: {{ item.cashAdvanceAprDisplay }}</div>
|
||||
{% endif %}
|
||||
{% if item.cashAdvanceFeeDisplay %}
|
||||
<div>Cash Advance Fee: {{ item.cashAdvanceFeeDisplay }}</div>
|
||||
{% endif %}
|
||||
<!--
|
||||
<td>
|
||||
Card benefits: <ul>
|
||||
{% for benefit in item.cardBenefits %}
|
||||
<li> {{ benefit }} </li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<td>
|
||||
Additional benefits: <ul>
|
||||
{% for benefit in item.additionalCardBenefits %}
|
||||
<li> {{ benefit }} </li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
-->
|
||||
</tr>
|
||||
<tr><td colspan=3><pre id="pre{{forloop.counter}}" style="display:none">
|
||||
{{ item|pprint|linebreaks }}</pre>
|
||||
{% empty %}
|
||||
<tr><td>
|
||||
<h2>Whoops, {{ publisher }} has no associated credit card offers.</h2>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
170
samples/gan/events/events.py
Normal file
170
samples/gan/events/events.py
Normal file
@@ -0,0 +1,170 @@
|
||||
#!/usr/bin/python2.4
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2011 Google Inc.
|
||||
|
||||
"""Sample for retrieving credit-card offers from GAN."""
|
||||
|
||||
__author__ = 'leadpipe@google.com (Luke Blanshard)'
|
||||
|
||||
import apiclient
|
||||
import gflags
|
||||
import httplib2
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import stat
|
||||
import sys
|
||||
|
||||
from django.conf import settings
|
||||
from django.template import Template, Context
|
||||
from django.template.loader import get_template
|
||||
|
||||
from apiclient.discovery import build
|
||||
from oauth2client.file import Storage
|
||||
from oauth2client.client import OAuth2WebServerFlow
|
||||
from oauth2client.tools import run
|
||||
|
||||
settings.configure(DEBUG=True, TEMPLATE_DEBUG=True,
|
||||
TEMPLATE_DIRS=('.'))
|
||||
|
||||
|
||||
FLAGS = gflags.FLAGS
|
||||
|
||||
# Set up a Flow object to be used if we need to authenticate. This
|
||||
# sample uses OAuth 2.0, and we set up the OAuth2WebServerFlow with
|
||||
# the information it needs to authenticate. Note that it is called
|
||||
# the Web Server Flow, but it can also handle the flow for native
|
||||
# applications <http://code.google.com/apis/accounts/docs/OAuth2.html#IA>
|
||||
# The client_id client_secret are copied from the API Access tab on
|
||||
# the Google APIs Console <http://code.google.com/apis/console>. When
|
||||
# creating credentials for this application be sure to choose an Application
|
||||
# type of "Installed application".
|
||||
FLOW = OAuth2WebServerFlow(
|
||||
client_id='767567128246-ti2q06i1neqm5boe2m1pqdc2riivhk41.apps.googleusercontent.com',
|
||||
client_secret='UtdXI8nKD2SEcQRLQDZPkGT9',
|
||||
scope='https://www.googleapis.com/auth/gan.readonly',
|
||||
user_agent='gan-events-sample/1.0')
|
||||
|
||||
# The gflags module makes defining command-line options easy for
|
||||
# applications. Run this program with the '--help' argument to see
|
||||
# all the flags that it understands.
|
||||
gflags.DEFINE_enum('logging_level', 'DEBUG',
|
||||
['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
|
||||
'Set the level of logging detail.')
|
||||
|
||||
gflags.DEFINE_enum("output_type", 'STDOUT', ['BOTH', 'HTML', 'STDOUT'],
|
||||
'Set how to output the results received from the API')
|
||||
|
||||
gflags.DEFINE_string('credentials_filename', 'events.dat',
|
||||
'File to store credentials in', short_name='cf')
|
||||
|
||||
API_FLAGS = {'eventDateMin':None, 'eventDateMax':None, 'advertiserId':None,
|
||||
'publisherId':None, 'orderId':None, 'sku':None,
|
||||
'productCategory':None, 'linkId':None, 'memberId':None,
|
||||
'status':None, 'type':None, 'role':None, 'roleId':None}
|
||||
|
||||
gflags.DEFINE_string(
|
||||
'eventDateMin', None,
|
||||
'RFC 3339 formatted min date. Ex: 2005-08-09-T10:57:00-08:00')
|
||||
|
||||
gflags.DEFINE_string(
|
||||
'eventDateMax', None,
|
||||
'RFC 3339 formatted max date. Ex: 2005-08-09-T10:57:00-08:00')
|
||||
|
||||
gflags.DEFINE_string('advertiserId', None,
|
||||
'caret delimited advertiser IDs')
|
||||
|
||||
gflags.DEFINE_string('publisherId', None,
|
||||
'caret delimited publisher IDs')
|
||||
|
||||
gflags.DEFINE_string('orderId', None,
|
||||
'caret delimited order IDs')
|
||||
|
||||
gflags.DEFINE_string('sku', None,
|
||||
'caret delimited SKUs')
|
||||
|
||||
gflags.DEFINE_string('productCategory', None,
|
||||
'caret delimited product categories')
|
||||
|
||||
gflags.DEFINE_string('linkId', None,
|
||||
'caret delimited link IDs')
|
||||
|
||||
gflags.DEFINE_string('memberId', None,
|
||||
'caret delimited member IDs')
|
||||
|
||||
gflags.DEFINE_string('status', None,
|
||||
'status of events - valid values "active" or "cancelled"')
|
||||
|
||||
gflags.DEFINE_string('type', None,
|
||||
'type of events - valid values "action" or "transaction"')
|
||||
|
||||
|
||||
def usage(argv):
|
||||
print 'Usage: %s <role> <role-id>\n%s' % (argv[0], FLAGS)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main(argv):
|
||||
# Let the gflags module process the command-line arguments
|
||||
try:
|
||||
argv = FLAGS(argv)
|
||||
except gflags.FlagsError, e:
|
||||
print e
|
||||
usage(argv)
|
||||
|
||||
if len(argv) != 3:
|
||||
usage(argv)
|
||||
params = {
|
||||
'role': argv[1],
|
||||
'roleId': argv[2]
|
||||
}
|
||||
|
||||
# Set the logging according to the command-line flag
|
||||
logging.getLogger().setLevel(getattr(logging, FLAGS.logging_level))
|
||||
|
||||
# If the Credentials don't exist or are invalid run through the native client
|
||||
# flow. The Storage object will ensure that if successful the good
|
||||
# Credentials will get written back to a file.
|
||||
storage = Storage(FLAGS.credentials_filename)
|
||||
credentials = storage.get()
|
||||
if credentials is None or credentials.invalid:
|
||||
credentials = run(FLOW, storage)
|
||||
|
||||
# Create an httplib2.Http object to handle our HTTP requests and authorize it
|
||||
# with our good Credentials.
|
||||
http = httplib2.Http()
|
||||
http = credentials.authorize(http)
|
||||
|
||||
service = build('gan', 'v1beta1', http=http)
|
||||
|
||||
events = service.events()
|
||||
|
||||
# Filter out all params that aren't set.
|
||||
for key in FLAGS:
|
||||
if key in API_FLAGS and FLAGS[key].value != None:
|
||||
params[key] = FLAGS[key].value
|
||||
|
||||
# Retrieve the relevant events.
|
||||
try:
|
||||
list_call = events.list(**params)
|
||||
list = list_call.execute()
|
||||
except apiclient.errors.HttpError, e:
|
||||
print json.dumps(e.__dict__, sort_keys=True, indent=4)
|
||||
|
||||
if FLAGS.output_type in ["BOTH", "HTML"]:
|
||||
template = get_template('events_template.html')
|
||||
context = Context(list)
|
||||
|
||||
out = open("output.html", 'w')
|
||||
out.write(template.render(context).encode('UTF-8'))
|
||||
os.fchmod(out.fileno(), stat.S_IROTH|stat.S_IRGRP|stat.S_IRUSR|stat.S_IWUSR)
|
||||
out.close()
|
||||
|
||||
print 'Wrote output.html'
|
||||
|
||||
if FLAGS.output_type in ["BOTH", "STDOUT"]:
|
||||
print json.dumps(list, sort_keys=True, indent=4)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
||||
106
samples/gan/events/events_template.html
Normal file
106
samples/gan/events/events_template.html
Normal file
@@ -0,0 +1,106 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Event Response</title>
|
||||
<style>
|
||||
h2 {
|
||||
margin: 3ex 0 1ex;
|
||||
}
|
||||
th {
|
||||
background-color: grey;
|
||||
}
|
||||
td {
|
||||
vertical-align: top;
|
||||
overflow: auto;
|
||||
}
|
||||
tr.details td {
|
||||
padding: 0 3ex;
|
||||
}
|
||||
td pre {
|
||||
margin: 3ex 3em;
|
||||
width: 500px;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function toggleDisplay(id) {
|
||||
el = document.getElementById(id);
|
||||
if (el.style.display == "none") {
|
||||
el.style.display = "block"
|
||||
} else {
|
||||
el.style.display = "none"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Events</h1>
|
||||
<table border="1" cellspacing="0">
|
||||
{% for item in items %}
|
||||
<tr>
|
||||
<th>Event Date</th>
|
||||
{% if item.modifyDate %}<th>Modify Date</th> {% endif %}
|
||||
{% if item.advertiserId %}<th>Advertiser Id</th>{% endif %}
|
||||
{% if item.advertiserName %}<th>Advertiser Name</th>{% endif %}
|
||||
{% if item.publisherId %}<th>Publisher Id</th>{% endif %}
|
||||
{% if item.publisherName %}<th>Publisher Name</th>{% endif %}
|
||||
<th>Order Id</th>
|
||||
<th>Member Id</th>
|
||||
<th>Event Status</th>
|
||||
<th>Event Type</th>
|
||||
<th>Commissionable Sales</th>
|
||||
{% if item.earnings %}<th>Earnings (Publisher Only)</th>{% endif %}
|
||||
{% if item.publisherFee %}<th>Publisher Fee (Advertiser Only)</th>{% endif %}
|
||||
{% if item.networkFee %}<th>Network Fee (Advertiser Only)</th>{% endif %}
|
||||
<tr class="eventinfo">
|
||||
<td>{{ item.eventDate }}</td>
|
||||
{% if item.modifyDate %}<td>{{ item.modifyDate }}</td>{% endif %}
|
||||
<td>{{ item.advertiserId }}{{ item.publisherId }}</td>
|
||||
<td>{{ item.advertiserName }}{{ item.publisherName }}</td>
|
||||
<td>{{ item.orderId }}</td>
|
||||
<td>{{ item.memberId }}</td>
|
||||
<td>{{ item.status }}</td>
|
||||
<td>{{ item.type }}</td>
|
||||
<td>{{ item.commissionableSales }}</td>
|
||||
{% if item.earnings %}<td>{{ item.earnings }}</td> {% endif %}
|
||||
{% if item.publisherFee %}<td>{{ item.publisherFee }}</td>{% endif %}
|
||||
{% if item.networkFee %}<td>{{ item.networkFee }}</td>{% endif %}
|
||||
</tr>
|
||||
<tr style="border:1px solid #444">
|
||||
<td class="products">Products:</td>
|
||||
<td colspan="11">
|
||||
<table border="1" cellspacing="0">
|
||||
<tr>
|
||||
<th>Sku</th>
|
||||
<th>Sku Name</th>
|
||||
<th>Unit Price</th>
|
||||
<th>Category ID</th>
|
||||
<th>Category Name</th>
|
||||
<th>Quantity</th>
|
||||
<th>Publisher Fee</th>
|
||||
<th>Earnings</th>
|
||||
<th>Network Fee</th>
|
||||
</tr>
|
||||
{% for product in item.products %}
|
||||
<tr>
|
||||
<td>{{ product.sku }}</td>
|
||||
<td>{{ product.skuName }}</td>
|
||||
<td>{{ product.unitPrice }}</td>
|
||||
<td>{{ product.categoryId }}</td>
|
||||
<td>{{ product.categoryName }}</td>
|
||||
<td>{{ product.quantity }}</td>
|
||||
<td>{{ product.publisherFee }}</td>
|
||||
<td>{{ product.earnings }}</td>
|
||||
<td>{{ product.networkFee }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td>
|
||||
<p style="padding:10px">No events fit that criteria. Try searching for different timeframe.</p>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user