itunes-connect 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
 - data/README.rdoc +86 -0
 - data/bin/itunes_connect +27 -0
 - data/lib/itunes_connect.rb +5 -0
 - data/lib/itunes_connect/commands.rb +41 -0
 - data/lib/itunes_connect/commands/download.rb +76 -0
 - data/lib/itunes_connect/commands/help.rb +31 -0
 - data/lib/itunes_connect/commands/import.rb +35 -0
 - data/lib/itunes_connect/commands/report.rb +78 -0
 - data/lib/itunes_connect/connection.rb +162 -0
 - data/lib/itunes_connect/rc_file.rb +30 -0
 - data/lib/itunes_connect/report.rb +56 -0
 - data/lib/itunes_connect/store.rb +129 -0
 - data/spec/commands/download_spec.rb +140 -0
 - data/spec/commands/help_spec.rb +64 -0
 - data/spec/commands/import_spec.rb +66 -0
 - data/spec/commands/report_spec.rb +195 -0
 - data/spec/commands_spec.rb +47 -0
 - data/spec/connection_spec.rb +26 -0
 - data/spec/fakeweb/homepage +365 -0
 - data/spec/fixtures/report.txt +5 -0
 - data/spec/report_spec.rb +37 -0
 - data/spec/spec_helper.rb +13 -0
 - data/spec/store_spec.rb +142 -0
 - metadata +146 -0
 
| 
         @@ -0,0 +1,195 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe ItunesConnect::Commands::Report do
         
     | 
| 
      
 4 
     | 
    
         
            +
              before(:each) do
         
     | 
| 
      
 5 
     | 
    
         
            +
                @cmd = ItunesConnect::Commands::Report.new(mock(:null_object => true))
         
     | 
| 
      
 6 
     | 
    
         
            +
                @defaults = {
         
     | 
| 
      
 7 
     | 
    
         
            +
                  :db => '/tmp/store.db',
         
     | 
| 
      
 8 
     | 
    
         
            +
                  :summarize? => false,
         
     | 
| 
      
 9 
     | 
    
         
            +
                  :to => nil,
         
     | 
| 
      
 10 
     | 
    
         
            +
                  :from => nil,
         
     | 
| 
      
 11 
     | 
    
         
            +
                  :country => nil,
         
     | 
| 
      
 12 
     | 
    
         
            +
                  :no_header? => false,
         
     | 
| 
      
 13 
     | 
    
         
            +
                  :delimiter => "\t",
         
     | 
| 
      
 14 
     | 
    
         
            +
                  :total? => false
         
     | 
| 
      
 15 
     | 
    
         
            +
                }
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              describe 'with valid execution arguments' do
         
     | 
| 
      
 19 
     | 
    
         
            +
                before(:each) do
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @store = mock(ItunesConnect::Store)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  ItunesConnect::Store.should_receive(:new).
         
     | 
| 
      
 22 
     | 
    
         
            +
                    with("/tmp/store.db").
         
     | 
| 
      
 23 
     | 
    
         
            +
                    and_return(@store)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  @io = StringIO.new
         
     | 
| 
      
 25 
     | 
    
         
            +
                  @data = [
         
     | 
| 
      
 26 
     | 
    
         
            +
                           mock(:report_date => Date.parse('2009/09/09'), :country => 'US',
         
     | 
| 
      
 27 
     | 
    
         
            +
                                :install_count => 1, :update_count => 2),
         
     | 
| 
      
 28 
     | 
    
         
            +
                           mock(:report_date => Date.parse('2009/09/09'), :country => 'GB',
         
     | 
| 
      
 29 
     | 
    
         
            +
                                :install_count => 3, :update_count => 4)
         
     | 
| 
      
 30 
     | 
    
         
            +
                          ]
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                it 'should request counts with no options with no qualifiers' do
         
     | 
| 
      
 34 
     | 
    
         
            +
                  @store.should_receive(:counts).and_return(@data)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  clip = stub(@defaults.merge(:db => '/tmp/store.db'))
         
     | 
| 
      
 36 
     | 
    
         
            +
                  @cmd.execute!(clip, [], @io)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  @io.string.should == <<EOF
         
     | 
| 
      
 38 
     | 
    
         
            +
            Date\tCountry\tInstalls\tUpgrades
         
     | 
| 
      
 39 
     | 
    
         
            +
            2009-09-09\tUS\t1\t2
         
     | 
| 
      
 40 
     | 
    
         
            +
            2009-09-09\tGB\t3\t4
         
     | 
| 
      
 41 
     | 
    
         
            +
            EOF
         
     | 
| 
      
 42 
     | 
    
         
            +
                end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                it 'should output data with other options' do
         
     | 
| 
      
 45 
     | 
    
         
            +
                  @store.should_receive(:counts).
         
     | 
| 
      
 46 
     | 
    
         
            +
                    with(:to => Date.parse('2009/09/09'),
         
     | 
| 
      
 47 
     | 
    
         
            +
                         :from => Date.parse('2009/09/01'),
         
     | 
| 
      
 48 
     | 
    
         
            +
                         :country => 'US').
         
     | 
| 
      
 49 
     | 
    
         
            +
                    and_return(@data)
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                  clip = stub(@defaults.merge(:db => '/tmp/store.db',
         
     | 
| 
      
 52 
     | 
    
         
            +
                                              :to => Date.parse('2009/09/09'),
         
     | 
| 
      
 53 
     | 
    
         
            +
                                              :from => Date.parse('2009/09/01'),
         
     | 
| 
      
 54 
     | 
    
         
            +
                                              :country => 'US'))
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  @cmd.execute!(clip, [], @io)
         
     | 
| 
      
 57 
     | 
    
         
            +
                  @io.string.should == <<EOF
         
     | 
| 
      
 58 
     | 
    
         
            +
            Date\tCountry\tInstalls\tUpgrades
         
     | 
| 
      
 59 
     | 
    
         
            +
            2009-09-09\tUS\t1\t2
         
     | 
| 
      
 60 
     | 
    
         
            +
            2009-09-09\tGB\t3\t4
         
     | 
| 
      
 61 
     | 
    
         
            +
            EOF
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                it 'should suppress the header when requested' do
         
     | 
| 
      
 65 
     | 
    
         
            +
                  @store.should_receive(:counts). and_return(@data)
         
     | 
| 
      
 66 
     | 
    
         
            +
                  clip = stub(@defaults.merge(:no_header? => true))
         
     | 
| 
      
 67 
     | 
    
         
            +
                  @cmd.execute!(clip, [], @io)
         
     | 
| 
      
 68 
     | 
    
         
            +
                  @io.string.should == <<EOF
         
     | 
| 
      
 69 
     | 
    
         
            +
            2009-09-09\tUS\t1\t2
         
     | 
| 
      
 70 
     | 
    
         
            +
            2009-09-09\tGB\t3\t4
         
     | 
| 
      
 71 
     | 
    
         
            +
            EOF
         
     | 
| 
      
 72 
     | 
    
         
            +
                end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                it 'should separate fields with specified delimiter' do
         
     | 
| 
      
 75 
     | 
    
         
            +
                  @store.should_receive(:counts). and_return(@data)
         
     | 
| 
      
 76 
     | 
    
         
            +
                  clip = stub(@defaults.merge(:delimiter => "|"))
         
     | 
| 
      
 77 
     | 
    
         
            +
                  @cmd.execute!(clip, [], @io)
         
     | 
| 
      
 78 
     | 
    
         
            +
                  @io.string.should == <<EOF
         
     | 
| 
      
 79 
     | 
    
         
            +
            Date|Country|Installs|Upgrades
         
     | 
| 
      
 80 
     | 
    
         
            +
            2009-09-09|US|1|2
         
     | 
| 
      
 81 
     | 
    
         
            +
            2009-09-09|GB|3|4
         
     | 
| 
      
 82 
     | 
    
         
            +
            EOF
         
     | 
| 
      
 83 
     | 
    
         
            +
                end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                it 'should output totals when the "totals" flag is specified' do
         
     | 
| 
      
 86 
     | 
    
         
            +
                  @store.should_receive(:counts). and_return(@data)
         
     | 
| 
      
 87 
     | 
    
         
            +
                  clip = stub(@defaults.merge(:total? => true))
         
     | 
| 
      
 88 
     | 
    
         
            +
                  @cmd.execute!(clip, [], @io)
         
     | 
| 
      
 89 
     | 
    
         
            +
                  @io.string.should == <<EOF
         
     | 
| 
      
 90 
     | 
    
         
            +
            Date\tCountry\tInstalls\tUpgrades
         
     | 
| 
      
 91 
     | 
    
         
            +
            2009-09-09\tUS\t1\t2
         
     | 
| 
      
 92 
     | 
    
         
            +
            2009-09-09\tGB\t3\t4
         
     | 
| 
      
 93 
     | 
    
         
            +
            Total\t-\t4\t6
         
     | 
| 
      
 94 
     | 
    
         
            +
            EOF
         
     | 
| 
      
 95 
     | 
    
         
            +
                end
         
     | 
| 
      
 96 
     | 
    
         
            +
              end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
              describe 'with :group option specified' do
         
     | 
| 
      
 99 
     | 
    
         
            +
                before(:each) do
         
     | 
| 
      
 100 
     | 
    
         
            +
                  @store = mock(ItunesConnect::Store)
         
     | 
| 
      
 101 
     | 
    
         
            +
                  ItunesConnect::Store.should_receive(:new).
         
     | 
| 
      
 102 
     | 
    
         
            +
                    with('/tmp/store.db').
         
     | 
| 
      
 103 
     | 
    
         
            +
                    and_return(@store)
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                  @io = StringIO.new
         
     | 
| 
      
 106 
     | 
    
         
            +
                  @data = [
         
     | 
| 
      
 107 
     | 
    
         
            +
                           mock(:country => 'US', :install_count => 1, :update_count => 2),
         
     | 
| 
      
 108 
     | 
    
         
            +
                           mock(:country => 'GB', :install_count => 3, :update_count => 4)
         
     | 
| 
      
 109 
     | 
    
         
            +
                          ]
         
     | 
| 
      
 110 
     | 
    
         
            +
                end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                it 'should request grouped country data' do
         
     | 
| 
      
 113 
     | 
    
         
            +
                  @store.should_receive(:country_counts).and_return(@data)
         
     | 
| 
      
 114 
     | 
    
         
            +
                  clip = stub(@defaults.merge(:summarize? => true))
         
     | 
| 
      
 115 
     | 
    
         
            +
                  @cmd.execute!(clip, [], @io)
         
     | 
| 
      
 116 
     | 
    
         
            +
                  @io.string.should == <<EOF
         
     | 
| 
      
 117 
     | 
    
         
            +
            Country\tInstalls\tUpgrades
         
     | 
| 
      
 118 
     | 
    
         
            +
            US\t1\t2
         
     | 
| 
      
 119 
     | 
    
         
            +
            GB\t3\t4
         
     | 
| 
      
 120 
     | 
    
         
            +
            EOF
         
     | 
| 
      
 121 
     | 
    
         
            +
                end
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                it 'should suppress the header when requested' do
         
     | 
| 
      
 124 
     | 
    
         
            +
                  @store.should_receive(:country_counts).and_return(@data)
         
     | 
| 
      
 125 
     | 
    
         
            +
                  clip = stub(@defaults.merge(:summarize? => true, :no_header? => true))
         
     | 
| 
      
 126 
     | 
    
         
            +
                  @cmd.execute!(clip, [], @io)
         
     | 
| 
      
 127 
     | 
    
         
            +
                  @io.string.should == <<EOF
         
     | 
| 
      
 128 
     | 
    
         
            +
            US\t1\t2
         
     | 
| 
      
 129 
     | 
    
         
            +
            GB\t3\t4
         
     | 
| 
      
 130 
     | 
    
         
            +
            EOF
         
     | 
| 
      
 131 
     | 
    
         
            +
                end
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
                it 'should separate fields with the specified delimiter' do
         
     | 
| 
      
 134 
     | 
    
         
            +
                  @store.should_receive(:country_counts).and_return(@data)
         
     | 
| 
      
 135 
     | 
    
         
            +
                  clip = stub(@defaults.merge(:summarize? => true, :delimiter => '|'))
         
     | 
| 
      
 136 
     | 
    
         
            +
                  @cmd.execute!(clip, [], @io)
         
     | 
| 
      
 137 
     | 
    
         
            +
                  @io.string.should == <<EOF
         
     | 
| 
      
 138 
     | 
    
         
            +
            Country|Installs|Upgrades
         
     | 
| 
      
 139 
     | 
    
         
            +
            US|1|2
         
     | 
| 
      
 140 
     | 
    
         
            +
            GB|3|4
         
     | 
| 
      
 141 
     | 
    
         
            +
            EOF
         
     | 
| 
      
 142 
     | 
    
         
            +
                end
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
                it 'should output totals when the "totals" flag is specified' do
         
     | 
| 
      
 145 
     | 
    
         
            +
                  @store.should_receive(:country_counts).and_return(@data)
         
     | 
| 
      
 146 
     | 
    
         
            +
                  clip = stub(@defaults.merge(:summarize? => true, :total? => true))
         
     | 
| 
      
 147 
     | 
    
         
            +
                  @cmd.execute!(clip, [], @io)
         
     | 
| 
      
 148 
     | 
    
         
            +
                  @io.string.should == <<EOF
         
     | 
| 
      
 149 
     | 
    
         
            +
            Country\tInstalls\tUpgrades
         
     | 
| 
      
 150 
     | 
    
         
            +
            US\t1\t2
         
     | 
| 
      
 151 
     | 
    
         
            +
            GB\t3\t4
         
     | 
| 
      
 152 
     | 
    
         
            +
            Total\t4\t6
         
     | 
| 
      
 153 
     | 
    
         
            +
            EOF
         
     | 
| 
      
 154 
     | 
    
         
            +
                end
         
     | 
| 
      
 155 
     | 
    
         
            +
              end
         
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
      
 157 
     | 
    
         
            +
              describe 'with invalid execution arguments' do
         
     | 
| 
      
 158 
     | 
    
         
            +
                it 'should require the :db option' do
         
     | 
| 
      
 159 
     | 
    
         
            +
                  lambda { @cmd.execute! }.should raise_error(ArgumentError)
         
     | 
| 
      
 160 
     | 
    
         
            +
                end
         
     | 
| 
      
 161 
     | 
    
         
            +
              end
         
     | 
| 
      
 162 
     | 
    
         
            +
             
     | 
| 
      
 163 
     | 
    
         
            +
              describe 'command-line option parsing' do
         
     | 
| 
      
 164 
     | 
    
         
            +
                it 'should add appropriate options to a given Clip' do
         
     | 
| 
      
 165 
     | 
    
         
            +
                  clip = mock("Clip")
         
     | 
| 
      
 166 
     | 
    
         
            +
                  clip.should_receive(:opt).
         
     | 
| 
      
 167 
     | 
    
         
            +
                    with('b', 'db',
         
     | 
| 
      
 168 
     | 
    
         
            +
                         :desc => 'Dump report to sqlite DB at the given path')
         
     | 
| 
      
 169 
     | 
    
         
            +
                  clip.should_receive(:opt).
         
     | 
| 
      
 170 
     | 
    
         
            +
                    with('c', 'country',
         
     | 
| 
      
 171 
     | 
    
         
            +
                         :desc => 'A two-letter country code to filter results with')
         
     | 
| 
      
 172 
     | 
    
         
            +
                  clip.should_receive(:opt).
         
     | 
| 
      
 173 
     | 
    
         
            +
                    with('f', 'from',
         
     | 
| 
      
 174 
     | 
    
         
            +
                         :desc => 'The starting date, inclusive')
         
     | 
| 
      
 175 
     | 
    
         
            +
                  clip.should_receive(:opt).
         
     | 
| 
      
 176 
     | 
    
         
            +
                    with('t', 'to',
         
     | 
| 
      
 177 
     | 
    
         
            +
                         :desc => 'The ending date, inclusive')
         
     | 
| 
      
 178 
     | 
    
         
            +
                  clip.should_receive(:flag).
         
     | 
| 
      
 179 
     | 
    
         
            +
                    with('s', 'summarize',
         
     | 
| 
      
 180 
     | 
    
         
            +
                         :desc => 'Summarize results by country code')
         
     | 
| 
      
 181 
     | 
    
         
            +
                  clip.should_receive(:flag).
         
     | 
| 
      
 182 
     | 
    
         
            +
                    with('n', 'no-header',
         
     | 
| 
      
 183 
     | 
    
         
            +
                         :desc => 'Suppress the column headers on output')
         
     | 
| 
      
 184 
     | 
    
         
            +
                  clip.should_receive(:opt).
         
     | 
| 
      
 185 
     | 
    
         
            +
                    with('d', 'delimiter',
         
     | 
| 
      
 186 
     | 
    
         
            +
                         :desc => 'The delimiter to use for output (normally TAB)',
         
     | 
| 
      
 187 
     | 
    
         
            +
                         :default => "\t")
         
     | 
| 
      
 188 
     | 
    
         
            +
                  clip.should_receive(:flag).
         
     | 
| 
      
 189 
     | 
    
         
            +
                    with('o', 'total', :desc => 'Add totals at the end of the report')
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
                  ItunesConnect::Commands::Report.new(clip)
         
     | 
| 
      
 192 
     | 
    
         
            +
                end
         
     | 
| 
      
 193 
     | 
    
         
            +
              end
         
     | 
| 
      
 194 
     | 
    
         
            +
             
     | 
| 
      
 195 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,47 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe ItunesConnect::Commands do
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              describe 'all' do
         
     | 
| 
      
 6 
     | 
    
         
            +
                it 'should return all available command' do
         
     | 
| 
      
 7 
     | 
    
         
            +
                  ItunesConnect::Commands.all.should == [
         
     | 
| 
      
 8 
     | 
    
         
            +
                                                    ItunesConnect::Commands::Download,
         
     | 
| 
      
 9 
     | 
    
         
            +
                                                    ItunesConnect::Commands::Import,
         
     | 
| 
      
 10 
     | 
    
         
            +
                                                    ItunesConnect::Commands::Report,
         
     | 
| 
      
 11 
     | 
    
         
            +
                                                    ItunesConnect::Commands::Help
         
     | 
| 
      
 12 
     | 
    
         
            +
                                                   ]
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              describe 'for_name' do
         
     | 
| 
      
 17 
     | 
    
         
            +
                before(:each) do
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @clip = mock(:null_object => true)
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                it 'should return Download for download' do
         
     | 
| 
      
 22 
     | 
    
         
            +
                  ItunesConnect::Commands.for_name('download', @clip).
         
     | 
| 
      
 23 
     | 
    
         
            +
                    should be_kind_of(ItunesConnect::Commands::Download)
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                it 'should return Import for import' do
         
     | 
| 
      
 27 
     | 
    
         
            +
                  ItunesConnect::Commands.for_name('import', @clip).
         
     | 
| 
      
 28 
     | 
    
         
            +
                    should be_kind_of(ItunesConnect::Commands::Import)
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                it 'should return Report for report' do
         
     | 
| 
      
 32 
     | 
    
         
            +
                  ItunesConnect::Commands.for_name('report', @clip).
         
     | 
| 
      
 33 
     | 
    
         
            +
                    should be_kind_of(ItunesConnect::Commands::Report)
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                it 'should return Help for help' do
         
     | 
| 
      
 37 
     | 
    
         
            +
                  ItunesConnect::Commands.for_name('help', @clip).
         
     | 
| 
      
 38 
     | 
    
         
            +
                    should be_kind_of(ItunesConnect::Commands::Help)
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                it 'should return nil for other names' do
         
     | 
| 
      
 43 
     | 
    
         
            +
                  ItunesConnect::Commands.for_name('foobar', @clip).should be_nil
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
            end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
         @@ -0,0 +1,26 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "fakeweb"
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            describe ItunesConnect::Connection do
         
     | 
| 
      
 5 
     | 
    
         
            +
              before(:each) do
         
     | 
| 
      
 6 
     | 
    
         
            +
                @itc = ItunesConnect::Connection.new("foo", "bar")
         
     | 
| 
      
 7 
     | 
    
         
            +
                FakeWeb.allow_net_connect = false
         
     | 
| 
      
 8 
     | 
    
         
            +
              end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              it 'should reject invalid periods' do
         
     | 
| 
      
 11 
     | 
    
         
            +
                lambda {
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @itc.get_report(Date.today - 1, $stdout, "Invalid")
         
     | 
| 
      
 13 
     | 
    
         
            +
                }.should raise_error(ArgumentError)
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              it 'should reject dates newer than yesterday' do
         
     | 
| 
      
 17 
     | 
    
         
            +
                lambda {
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @itc.get_report(Date.today, $stdout)
         
     | 
| 
      
 19 
     | 
    
         
            +
                }.should raise_error(ArgumentError)
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                lambda {
         
     | 
| 
      
 22 
     | 
    
         
            +
                  @itc.get_report(Date.today + 1, $stdout)
         
     | 
| 
      
 23 
     | 
    
         
            +
                }.should raise_error(ArgumentError)
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,365 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            HTTP/1.1 200 Apple
         
     | 
| 
      
 2 
     | 
    
         
            +
            Date: Tue, 25 Aug 2009 18:19:18 GMT
         
     | 
| 
      
 3 
     | 
    
         
            +
            Server: Apache/1.3.33 (Darwin) mod_ssl/2.8.24 OpenSSL/0.9.7l
         
     | 
| 
      
 4 
     | 
    
         
            +
            Cache-Control: max-age=60
         
     | 
| 
      
 5 
     | 
    
         
            +
            Expires: Tue, 25 Aug 2009 18:20:18 GMT
         
     | 
| 
      
 6 
     | 
    
         
            +
            cache-control: private
         
     | 
| 
      
 7 
     | 
    
         
            +
            cache-control: no-cache
         
     | 
| 
      
 8 
     | 
    
         
            +
            cache-control: no-store
         
     | 
| 
      
 9 
     | 
    
         
            +
            cache-control: must-revalidate
         
     | 
| 
      
 10 
     | 
    
         
            +
            cache-control: max-age=0
         
     | 
| 
      
 11 
     | 
    
         
            +
            expires: Tue, 25-Aug-2009 16:36:29 GMT
         
     | 
| 
      
 12 
     | 
    
         
            +
            pragma: no-cache
         
     | 
| 
      
 13 
     | 
    
         
            +
            content-length: 11640
         
     | 
| 
      
 14 
     | 
    
         
            +
            Keep-Alive: timeout=15, max=100
         
     | 
| 
      
 15 
     | 
    
         
            +
            Connection: Keep-Alive
         
     | 
| 
      
 16 
     | 
    
         
            +
            Content-Type: text/html
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            <html>
         
     | 
| 
      
 19 
     | 
    
         
            +
                 <head>
         
     | 
| 
      
 20 
     | 
    
         
            +
            		<title>Piano-Sign In</title>
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            			<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
         
     | 
| 
      
 23 
     | 
    
         
            +
            			<meta name="Author" content="Apple Computer, Inc.">
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            				<link rel="home" href="http://www.apple.com/">
         
     | 
| 
      
 26 
     | 
    
         
            +
            				<link rel="index" href="http://www.apple.com/find/sitemap.html">
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            	<script language="JavaScript">
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            	function browserAlert() 
         
     | 
| 
      
 33 
     | 
    
         
            +
            	{	
         
     | 
| 
      
 34 
     | 
    
         
            +
            		//alert(navigator.userAgent);
         
     | 
| 
      
 35 
     | 
    
         
            +
            		//alert(document.getElementById("checkAlrt").value);
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            		var alertMessage ="The browser you are using is not supported by this application. The application may not work as expected. Supported browsers are:- Safari 2 and above in Mac & IE 6.0 and above in Windows & Firefox 2 and above in both Mac and Windows";
         
     | 
| 
      
 38 
     | 
    
         
            +
            		if(document.getElementById("checkAlrt").value!="Message Displayed")
         
     | 
| 
      
 39 
     | 
    
         
            +
            		{
         
     | 
| 
      
 40 
     | 
    
         
            +
            			
         
     | 
| 
      
 41 
     | 
    
         
            +
            			var browserType = navigator.userAgent;
         
     | 
| 
      
 42 
     | 
    
         
            +
            			var s = browserType.length;
         
     | 
| 
      
 43 
     | 
    
         
            +
            			var i = browserType.lastIndexOf("/")+1;
         
     | 
| 
      
 44 
     | 
    
         
            +
            			//alert("Split :::::" + navigator.userAgent.split("/"));
         
     | 
| 
      
 45 
     | 
    
         
            +
            			tempVersion = navigator.userAgent.split("/");
         
     | 
| 
      
 46 
     | 
    
         
            +
            			//alert(tempVersion[3]); 
         
     | 
| 
      
 47 
     | 
    
         
            +
            			var iSafari = browserType.indexOf("Safari");
         
     | 
| 
      
 48 
     | 
    
         
            +
            			var iNetscape = browserType.indexOf("Netscape");
         
     | 
| 
      
 49 
     | 
    
         
            +
            			var iFirefox = browserType.indexOf("Firefox");
         
     | 
| 
      
 50 
     | 
    
         
            +
            			var iIE = browserType.indexOf("IE");
         
     | 
| 
      
 51 
     | 
    
         
            +
            			var iMac = browserType.indexOf("Mac");
         
     | 
| 
      
 52 
     | 
    
         
            +
            			var iOpera = browserType.indexOf("Opera");
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            			
         
     | 
| 
      
 55 
     | 
    
         
            +
            			if(iSafari < 0 && iFirefox < 0 && iIE < 0 )
         
     | 
| 
      
 56 
     | 
    
         
            +
            			{
         
     | 
| 
      
 57 
     | 
    
         
            +
            				alert(alertMessage);
         
     | 
| 
      
 58 
     | 
    
         
            +
            			}
         
     | 
| 
      
 59 
     | 
    
         
            +
            			
         
     | 
| 
      
 60 
     | 
    
         
            +
            			else 
         
     | 
| 
      
 61 
     | 
    
         
            +
            			{
         
     | 
| 
      
 62 
     | 
    
         
            +
            				  
         
     | 
| 
      
 63 
     | 
    
         
            +
            				if(iSafari > -1)
         
     | 
| 
      
 64 
     | 
    
         
            +
            				{
         
     | 
| 
      
 65 
     | 
    
         
            +
            					if(browserType.substring(s,i) < 412)
         
     | 
| 
      
 66 
     | 
    
         
            +
            					{
         
     | 
| 
      
 67 
     | 
    
         
            +
            						alert(alertMessage);
         
     | 
| 
      
 68 
     | 
    
         
            +
            					}
         
     | 
| 
      
 69 
     | 
    
         
            +
            				}
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            				if(iFirefox > -1)
         
     | 
| 
      
 73 
     | 
    
         
            +
            				{
         
     | 
| 
      
 74 
     | 
    
         
            +
            					if(browserType.substring(i,s) < 2.0)
         
     | 
| 
      
 75 
     | 
    
         
            +
            					{
         
     | 
| 
      
 76 
     | 
    
         
            +
            						alert(alertMessage);
         
     | 
| 
      
 77 
     | 
    
         
            +
            					}
         
     | 
| 
      
 78 
     | 
    
         
            +
            				}
         
     | 
| 
      
 79 
     | 
    
         
            +
            				
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
            				if(iIE > -1)
         
     | 
| 
      
 82 
     | 
    
         
            +
            				{
         
     | 
| 
      
 83 
     | 
    
         
            +
            					temp=navigator.userAgent.split("MSIE")
         
     | 
| 
      
 84 
     | 
    
         
            +
            					version=parseFloat(temp[1])
         
     | 
| 
      
 85 
     | 
    
         
            +
            					//alert(version);
         
     | 
| 
      
 86 
     | 
    
         
            +
            					if(version < 6.0 || iMac > 1)
         
     | 
| 
      
 87 
     | 
    
         
            +
            					{
         
     | 
| 
      
 88 
     | 
    
         
            +
            						alert(alertMessage);
         
     | 
| 
      
 89 
     | 
    
         
            +
            					}
         
     | 
| 
      
 90 
     | 
    
         
            +
            				}
         
     | 
| 
      
 91 
     | 
    
         
            +
            			
         
     | 
| 
      
 92 
     | 
    
         
            +
            			}
         
     | 
| 
      
 93 
     | 
    
         
            +
            		}
         
     | 
| 
      
 94 
     | 
    
         
            +
            	}
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
            </script>
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
            </head>
         
     | 
| 
      
 102 
     | 
    
         
            +
            <body onLoad="browserAlert()">
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
            			<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
         
     | 
| 
      
 105 
     | 
    
         
            +
            "http://www.w3.org/TR/html4/loose.dtd">
         
     | 
| 
      
 106 
     | 
    
         
            +
            <html>
         
     | 
| 
      
 107 
     | 
    
         
            +
                 <head>
         
     | 
| 
      
 108 
     | 
    
         
            +
            		<title>Piano-Sign In</title>
         
     | 
| 
      
 109 
     | 
    
         
            +
            		<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
         
     | 
| 
      
 110 
     | 
    
         
            +
            		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
         
     | 
| 
      
 111 
     | 
    
         
            +
            		<meta http-equiv="pics-label" content='(pics-1.1 "http://www.icra.org/ratingsv02.html" l gen true for "http://www.apple.com" r (cz 1 lz 1 nz 1 oz 1 vz 1) "http://www.rsac.org/ratingsv01.html" l gen true for "http://www.apple.com" r (n 0 s 0 v 0 l 0))'>
         
     | 
| 
      
 112 
     | 
    
         
            +
            		<meta http-equiv="Expires" content="Fri, 26 Mar 1999 23:59:59 GMT">
         
     | 
| 
      
 113 
     | 
    
         
            +
            		<meta name="Author" content="Apple Computer, Inc.">
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
            		<link rel="home" href="http://www.apple.com/">
         
     | 
| 
      
 116 
     | 
    
         
            +
            		<link rel="index" href="http://www.apple.com/find/sitemap.html">
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
            	
         
     | 
| 
      
 119 
     | 
    
         
            +
            			<link rel="stylesheet" type="text/css" href="/WebObjects/piano.woa/Contents/WebServerResources/index.css" media="screen">
         
     | 
| 
      
 120 
     | 
    
         
            +
            			<link rel="stylesheet" type="text/css" href="/WebObjects/piano.woa/Contents/WebServerResources/global.css" media="screen">
         
     | 
| 
      
 121 
     | 
    
         
            +
            			<link rel="stylesheet" type="text/css" href="/WebObjects/piano.woa/Contents/WebServerResources/fonts.css" media="screen">
         
     | 
| 
      
 122 
     | 
    
         
            +
            			<link rel="stylesheet" type="text/css" href="/WebObjects/piano.woa/Contents/WebServerResources/Pianonav.css" media="screen">
         
     | 
| 
      
 123 
     | 
    
         
            +
            			<link rel="stylesheet" type="text/css" href="/WebObjects/piano.woa/Contents/WebServerResources/job.css" media="screen">
         
     | 
| 
      
 124 
     | 
    
         
            +
            			<link rel="stylesheet" type="text/css" href="/WebObjects/piano.woa/Contents/WebServerResources/build.css" media="print">
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
            <SCRIPT LANGUAGE="javascript">
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
            appleOver = new Image()
         
     | 
| 
      
 129 
     | 
    
         
            +
            appleOver.src = "/WebObjects/piano.woa/Contents/WebServerResources/Images_Header/AppleOr.png"
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
            storeOver = new Image()
         
     | 
| 
      
 132 
     | 
    
         
            +
            storeOver.src = "/WebObjects/piano.woa/Contents/WebServerResources/Images_Header/StoreOr.png"
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
            macOver = new Image()
         
     | 
| 
      
 135 
     | 
    
         
            +
            macOver.src = "/WebObjects/piano.woa/Contents/WebServerResources/Images_Header/MacOr.png" 
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
            tunesOver = new Image()
         
     | 
| 
      
 138 
     | 
    
         
            +
            tunesOver.src = "/WebObjects/piano.woa/Contents/WebServerResources/Images_Header/TunesOr.png"
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
            phoneOver = new Image()
         
     | 
| 
      
 141 
     | 
    
         
            +
            phoneOver.src = "/WebObjects/piano.woa/Contents/WebServerResources/Images_Header/PhoneOr.png"
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
            downloadOver = new Image()
         
     | 
| 
      
 144 
     | 
    
         
            +
            downloadOver.src = "/WebObjects/piano.woa/Contents/WebServerResources/Images_Header/DownloadOr.png" 
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
            supportOver = new Image()
         
     | 
| 
      
 147 
     | 
    
         
            +
            supportOver.src = "/WebObjects/piano.woa/Contents/WebServerResources/Images_Header/SupportOr.png" 
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
            originalOver = new Image()
         
     | 
| 
      
 150 
     | 
    
         
            +
            originalOver.src = "/WebObjects/piano.woa/Contents/WebServerResources/Images_Header/TunesOr.png" 
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
            function original() {
         
     | 
| 
      
 156 
     | 
    
         
            +
            document.emp.src = originalOver.src; return true;
         
     | 
| 
      
 157 
     | 
    
         
            +
            }
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
            function apple() {
         
     | 
| 
      
 161 
     | 
    
         
            +
            document.emp.src = appleOver.src; return true;
         
     | 
| 
      
 162 
     | 
    
         
            +
            }
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
            function store() {
         
     | 
| 
      
 165 
     | 
    
         
            +
            document.emp.src = storeOver.src; return true;
         
     | 
| 
      
 166 
     | 
    
         
            +
            }
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
      
 168 
     | 
    
         
            +
            function mac() {
         
     | 
| 
      
 169 
     | 
    
         
            +
            document.emp.src = macOver.src; return true; 
         
     | 
| 
      
 170 
     | 
    
         
            +
            }
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
            function tunes() {
         
     | 
| 
      
 173 
     | 
    
         
            +
            document.emp.src = tunesOver.src; return true;
         
     | 
| 
      
 174 
     | 
    
         
            +
            }
         
     | 
| 
      
 175 
     | 
    
         
            +
             
     | 
| 
      
 176 
     | 
    
         
            +
            function phone() {
         
     | 
| 
      
 177 
     | 
    
         
            +
            document.emp.src = phoneOver.src; return true; 
         
     | 
| 
      
 178 
     | 
    
         
            +
            }
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
            function download() {
         
     | 
| 
      
 181 
     | 
    
         
            +
            document.emp.src = downloadOver.src; return true; 
         
     | 
| 
      
 182 
     | 
    
         
            +
            }
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
      
 184 
     | 
    
         
            +
            function support() {
         
     | 
| 
      
 185 
     | 
    
         
            +
            document.emp.src = supportOver.src; return true; 
         
     | 
| 
      
 186 
     | 
    
         
            +
            }
         
     | 
| 
      
 187 
     | 
    
         
            +
             
     | 
| 
      
 188 
     | 
    
         
            +
             
     | 
| 
      
 189 
     | 
    
         
            +
            </SCRIPT>
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
            </head>
         
     | 
| 
      
 193 
     | 
    
         
            +
                <body marginwidth=0 marginheight=0 topmargin=0 leftmargin=0 bgcolor="#FFFFFF" background="">
         
     | 
| 
      
 194 
     | 
    
         
            +
             
     | 
| 
      
 195 
     | 
    
         
            +
            <br>
         
     | 
| 
      
 196 
     | 
    
         
            +
            <IMG NAME="emp" SRC="/WebObjects/piano.woa/Contents/WebServerResources/Images_Header/TunesOr.png" USEMAP="#map1" border = 0>
         
     | 
| 
      
 197 
     | 
    
         
            +
             
     | 
| 
      
 198 
     | 
    
         
            +
             
     | 
| 
      
 199 
     | 
    
         
            +
             
     | 
| 
      
 200 
     | 
    
         
            +
            <MAP NAME="map1">
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
      
 202 
     | 
    
         
            +
            <AREA
         
     | 
| 
      
 203 
     | 
    
         
            +
               HREF="http://www.apple.com/" ALT="Apple" TITLE="Apple"
         
     | 
| 
      
 204 
     | 
    
         
            +
               SHAPE=RECT COORDS="0,0,116,190" onMouseOver="apple()" onMouseOut="original()" onClick= "appleMouseClick()">
         
     | 
| 
      
 205 
     | 
    
         
            +
            <AREA
         
     | 
| 
      
 206 
     | 
    
         
            +
               HREF="http://store.apple.com/" ALT="Store" TITLE="Store"
         
     | 
| 
      
 207 
     | 
    
         
            +
               SHAPE=RECT COORDS="0,0,233,190" onMouseOver="store()" onMouseOut="original()" onClick= "zoomout1()">
         
     | 
| 
      
 208 
     | 
    
         
            +
            <AREA
         
     | 
| 
      
 209 
     | 
    
         
            +
               HREF="http://www.apple.com/mac/" ALT="Mac" TITLE="Mac"
         
     | 
| 
      
 210 
     | 
    
         
            +
               SHAPE=RECT COORDS="0,0,348,190" onMouseOver="mac()" onMouseOut="original()" onClick= "zoomout()">
         
     | 
| 
      
 211 
     | 
    
         
            +
            <AREA
         
     | 
| 
      
 212 
     | 
    
         
            +
               HREF="http://www.apple.com/itunes/" ALT="iTunes" TITLE="iTunes"
         
     | 
| 
      
 213 
     | 
    
         
            +
               SHAPE=RECT COORDS="0,0,465,190" onMouseOver="tunes()" onMouseOut="original()" onClick= "zoomout()">
         
     | 
| 
      
 214 
     | 
    
         
            +
             
     | 
| 
      
 215 
     | 
    
         
            +
            <AREA
         
     | 
| 
      
 216 
     | 
    
         
            +
               HREF="http://www.apple.com/iphone/" ALT="iPhone" TITLE="iPhone"
         
     | 
| 
      
 217 
     | 
    
         
            +
               SHAPE=RECT COORDS="0,0,583,190" onMouseOver="phone()" onMouseOut="original()" onClick= "zoomout()">
         
     | 
| 
      
 218 
     | 
    
         
            +
             
     | 
| 
      
 219 
     | 
    
         
            +
            <AREA
         
     | 
| 
      
 220 
     | 
    
         
            +
               HREF="http://www.apple.com/downloads/" ALT="Downloads" TITLE="Downloads"
         
     | 
| 
      
 221 
     | 
    
         
            +
               SHAPE=RECT COORDS="0,0,699,190" onMouseOver="download()" onMouseOut="original()" onClick= "zoomout()">
         
     | 
| 
      
 222 
     | 
    
         
            +
             
     | 
| 
      
 223 
     | 
    
         
            +
            <AREA
         
     | 
| 
      
 224 
     | 
    
         
            +
               HREF="http://www.apple.com/support/" ALT="Support" TITLE="Support"
         
     | 
| 
      
 225 
     | 
    
         
            +
               SHAPE=RECT COORDS="0,0,817,190" onMouseOver="support()" onMouseOut="original()" onClick= "zoomout()"></MAP>
         
     | 
| 
      
 226 
     | 
    
         
            +
            </body>
         
     | 
| 
      
 227 
     | 
    
         
            +
            </html>
         
     | 
| 
      
 228 
     | 
    
         
            +
             
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
             
     | 
| 
      
 231 
     | 
    
         
            +
             
     | 
| 
      
 232 
     | 
    
         
            +
            <input Id="checkAlrt" type="hidden" name="2" />
         
     | 
| 
      
 233 
     | 
    
         
            +
            			<form method="post" action="/cgi-bin/WebObjects/Piano.woa/2/wo/9tkH3ucxG921Y1uBDoPAIM/0.4">
         
     | 
| 
      
 234 
     | 
    
         
            +
            			<br>
         
     | 
| 
      
 235 
     | 
    
         
            +
            			<table>
         
     | 
| 
      
 236 
     | 
    
         
            +
            			<tr>
         
     | 
| 
      
 237 
     | 
    
         
            +
            				<td class="cellLeft">
         
     | 
| 
      
 238 
     | 
    
         
            +
            				<h2><p align="left">       <img src="https://phobos.apple.com/images/labelconnect/txt_title_itunesvips.gif" alt="iTunes VIPs" border="0"></p></h2>
         
     | 
| 
      
 239 
     | 
    
         
            +
            				<font size = 2 color = "red"><p align = "center"> </p></font><br>
         
     | 
| 
      
 240 
     | 
    
         
            +
            				<div id="main"><table cellspacing="0" cellpadding="1" width="100%" border="0">
         
     | 
| 
      
 241 
     | 
    
         
            +
            				<tr>
         
     | 
| 
      
 242 
     | 
    
         
            +
            					<td></td>
         
     | 
| 
      
 243 
     | 
    
         
            +
            					<td align="rignt">
         
     | 
| 
      
 244 
     | 
    
         
            +
            						<div id="jobHeader">Sign In</div></td></tr><tr><td valign="top" width="50%"><hr><br><font size=2.5><b>Welcome!</b></font><font size=2>This site will allow you to view and/or download daily and weekly iTunes sales data. <br><br>If you have any issues, please contact us by email at  </font><font size=2.5><b><a href= mailto:itunesondemand@apple.com>itunesondemand@apple.com<br><br></a></b><p>Please note:    The information you are accessing on this site is market trend reports, and should not be considered to be your monthly royalty reports.<br></p><font><p></p><hr></td><td valign="top">
         
     | 
| 
      
 245 
     | 
    
         
            +
            						<div id="DSSecurityList">
         
     | 
| 
      
 246 
     | 
    
         
            +
            				<table>
         
     | 
| 
      
 247 
     | 
    
         
            +
            					<tr>
         
     | 
| 
      
 248 
     | 
    
         
            +
            						<td colspan="3">
         
     | 
| 
      
 249 
     | 
    
         
            +
            							<font size="1" color=red><a href="/cgi-bin/WebObjects/Piano.woa/2/wo/9tkH3ucxG921Y1uBDoPAIM/0.4.18"></a></font>
         
     | 
| 
      
 250 
     | 
    
         
            +
            						</td>
         
     | 
| 
      
 251 
     | 
    
         
            +
            					</tr>
         
     | 
| 
      
 252 
     | 
    
         
            +
            					<tr>
         
     | 
| 
      
 253 
     | 
    
         
            +
            						<td colspan="3">
         
     | 
| 
      
 254 
     | 
    
         
            +
            							
         
     | 
| 
      
 255 
     | 
    
         
            +
            						<script>
         
     | 
| 
      
 256 
     | 
    
         
            +
            	function dsfocus(){ document.appleConnectForm.theAccountName.focus(); }
         
     | 
| 
      
 257 
     | 
    
         
            +
            </script>
         
     | 
| 
      
 258 
     | 
    
         
            +
             
     | 
| 
      
 259 
     | 
    
         
            +
             
     | 
| 
      
 260 
     | 
    
         
            +
            	
         
     | 
| 
      
 261 
     | 
    
         
            +
            		
         
     | 
| 
      
 262 
     | 
    
         
            +
            <!-- This FORM is embedded inside another FORM. Omitting Open Tag -->
         
     | 
| 
      
 263 
     | 
    
         
            +
             
     | 
| 
      
 264 
     | 
    
         
            +
            	<div id="ds_container">
         
     | 
| 
      
 265 
     | 
    
         
            +
            		
         
     | 
| 
      
 266 
     | 
    
         
            +
            		
         
     | 
| 
      
 267 
     | 
    
         
            +
             
     | 
| 
      
 268 
     | 
    
         
            +
            		
         
     | 
| 
      
 269 
     | 
    
         
            +
            			
         
     | 
| 
      
 270 
     | 
    
         
            +
            			
         
     | 
| 
      
 271 
     | 
    
         
            +
            			
         
     | 
| 
      
 272 
     | 
    
         
            +
            			
         
     | 
| 
      
 273 
     | 
    
         
            +
            			
         
     | 
| 
      
 274 
     | 
    
         
            +
            				<font face="Lucida Grande, Geneva, Verdana, Arial, Helvetica, sans-serif" CLASS="L12" />
         
     | 
| 
      
 275 
     | 
    
         
            +
            				<font size=2>
         
     | 
| 
      
 276 
     | 
    
         
            +
            					<span class="dstext">Please enter your Apple ID and password.</span>
         
     | 
| 
      
 277 
     | 
    
         
            +
            				</font>
         
     | 
| 
      
 278 
     | 
    
         
            +
            				</font /><br><br>
         
     | 
| 
      
 279 
     | 
    
         
            +
            			
         
     | 
| 
      
 280 
     | 
    
         
            +
            			
         
     | 
| 
      
 281 
     | 
    
         
            +
            			
         
     | 
| 
      
 282 
     | 
    
         
            +
            			
         
     | 
| 
      
 283 
     | 
    
         
            +
            			
         
     | 
| 
      
 284 
     | 
    
         
            +
            			
         
     | 
| 
      
 285 
     | 
    
         
            +
            			
         
     | 
| 
      
 286 
     | 
    
         
            +
            				
         
     | 
| 
      
 287 
     | 
    
         
            +
            				
         
     | 
| 
      
 288 
     | 
    
         
            +
            				
         
     | 
| 
      
 289 
     | 
    
         
            +
            				<table cellpadding=0 cellspacing=0 border=0 width=273>
         
     | 
| 
      
 290 
     | 
    
         
            +
            					<tr valign=top>
         
     | 
| 
      
 291 
     | 
    
         
            +
            						<td align=left><font size=2><font face="Geneva, Verdana, Arial, Helvetica, sans-serif" SIZE=1 CLASS="G10" />
         
     | 
| 
      
 292 
     | 
    
         
            +
            							<label for="accountname"><span class="dslabel">Apple ID</span></label>
         
     | 
| 
      
 293 
     | 
    
         
            +
            							<font color="#ff1102"></font></font /><br>
         
     | 
| 
      
 294 
     | 
    
         
            +
            							<font size='2'><input size="30" maxlength="128" id="accountname" type="text" name="theAccountName" /></font></font>
         
     | 
| 
      
 295 
     | 
    
         
            +
            							
         
     | 
| 
      
 296 
     | 
    
         
            +
            						</td>
         
     | 
| 
      
 297 
     | 
    
         
            +
            					</tr>
         
     | 
| 
      
 298 
     | 
    
         
            +
            					<tr><td><img alt="" width="273" height="5" src="/AppleConnect/US-EN/spacer.gif" /></td></tr>
         
     | 
| 
      
 299 
     | 
    
         
            +
            					<tr><td><img alt="" width="273" height="5" src="/AppleConnect/US-EN/spacer.gif" /></td></tr>
         
     | 
| 
      
 300 
     | 
    
         
            +
            					<tr>
         
     | 
| 
      
 301 
     | 
    
         
            +
            						<td align='left'>
         
     | 
| 
      
 302 
     | 
    
         
            +
            							<font face="Geneva, Verdana, Arial, Helvetica, sans-serif" SIZE=1 CLASS="G10" />
         
     | 
| 
      
 303 
     | 
    
         
            +
            								<label for="accountpassword"><span class="dslabel">Password</span></label>
         
     | 
| 
      
 304 
     | 
    
         
            +
            							</font />
         
     | 
| 
      
 305 
     | 
    
         
            +
            							<br>
         
     | 
| 
      
 306 
     | 
    
         
            +
            							<input size="30" maxlength="32" id="accountpassword" type="password" name="theAccountPW" /><input border="0" width="0" height="0" type="image" name="1.Continue" src="/AppleConnect/US-EN/spacer.gif" />
         
     | 
| 
      
 307 
     | 
    
         
            +
            						</td>
         
     | 
| 
      
 308 
     | 
    
         
            +
            					</tr>
         
     | 
| 
      
 309 
     | 
    
         
            +
            					<tr><td><img alt="" width="273" height="5" src="/AppleConnect/US-EN/spacer.gif" /></td></tr>
         
     | 
| 
      
 310 
     | 
    
         
            +
            					<tr><td><img alt="" width="273" height="5" src="/AppleConnect/US-EN/spacer.gif" /></td></tr>
         
     | 
| 
      
 311 
     | 
    
         
            +
            					<tr>
         
     | 
| 
      
 312 
     | 
    
         
            +
            						<td>
         
     | 
| 
      
 313 
     | 
    
         
            +
            							<table cellspacing='0' border='0' width='273' cellpadding='0'>
         
     | 
| 
      
 314 
     | 
    
         
            +
            								<tr align='left'>
         
     | 
| 
      
 315 
     | 
    
         
            +
            									<td align='left' width='170'>
         
     | 
| 
      
 316 
     | 
    
         
            +
            										
         
     | 
| 
      
 317 
     | 
    
         
            +
             
     | 
| 
      
 318 
     | 
    
         
            +
            										
         
     | 
| 
      
 319 
     | 
    
         
            +
            											<font size='1'>
         
     | 
| 
      
 320 
     | 
    
         
            +
            												<span class="dstext">
         
     | 
| 
      
 321 
     | 
    
         
            +
            													
         
     | 
| 
      
 322 
     | 
    
         
            +
             
     | 
| 
      
 323 
     | 
    
         
            +
            													
         
     | 
| 
      
 324 
     | 
    
         
            +
            														
         
     | 
| 
      
 325 
     | 
    
         
            +
            														
         
     | 
| 
      
 326 
     | 
    
         
            +
            															
         
     | 
| 
      
 327 
     | 
    
         
            +
            															<input border="0" alt="Did you forget your password?" type="image" name="1.Forgot" src="/AppleConnect/US-EN/forgotpasswdlink.gif" />
         
     | 
| 
      
 328 
     | 
    
         
            +
            														
         
     | 
| 
      
 329 
     | 
    
         
            +
            													
         
     | 
| 
      
 330 
     | 
    
         
            +
            												</span>
         
     | 
| 
      
 331 
     | 
    
         
            +
            											</font>
         
     | 
| 
      
 332 
     | 
    
         
            +
            										
         
     | 
| 
      
 333 
     | 
    
         
            +
            									</td>
         
     | 
| 
      
 334 
     | 
    
         
            +
            									<td width='15'><img alt="" width="15" height="5" src="/AppleConnect/US-EN/spacer.gif" /></td>
         
     | 
| 
      
 335 
     | 
    
         
            +
            									<td align='left' width='88'><input border="0" alt="Sign In" type="image" name="1.Continue" src="/AppleConnect/US-EN/buttonloginlime.gif" /></td>
         
     | 
| 
      
 336 
     | 
    
         
            +
            								</tr>
         
     | 
| 
      
 337 
     | 
    
         
            +
            							</table>
         
     | 
| 
      
 338 
     | 
    
         
            +
            						</td>
         
     | 
| 
      
 339 
     | 
    
         
            +
            					</tr>
         
     | 
| 
      
 340 
     | 
    
         
            +
            				</table>
         
     | 
| 
      
 341 
     | 
    
         
            +
            			
         
     | 
| 
      
 342 
     | 
    
         
            +
            			
         
     | 
| 
      
 343 
     | 
    
         
            +
            			
         
     | 
| 
      
 344 
     | 
    
         
            +
            		
         
     | 
| 
      
 345 
     | 
    
         
            +
            			
         
     | 
| 
      
 346 
     | 
    
         
            +
            		<input type="hidden" name="theAuxValue" />
         
     | 
| 
      
 347 
     | 
    
         
            +
            	</div>
         
     | 
| 
      
 348 
     | 
    
         
            +
            <input type="hidden" name="wosid" value="9tkH3ucxG921Y1uBDoPAIM" />
         
     | 
| 
      
 349 
     | 
    
         
            +
            <!-- This FORM is embedded inside another FORM. Omitting Close Tag -->
         
     | 
| 
      
 350 
     | 
    
         
            +
             
     | 
| 
      
 351 
     | 
    
         
            +
            	
         
     | 
| 
      
 352 
     | 
    
         
            +
            	
         
     | 
| 
      
 353 
     | 
    
         
            +
            	
         
     | 
| 
      
 354 
     | 
    
         
            +
            	
         
     | 
| 
      
 355 
     | 
    
         
            +
            	
         
     | 
| 
      
 356 
     | 
    
         
            +
             
     | 
| 
      
 357 
     | 
    
         
            +
             
     | 
| 
      
 358 
     | 
    
         
            +
             
     | 
| 
      
 359 
     | 
    
         
            +
            <p></p><br><br></td>
         
     | 
| 
      
 360 
     | 
    
         
            +
            					</tr>
         
     | 
| 
      
 361 
     | 
    
         
            +
            				</table>
         
     | 
| 
      
 362 
     | 
    
         
            +
            </td></tr></table></div><div class="sidebar"></div><div class="clear"></div><input type="hidden" name="wosid" value="9tkH3ucxG921Y1uBDoPAIM" /></form><br> <div class="footerLinks" align="center"><a href="/cgi-bin/WebObjects/Piano.woa/2/wo/9tkH3ucxG921Y1uBDoPAIM/0.6.1">Home</a> <!--| <a href="/cgi-bin/WebObjects/Piano.woa/2/wo/9tkH3ucxG921Y1uBDoPAIM/0.6.3">FAQs</a> -->| <a href="/cgi-bin/WebObjects/Piano.woa/2/wo/9tkH3ucxG921Y1uBDoPAIM/0.6.5">Sign Out</a></div>
         
     | 
| 
      
 363 
     | 
    
         
            +
             <div class="footerCopyright" align="center">Copyright © 2008 Apple Inc. All rights reserved. </div><br/>
         
     | 
| 
      
 364 
     | 
    
         
            +
               </body>
         
     | 
| 
      
 365 
     | 
    
         
            +
            </html>
         
     |