confuddle 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/.gitignore +18 -0
  2. data/.passwd_to_unfuddle.example.yml +7 -0
  3. data/README.md +40 -0
  4. data/bin/un +833 -0
  5. data/bin/un.cmd +1 -0
  6. data/confuddle.gemspec +22 -0
  7. data/lib/graft/README.rdoc +138 -0
  8. data/lib/graft/Rakefile +43 -0
  9. data/lib/graft/lib/graft/core_ext/hash.rb +9 -0
  10. data/lib/graft/lib/graft/json.rb +14 -0
  11. data/lib/graft/lib/graft/json/attribute.rb +18 -0
  12. data/lib/graft/lib/graft/json/model.rb +28 -0
  13. data/lib/graft/lib/graft/model.rb +43 -0
  14. data/lib/graft/lib/graft/version.rb +13 -0
  15. data/lib/graft/lib/graft/xml.rb +19 -0
  16. data/lib/graft/lib/graft/xml/attribute.rb +55 -0
  17. data/lib/graft/lib/graft/xml/model.rb +49 -0
  18. data/lib/graft/lib/graft/xml/type.rb +91 -0
  19. data/lib/graft/test/test_helper.rb +38 -0
  20. data/lib/graft/test/unit/core_ext/hash_test.rb +29 -0
  21. data/lib/graft/test/unit/json/attribute_test.rb +51 -0
  22. data/lib/graft/test/unit/json/model_test.rb +86 -0
  23. data/lib/graft/test/unit/xml/attribute_test.rb +161 -0
  24. data/lib/graft/test/unit/xml/model_test.rb +173 -0
  25. data/lib/graft/test/unit/xml/type_test.rb +65 -0
  26. data/lib/unfuzzle/.gitignore +4 -0
  27. data/lib/unfuzzle/README.rdoc +129 -0
  28. data/lib/unfuzzle/Rakefile +39 -0
  29. data/lib/unfuzzle/lib/unfuzzle.rb +87 -0
  30. data/lib/unfuzzle/lib/unfuzzle/comment.rb +37 -0
  31. data/lib/unfuzzle/lib/unfuzzle/component.rb +31 -0
  32. data/lib/unfuzzle/lib/unfuzzle/milestone.rb +54 -0
  33. data/lib/unfuzzle/lib/unfuzzle/person.rb +20 -0
  34. data/lib/unfuzzle/lib/unfuzzle/priority.rb +30 -0
  35. data/lib/unfuzzle/lib/unfuzzle/project.rb +62 -0
  36. data/lib/unfuzzle/lib/unfuzzle/request.rb +75 -0
  37. data/lib/unfuzzle/lib/unfuzzle/response.rb +25 -0
  38. data/lib/unfuzzle/lib/unfuzzle/severity.rb +31 -0
  39. data/lib/unfuzzle/lib/unfuzzle/ticket.rb +156 -0
  40. data/lib/unfuzzle/lib/unfuzzle/ticket_report.rb +29 -0
  41. data/lib/unfuzzle/lib/unfuzzle/time_entry.rb +75 -0
  42. data/lib/unfuzzle/lib/unfuzzle/version.rb +13 -0
  43. data/lib/unfuzzle/test/fixtures/component.xml +8 -0
  44. data/lib/unfuzzle/test/fixtures/components.xml +17 -0
  45. data/lib/unfuzzle/test/fixtures/milestone.xml +12 -0
  46. data/lib/unfuzzle/test/fixtures/milestones.xml +25 -0
  47. data/lib/unfuzzle/test/fixtures/project.xml +17 -0
  48. data/lib/unfuzzle/test/fixtures/projects.xml +35 -0
  49. data/lib/unfuzzle/test/fixtures/severities.xml +24 -0
  50. data/lib/unfuzzle/test/fixtures/severity.xml +8 -0
  51. data/lib/unfuzzle/test/fixtures/ticket.xml +25 -0
  52. data/lib/unfuzzle/test/fixtures/tickets.xml +51 -0
  53. data/lib/unfuzzle/test/test_helper.rb +60 -0
  54. data/lib/unfuzzle/test/unit/unfuzzle/component_test.rb +36 -0
  55. data/lib/unfuzzle/test/unit/unfuzzle/milestone_test.rb +100 -0
  56. data/lib/unfuzzle/test/unit/unfuzzle/priority_test.rb +25 -0
  57. data/lib/unfuzzle/test/unit/unfuzzle/project_test.rb +87 -0
  58. data/lib/unfuzzle/test/unit/unfuzzle/request_test.rb +104 -0
  59. data/lib/unfuzzle/test/unit/unfuzzle/response_test.rb +37 -0
  60. data/lib/unfuzzle/test/unit/unfuzzle/severity_test.rb +36 -0
  61. data/lib/unfuzzle/test/unit/unfuzzle/ticket_test.rb +181 -0
  62. data/lib/unfuzzle/test/unit/unfuzzle_test.rb +39 -0
  63. data/lib/unfuzzle/unfuzzle.gemspec +31 -0
  64. data/lib/version.rb +3 -0
  65. metadata +176 -0
@@ -0,0 +1 @@
1
+ "ruby.exe" "%~dpn0" %*
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.dirname(__FILE__) + "/lib/version"
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = %q{confuddle}
6
+ s.version = Un::VERSION
7
+ s.authors = ["Makarchev Konstantin"]
8
+ s.description = %q{Utility for work with unfuddle.com account from console}
9
+ s.summary = %q{Utility for work with unfuddle.com account from console}
10
+
11
+ s.email = %q{kostya27@gmail.com}
12
+ s.homepage = %q{http://github.com/kostya/confuddle}
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+
18
+ s.add_dependency 'activesupport', ">=2.3.2"
19
+ s.add_dependency 'thor', ">=0.14.3"
20
+ s.add_dependency 'hpricot'
21
+
22
+ end
@@ -0,0 +1,138 @@
1
+ = Graft
2
+
3
+ == Description
4
+
5
+ Graft provides an easy way to map XML and JSON data onto your Ruby classes.
6
+
7
+ == Installation
8
+
9
+ Stable:
10
+
11
+ $ sudo gem install graft
12
+
13
+ Bleeding edge:
14
+
15
+ $ git clone git://github.com/reagent/graft.git
16
+ $ cd graft && rake gem
17
+ $ sudo gem install pkg/graft-<version>.gem
18
+
19
+ == Usage
20
+
21
+ When interacting with APIs, it's quite often the case that the data returned as
22
+ part of the response is represented either as XML or JSON. The Graft library makes
23
+ turning that data into Ruby objects pretty simple. This code was an extraction from
24
+ my work on both the Fleakr[http://reagent.github.com/fleakr] and
25
+ Etsy[http://github.com/reagent/etsy] gems.
26
+
27
+ === Mapping XML
28
+
29
+ If you want to use Graft in XML mode, you'll need to include the right library:
30
+
31
+ require 'rubygems'
32
+ require 'graft/xml'
33
+
34
+ Once that is set up, you can take an XML string like this:
35
+
36
+ <rsp>
37
+ <user nsid="3">reagent</user>
38
+ <name>Patrick Reagan</name>
39
+ </rsp>
40
+
41
+ And map it onto a Ruby class:
42
+
43
+ class User
44
+ include Graft
45
+
46
+ attribute :name
47
+ attribute :username, :from => 'user'
48
+ attribute :id, :from => 'user@nsid', :type => :integer
49
+ end
50
+
51
+ There are a couple of ways to pull this data into the +User+ object. The simplest
52
+ is from the constructor:
53
+
54
+ user = User.new(xml)
55
+
56
+ There is also a +populate_from+ instance method that will do the same:
57
+
58
+ user = User.new
59
+ user.populate_from(xml)
60
+
61
+ This second method is useful if the data you want in your Ruby object comes from 2
62
+ separate XML files. Accessing it is simple:
63
+
64
+ >> user.name # => "Patrick Reagan"
65
+ >> user.username # => "reagent"
66
+ >> user.id # => 3
67
+
68
+ === Mapping JSON
69
+
70
+ The process of mapping JSON is similar to XML, except:
71
+
72
+ * You don't need to declare the type of the attribute
73
+ * You need to provide a full path to the JSON value
74
+
75
+ To get started, include the correct library:
76
+
77
+ require 'rubygems'
78
+ require 'graft/json'
79
+
80
+ Then for simple JSON data:
81
+
82
+ {
83
+ "rsp": {
84
+ "user_id": 3,
85
+ "username": "reagent",
86
+ "name": "Patrick Reagan"
87
+ }
88
+ }
89
+
90
+ You can map it in a similar way:
91
+
92
+ class User
93
+ include Graft
94
+
95
+ attribute :name, :from => 'rsp/name'
96
+ attribute :username, :from => 'rsp/username'
97
+ attribute :id, :from => 'rsp/user_id'
98
+ end
99
+
100
+ Again, you can initialize the values from both the constructor:
101
+
102
+ user = User.new(json)
103
+
104
+ Or the +populate_from+ method:
105
+
106
+ user = User.new
107
+ user.populate_from(json)
108
+
109
+ The results are the same:
110
+
111
+ >> user.name # => "Patrick Reagan"
112
+ >> user.username # => "reagent"
113
+ >> user.id # => 3
114
+
115
+ == License
116
+
117
+ Copyright (c) 2009 Patrick Reagan (reaganpr@gmail.com)
118
+
119
+ Permission is hereby granted, free of charge, to any person
120
+ obtaining a copy of this software and associated documentation
121
+ files (the "Software"), to deal in the Software without
122
+ restriction, including without limitation the rights to use,
123
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
124
+ copies of the Software, and to permit persons to whom the
125
+ Software is furnished to do so, subject to the following
126
+ conditions:
127
+
128
+ The above copyright notice and this permission notice shall be
129
+ included in all copies or substantial portions of the Software.
130
+
131
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
132
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
133
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
134
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
135
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
136
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
137
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
138
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,43 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'rake/testtask'
4
+
5
+ require 'lib/graft/version'
6
+
7
+ task :default => :test
8
+
9
+ spec = Gem::Specification.new do |s|
10
+ s.name = 'graft'
11
+ s.version = Graft::Version.to_s
12
+ s.has_rdoc = true
13
+ s.extra_rdoc_files = %w(README.rdoc)
14
+ s.rdoc_options = %w(--main README.rdoc)
15
+ s.summary = "Graft provides an easy way to map XML and JSON data onto your Ruby classes"
16
+ s.author = 'Patrick Reagan'
17
+ s.email = 'reaganpr@gmail.com'
18
+ s.homepage = 'http://sneaq.net/'
19
+ s.files = %w(README.rdoc Rakefile) + Dir.glob("{lib,test}/**/*")
20
+
21
+ s.add_dependency('hpricot', '>= 0.6.164')
22
+ s.add_dependency('tzinfo', '>= 0.3.12')
23
+ s.add_dependency('builder', '>= 2.1.2')
24
+ s.add_dependency('activesupport', '>= 2.0')
25
+ s.add_dependency('json', '>= 1.1.7')
26
+ end
27
+
28
+ Rake::GemPackageTask.new(spec) do |pkg|
29
+ pkg.gem_spec = spec
30
+ end
31
+
32
+ Rake::TestTask.new do |t|
33
+ t.libs << 'test'
34
+ t.test_files = FileList["test/**/*_test.rb"]
35
+ t.verbose = true
36
+ end
37
+
38
+ desc 'Generate the gemspec to serve this Gem from Github'
39
+ task :github do
40
+ file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
41
+ File.open(file, 'w') {|f| f << spec.to_ruby }
42
+ puts "Created gemspec: #{file}"
43
+ end
@@ -0,0 +1,9 @@
1
+ class Hash
2
+
3
+ def /(path)
4
+ path.to_s.split('/').inject(self) do |data, key|
5
+ (data.is_a?(Hash) && data[key]) ? data[key] : nil
6
+ end
7
+ end
8
+
9
+ end
@@ -0,0 +1,14 @@
1
+ $:.unshift File.dirname(__FILE__) + '/..'
2
+
3
+ require 'json'
4
+ require 'graft/core_ext/hash'
5
+
6
+ require 'graft/model'
7
+ require 'graft/json/attribute'
8
+ require 'graft/json/model'
9
+
10
+ module Graft
11
+ def self.included(other)
12
+ other.send(:include, Graft::Json::Model)
13
+ end
14
+ end
@@ -0,0 +1,18 @@
1
+ module Graft
2
+ module Json
3
+ class Attribute
4
+
5
+ attr_reader :name, :source
6
+
7
+ def initialize(name, source = nil)
8
+ @name = name
9
+ @source = source.nil? ? @name.to_s : source
10
+ end
11
+
12
+ def value_from(data)
13
+ data/source
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,28 @@
1
+ module Graft
2
+ module Json
3
+ module Model
4
+
5
+ module ClassMethods
6
+
7
+ def attribute(name, options = {})
8
+ source = options[:from]
9
+
10
+ self.attributes << Graft::Json::Attribute.new(name, source)
11
+ class_eval "attr_accessor :#{name}"
12
+ end
13
+
14
+ def data_from(json_or_hash)
15
+ json_or_hash.is_a?(String) ? JSON.parse(json_or_hash) : json_or_hash
16
+ end
17
+
18
+ end
19
+
20
+ def self.included(other)
21
+ other.send(:extend, Graft::Model::ClassMethods)
22
+ other.send(:extend, Graft::Json::Model::ClassMethods)
23
+ other.send(:include, Graft::Model::InstanceMethods)
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,43 @@
1
+ module Graft
2
+ module Model
3
+
4
+ module ClassMethods
5
+ def attributes
6
+ @attributes ||= []
7
+ end
8
+
9
+ def collection_from(data_source, node)
10
+ (data_from(data_source)/node).map {|n| new n }
11
+ end
12
+
13
+ def collection_from_block(data_source, node, &block)
14
+ (data_from(data_source)/node).map{|n| yield(n) }
15
+ end
16
+ end
17
+
18
+ module InstanceMethods
19
+
20
+ def initialize(source_data = nil)
21
+ self.source_data = source_data
22
+ self.populate_from(self.source_data) unless self.source_data.nil?
23
+ end
24
+
25
+ def source_data=(source_data)
26
+ @source_data = self.class.data_from(source_data)
27
+ end
28
+
29
+ def source_data
30
+ @source_data
31
+ end
32
+
33
+ def populate_from(data_source)
34
+ self.class.attributes.each do |attribute|
35
+ value = attribute.value_from(self.class.data_from(data_source))
36
+ self.send("#{attribute.name}=".to_sym, value) unless value.nil?
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,13 @@
1
+ module Graft
2
+ module Version
3
+
4
+ MAJOR = 0
5
+ MINOR = 2
6
+ TINY = 1
7
+
8
+ def self.to_s # :nodoc:
9
+ [MAJOR, MINOR, TINY].join('.')
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ $:.unshift File.dirname(__FILE__) + '/..'
2
+
3
+ require 'hpricot'
4
+ require 'builder'
5
+ require 'tzinfo'
6
+
7
+ require 'active_support/time_with_zone'
8
+ require 'active_support/inflector'
9
+
10
+ require 'graft/model'
11
+ require 'graft/xml/type'
12
+ require 'graft/xml/attribute'
13
+ require 'graft/xml/model'
14
+
15
+ module Graft
16
+ def self.included(other)
17
+ other.send(:include, Graft::Xml::Model)
18
+ end
19
+ end
@@ -0,0 +1,55 @@
1
+ module Graft
2
+ module Xml
3
+ class Attribute
4
+
5
+ # TODO: Refactor the location / attribute logic into a Source class
6
+
7
+ attr_reader :name, :sources
8
+
9
+ def initialize(name, type = :string, sources = nil)
10
+ @name = name.to_sym
11
+ @type = type
12
+
13
+ @sources = Array(sources)
14
+ @sources << @name.to_s if @sources.empty?
15
+ end
16
+
17
+ def type_class
18
+ "Graft::Xml::Type::#{@type.to_s.camelize}".constantize
19
+ end
20
+
21
+ def split(source)
22
+ location, attribute = source.split('@')
23
+ location = self.name.to_s if location.blank?
24
+
25
+ [location, attribute]
26
+ end
27
+
28
+ def node_for(document, source)
29
+ document.at(location(source)) || document.search("//[@#{attribute(source)}]").first
30
+ end
31
+
32
+ def attribute(source)
33
+ location, attribute = source.split('@')
34
+ attribute || location
35
+ end
36
+
37
+ def location(source)
38
+ split(source).first
39
+ end
40
+
41
+ def value_from(document)
42
+ values = sources.map do |source|
43
+ node = node_for(document, source)
44
+ if !node.nil?
45
+ possible_values = [node.attributes[attribute(source)], node.inner_text]
46
+ possible_values.detect {|value| !value.blank? }
47
+ end
48
+ end
49
+
50
+ type_class.new(values.compact.first).value
51
+ end
52
+
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,49 @@
1
+ module Graft
2
+ module Xml
3
+ module Model
4
+
5
+ module ClassMethods
6
+
7
+ def attribute(name, options = {})
8
+ source = options[:from]
9
+ type = options[:type] || :string
10
+
11
+ self.attributes << Graft::Xml::Attribute.new(name, type, source)
12
+ class_eval "attr_accessor :#{name}"
13
+ end
14
+
15
+ def data_from(xml_or_document)
16
+ xml_or_document.is_a?(String) ? Hpricot.XML(xml_or_document) : xml_or_document
17
+ end
18
+
19
+ end
20
+
21
+ module InstanceMethods
22
+
23
+ def to_hash
24
+ self.class.attributes.inject({}) {|h,a| h.merge(a.name.to_s => send(a.name)) }
25
+ end
26
+
27
+ def to_xml(tag_name)
28
+ xml = Builder::XmlMarkup.new
29
+ xml.instruct!
30
+ xml.tag! tag_name do
31
+ to_hash.each do |attribute, value|
32
+ xml.tag! attribute, value
33
+ end
34
+ end
35
+ xml.target!
36
+ end
37
+
38
+ end
39
+
40
+ def self.included(other)
41
+ other.send(:extend, Graft::Model::ClassMethods)
42
+ other.send(:extend, Graft::Xml::Model::ClassMethods)
43
+ other.send(:include, Graft::Model::InstanceMethods)
44
+ other.send(:include, Graft::Xml::Model::InstanceMethods)
45
+ end
46
+
47
+ end
48
+ end
49
+ end