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/lib/fiddler/parsers.rb
    CHANGED
    
    
| @@ -0,0 +1,54 @@ | |
| 1 | 
            +
            module Fiddler
         | 
| 2 | 
            +
               module Parsers
         | 
| 3 | 
            +
                  class AttachmentParser < BaseParser
         | 
| 4 | 
            +
                     def self.parse_single(response)
         | 
| 5 | 
            +
                        response = check_response_code(response)
         | 
| 6 | 
            +
                        response = check_for_errors(response)
         | 
| 7 | 
            +
                        attachment_from_response(response)
         | 
| 8 | 
            +
                     end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                     def self.parse_content(response)
         | 
| 11 | 
            +
                        response = check_response_code(response,false,false)
         | 
| 12 | 
            +
                        return response.join("\n")
         | 
| 13 | 
            +
                     end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                     protected
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                     def self.check_for_errors(response)
         | 
| 18 | 
            +
                        if response.length == 1
         | 
| 19 | 
            +
                           raise Fiddler::FiddlerError, response.first
         | 
| 20 | 
            +
                        end
         | 
| 21 | 
            +
                        response
         | 
| 22 | 
            +
                     end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                     def self.attachment_from_response(response)
         | 
| 25 | 
            +
                        result = {}
         | 
| 26 | 
            +
                        collect_headers = false
         | 
| 27 | 
            +
                        headers = []
         | 
| 28 | 
            +
                        response.each do |line|
         | 
| 29 | 
            +
                           matches = /^(\S*?):\s(.*)/.match(line)
         | 
| 30 | 
            +
                           if(matches)
         | 
| 31 | 
            +
                              key = matches[1].underscore
         | 
| 32 | 
            +
                              result[key] = matches[2]
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                              if key == "headers"
         | 
| 35 | 
            +
                                 collect_headers = true
         | 
| 36 | 
            +
                                 next
         | 
| 37 | 
            +
                              elsif key == "content"
         | 
| 38 | 
            +
                                 break
         | 
| 39 | 
            +
                              end
         | 
| 40 | 
            +
                           end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                           spaced_content_matches = /^\s{9}(.*)$/.match(line)
         | 
| 43 | 
            +
                           if spaced_content_matches and collect_headers
         | 
| 44 | 
            +
                              headers << spaced_content_matches[1]
         | 
| 45 | 
            +
                           end
         | 
| 46 | 
            +
                        end
         | 
| 47 | 
            +
                        result.delete("content")
         | 
| 48 | 
            +
                        headers.unshift(result["headers"])
         | 
| 49 | 
            +
                        result["headers"] = headers
         | 
| 50 | 
            +
                        attachment = Fiddler::Attachment.new(result)
         | 
| 51 | 
            +
                     end
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
               end
         | 
| 54 | 
            +
            end
         | 
| @@ -5,19 +5,57 @@ module Fiddler | |
| 5 5 | 
             
                     SUCCESS_CODES = (200..299).to_a
         | 
| 6 6 | 
             
                     ERROR_CODES = (400..499).to_a
         | 
| 7 7 |  | 
| 8 | 
            -
                     def self.check_response_code(response)
         | 
| 9 | 
            -
                         | 
| 8 | 
            +
                     def self.check_response_code(response, reject_blank_lines=true, raise_error_for_empty_response=true)
         | 
| 9 | 
            +
                        response = safe_encode(response)
         | 
| 10 | 
            +
                        lines = response.split("\n")
         | 
| 11 | 
            +
                        lines = lines.delete_if { |l| l.nil? or l == "" } if reject_blank_lines
         | 
| 10 12 | 
             
                        if lines.count == 0
         | 
| 11 | 
            -
                            | 
| 13 | 
            +
                           if raise_error_for_empty_response
         | 
| 14 | 
            +
                              raise RequestError, "Empty Response"
         | 
| 15 | 
            +
                           else
         | 
| 16 | 
            +
                              return []
         | 
| 17 | 
            +
                           end
         | 
| 12 18 | 
             
                        else
         | 
| 13 19 | 
             
                           status_line = lines.shift
         | 
| 14 20 | 
             
                           version, status_code, status_text = status_line.split(/\s+/,2)
         | 
| 15 21 | 
             
                           unless SUCCESS_CODES.include?(status_code.to_i)
         | 
| 16 22 | 
             
                              raise RequestError, status_text
         | 
| 17 23 | 
             
                           end
         | 
| 24 | 
            +
                           lines.shift unless reject_blank_lines
         | 
| 18 25 | 
             
                           lines
         | 
| 19 26 | 
             
                        end
         | 
| 20 27 | 
             
                     end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                     def self.tokenize_response(response)
         | 
| 30 | 
            +
                        tokens = Array.new
         | 
| 31 | 
            +
                        current = Array.new
         | 
| 32 | 
            +
                        response.each do |item|
         | 
| 33 | 
            +
                           if(item == "--")
         | 
| 34 | 
            +
                              tokens << current
         | 
| 35 | 
            +
                              current = Array.new
         | 
| 36 | 
            +
                              next
         | 
| 37 | 
            +
                           end
         | 
| 38 | 
            +
                           current << item
         | 
| 39 | 
            +
                        end
         | 
| 40 | 
            +
                        tokens << current unless current.empty?
         | 
| 41 | 
            +
                        tokens
         | 
| 42 | 
            +
                     end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                     protected
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                     def self.safe_encode(response)
         | 
| 47 | 
            +
                        require 'iconv' unless String.method_defined?(:encode)
         | 
| 48 | 
            +
                        if String.method_defined?(:encode)
         | 
| 49 | 
            +
                           response.encode!('UTF-8', 'UTF-8', :invalid => :replace)
         | 
| 50 | 
            +
                        else
         | 
| 51 | 
            +
                           begin
         | 
| 52 | 
            +
                              Iconv.iconv("UTF-8//IGNORE", "UTF-8", response).join("")
         | 
| 53 | 
            +
                           rescue Exception => e
         | 
| 54 | 
            +
                              raise IllegalCharacterError, "Attachment contains illegal characters"
         | 
| 55 | 
            +
                           end 
         | 
| 56 | 
            +
                        end
         | 
| 57 | 
            +
                        response
         | 
| 58 | 
            +
                     end
         | 
| 21 59 | 
             
                  end
         | 
| 22 60 | 
             
               end
         | 
| 23 61 | 
             
            end
         | 
| @@ -0,0 +1,72 @@ | |
| 1 | 
            +
            module Fiddler
         | 
| 2 | 
            +
               module Parsers
         | 
| 3 | 
            +
                  class HistoryParser < BaseParser
         | 
| 4 | 
            +
                     def self.parse_single(response)
         | 
| 5 | 
            +
                        response = check_response_code(response)
         | 
| 6 | 
            +
                        response = check_for_errors(response)
         | 
| 7 | 
            +
                        history_from_response(response)
         | 
| 8 | 
            +
                     end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                     def self.parse_multiple(response)
         | 
| 11 | 
            +
                        response = check_response_code(response)
         | 
| 12 | 
            +
                        response = check_for_errors(response)
         | 
| 13 | 
            +
                        token_responses = tokenize_response(response)
         | 
| 14 | 
            +
                        histories = Array.new
         | 
| 15 | 
            +
                        token_responses.each do |token_response|
         | 
| 16 | 
            +
                           histories << history_from_response(token_response)
         | 
| 17 | 
            +
                        end
         | 
| 18 | 
            +
                        histories
         | 
| 19 | 
            +
                     end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                     protected
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                     def self.check_for_errors(response)
         | 
| 24 | 
            +
                        if response.length == 1
         | 
| 25 | 
            +
                           raise Fiddler::FiddlerError, response.first
         | 
| 26 | 
            +
                        else
         | 
| 27 | 
            +
                           response.shift
         | 
| 28 | 
            +
                        end
         | 
| 29 | 
            +
                        response
         | 
| 30 | 
            +
                     end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                     def self.history_from_response(response)
         | 
| 33 | 
            +
                        result = {}
         | 
| 34 | 
            +
                        content_lines = []
         | 
| 35 | 
            +
                        result["attachment_ids"] = []
         | 
| 36 | 
            +
                        collect_content = false
         | 
| 37 | 
            +
                        collect_attachments = false
         | 
| 38 | 
            +
                        response.each do |line|
         | 
| 39 | 
            +
                           matches = /^(\S*?):\s(.*)/.match(line)
         | 
| 40 | 
            +
                           if(matches)
         | 
| 41 | 
            +
                              key = matches[1].underscore
         | 
| 42 | 
            +
                              result[key] = matches[2]
         | 
| 43 | 
            +
                              if key == "content"
         | 
| 44 | 
            +
                                 collect_content = true
         | 
| 45 | 
            +
                              elsif key == "attachments"
         | 
| 46 | 
            +
                                 collect_content = false
         | 
| 47 | 
            +
                                 collect_attachments = true
         | 
| 48 | 
            +
                              end
         | 
| 49 | 
            +
                           end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                           if collect_content
         | 
| 52 | 
            +
                              content_matches = /^\s{9}(.*)$/.match(line)
         | 
| 53 | 
            +
                              if(content_matches)
         | 
| 54 | 
            +
                                 content_lines << content_matches[1]
         | 
| 55 | 
            +
                              end
         | 
| 56 | 
            +
                           end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                           if collect_attachments
         | 
| 59 | 
            +
                              attachment_matches = /^\s{13}(.*?):\s(.*)/.match(line)
         | 
| 60 | 
            +
                              if(attachment_matches)
         | 
| 61 | 
            +
                                 result["attachment_ids"] << attachment_matches[1]
         | 
| 62 | 
            +
                              end
         | 
| 63 | 
            +
                           end
         | 
| 64 | 
            +
                        end
         | 
| 65 | 
            +
                        result["attachment_ids"].count.times { content_lines.pop }
         | 
| 66 | 
            +
                        result["content"] += content_lines.join("\n")
         | 
| 67 | 
            +
                        result.delete("attachments")
         | 
| 68 | 
            +
                        history = Fiddler::History.new(result)
         | 
| 69 | 
            +
                     end
         | 
| 70 | 
            +
                  end
         | 
| 71 | 
            +
               end
         | 
| 72 | 
            +
            end
         | 
| @@ -10,12 +10,39 @@ module Fiddler | |
| 10 10 | 
             
                     def self.parse_multiple(response)
         | 
| 11 11 | 
             
                        response = check_response_code(response)
         | 
| 12 12 | 
             
                        response = check_for_errors(response)
         | 
| 13 | 
            -
                         | 
| 14 | 
            -
             | 
| 15 | 
            -
                         | 
| 16 | 
            -
                            | 
| 13 | 
            +
                        if response.count == 0
         | 
| 14 | 
            +
                           []
         | 
| 15 | 
            +
                        else
         | 
| 16 | 
            +
                           ticket_token_responses = tokenize_response(response)
         | 
| 17 | 
            +
                           tickets = Array.new
         | 
| 18 | 
            +
                           ticket_token_responses.each do |token_response|
         | 
| 19 | 
            +
                              tickets << ticket_from_response(token_response)
         | 
| 20 | 
            +
                           end
         | 
| 21 | 
            +
                           tickets
         | 
| 22 | 
            +
                        end
         | 
| 23 | 
            +
                     end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                     def self.parse_reply_response(response)
         | 
| 26 | 
            +
                        response = check_response_code(response)
         | 
| 27 | 
            +
                        return !response.first.match(/^# Message recorded/).nil?
         | 
| 28 | 
            +
                     end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                     def self.parse_change_ownership_response(response)
         | 
| 31 | 
            +
                        response = check_response_code(response)
         | 
| 32 | 
            +
                        if response.first =~ /^# Owner changed from (\S+) to (\S+)/
         | 
| 33 | 
            +
                           return $2
         | 
| 34 | 
            +
                        else
         | 
| 35 | 
            +
                           return nil
         | 
| 36 | 
            +
                        end
         | 
| 37 | 
            +
                     end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                     def self.parse_update_response(response, method)
         | 
| 40 | 
            +
                        response = check_response_code(response)
         | 
| 41 | 
            +
                        if method == :create
         | 
| 42 | 
            +
                           return response.first =~ /^# Ticket (\S+) created/ ? $1 : nil
         | 
| 43 | 
            +
                        elsif method == :update
         | 
| 44 | 
            +
                           return response.first =~ /^# Ticket (\S+) updated/ ? $1 : nil
         | 
| 17 45 | 
             
                        end
         | 
| 18 | 
            -
                        tickets
         | 
| 19 46 | 
             
                     end
         | 
| 20 47 |  | 
| 21 48 | 
             
                     protected
         | 
| @@ -24,35 +51,39 @@ module Fiddler | |
| 24 51 | 
             
                        message = response.first.strip
         | 
| 25 52 | 
             
                        if message =~ /^#/
         | 
| 26 53 | 
             
                           raise Fiddler::TicketNotFoundError, message
         | 
| 54 | 
            +
                        elsif message == "No matching results."
         | 
| 55 | 
            +
                           response = []
         | 
| 27 56 | 
             
                        end
         | 
| 28 57 | 
             
                        response
         | 
| 29 58 | 
             
                     end
         | 
| 30 59 |  | 
| 31 60 | 
             
                     def self.ticket_from_response(response)
         | 
| 32 61 | 
             
                        result = {}
         | 
| 62 | 
            +
                        prev_key = nil
         | 
| 33 63 | 
             
                        response.each do |line|
         | 
| 34 | 
            -
                           matches = /^( | 
| 64 | 
            +
                           matches = /^(\S*?):\s(.*)/.match(line)
         | 
| 35 65 | 
             
                           if(matches)
         | 
| 36 66 | 
             
                              key = matches[1].underscore
         | 
| 67 | 
            +
                              prev_key = key
         | 
| 37 68 | 
             
                              result[key] = matches[2]
         | 
| 69 | 
            +
                           else
         | 
| 70 | 
            +
                              whitespace_matches = /^\s{12}(.*)/.match(line)
         | 
| 71 | 
            +
                              if whitespace_matches and prev_key
         | 
| 72 | 
            +
                                 values = result[prev_key]
         | 
| 73 | 
            +
                                 values = values.split(",") unless values.is_a?(Array)
         | 
| 74 | 
            +
                                 result[prev_key] = values.concat(whitespace_matches[1].split(",")).collect { |x| x.strip }
         | 
| 75 | 
            +
                              end
         | 
| 38 76 | 
             
                           end
         | 
| 39 77 | 
             
                        end
         | 
| 40 | 
            -
                         | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
                        tokens = Array.new
         | 
| 45 | 
            -
                        current = Array.new
         | 
| 46 | 
            -
                        response.each do |item|
         | 
| 47 | 
            -
                           if(item == "--")
         | 
| 48 | 
            -
                              tokens << current
         | 
| 49 | 
            -
                              current = Array.new
         | 
| 50 | 
            -
                              next
         | 
| 51 | 
            -
                           end
         | 
| 52 | 
            -
                           current << item
         | 
| 78 | 
            +
                        begin
         | 
| 79 | 
            +
                           id = result['id'].scan(/^ticket\/(\d*)$/).first.first.to_i
         | 
| 80 | 
            +
                        rescue
         | 
| 81 | 
            +
                           raise RequestError, "Unexpected response for id : #{result['id']}"
         | 
| 53 82 | 
             
                        end
         | 
| 54 | 
            -
                         | 
| 83 | 
            +
                        ticket = Fiddler::Ticket.new(result)
         | 
| 84 | 
            +
                        ticket.id = id
         | 
| 85 | 
            +
                        return ticket
         | 
| 55 86 | 
             
                     end
         | 
| 56 87 | 
             
                  end
         | 
| 57 88 | 
             
               end
         | 
| 58 | 
            -
            end
         | 
| 89 | 
            +
            end
         | 
    
        data/lib/fiddler/ticket.rb
    CHANGED
    
    | @@ -1,42 +1,147 @@ | |
| 1 | 
            +
            require 'active_attr'
         | 
| 1 2 | 
             
            module Fiddler
         | 
| 2 3 | 
             
               class Ticket
         | 
| 4 | 
            +
                  include ActiveAttr::Model
         | 
| 3 5 |  | 
| 4 | 
            -
                   | 
| 5 | 
            -
                   | 
| 6 | 
            +
                  attribute :id, :default => 'ticket/new'
         | 
| 7 | 
            +
                  attribute :queue
         | 
| 8 | 
            +
                  attribute :owner
         | 
| 9 | 
            +
                  attribute :creator
         | 
| 10 | 
            +
                  attribute :subject
         | 
| 11 | 
            +
                  attribute :status
         | 
| 12 | 
            +
                  attribute :priority
         | 
| 13 | 
            +
                  attribute :initial_priority
         | 
| 14 | 
            +
                  attribute :final_priority
         | 
| 15 | 
            +
                  attribute :requestors
         | 
| 16 | 
            +
                  attribute :cc
         | 
| 17 | 
            +
                  attribute :admin_cc
         | 
| 18 | 
            +
                  attribute :created
         | 
| 19 | 
            +
                  attribute :starts
         | 
| 20 | 
            +
                  attribute :started
         | 
| 21 | 
            +
                  attribute :due
         | 
| 22 | 
            +
                  attribute :resolved
         | 
| 23 | 
            +
                  attribute :told
         | 
| 24 | 
            +
                  attribute :last_updated
         | 
| 25 | 
            +
                  attribute :time_estimated
         | 
| 26 | 
            +
                  attribute :time_worked
         | 
| 27 | 
            +
                  attribute :time_left
         | 
| 28 | 
            +
                  attribute :text
         | 
| 6 29 |  | 
| 7 | 
            -
                   | 
| 8 | 
            -
             | 
| 9 | 
            -
                   | 
| 30 | 
            +
                  validates_presence_of :id, :queue, :subject
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  def histories
         | 
| 33 | 
            +
                     if @histories == nil
         | 
| 34 | 
            +
                        url = "ticket/#{id}/history"
         | 
| 35 | 
            +
                        response = Fiddler::ConnectionManager.get(url, {:format => "l"})
         | 
| 36 | 
            +
                        @histories = Fiddler::Parsers::HistoryParser.parse_multiple(response)
         | 
| 37 | 
            +
                     end
         | 
| 38 | 
            +
                     @histories
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  # make the setting and getting of requestors easier
         | 
| 42 | 
            +
                  def requestor_array
         | 
| 43 | 
            +
                     self.requestors.split(",").collect { |x| x.strip }
         | 
| 44 | 
            +
                  end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  def requestor_array=(requestor_array)
         | 
| 47 | 
            +
                     if requestor_array.is_a?(Array)
         | 
| 48 | 
            +
                        self.requestors = requestor_array.join(", ")
         | 
| 49 | 
            +
                     end
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                  # Add a comment to a ticket
         | 
| 53 | 
            +
                  # Example:
         | 
| 54 | 
            +
                  #   tix = Ticket.get(1000)
         | 
| 55 | 
            +
                  #   tix.comment("This is a comment", :time_worked => 45, :cc => 'someone@example.com')
         | 
| 56 | 
            +
                  #
         | 
| 57 | 
            +
                  #   Attachments
         | 
| 58 | 
            +
                  #   tix.comment("This is a comment", :attachments => "/tmp/filename.txt")
         | 
| 59 | 
            +
                  #
         | 
| 60 | 
            +
                  #   Attachment as a file descriptor
         | 
| 61 | 
            +
                  #   tix.correspond("This is a comment", :attachments => File.new("/tmp/filename.txt"))
         | 
| 10 62 | 
             
                  #
         | 
| 11 | 
            -
                  #  | 
| 12 | 
            -
                   | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 63 | 
            +
                  #   Attachment as a ActionDispatch::Http::UploadedFile instance
         | 
| 64 | 
            +
                  #   tix.comment("This is a comment", :attachments => [params[:attachment_1], params[:attachment_2]])
         | 
| 65 | 
            +
                  #
         | 
| 66 | 
            +
                  def comment(comment, opt = {})
         | 
| 67 | 
            +
                     reply('Comment', comment, opt)
         | 
| 68 | 
            +
                  end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                  def correspond(comment, opt = {})
         | 
| 71 | 
            +
                     reply('Correspond', comment, opt)
         | 
| 72 | 
            +
                  end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                  def steal
         | 
| 75 | 
            +
                     change_ownership "Steal"
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                  def take
         | 
| 79 | 
            +
                     change_ownership "Take"
         | 
| 80 | 
            +
                  end
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                  def untake
         | 
| 83 | 
            +
                     change_ownership "Untake"
         | 
| 84 | 
            +
                  end
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                  def save
         | 
| 87 | 
            +
                     id == "ticket/new" ? create : update
         | 
| 88 | 
            +
                  end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                  protected
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                  def reply(method, comment, opt)
         | 
| 93 | 
            +
                     # make sure the options are only the valid ones.
         | 
| 94 | 
            +
                     valid_options = [:cc, :bcc, :time_worked, :attachments, :status]
         | 
| 95 | 
            +
                     opt.delete_if { |key,value| !valid_options.include?(key) }
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                     payload = { :text => comment, :action => method}.merge(opt)
         | 
| 98 | 
            +
                     payload.delete(:attachments)
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                     attachments = Fiddler::AttachmentCollection.fill(opt[:attachments])
         | 
| 101 | 
            +
                     payload.merge!(:attachment => attachments.map(&:name).join(",")) unless attachments.empty?
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                     response = Fiddler::ConnectionManager.post_content("ticket/#{id}/comment", { :content => payload.to_content_format }.merge(attachments.to_payload) )
         | 
| 104 | 
            +
             | 
| 105 | 
            +
                     result = Fiddler::Parsers::TicketParser.parse_reply_response(response)
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                     # update the ticket parameters if the action was successful
         | 
| 108 | 
            +
                     if result and opt.has_key?(:status)
         | 
| 109 | 
            +
                        self.status = opt[:status]
         | 
| 110 | 
            +
                        result
         | 
| 15 111 | 
             
                     else
         | 
| 16 | 
            -
                         | 
| 112 | 
            +
                        result
         | 
| 17 113 | 
             
                     end
         | 
| 18 | 
            -
                     @attributes.update(:id => 'ticket/new')
         | 
| 19 | 
            -
                     @saved = false
         | 
| 20 | 
            -
                     @histories = []  
         | 
| 21 | 
            -
                     @new_record = true
         | 
| 22 | 
            -
                     add_methods!
         | 
| 23 114 | 
             
                  end
         | 
| 24 115 |  | 
| 25 | 
            -
                  def  | 
| 26 | 
            -
                      | 
| 27 | 
            -
             | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 30 | 
            -
                         | 
| 31 | 
            -
             | 
| 32 | 
            -
             | 
| 116 | 
            +
                  def change_ownership(method)
         | 
| 117 | 
            +
                     payload = { "Action" => method }
         | 
| 118 | 
            +
                     response = Fiddler::ConnectionManager.post("ticket/#{id}/take", :content => payload.to_content_format)
         | 
| 119 | 
            +
                     new_owner = Fiddler::Parsers::TicketParser.parse_change_ownership_response(response)
         | 
| 120 | 
            +
                     if new_owner
         | 
| 121 | 
            +
                        self.owner = new_owner
         | 
| 122 | 
            +
                        return self
         | 
| 123 | 
            +
                     else
         | 
| 124 | 
            +
                        return nil
         | 
| 33 125 | 
             
                     end
         | 
| 34 126 | 
             
                  end
         | 
| 35 127 |  | 
| 36 | 
            -
                  def  | 
| 37 | 
            -
                      | 
| 38 | 
            -
             | 
| 39 | 
            -
                      | 
| 128 | 
            +
                  def create
         | 
| 129 | 
            +
                     return false unless valid?
         | 
| 130 | 
            +
                     response = Fiddler::ConnectionManager.post("ticket/new", :content => @attributes.to_content_format)
         | 
| 131 | 
            +
                     id = Fiddler::Parsers::TicketParser.parse_update_response(response, :create)
         | 
| 132 | 
            +
                     return false unless id
         | 
| 133 | 
            +
                     self.id = id.to_i
         | 
| 134 | 
            +
                     true
         | 
| 135 | 
            +
                  end
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                  def update
         | 
| 138 | 
            +
                     return false unless valid?
         | 
| 139 | 
            +
                     payload = @attributes.clone
         | 
| 140 | 
            +
                     payload.delete("text")
         | 
| 141 | 
            +
                     payload.delete("id")
         | 
| 142 | 
            +
                     response = Fiddler::ConnectionManager.post("ticket/#{id}/edit", :content => payload.to_content_format)
         | 
| 143 | 
            +
                     id = Fiddler::Parsers::TicketParser.parse_update_response(response, :update)
         | 
| 144 | 
            +
                     return !id.nil?
         | 
| 40 145 | 
             
                  end
         | 
| 41 146 |  | 
| 42 147 | 
             
                  # Class methods
         | 
| @@ -49,6 +154,7 @@ module Fiddler | |
| 49 154 | 
             
                        url = "ticket/#{id}"
         | 
| 50 155 | 
             
                        response = Fiddler::ConnectionManager.get(url)
         | 
| 51 156 | 
             
                        ticket = Fiddler::Parsers::TicketParser.parse_single(response)
         | 
| 157 | 
            +
                        ticket
         | 
| 52 158 | 
             
                     end
         | 
| 53 159 |  | 
| 54 160 | 
             
                     # Search the tickets with the given conditions
         | 
| @@ -56,9 +162,14 @@ module Fiddler | |
| 56 162 | 
             
                     # @params [Hash] of conditions
         | 
| 57 163 | 
             
                     # @returns [Array<Ticket>] of the tickets matching the criteria
         | 
| 58 164 | 
             
                     def all(conditions={})
         | 
| 165 | 
            +
                        tickets = []
         | 
| 59 166 | 
             
                        url = "search/ticket"
         | 
| 60 | 
            -
                         | 
| 61 | 
            -
                         | 
| 167 | 
            +
                        request_hash = Fiddler::Formatters::SearchRequestFormatter.format(conditions)
         | 
| 168 | 
            +
                        unless request_hash.empty?
         | 
| 169 | 
            +
                           response = Fiddler::ConnectionManager.get(url,request_hash)
         | 
| 170 | 
            +
                           tickets = Fiddler::Parsers::TicketParser.parse_multiple(response)
         | 
| 171 | 
            +
                        end
         | 
| 172 | 
            +
                        tickets
         | 
| 62 173 | 
             
                     end
         | 
| 63 174 |  | 
| 64 175 | 
             
                     # Creates a new ticket with the given options, it will not save the ticket
         | 
| @@ -67,19 +178,6 @@ module Fiddler | |
| 67 178 | 
             
                     # @returns [Ticket] returns new ticket object
         | 
| 68 179 | 
             
                     def create(options)
         | 
| 69 180 | 
             
                     end
         | 
| 70 | 
            -
             | 
| 71 | 
            -
                     # Saves the changes to the ticket object
         | 
| 72 | 
            -
                     #
         | 
| 73 | 
            -
                     # @returns [boolean] save succcessful or not
         | 
| 74 | 
            -
                     def save
         | 
| 75 | 
            -
                     end
         | 
| 76 | 
            -
             | 
| 77 | 
            -
                     # Find the tickets with the given options
         | 
| 78 | 
            -
                     #
         | 
| 79 | 
            -
                     # @params [Hash] of options
         | 
| 80 | 
            -
                     # @returns [Array<Ticket>] of ticket matching the criteria
         | 
| 81 | 
            -
                     def find(options={})
         | 
| 82 | 
            -
                     end
         | 
| 83 181 | 
             
                  end
         | 
| 84 182 | 
             
               end
         | 
| 85 | 
            -
            end
         | 
| 183 | 
            +
            end
         |