elekk 0.1.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -9,7 +9,7 @@ begin
9
9
  s.email = "agnoster@gmail.com"
10
10
  s.homepage = "http://github.com/agnoster/elekk"
11
11
  s.description = "A simple library for World of Warcraft data in Ruby."
12
- s.authors = ["Isaac Wasileski"]
12
+ s.authors = ["Isaac Wolkerstorfer"]
13
13
  s.files = FileList["*", "{lib,spec}/**/*"]
14
14
  s.add_dependency 'typhoeus'
15
15
  s.add_dependency 'memcached'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 1.0.1
@@ -0,0 +1,9 @@
1
+ # elekk v0.1.0
2
+
3
+ * Get Achievements
4
+ * Move JSON/XML well-formedness checks to Elekk::HTTP, so the cache can be busted if the data is bad
5
+
6
+ # elekk v0.0.1
7
+
8
+ * Connect to Armory for basic character information
9
+ * Connect to Wowhead for searches
@@ -5,18 +5,18 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{elekk}
8
- s.version = "0.1.0"
8
+ s.version = "1.0.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Isaac Wasileski"]
12
- s.date = %q{2010-06-05}
11
+ s.authors = ["Isaac Wolkerstorfer"]
12
+ s.date = %q{2010-07-25}
13
13
  s.description = %q{A simple library for World of Warcraft data in Ruby.}
14
14
  s.email = %q{agnoster@gmail.com}
15
15
  s.files = [
16
- "CHANGELOG",
17
- "Manifest",
16
+ "Manifest",
18
17
  "Rakefile",
19
18
  "VERSION",
19
+ "changelog.md",
20
20
  "elekk.gemspec",
21
21
  "lib/elekk.rb",
22
22
  "lib/elekk/achievement.rb",
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
30
30
  "spec/armory_spec.rb",
31
31
  "spec/character_spec.rb",
32
32
  "spec/klass_spec.rb",
33
+ "spec/test.rb",
33
34
  "spec/wowhead_spec.rb"
34
35
  ]
35
36
  s.homepage = %q{http://github.com/agnoster/elekk}
@@ -42,6 +43,7 @@ Gem::Specification.new do |s|
42
43
  "spec/armory_spec.rb",
43
44
  "spec/character_spec.rb",
44
45
  "spec/klass_spec.rb",
46
+ "spec/test.rb",
45
47
  "spec/wowhead_spec.rb"
46
48
  ]
47
49
 
@@ -8,7 +8,7 @@ module Elekk
8
8
  @points = opts[:points]
9
9
  @icon = opts[:icon]
10
10
  @description = opts[:description]
11
- @category = opts[:category]
11
+ @category = AchievementCategory[opts[:category]]
12
12
  @completed = opts[:completed]
13
13
  end
14
14
 
@@ -18,7 +18,7 @@ module Elekk
18
18
  :points => node['points'].to_i,
19
19
  :icon => node['icon'].to_s,
20
20
  :description => node['description'].to_s,
21
- :category => Achievements[node['categoryId'].to_i]
21
+ :category => node['categoryId'].to_i
22
22
  })
23
23
  a.completed = Time.parse(node['dateCompleted'].to_s) if node['dateCompleted']
24
24
  a
@@ -33,7 +33,19 @@ module Elekk
33
33
  end
34
34
  end
35
35
 
36
- class Achievements < Enum
37
- add_item 'Raid', 168
36
+ class AchievementCategory < Enum
37
+ add_item 'General', 92
38
+ add_item 'Quests', 96
39
+ add_item 'Exploration', 97
40
+ add_item 'Player vs. Player', 95
41
+ add_item 'Dungeons & Raids', 168
42
+ add_item 'Professions', 169
43
+ add_item 'Reputation', 201
44
+ add_item 'World Events', 155
45
+ add_item 'Feats of Strength', 81
46
+
47
+ add_obj AchievementCategory::DungeonsRaids, :Raid
48
+ add_obj AchievementCategory::PlayervsPlayer, :PvP
49
+ add_obj AchievementCategory::Reputation, :Rep
38
50
  end
39
51
  end
@@ -26,18 +26,99 @@ module Elekk
26
26
  end
27
27
 
28
28
  def get_xml(resource, params=nil)
29
- response = HTTP.xml(url(resource+'.xml'), params, {
29
+ resource+= '.xml' unless resource =~ /\./
30
+ response = HTTP.xml(url(resource), params, {
30
31
  :cache_timeout => 24*3600,
31
32
  :user_agent => 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9'
32
33
  })
33
34
  end
34
35
 
36
+ def get_feed(characters, realm=nil)
37
+ characters = [characters] unless characters.is_a? Array
38
+ feed_xml = get_xml 'character-feed.atom', :r => (realm || @realm), :cn => characters.sort.join(',')
39
+ feed = feed_xml.css('entry').collect do |c|
40
+ item = { :title => c.at_css('title').content,
41
+ :id => c.at_css('id').content,
42
+ :link => c.at_css('link').content,
43
+ :time => Time.parse(c.at_css('published').content),
44
+ :content => c.at_css('content').content
45
+ }
46
+ item[:character] = $1 if item[:title] =~ /(\w+)/
47
+ if item[:title] =~ /\[((.*)\s+\w+\s*\(([^(]+)\))\]\s+\d+\s+times/
48
+ item[:collator] = $1
49
+ item[:boss] = $2
50
+ item[:instance] = $3
51
+ item[:type] = :boss
52
+ end
53
+ if item[:content] =~ /<a href=.*#ach(\d+)">([^<]*)<\/a>/
54
+ item[:achievement_id] = $1
55
+ item[:achievement_name] = $2
56
+ item[:collator] = $2
57
+ if item[:title] =~ /step \[([^\]]*)\]/
58
+ item[:type] = :step
59
+ item[:collator] = item[:achievement_name] + " - " + $1
60
+ item[:step] = $1
61
+ else
62
+ item[:type] = :achievement
63
+ end
64
+ end
65
+ if item[:content] =~ /item-info\.xml\?i=(\d+).*\[(.*)\]/
66
+ item[:item_id] = $1
67
+ item[:item_name] = $2
68
+ item[:collator] = $2
69
+ item[:type] = :item
70
+ end
71
+ item[:coll_id] = [item[:type], item[:collator], item[:time]].hash
72
+ item
73
+ end
74
+ end
75
+
76
+ def get_feeds(characters, realm=nil)
77
+ # split characters into least set of batches of no more than 5,
78
+ # no less than 2
79
+
80
+ batches = characters.sort / 5
81
+ if batches.last.length < 2
82
+ batches.last.unshift batches[batches.length - 2].pop
83
+ end
84
+
85
+ feeds = []
86
+ batches.collect {|chars|
87
+ feeds += get_feed chars, realm
88
+ }
89
+ feeds.sort {|a,b| b[:time] <=> a[:time]}
90
+ end
91
+
92
+ def collate_feeds(feeds)
93
+ coll = {}
94
+ feeds.each do |e|
95
+ coll[e[:coll_id]] ||= e
96
+ coll[e[:coll_id]] << e
97
+ end
98
+ coll
99
+ end
100
+
101
+ def search(query, type=:all)
102
+ xml = get_xml('search', :searchQuery => query, :searchType => type.to_s)
103
+ end
104
+
35
105
  def self.icon_url(icon)
36
- "http://us.wowarmory.com/wow-icons/_images/51x51/#{icon}.jpg"
106
+ url "wow-icons/_images/51x51/#{icon}.jpg"
37
107
  end
38
108
 
39
109
  def url(path)
40
110
  base + path
41
111
  end
42
112
  end
43
- end
113
+ end
114
+
115
+ class Array
116
+ def / len
117
+ a = []
118
+ each_with_index do |x,i|
119
+ a << [] if i % len == 0
120
+ a.last << x
121
+ end
122
+ a
123
+ end
124
+ end
@@ -21,6 +21,7 @@ module Elekk
21
21
  end
22
22
 
23
23
  def achievements(category)
24
+ category = AchievementCategory[category]
24
25
  @achievements ||= {}
25
26
  @achievements[category.to_sym] ||=
26
27
  xml(:achievements, :c => category.to_i).css('achievement').map {|x| Achievement.from_xml x}
@@ -56,6 +57,10 @@ module Elekk
56
57
  @properties[:points] ||= sheet.at_css('character')['points'].to_i
57
58
  end
58
59
 
60
+ def feed
61
+ self.armory.get_feed @name, @realm
62
+ end
63
+
59
64
  def spec(which)
60
65
  if not @properties[:specs]
61
66
  specs = {}
@@ -74,7 +79,7 @@ module Elekk
74
79
  type = 'default'
75
80
  [60, 70, 80].each { |m| type = m if level >= m }
76
81
 
77
- @armory.url "_images/portraits/wow-#{type}/#{gender.id}-#{race.id}-#{klass.id}.gif"
82
+ self.armory.url "_images/portraits/wow-#{type}/#{gender.id}-#{race.id}-#{klass.id}.gif"
78
83
  end
79
84
 
80
85
  def fullname(tag=nil)
@@ -22,21 +22,32 @@ module Elekk
22
22
  @hash[idx.gsub(/\W/,'').to_sym]
23
23
  elsif idx.is_a? Symbol
24
24
  @hash[idx]
25
+ elsif idx.is_a? Enum
26
+ idx
25
27
  else
26
28
  nil
27
29
  end
28
30
  end
29
31
 
30
32
  def self.add_item(name, id=nil?)
31
- @hash ||= {}
32
33
  @array ||= []
33
34
  id ||= @array.length
34
- if name.nil?
35
- @array[id] = nil
35
+ obj = name ? self.new(name, id) : nil
36
+ add_obj obj, nil, id
37
+ end
38
+
39
+ def self.add_obj(obj, sym=nil, id=nil)
40
+ @hash ||= {}
41
+ @array ||= []
42
+ if obj and @hash[obj.to_sym]
43
+ # creating an alias
44
+ @hash[sym] = obj if sym
45
+ @array[id] = obj if id
36
46
  else
37
- k = self.new(name,id)
38
- @array[id] = k
39
- @hash[k.to_sym] = k
47
+ # adding for the first time
48
+ @hash[obj.to_sym] = obj if obj
49
+ id ||= @array.length
50
+ @array[id] = obj
40
51
  end
41
52
  end
42
53
 
data/readme.md CHANGED
@@ -2,7 +2,61 @@ Elekk
2
2
  =====
3
3
  [Elekk][1] is a Ruby library for World of Warcraft data.
4
4
 
5
- It does not do very much right now.
5
+ Goals:
6
6
 
7
+ * Make querying information as natural and simple as possible
8
+ * Have native representations of every data type
9
+ * Reflect actual identifiers/schemes as closely as possible
7
10
 
8
- [1]: http://github.com/agnoster/elekk "Elekk on github"
11
+ Here is what you can do with it currently:
12
+
13
+ * Get basic character information from the Armory
14
+ * Class
15
+ * Level
16
+ * Faction
17
+ * Race
18
+ * Gender
19
+ * Achievement Points
20
+ * Title
21
+ * Armory portrait
22
+ * Search on Wowhead with a simple text query and get
23
+ * Internal identifiers for results
24
+ * Links back to Wowhead
25
+ * Icons (when available)
26
+ * Quality (for items)
27
+ * Query achievements
28
+ * Get internal identifiers, icons, title and description
29
+ * Get the date the character completed the achievement
30
+ * Should support all categories now
31
+
32
+ To see how all this is done, it's probably best to check the [`spec/`][2] directory, which has exhaustive examples of how to use nearly all the APIs, and is likely to be kept more up-to-date than this readme.
33
+
34
+ Example:
35
+
36
+ >> a = Armory.new 'Uldaman', :us
37
+ => #<Elekk::Armory:0x10168cf20 @region=:us, @realm="Uldaman">
38
+ >> fyrbard = a.character 'Fyrbard'
39
+ => #<Elekk::Character:0x101687818 @name="Fyrbard", @properties={:realm=>"Uldaman", :region=>:us, :name=>"Fyrbard"}, @armory=#<Elekk::Armory:0x10168cf20 @region=:us, @realm="Uldaman">, @region=:us, @realm="Uldaman">
40
+ >> puts fyrbard.race, fyrbard.race.to_i; fyrbard.race.to_sym
41
+ Dwarf
42
+ 3
43
+ => :Dwarf
44
+ >> fyrbard.level
45
+ => 80
46
+ >> fyrbard.points
47
+ => 4505
48
+ >> bitten = fyrbard.achievements(Achievements::Raid).find {|a| a.title =~ /once bitten/i}
49
+ => #<Elekk::Achievement:0x1013e1aa0 @category=#<Elekk::Achievements:0x1016a6308 @name="Raid", @symbol=:Raid, @id=168>, @points=10, @description="", @id=4539, @time=Wed May 19 08:34:00 +0200 2010, @title="Once Bitten, Twice Shy (10 player)", @icon="achievement_boss_lanathel">
50
+ >> (Time.now - bitten.completed) / (3600*24)
51
+ => 17.1609193367708
52
+ >> bitten.wowhead.icon_url(:large)
53
+ => "http://static.wowhead.com/images/wow/icons/large/achievement_boss_lanathel.jpg"
54
+ >> results = Wowhead.search 'once bitten'
55
+ => [#<Elekk::Wowhead::Result:0x101298108 @name="Once Bitten, Twice Shy (10 player)", @id=4539, @kind=#<Elekk::Kind:0x10141eea0 @name="Achievement", @symbol=:Achievement, @id=10>, @icon="achievement_boss_lanathel">, #<Elekk::Wowhead::Result:0x101297460 @name="Once Bitten, Twice Shy (25 player)", @id=4618, @kind=#<Elekk::Kind:0x10141eea0 @name="Achievement", @symbol=:Achievement, @id=10>, @icon="achievement_boss_lanathel">]
56
+ >> results.first.id == bitten.id
57
+ => true
58
+ >> results.first.to_html
59
+ => "<a href='http://www.wowhead.com/achievement=4539'>Once Bitten, Twice Shy (10 player)</a>"
60
+
61
+ [1]: http://github.com/agnoster/elekk "Elekk on github"
62
+ [2]: http://github.com/agnoster/elekk/tree/master/spec/ "Elekk specs on github"
@@ -3,14 +3,14 @@ include Elekk
3
3
 
4
4
  describe Achievement do
5
5
  before :each do
6
- @achievements = Character.new('Fyrbard','Uldaman').achievements(Achievements::Raid)
6
+ @achievements = Character.new('Fyrbard','Uldaman').achievements(:Raid)
7
7
  @oncebitten = @achievements.find {|a| a.id == 4539 }
8
- @bane = @achievements.find {|a| a.id == 4608 }
8
+ @lk25 = @achievements.find {|a| a.id == 4608 }
9
9
  end
10
10
 
11
11
  it "should give a list of achievements" do
12
12
  @oncebitten.should_not be_nil
13
- @bane.should_not be_nil
13
+ @lk25.should_not be_nil
14
14
  end
15
15
 
16
16
  it "should have the correct title" do
@@ -22,7 +22,7 @@ describe Achievement do
22
22
  end
23
23
 
24
24
  it "should have the correct category" do
25
- @oncebitten.category.should == Achievements::Raid
25
+ @oncebitten.category.to_s.should == "Dungeons & Raids"
26
26
  end
27
27
 
28
28
  it "should have the correct point total as an integer" do
@@ -31,24 +31,18 @@ describe Achievement do
31
31
 
32
32
  it "should have the correct time of completion" do
33
33
  @oncebitten.completed.to_i.should == 1274250840
34
- @bane.completed.should be_nil
34
+ @lk25.completed.should be_nil
35
35
  end
36
36
 
37
37
  it "should show correct completion state" do
38
38
  @oncebitten.complete?.should == true
39
- @bane.complete?.should == false
39
+ @lk25.complete?.should == false
40
40
  end
41
41
 
42
42
  it "should get the correct information to display on wowhead" do
43
43
  @oncebitten.wowhead.url.should == 'http://www.wowhead.com/achievement=4539'
44
44
  @oncebitten.wowhead.icon_url(:large).should == 'http://static.wowhead.com/images/wow/icons/large/achievement_boss_lanathel.jpg'
45
45
  end
46
-
47
- it "should look bitchin when I print them all" do
48
- @achievements.select {|a| a.complete?}.sort_by {|a| -a.completed.to_i}.each do |a|
49
- puts "<a href=\"#{a.wowhead.url}\"><img src=\"#{Armory.icon_url(a.icon)}\" /> <img src=\"#{a.wowhead.icon_url(:large)}\" /> #{a.title}</a><br />"
50
- end
51
- end
52
46
  end
53
47
 
54
48
 
@@ -36,9 +36,18 @@ describe Armory do
36
36
  @armory.url('character-sheet.xml').should == 'http://us.wowarmory.com/character-sheet.xml';
37
37
  end
38
38
 
39
- it "should get xml from the armory" do
39
+ it "should get XML from the armory" do
40
40
  xml = @armory.get_xml 'character-sheet', :r => 'Uldaman', :cn => 'Fyrbard'
41
41
  xml.should_not be_nil
42
42
  end
43
43
 
44
+ it "should get XML from armory with custom extensions" do
45
+ xml = @armory.get_xml 'character-feed.atom', :r => 'Uldaman', :cn => 'Fyrbard'
46
+ xml.should_not be_nil
47
+ end
48
+
49
+ it "should get a multi-character feed" do
50
+ feed = @armory.get_feed ['Aldea', 'Alassiel', 'Puya', 'Ultimohombre', 'Fyrbard']
51
+ end
52
+
44
53
  end
@@ -76,10 +76,10 @@ describe Character do
76
76
  end
77
77
 
78
78
  it "should have the right title" do
79
- @fyrbard.fullname.should == 'Fyrbard Jenkins'
79
+ @fyrbard.fullname.should == 'Fyrbard of the Ashen Verdict'
80
80
  @aldea.fullname.should == 'Aldea of the Nightfall'
81
81
  @aldea.fullname(:strong).should == '<strong>Aldea</strong> of the Nightfall'
82
- @fyrbard.fullname('').should == 'Fyrbard Jenkins'
82
+ @fyrbard.fullname('').should == 'Fyrbard of the Ashen Verdict'
83
83
  @armory.character('Bitterleaf').fullname('strong').should == 'Loremaster <strong>Bitterleaf</strong>'
84
84
  end
85
85
 
@@ -88,5 +88,10 @@ describe Character do
88
88
  @aldea.portrait.should == 'http://us.wowarmory.com/_images/portraits/wow-80/1-1-1.gif';
89
89
  @armory.character('Harimad').portrait.should == 'http://us.wowarmory.com/_images/portraits/wow-default/1-3-1.gif';
90
90
  end
91
+
92
+ it "should have a valid RSS feed" do
93
+ feed = @fyrbard.feed
94
+ feed.should_not be_nil
95
+ end
91
96
 
92
97
  end
@@ -0,0 +1,7 @@
1
+ require '../lib/elekk.rb'
2
+
3
+ @armory = Elekk::Armory.new 'Uldaman'
4
+ @feeds = @armory.get_feeds ['Fyrbard', 'Aldea', 'Alassiel', 'Ultimohombre', 'Puya', 'Wulffe', 'Silinix', 'Katalia', 'Hdarkone', 'Gleanna', 'Stormrazor', 'Gracasta']
5
+ @collated = @armory.collate_feeds @feeds
6
+
7
+ @collated.each { |k,v| puts v.first[:title]; v.each {|e| puts e[:character]}; puts }
@@ -1,7 +1,7 @@
1
1
  require 'elekk'
2
2
  include Elekk
3
3
 
4
- describe Wowhead do
4
+ describe Wowhead, '#search' do
5
5
  before :each do
6
6
  @q = Wowhead.search 'Varian'
7
7
  end
metadata CHANGED
@@ -1,21 +1,21 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elekk
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 21
5
5
  prerelease: false
6
6
  segments:
7
- - 0
8
7
  - 1
9
8
  - 0
10
- version: 0.1.0
9
+ - 1
10
+ version: 1.0.1
11
11
  platform: ruby
12
12
  authors:
13
- - Isaac Wasileski
13
+ - Isaac Wolkerstorfer
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-06-05 00:00:00 +02:00
18
+ date: 2010-07-25 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -83,10 +83,10 @@ extensions: []
83
83
  extra_rdoc_files: []
84
84
 
85
85
  files:
86
- - CHANGELOG
87
86
  - Manifest
88
87
  - Rakefile
89
88
  - VERSION
89
+ - changelog.md
90
90
  - elekk.gemspec
91
91
  - lib/elekk.rb
92
92
  - lib/elekk/achievement.rb
@@ -100,6 +100,7 @@ files:
100
100
  - spec/armory_spec.rb
101
101
  - spec/character_spec.rb
102
102
  - spec/klass_spec.rb
103
+ - spec/test.rb
103
104
  - spec/wowhead_spec.rb
104
105
  has_rdoc: true
105
106
  homepage: http://github.com/agnoster/elekk
@@ -140,4 +141,5 @@ test_files:
140
141
  - spec/armory_spec.rb
141
142
  - spec/character_spec.rb
142
143
  - spec/klass_spec.rb
144
+ - spec/test.rb
143
145
  - spec/wowhead_spec.rb
data/CHANGELOG DELETED
@@ -1,7 +0,0 @@
1
- v0.1.0
2
- -- Get Achievements
3
- --
4
-
5
- v0.0.1
6
- -- Connect to Armory for basic character information
7
- -- Connect to Wowhead for searches