confluencer 0.2.7 → 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.7
1
+ 0.2.8
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{confluencer}
8
- s.version = "0.2.7"
8
+ s.version = "0.2.8"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Gabor Ratky"]
12
- s.date = %q{2010-05-07}
12
+ s.date = %q{2010-05-11}
13
13
  s.description = %q{ActiveRecord-like classes to access Confluence through XMLRPC.}
14
14
  s.email = %q{rgabo@rgabostyle.com}
15
15
  s.extra_rdoc_files = [
@@ -37,7 +37,10 @@ Gem::Specification.new do |s|
37
37
  "script/console",
38
38
  "script/console_init.rb",
39
39
  "spec/confluence.yaml.example",
40
+ "spec/confluence/bookmark_spec.rb",
41
+ "spec/confluence/client_spec.rb",
40
42
  "spec/confluence/page_spec.rb",
43
+ "spec/confluence/record_spec.rb",
41
44
  "spec/confluence/session_spec.rb",
42
45
  "spec/confluencer_spec.rb",
43
46
  "spec/spec.opts",
@@ -49,7 +52,10 @@ Gem::Specification.new do |s|
49
52
  s.rubygems_version = %q{1.3.6}
50
53
  s.summary = %q{Useful classes to manage Confluence.}
51
54
  s.test_files = [
52
- "spec/confluence/page_spec.rb",
55
+ "spec/confluence/bookmark_spec.rb",
56
+ "spec/confluence/client_spec.rb",
57
+ "spec/confluence/page_spec.rb",
58
+ "spec/confluence/record_spec.rb",
53
59
  "spec/confluence/session_spec.rb",
54
60
  "spec/confluencer_spec.rb",
55
61
  "spec/spec_helper.rb"
@@ -1,67 +1,126 @@
1
1
  require 'xmlrpc/client'
2
2
 
3
- # Originally confluence4r, available at: http://confluence.atlassian.com/display/DISC/Confluence4r
4
-
5
- # A useful helper for running Confluence XML-RPC from Ruby. Takes care of
6
- # adding the token to each method call (so you can call server.getSpaces()
7
- # instead of server.getSpaces(token)). Also takes care of re-logging in
8
- # if your login times out.
9
- #
10
- # Usage:
11
- #
12
- # client = Confluence::Client.new(:url => "http://confluence.atlassian.com")
13
- # client.login("user", "password")
14
- # puts client.getSpaces()
15
- #
3
+ # Module containing Confluence-related classes.
16
4
  module Confluence
5
+ # Originally confluence4r, available at: http://confluence.atlassian.com/display/DISC/Confluence4r
6
+
7
+ # A useful helper for running Confluence XML-RPC from Ruby. Takes care of
8
+ # adding the token to each method call (so you can call server.getSpaces()
9
+ # instead of server.getSpaces(token)).
10
+ #
11
+ # Usage:
12
+ #
13
+ # client = Confluence::Client.new(:url => "http://confluence.atlassian.com")
14
+ # client.login("user", "password")
15
+ # p client.getSpaces
16
+ #
17
17
  class Client
18
18
  PREFIX = "confluence1"
19
+ XMLRPC_SUFFIX = "/rpc/xmlrpc"
19
20
 
20
- attr_reader :username, :token
21
-
22
- def initialize(options = {})
23
- server_url = options[:url]
24
- server_url += "/rpc/xmlrpc" unless server_url[-11..-1] == "/rpc/xmlrpc"
25
- @server_url = server_url
26
-
27
- client = XMLRPC::Client.new_from_uri(server_url)
21
+ attr_reader :url, :username, :token
22
+
23
+ # Initializes a new client with the given arguments.
24
+ #
25
+ # ==== Parameters
26
+ # arguments<Hash>:: Described below.
27
+ #
28
+ # ==== Arguments
29
+ # :url - The url of the Confluence instance. The trailing '/rpc/xmlrpc' path is optional.
30
+ # :token - An existing session token to reuse.
31
+ #
32
+ def initialize(arguments = {})
33
+ @url = arguments[:url]
34
+ @token = arguments[:token]
28
35
 
29
- @confluence = client.proxy(PREFIX)
30
- @token = options[:token]
36
+ Log4r::MDC.put('token', @token || 'nil')
37
+ log.info "initialized client (:url => #{@url}, :token => #{@token || 'nil'})"
31
38
  end
32
-
39
+
40
+ # Returns true, if the client has a session token.
41
+ #
33
42
  def has_token?
34
43
  !@token.nil?
35
44
  end
36
45
 
46
+ # Logs in and returns the newly acquired session token.
47
+ #
48
+ # ==== Parameters
49
+ # username<String>:: The username.
50
+ # password<String>:: The password.
51
+ #
37
52
  def login(username, password)
38
- @username = username
39
- @password = password
53
+ handle_fault do
54
+ if @token = proxy.login(username, password)
55
+ Log4r::MDC.put('token', @token)
56
+ log.info "logged in as '#{username}' and acquired token."
40
57
 
41
- request do |confluence|
42
- @token = confluence.login(@username, @password)
58
+ @username = username
59
+ @password = password
60
+ end
43
61
  end
62
+
63
+ @token
44
64
  end
45
65
 
66
+ # Logs out and invalidates the session token.
67
+ #
46
68
  def logout
47
- request do |confluence|
48
- confluence.logout(@token)
69
+ handle_fault do
70
+ @token = nil if @token and result = proxy.logout(@token)
71
+ log.info "logged out"
72
+ Log4r::MDC.put('token', 'nil')
73
+ result
49
74
  end
50
75
  end
51
76
 
77
+ # Translates every call into XMLRPC calls.
78
+ #
52
79
  def method_missing(method_name, *args)
53
- request do |confluence|
54
- confluence.send(method_name, *([@token] + args))
80
+ handle_fault do
81
+ if args.empty?
82
+ log.debug "#{method_name}"
83
+ else
84
+ log.debug "#{method_name}(#{args.join(', ')})"
85
+ end
86
+ result = proxy.send(method_name, *([@token] + args))
87
+ log.debug(result.inspect)
88
+ result
55
89
  end
56
90
  end
57
91
 
58
92
  private
59
-
60
- def request(&block)
93
+
94
+ # Returns the Confluence::Client logger.
95
+ def log
96
+ Log4r::Logger[Confluence::Client.to_s] || Log4r::Logger.root
97
+ end
98
+
99
+ # Returns the Confluence XMLRPC endpoint url.
100
+ #
101
+ def xmlrpc_url
102
+ unless @url[-11..-1] == XMLRPC_SUFFIX
103
+ @url + XMLRPC_SUFFIX
104
+ else
105
+ @url
106
+ end
107
+ end
108
+
109
+ # Returns the XMLRPC client proxy for the Confluence API v1.
110
+ #
111
+ def proxy
112
+ @proxy ||= XMLRPC::Client.new_from_uri(xmlrpc_url).proxy(PREFIX)
113
+ end
114
+
115
+ # Yields and translates any XMLRPC::FaultExceptions raised by Confluence to Confluence::Errors.
116
+ #
117
+ def handle_fault(&block)
61
118
  begin
62
- block.call(@confluence)
119
+ block.call
63
120
  rescue XMLRPC::FaultException => e
64
- case message = e.faultString.rpartition(':').last
121
+ log.warn message = e.faultString.rpartition(':').last
122
+
123
+ case message
65
124
  when /Transaction rolled back/
66
125
  raise Confluence::Error, "Could not save or update record."
67
126
  else
@@ -1,8 +1,16 @@
1
1
  module Confluence
2
2
  class Record
3
3
  class << self
4
+ def client
5
+ raise "Confluence client is unavailable. Did you forget to use Confluence::Session.new?" unless @@client
6
+ @@client
7
+ end
8
+
9
+ def client=(value)
10
+ @@client = value
11
+ end
12
+
4
13
  def record_attr_accessor(*args)
5
-
6
14
  attributes = {}
7
15
 
8
16
  # iterate through each argument
@@ -31,7 +39,12 @@ module Confluence
31
39
  attr_accessor :attributes
32
40
 
33
41
  def initialize(hash)
34
- @attributes = Hash[*(hash.keys.map {|k| k.to_sym}).zip(hash.values).flatten]
42
+ @attributes = {}
43
+
44
+ # iterate through each key/value pair and set attribute keyed by symbol
45
+ hash.each_pair do |key, value|
46
+ self[key.to_sym] = value
47
+ end
35
48
  end
36
49
 
37
50
  def [](attr)
@@ -47,27 +60,17 @@ module Confluence
47
60
  end
48
61
 
49
62
  def labels
50
- client.getLabelsById(record_id).collect {|label| label["name"]}
63
+ @labels ||= client.getLabelsById(record_id).collect {|label| label["name"]}
51
64
  end
52
65
 
53
66
  def labels=(value)
54
- existing_labels = labels
55
- removed_labels = existing_labels - value
56
- added_labels = value - existing_labels
67
+ removed_labels = labels - value
68
+ added_labels = value - labels
57
69
 
58
70
  client.removeLabelByName(removed_labels.join(" "), record_id) unless removed_labels.empty?
59
71
  client.addLabelByName(added_labels.join(" "), record_id) unless added_labels.empty?
60
- end
61
-
62
- @@client = nil
63
-
64
- def self.client
65
- raise "Confluence client is unavailable. Did you forget to use Confluence::Session.new?" unless @@client
66
- @@client
67
- end
68
-
69
- def self.client=(client)
70
- @@client = client
72
+
73
+ @labels = value
71
74
  end
72
75
 
73
76
  def client
@@ -1,11 +1,22 @@
1
1
  module Confluence
2
+ # Wraps a Confluence::Client and manages the lifetime of a session.
3
+ #
2
4
  class Session
3
5
  attr_reader :client
4
6
 
5
- def token
6
- client.token if client
7
- end
8
-
7
+ # Initializes a new session with the given arguments and sets it for other classes like Confluence::Page.
8
+ #
9
+ # If a block is given to initialize, initialize yields with the Confluence::Client and automatically logs out of the session afterwards.
10
+ # Otherwise Session#destroy should be called after finished.
11
+ #
12
+ # ==== Parameters
13
+ # arguments<Hash>:: Described below.
14
+ #
15
+ # ==== Arguments
16
+ # :url - The url of the Confluence instance.
17
+ # :username - The username.
18
+ # :password - The password.
19
+ #
9
20
  def initialize(arguments = {})
10
21
  raise ArgumentError, "Required argument 'url' is missing." unless arguments.key? :url
11
22
 
@@ -19,30 +30,33 @@ module Confluence
19
30
  end
20
31
 
21
32
  # set client for records
22
- Confluence::Record::client = @client
33
+ Confluence::Record.client = @client
23
34
 
35
+ # yield if block was given and destroy afterwards
24
36
  if block_given?
25
- begin
26
- yield @client
27
- rescue RuntimeError => e
28
- # strip non-message part of java exception message
29
- raise e.message.split(":").last.strip
30
- end
37
+ yield @client
31
38
 
32
39
  self.destroy
33
40
  end
34
41
  end
35
42
 
43
+ # Returns the current session token.
44
+ #
45
+ def token
46
+ client.token if client
47
+ end
48
+
49
+ # Destroys the session by logging out and resets other classes like Confluence::Page.
50
+ #
36
51
  def destroy
37
52
  # invalidate the token
38
53
  client.logout
39
54
 
40
- # client and token is not valid anymore
55
+ # client is not valid anymore
41
56
  @client = nil
42
- @token = nil
43
57
 
44
58
  # reset client for records
45
- Confluence::Record::client = nil
59
+ Confluence::Record.client = nil
46
60
  end
47
61
  end
48
62
  end
@@ -1,6 +1,9 @@
1
1
  # ensure that lib is in the load path
2
2
  $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
 
4
+ require 'rubygems'
5
+ require 'log4r'
6
+
4
7
  require 'confluence/error'
5
8
 
6
9
  require 'confluence/client'
@@ -10,3 +13,7 @@ require 'confluence/record'
10
13
  require 'confluence/page'
11
14
  require 'confluence/bookmark'
12
15
  require 'confluence/blog_entry'
16
+
17
+ module Confluencer
18
+ VERSION = "0.2.7"
19
+ end
@@ -4,4 +4,30 @@
4
4
  :username: roger
5
5
  :password: jessica
6
6
  :space: confluencer
7
- :page_title: Confluencer RSpec Test Page
7
+ :page_title: Confluencer RSpec Test Page
8
+
9
+ # Log4r configuration
10
+ log4r_config:
11
+ pre_config:
12
+ global:
13
+ level: DEBUG
14
+ root:
15
+ level: DEBUG
16
+
17
+ # loggers
18
+ loggers:
19
+ - name : Confluence::Client
20
+ level : DEBUG
21
+ additive : 'false'
22
+ trace : 'false'
23
+ outputters:
24
+ - stdout
25
+
26
+ # outputters
27
+ outputters:
28
+ - type : StdoutOutputter
29
+ name : stdout
30
+ level : DEBUG
31
+ formatter:
32
+ type : PatternFormatter
33
+ pattern : '%d %C (%X{token}) [%l]: %m'
@@ -0,0 +1,4 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe Confluence::Bookmark do
4
+ end
@@ -0,0 +1,74 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe Confluence::Client do
4
+ include ConfigurationHelperMethods
5
+
6
+ def new_client_from_config
7
+ Confluence::Client.new(config)
8
+ end
9
+
10
+ def logged_in_client
11
+ client = new_client_from_config
12
+ client.login(config[:username], config[:password])
13
+ client.has_token?.should be_true
14
+ client
15
+ end
16
+
17
+ it "can initialize a client with a url" do
18
+ client = Confluence::Client.new :url => "http://confluence.atlassian.com"
19
+
20
+ client.should_not be_nil
21
+ client.url.should_not be_nil
22
+ client.url.should == "http://confluence.atlassian.com"
23
+ end
24
+
25
+ it "can initialize a client with an existing token" do
26
+ client = Confluence::Client.new :url => "http://confluence.atlassian.com", :token => "abcdef"
27
+ client.token.should_not be_nil
28
+ client.token.should == "abcdef"
29
+ end
30
+
31
+ it "can return whether a token is already available" do
32
+ client = Confluence::Client.new :url => "http://confluence.atlassian.com"
33
+ client.has_token?.should be_false
34
+
35
+ client = Confluence::Client.new :url => "http://confluence.atlassian.com", :token => "abcdef"
36
+ client.has_token?.should be_true
37
+ end
38
+
39
+ it "can log in and acquire a session token" do
40
+ client = new_client_from_config
41
+ client.has_token?.should be_false
42
+
43
+ token = client.login(config[:username], config[:password])
44
+ token.should_not be_nil
45
+
46
+ client.has_token?.should be_true
47
+ client.token.should == token
48
+ end
49
+
50
+ it "raises an error if it cannot login" do
51
+ client = new_client_from_config
52
+
53
+ lambda { client.login(config[:username], "bogus") }.should raise_exception(Confluence::Error, /incorrect password/)
54
+ client.has_token?.should be_false
55
+
56
+ lambda { client.login("bogus", "bogus") }.should raise_exception(Confluence::Error, /no user could be found/)
57
+ client.has_token?.should be_false
58
+ end
59
+
60
+ it "can logout and invalidate a session token" do
61
+ client = logged_in_client
62
+
63
+ client.logout.should be_true
64
+ client.has_token?.should be_false
65
+ end
66
+
67
+ it "can make XMLRPC calls" do
68
+ client = logged_in_client
69
+
70
+ server_info = client.getServerInfo
71
+ server_info.should_not be_nil
72
+ server_info["baseUrl"].should == client.url
73
+ end
74
+ end
@@ -21,9 +21,9 @@ describe Confluence::Page do
21
21
  new_session do
22
22
  begin
23
23
  # check whether we need to remove the test page
24
- test_page = Confluence::Page.find_by_title config[:space], config[:page_title]
24
+ test_page = Confluence::Page.find_by_title config[:space], config[:page_title]
25
25
  test_page.remove if test_page
26
- rescue RuntimeError
26
+ rescue Confluence::Error
27
27
  end
28
28
  end
29
29
  end
@@ -31,7 +31,7 @@ describe Confluence::Page do
31
31
  it "should add a new page in Confluence" do
32
32
  page = nil
33
33
 
34
- new_session do
34
+ new_session do |client|
35
35
  # initialize test page
36
36
  page = create_test_page
37
37
 
@@ -0,0 +1,9 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ describe Confluence::Record do
4
+ it "should initialize new record from Confluence hash" do
5
+ record = Confluence::Record.new :foo => 'bar'
6
+
7
+ record[:foo].should == 'bar'
8
+ end
9
+ end
@@ -6,7 +6,12 @@ require 'spec'
6
6
  require 'spec/autorun'
7
7
  require 'yaml'
8
8
 
9
+ require 'log4r/yamlconfigurator'
10
+
9
11
  Spec::Runner.configure do |config|
12
+ config.before :suite do
13
+ Log4r::YamlConfigurator.load_yaml_file(File.join(File.dirname(__FILE__), 'confluence.yaml'))
14
+ end
10
15
  end
11
16
 
12
17
  module ConfigurationHelperMethods
@@ -22,7 +27,7 @@ module SessionHelperMethods
22
27
  def new_session
23
28
  if block_given?
24
29
  # initialize session and yield
25
- Confluence::Session.new config { yield }
30
+ Confluence::Session.new(config) {|client| yield client }
26
31
  else
27
32
  # initialize session and return
28
33
  Confluence::Session.new config
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 2
8
- - 7
9
- version: 0.2.7
8
+ - 8
9
+ version: 0.2.8
10
10
  platform: ruby
11
11
  authors:
12
12
  - Gabor Ratky
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-05-07 00:00:00 +02:00
17
+ date: 2010-05-11 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -61,7 +61,10 @@ files:
61
61
  - script/console
62
62
  - script/console_init.rb
63
63
  - spec/confluence.yaml.example
64
+ - spec/confluence/bookmark_spec.rb
65
+ - spec/confluence/client_spec.rb
64
66
  - spec/confluence/page_spec.rb
67
+ - spec/confluence/record_spec.rb
65
68
  - spec/confluence/session_spec.rb
66
69
  - spec/confluencer_spec.rb
67
70
  - spec/spec.opts
@@ -97,7 +100,10 @@ signing_key:
97
100
  specification_version: 3
98
101
  summary: Useful classes to manage Confluence.
99
102
  test_files:
103
+ - spec/confluence/bookmark_spec.rb
104
+ - spec/confluence/client_spec.rb
100
105
  - spec/confluence/page_spec.rb
106
+ - spec/confluence/record_spec.rb
101
107
  - spec/confluence/session_spec.rb
102
108
  - spec/confluencer_spec.rb
103
109
  - spec/spec_helper.rb