uva-tools 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 600ae5264d13d0c083a5ad143e01f6cd5cd3b180
4
+ data.tar.gz: c13486119816dc8ad210072915efac90142d6256
5
+ SHA512:
6
+ metadata.gz: 5d565deb6a25120c1f19a66d640f7e060055b28ba31a6abc1ee01457ff0c5da25bf08b9678e51f309ca0c9be57fb05a7329f296e3b125638b4853711c63c9e86
7
+ data.tar.gz: 55be55d88c394e2570361d3508dcc506a626308f55fdc0136968ca98beed12bc8a2efa1c52cda3d9af0055b876a84a299194eb627eae2f9468d4d33657dd1d20
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ doc
2
+ pkg
3
+ *.gem
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Henning Koch
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1 @@
1
+ # UVa Tools
@@ -0,0 +1,124 @@
1
+ =begin
2
+ 0: Problem ID
3
+ 1: Problem Number
4
+ 2: Problem Title
5
+ 3: Number of Distinct Accepted User (DACU)
6
+ 4: Best Runtime of an Accepted Submission
7
+ 5: Best Memory used of an Accepted Submission
8
+ 6: Number of No Verdict Given (can be ignored)
9
+ 7: Number of Submission Error
10
+ 8: Number of Can't be Judged
11
+ 9: Number of In Queue
12
+ 10: Number of Compilation Error
13
+ 11: Number of Restricted Function
14
+ 12: Number of Runtime Error
15
+ 13: Number of Output Limit Exceeded
16
+ 14: Number of Time Limit Exceeded
17
+ 15: Number of Memory Limit Exceeded
18
+ 16: Number of Wrong Answer
19
+ 17: Number of Presentation Error
20
+ 18: Number of Accepted
21
+ 19: Problem Run-Time Limit (milliseconds)
22
+ 20: Problem Status (0 = unavailable, 1 = normal, 2 = special judge)
23
+ =end
24
+
25
+ module UVaTools
26
+ class Problem
27
+ def initialize(array)
28
+ @info = array
29
+ end
30
+
31
+ def id
32
+ @info[0]
33
+ end
34
+
35
+ def number
36
+ @info[1]
37
+ end
38
+
39
+ def title
40
+ @info[2]
41
+ end
42
+
43
+ def info
44
+ {
45
+ id: id,
46
+ number: number,
47
+ title: title,
48
+ run_time: @info[19]
49
+ }
50
+ end
51
+
52
+ def submitted
53
+ @info[6..18].inject(:+)
54
+ end
55
+
56
+ def accepted
57
+ @info[18]
58
+ end
59
+
60
+ def dacu
61
+ @info[3]
62
+ end
63
+
64
+ def submission_info
65
+ {
66
+ submitted: submitted,
67
+ accepted: accepted,
68
+ dacu: dacu
69
+ }
70
+ end
71
+
72
+ def download
73
+ unless downloaded?
74
+ FileUtils::mkdir_p dir_name
75
+ Dir.chdir(dir_name) do
76
+ uri = URI("https://uva.onlinejudge.org/external/#{number/100}/#{number}.html")
77
+ source = Net::HTTP.get(uri)
78
+ if source.include? "URL=p#{number}.pdf"
79
+ File.open("#{number.to_s}.pdf", 'w') do |pdf|
80
+ pdf.write open("https://uva.onlinejudge.org/external/#{number/100}/p#{number}.pdf").read
81
+ end
82
+ else
83
+ File.open("#{number.to_s}.html", 'w') { |f| f.write source }
84
+
85
+ source.scan(/#{number}img\d{1,3}\.[a-zA-Z]+/).uniq.each do |picture|
86
+ File.open(picture, 'wb') do |pic_file|
87
+ pic_file.write open("https://uva.onlinejudge.org/external/#{number/100}/#{picture}").read
88
+ end
89
+ end
90
+ end
91
+ end
92
+ puts "downloaded: #{number}"
93
+ true
94
+ else
95
+ puts "#{number} was already downloaded"
96
+ false
97
+ end
98
+ end
99
+
100
+ def remove
101
+ if downloaded?
102
+ Dir.chdir(dir_name) do
103
+ Dir.entries('.').each do |file_name|
104
+ if file_name =~ /^#{number}.*/ && !File.directory?(file_name)
105
+ File.delete(file_name)
106
+ end
107
+ end
108
+ end
109
+ puts "removed #{number}"
110
+ else
111
+ puts "#{number} wasn't downloaded"
112
+ end
113
+ end
114
+
115
+ def downloaded?
116
+ File.directory?(dir_name) && (File.exists?("#{dir_name}/#{number}.html") || File.exists?("#{dir_name}/#{number}.pdf"))
117
+ end
118
+
119
+ private
120
+ def dir_name
121
+ "#{ENV['HOME']}/uva-tools/#{number/100}"
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,80 @@
1
+ module UVaTools
2
+ class User
3
+ def initialize(username)
4
+ @username = username
5
+ end
6
+
7
+ def solved
8
+ solved_hash.values
9
+ end
10
+
11
+ def solved_by_number
12
+ solved_hash
13
+ end
14
+
15
+ def unsolved
16
+ @unsolved ||= begin
17
+ prob_by_id = UVaTools.problems_by_id
18
+ unsolved_pids.map do |pid|
19
+ prob_by_id[pid]
20
+ end.sort{ |a, b| b.dacu <=> a.dacu }
21
+ end
22
+ end
23
+
24
+ def has_solved?(prob_nums)
25
+ res = Array(prob_nums).map do |prob_num|
26
+ solved_by_number.has_key? prob_num
27
+ end
28
+ res.length < 2 ? res[0] : res
29
+ end
30
+
31
+ def reload
32
+ @solved_pids = nil
33
+ @solved = nil
34
+ @unsolved = nil
35
+ self
36
+ end
37
+
38
+ private
39
+ def uid
40
+ @uid ||= begin
41
+ uri = URI("http://uhunt.felix-halim.net/api/uname2uid/#{@username}")
42
+ Net::HTTP.get(uri)
43
+ end
44
+ end
45
+
46
+ def solved_pids
47
+ @solved_pids ||= get_solved_pids
48
+ end
49
+
50
+ def solved_hash
51
+ @solved ||= begin
52
+ prob_by_id = UVaTools.problems_by_id
53
+ h = {}
54
+ solved_pids.each do |pid|
55
+ problem = prob_by_id[pid]
56
+ h[problem.number] = problem
57
+ end
58
+ h
59
+ end
60
+ end
61
+
62
+ def reload_solved_pids
63
+ @solved_pids = get_solved_pids
64
+ end
65
+
66
+ def get_solved_pids
67
+ uri = URI("http://uhunt.felix-halim.net/api/solved-bits/#{uid}")
68
+ res = JSON.parse(Net::HTTP.get(uri))[0]['solved']
69
+ res.each_with_index.map do |num, j|
70
+ num.to_s(2).reverse.scan(/./).each_with_index.map do |c, i|
71
+ j*32 + i if c == '1'
72
+ end.compact
73
+ end.flatten.sort
74
+ end
75
+
76
+ def unsolved_pids
77
+ UVaTools.problems.map(&:id) - solved_pids
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,108 @@
1
+ module UVaTools
2
+ class << self
3
+ def problems
4
+ problem_hash.values
5
+ end
6
+
7
+ def problems_by_number
8
+ problem_hash
9
+ end
10
+
11
+ def problems_by_id
12
+ h = {}
13
+ problem_hash.values.each{ |p| h[p.id] = p }
14
+ h
15
+ end
16
+
17
+ def download_multiple(prob_nums, worker_count = 4)
18
+ to_download = Array(prob_nums).map do |prob_num|
19
+ problems_by_number[prob_num]
20
+ end
21
+
22
+ if to_download.length > 0
23
+ worker_count = [worker_count, to_download.length].min
24
+ workers = []
25
+
26
+ worker_count.times do
27
+ workers << worker(to_download)
28
+ end
29
+
30
+ reads = workers.map{|worker| worker[:read]}
31
+ writes = workers.map{|worker| worker[:write]}
32
+
33
+ index = 0
34
+ finished = 0
35
+
36
+ loop do
37
+ break if finished >= to_download.size
38
+
39
+ ready = IO.select(reads, writes)
40
+
41
+ ready[0].each do |readable|
42
+ data = Marshal.load(readable)
43
+ # assets.merge! data["assets"]
44
+ # files.merge! data["files"]
45
+ # paths_with_errors.merge! data["errors"]
46
+ finished += 1
47
+ end
48
+
49
+ ready[1].each do |write|
50
+ break if index >= to_download.size
51
+
52
+ Marshal.dump(index, write)
53
+ index += 1
54
+ end
55
+ end
56
+
57
+ workers.each do |worker|
58
+ worker[:read].close
59
+ worker[:write].close
60
+ end
61
+
62
+ workers.each do |worker|
63
+ Process.wait worker[:pid]
64
+ end
65
+ end
66
+
67
+ nil
68
+ end
69
+
70
+ private
71
+ def worker(problems)
72
+ child_read, parent_write = IO.pipe
73
+ parent_read, child_write = IO.pipe
74
+
75
+ pid = fork do
76
+ begin
77
+ parent_write.close
78
+ parent_read.close
79
+
80
+ while !child_read.eof?
81
+ problem = problems[Marshal.load(child_read)]
82
+ problem.download
83
+ Marshal.dump(problem.number, child_write)
84
+ end
85
+ ensure
86
+ child_read.close
87
+ child_write.close
88
+ end
89
+ end
90
+
91
+ child_read.close
92
+ child_write.close
93
+
94
+ {:read => parent_read, :write => parent_write, :pid => pid}
95
+ end
96
+
97
+ def problem_hash
98
+ @@problems ||= begin
99
+ uri = URI("http://uhunt.felix-halim.net/api/p")
100
+ res = JSON.parse(Net::HTTP.get(uri))
101
+
102
+ h = {}
103
+ res.each{ |row| h[row[1]] = UVaTools::Problem.new(row) }
104
+ h
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,3 @@
1
+ module UVaTools
2
+ VERSION = '0.0.1'
3
+ end
data/lib/uva-tools.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'net/http'
2
+ require 'open-uri'
3
+ require 'json'
4
+ require 'fileutils'
5
+ require 'uva-tools/uva-tools'
6
+ require 'uva-tools/user'
7
+ require 'uva-tools/problem'
data/uva-tools.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $: << File.expand_path('../lib', __FILE__)
3
+ require 'uva-tools/version'
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.authors = "Dave Allie"
7
+ gem.email = "dave@daveallie.com"
8
+ gem.description = "Set of UVa Online tools"
9
+ gem.summary = gem.description
10
+ gem.homepage = "https://github.com/daveallie/uva-tools"
11
+ gem.license = 'MIT'
12
+
13
+ gem.files = `git ls-files`.split($\)
14
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
15
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
16
+ gem.name = "uva-tools"
17
+ gem.require_paths = ["lib"]
18
+ gem.version = UVaTools::VERSION
19
+ end
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: uva-tools
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Dave Allie
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-10-05 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Set of UVa Online tools
14
+ email: dave@daveallie.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - ".gitignore"
20
+ - MIT-LICENSE
21
+ - README.md
22
+ - lib/uva-tools.rb
23
+ - lib/uva-tools/problem.rb
24
+ - lib/uva-tools/user.rb
25
+ - lib/uva-tools/uva-tools.rb
26
+ - lib/uva-tools/version.rb
27
+ - uva-tools.gemspec
28
+ homepage: https://github.com/daveallie/uva-tools
29
+ licenses:
30
+ - MIT
31
+ metadata: {}
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubyforge_project:
48
+ rubygems_version: 2.4.5.1
49
+ signing_key:
50
+ specification_version: 4
51
+ summary: Set of UVa Online tools
52
+ test_files: []