partyhat 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.
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem "curb"
4
+ gem "nokogiri"
5
+
6
+ group :development do
7
+ gem "rspec"
8
+ gem "bundler"
9
+ gem "jeweler"
10
+ gem "simplecov"
11
+ gem "simplecov-gem-adapter"
12
+ end
@@ -0,0 +1,39 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ curb (0.7.16)
5
+ diff-lcs (1.1.3)
6
+ git (1.2.5)
7
+ jeweler (1.6.4)
8
+ bundler (~> 1.0)
9
+ git (>= 1.2.5)
10
+ rake
11
+ multi_json (1.0.4)
12
+ nokogiri (1.5.0)
13
+ rake (0.9.2.2)
14
+ rspec (2.7.0)
15
+ rspec-core (~> 2.7.0)
16
+ rspec-expectations (~> 2.7.0)
17
+ rspec-mocks (~> 2.7.0)
18
+ rspec-core (2.7.1)
19
+ rspec-expectations (2.7.0)
20
+ diff-lcs (~> 1.1.2)
21
+ rspec-mocks (2.7.0)
22
+ simplecov (0.5.4)
23
+ multi_json (~> 1.0.3)
24
+ simplecov-html (~> 0.5.3)
25
+ simplecov-gem-adapter (1.0.1)
26
+ simplecov
27
+ simplecov-html (0.5.3)
28
+
29
+ PLATFORMS
30
+ ruby
31
+
32
+ DEPENDENCIES
33
+ bundler
34
+ curb
35
+ jeweler
36
+ nokogiri
37
+ rspec
38
+ simplecov
39
+ simplecov-gem-adapter
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Nico Hämäläinen
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.
@@ -0,0 +1,23 @@
1
+ = Partyhat
2
+ == usage
3
+
4
+ require 'partyhat'
5
+ first_skill = Partyhat::Skill.new(:attack, 99, 23_784_441, 2509)
6
+ second_skill = Partyhat::Skill.new(:attack, 99, 16_700_194, 6492)
7
+ first_skill.compare_to(second_skill).experience # returns experience difference
8
+
9
+ == Contributing to partyhat
10
+
11
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
12
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
13
+ * Fork the project
14
+ * Start a feature/bugfix branch
15
+ * Commit and push until you are happy with your contribution
16
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
17
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
18
+
19
+ == Copyright
20
+
21
+ Copyright (c) 2011 Clooth. See LICENSE.txt for
22
+ further details.
23
+
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "partyhat"
18
+ gem.homepage = "http://github.com/clooth/partyhat"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{General Runescape Gem}
21
+ gem.description = %Q{Versatile runescape gem offering useful tools for runescape-related apps}
22
+ gem.authors = ["clooth"]
23
+ gem.email = "zenverse@gmail.com"
24
+ end
25
+ Jeweler::RubygemsDotOrgTasks.new
26
+
27
+ require 'rspec/core'
28
+ require 'rspec/core/rake_task'
29
+ RSpec::Core::RakeTask.new(:spec) do |spec|
30
+ spec.pattern = FileList['spec/**/*_spec.rb']
31
+ end
32
+
33
+ task :default => :spec
34
+
35
+ require 'rake/rdoctask'
36
+ Rake::RDocTask.new do |rdoc|
37
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
38
+
39
+ rdoc.rdoc_dir = 'rdoc'
40
+ rdoc.title = "partyhat #{version}"
41
+ rdoc.rdoc_files.include('README*')
42
+ rdoc.rdoc_files.include('lib/**/*.rb')
43
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,19 @@
1
+ module Partyhat
2
+ end
3
+
4
+ require 'open-uri'
5
+ require 'curb'
6
+ require 'nokogiri'
7
+ require 'partyhat/util'
8
+ require 'partyhat/stat'
9
+ require 'partyhat/skill'
10
+ require 'partyhat/skill_comparison'
11
+ require 'partyhat/activity'
12
+ require 'partyhat/activity_comparison'
13
+ require 'partyhat/forums'
14
+ require 'partyhat/forums/forum_post'
15
+ require 'partyhat/forums/forum_thread'
16
+ require 'partyhat/calculators'
17
+ require 'partyhat/calculators/combat'
18
+ require 'partyhat/player'
19
+ require 'partyhat/highscores'
@@ -0,0 +1,34 @@
1
+ module Partyhat
2
+ class Activity < Partyhat::Stat
3
+ @name = nil
4
+ @score = nil
5
+ @rank = nil
6
+
7
+ def initialize name, score, rank
8
+ raise ArgumentError, 'Invalid activity name' unless ActivitiesList.include? name
9
+ @name = name
10
+ @score = score < 0 ? nil : score
11
+ @rank = rank < 0 ? nil : rank
12
+ end
13
+
14
+ def name
15
+ @name
16
+ end
17
+
18
+ def human_name
19
+ Partyhat::Stat.human_name_for @name
20
+ end
21
+
22
+ def score
23
+ @score
24
+ end
25
+
26
+ def rank
27
+ @rank
28
+ end
29
+
30
+ def compare_to another_activity
31
+ Partyhat::ActivityComparison.new(self, another_activity)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,29 @@
1
+ module Partyhat
2
+ class ActivityComparison
3
+ @first_activity = nil
4
+ @second_activity = nil
5
+ @score = nil
6
+ @rank = nil
7
+
8
+ def initialize first_activity, second_activity
9
+ # Check the classes so they don't fail
10
+ unless (first_activity.class == Partyhat::Activity) && (second_activity.class == Partyhat::Activity)
11
+ raise InvalidArgumentError 'You can only compare two Partyhat::Activity objects.'
12
+ end
13
+ # Assign instance variables
14
+ @first_activity = first_activity
15
+ @second_activity = second_activity
16
+ # Perform comparison
17
+ @score = @second_activity.score - @first_activity.score
18
+ @rank = @second_activity.rank - @first_activity.rank
19
+ end
20
+
21
+ def score
22
+ @score
23
+ end
24
+
25
+ def rank
26
+ @rank
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,4 @@
1
+ module Partyhat
2
+ module Calculators
3
+ end
4
+ end
@@ -0,0 +1,43 @@
1
+ module Partyhat
2
+ module Calculators
3
+ # Calculate a user's combat level with the given stats hash
4
+ # The method defaults to runescape starter stats if any of
5
+ # the skills are missing from the hash.
6
+ def self.combat stats
7
+ return nil if stats.nil? || stats.empty?
8
+ # Default combat calculator stats
9
+ default_stats = {
10
+ :attack => 1,
11
+ :defence => 1,
12
+ :strength => 1,
13
+ :constitution => 10,
14
+ :ranged => 1,
15
+ :prayer => 1,
16
+ :magic => 1,
17
+ :summoning => 1
18
+ }
19
+ # Replace non-set values with defaults
20
+ values = default_stats.inject({}) { |h, (k, v)| h[k] = stats[k].level.to_i || v; h }
21
+
22
+ # Level calculations
23
+ base_level = (values[:defence] + values[:constitution] + (values[:prayer] / 2).floor + (values[:summoning] / 2).floor) * 0.25
24
+ base_melee = (values[:attack] + values[:strength]) * 0.325
25
+ base_range = (values[:ranged] * 1.5).floor * 0.325
26
+ base_magic = (values[:magic] * 1.5).floor * 0.325
27
+
28
+ combat_level = base_level + [base_melee, base_range, base_magic].max
29
+
30
+ # Remainder calculations
31
+ remainder_diff = combat_level + 1
32
+ remainder_diff = combat_level.ceil - combat_level if combat_level.is_a?(Float)
33
+ remainders = {
34
+ :strength_attack => (remainder_diff / (1.0/3.0)).ceil,
35
+ :defence_constitution => (remainder_diff / 0.25).ceil,
36
+ :prayer_summoning => (remainder_diff / 0.125).ceil
37
+ }
38
+
39
+ { :level => combat_level,
40
+ :remainders => remainders }
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,10 @@
1
+ module Partyhat
2
+ module Forums
3
+ QUICK_FIND_CODE_FORMAT = /^\d+-\d+-\d+-\d+$/
4
+
5
+ def self.valid_qfc? qfc
6
+ return false if qfc.match(QUICK_FIND_CODE_FORMAT).nil?
7
+ true
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,30 @@
1
+ module Partyhat
2
+ module Forums
3
+ # TODO: Deleted post type
4
+ # TODO: Make sure it cannot be instantiated with invalid information (date in the future etc)
5
+ # TODO: Check for moderator posts
6
+ class ForumPost
7
+ @author = nil
8
+ @posted = nil
9
+ @contents = nil
10
+
11
+ def initialize author, posted, contents
12
+ @author = author
13
+ @posted = posted
14
+ @contents = contents
15
+ end
16
+
17
+ def author
18
+ @author
19
+ end
20
+
21
+ def posted
22
+ @posted
23
+ end
24
+
25
+ def contents
26
+ @contents
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,48 @@
1
+ module Partyhat
2
+ module Forums
3
+ # TODO: Add pagination support
4
+ # e.g. thread.next_page
5
+ class ForumThread
6
+ URL_FORMAT = 'http://services.runescape.com/m=forum/forums.ws?%s'
7
+ @posts = []
8
+ @link = nil
9
+ @qfc = nil
10
+
11
+ def initialize qfc
12
+ raise InvalidArgumentError('Invalid quick find code') unless Forums.valid_qfc?(qfc)
13
+ @posts = []
14
+ @qfc = qfc
15
+ @link = URL_FORMAT % qfc.gsub(/-/, ",")
16
+ parse_from_page Partyhat::Util.fetch_remote(@link)
17
+ end
18
+
19
+ def title
20
+ @title
21
+ end
22
+
23
+ def posts
24
+ @posts
25
+ end
26
+
27
+ def link
28
+ @link
29
+ end
30
+
31
+ def qfc
32
+ @qfc
33
+ end
34
+
35
+ protected
36
+ def parse_from_page page
37
+ document = Nokogiri::HTML(page)
38
+ # Get title
39
+ @title = document.css('.BarFullTop span.G0').first.content
40
+ # Get posts on the page
41
+ document.css('#MainContent .message').each do |post|
42
+ author, posted, contents = [post.css('.author'), post.css('.BubbleCreation span'), post.css('.msgcontents td')].map(&:text)
43
+ @posts << Partyhat::Forums::ForumPost.new(author, posted, contents)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,31 @@
1
+ module Partyhat
2
+ module Highscores
3
+ HIGHSCORES_PAGE_URL = 'http://hiscore.runescape.com/index_lite.ws?player=%s'
4
+
5
+ # Fetch a user's highscores object
6
+ def self.find_player name
7
+ page_url = HIGHSCORES_PAGE_URL % URI::encode(name)
8
+ page_src = Partyhat::Util.fetch_remote(page_url)
9
+ self.parse_lite_page(page_src) unless page_src.nil?
10
+ end
11
+
12
+ # Parse the result page from the highscores into
13
+ # A hash containing skill/activity objects with
14
+ # the corresponding stat name as key.
15
+ def self.parse_lite_page page
16
+ lite_page_lines = page.split("\n")
17
+ user_stats = {}
18
+ Partyhat::Stat::List.each do |stat|
19
+ line_parts = lite_page_lines.shift.split(',').map(&:to_i)
20
+ if line_parts.size == 3
21
+ rank, level, experience = line_parts.shift, line_parts.shift, line_parts.shift
22
+ user_stats[stat] = Partyhat::Skill.new(stat, level, experience, rank)
23
+ else
24
+ rank, score = line_parts.shift, line_parts.shift
25
+ user_stats[stat] = Partyhat::Activity.new(stat, score, rank)
26
+ end
27
+ end
28
+ user_stats
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ module Partyhat
2
+ class Player
3
+ @name = nil
4
+ @stats = nil
5
+
6
+ def initialize name
7
+ @name = name
8
+ @stats = Partyhat::Highscores.find_player(@name)
9
+ end
10
+
11
+ def name
12
+ @name
13
+ end
14
+
15
+ def stats
16
+ @stats
17
+ end
18
+
19
+ def combat
20
+ Partyhat::Calculators.combat(stats)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,42 @@
1
+ module Partyhat
2
+ class Skill < Partyhat::Stat
3
+ @name = nil
4
+ @level = nil
5
+ @experience = nil
6
+ @rank = nil
7
+
8
+ def initialize name, level, experience, rank
9
+ raise ArgumentError, 'Invalid skill name "' + name.to_s + '"' unless (SkillsList+[:overall]).include? name
10
+ @name = name
11
+
12
+ # Nilify negative values
13
+ @level = level < 0 ? nil : level
14
+ @experience = experience < 0 ? nil : experience
15
+ @rank = rank < 0 ? nil : rank
16
+ end
17
+
18
+ def name
19
+ @name
20
+ end
21
+
22
+ def human_name
23
+ Partyhat::Stat.human_name_for @name
24
+ end
25
+
26
+ def level
27
+ @level
28
+ end
29
+
30
+ def experience
31
+ @experience
32
+ end
33
+
34
+ def rank
35
+ @rank
36
+ end
37
+
38
+ def compare_to another_skill
39
+ Partyhat::SkillComparison.new(self, another_skill)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,35 @@
1
+ module Partyhat
2
+ class SkillComparison
3
+ @first_skill = nil
4
+ @second_skill = nil
5
+ @level = nil
6
+ @experience = nil
7
+ @rank = nil
8
+
9
+ def initialize first_skill, second_skill
10
+ # Check the classes so they don't fail
11
+ unless (first_skill.class == Partyhat::Skill) && (second_skill.class == Partyhat::Skill)
12
+ raise InvalidArgumentError 'You can only compare two Skill objects.'
13
+ end
14
+ # Assign instance variables
15
+ @first_skill = first_skill
16
+ @second_skill = second_skill
17
+ # Perform comparison
18
+ @level = @second_skill.level - @first_skill.level
19
+ @experience = @second_skill.experience - @first_skill.experience
20
+ @rank = @second_skill.rank - @first_skill.rank
21
+ end
22
+
23
+ def level
24
+ @level
25
+ end
26
+
27
+ def experience
28
+ @experience
29
+ end
30
+
31
+ def rank
32
+ @rank
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,112 @@
1
+ module Partyhat
2
+ class Stat
3
+ # List of skills that appear in the highscores
4
+ SkillsList = [
5
+ :attack,
6
+ :defence,
7
+ :strength,
8
+ :constitution,
9
+ :ranged,
10
+ :prayer,
11
+ :magic,
12
+ :cooking,
13
+ :woodcutting,
14
+ :fletching,
15
+ :fishing,
16
+ :firemaking,
17
+ :crafting,
18
+ :smithing,
19
+ :mining,
20
+ :herblore,
21
+ :agility,
22
+ :thieving,
23
+ :slayer,
24
+ :farming,
25
+ :runecrafting,
26
+ :hunter,
27
+ :construction,
28
+ :summoning,
29
+ :dungeoneering
30
+ ]
31
+
32
+ # List of activities that appear in the highscores
33
+ ActivitiesList = [
34
+ :duel_tournament,
35
+ :bounty_hunters,
36
+ :bounty_hunter_rogues,
37
+ :fist_of_guthix,
38
+ :mobilising_armies,
39
+ :ba_attackers,
40
+ :ba_defenders,
41
+ :ba_collectors,
42
+ :ba_healers,
43
+ :castle_wars_games,
44
+ :conquest,
45
+ :dominion_tower
46
+ ]
47
+
48
+ # List of skills that count in your combat level
49
+ CombatSkillsList = [
50
+ :attack,
51
+ :defence,
52
+ :strength,
53
+ :constitution,
54
+ :ranged,
55
+ :prayer,
56
+ :magic,
57
+ :summoning
58
+ ]
59
+
60
+ # List of all stats that can belong to a player
61
+ List = [:overall] + SkillsList + ActivitiesList
62
+
63
+ # Human readable names for all skills and activities
64
+ HumanNames = {
65
+ :overall => 'Overall',
66
+ :attack => 'Attack',
67
+ :defence => 'Defence',
68
+ :strength => 'Strength',
69
+ :constitution => 'Constitution',
70
+ :ranged => 'Ranged',
71
+ :prayer => 'Prayer',
72
+ :magic => 'Magic',
73
+ :cooking => 'Cooking',
74
+ :woodcutting => 'Woodcutting',
75
+ :fletching => 'Fletching',
76
+ :fishing => 'Fishing',
77
+ :firemaking => 'Firemaking',
78
+ :crafting => 'Crafting',
79
+ :smithing => 'Smithing',
80
+ :mining => 'Mining',
81
+ :herblore => 'Herblore',
82
+ :agility => 'Agility',
83
+ :thieving => 'Thieving',
84
+ :slayer => 'Slayer',
85
+ :farming => 'Farming',
86
+ :runecrafting => 'Runecrafting',
87
+ :hunter => 'Hunter',
88
+ :construction => 'Construction',
89
+ :summoning => 'Summoning',
90
+ :dungeoneering => 'Dungeoneering',
91
+ :duel_tournament => 'Duel Tournament',
92
+ :bounty_hunters => 'Bounty Hunters',
93
+ :bounty_hunter_rogues => 'Bounty Hunter Rogues',
94
+ :fist_of_guthix => 'Fist of Guthix',
95
+ :mobilising_armies => 'Mobilising Armies',
96
+ :ba_attackers => 'B.A Attackers',
97
+ :ba_defenders => 'B.A Defenders',
98
+ :ba_collectors => 'B.A Collectors',
99
+ :ba_healers => 'B.A Healers',
100
+ :castle_wars_games => 'Castle Wars Games',
101
+ :conquest => 'Conquest',
102
+ :dominion_tower => 'Dominion Tower'
103
+ }
104
+
105
+ # Get the human readable name for a stat name
106
+ #
107
+ # * returns 'Undefined' if not found
108
+ def self.human_name_for stat
109
+ HumanNames[stat] || 'Undefined'
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,92 @@
1
+ module Partyhat
2
+ class Util
3
+ # Convert an experience value to a level
4
+ # Uses a formula from somewhere.
5
+ # TODO: Add source for formula.
6
+ def self.experience_to_level experience
7
+ modifier = 0
8
+ (1..200).each do |n|
9
+ modifier += (n + 300 * (2 ** (n.to_f/7.0))).floor
10
+ level = (modifier/4).floor
11
+ return n if experience < level
12
+ end
13
+ 200
14
+ end
15
+
16
+ # Convert a level value into experience
17
+ # Uses a formula from somewhere.
18
+ # FIXME: This is not accurate, check partyhat_util_spec results
19
+ # TODO: Add source for formula.
20
+ def self.level_to_experience level
21
+ experience = 0
22
+ (1..level-1).each do |n|
23
+ experience += (n + 300 * (2 ** (n.to_f/7.0))).floor
24
+ end
25
+ (experience/4).floor
26
+ end
27
+
28
+ # Abbreviate a small or large number into compressed form
29
+ # Usage:
30
+ # Partyhat::Util.abbreviate_number(55_500) => "55K"
31
+ # as seen all over the game. e.g. "5K"
32
+ def self.shorten_number number
33
+ divider = 1
34
+ suffix = nil
35
+ if number >= 1_000_000_000
36
+ divider = 1_000_000_000
37
+ suffix = 'B'
38
+ elsif number >= 1_000_000
39
+ divider = 1_000_000
40
+ suffix = 'M'
41
+ elsif number >= 1_000
42
+ divider = 1_000
43
+ suffix = 'K'
44
+ end
45
+ (number / divider.to_f).round(1).to_s + suffix
46
+ end
47
+
48
+ # De-abbreviate the already compressed number with the
49
+ # abbreviate_number method.
50
+ # Note:
51
+ # Values might not stay the same if abbreviated
52
+ # and then deabbreviated
53
+ def self.parse_number string
54
+ number = string.chop.to_f
55
+ ending = string[-1, 1]
56
+ multiplier = 1
57
+ case ending.upcase
58
+ when 'B' then multiplier = 1_000_000_000
59
+ when 'M' then multiplier = 1_000_000
60
+ when 'K' then multiplier = 1_000
61
+ end
62
+ (number * (multiplier || 1)).round(1)
63
+ end
64
+
65
+ # Fetch a remote page and return it
66
+ # If you pass in only one URL, direct source will be returneds
67
+ # If you pass in multiple URLs, a hash will be returned with url indexes
68
+ def self.fetch_remote urls
69
+ urls = [urls] unless urls.is_a?(Array)
70
+ responses = {}
71
+ m = Curl::Multi.new
72
+ urls.reject.each do |url|
73
+ responses[url] = ""
74
+ c = Curl::Easy.new(url) do|curl|
75
+ curl.follow_location = true
76
+ curl.on_body do |data|
77
+ responses[url] << data
78
+ data.size
79
+ end
80
+ end
81
+ m.add(c)
82
+ end
83
+ m.perform
84
+
85
+ if responses.size > 1
86
+ responses
87
+ else
88
+ responses[urls.pop]
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,89 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "partyhat"
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["clooth"]
12
+ s.date = "2011-12-15"
13
+ s.description = "Versatile runescape gem offering useful tools for runescape-related apps"
14
+ s.email = "zenverse@gmail.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "LICENSE.txt",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "lib/partyhat.rb",
29
+ "lib/partyhat/activity.rb",
30
+ "lib/partyhat/activity_comparison.rb",
31
+ "lib/partyhat/calculators.rb",
32
+ "lib/partyhat/calculators/combat.rb",
33
+ "lib/partyhat/forums.rb",
34
+ "lib/partyhat/forums/forum_post.rb",
35
+ "lib/partyhat/forums/forum_thread.rb",
36
+ "lib/partyhat/highscores.rb",
37
+ "lib/partyhat/player.rb",
38
+ "lib/partyhat/skill.rb",
39
+ "lib/partyhat/skill_comparison.rb",
40
+ "lib/partyhat/stat.rb",
41
+ "lib/partyhat/util.rb",
42
+ "partyhat.gemspec",
43
+ "spec/activity_spec.rb",
44
+ "spec/calculators_spec.rb",
45
+ "spec/forums_spec.rb",
46
+ "spec/highscores_spec.rb",
47
+ "spec/player_spec.rb",
48
+ "spec/skill_spec.rb",
49
+ "spec/spec_helper.rb",
50
+ "spec/stat_spec.rb",
51
+ "spec/util_spec.rb"
52
+ ]
53
+ s.homepage = "http://github.com/clooth/partyhat"
54
+ s.licenses = ["MIT"]
55
+ s.require_paths = ["lib"]
56
+ s.rubygems_version = "1.8.10"
57
+ s.summary = "General Runescape Gem"
58
+
59
+ if s.respond_to? :specification_version then
60
+ s.specification_version = 3
61
+
62
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
63
+ s.add_runtime_dependency(%q<curb>, [">= 0"])
64
+ s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
65
+ s.add_development_dependency(%q<rspec>, [">= 0"])
66
+ s.add_development_dependency(%q<bundler>, [">= 0"])
67
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
68
+ s.add_development_dependency(%q<simplecov>, [">= 0"])
69
+ s.add_development_dependency(%q<simplecov-gem-adapter>, [">= 0"])
70
+ else
71
+ s.add_dependency(%q<curb>, [">= 0"])
72
+ s.add_dependency(%q<nokogiri>, [">= 0"])
73
+ s.add_dependency(%q<rspec>, [">= 0"])
74
+ s.add_dependency(%q<bundler>, [">= 0"])
75
+ s.add_dependency(%q<jeweler>, [">= 0"])
76
+ s.add_dependency(%q<simplecov>, [">= 0"])
77
+ s.add_dependency(%q<simplecov-gem-adapter>, [">= 0"])
78
+ end
79
+ else
80
+ s.add_dependency(%q<curb>, [">= 0"])
81
+ s.add_dependency(%q<nokogiri>, [">= 0"])
82
+ s.add_dependency(%q<rspec>, [">= 0"])
83
+ s.add_dependency(%q<bundler>, [">= 0"])
84
+ s.add_dependency(%q<jeweler>, [">= 0"])
85
+ s.add_dependency(%q<simplecov>, [">= 0"])
86
+ s.add_dependency(%q<simplecov-gem-adapter>, [">= 0"])
87
+ end
88
+ end
89
+
@@ -0,0 +1,49 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Partyhat::Activity" do
4
+ before :each do
5
+ @activity = Partyhat::Activity.new(:ba_attackers, 5000, 10)
6
+ @better_activity = Partyhat::Activity.new(:ba_attackers, 59834, 2)
7
+ @unranked_activity = Partyhat::Activity.new(:fist_of_guthix, -1, -1)
8
+ end
9
+
10
+ it "should be initializable" do
11
+ @activity.should be_instance_of(Partyhat::Activity)
12
+ end
13
+
14
+ it "should raise error on invalid skill name" do
15
+ lambda {
16
+ Partyhat::Activity.new(:jingle_bells, 1, 0)
17
+ }.should raise_error
18
+ end
19
+
20
+ it "should have accessible information" do
21
+ @activity.name.should eq(:ba_attackers)
22
+ @activity.human_name.should eq(Partyhat::Stat.human_name_for(@activity.name))
23
+ @activity.score.should_not be_nil
24
+ @activity.rank.should_not be_nil
25
+ end
26
+
27
+ it "should turn negative and/or 0 values into nils" do
28
+ @unranked_activity.score.should eq(nil)
29
+ @unranked_activity.rank.should eq(nil)
30
+ end
31
+
32
+ context "Comparing" do
33
+ it "should be able to compare two activities" do
34
+ @activity.compare_to(@better_activity).should be_instance_of(Partyhat::ActivityComparison)
35
+ end
36
+
37
+ it "should not be possible to compare an activity and a skill" do
38
+ lambda {
39
+ @activity.compare_to(Partyhat::Skill.new(:defence, 5000, 10, 2000))
40
+ }.should raise_error
41
+ end
42
+
43
+ it "should be comparable to other activities" do
44
+ comparison = @activity.compare_to(@better_activity)
45
+ comparison.score.should eq(54834)
46
+ comparison.rank.should eq(-8) # smaller is better
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Partyhat::Calculators" do
4
+ it "should calculate combat" do
5
+ maxed = Partyhat::Calculators.combat({
6
+ :attack => Partyhat::Skill.new(:attack, 99, 99, 99),
7
+ :defence => Partyhat::Skill.new(:defence, 99, 99, 99),
8
+ :strength => Partyhat::Skill.new(:strength, 99, 99, 99),
9
+ :constitution => Partyhat::Skill.new(:constitution, 99, 99, 99),
10
+ :ranged => Partyhat::Skill.new(:ranged, 99, 99, 99),
11
+ :prayer => Partyhat::Skill.new(:prayer, 99, 99, 99),
12
+ :magic => Partyhat::Skill.new(:magic, 99, 99, 99),
13
+ :summoning => Partyhat::Skill.new(:summoning, 99, 99, 99)
14
+ })
15
+
16
+ maxed[:level].to_i.should eq(138)
17
+ end
18
+ end
@@ -0,0 +1,46 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Partyhat::Forums" do
4
+
5
+ before :all do
6
+ @valid_qfc = "13-14-933-63418737"
7
+ @invalid_qfc = "13--14-14-933-63418737"
8
+ end
9
+
10
+ it "should validate quick find codes" do
11
+ Partyhat::Forums.valid_qfc?(@valid_qfc).should eq(true)
12
+ Partyhat::Forums.valid_qfc?(@invalid_qfc).should eq(false)
13
+ end
14
+
15
+ context "Partyhat::Forums::ForumThread" do
16
+ before :all do
17
+ @thread = Partyhat::Forums::ForumThread.new(@valid_qfc)
18
+ end
19
+
20
+ it "should be instantiable with a qfc" do
21
+ @thread.should be_instance_of(Partyhat::Forums::ForumThread)
22
+ end
23
+
24
+ it "should have accessible values" do
25
+ @thread.title.should eq('Behind The Scenes - December')
26
+ @thread.posts.size.should > 0
27
+ @thread.qfc.should eq(@valid_qfc)
28
+ @thread.link.should eq(Partyhat::Forums::ForumThread::URL_FORMAT % @valid_qfc.gsub(/-/, ','))
29
+ end
30
+ end
31
+
32
+ describe "Partyhat::Forums::ForumPost" do
33
+ before :all do
34
+ @thread = Partyhat::Forums::ForumThread.new(@valid_qfc)
35
+ @posts = @thread.posts
36
+ end
37
+
38
+ it "should have the right information" do
39
+ @posts.each do |post|
40
+ post.author.should_not be_nil
41
+ post.posted.should_not be_nil
42
+ post.contents.should_not be_nil
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,10 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Partyhat::Highscores" do
4
+ it "should fetch highscores properly" do
5
+ stats = Partyhat::Highscores.find_player("Not Clooth")
6
+ Partyhat::Stat::List.each do |stat|
7
+ stats.has_key?(stat).should == true
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,22 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Partyhat::Player" do
4
+ before :each do
5
+ @player = Partyhat::Player.new("Not Clooth")
6
+ end
7
+
8
+ it "should should be instantiable with name" do
9
+ @player.should be_instance_of(Partyhat::Player)
10
+ @player.name.should eq("Not Clooth")
11
+ end
12
+
13
+ it "should have stats accessible" do
14
+ Partyhat::Stat::List.each do |stat|
15
+ @player.stats.has_key?(stat).should == true
16
+ end
17
+ end
18
+
19
+ it "should calculate combat correctly" do
20
+ @player.combat[:level].to_i.should == 109
21
+ end
22
+ end
@@ -0,0 +1,52 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Partyhat::Skill" do
4
+ before :each do
5
+ @skill = Partyhat::Skill.new(:attack, 1, 0, 50000)
6
+ @better_skill = Partyhat::Skill.new(:attack, 4, 500, 234)
7
+ @unranked_skill = Partyhat::Skill.new(:dungeoneering, -1, -1, -1)
8
+ end
9
+
10
+ it "should be initializable" do
11
+ @skill.should be_instance_of(Partyhat::Skill)
12
+ end
13
+
14
+ it "should raise error on invalid skill name" do
15
+ lambda {
16
+ Partyhat::Skill.new(:jingle_bells, 1, 0, 49999)
17
+ }.should raise_error
18
+ end
19
+
20
+ it "should have accessible information" do
21
+ @skill.name.should eq(:attack)
22
+ @skill.human_name.should eq(Partyhat::Stat.human_name_for(@skill.name))
23
+ @skill.level.should_not be_nil
24
+ @skill.experience.should_not be_nil
25
+ @skill.rank.should_not be_nil
26
+ end
27
+
28
+ it "should turn negative and/or 0 values into nils" do
29
+ @unranked_skill.level.should eq(nil)
30
+ @unranked_skill.experience.should eq(nil)
31
+ @unranked_skill.rank.should eq(nil)
32
+ end
33
+
34
+ context "Comparing" do
35
+ it "should be able to compare two skills" do
36
+ @skill.compare_to(@better_skill).should be_instance_of(Partyhat::SkillComparison)
37
+ end
38
+
39
+ it "should not be possible to compare a skill and an activity" do
40
+ lambda {
41
+ @skill.compare_to(Partyhat::Activity.new(:ba_attackers, 5000, 10))
42
+ }.should raise_error
43
+ end
44
+
45
+ it "should be comparable to other skills" do
46
+ comparison = @skill.compare_to(@better_skill)
47
+ comparison.level.should eq(3) # Level is better when it's higher
48
+ comparison.experience.should eq(500) # Experience is higher than the first skill
49
+ comparison.rank.should eq(-49766) # Rank should be higher (smaller is better)
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,13 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'simplecov'
4
+ require 'simplecov-gem-adapter'
5
+ SimpleCov.start 'gem'
6
+
7
+ require 'rspec'
8
+ require 'curb'
9
+ require 'partyhat'
10
+
11
+ RSpec.configure do |config|
12
+
13
+ end
@@ -0,0 +1,26 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Partyhat::Stat" do
4
+ it "should have lists of stats" do
5
+ [
6
+ Partyhat::Stat::SkillsList,
7
+ Partyhat::Stat::ActivitiesList,
8
+ Partyhat::Stat::CombatSkillsList,
9
+ Partyhat::Stat::List
10
+ ].each do |property|
11
+ property.should_not be_nil
12
+ end
13
+ end
14
+
15
+ context "Human names" do
16
+ it "should be able to get names for stats" do
17
+ Partyhat::Stat::List.each do |stat|
18
+ Partyhat::Stat.human_name_for(stat).should_not eq('Undefined')
19
+ end
20
+ end
21
+
22
+ it "should gracefully degrade on unknown stat" do
23
+ Partyhat::Stat.human_name_for(:jingle_bells).should eq('Undefined')
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,87 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Partyhat::Util" do
4
+ before :all do
5
+ @sliding_experiences = {
6
+ 2 => 150,
7
+ 34 => 21_000,
8
+ 60 => 280_000,
9
+ 83 => 2_800_000,
10
+ 99 => 13_500_000,
11
+ 115 => 67_000_000,
12
+ 119 => 96_000_000
13
+ }
14
+ @exact_experiences = {
15
+ 29 => 12_031,
16
+ 52 => 123_660,
17
+ 70 => 737_627,
18
+ 98 => 11_805_606
19
+ }
20
+ @numbers_and_shorts = {
21
+ 55_000 => '55.0K',
22
+ 123_500 => '123.5K',
23
+ 5_123_000 => '5.1M',
24
+ 123_100_000 => '123.1M',
25
+ 4_500_000_000 => '4.5B'
26
+ }
27
+ @shorts_and_numbers = {
28
+ '55.0K' => 55_000,
29
+ '55.5K' => 55_500,
30
+ '123.54K' => 123_540,
31
+ '5.123M' => 5_123_000,
32
+ '123.12M' => 123_120_000,
33
+ '4.72B' => 4_720_000_000
34
+ }
35
+ end
36
+
37
+ context "Experience to Level" do
38
+ it "should successfully convert experience to level" do
39
+ @sliding_experiences.each do |key, value|
40
+ converted = Partyhat::Util.experience_to_level(value)
41
+ converted.should eq(key)
42
+ end
43
+ end
44
+
45
+ it "should return a maximum level of 200" do
46
+ Partyhat::Util.experience_to_level(500_000_000_000).should eq(200)
47
+ end
48
+ end
49
+
50
+ context "Level to experience" do
51
+ it "should successfully convert level to experience" do
52
+ @exact_experiences.each do |key, value|
53
+ converted = Partyhat::Util.level_to_experience(key)
54
+ converted.should eq(value)
55
+ end
56
+ end
57
+ end
58
+
59
+ context "Shortening and parsing numbers" do
60
+ it "should be able to shorten a number" do
61
+ @numbers_and_shorts.each do |number, short|
62
+ Partyhat::Util.shorten_number(number).should eq(short)
63
+ end
64
+ end
65
+
66
+ it "should be able to parse a number" do
67
+ @shorts_and_numbers.each do |short, number|
68
+ Partyhat::Util.parse_number(short).should eq(number)
69
+ end
70
+ end
71
+ end
72
+
73
+ context "Fetching remote pages" do
74
+ it "should be able to fetch and return a single page" do
75
+ url = 'http://google.com'
76
+ Partyhat::Util.fetch_remote(url).class.should == String
77
+ end
78
+
79
+ it "should be able to fetch and return multiple pages" do
80
+ urls = ['http://google.com', 'http://microsoft.com']
81
+ pages = Partyhat::Util.fetch_remote(urls)
82
+ pages.class.should == Hash
83
+ pages["http://google.com"].class.should == String
84
+ pages["http://microsoft.com"].class.should == String
85
+ end
86
+ end
87
+ end
metadata ADDED
@@ -0,0 +1,159 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: partyhat
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - clooth
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: curb
16
+ requirement: &70291871068960 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70291871068960
25
+ - !ruby/object:Gem::Dependency
26
+ name: nokogiri
27
+ requirement: &70291871066920 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70291871066920
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &70291871066040 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70291871066040
47
+ - !ruby/object:Gem::Dependency
48
+ name: bundler
49
+ requirement: &70291871064340 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70291871064340
58
+ - !ruby/object:Gem::Dependency
59
+ name: jeweler
60
+ requirement: &70291871079620 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70291871079620
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
71
+ requirement: &70291871078980 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70291871078980
80
+ - !ruby/object:Gem::Dependency
81
+ name: simplecov-gem-adapter
82
+ requirement: &70291871078200 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70291871078200
91
+ description: Versatile runescape gem offering useful tools for runescape-related apps
92
+ email: zenverse@gmail.com
93
+ executables: []
94
+ extensions: []
95
+ extra_rdoc_files:
96
+ - LICENSE.txt
97
+ - README.rdoc
98
+ files:
99
+ - .document
100
+ - .rspec
101
+ - Gemfile
102
+ - Gemfile.lock
103
+ - LICENSE.txt
104
+ - README.rdoc
105
+ - Rakefile
106
+ - VERSION
107
+ - lib/partyhat.rb
108
+ - lib/partyhat/activity.rb
109
+ - lib/partyhat/activity_comparison.rb
110
+ - lib/partyhat/calculators.rb
111
+ - lib/partyhat/calculators/combat.rb
112
+ - lib/partyhat/forums.rb
113
+ - lib/partyhat/forums/forum_post.rb
114
+ - lib/partyhat/forums/forum_thread.rb
115
+ - lib/partyhat/highscores.rb
116
+ - lib/partyhat/player.rb
117
+ - lib/partyhat/skill.rb
118
+ - lib/partyhat/skill_comparison.rb
119
+ - lib/partyhat/stat.rb
120
+ - lib/partyhat/util.rb
121
+ - partyhat.gemspec
122
+ - spec/activity_spec.rb
123
+ - spec/calculators_spec.rb
124
+ - spec/forums_spec.rb
125
+ - spec/highscores_spec.rb
126
+ - spec/player_spec.rb
127
+ - spec/skill_spec.rb
128
+ - spec/spec_helper.rb
129
+ - spec/stat_spec.rb
130
+ - spec/util_spec.rb
131
+ homepage: http://github.com/clooth/partyhat
132
+ licenses:
133
+ - MIT
134
+ post_install_message:
135
+ rdoc_options: []
136
+ require_paths:
137
+ - lib
138
+ required_ruby_version: !ruby/object:Gem::Requirement
139
+ none: false
140
+ requirements:
141
+ - - ! '>='
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ segments:
145
+ - 0
146
+ hash: -1818227121818652947
147
+ required_rubygems_version: !ruby/object:Gem::Requirement
148
+ none: false
149
+ requirements:
150
+ - - ! '>='
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ requirements: []
154
+ rubyforge_project:
155
+ rubygems_version: 1.8.10
156
+ signing_key:
157
+ specification_version: 3
158
+ summary: General Runescape Gem
159
+ test_files: []