local_unfuddle_notebook 1.0.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/.gitignore +9 -0
- data/Gemfile +4 -0
- data/Guardfile +17 -0
- data/README.markdown +27 -0
- data/Rakefile +1 -0
- data/bin/lunbook +4 -0
- data/lib/local_unfuddle_notebook.rb +8 -0
- data/lib/local_unfuddle_notebook/app.rb +36 -0
- data/lib/local_unfuddle_notebook/notebook.rb +110 -0
- data/lib/local_unfuddle_notebook/page.rb +44 -0
- data/lib/local_unfuddle_notebook/version.rb +3 -0
- data/local_unfuddle_notebook.gemspec +32 -0
- data/spec/fixtures/webmock/unique_pages_with_single_page.xml +20 -0
- data/spec/lib/local_unfuddle_notebook/app_spec.rb +6 -0
- data/spec/lib/local_unfuddle_notebook/notebook_spec.rb +278 -0
- data/spec/lib/local_unfuddle_notebook/page_spec.rb +97 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +19 -0
- metadata +242 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'rspec', :cli => '--color', :version => 1 do
|
5
|
+
watch(%r{^spec/.+_spec\.rb})
|
6
|
+
watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
|
9
|
+
# Rails example
|
10
|
+
watch('spec/spec_helper.rb') { "spec" }
|
11
|
+
watch('config/routes.rb') { "spec/routing" }
|
12
|
+
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
13
|
+
watch(%r{^spec/.+_spec\.rb})
|
14
|
+
watch(%r{^app/(.+)\.rb}) { |m| "spec/#{m[1]}_spec.rb" }
|
15
|
+
watch(%r{^lib/(.+)\.rb}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
16
|
+
watch(%r{^app/controllers/(.+)_(controller)\.rb}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
17
|
+
end
|
data/README.markdown
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
> lunbook help
|
2
|
+
|
3
|
+
Tasks:
|
4
|
+
lunbook checkout # Download unfuddle notebook and save locally.
|
5
|
+
lunbook help [TASK] # Describe available tasks or one specific task
|
6
|
+
lunbook pull # Update the local copy of your unfuddle notebook
|
7
|
+
lunbook push # Upload updated pages to your unfuddle notebook
|
8
|
+
lunbook status # Check which pages have been updated locally
|
9
|
+
|
10
|
+
|
11
|
+
Usage:
|
12
|
+
lunbook checkout
|
13
|
+
|
14
|
+
Options:
|
15
|
+
-p, [--password=PASSWORD] # Unfuddle password (required)
|
16
|
+
-s, [--subdomain=SUBDOMAIN] # Unfuddle subdomain (required)
|
17
|
+
-u, [--username=USERNAME] # Unfuddle username (required)
|
18
|
+
-r, [--project-id=PROJECT_ID] # Unfuddle project id (required)
|
19
|
+
-n, [--notebook-id=NOTEBOOK_ID] # Unfuddle notebook id (required)
|
20
|
+
-o, [--protocol=PROTOCOL] # http/https (default: http)
|
21
|
+
|
22
|
+
Usage:
|
23
|
+
lunbook push
|
24
|
+
|
25
|
+
Options:
|
26
|
+
-m, [--message=MESSAGE] # Message
|
27
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/lunbook
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'thor'
|
2
|
+
|
3
|
+
module LocalUnfuddleNotebook
|
4
|
+
class App < Thor
|
5
|
+
desc "checkout", "Download unfuddle notebook and save locally."
|
6
|
+
method_option :subdomain, :aliases => '-s', :desc => "Unfuddle subdomain (required)"
|
7
|
+
method_option :username, :aliases => '-u', :desc => "Unfuddle username (required)"
|
8
|
+
method_option :password, :aliases => '-p', :desc => "Unfuddle password (required)"
|
9
|
+
method_option :project_id, :aliases => '-r', :desc => "Unfuddle project id (required)"
|
10
|
+
method_option :notebook_id, :aliases => '-n', :desc => "Unfuddle notebook id (required)"
|
11
|
+
method_option :protocol, :aliases => '-o', :desc => "http/https (default: http)"
|
12
|
+
def checkout
|
13
|
+
Notebook.with_attributes(options).pull
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "pull", "Update the local copy of your unfuddle notebook"
|
17
|
+
def pull
|
18
|
+
Notebook.local.pull
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "push", "Upload updated pages to your unfuddle notebook"
|
22
|
+
method_option :message, :aliases => '-m', :desc => "Message"
|
23
|
+
def push
|
24
|
+
Notebook.local.push options[:message]
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "status", "Check which pages have been updated locally"
|
28
|
+
def status
|
29
|
+
puts "Pages changed locally:"
|
30
|
+
puts Notebook.local.local_pages.select(&:changed?).map{|page|
|
31
|
+
page.local_file.name(true)
|
32
|
+
}.sort
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'crack'
|
2
|
+
require 'rest-client'
|
3
|
+
|
4
|
+
module LocalUnfuddleNotebook
|
5
|
+
class Notebook < RestClient::Resource
|
6
|
+
class << self
|
7
|
+
def attributes_path
|
8
|
+
".local_unfuddle_notebook.yaml"
|
9
|
+
end
|
10
|
+
|
11
|
+
def local
|
12
|
+
with_attributes(saved_attributes)
|
13
|
+
end
|
14
|
+
|
15
|
+
def local_pages_path
|
16
|
+
"pages"
|
17
|
+
end
|
18
|
+
|
19
|
+
def saved_attributes
|
20
|
+
YAML::load(Pow(attributes_path).read) if Pow(attributes_path).file?
|
21
|
+
end
|
22
|
+
|
23
|
+
def with_attributes(attributes)
|
24
|
+
attributes[:protocol] ||= 'http'
|
25
|
+
url = "#{attributes[:protocol]}://#{attributes[:subdomain]}.unfuddle.com/api/v1/projects/#{attributes[:project_id]}/notebooks/#{attributes[:notebook_id]}"
|
26
|
+
Notebook.new(url, attributes[:username], attributes[:password]).tap do |notebook|
|
27
|
+
notebook.last_updated_at = attributes[:last_updated_at]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_accessor :last_updated_at
|
33
|
+
|
34
|
+
def local_attributes
|
35
|
+
{
|
36
|
+
:subdomain => subdomain,
|
37
|
+
:username => user,
|
38
|
+
:password => password,
|
39
|
+
:project_id => project_id,
|
40
|
+
:notebook_id => notebook_id,
|
41
|
+
:last_updated_at => last_updated_at,
|
42
|
+
:protocol => protocol
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
def local_pages
|
47
|
+
Pow(Notebook.local_pages_path).files.map do |file|
|
48
|
+
Page.new(YAML.load(file.read)).tap do |page|
|
49
|
+
page.notebook = self
|
50
|
+
page.local_file = file
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def notebook_id
|
56
|
+
url.match(%r{notebooks/(\d+)})[1].to_i
|
57
|
+
end
|
58
|
+
|
59
|
+
def project_id
|
60
|
+
url.match(%r{projects/(\d+)})[1].to_i
|
61
|
+
end
|
62
|
+
|
63
|
+
def protocol
|
64
|
+
url.match(%r{^(\w*)://})[1]
|
65
|
+
end
|
66
|
+
|
67
|
+
def pull
|
68
|
+
if Pow(self.class.local_pages_path).exists?
|
69
|
+
Pow(self.class.local_pages_path).delete!
|
70
|
+
end
|
71
|
+
|
72
|
+
remote_pages.each do |page|
|
73
|
+
page.save
|
74
|
+
end
|
75
|
+
|
76
|
+
self.last_updated_at = Time.now
|
77
|
+
self.update_attributes_file
|
78
|
+
end
|
79
|
+
|
80
|
+
def push(message)
|
81
|
+
local_pages.select{|page| page.changed?}.each do |page|
|
82
|
+
page.message = message
|
83
|
+
page.push
|
84
|
+
end
|
85
|
+
|
86
|
+
pull
|
87
|
+
end
|
88
|
+
|
89
|
+
def remote_pages
|
90
|
+
Crack::XML.parse(self["pages/unique"].get)['pages'].map do |remote_page_hash|
|
91
|
+
page_attributes = remote_page_hash.delete_if{|k, v| ! Page.attributes.include?(k.to_sym) }
|
92
|
+
Page.new(page_attributes).tap do |page|
|
93
|
+
page.notebook = self
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def subdomain
|
99
|
+
url.match(%r{http.*://(.*)\.unfuddle.com})[1]
|
100
|
+
end
|
101
|
+
|
102
|
+
def update_attributes_file
|
103
|
+
Pow(self.class.attributes_path).write local_attributes.to_yaml
|
104
|
+
end
|
105
|
+
|
106
|
+
def url_with_basic_auth(suburl)
|
107
|
+
self[suburl].url.sub("#{protocol}://", "#{protocol}://#{user}:#{password}@")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'valuable'
|
2
|
+
|
3
|
+
module LocalUnfuddleNotebook
|
4
|
+
class Page < Valuable
|
5
|
+
has_value :body
|
6
|
+
has_value :id
|
7
|
+
has_value :notebook
|
8
|
+
has_value :local_file
|
9
|
+
has_value :message
|
10
|
+
has_value :title
|
11
|
+
|
12
|
+
def basename
|
13
|
+
"#{title.gsub(/\W/, '-')}.yaml".downcase
|
14
|
+
end
|
15
|
+
|
16
|
+
def changed?
|
17
|
+
notebook.last_updated_at < local_file.mtime
|
18
|
+
end
|
19
|
+
|
20
|
+
def local_attributes
|
21
|
+
{
|
22
|
+
:body => body,
|
23
|
+
:id => id,
|
24
|
+
:title => title
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def push
|
29
|
+
notebook["/pages/#{id}"].put :page => remote_attributes
|
30
|
+
end
|
31
|
+
|
32
|
+
def remote_attributes
|
33
|
+
{
|
34
|
+
:title => title,
|
35
|
+
:body => body,
|
36
|
+
:message => message
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def save
|
41
|
+
(Pow(Notebook.local_pages_path)/basename).write(local_attributes.to_yaml)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "local_unfuddle_notebook/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "local_unfuddle_notebook"
|
7
|
+
s.version = LocalUnfuddleNotebook::VERSION
|
8
|
+
s.authors = ["George Mendoza"]
|
9
|
+
s.email = ["gsmendoza@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = "Download unfuddle notebook and save locally"
|
12
|
+
s.description = "Download unfuddle notebook and save locally"
|
13
|
+
|
14
|
+
s.rubyforge_project = "local_unfuddle_notebook"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_development_dependency "guard", '~> 0.6.2'
|
22
|
+
s.add_development_dependency 'guard-rspec', '~> 0.3.1'
|
23
|
+
s.add_development_dependency 'guard-rspec', '~> 0.3.1'
|
24
|
+
s.add_development_dependency "rspec", '~> 1.3.2'
|
25
|
+
s.add_development_dependency 'ruby-debug', '~> 0.10.4'
|
26
|
+
s.add_development_dependency 'webmock', '~> 1.6.2'
|
27
|
+
|
28
|
+
s.add_runtime_dependency "pow", '~> 0.2.3'
|
29
|
+
s.add_runtime_dependency "rest-client", '~> 1.6.3'
|
30
|
+
s.add_runtime_dependency 'thor', '~> 0.14.6'
|
31
|
+
s.add_runtime_dependency "valuable", '~> 0.8.5'
|
32
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<pages type="array">
|
3
|
+
<page>
|
4
|
+
<author-id type="integer">23</author-id>
|
5
|
+
<body>Body
|
6
|
+
# Head
|
7
|
+
code
|
8
|
+
</body>
|
9
|
+
<body-format>markdown</body-format>
|
10
|
+
<id type="integer">268</id>
|
11
|
+
<message>This is a message.</message>
|
12
|
+
<message-format>markdown</message-format>
|
13
|
+
<notebook-id type="integer">11</notebook-id>
|
14
|
+
<number type="integer">8</number>
|
15
|
+
<title>This is the title.</title>
|
16
|
+
<version type="integer">12</version>
|
17
|
+
<created-at>2011-10-12T08:29:21Z</created-at>
|
18
|
+
<updated-at>2011-10-12T08:29:21Z</updated-at>
|
19
|
+
</page>
|
20
|
+
</pages>
|
@@ -0,0 +1,278 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module LocalUnfuddleNotebook
|
4
|
+
describe Notebook do
|
5
|
+
let :last_updated_at do
|
6
|
+
Time.now
|
7
|
+
end
|
8
|
+
|
9
|
+
let :attributes do
|
10
|
+
{
|
11
|
+
:subdomain => 'hmsinc',
|
12
|
+
:username => 'gsmendoza',
|
13
|
+
:password => '12345678',
|
14
|
+
:project_id => 15,
|
15
|
+
:notebook_id => 11,
|
16
|
+
:last_updated_at => last_updated_at,
|
17
|
+
:protocol => 'http'
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "with_attributes(settings)" do
|
22
|
+
it "should build a new notebook with the given settings" do
|
23
|
+
attributes[:protocol] = 'https'
|
24
|
+
notebook = Notebook.with_attributes(attributes)
|
25
|
+
notebook.url.should == "https://hmsinc.unfuddle.com/api/v1/projects/15/notebooks/11"
|
26
|
+
notebook.user.should == 'gsmendoza'
|
27
|
+
notebook.password.should == '12345678'
|
28
|
+
notebook.last_updated_at.should == last_updated_at
|
29
|
+
notebook.protocol.should == 'https'
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should set the protocol to http by default" do
|
33
|
+
notebook = Notebook.with_attributes({})
|
34
|
+
notebook.protocol.should == 'http'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "pull" do
|
39
|
+
it "should save the notebook pages in the local pages path" do
|
40
|
+
Pow(Notebook.local_pages_path).should_not exist
|
41
|
+
|
42
|
+
notebook = Notebook.with_attributes(attributes)
|
43
|
+
|
44
|
+
stub_request(:get, notebook.url_with_basic_auth('pages/unique')).
|
45
|
+
to_return(:body => Pow('spec/fixtures/webmock/unique_pages_with_single_page.xml').read)
|
46
|
+
|
47
|
+
notebook.pull
|
48
|
+
|
49
|
+
notebook.remote_pages.should have(1).page
|
50
|
+
Pow(Notebook.local_pages_path).should exist
|
51
|
+
Pow(Notebook.local_pages_path).files.should have(1).file
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should clear the local pages page before downloading the pages from remote" do
|
55
|
+
Pow(Notebook.local_pages_path).create_directory do
|
56
|
+
Pow("1-title.yaml").create_file
|
57
|
+
end
|
58
|
+
Pow(Notebook.local_pages_path).files.should have(1).file
|
59
|
+
|
60
|
+
notebook = Notebook.with_attributes(attributes)
|
61
|
+
|
62
|
+
no_pages_in_response_body = <<-EOS
|
63
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
64
|
+
<pages type="array">
|
65
|
+
</pages>
|
66
|
+
EOS
|
67
|
+
|
68
|
+
stub_request(:get, notebook.url_with_basic_auth('pages/unique')).
|
69
|
+
to_return(:body => no_pages_in_response_body)
|
70
|
+
|
71
|
+
notebook.pull
|
72
|
+
|
73
|
+
Pow(Notebook.local_pages_path).should_not exist
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should set the last_updated_at time of the notebook to now" do
|
77
|
+
time_now = Time.now
|
78
|
+
Time.stub(:now).and_return(time_now)
|
79
|
+
|
80
|
+
notebook = Notebook.with_attributes(attributes)
|
81
|
+
notebook.last_updated_at = nil
|
82
|
+
|
83
|
+
stub_request(:get, notebook.url_with_basic_auth('pages/unique')).
|
84
|
+
to_return(:body => Pow('spec/fixtures/webmock/unique_pages_with_single_page.xml').read)
|
85
|
+
|
86
|
+
notebook.pull
|
87
|
+
notebook.last_updated_at.should == time_now
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should save the local attributes of the notebook" do
|
91
|
+
time_now = Time.now
|
92
|
+
Time.stub(:now).and_return(time_now)
|
93
|
+
|
94
|
+
notebook = Notebook.with_attributes(attributes)
|
95
|
+
|
96
|
+
stub_request(:get, notebook.url_with_basic_auth('pages/unique')).
|
97
|
+
to_return(:body => Pow('spec/fixtures/webmock/unique_pages_with_single_page.xml').read)
|
98
|
+
|
99
|
+
notebook.pull
|
100
|
+
|
101
|
+
local_attributes = {
|
102
|
+
:subdomain => 'hmsinc',
|
103
|
+
:username => 'gsmendoza',
|
104
|
+
:password => '12345678',
|
105
|
+
:project_id => 15,
|
106
|
+
:notebook_id => 11,
|
107
|
+
:last_updated_at => time_now,
|
108
|
+
:protocol => 'http'
|
109
|
+
}
|
110
|
+
|
111
|
+
Pow(Notebook.attributes_path).should be_a_file
|
112
|
+
Pow(Notebook.attributes_path).read.should == local_attributes.to_yaml
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "remote_pages" do
|
117
|
+
it "should be the pages of the notebook from unfuddle" do
|
118
|
+
notebook = Notebook.with_attributes(attributes)
|
119
|
+
|
120
|
+
response_body = <<-EOS
|
121
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
122
|
+
<pages type="array">
|
123
|
+
<page>
|
124
|
+
<author-id type="integer">23</author-id>
|
125
|
+
<body>Body
|
126
|
+
# Head
|
127
|
+
code
|
128
|
+
</body>
|
129
|
+
<body-format>markdown</body-format>
|
130
|
+
<id type="integer">268</id>
|
131
|
+
<message>This is a message.</message>
|
132
|
+
<message-format>markdown</message-format>
|
133
|
+
<notebook-id type="integer">11</notebook-id>
|
134
|
+
<number type="integer">8</number>
|
135
|
+
<title>This is the title.</title>
|
136
|
+
<version type="integer">12</version>
|
137
|
+
<created-at>2011-10-12T08:29:21Z</created-at>
|
138
|
+
<updated-at>2011-10-12T08:29:21Z</updated-at>
|
139
|
+
</page>
|
140
|
+
</pages>
|
141
|
+
EOS
|
142
|
+
|
143
|
+
stub_request(:get, notebook.url_with_basic_auth('pages/unique')).
|
144
|
+
to_return(:body => response_body)
|
145
|
+
|
146
|
+
remote_pages = notebook.remote_pages
|
147
|
+
remote_pages.should have(1).page
|
148
|
+
|
149
|
+
page = remote_pages[0]
|
150
|
+
page.id.should == 268
|
151
|
+
page.title.should == 'This is the title.'
|
152
|
+
page.notebook.should == notebook
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe "saved_attributes" do
|
157
|
+
it "should get the connection settings from the local connection settings file" do
|
158
|
+
Pow(Notebook.attributes_path).should_not exist
|
159
|
+
Notebook.saved_attributes.should be_nil
|
160
|
+
|
161
|
+
content = <<-EOS
|
162
|
+
--- !map:Thor::CoreExt::HashWithIndifferentAccess
|
163
|
+
notebook_id: "11"
|
164
|
+
project_id: "15"
|
165
|
+
username: gsmendoza
|
166
|
+
subdomain: hmsinc
|
167
|
+
password: 12345678
|
168
|
+
EOS
|
169
|
+
|
170
|
+
Pow(Notebook.attributes_path).write(content)
|
171
|
+
|
172
|
+
settings = Notebook.saved_attributes
|
173
|
+
settings[:username].should == 'gsmendoza'
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "url_with_basic_auth(suburl)" do
|
178
|
+
it "should be add the user and password to the suburl" do
|
179
|
+
notebook = Notebook.with_attributes(attributes)
|
180
|
+
|
181
|
+
notebook.url_with_basic_auth('pages/unique').should ==
|
182
|
+
"http://gsmendoza:12345678@hmsinc.unfuddle.com/api/v1/projects/15/notebooks/11/pages/unique"
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe "local_attributes" do
|
187
|
+
it "should be the attributes of the notebook intended for saving" do
|
188
|
+
notebook = Notebook.with_attributes(attributes)
|
189
|
+
notebook.last_updated_at = time_now = Time.now
|
190
|
+
|
191
|
+
notebook.local_attributes.should == {
|
192
|
+
:subdomain => 'hmsinc',
|
193
|
+
:username => 'gsmendoza',
|
194
|
+
:password => '12345678',
|
195
|
+
:project_id => 15,
|
196
|
+
:notebook_id => 11,
|
197
|
+
:last_updated_at => time_now,
|
198
|
+
:protocol => 'http'
|
199
|
+
}
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe "subdomain" do
|
204
|
+
it "should come from the url" do
|
205
|
+
notebook = Notebook.new("http://sub.domain.unfuddle.com")
|
206
|
+
notebook.subdomain.should == "sub.domain"
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
describe "project_id" do
|
211
|
+
it "should come from the url" do
|
212
|
+
notebook = Notebook.new("http://hmsinc.unfuddle.com/api/v1/projects/15/notebooks/11/pages/unique")
|
213
|
+
notebook.project_id.should == 15
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
describe "notebook_id" do
|
218
|
+
it "should come from the url" do
|
219
|
+
notebook = Notebook.new("http://hmsinc.unfuddle.com/api/v1/projects/15/notebooks/11/pages/unique")
|
220
|
+
notebook.notebook_id.should == 11
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
describe "local_pages" do
|
225
|
+
it "should be the pages stored locally" do
|
226
|
+
|
227
|
+
attributes = {
|
228
|
+
:id => 1,
|
229
|
+
:title => 'This is a title',
|
230
|
+
:body => 'This is a body',
|
231
|
+
:message => 'This is a message'
|
232
|
+
}
|
233
|
+
(Pow(Notebook.local_pages_path) / "1-this-is-a-title.yaml").write attributes.to_yaml
|
234
|
+
|
235
|
+
notebook = Notebook.new("url")
|
236
|
+
local_pages = notebook.local_pages
|
237
|
+
local_pages.should have(1).page
|
238
|
+
|
239
|
+
local_page = local_pages.first
|
240
|
+
|
241
|
+
local_page.id.should == 1
|
242
|
+
local_page.notebook.should == notebook
|
243
|
+
local_page.local_file.name(true).should == "1-this-is-a-title.yaml"
|
244
|
+
local_page.title.should == 'This is a title'
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
describe "push" do
|
249
|
+
it "should upload a changed page to unfuddle" do
|
250
|
+
page = Page.new
|
251
|
+
page.should_receive(:changed?).and_return(true)
|
252
|
+
page.should_receive(:message=).with("message")
|
253
|
+
page.should_receive(:push)
|
254
|
+
|
255
|
+
notebook = Notebook.with_attributes(attributes)
|
256
|
+
notebook.should_receive(:local_pages).and_return([page])
|
257
|
+
notebook.should_receive :pull
|
258
|
+
notebook.push 'message'
|
259
|
+
end
|
260
|
+
|
261
|
+
it "should pull afterwards to update the ids and the last_updated_at" do
|
262
|
+
Pow(Notebook.local_pages_path).create_directory
|
263
|
+
|
264
|
+
notebook = Notebook.with_attributes(attributes)
|
265
|
+
notebook.should_receive :pull
|
266
|
+
notebook.push 'message'
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
describe "protocol" do
|
271
|
+
it "should come from the url" do
|
272
|
+
notebook = Notebook.new("https://hmsinc.unfuddle.com")
|
273
|
+
notebook.protocol.should == 'https'
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module LocalUnfuddleNotebook
|
4
|
+
describe Page do
|
5
|
+
describe "save" do
|
6
|
+
it "should save the page in the local pages path" do
|
7
|
+
Pow(Notebook.local_pages_path).should_not exist
|
8
|
+
|
9
|
+
attributes = {
|
10
|
+
:id => 1,
|
11
|
+
:title => 'This is a title',
|
12
|
+
:body => 'This is a body',
|
13
|
+
:message => 'This is a message'
|
14
|
+
}
|
15
|
+
|
16
|
+
page = Page.new(attributes)
|
17
|
+
page.save
|
18
|
+
|
19
|
+
page_local_file = (Pow(Notebook.local_pages_path)/page.basename)
|
20
|
+
page_local_file.should exist
|
21
|
+
page_local_file.read.should == page.local_attributes.to_yaml
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "basename" do
|
26
|
+
it "should be the basename of the page's local file" do
|
27
|
+
page = Page.new(:id => 1, :title => 'Testing: Title')
|
28
|
+
page.basename.should == 'testing--title.yaml'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "local_attributes" do
|
33
|
+
it "should be the attributes of the page that can be saved locally" do
|
34
|
+
attributes = {
|
35
|
+
:id => 1,
|
36
|
+
:title => 'This is a title',
|
37
|
+
:body => 'This is a body',
|
38
|
+
:message => 'This is a message'
|
39
|
+
}
|
40
|
+
|
41
|
+
page = Page.new(attributes)
|
42
|
+
page.local_attributes.should == {
|
43
|
+
:id => 1,
|
44
|
+
:title => 'This is a title',
|
45
|
+
:body => 'This is a body'
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "changed?" do
|
51
|
+
it "should be true if the page's local file was updated after the notebook's last pull timestamp" do
|
52
|
+
notebook = Notebook.new('')
|
53
|
+
notebook.last_updated_at = Time.now
|
54
|
+
|
55
|
+
file = (Pow(Notebook.local_pages_path) / "1-title.yaml").create
|
56
|
+
file.should_receive(:mtime).and_return(notebook.last_updated_at + 60)
|
57
|
+
|
58
|
+
page = Page.new(:notebook => notebook, :local_file => file)
|
59
|
+
page.should be_changed
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should be false if the page's local file is the same as last pull timestamp" do
|
63
|
+
notebook = Notebook.new('')
|
64
|
+
notebook.last_updated_at = Time.now
|
65
|
+
|
66
|
+
file = (Pow(Notebook.local_pages_path) / "1-title.yaml").create
|
67
|
+
file.should_receive(:mtime).and_return(notebook.last_updated_at)
|
68
|
+
|
69
|
+
page = Page.new(:notebook => notebook, :local_file => file)
|
70
|
+
page.should_not be_changed
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "push" do
|
75
|
+
it "should push the page's remote attributes to unfuddle" do
|
76
|
+
notebook = Notebook.new('http://test.unfuddle.com')
|
77
|
+
stub_request(:put, notebook["pages/1"].url.to_s).to_return(:body => '')
|
78
|
+
|
79
|
+
page = Page.new(:notebook => notebook, :id => 1)
|
80
|
+
page.push
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "remote_attributes" do
|
85
|
+
it "should be the attributes that can be put to unfuddle" do
|
86
|
+
expected_attributes = {
|
87
|
+
:title => 'This is a title',
|
88
|
+
:body => 'This is a body',
|
89
|
+
:message => 'This is a message'
|
90
|
+
}
|
91
|
+
|
92
|
+
page = Page.new(expected_attributes.merge(:id => 1))
|
93
|
+
page.remote_attributes.should == expected_attributes
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'local_unfuddle_notebook'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'ruby-debug'
|
4
|
+
require 'webmock/rspec'
|
5
|
+
|
6
|
+
Spec::Runner.configure do |config|
|
7
|
+
config.before :each do
|
8
|
+
LocalUnfuddleNotebook::Notebook.stub(:local_pages_path).and_return("tmp/pages")
|
9
|
+
if Pow(LocalUnfuddleNotebook::Notebook.local_pages_path).exists?
|
10
|
+
Pow(LocalUnfuddleNotebook::Notebook.local_pages_path).delete!
|
11
|
+
end
|
12
|
+
|
13
|
+
LocalUnfuddleNotebook::Notebook.stub(:attributes_path).and_return("tmp/local_unfuddle_notebook.yaml")
|
14
|
+
if Pow(LocalUnfuddleNotebook::Notebook.attributes_path).exists?
|
15
|
+
Pow(LocalUnfuddleNotebook::Notebook.attributes_path).delete
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
metadata
ADDED
@@ -0,0 +1,242 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: local_unfuddle_notebook
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
version: 1.0.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- George Mendoza
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-10-31 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: guard
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
- 6
|
32
|
+
- 2
|
33
|
+
version: 0.6.2
|
34
|
+
type: :development
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: guard-rspec
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 17
|
45
|
+
segments:
|
46
|
+
- 0
|
47
|
+
- 3
|
48
|
+
- 1
|
49
|
+
version: 0.3.1
|
50
|
+
type: :development
|
51
|
+
version_requirements: *id002
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: guard-rspec
|
54
|
+
prerelease: false
|
55
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ~>
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 17
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
- 3
|
64
|
+
- 1
|
65
|
+
version: 0.3.1
|
66
|
+
type: :development
|
67
|
+
version_requirements: *id003
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: rspec
|
70
|
+
prerelease: false
|
71
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
hash: 31
|
77
|
+
segments:
|
78
|
+
- 1
|
79
|
+
- 3
|
80
|
+
- 2
|
81
|
+
version: 1.3.2
|
82
|
+
type: :development
|
83
|
+
version_requirements: *id004
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: ruby-debug
|
86
|
+
prerelease: false
|
87
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ~>
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
hash: 63
|
93
|
+
segments:
|
94
|
+
- 0
|
95
|
+
- 10
|
96
|
+
- 4
|
97
|
+
version: 0.10.4
|
98
|
+
type: :development
|
99
|
+
version_requirements: *id005
|
100
|
+
- !ruby/object:Gem::Dependency
|
101
|
+
name: webmock
|
102
|
+
prerelease: false
|
103
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
105
|
+
requirements:
|
106
|
+
- - ~>
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
hash: 11
|
109
|
+
segments:
|
110
|
+
- 1
|
111
|
+
- 6
|
112
|
+
- 2
|
113
|
+
version: 1.6.2
|
114
|
+
type: :development
|
115
|
+
version_requirements: *id006
|
116
|
+
- !ruby/object:Gem::Dependency
|
117
|
+
name: pow
|
118
|
+
prerelease: false
|
119
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
120
|
+
none: false
|
121
|
+
requirements:
|
122
|
+
- - ~>
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
hash: 17
|
125
|
+
segments:
|
126
|
+
- 0
|
127
|
+
- 2
|
128
|
+
- 3
|
129
|
+
version: 0.2.3
|
130
|
+
type: :runtime
|
131
|
+
version_requirements: *id007
|
132
|
+
- !ruby/object:Gem::Dependency
|
133
|
+
name: rest-client
|
134
|
+
prerelease: false
|
135
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
136
|
+
none: false
|
137
|
+
requirements:
|
138
|
+
- - ~>
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
hash: 9
|
141
|
+
segments:
|
142
|
+
- 1
|
143
|
+
- 6
|
144
|
+
- 3
|
145
|
+
version: 1.6.3
|
146
|
+
type: :runtime
|
147
|
+
version_requirements: *id008
|
148
|
+
- !ruby/object:Gem::Dependency
|
149
|
+
name: thor
|
150
|
+
prerelease: false
|
151
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
152
|
+
none: false
|
153
|
+
requirements:
|
154
|
+
- - ~>
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
hash: 43
|
157
|
+
segments:
|
158
|
+
- 0
|
159
|
+
- 14
|
160
|
+
- 6
|
161
|
+
version: 0.14.6
|
162
|
+
type: :runtime
|
163
|
+
version_requirements: *id009
|
164
|
+
- !ruby/object:Gem::Dependency
|
165
|
+
name: valuable
|
166
|
+
prerelease: false
|
167
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
168
|
+
none: false
|
169
|
+
requirements:
|
170
|
+
- - ~>
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
hash: 53
|
173
|
+
segments:
|
174
|
+
- 0
|
175
|
+
- 8
|
176
|
+
- 5
|
177
|
+
version: 0.8.5
|
178
|
+
type: :runtime
|
179
|
+
version_requirements: *id010
|
180
|
+
description: Download unfuddle notebook and save locally
|
181
|
+
email:
|
182
|
+
- gsmendoza@gmail.com
|
183
|
+
executables:
|
184
|
+
- lunbook
|
185
|
+
extensions: []
|
186
|
+
|
187
|
+
extra_rdoc_files: []
|
188
|
+
|
189
|
+
files:
|
190
|
+
- .gitignore
|
191
|
+
- Gemfile
|
192
|
+
- Guardfile
|
193
|
+
- README.markdown
|
194
|
+
- Rakefile
|
195
|
+
- bin/lunbook
|
196
|
+
- lib/local_unfuddle_notebook.rb
|
197
|
+
- lib/local_unfuddle_notebook/app.rb
|
198
|
+
- lib/local_unfuddle_notebook/notebook.rb
|
199
|
+
- lib/local_unfuddle_notebook/page.rb
|
200
|
+
- lib/local_unfuddle_notebook/version.rb
|
201
|
+
- local_unfuddle_notebook.gemspec
|
202
|
+
- spec/fixtures/webmock/unique_pages_with_single_page.xml
|
203
|
+
- spec/lib/local_unfuddle_notebook/app_spec.rb
|
204
|
+
- spec/lib/local_unfuddle_notebook/notebook_spec.rb
|
205
|
+
- spec/lib/local_unfuddle_notebook/page_spec.rb
|
206
|
+
- spec/spec.opts
|
207
|
+
- spec/spec_helper.rb
|
208
|
+
homepage: ""
|
209
|
+
licenses: []
|
210
|
+
|
211
|
+
post_install_message:
|
212
|
+
rdoc_options: []
|
213
|
+
|
214
|
+
require_paths:
|
215
|
+
- lib
|
216
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
217
|
+
none: false
|
218
|
+
requirements:
|
219
|
+
- - ">="
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
hash: 3
|
222
|
+
segments:
|
223
|
+
- 0
|
224
|
+
version: "0"
|
225
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
226
|
+
none: false
|
227
|
+
requirements:
|
228
|
+
- - ">="
|
229
|
+
- !ruby/object:Gem::Version
|
230
|
+
hash: 3
|
231
|
+
segments:
|
232
|
+
- 0
|
233
|
+
version: "0"
|
234
|
+
requirements: []
|
235
|
+
|
236
|
+
rubyforge_project: local_unfuddle_notebook
|
237
|
+
rubygems_version: 1.8.10
|
238
|
+
signing_key:
|
239
|
+
specification_version: 3
|
240
|
+
summary: Download unfuddle notebook and save locally
|
241
|
+
test_files: []
|
242
|
+
|