confuddle 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.
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