fiddler 0.0.1 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/README.md +70 -0
  2. data/lib/fiddler.rb +5 -1
  3. data/lib/fiddler/attachment.rb +142 -0
  4. data/lib/fiddler/configuration.rb +7 -2
  5. data/lib/fiddler/connection_manager.rb +62 -20
  6. data/lib/fiddler/errors.rb +1 -0
  7. data/lib/fiddler/extensions.rb +2 -0
  8. data/lib/fiddler/extensions/file.rb +5 -0
  9. data/lib/fiddler/extensions/hash.rb +15 -0
  10. data/lib/fiddler/formatters/base_formatter.rb +3 -0
  11. data/lib/fiddler/formatters/search_request_formatter.rb +2 -2
  12. data/lib/fiddler/history.rb +32 -0
  13. data/lib/fiddler/parsers.rb +3 -1
  14. data/lib/fiddler/parsers/attachment_parser.rb +54 -0
  15. data/lib/fiddler/parsers/base_parser.rb +41 -3
  16. data/lib/fiddler/parsers/history_parser.rb +72 -0
  17. data/lib/fiddler/parsers/ticket_parser.rb +52 -21
  18. data/lib/fiddler/ticket.rb +141 -43
  19. data/lib/fiddler/version.rb +1 -1
  20. data/spec/attachment_spec.rb +26 -0
  21. data/spec/cassettes/change-ownership-take.yml +98 -0
  22. data/spec/cassettes/get-tickets.yml +89087 -0
  23. data/spec/cassettes/reply-to-tickets.yml +232 -0
  24. data/spec/cassettes/root-request.yml +79 -0
  25. data/spec/cassettes/search-tickets.yml +38249 -0
  26. data/spec/cassettes/ticket-histories-count.yml +2195 -0
  27. data/spec/cassettes/ticket-histories.yml +954 -0
  28. data/spec/connection_manager_spec.rb +5 -1
  29. data/spec/formatters/search_request_formatter_spec.rb +13 -0
  30. data/spec/parsers/attachment_parser_spec.rb +29 -0
  31. data/spec/parsers/base_parser_spec.rb +16 -0
  32. data/spec/parsers/history_parser_spec.rb +32 -0
  33. data/spec/parsers/ticket_parser_spec.rb +5 -1
  34. data/spec/spec_helper.rb +9 -0
  35. data/spec/ticket_spec.rb +188 -6
  36. metadata +80 -9
data/README.md CHANGED
@@ -3,6 +3,76 @@ Fiddler
3
3
 
4
4
  Ruby gem to provide an easy interface to Request Tracker Installation.
5
5
 
6
+ Installation
7
+ -------------
8
+
9
+ Install the gem using this commands
10
+
11
+ `gem install fiddler`
12
+
13
+ or you can include it in your Gemfile.
14
+
15
+ `gem 'fiddler'`
16
+
17
+ Configuration
18
+ --------------
19
+
20
+ For a Rails app, create an initializer files and for any other app, include this before using the gem.
21
+ <pre>
22
+ <code>
23
+ Fiddler.configure do |config|
24
+ config.server_url = "request_tracker_url"
25
+ config.username = "some_user"
26
+ config.password = "some_password"
27
+ end
28
+ </code>
29
+ </pre>
30
+
31
+ You can modify the settings on the fly as well using `Fiddler.configuration` variable.
32
+
33
+ Attachments
34
+ -----------
35
+
36
+ Fiddler saves the attachments object in a folder specified by
37
+ `Fiddler.configuration.attachments_path`. This is relative to the rails
38
+ root.
39
+
40
+ Using Cookies
41
+ -------------
42
+
43
+ Make sure you have RT-External-Auth configured properly to use cookies with Request Tracker.
44
+ Once that part has been done, change the config file to the following format.
45
+
46
+ <pre>
47
+ <code>
48
+ Fiddler.configure do |config|
49
+ config.server_url = "request_tracker_url"
50
+ config.use_cookies = true
51
+ config.cookie_domain = ".domainname"
52
+ config.request_tracker_key = "loginCookieValue"
53
+ end
54
+ </code>
55
+ </pre>
56
+
57
+ Once the configuration is done, cookie value can be set using
58
+ `Fiddler.configuration.cookie_value` method (appropriate place for that
59
+ would be somewhere like ApplicationController where it can set
60
+ dynamically).
61
+
62
+ Debugging Response
63
+ ------------------
64
+
65
+ You can set the config option `Fiddler.configuration.debug_response` to
66
+ `true` to start debugging the responses from RT. If using in rails, it
67
+ will log to the current environment log otherwise print it to the stdout.
68
+
69
+ SSL Verification
70
+ ----------------
71
+
72
+ SSL certificate verification can be turned off by using
73
+ `Fiddler.configuration.ssl_verify` option. This is very helpful in jruby
74
+ implementations where ssl is bit of a pain.
75
+
6
76
  Supported Versions of Request Tracker
7
77
  -------------------------------------
8
78
  * 4.0.4
@@ -2,7 +2,11 @@ require 'fiddler/configuration'
2
2
  require 'fiddler/errors'
3
3
  require 'fiddler/parsers'
4
4
  require 'fiddler/formatters'
5
- require 'fiddler/ticket'
5
+ require 'fiddler/extensions'
6
6
  require 'fiddler/connection_manager'
7
7
 
8
+ require 'fiddler/ticket'
9
+ require 'fiddler/history'
10
+ require 'fiddler/attachment'
11
+
8
12
  require 'active_support/all'
@@ -0,0 +1,142 @@
1
+ require 'active_attr'
2
+ module Fiddler
3
+ class AttachmentCollection < Array
4
+ def to_payload
5
+ hash = Hash.new
6
+ self.each_with_index do |attach, index|
7
+ hash["attachment_#{index+1}"] = attach
8
+ end
9
+ hash
10
+ end
11
+
12
+ def self.fill(*args)
13
+ AttachmentCollection.new Array(args.compact).flatten.map { |attachment|
14
+ if attachment.is_a?(File)
15
+ AttachmentFile.new(attachment.path)
16
+ elsif attachment.is_a?(String)
17
+ AttachmentFile.new(attachment)
18
+ elsif attachment.is_a?(ActionDispatch::Http::UploadedFile)
19
+ AttachmentFile.new(attachment.tempfile.path, attachment.original_filename)
20
+ end
21
+ }.compact
22
+ end
23
+ end
24
+
25
+ class AttachmentFile < File
26
+ attr_accessor :name
27
+
28
+ def initialize(path,name=nil)
29
+ super(path)
30
+ @name = name || File.basename(path)
31
+ end
32
+ end
33
+
34
+ # the attachment in itself
35
+ class Attachment
36
+ include ActiveAttr::Model
37
+
38
+ attribute :id
39
+ attribute :subject
40
+ attribute :creator
41
+ attribute :created
42
+ attribute :transaction
43
+ attribute :parent
44
+ attribute :message_id
45
+ attribute :filename
46
+ attribute :content_type
47
+ attribute :content_encoding
48
+ attribute :headers
49
+
50
+ attr_accessor :ticket_id, :content, :path
51
+
52
+ # Public class method to get an attachment
53
+ def self.get(id, ticket_id)
54
+ url = "/ticket/#{ticket_id}/attachments/#{id}"
55
+ response = Fiddler::ConnectionManager.get(url)
56
+ attachment = Fiddler::Parsers::AttachmentParser.parse_single(response)
57
+ attachment.ticket_id = ticket_id
58
+ attachment
59
+ end
60
+
61
+ def content_length
62
+ length = header_value_for_key("Content-Length")
63
+ if !length.nil?
64
+ length.to_i
65
+ elsif @content.nil?
66
+ -1
67
+ else
68
+ @content.length
69
+ end
70
+ end
71
+
72
+ def content
73
+ populate_data
74
+ @content
75
+ end
76
+
77
+ def path
78
+ populate_data
79
+ @path
80
+ end
81
+
82
+ def has_text_content
83
+ if content_type == "text/plain" or content_type == "text/html"
84
+ return true
85
+ else
86
+ return false
87
+ end
88
+ end
89
+
90
+ protected
91
+
92
+ def populate_data
93
+ @data_populated ||= false
94
+ unless @data_populated
95
+ if content_length != 0
96
+ if has_text_content
97
+ load_content
98
+ @path = nil
99
+ else
100
+ @path = full_path_for_filename
101
+ if File.exists?(@path)
102
+ @content = ""
103
+ else
104
+ load_content
105
+ save_content_to_file
106
+ end
107
+ end
108
+ else
109
+ @content = ""
110
+ end
111
+ @data_populated = true
112
+ end
113
+ end
114
+
115
+ def load_content
116
+ url = "/ticket/#{ticket_id}/attachments/#{id}/content"
117
+ response = Fiddler::ConnectionManager.get(url)
118
+ @content = Fiddler::Parsers::AttachmentParser.parse_content(response)
119
+ end
120
+
121
+ def header_value_for_key(header_key)
122
+ final_value = nil
123
+ headers.each do |header_line|
124
+ (key,value) = header_line.split(":")
125
+ if header_key == key
126
+ final_value = value
127
+ break
128
+ end
129
+ end
130
+ return final_value
131
+ end
132
+
133
+ def save_content_to_file
134
+ File.open(full_path_for_filename, "w") { |f| f.write(@content) }
135
+ @content = ""
136
+ end
137
+
138
+ def full_path_for_filename
139
+ "#{Fiddler.configuration.attachments_path}/#{id}-#{filename}"
140
+ end
141
+ end
142
+ end
@@ -1,11 +1,16 @@
1
1
  module Fiddler
2
2
  # Based on the Clearance gem configuration - https://github.com/thoughtbot/clearance/blob/master/lib/clearance/configuration.rb
3
3
  class Configuration
4
- attr_accessor :server_url, :username, :password, :use_cookies, :cookie_domain, :ssl_verify
4
+ attr_accessor :server_url, :username, :password, :use_cookies, :cookie_domain, :cookie_value, :request_tracker_key, :ssl_verify, :attachments_path, :debug_response
5
5
 
6
6
  def initialize
7
7
  @use_cookies = false
8
8
  @ssl_verify = true
9
+ @attachments_path = "attachments"
10
+ @cookie_value = nil
11
+ @cookie_domain = nil
12
+ @request_tracker_key = "loginCookieValue"
13
+ @debug_response = false
9
14
  end
10
15
  end
11
16
 
@@ -17,4 +22,4 @@ module Fiddler
17
22
  self.configuration ||= Configuration.new
18
23
  yield configuration
19
24
  end
20
- end
25
+ end
@@ -1,33 +1,67 @@
1
1
  require 'httpclient'
2
+ require 'awesome_print'
2
3
 
3
4
  module Fiddler
4
5
  module ConnectionManager
5
6
 
6
7
  class Connection
7
- attr_accessor :client
8
+ attr_accessor :client, :logged_in
9
+
8
10
  def initialize
9
11
  @client = HTTPClient.new
10
12
  @client.set_cookie_store("cookies.dat")
13
+ @logged_in = false
11
14
  end
12
15
 
13
- def base_url
14
- "#{Fiddler.configuration.server_url}/REST/1.0/"
16
+ def get(path,options)
17
+ login! unless @logged_in
18
+ @client.get(url_for(path),options).content
15
19
  end
16
20
 
17
- def get(url,options)
18
- url = "#{base_url}#{url}"
19
- options = options_with_login(options)
20
- @client.get(url,options).content
21
+ def post(path,options)
22
+ login! unless @logged_in
23
+ @client.post(url_for(path),options).content
21
24
  end
22
25
 
23
- def post(url,options)
24
- url = "#{base_url}#{url}"
25
- @client.post(url,options_with_login(options)).content
26
+ def post_content(path,options)
27
+ login! unless @logged_in
28
+ @client.post_content(url_for(path),options)
26
29
  end
27
30
 
28
- def options_with_login(options)
31
+ private
32
+
33
+ def login!
29
34
  unless Fiddler.configuration.use_cookies
30
- options.merge({ :user => Fiddler.configuration.username, :pass => Fiddler.configuration.password })
35
+ unless @logged_in
36
+ @client.post(url_for(base_url), :user => Fiddler.configuration.username, :pass => Fiddler.configuration.password )
37
+ @logged_in = true
38
+ end
39
+ else
40
+ @client.cookie_manager.cookies = []
41
+ cookie = WebAgent::Cookie.new
42
+ cookie.name = Fiddler.configuration.request_tracker_key
43
+ cookie.value = Fiddler.configuration.cookie_value
44
+ cookie.url = URI.parse(Fiddler.configuration.server_url)
45
+ cookie.domain_orig = Fiddler.configuration.cookie_domain
46
+ @client.cookie_manager.add(cookie)
47
+ @logged_in = false
48
+ end
49
+ end
50
+
51
+ def base_url
52
+ server_url = Fiddler.configuration.server_url
53
+ if server_url =~ /\/$/
54
+ "#{Fiddler.configuration.server_url}REST/1.0"
55
+ else
56
+ "#{Fiddler.configuration.server_url}/REST/1.0"
57
+ end
58
+ end
59
+
60
+ def url_for(path)
61
+ if path =~ /^\//
62
+ "#{base_url}#{path}"
63
+ else
64
+ "#{base_url}/#{path}"
31
65
  end
32
66
  end
33
67
  end
@@ -37,16 +71,17 @@ module Fiddler
37
71
 
38
72
  def get(url,options={})
39
73
  check_config
40
- response = connection.get(url,options)
41
- debug(response)
42
- response
74
+ debug connection.get(url,options)
43
75
  end
44
76
 
45
77
  def post(url,options={})
46
78
  check_config
47
- response = connection.post(url,options)
48
- debug(response)
49
- response
79
+ debug connection.post(url,options)
80
+ end
81
+
82
+ def post_content(url,options={})
83
+ check_config
84
+ debug connection.post_content(url,options)
50
85
  end
51
86
 
52
87
  protected
@@ -55,7 +90,7 @@ module Fiddler
55
90
  config = Fiddler.configuration
56
91
  raise InvalidConfigurationError if config.server_url.blank?
57
92
  if config.username.blank? or config.password.blank?
58
- raise InvalidConfigurationError unless config.use_cookies
93
+ raise InvalidConfigurationError unless config.use_cookies and config.request_tracker_key and config.cookie_value and config.cookie_domain
59
94
  end
60
95
  end
61
96
 
@@ -64,7 +99,14 @@ module Fiddler
64
99
  end
65
100
 
66
101
  def debug(response)
67
- puts response.inspect if ENV['DEBUG']
102
+ if ENV['DEBUG'] or Fiddler.configuration.debug_response
103
+ if defined?(Rails)
104
+ Rails.logger.debug response
105
+ else
106
+ ap response
107
+ end
108
+ end
109
+ return response
68
110
  end
69
111
  end # end class method definitions
70
112
  end # end ConnectionManager module definition
@@ -4,4 +4,5 @@ module Fiddler
4
4
  class InvalidConfigurationError < StandardError; end
5
5
  class TicketAccessDeniedError < StandardError; end
6
6
  class RequestError < StandardError; end
7
+ class IllegalCharacterError < StandardError; end
7
8
  end
@@ -0,0 +1,2 @@
1
+ require 'fiddler/extensions/hash'
2
+ require 'fiddler/extensions/file'
@@ -0,0 +1,5 @@
1
+ class File
2
+ def name
3
+ File.basename(path)
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ class Hash
2
+ def to_content_format
3
+ fields = self.map do |key,value|
4
+ unless value.nil?
5
+ value = Fiddler::Formatters::BaseFormatter.format_string(value.to_s)
6
+ if key.to_s.match(/^cf_.+/)
7
+ "CF-#{key.to_s[3..key.to_s.length].gsub(/_/, " ").camelize.humanize}: #{value}"
8
+ else
9
+ "#{key.to_s.camelize}: #{value}"
10
+ end
11
+ end
12
+ end
13
+ content = fields.compact.sort.join("\n")
14
+ end
15
+ end
@@ -1,6 +1,9 @@
1
1
  module Fiddler
2
2
  module Formatters
3
3
  class BaseFormatter
4
+ def self.format_string(string)
5
+ string.gsub("\r", '').gsub("\n", "\n ")
6
+ end
4
7
  end
5
8
  end
6
9
  end
@@ -51,8 +51,8 @@ module Fiddler
51
51
  end
52
52
  query_array << '( ' + parts.join(" AND ") + ' )'
53
53
  elsif value.is_a?(String)
54
- # special case for when user is Nobody, like doesnt work there
55
- if key == "Owner" and value == "Nobody"
54
+ # special case for the owner field
55
+ if key == "Owner"
56
56
  query_array << "#{key} = '#{value}'"
57
57
  else
58
58
  query_array << "#{key} LIKE '#{value}'"
@@ -0,0 +1,32 @@
1
+ require 'active_attr'
2
+ module Fiddler
3
+ class History
4
+ include ActiveAttr::Model
5
+
6
+ attribute :id
7
+ attribute :ticket
8
+ attribute :time_taken
9
+ attribute :type
10
+ attribute :field
11
+ attribute :old_value
12
+ attribute :new_value
13
+ attribute :data
14
+ attribute :description
15
+ attribute :content
16
+ attribute :creator
17
+ attribute :created
18
+ attribute :attachment_ids
19
+
20
+ attr_reader :attachments
21
+
22
+ def attachments
23
+ if @attachments == nil
24
+ @attachments = []
25
+ attachment_ids.each do |id|
26
+ @attachments << Fiddler::Attachment.get(id,ticket)
27
+ end
28
+ end
29
+ @attachments
30
+ end
31
+ end
32
+ end