CatchNotes_api 0.1.3 → 0.1.5
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/CHANGELOG.rdoc +4 -0
- data/CatchNotes_api.gemspec +30 -24
- data/README.rdoc +2 -4
- data/VERSION +1 -1
- data/lib/catch_notes.rb +13 -1
- data/lib/catch_notes/base.rb +4 -187
- data/lib/catch_notes/image.rb +81 -0
- data/lib/catch_notes/module/auth_items.rb +33 -0
- data/lib/catch_notes/module/crud_methods.rb +82 -0
- data/lib/catch_notes/module/finder_methods.rb +112 -0
- data/lib/catch_notes/module/image_support.rb +28 -0
- data/test/catch_logo.png +0 -0
- data/test/faker.rb +37 -10
- data/test/helper.rb +2 -0
- data/test/test_image.rb +26 -0
- metadata +14 -7
- data/.gitignore +0 -21
data/CHANGELOG.rdoc
CHANGED
data/CatchNotes_api.gemspec
CHANGED
@@ -5,47 +5,53 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{CatchNotes_api}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.5"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Wade West"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-12-01}
|
13
13
|
s.description = %q{An ActiveResource like interface to catch.com}
|
14
14
|
s.email = %q{wwest81@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
17
|
-
|
17
|
+
"README.rdoc"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".document",
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
21
|
+
"CHANGELOG.rdoc",
|
22
|
+
"CatchNotes_api.gemspec",
|
23
|
+
"LICENSE",
|
24
|
+
"README.rdoc",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"lib/catch_notes.rb",
|
28
|
+
"lib/catch_notes/base.rb",
|
29
|
+
"lib/catch_notes/errors.rb",
|
30
|
+
"lib/catch_notes/image.rb",
|
31
|
+
"lib/catch_notes/module/auth_items.rb",
|
32
|
+
"lib/catch_notes/module/crud_methods.rb",
|
33
|
+
"lib/catch_notes/module/finder_methods.rb",
|
34
|
+
"lib/catch_notes/module/image_support.rb",
|
35
|
+
"lib/catch_notes/tagging.rb",
|
36
|
+
"test/catch_logo.png",
|
37
|
+
"test/faker.rb",
|
38
|
+
"test/helper.rb",
|
39
|
+
"test/note_class.rb",
|
40
|
+
"test/test_catch_notes.rb",
|
41
|
+
"test/test_image.rb",
|
42
|
+
"test/test_tagging.rb"
|
37
43
|
]
|
38
44
|
s.homepage = %q{http://github.com/wadewest/CatchNotes_api}
|
39
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
40
45
|
s.require_paths = ["lib"]
|
41
46
|
s.rubygems_version = %q{1.3.7}
|
42
47
|
s.summary = %q{An ActiveResource like interface to catch.com}
|
43
48
|
s.test_files = [
|
44
49
|
"test/faker.rb",
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
50
|
+
"test/helper.rb",
|
51
|
+
"test/note_class.rb",
|
52
|
+
"test/test_catch_notes.rb",
|
53
|
+
"test/test_image.rb",
|
54
|
+
"test/test_tagging.rb"
|
49
55
|
]
|
50
56
|
|
51
57
|
if s.respond_to? :specification_version then
|
data/README.rdoc
CHANGED
@@ -29,16 +29,14 @@
|
|
29
29
|
my_note.destroy # will return true if all is good
|
30
30
|
|
31
31
|
# listing tags
|
32
|
-
Note.tags
|
32
|
+
Note.tags
|
33
33
|
|
34
34
|
# finding note by a tag
|
35
35
|
my_notes = Note.find_all_by_tag 'blah'
|
36
36
|
|
37
37
|
my_note = Note.find_by_tag 'blah'
|
38
38
|
|
39
|
-
== Todo
|
40
|
-
|
41
|
-
* Add CRUD support for image attachments.
|
39
|
+
== {Todo List}[http://catch-blog.heroku.com/article/20888435]
|
42
40
|
|
43
41
|
== Note on Patches/Pull Requests
|
44
42
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.5
|
data/lib/catch_notes.rb
CHANGED
@@ -2,6 +2,14 @@ module CatchNotes
|
|
2
2
|
module Util
|
3
3
|
|
4
4
|
module ClassMethods
|
5
|
+
# Takes a hash and returns a new hash with all keys
|
6
|
+
# transformed into strings.
|
7
|
+
#
|
8
|
+
# ==== Parameters
|
9
|
+
# * +input_hash+ - The hash to stringify
|
10
|
+
#
|
11
|
+
# ==== Example
|
12
|
+
# stringify_keys( :hello => "world", 1 => 2) # => {'hello' => 'world', '1' => 2}
|
5
13
|
def stringify_keys (input_hash)
|
6
14
|
input_hash.map{|k,v| [k.to_s, v]}.inject({}) do |hash, pair|
|
7
15
|
hash[pair.first] = pair.last
|
@@ -20,7 +28,7 @@ module CatchNotes
|
|
20
28
|
end
|
21
29
|
end
|
22
30
|
|
23
|
-
def self.included(klass)
|
31
|
+
def self.included(klass) #:nodoc:
|
24
32
|
klass.extend ClassMethods
|
25
33
|
end
|
26
34
|
|
@@ -28,5 +36,9 @@ module CatchNotes
|
|
28
36
|
end
|
29
37
|
|
30
38
|
require 'catch_notes/errors'
|
39
|
+
Dir["#{File.dirname(__FILE__)}/catch_notes/module/*.rb"].each do |lib|
|
40
|
+
require lib
|
41
|
+
end
|
31
42
|
require 'catch_notes/base'
|
32
43
|
require 'catch_notes/tagging'
|
44
|
+
require 'catch_notes/image'
|
data/lib/catch_notes/base.rb
CHANGED
@@ -1,202 +1,19 @@
|
|
1
1
|
require 'httparty'
|
2
|
+
|
2
3
|
module CatchNotes
|
3
4
|
class Base
|
4
5
|
|
5
6
|
attr_reader :id, :created_at, :modified_at, :source, :source_url,
|
6
|
-
:children, :user_name, :user_id
|
7
|
-
attr_accessor :text, :summary, :
|
7
|
+
:children, :user_name, :user_id, :tags
|
8
|
+
attr_accessor :text, :summary, :reminder_at, :location
|
8
9
|
|
9
10
|
include HTTParty
|
10
11
|
base_uri "https://api.catch.com/v1"
|
11
12
|
|
12
|
-
# Methods for Authenication
|
13
|
-
module AuthItems
|
14
|
-
module ClassMethods
|
15
|
-
def username( username )
|
16
|
-
send(:basic_auth, username, get_auth[:password] || '')
|
17
|
-
end
|
18
|
-
|
19
|
-
def password( password )
|
20
|
-
send(:basic_auth, get_auth[:username] || '', password)
|
21
|
-
end
|
22
|
-
|
23
|
-
def valid_username?
|
24
|
-
username = get_auth[:username]
|
25
|
-
!(username.nil? || username == '')
|
26
|
-
end
|
27
|
-
|
28
|
-
def valid_password?
|
29
|
-
password = get_auth[:password]
|
30
|
-
!(password.nil? || password == '')
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
def get_auth
|
35
|
-
send(:default_options)[:basic_auth] || {}
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.included(klass)
|
40
|
-
klass.extend ClassMethods
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
# Methods for finding resources
|
45
|
-
module FinderMethods
|
46
|
-
module ClassMethods
|
47
|
-
def all
|
48
|
-
res = get "/notes"
|
49
|
-
build_note_array( res.parsed_response['notes'] ) if send(:ok?, res)
|
50
|
-
end
|
51
|
-
|
52
|
-
def find!(id)
|
53
|
-
res = get "/notes/#{id}"
|
54
|
-
send(:build_from_hash,res.parsed_response['notes'].first ) if send(:ok?,res)
|
55
|
-
end
|
56
|
-
|
57
|
-
def find(id)
|
58
|
-
find!(id)
|
59
|
-
rescue CatchNotes::NotFound
|
60
|
-
nil
|
61
|
-
end
|
62
|
-
|
63
|
-
def find_all_by_tag!( tag_name )
|
64
|
-
res = get "/search?q=%23#{tag_name}"
|
65
|
-
build_note_array( res.parsed_response['notes'] ) if send(:ok?, res)
|
66
|
-
end
|
67
|
-
|
68
|
-
def find_all_by_tag( tag_name )
|
69
|
-
find_all_by_tag!(tag_name)
|
70
|
-
rescue
|
71
|
-
[]
|
72
|
-
end
|
73
|
-
|
74
|
-
def find_by_tag!( tag_name )
|
75
|
-
find_all_by_tag!(tag_name).first
|
76
|
-
end
|
77
|
-
|
78
|
-
def find_by_tag( tag_name )
|
79
|
-
find_all_by_tag!(tag_name).first
|
80
|
-
rescue
|
81
|
-
nil
|
82
|
-
end
|
83
|
-
|
84
|
-
def first
|
85
|
-
all.first
|
86
|
-
end
|
87
|
-
|
88
|
-
def last
|
89
|
-
all.last
|
90
|
-
end
|
91
|
-
|
92
|
-
def tags
|
93
|
-
res = get "/tags"
|
94
|
-
if send(:ok?, res)
|
95
|
-
res.parsed_response['tags'].inject({}) do |hash, t|
|
96
|
-
hash[t['name']] = Tagging.new t, self
|
97
|
-
#hash[t['name'].to_sym] = Tagging.new t, self
|
98
|
-
hash
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
private
|
104
|
-
def build_note_array( notes )
|
105
|
-
notes.map do |note|
|
106
|
-
send :build_from_hash, note
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
def self.included(klass)
|
112
|
-
klass.extend ClassMethods
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
module CRUDMethods
|
117
|
-
|
118
|
-
module ClassMethods
|
119
|
-
private
|
120
|
-
def build_from_hash(hash)
|
121
|
-
send :new, hash
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
def self.included(klass)
|
126
|
-
klass.extend ClassMethods
|
127
|
-
end
|
128
|
-
|
129
|
-
def initialize(attributes)
|
130
|
-
@attr = self.class.send :stringify_keys, attributes
|
131
|
-
@id = @attr['id']
|
132
|
-
@created_at = @attr['created_at']
|
133
|
-
@modified_at = @attr['modified_at']
|
134
|
-
@source = @attr['source']
|
135
|
-
@source_url = @attr['source_url']
|
136
|
-
@children = @attr['children']
|
137
|
-
@text = @attr['text']
|
138
|
-
@summary = @attr['summary']
|
139
|
-
@tags = @attr['tags']
|
140
|
-
@reminder_at = @attr['reminder_at']
|
141
|
-
@location = @attr['location']
|
142
|
-
unless @attr['user'].nil?
|
143
|
-
@user_name = @attr['user']['user_name']
|
144
|
-
@user_id = @attr['user']['id']
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
def save!
|
149
|
-
res = if new_record?
|
150
|
-
self.class.send(:post, "/notes", :body => post_body)
|
151
|
-
else
|
152
|
-
self.class.send(:post, "/notes/#{self.id}", :body => post_body)
|
153
|
-
end
|
154
|
-
if self.class.send(:ok?, res)
|
155
|
-
rebuild res.parsed_response['notes'].first
|
156
|
-
end
|
157
|
-
true
|
158
|
-
end
|
159
|
-
|
160
|
-
def save
|
161
|
-
save!
|
162
|
-
rescue
|
163
|
-
false
|
164
|
-
end
|
165
|
-
|
166
|
-
def destroy!
|
167
|
-
raise CatchNotes::NotFound if new_record? # can't delete an unsaved note
|
168
|
-
res = self.class.send(:delete, "/notes/#{self.id}")
|
169
|
-
self.class.send(:ok?, res)
|
170
|
-
end
|
171
|
-
|
172
|
-
def destroy
|
173
|
-
destroy!
|
174
|
-
rescue
|
175
|
-
false
|
176
|
-
end
|
177
|
-
|
178
|
-
def new_record?
|
179
|
-
i = self.send :id
|
180
|
-
i.nil?
|
181
|
-
end
|
182
|
-
|
183
|
-
private
|
184
|
-
def post_body
|
185
|
-
{
|
186
|
-
'text' => send(:text)
|
187
|
-
}.map{|k,v| "#{URI.encode(k)}=#{URI.encode(v)}"}.join("&")
|
188
|
-
end
|
189
|
-
|
190
|
-
def rebuild(attrs)
|
191
|
-
initialize(attrs)
|
192
|
-
end
|
193
|
-
|
194
|
-
|
195
|
-
end
|
196
|
-
|
197
13
|
include AuthItems
|
198
14
|
include FinderMethods
|
199
15
|
include CRUDMethods
|
16
|
+
include ImageSupport
|
200
17
|
include Util
|
201
18
|
|
202
19
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module CatchNotes
|
2
|
+
class Image
|
3
|
+
|
4
|
+
attr_accessor :url, :data
|
5
|
+
|
6
|
+
def initialize(opts = {})
|
7
|
+
@attr = opts
|
8
|
+
@url = nil
|
9
|
+
@data = nil
|
10
|
+
if opts[:url]
|
11
|
+
init_from_url
|
12
|
+
elsif opts[:file]
|
13
|
+
init_from_file
|
14
|
+
elsif opts[:data]
|
15
|
+
init_from_data
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Sets the url of the image to +new_url+
|
20
|
+
#
|
21
|
+
# ==== Parameters
|
22
|
+
# * +new_url+ - A URL that points to an image. The data attribute will be set to nil when this is set.
|
23
|
+
#
|
24
|
+
# ==== Example
|
25
|
+
# image = CatchNotes::Image.new
|
26
|
+
# image.url = 'http://example.com/hosted/image.jpg'
|
27
|
+
def url=(new_url)
|
28
|
+
@data = nil
|
29
|
+
@url = new_url
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns the raw data of the image. If there is no data, it will be generated from the image at +url+ if it is set.
|
33
|
+
def data
|
34
|
+
if @data.nil? && !@url.nil?
|
35
|
+
res = HTTParty.get(@url)
|
36
|
+
if res.code == 200
|
37
|
+
@data = res.body
|
38
|
+
else
|
39
|
+
raise "Couldn't get #{@url} -- #{res.code}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
@data
|
43
|
+
end
|
44
|
+
|
45
|
+
# Set the raw data of the image to +new_data+. The url attribute will be set to nil when this is set.
|
46
|
+
#
|
47
|
+
# ==== Parameters
|
48
|
+
# * +new_data+ - The data of an image.
|
49
|
+
#
|
50
|
+
# ==== Example
|
51
|
+
# image = CatchNotes::Image.new
|
52
|
+
# image.data = File.read('tmp/some_uploaded_image.jpg')
|
53
|
+
def data=(new_data)
|
54
|
+
@url = nil
|
55
|
+
@data = new_data
|
56
|
+
end
|
57
|
+
|
58
|
+
def destroy! #:nodoc:
|
59
|
+
end
|
60
|
+
|
61
|
+
def destroy #:nodoc:
|
62
|
+
destroy!
|
63
|
+
rescue
|
64
|
+
false
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
def init_from_file
|
69
|
+
@data = File.read(@attr[:file])
|
70
|
+
end
|
71
|
+
|
72
|
+
def init_from_url
|
73
|
+
@url = @attr[:url]
|
74
|
+
end
|
75
|
+
|
76
|
+
def init_from_data
|
77
|
+
@data = @attr[:data]
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module CatchNotes
|
2
|
+
# Methods for Authenication
|
3
|
+
module AuthItems
|
4
|
+
module ClassMethods
|
5
|
+
def username( username )
|
6
|
+
send(:basic_auth, username, get_auth[:password] || '')
|
7
|
+
end
|
8
|
+
|
9
|
+
def password( password )
|
10
|
+
send(:basic_auth, get_auth[:username] || '', password)
|
11
|
+
end
|
12
|
+
|
13
|
+
def valid_username?
|
14
|
+
username = get_auth[:username]
|
15
|
+
!(username.nil? || username == '')
|
16
|
+
end
|
17
|
+
|
18
|
+
def valid_password?
|
19
|
+
password = get_auth[:password]
|
20
|
+
!(password.nil? || password == '')
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def get_auth
|
25
|
+
send(:default_options)[:basic_auth] || {}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.included(klass) #:nodoc:
|
30
|
+
klass.extend ClassMethods
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module CatchNotes
|
2
|
+
module CRUDMethods
|
3
|
+
|
4
|
+
module ClassMethods
|
5
|
+
private
|
6
|
+
def build_from_hash(hash)
|
7
|
+
send :new, hash
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.included(klass) #:nodoc:
|
12
|
+
klass.extend ClassMethods
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(attributes)
|
16
|
+
@attr = self.class.send :stringify_keys, attributes
|
17
|
+
@id = @attr['id']
|
18
|
+
@created_at = @attr['created_at']
|
19
|
+
@modified_at = @attr['modified_at']
|
20
|
+
@source = @attr['source']
|
21
|
+
@source_url = @attr['source_url']
|
22
|
+
@children = @attr['children']
|
23
|
+
@text = @attr['text']
|
24
|
+
@summary = @attr['summary']
|
25
|
+
@tags = @attr['tags']
|
26
|
+
@reminder_at = @attr['reminder_at']
|
27
|
+
@location = @attr['location']
|
28
|
+
unless @attr['user'].nil?
|
29
|
+
@user_name = @attr['user']['user_name']
|
30
|
+
@user_id = @attr['user']['id']
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def save!
|
35
|
+
res = if new_record?
|
36
|
+
self.class.send(:post, "/notes", :body => post_body)
|
37
|
+
else
|
38
|
+
self.class.send(:post, "/notes/#{self.id}", :body => post_body)
|
39
|
+
end
|
40
|
+
if self.class.send(:ok?, res)
|
41
|
+
rebuild res.parsed_response['notes'].first
|
42
|
+
end
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
def save
|
47
|
+
save!
|
48
|
+
rescue
|
49
|
+
false
|
50
|
+
end
|
51
|
+
|
52
|
+
def destroy!
|
53
|
+
raise CatchNotes::NotFound if new_record? # can't delete an unsaved note
|
54
|
+
res = self.class.send(:delete, "/notes/#{self.id}")
|
55
|
+
self.class.send(:ok?, res)
|
56
|
+
end
|
57
|
+
|
58
|
+
def destroy
|
59
|
+
destroy!
|
60
|
+
rescue
|
61
|
+
false
|
62
|
+
end
|
63
|
+
|
64
|
+
def new_record?
|
65
|
+
i = self.send :id
|
66
|
+
i.nil?
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
def post_body
|
71
|
+
{
|
72
|
+
'text' => send(:text)
|
73
|
+
}.map{|k,v| "#{URI.encode(k)}=#{URI.encode(v)}"}.join("&")
|
74
|
+
end
|
75
|
+
|
76
|
+
def rebuild(attrs)
|
77
|
+
initialize(attrs)
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module CatchNotes
|
2
|
+
# Methods for finding resources
|
3
|
+
module FinderMethods
|
4
|
+
module ClassMethods
|
5
|
+
# Returns all notes in the user's catch.com account
|
6
|
+
#
|
7
|
+
# ==== Example
|
8
|
+
# MyNoteClass.all
|
9
|
+
def all
|
10
|
+
res = get "/notes"
|
11
|
+
build_note_array( res.parsed_response['notes'] ) if send(:ok?, res)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns the note with the given +id+. Will raise
|
15
|
+
# a CatchNotes::NotFound exception if the note
|
16
|
+
# doesn't exist.
|
17
|
+
#
|
18
|
+
# ==== Parameters
|
19
|
+
# * +id+ - The id of the note to find
|
20
|
+
#
|
21
|
+
# ==== Example
|
22
|
+
# my_note = MyNoteClass.find!(1234)
|
23
|
+
def find!(id)
|
24
|
+
res = get "/notes/#{id}"
|
25
|
+
send(:build_from_hash,res.parsed_response['notes'].first ) if send(:ok?,res)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Returns the note with the given +id+. Will return
|
29
|
+
# nil if the note doesn't exist.
|
30
|
+
#
|
31
|
+
# ==== Parameters
|
32
|
+
# * +id+ - The id of the note to find
|
33
|
+
#
|
34
|
+
# ==== Example
|
35
|
+
# my_note = MyNoteClass.find(1234)
|
36
|
+
def find(id)
|
37
|
+
find!(id)
|
38
|
+
rescue CatchNotes::NotFound
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns all notes that contain the given +tag_name+. Will
|
43
|
+
# return an empty array if nothing is found, and raises an
|
44
|
+
# exception if something goes wrong.
|
45
|
+
#
|
46
|
+
# ==== Parameters
|
47
|
+
# * +tag_name+ - Then name of the tag to search for.
|
48
|
+
#
|
49
|
+
# ==== Example
|
50
|
+
# notes_about_blah = MyNoteClass.find_all_by_tag!('blah')
|
51
|
+
def find_all_by_tag!( tag_name )
|
52
|
+
res = get "/search?q=%23#{tag_name}"
|
53
|
+
build_note_array( res.parsed_response['notes'] ) if send(:ok?, res)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns all notes that contain the given +tag_name+. Will
|
57
|
+
# return an empty array if nothing is found, and returns
|
58
|
+
# nil if something goes wrong.
|
59
|
+
#
|
60
|
+
# ==== Parameters
|
61
|
+
# * +tag_name+ - Then name of the tag to search for.
|
62
|
+
#
|
63
|
+
# ==== Example
|
64
|
+
# notes_about_blah = MyNoteClass.find_all_by_tag('blah')
|
65
|
+
def find_all_by_tag( tag_name )
|
66
|
+
find_all_by_tag!(tag_name)
|
67
|
+
rescue
|
68
|
+
[]
|
69
|
+
end
|
70
|
+
|
71
|
+
def find_by_tag!( tag_name )
|
72
|
+
find_all_by_tag!(tag_name).first
|
73
|
+
end
|
74
|
+
|
75
|
+
def find_by_tag( tag_name )
|
76
|
+
find_all_by_tag!(tag_name).first
|
77
|
+
rescue
|
78
|
+
nil
|
79
|
+
end
|
80
|
+
|
81
|
+
def first
|
82
|
+
all.first
|
83
|
+
end
|
84
|
+
|
85
|
+
def last
|
86
|
+
all.last
|
87
|
+
end
|
88
|
+
|
89
|
+
def tags
|
90
|
+
res = get "/tags"
|
91
|
+
if send(:ok?, res)
|
92
|
+
res.parsed_response['tags'].inject({}) do |hash, t|
|
93
|
+
hash[t['name']] = Tagging.new t, self
|
94
|
+
#hash[t['name'].to_sym] = Tagging.new t, self
|
95
|
+
hash
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
def build_note_array( notes )
|
102
|
+
notes.map do |note|
|
103
|
+
send :build_from_hash, note
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.included(klass) #:nodoc:
|
109
|
+
klass.extend ClassMethods
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module CatchNotes
|
2
|
+
|
3
|
+
# Adds support for working with an image attached to a note.
|
4
|
+
module ImageSupport
|
5
|
+
|
6
|
+
# Returns true if the note has an attached image.
|
7
|
+
def attached_image?
|
8
|
+
!!((@attr['media'] && @attr['media'].size > 0) || @image)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Returns the images attached to the note
|
12
|
+
def attached_image
|
13
|
+
if attached_image?
|
14
|
+
@image ||= Image.new(:url => @attr['media'].first['src'], :note => self)
|
15
|
+
else
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Sets the image attached to the note, and uploads the image.
|
21
|
+
#
|
22
|
+
# ==== Parameters
|
23
|
+
# * +image_object_or_file_path_or_url+ - Can be one of three things: a CatchNotes::Image instance, a path to a file on the local filesystem, or a url to an image. Passing in nil will delete the current attachment.
|
24
|
+
def attached_image=(image_object_or_file_path_or_url)
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/test/catch_logo.png
ADDED
Binary file
|
data/test/faker.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'rubygems'
|
1
2
|
require 'sinatra/base'
|
2
3
|
require 'json'
|
3
4
|
module Faker
|
@@ -7,16 +8,25 @@ module Faker
|
|
7
8
|
|
8
9
|
class Server < Sinatra::Base
|
9
10
|
|
10
|
-
use Rack::Auth::Basic do |username, password|
|
11
|
-
[username, password] == ['foo@example.com', 'foobar']
|
12
|
-
end
|
13
|
-
|
14
11
|
helpers do
|
12
|
+
def protected!
|
13
|
+
unless authorized?
|
14
|
+
response['WWW-Authenticate'] = %(Basic realm="HTTP Auth")
|
15
|
+
throw(:halt, [401, "Not authorized\n"])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def authorized?
|
20
|
+
@auth ||= Rack::Auth::Basic::Request.new(request.env)
|
21
|
+
@auth.provided? && @auth.basic? && @auth.credentials && @auth.credentials == ['foo@example.com', 'foobar']
|
22
|
+
end
|
23
|
+
|
15
24
|
def build_note(opts = {})
|
16
25
|
opts = {
|
17
26
|
'id' => rand(332422),
|
18
27
|
'text' => "A Note for testing.",
|
19
|
-
'tags' => []
|
28
|
+
'tags' => [],
|
29
|
+
'media' => []
|
20
30
|
}.merge(opts)
|
21
31
|
{
|
22
32
|
"browser_url" => "https:\/\/catch.com\/m\/BPTEv\/6Jmd9SKkP0f",
|
@@ -27,6 +37,7 @@ module Faker
|
|
27
37
|
"tags" => opts['tags'],
|
28
38
|
"modified_at" => "2010-11-03T13:47:28.674Z",
|
29
39
|
"source_url" => "https:\/\/catch.com\/",
|
40
|
+
"media" => opts['media'],
|
30
41
|
"children" => 0,
|
31
42
|
"reminder_at" => nil,
|
32
43
|
"location" => nil,
|
@@ -40,6 +51,11 @@ module Faker
|
|
40
51
|
end
|
41
52
|
end
|
42
53
|
|
54
|
+
PUBLIC_PATHS = []
|
55
|
+
before do
|
56
|
+
protected! unless PUBLIC_PATHS.include? request.path_info
|
57
|
+
end
|
58
|
+
|
43
59
|
# For getting all notes
|
44
60
|
get "/notes" do
|
45
61
|
content_type 'application/json', :charset => 'utf-8'
|
@@ -111,19 +127,30 @@ module Faker
|
|
111
127
|
get '/search' do
|
112
128
|
content_type 'application/json', :charset => 'utf-8'
|
113
129
|
tag = params[:q].gsub(/^#/, '')
|
130
|
+
media = {}
|
131
|
+
if tag == 'image'
|
132
|
+
media = {'media' => [{'src' => "http://#{HOST}:#{PORT}/catch_image.png"}]}
|
133
|
+
end
|
114
134
|
JSON.generate({
|
115
135
|
'notes' => [
|
116
|
-
build_note('text'=>'Test note one', 'tags' => [tag]),
|
117
|
-
build_note('text'=>'Test note
|
118
|
-
build_note('text'=>'Test note
|
119
|
-
build_note('text'=>'Test note
|
136
|
+
build_note({'text'=>'Test note one', 'tags' => [tag]}.merge(media)),
|
137
|
+
build_note({'text'=>'Test note one', 'tags' => [tag]}.merge(media)),
|
138
|
+
build_note({'text'=>'Test note one', 'tags' => [tag]}.merge(media)),
|
139
|
+
build_note({'text'=>'Test note one', 'tags' => [tag]}.merge(media))
|
120
140
|
]
|
121
141
|
})
|
122
142
|
end
|
143
|
+
|
144
|
+
# Image attachments
|
145
|
+
PUBLIC_PATHS.push('/catch_image.png')
|
146
|
+
get '/catch_image.png' do
|
147
|
+
content_type 'image/png'
|
148
|
+
send_file(File.join(File.dirname(__FILE__), 'catch_logo.png'))
|
149
|
+
end
|
123
150
|
end
|
124
151
|
|
125
152
|
Thread.new do
|
126
153
|
Server.run! :host => HOST, :port => PORT.to_i
|
127
154
|
end
|
128
155
|
|
129
|
-
end
|
156
|
+
end
|
data/test/helper.rb
CHANGED
data/test/test_image.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'note_class'
|
3
|
+
|
4
|
+
class TestImage < Test::Unit::TestCase
|
5
|
+
should 'be able to download the image from the fake server' do
|
6
|
+
res = NoteClass.get '/catch_image.png'
|
7
|
+
assert res.code == 200
|
8
|
+
assert_equal res.body, File.read(File.join(TEST_DIR, "catch_logo.png"))
|
9
|
+
end
|
10
|
+
|
11
|
+
should 'be able to get the url of an attached image' do
|
12
|
+
note = NoteClass.find_by_tag 'image'
|
13
|
+
assert_instance_of NoteClass, note
|
14
|
+
assert note.respond_to? :attached_image?
|
15
|
+
assert note.attached_image?
|
16
|
+
assert_equal note.attached_image.url, "http://#{Faker::HOST}:#{Faker::PORT}/catch_image.png"
|
17
|
+
end
|
18
|
+
|
19
|
+
should 'be able to get the data of an attached image' do
|
20
|
+
note = NoteClass.find_by_tag 'image'
|
21
|
+
assert_instance_of NoteClass, note
|
22
|
+
assert note.respond_to? :attached_image?
|
23
|
+
assert note.attached_image?
|
24
|
+
assert_equal note.attached_image.data, File.read(File.join(TEST_DIR, "catch_logo.png"))
|
25
|
+
end
|
26
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: CatchNotes_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 5
|
10
|
+
version: 0.1.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Wade West
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-12-01 00:00:00 -06:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -91,7 +91,6 @@ extra_rdoc_files:
|
|
91
91
|
- README.rdoc
|
92
92
|
files:
|
93
93
|
- .document
|
94
|
-
- .gitignore
|
95
94
|
- CHANGELOG.rdoc
|
96
95
|
- CatchNotes_api.gemspec
|
97
96
|
- LICENSE
|
@@ -101,19 +100,26 @@ files:
|
|
101
100
|
- lib/catch_notes.rb
|
102
101
|
- lib/catch_notes/base.rb
|
103
102
|
- lib/catch_notes/errors.rb
|
103
|
+
- lib/catch_notes/image.rb
|
104
|
+
- lib/catch_notes/module/auth_items.rb
|
105
|
+
- lib/catch_notes/module/crud_methods.rb
|
106
|
+
- lib/catch_notes/module/finder_methods.rb
|
107
|
+
- lib/catch_notes/module/image_support.rb
|
104
108
|
- lib/catch_notes/tagging.rb
|
109
|
+
- test/catch_logo.png
|
105
110
|
- test/faker.rb
|
106
111
|
- test/helper.rb
|
107
112
|
- test/note_class.rb
|
108
113
|
- test/test_catch_notes.rb
|
114
|
+
- test/test_image.rb
|
109
115
|
- test/test_tagging.rb
|
110
116
|
has_rdoc: true
|
111
117
|
homepage: http://github.com/wadewest/CatchNotes_api
|
112
118
|
licenses: []
|
113
119
|
|
114
120
|
post_install_message:
|
115
|
-
rdoc_options:
|
116
|
-
|
121
|
+
rdoc_options: []
|
122
|
+
|
117
123
|
require_paths:
|
118
124
|
- lib
|
119
125
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -146,4 +152,5 @@ test_files:
|
|
146
152
|
- test/helper.rb
|
147
153
|
- test/note_class.rb
|
148
154
|
- test/test_catch_notes.rb
|
155
|
+
- test/test_image.rb
|
149
156
|
- test/test_tagging.rb
|