Skip to content

Commit

Permalink
Rename the whole damn thing to 'itunes-connect'.
Browse files Browse the repository at this point in the history
  • Loading branch information
alexvollmer committed Nov 7, 2009
1 parent 857cb86 commit 7301ff7
Show file tree
Hide file tree
Showing 23 changed files with 153 additions and 154 deletions.
31 changes: 15 additions & 16 deletions README.rdoc
@@ -1,4 +1,4 @@
= appstore
= itunes_connect

This gem provides a very simple command-line utility and backing
"library" (if I can be so bold to use the term in this context) for
Expand All @@ -10,34 +10,33 @@ for you.

=== Command-Line Usage

This gem comes with the <tt>appstore</tt> executable which you can use
This gem comes with the <tt>itunes_connect</tt> executable which you can use
to download reports, import into a sqlite database and report
from.

You can specify the default values for a handful of command-line
options by putting them in a file named <tt>.itunesrc</tt> in your
home directory. The file is in YAML format and should look something
like this:
home directory. The file is in YAML format and should have the
following keys:

---
:username: myusername
:password: mysekrets3key
:database: /my/appstore/database.db
* username
* password
* database (path to sqlite3 file, optional)

==== Downloading Reports
You can download reports from iTunes Connect using <tt>appstore
You can download reports from iTunes Connect using <tt>itunes_connect
download</tt>. You may specify your iTunes Connect credentials on
the command line _or_ you can put them in YAML format in
<tt>~/.itunesrc</tt> with the keys of <tt>:username</tt> and
<tt>:password</tt>.

You can also dump the report to a file (or standard out):

appstore download -o /tmp/report.txt
itunes_connect download -o /tmp/report.txt

Or you can dump it directly into a sqlite3 database:

appstore download -b /tmp/report.db
itunes_connect download -b /tmp/report.db

By default the <tt>download</tt> command will retrieve the most recent
daily report. If you have a <tt>database</tt> key in your
Expand All @@ -49,27 +48,27 @@ You can also ask for weekly or monthly reports by using the
montly report directly into the database because the monthly reports
don't have any days associated with the entries.

Run <tt>appstore help download</tt> for full usage details.
Run <tt>itunes_connect help download</tt> for full usage details.

==== Importing Reports
The <tt>import</tt> command allows you to dump an existing report file
into the database. This is useful if you've already downloaded a
number of reports from iTunes Connect and you just want to put them
into the database.

Run <tt>appstore help import</tt> for full usage details.
Run <tt>itunes_connect help import</tt> for full usage details.

==== Reporting
The <tt>report</tt> command queries your database and can produce
either detailed, or grouped output. In both cases you can constrain
the query to any combination of country, start date and end date.

Run <tt>appstore help report</tt> for full usage details.
Run <tt>itunes_connect help report</tt> for full usage details.

=== Programmatic Usage

See the documentation for the AppStore::Connection,
AppStore::Report and AppStore::Store classes for details.
See the documentation for the ItunesConnect::Connection,
ItunesConnect::Report and ItunesConnect::Store classes for details.

== Note on Patches/Pull Requests

Expand Down
8 changes: 4 additions & 4 deletions Rakefile
Expand Up @@ -4,11 +4,11 @@ require 'rake'
begin
require 'jeweler'
Jeweler::Tasks.new do |gem|
gem.name = "appstore"
gem.name = "itunes-connect"
gem.summary = %Q{Get your iTunes Connect Reports}
gem.description = %Q{Programmatic and command-line access to iTunes Connect Reports}
gem.email = "alex.vollmer@gmail.com"
gem.homepage = "http://github.com/alexvollmer/appstore"
gem.homepage = "http://github.com/alexvollmer/itunes-connect"
gem.authors = ["Alex Vollmer"]
gem.files = FileList["lib/**/*.rb", "bin/*", "spec/**/*"]

Expand Down Expand Up @@ -50,9 +50,9 @@ Rake::RDocTask.new do |rdoc|
end

rdoc.rdoc_dir = 'rdoc'
rdoc.title = "appstore #{version}"
rdoc.title = "itunes-connect #{version}"
rdoc.main = 'README.rdoc'
rdoc.rdoc_files.include('lib/*.rb')
rdoc.rdoc_files.include('README.rdoc')
rdoc.rdoc_files.include('lib/appstore/*.rb')
rdoc.rdoc_files.include('lib/itunes_connect/*.rb')
end
12 changes: 6 additions & 6 deletions bin/appstore → bin/itunes_connect
@@ -1,18 +1,18 @@
#!/usr/bin/env ruby

require "appstore"
require "itunes_connect"
require "clip"

AppStore::Commands.usage("No command given") if ARGV.empty?
ItunesConnect::Commands.usage("No command given") if ARGV.empty?

case command_name = ARGV.shift
when '--help', '-h'
cli = Clip::Parser.new
AppStore::Commands::Help.new(cli).execute!(cli)
ItunesConnect::Commands::Help.new(cli).execute!(cli)
else
cli = AppStore::Commands.default_clip
command = AppStore::Commands.for_name(command_name, cli)
AppStore::Commands.usage("Unrecognized command '#{command_name}'") if command.nil?
cli = ItunesConnect::Commands.default_clip
command = ItunesConnect::Commands.for_name(command_name, cli)
ItunesConnect::Commands.usage("Unrecognized command '#{command_name}'") if command.nil?
begin
cli.parse(ARGV)
if cli.valid?
Expand Down
5 changes: 0 additions & 5 deletions lib/appstore.rb

This file was deleted.

5 changes: 5 additions & 0 deletions lib/itunes_connect.rb
@@ -0,0 +1,5 @@
require "itunes_connect/connection"
require "itunes_connect/report"
require "itunes_connect/store"
require "itunes_connect/commands"

14 changes: 7 additions & 7 deletions lib/appstore/commands.rb → lib/itunes_connect/commands.rb
@@ -1,10 +1,10 @@
require "appstore/commands/download"
require "appstore/commands/import"
require "appstore/commands/report"
require "appstore/commands/help"
require "itunes_connect/commands/download"
require "itunes_connect/commands/import"
require "itunes_connect/commands/report"
require "itunes_connect/commands/help"
require "clip"

module AppStore::Commands # :nodoc:
module ItunesConnect::Commands # :nodoc:
class << self
def for_name(name, clip)
self.const_get(name.capitalize.to_sym).new(clip)
Expand All @@ -18,8 +18,8 @@ def all

def usage(msg)
$stderr.puts msg if msg
$stderr.puts "USAGE: appstore [command] [options]"
AppStore::Commands.all.each do |cmd_cls|
$stderr.puts "USAGE: itunes_connect [command] [options]"
ItunesConnect::Commands.all.each do |cmd_cls|
cli = Clip do |c|
c.banner = "'#{cmd_cls.to_s.split('::').last.downcase}' command options:"

Expand Down
@@ -1,9 +1,9 @@
require "appstore/rc_file"
require "appstore/report"
require "itunes_connect/rc_file"
require "itunes_connect/report"

module AppStore::Commands
module ItunesConnect::Commands
class Download # :nodoc:
def initialize(c, rcfile=AppStore::RcFile.default)
def initialize(c, rcfile=ItunesConnect::RcFile.default)
c.opt('u', 'username', :desc => 'iTunes Connect username')
c.opt('p', 'password', :desc => 'iTunes Connect password')
c.opt('d', 'date', :desc => 'Daily report date (MM/DD/YYYY format)',
Expand All @@ -27,7 +27,7 @@ def execute!(opts, args=[])

raise ArgumentError.new("Please provide a username") unless username
raise ArgumentError.new("Please provide a password") unless password

if opts.db and opts.out
raise ArgumentError.new("You can only specify :out or :db, not both")
end
Expand All @@ -38,7 +38,7 @@ def execute!(opts, args=[])
"associated with them")
end

connection = AppStore::Connection.new(username,
connection = ItunesConnect::Connection.new(username,
password,
opts.verbose?,
opts.debug?)
Expand All @@ -52,9 +52,9 @@ def execute!(opts, args=[])

if db and StringIO === out
$stdout.puts "Importing into database file: #{db}" if opts.verbose?
store = AppStore::Store.new(db, opts.verbose?)
store = ItunesConnect::Store.new(db, opts.verbose?)
out.rewind
report = AppStore::Report.new(out)
report = ItunesConnect::Report.new(out)
count = 0
report.each do |entry|
count += 1 if store.add(entry.date,
Expand Down
@@ -1,6 +1,6 @@
require "appstore/commands"
require "itunes_connect/commands"

module AppStore::Commands
module ItunesConnect::Commands
class Help # :nodoc:
def initialize(c)
# nothing to do here
Expand All @@ -10,14 +10,14 @@ def execute!(opts={ }, args=[], out=$stdout)
if args.empty?
out.puts "Available commands:"
out.puts
AppStore::Commands.all.each do |cmd|
ItunesConnect::Commands.all.each do |cmd|
out.printf("%-9s %s\n",
cmd.to_s.split('::').last.downcase,
cmd.new(Clip::Parser.new).description)
end
else
cli = AppStore::Commands.default_clip
cmd = AppStore::Commands.for_name(args.first, cli)
cli = ItunesConnect::Commands.default_clip
cmd = ItunesConnect::Commands.for_name(args.first, cli)
cli.banner = "Command options for '#{cmd.class.to_s.split('::').last.downcase}':"
raise ArgumentError.new("Unrecognized command '#{args.first}'") if cmd.nil?
out.puts(cli.help)
Expand Down
@@ -1,9 +1,9 @@
require "appstore/rc_file"
require "appstore/report"
require "itunes_connect/rc_file"
require "itunes_connect/report"

module AppStore::Commands
module ItunesConnect::Commands
class Import # :nodoc:
def initialize(c, rcfile=AppStore::RcFile.default)
def initialize(c, rcfile=ItunesConnect::RcFile.default)
c.opt('b', 'db', :desc => 'Dump report to sqlite DB at the given path')
c.req('f', 'file', :desc => 'The file to import, - means standard in')
@rcfile = rcfile
Expand All @@ -13,10 +13,10 @@ def execute!(opts, args=[])
db = opts.db || @rcfile.database || nil
raise ArgumentError.new("Missing :db option") unless db
raise ArgumentError.new("Missing :file option") if opts.file.nil?
store = AppStore::Store.new(db, opts.verbose?)
store = ItunesConnect::Store.new(db, opts.verbose?)
input = opts.file == '-' ? $stdin : open(opts.file, 'r')
count = 0
AppStore::Report.new(input).each do |entry|
ItunesConnect::Report.new(input).each do |entry|
count += 1 if store.add(entry.date,
entry.country,
entry.install_count,
Expand Down
@@ -1,9 +1,9 @@
require "appstore/rc_file"
require "appstore/store"
require "itunes_connect/rc_file"
require "itunes_connect/store"

module AppStore::Commands
module ItunesConnect::Commands
class Report # :nodoc:
def initialize(c, rcfile=AppStore::RcFile.default)
def initialize(c, rcfile=ItunesConnect::RcFile.default)
c.opt('b', 'db', :desc => 'Dump report to sqlite DB at the given path')
c.opt('c', 'country',
:desc => 'A two-letter country code to filter results with')
Expand All @@ -25,15 +25,15 @@ def initialize(c, rcfile=AppStore::RcFile.default)
def execute!(opts, args=[], out=$stdout)
db = opts.db || @rcfile.database || nil
raise ArgumentError.new("Missing :db option") if db.nil?
store = AppStore::Store.new(db)
store = ItunesConnect::Store.new(db)
params = {
:to => opts.to,
:from => opts.from,
:country => opts.country
}

total_installs, total_upgrades = 0, 0

unless opts.no_header?
out.puts([opts.summarize? ? nil : "Date",
"Country",
Expand Down
12 changes: 6 additions & 6 deletions lib/appstore/connection.rb → lib/itunes_connect/connection.rb
Expand Up @@ -6,13 +6,13 @@
require "httpclient"
require "nokogiri"

module AppStore
module ItunesConnect

# Abstracts the iTunes Connect website.
# Implementation inspired by
# http://code.google.com/p/itunes-connect-scraper/
class Connection

REPORT_PERIODS = ["Monthly Free", "Weekly", "Daily"]

BASE_URL = 'https://itts.apple.com' # :nodoc:
Expand Down Expand Up @@ -43,7 +43,7 @@ def debug? # :nodoc:
#
# Any dates given that equal the current date or newer will cause
# this method to raise an <tt>ArgumentError</tt>.
#
#
def get_report(date, out, period='Daily')
date = Date.parse(date) if String === date
if date >= Date.today
Expand Down Expand Up @@ -96,7 +96,7 @@ def get_report(date, out, period='Daily')
end

raise ArgumentError, "No reports are available for that date" unless date_str

report = get_content(report_url, {
report_type_name => 'Summary',
date_type_name => period,
Expand All @@ -117,7 +117,7 @@ def get_report(date, out, period='Daily')
end
end

private
private

def client
@client ||= client = HTTPClient.new
Expand Down Expand Up @@ -153,7 +153,7 @@ def get_content(uri, query=nil, headers={ })
end
puts "#{url} -> #{path}"
end

@referer = url
response.body.dump
end
Expand Down
4 changes: 2 additions & 2 deletions lib/appstore/rc_file.rb → lib/itunes_connect/rc_file.rb
@@ -1,13 +1,13 @@
require "yaml"

class AppStore::RcFile # :nodoc:
class ItunesConnect::RcFile # :nodoc:

DEFAULT_RCFILE_PATH = File.expand_path("~/.itunesrc")

def self.default
self.new(DEFAULT_RCFILE_PATH)
end

def initialize(path=DEFAULT_RCFILE_PATH)
if File.exist?(path)
@rc = YAML.load_file(path)
Expand Down
4 changes: 2 additions & 2 deletions lib/appstore/report.rb → lib/itunes_connect/report.rb
Expand Up @@ -4,12 +4,12 @@
# series of objects representing each row. You can either get the
# entire set of data by accessing the +data+ attribute, or by calling
# the +each+ method and handing it a block.
class AppStore::Report
class ItunesConnect::Report
include Enumerable

# The report as a Hash, where the keys are country codes and the
# values are Hashes with the keys, <tt>:date</tt>, <tt>:upgrade</tt>,
# <tt>:install</tt>.
# <tt>:install</tt>.
attr_reader :data

# Give me an +IO+-like object (one that responds to the +each+
Expand Down

0 comments on commit 7301ff7

Please sign in to comment.