1. Statistiques de ventes des
Applications AppStore et
MacAppStore
Frank Lefebvre & Jacques Foucry
Cocoaheads Paris 14/03/2013
2. L’existant
iTunesConnect : site web et application iOS
Données agrégées après 15 jours
C’est beau mais bon...
Les applications dans le cloud
Obligation de laisser un login/mot de passe
Non sérieux, le cloud...
Récupération des données
Solution fournie par Apple (même s’ils ne sont pas
au courant)
3. Autoingestion.class
C’est une classe Java fournie par Apple
Documentation
iTunes Connect Sales and Trends Guide
Limitations
... Et si on refaisait le truc ?
4. Reverse engineering
...
String body = "USERNAME=" + URLEncoder.encode(paramArrayOfString[0], "UTF-8");
body = body + "&PASSWORD=" + URLEncoder.encode(paramArrayOfString[1], "UTF-8");
body = body + "&VNDNUMBER=" + URLEncoder.encode(paramArrayOfString[2], "UTF-8");
body = body + "&TYPEOFREPORT=" + URLEncoder.encode(paramArrayOfString[3], "UTF-8");
body = body + "&DATETYPE=" + URLEncoder.encode(paramArrayOfString[4], "UTF-8");
body = body + "&REPORTTYPE=" + URLEncoder.encode(paramArrayOfString[5], "UTF-8");
body = body + "&REPORTDATE=" + URLEncoder.encode(str1, "UTF-8");
URL url = new URL("https://reportingitc.apple.com/autoingestion.tft?");
HttpsURLConnection connection = url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setDoOutput(true);
OutputStreamWriter localOutputStreamWriter = new
OutputStreamWriter(connection.getOutputStream());
localOutputStreamWriter.write(body);
localOutputStreamWriter.flush();
localOutputStreamWriter.close();
...
5. Que nous envoie Apple ?
Daily summary avec différenciation des ventes, des
mises à jour, des in-app purchases
NewsStand : abonnements et données personnelles
Données iOS et MacAppStore
Apple ne fournit que deux semaines de données
Obligation de récupérer tous les jours et de
stocker localement (+backup)
6. Format du fichier
C’est du texte Gzippé
Tab delimited
Avec les entêtes
Attention, les dates sont au format US (mm/dd/yyyy)
7. Un compte spécifique
Dans iTunesConnect, il est possible de créer des
comptes avec des droits restreints
Cela va faciliter l’automatisation
Et surtout sécuriser l’accès au compte
15. Stockage
Archivage (et backup) des fichier txt.gz
une base données sqlite3
Disponible directement sous OSX
Facile à installer sur d’autres environnements
16. Schéma de la base
product daily_summary report_date
product_id product_version date
apple_product_id transaction_type
product_sku units
iap_parent_sku customer_country
product_name customer_currency
developer payment_currency
customer_price
payment_price
promo_code
subscription_type
subscription_period
17. Le script Python
Pourquoi Python ?
Parce que pas perl !
Simple à mettre en œuvre, présent sur toutes les
plateformes
Intégration sqlite3
18. Dépendances
Python 2.7
Dispo sans problème sur OSX, ça peut être
amusant sur d’autres OS (par exemple CentOS)
Mako, pour les gabarits
Flotr2, pour le rendu
20. Ligne de commande
iTunesStats
--download config_file [--date yyyy-mm-dd]
--download-import config_file [--date yyyy-mm-dd]
--import config_file path
--report config_file
21. Fichier de configuration
Trois sections :
[iTunes] : les informations nécessaires à la
connection à iTunesConnect
[data] : les informations de stockage (fichiers tgz
et base de données)
[report] : l’emplacement des templates et le
répertoire où son stockés les rapports
22. Fichier de configuration, un
exemple
[iTunes]
username = sales@foucry.net
password = Tucroyaisquejelaisseraismonmotdepasse
vendor = 12345678
[data]
archive = /Users/jacques/its/sales
history = /Users/jacques/its/itc-history
database = /Users/jacques/its/sales/itunes-stats.db
[report]
templates = /Users/jacques/its/templates
output = /Users/jacques/its/output
23. Automatisation
Quelle est la meilleure heure pour lancer la
récupération des stats ?
La plupart du temps, c’est 14h30 UTC
Parfois il y a des ratés (serveurs surchargés par
exemple)
Et pourquoi pas toutes les heures ?
S’il n’y a rien à récupérer, on ne fait rien
24. Sur OSX
launchd
une plist qui décrit au daemon launchd comment
lancer le script et quand
26. Emplacement des fichiers
Fichier Launchd
à mettre dans /Library/LaunchDaemons
Fichier de paramètres
par exemple dans /etc/itc (ou /Library/Application
Support/its)
Les scripts
j’aime bien mettre mes scripts dans /usr/local/
scripts
27. Prise en compte par launchd
et vérification
sudo launchctl load -w /Library/LaunchDaemons/
net.correze-software.its.plist
sudo launchctl list
28. Sur un autre unix like (linux,
*BSD, Aix, Solaris, sco...)
cron/crontab
Deux posibilités :
éditer la crontab
utiliser le répertoire /etc/cron.hourly
29. Éditer la crontab
$ crontab -e
25! *! *! *! /usr/local/scripts/iTunesStats --
*!
download-import /home/jacques/its-param 1> /dev/null
2> /var/log/its_download.log
(Lancement toutes les heures de tous les jours,
tous les mois... à 25 minutes)
30. Utiliser /etc/cron.hourly
Il suffit de déposer dans ce répertoire un petit script
shell qui lancera notre script avec les paramètres
nécessaires
#!/bin/sh
if [ -x /usr/local/scripts/iTunesStats]
then
! /usr/local/scripts/iTunesStats --download-import /home/jacques/
its-param 1> /dev/null 2>/var/log/its_download.log
fi
31. Le rendu
Assuré par Flotr2 <http://humblesoftware.com/
flotr2/>
du json
un template mako
32. le json
Généré par le script its_report.py (requête sur la
base et écriture du résultat sous forme de json)
33. Le template Mako
Pour intégrer le json à du HTML++ (avec des
boucles, des variables, etc)
Génére le fichier HTML