Skip to content

Instantly share code, notes, and snippets.

@alexeckermann
Created September 12, 2016 11:07
Show Gist options
  • Save alexeckermann/18bc93b6c3f78df83c7fa32abbe221d4 to your computer and use it in GitHub Desktop.
Save alexeckermann/18bc93b6c3f78df83c7fa32abbe221d4 to your computer and use it in GitHub Desktop.

Revisions

  1. alexeckermann created this gist Sep 12, 2016.
    115 changes: 115 additions & 0 deletions iphone7.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,115 @@
    # iPhone 6 Reservation Availability in Australia
    # !! Please use responsibly. Personal use only !!
    # `ruby iphone6.rb` - list all available models in all stores
    # `ruby iphone6.rb R405` - list available models for a specific store, Rundle Place in this example.

    require 'open-uri'
    require 'json'
    MODEL_NAMES = {
    "MN8X2X/A" => "7 32 Black",
    "MN8Y2X/A" => "7 32 Silver",
    "MN902X/A" => "7 32 Gold",
    "MN912X/A" => "7 32 Rose",
    "MN922X/A" => "7 128 Black",
    "MN932X/A" => "7 128 Silver",
    "MN942X/A" => "7 128 Gold",
    "MN952X/A" => "7 128 Rose",
    "MN962X/A" => "7 128 Jet",
    "MN972X/A" => "7 256 Black",
    "MN982X/A" => "7 256 Silver",
    "MN992X/A" => "7 256 Gold",
    "MN9A2X/A" => "7 256 Rose",
    "MN9C2X/A" => "7 256 Jet",
    "MN4M2X/A" => "7+ 128 Black",
    "MN4P2X/A" => "7+ 128 Silver",
    "MN4Q2X/A" => "7+ 128 Gold",
    "MN4U2X/A" => "7+ 128 Rose",
    "MN4V2X/A" => "7+ 128 Jet",
    "MN4W2X/A" => "7+ 256 Black",
    "MN4X2X/A" => "7+ 256 Silver",
    "MN4Y2X/A" => "7+ 256 Gold",
    "MN502X/A" => "7+ 256 Rose",
    "MN512X/A" => "7+ 256 Jet",
    "MNQM2X/A" => "7+ 32 Black",
    "MNQN2X/A" => "7+ 32 Silver",
    "MNQP2X/A" => "7+ 32 Gold",
    "MNQQ2X/A" => "7+ 32 Rose"
    }

    MODEL_ORDER = ["MN8X2X/A","MN8Y2X/A","MN902X/A","MN912X/A","MN922X/A","MN932X/A","MN942X/A","MN952X/A","MN962X/A","MN972X/A","MN982X/A","MN992X/A","MN9A2X/A","MN9C2X/A","MN4M2X/A","MN4P2X/A","MN4Q2X/A","MN4U2X/A","MN4V2X/A","MN4W2X/A","MN4X2X/A","MN4Y2X/A","MN502X/A","MN512X/A","MNQM2X/A","MNQN2X/A","MNQP2X/A","MNQQ2X/A"]

    MODEL_REGEX = /^M[A-Z0-9]{5}\/A$/

    module Utils

    def self.get_json(url)
    JSON.parse(open(url, "User-Agent" => "Ruby/2.1.0; personal-use-only ([email protected]);", "Referer" => "http://alexeckermann.com").read) rescue nil
    end

    def self.model_name(model_no)
    MODEL_NAMES.key?(model_no) ? MODEL_NAMES[model_no] : model_no.to_s
    end

    end

    module Commands

    def self.list_all(stores, availability)

    availability.each do |store_identifier, model_availability|
    next unless model_availability.is_a?(Hash)
    available_models = []
    model_availability.each { |model_no, available| available_models.push(model_no) if model_no =~ MODEL_REGEX && available != 'NONE' }
    store_description = stores['stores'].detect { |s| s['storeNumber'] == store_identifier }
    next if store_description.nil?
    if available_models.length > 0
    puts "\033[1;39;49m#{store_description['storeName']}\033[0m (#{store_identifier})"
    puts available_models.select { |model_no| model_no =~ MODEL_REGEX }.map { |model_no| "\033[0;32;49m#{Utils::model_name(model_no)}\033[0m" }.join(', ')
    end
    end

    end

    def self.list_store(store, availability)
    MODEL_ORDER.each do |model_no|
    available = availability[model_no]
    next unless available
    if available == 'NONE'
    available = 'NO'
    colour = 31
    else
    available = 'YES'
    colour = 32
    end
    puts "#{Utils::model_name(model_no)}: \t\033[1;#{colour};49m#{available}\033[0m\n"
    end
    end

    end

    begin
    stores = Utils::get_json("https://reserve.cdn-apple.com/AU/en_AU/reserve/iPhone/stores.json")
    availability = Utils::get_json("https://reserve.cdn-apple.com/AU/en_AU/reserve/iPhone/availability.json")
    rescue => e
    puts "Exception: #{e.message}"
    exit 1
    end

    updated_at = Time.at(availability.delete('updated') / 1000).strftime('%d %b, %H:%M:%S %Z') rescue nil

    case ARGV.length
    when 0
    puts "\033[4;39;49mListing stores with stock availability\033[0m\n"
    puts "-- Updated at: #{updated_at} --\n"
    Commands::list_all(stores, availability)
    when 1
    store_identifier = ARGV.shift
    store_description = stores['stores'].detect { |s| s['storeNumber'] == store_identifier }
    puts "\033[1;39;49m#{store_description['storeName']}\033[0m\n"
    puts "-- Updated at: #{updated_at} --\n"
    Commands::list_store(store_identifier, availability[store_identifier])
    else
    puts '¯\_(ツ)_/¯'
    end

    exit 0