uva-tools 0.0.1

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.
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: []