mhennemeyer-rwriteboard 0.1.0
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 +46 -0
- data/lib/rwriteboard.rb +96 -0
- data/lib/string_extension.rb +20 -0
- data/rwriteboard.gemspec +18 -0
- data/spec/rwriteboard_spec.rb +80 -0
- data/spec/string_extension_spec.rb +61 -0
- metadata +57 -0
data/README
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
= RWriteboard
|
2
|
+
|
3
|
+
by Matthias Hennemeyer <mhennemeyer@gmail.com>
|
4
|
+
|
5
|
+
== Introduction
|
6
|
+
|
7
|
+
Fetch a writeboard by path and password.
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
== Usage
|
12
|
+
|
13
|
+
require 'rwriteboard'
|
14
|
+
|
15
|
+
Create a local reference to a writeboard:
|
16
|
+
Writeboard.create({
|
17
|
+
:name => "some name",
|
18
|
+
:path => "/sadfasdfasdf", # the custom part of the url
|
19
|
+
:password => "123123"
|
20
|
+
})
|
21
|
+
|
22
|
+
Use it to read the title and the body of the writeboard:
|
23
|
+
title = ""
|
24
|
+
body = ""
|
25
|
+
Writeboard.find(:name => "some name") do |writeboard|
|
26
|
+
writeboard.get
|
27
|
+
title = writeboard.title
|
28
|
+
body = writeboard.body
|
29
|
+
end
|
30
|
+
|
31
|
+
Use it to change the title of the writeboard:
|
32
|
+
Writeboard.find(:name => "some name") do |writeboard|
|
33
|
+
writeboard.title = "some other title"
|
34
|
+
writeboard.post_without_revision
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
== INSTALL:
|
42
|
+
|
43
|
+
$ sudo gem install mhennmemeyer-rwriteboard
|
44
|
+
|
45
|
+
|
46
|
+
Copyright (c) 2008 Matthias Hennemeyer, released under the MIT license
|
data/lib/rwriteboard.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
class Writeboard
|
5
|
+
|
6
|
+
attr_accessor :password,
|
7
|
+
:path,
|
8
|
+
:session,
|
9
|
+
:cookie,
|
10
|
+
:http,
|
11
|
+
:name,
|
12
|
+
:header,
|
13
|
+
:title,
|
14
|
+
:body
|
15
|
+
|
16
|
+
@@writeboards ||= []
|
17
|
+
|
18
|
+
def @@writeboards.find(hash)
|
19
|
+
memo = self
|
20
|
+
hash.each do |k,v|
|
21
|
+
memo = memo.detect {|wb| wb.send(k.to_sym) == v}
|
22
|
+
end
|
23
|
+
memo
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize(hash)
|
27
|
+
self.password = hash[:password]
|
28
|
+
self.path = hash[:path]
|
29
|
+
self.name = hash[:name]
|
30
|
+
end
|
31
|
+
|
32
|
+
def get
|
33
|
+
response_body = self.http.get(self.path, self.cookie).body
|
34
|
+
self.title = response_body.scan(%r{<div class="writeboardtitle">(.*?)</div>}m).to_s.strip_tags
|
35
|
+
self.body = response_body.scan(%r{<div class="writeboardbody">(.*?)</div>}m).to_s.strip_tags
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
def logged_in
|
40
|
+
Net::HTTP.start('123.writeboard.com') do |http|
|
41
|
+
login_path = self.path + "/login"
|
42
|
+
self.header = "password=#{self.password}"
|
43
|
+
login_response = http.post(login_path, self.header)
|
44
|
+
cookie = {'Cookie' => login_response.response['Set-Cookie']}
|
45
|
+
self.http = http
|
46
|
+
self.cookie = cookie
|
47
|
+
self.session = cookie['Cookie'][1]
|
48
|
+
yield self
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def post_without_revision(hash={})
|
53
|
+
raise "There is no connection" unless self.http
|
54
|
+
set_attributes_from_hash(hash)
|
55
|
+
self.get unless self.title && self.body
|
56
|
+
postdata = "minor_edit=1" + "&" +
|
57
|
+
"commit=Save over the current version" + "&" +
|
58
|
+
"version[body]=#{self.body.gsub(%r(\\n), "<br />")}" + "&" +
|
59
|
+
"version[title]=#{self.title}"
|
60
|
+
self.http.post(self.path + "/v/create", postdata, self.cookie)
|
61
|
+
end
|
62
|
+
|
63
|
+
def set_attributes_from_hash(hash)
|
64
|
+
hash.each {|k,v| self.send(k.to_s.concat("=").to_sym, v)}
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.create(hash)
|
68
|
+
password = hash[:password]
|
69
|
+
path = hash[:path] || hash[:id] || hash[:address] || ""
|
70
|
+
path = "/" + path unless path =~ /^\//
|
71
|
+
name = hash[:name] || self.count + 1
|
72
|
+
wb = self.new(:password => password, :path => path, :name => name)
|
73
|
+
@@writeboards << wb
|
74
|
+
if block_given?
|
75
|
+
wb.logged_in do |_wb|
|
76
|
+
yield _wb
|
77
|
+
end
|
78
|
+
end
|
79
|
+
wb
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.find(hash)
|
83
|
+
writeboard = self.writeboards.find(hash)
|
84
|
+
writeboard.logged_in do |wb|
|
85
|
+
yield wb
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.count
|
90
|
+
@@writeboards.size
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.writeboards
|
94
|
+
@@writeboards
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
String.module_eval do
|
2
|
+
def compact
|
3
|
+
self.gsub(%r(([ \t\f\r])+), " ").gsub(%r(\n+),"\n").gsub(%r(^\s+), "").gsub(%r(\s+$),"")
|
4
|
+
end
|
5
|
+
|
6
|
+
def cut_runner_output
|
7
|
+
self.split(%r(### RUNNER OUTPUT ###)).first.chomp
|
8
|
+
end
|
9
|
+
|
10
|
+
def replace_newlines
|
11
|
+
self.gsub(%r(<br />), '\n')
|
12
|
+
end
|
13
|
+
|
14
|
+
def remove_tags
|
15
|
+
self.gsub(%r(<[^>]*>), "")
|
16
|
+
end
|
17
|
+
def strip_tags
|
18
|
+
self.replace_newlines.remove_tags.compact
|
19
|
+
end
|
20
|
+
end
|
data/rwriteboard.gemspec
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "rwriteboard"
|
3
|
+
s.version = "0.1.0"
|
4
|
+
s.date = "2008-11-15"
|
5
|
+
s.summary = "Interface to writeboard"
|
6
|
+
s.email = "mhennemeyer@gmail.com"
|
7
|
+
s.homepage = "http://github.com/mhennemeyer/rwriteboard"
|
8
|
+
s.description = "RWriteboard is used to fetch and post writeboard contents"
|
9
|
+
s.has_rdoc = false
|
10
|
+
s.authors = ["Matthias Hennemeyer"]
|
11
|
+
s.files = [
|
12
|
+
"README",
|
13
|
+
"rwriteboard.gemspec",
|
14
|
+
"lib/rwriteboard.rb",
|
15
|
+
"lib/string_extension.rb"]
|
16
|
+
s.test_files = ["spec/rwriteboard_spec.rb",
|
17
|
+
"spec/string_extension_spec.rb"]
|
18
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
def password
|
4
|
+
"HG3pJX7N0z7sY12"
|
5
|
+
end
|
6
|
+
def path
|
7
|
+
"/e97e5d84cd8d39ca6"
|
8
|
+
end
|
9
|
+
|
10
|
+
describe Writeboard do
|
11
|
+
before(:all) do
|
12
|
+
Writeboard.create({
|
13
|
+
:name => "Feature1",
|
14
|
+
:password => password,
|
15
|
+
:path => path
|
16
|
+
})
|
17
|
+
end
|
18
|
+
|
19
|
+
describe ".create(hash)" do
|
20
|
+
it "should add the writeboard with name, password and address to the @@writeboards collection" do
|
21
|
+
Writeboard.writeboards.detect {|wb| wb.name == "Feature1"}.password.should eql(password)
|
22
|
+
end
|
23
|
+
it "should yield the logged in writeboard if block given" do
|
24
|
+
Writeboard.create({
|
25
|
+
:name => "Feature1",
|
26
|
+
:password => password,
|
27
|
+
:path => path
|
28
|
+
}) do |wb|
|
29
|
+
wb.password.should eql(password)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe ".find(hash)" do
|
35
|
+
it "should yield the writeboard, identified by hash and logged in" do
|
36
|
+
Writeboard.find :name => "Feature1" do |wb|
|
37
|
+
wb.password.should eql(password)
|
38
|
+
wb.path.should eql(path)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#get" do
|
44
|
+
it "should get the writeboard" do
|
45
|
+
Writeboard.find :name => "Feature1" do |wb|
|
46
|
+
wb.get.password.should eql(password)
|
47
|
+
wb.get.path.should eql(path)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
it "should set the writeboards title" do
|
51
|
+
Writeboard.find :name => "Feature1" do |wb|
|
52
|
+
wb.get.title.should eql("first writeboard")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
it "should set the writeboards body" do
|
56
|
+
Writeboard.find :name => "Feature1" do |wb|
|
57
|
+
wb.get.body.should eql('Feature: FeatureTitle\n In order to gain profits')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "post_without_revision" do
|
63
|
+
it "should post to the writeboard and make no new revision" do
|
64
|
+
Writeboard.find :name => "Feature1" do |wb|
|
65
|
+
wb.post_without_revision(:body => 'Feature: FeatureTitle\n In order to gain profits')
|
66
|
+
wb.get.body.should eql('Feature: FeatureTitle\n In order to gain profits')
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should get what it posts" do
|
71
|
+
Writeboard.find :name => "Feature1" do |wb|
|
72
|
+
string = 'Feature: FeatureTitle\n In order to gain profits'
|
73
|
+
wb.post_without_revision(:body => string)
|
74
|
+
wb.get.body.should eql(string)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe "String" do
|
4
|
+
|
5
|
+
describe "#compact" do
|
6
|
+
it "should replace any whitespace character except newline with a single space" do
|
7
|
+
string = " sdlkj sdf \t sdfsdf \t \t \t"
|
8
|
+
string.compact.should eql("sdlkj sdf sdfsdf")
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should replace multiple newlines with one newline" do
|
12
|
+
string = " \n sdlkj sdf \t \n \n sdfsdf \n \n \t"
|
13
|
+
string.compact.should eql("sdlkj sdf\nsdfsdf")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#remove_tags" do
|
18
|
+
it "should remove all tags from a string" do
|
19
|
+
html = "<sdf>lksjdlkjasd<kjsadf/><sdf>"
|
20
|
+
html.remove_tags.should eql("lksjdlkjasd")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#replace_newlines" do
|
25
|
+
it "should replace all <br /> tags with '\\n'" do
|
26
|
+
html = "Hello<br />"
|
27
|
+
html.replace_newlines.should eql('Hello\n')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#cut_runner_output" do
|
32
|
+
it "should cut away ### RUNNER OUTPUT ### and any subsequent characters" do
|
33
|
+
html = '\nFeature: FeatureTitle\nIn order to gain profits\n
|
34
|
+
Scenario: On the new calculation Page\nGiven I am on the new calculation page\n
|
35
|
+
### RUNNER OUTPUT ###\nPending Scenarios:\n1) FeatureTitle\nIn order to gain profits (On the new calculation Page\n
|
36
|
+
Given I am on the new calculation page)\n'
|
37
|
+
|
38
|
+
html.cut_runner_output.should eql('\nFeature: FeatureTitle\nIn order to gain profits\n
|
39
|
+
Scenario: On the new calculation Page\nGiven I am on the new calculation page\n')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#strip_tags" do
|
44
|
+
it "should remove all tags except <br /> from a string" do
|
45
|
+
html = <<-END
|
46
|
+
<div class="standard_form">
|
47
|
+
<h3> Sorry, this commit is taking too long to generate. </h3>
|
48
|
+
<p>
|
49
|
+
View it locally:<br /> <code>$ git show 9a3a2ef</code>
|
50
|
+
|
51
|
+
|
52
|
+
</p>
|
53
|
+
</div>
|
54
|
+
END
|
55
|
+
string = "Sorry, this commit is taking too long to generate. " +
|
56
|
+
"View it locally:\n$ git show 9a3a2ef"
|
57
|
+
string.strip_tags.should eql(string)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
metadata
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mhennemeyer-rwriteboard
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matthias Hennemeyer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-11-15 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: RWriteboard is used to fetch and post writeboard contents
|
17
|
+
email: mhennemeyer@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- README
|
26
|
+
- rwriteboard.gemspec
|
27
|
+
- lib/rwriteboard.rb
|
28
|
+
- lib/string_extension.rb
|
29
|
+
has_rdoc: false
|
30
|
+
homepage: http://github.com/mhennemeyer/rwriteboard
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: "0"
|
41
|
+
version:
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
version:
|
48
|
+
requirements: []
|
49
|
+
|
50
|
+
rubyforge_project:
|
51
|
+
rubygems_version: 1.2.0
|
52
|
+
signing_key:
|
53
|
+
specification_version: 2
|
54
|
+
summary: Interface to writeboard
|
55
|
+
test_files:
|
56
|
+
- spec/rwriteboard_spec.rb
|
57
|
+
- spec/string_extension_spec.rb
|