Permalink
Browse files

Now works with multiple iTunes Connect accounts.

  • Loading branch information...
Basil Shkara
Basil Shkara committed Nov 28, 2009
1 parent f5358d0 commit 62b5282097902e41ccee856a5e28cbbe10d48839
View
@@ -1,5 +1,5 @@
CATEGORIES = {
- "Top 200" :25211,
+ "Top 100" :25211,
"Lifestyle" :25203,
}
COUNTRIES = {
View
@@ -202,7 +202,15 @@ def units_chart(self, pid):
# Add vertical labels
max_num_vertical_labels = 15
overall_chart.left.min = 0
- overall_chart.left.max = max(upgrades) if max(upgrades) > max(sales) else max(sales)
+
+ max_sales = 0
+ max_upgrades = 0
+ if sales:
+ max_sales = max(sales)
+ if upgrades:
+ max_upgrades = max(upgrades)
+
+ overall_chart.left.max = max_upgrades if max_upgrades > max_sales else max_sales
vertical_labels = []
segment_gap = overall_chart.left.max / max_num_vertical_labels
for i in range(0, max_num_vertical_labels + 1):
View
@@ -18,7 +18,7 @@ def get(self):
# Queue requests for category rankings
self.fetch_rankings(pid, category_id)
# Queue requests for top 100 list
- self.fetch_rankings(pid, jobs.app_store_codes.CATEGORIES['Top 200'])
+ self.fetch_rankings(pid, jobs.app_store_codes.CATEGORIES['Top 100'])
def fetch_rankings(self, pid, category_id):
app_id = settings.PRODUCTS[pid]['app_id']
View
@@ -20,17 +20,20 @@ def get(self):
one_day = datetime.timedelta(days=1)
yesterday = now - one_day
yesterday = yesterday.strftime('%m/%d/%Y')
- try:
- latest_report = itcscrape.getLastDayReport(settings.SETTINGS['itunesconnect_username'], settings.SETTINGS['itunesconnect_password'], yesterday)
- report_persister.persist(latest_report['filename'], latest_report['content'])
- except:
- # Download failed (timeout or report not available yet)
- # Send email to administrator
- message = mail.EmailMessage(sender=settings.SETTINGS['admin_email_address'],
- subject='[ASM] Report job failed for: ' + yesterday)
- message.to = settings.SETTINGS['admin_email_address']
- message.body = 'Failed to download the iTunes Connect sales report for: ' + yesterday
- message.send()
+
+ # Fetch for all available accounts
+ for account_name in settings.ACCOUNTS:
+ try:
+ latest_report = itcscrape.getLastDayReport(settings.ACCOUNTS[account_name]['itunesconnect_username'], settings.ACCOUNTS[account_name]['itunesconnect_password'], yesterday)
+ report_persister.persist(latest_report['filename'], latest_report['content'])
+ except:
+ # Download failed (timeout or report not available yet)
+ # Send email to administrator
+ message = mail.EmailMessage(sender=settings.SETTINGS['admin_email_address'],
+ subject='[ASM] Report job failed for: ' + yesterday)
+ message.to = settings.SETTINGS['admin_email_address']
+ message.body = 'Failed to download the iTunes Connect sales report for: ' + yesterday
+ message.send()
def main():
application = webapp.WSGIApplication([('/jobs/pull_report', ReportJob)], debug=True)
View
@@ -4,4 +4,5 @@ class RawReport(db.Model):
filename = db.StringProperty(multiline=False)
content = db.TextProperty()
report_date = db.DateTimeProperty()
+ sha1 = db.StringProperty(multiline=False)
date_added = db.DateTimeProperty(auto_now_add=True)
@@ -4,6 +4,7 @@
import StringIO
import csv, decimal
import xml.dom.minidom #Used for currency converter
+from google.appengine.api import urlfetch
# Munging code taken and modified from http://www.rogueamoeba.com/utm/2009/05/04/itunesconnectarchiver/
# Thanks RA!
@@ -133,9 +134,10 @@ def conversionTableForDate( self, date ):
#We do little error checking here, because I'm not really in the mood to be paranoid
#Should just wrap it in giant try: block at some point
- socket = urllib2.urlopen( 'http://api.finance.xaviermedia.com/api/latest.xml' )
- xmlData = socket.read()
- socket.close()
+ response = urlfetch.fetch(url='http://api.finance.xaviermedia.com/api/latest.xml',
+ method=urlfetch.GET,
+ deadline=10)
+ xmlData = response.content
xmlTree = xml.dom.minidom.parseString( xmlData )
baseCurrency = xmlTree.getElementsByTagName('basecurrency')[0].firstChild.data
@@ -3,6 +3,7 @@
import models.data
import re
import settings
+import hashlib
from processors import report_munger
@@ -20,12 +21,14 @@ def persist(filename, content):
def persist_original_file(filename, date, content):
# Check if the report already exists in the data store
- existing_report = db.GqlQuery("SELECT * FROM RawReport where report_date = :1 LIMIT 1", date).get()
+ sha1 = hashlib.sha1(content).hexdigest()
+ existing_report = db.GqlQuery("SELECT * FROM RawReport WHERE report_date = :1 AND sha1 = :2 LIMIT 1", date, sha1).get()
if existing_report == None:
report = models.raw_report.RawReport()
report.filename = filename
report.content = content
+ report.sha1 = sha1
report.report_date = date
return report.put()
else:
@@ -43,21 +46,22 @@ def persist_parsed_data(parsed_data):
upgrades = parsed_data[date]['upgrades']
# Store sale and upgrade data in separate tables
- sale_store = models.data.Sale()
- _store_data(sales, sale_store, date)
- upgrade_store = models.data.Upgrade()
- _store_data(upgrades, upgrade_store, date)
-
- sale_store.put()
- upgrade_store.put()
-
-def _store_data(data, store, date):
- for product in data:
- store.income_revenue = float(product['incomeRevenue'])
- store.income_units = product['incomeUnits']
- store.revenue_by_currency = product['revenueByCurrency']
- store.units_by_country = product['unitsByCountry']
- store.refund_loss = float(product['refundLoss'])
- store.refund_units = float(product['refundUnits'])
- store.pid = product['pid']
- store.report_date = date
+ for product in sales:
+ sale_store = models.data.Sale()
+ _store_data(product, sale_store, date)
+ sale_store.put()
+
+ for product in upgrades:
+ upgrade_store = models.data.Upgrade()
+ _store_data(product, upgrade_store, date)
+ upgrade_store.put()
+
+def _store_data(product, store, date):
+ store.income_revenue = float(product['incomeRevenue'])
+ store.income_units = product['incomeUnits']
+ store.revenue_by_currency = product['revenueByCurrency']
+ store.units_by_country = product['unitsByCountry']
+ store.refund_loss = float(product['refundLoss'])
+ store.refund_units = float(product['refundUnits'])
+ store.pid = product['pid']
+ store.report_date = date
View
@@ -9,10 +9,12 @@
import datetime
import settings
import os
+import urllib
import models.data
def fetch_reports(app_name, format_date=True):
+ app_name = urllib.unquote(app_name)
products = settings.PRODUCTS.keys()
# Find the product ID for the provided application name
found = False
View
@@ -10,10 +10,6 @@
# Currency you would like your daily income revenue figures to be converted to
"base_currency": "AUD",
- # Your iTunes Connect credentials for the cron job to log in and download your reports daily
- "itunesconnect_username": "<<username>>",
- "itunesconnect_password": "<<password>>",
-
# This must be the email address of a registered administrator for the application due to mail API restrictions
"admin_email_address": "My Name <sender@example.com>",
@@ -22,6 +18,15 @@
"upload_form_name": "file_upload",
}
+ACCOUNTS = {
+ # Your iTunes Connect credentials for the cron job to log in and download your reports daily
+ # You can specify more than 1 account
+ "<< Arbitrary account name >>": {
+ "itunesconnect_username": "<<username>>",
+ "itunesconnect_password": "<<password>>",
+ }
+}
+
PRODUCTS = {
# SKU of the app when you uploaded it to the App Store
"<<SKU>>": {
View
@@ -21,7 +21,7 @@ <h3>Figures</h3>
<p> - <b>{{ upgrade_rate }}</b></p>
<p>Approximate total income revenue ({{ currency }}):</p>
- <p> - <b>{{ sales_total_revenue }}</b></p>
+ <p> - <b>${{ sales_total_revenue }}</b></p>
<p>Rankings (as of {{ rankings_pull_date }} UTC):</p>

0 comments on commit 62b5282

Please sign in to comment.