fiddler 0.0.1 → 1.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.
- data/README.md +70 -0
- data/lib/fiddler.rb +5 -1
- data/lib/fiddler/attachment.rb +142 -0
- data/lib/fiddler/configuration.rb +7 -2
- data/lib/fiddler/connection_manager.rb +62 -20
- data/lib/fiddler/errors.rb +1 -0
- data/lib/fiddler/extensions.rb +2 -0
- data/lib/fiddler/extensions/file.rb +5 -0
- data/lib/fiddler/extensions/hash.rb +15 -0
- data/lib/fiddler/formatters/base_formatter.rb +3 -0
- data/lib/fiddler/formatters/search_request_formatter.rb +2 -2
- data/lib/fiddler/history.rb +32 -0
- data/lib/fiddler/parsers.rb +3 -1
- data/lib/fiddler/parsers/attachment_parser.rb +54 -0
- data/lib/fiddler/parsers/base_parser.rb +41 -3
- data/lib/fiddler/parsers/history_parser.rb +72 -0
- data/lib/fiddler/parsers/ticket_parser.rb +52 -21
- data/lib/fiddler/ticket.rb +141 -43
- data/lib/fiddler/version.rb +1 -1
- data/spec/attachment_spec.rb +26 -0
- data/spec/cassettes/change-ownership-take.yml +98 -0
- data/spec/cassettes/get-tickets.yml +89087 -0
- data/spec/cassettes/reply-to-tickets.yml +232 -0
- data/spec/cassettes/root-request.yml +79 -0
- data/spec/cassettes/search-tickets.yml +38249 -0
- data/spec/cassettes/ticket-histories-count.yml +2195 -0
- data/spec/cassettes/ticket-histories.yml +954 -0
- data/spec/connection_manager_spec.rb +5 -1
- data/spec/formatters/search_request_formatter_spec.rb +13 -0
- data/spec/parsers/attachment_parser_spec.rb +29 -0
- data/spec/parsers/base_parser_spec.rb +16 -0
- data/spec/parsers/history_parser_spec.rb +32 -0
- data/spec/parsers/ticket_parser_spec.rb +5 -1
- data/spec/spec_helper.rb +9 -0
- data/spec/ticket_spec.rb +188 -6
- 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
|
data/lib/fiddler.rb
CHANGED
@@ -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/
|
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
|
14
|
-
|
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
|
18
|
-
|
19
|
-
|
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
|
24
|
-
|
25
|
-
@client.
|
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
|
-
|
31
|
+
private
|
32
|
+
|
33
|
+
def login!
|
29
34
|
unless Fiddler.configuration.use_cookies
|
30
|
-
|
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
|
-
|
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
|
-
|
48
|
-
|
49
|
-
|
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
|
-
|
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
|
data/lib/fiddler/errors.rb
CHANGED
@@ -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
|
@@ -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
|
55
|
-
if key == "Owner"
|
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
|