160 lines
3.6 KiB
Ruby
160 lines
3.6 KiB
Ruby
#!/usr/bin/env ruby
|
|
## soluapp-enumerator.rb - enumerates soluapp.pub IDs for users and stories
|
|
|
|
require 'digest'
|
|
require 'net/http'
|
|
require 'uri'
|
|
|
|
module Soluapp
|
|
|
|
URL_TEMPLATES = {
|
|
:one => {
|
|
:legacy_chapter => 'http://soluapp.pub/legacy-chapter.php?id=%i',
|
|
:story_slide => 'http://soluapp.pub/story_slide.php?userid=%i&key=0&ty=',
|
|
},
|
|
:two => {
|
|
:last_story => 'http://soluapp.pub/legacy/last_story1.php?userid=%i&id=%i&img=bg_image7.png&key=0&ty=&chapkey=0',
|
|
:write_legacy => 'http://soluapp.pub/legacy/write_legacy.php?id=%i&img=&key=&chapkey=&ty=&user=%i',
|
|
},
|
|
:buckle_my_shoe => {},
|
|
}
|
|
|
|
class Utility
|
|
|
|
def self.get_url_one(type, id)
|
|
sprintf(URL_TEMPLATES[:one][type], id)
|
|
end
|
|
|
|
def self.get_url_two(type, id1, id2)
|
|
sprintf(URL_TEMPLATES[:two][type], id1, id2)
|
|
end
|
|
|
|
def self.get_url(url)
|
|
uri = URI.parse(url)
|
|
http = Net::HTTP.new(uri.host, uri.port)
|
|
http.use_ssl = false
|
|
request = Net::HTTP::Get.new(uri.request_uri)
|
|
response = http.request(request)
|
|
|
|
if response.code.eql?('301')
|
|
return self.get_url(response.header['location'])
|
|
end
|
|
|
|
response
|
|
end
|
|
|
|
end
|
|
|
|
class Response
|
|
|
|
attr_reader :url, :response, :hash, :size, :success
|
|
|
|
def initialize(url, response)
|
|
@url = url
|
|
@response = response
|
|
@success = ! response.code.match(/4.*/)
|
|
|
|
@hash = Digest::MD5.hexdigest(response.body)
|
|
@size = response.body.length
|
|
end
|
|
end
|
|
|
|
class Application
|
|
attr_reader :type, :ceiling, :floor, :responses
|
|
|
|
def initialize(type, ceiling = 10_000, floor = 0)
|
|
@type = type.to_sym
|
|
@ceiling = ceiling
|
|
@floor = floor
|
|
@responses = Array.new
|
|
|
|
raise StandardError.new(sprintf('invalid type[%s] specified', type)) unless URL_TEMPLATES[:one].has_key?(type) or URL_TEMPLATES[:two].has_key?(type)
|
|
end
|
|
|
|
def inspect
|
|
candidate = {
|
|
:type => @type,
|
|
:ceiling => @ceiling,
|
|
:floor => @floor,
|
|
}
|
|
|
|
candidate.delete(:floor) if @floor.eql?(0)
|
|
candidate
|
|
end
|
|
|
|
def to_s
|
|
self.inspect.to_s
|
|
end
|
|
|
|
def request!
|
|
|
|
return request_url_one if URL_TEMPLATES[:one].has_key?(@type)
|
|
return request_url_two if URL_TEMPLATES[:two].has_key?(@type)
|
|
|
|
end
|
|
|
|
def request_url_one
|
|
|
|
@floor.upto(@ceiling) do |i|
|
|
url = Soluapp::Utility.get_url_one(@type, i)
|
|
response = Soluapp::Utility.get_url(url)
|
|
@responses << Soluapp::Response.new(url, response)
|
|
end
|
|
|
|
end
|
|
|
|
def request_url_two
|
|
|
|
@floor.upto(@ceiling) do |i|
|
|
@floor.upto(@ceiling) do |j|
|
|
url = Soluapp::Utility.get_url_two(@type, i, j)
|
|
response = Soluapp::Utility.get_url(url)
|
|
@responses << Soluapp::Response.new(url, response)
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
def summarize
|
|
successes = @responses.select { |r| r.success.eql?(true) }
|
|
failures = @responses - successes
|
|
|
|
puts sprintf('total responses[%i]', @responses.size)
|
|
puts sprintf(' successful responses[%i]', successes.size)
|
|
puts sprintf(' failed responses [%i]', failures.size)
|
|
|
|
sizes = Hash.new(0)
|
|
successes.each do |s|
|
|
sizes[s.size] += 1
|
|
end
|
|
|
|
puts sprintf('size distribution[%s]', sizes)
|
|
|
|
md5s = Hash.new('')
|
|
successes.each do |s|
|
|
md5s[s.hash] += 1
|
|
end
|
|
|
|
puts sprintf('hash distribution[%s]', md5s)
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
ceiling = 10
|
|
floor = 0
|
|
|
|
[
|
|
:legacy_chapter,
|
|
:story_slide,
|
|
:last_story,
|
|
:write_legacy,
|
|
].each do |type|
|
|
app = Soluapp::Application.new(type, ceiling, floor)
|
|
|
|
app.request!
|
|
|
|
app.summarize
|
|
|
|
end |