magnolia 1.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/CHANGELOG +0 -0
- data/README +3 -0
- data/Rakefile +85 -0
- data/examples/examples.rb +108 -0
- data/lib/magnolia.rb +1 -0
- data/lib/magnolia/magnolia.rb +486 -0
- data/lib/magnolia/version.rb +9 -0
- data/test/magnolia_test.rb +11 -0
- data/test/test_helper.rb +2 -0
- metadata +65 -0
data/CHANGELOG
ADDED
File without changes
|
data/README
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/packagetask'
|
6
|
+
require 'rake/gempackagetask'
|
7
|
+
require 'rake/rdoctask'
|
8
|
+
require 'rake/contrib/rubyforgepublisher'
|
9
|
+
require 'fileutils'
|
10
|
+
include FileUtils
|
11
|
+
require File.join(File.dirname(__FILE__), 'lib', 'magnolia', 'version')
|
12
|
+
|
13
|
+
AUTHOR = "John Nunemaker"
|
14
|
+
EMAIL = "nunemaker@gmail.com"
|
15
|
+
DESCRIPTION = "Library which makes it really easy to access your ma.gnolia bookmarks"
|
16
|
+
RUBYFORGE_PROJECT = "magnolia"
|
17
|
+
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
18
|
+
BIN_FILES = %w( )
|
19
|
+
|
20
|
+
|
21
|
+
NAME = "magnolia"
|
22
|
+
REV = File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
|
23
|
+
VERS = ENV['VERSION'] || (Magnolium::VERSION::STRING + (REV ? ".#{REV}" : ""))
|
24
|
+
CLEAN.include ['**/.*.sw?', '*.gem', '.config']
|
25
|
+
RDOC_OPTS = ['--quiet', '--title', "magnolia documentation",
|
26
|
+
"--opname", "index.html",
|
27
|
+
"--line-numbers",
|
28
|
+
"--main", "README",
|
29
|
+
"--inline-source"]
|
30
|
+
|
31
|
+
desc "Packages up magnolia gem."
|
32
|
+
task :default => [:test]
|
33
|
+
task :package => [:clean]
|
34
|
+
|
35
|
+
Rake::TestTask.new("test") { |t|
|
36
|
+
t.libs << "test"
|
37
|
+
t.pattern = "test/**/*_test.rb"
|
38
|
+
t.verbose = true
|
39
|
+
}
|
40
|
+
|
41
|
+
spec =
|
42
|
+
Gem::Specification.new do |s|
|
43
|
+
s.name = NAME
|
44
|
+
s.version = VERS
|
45
|
+
s.platform = Gem::Platform::RUBY
|
46
|
+
s.has_rdoc = true
|
47
|
+
s.extra_rdoc_files = ["README", "CHANGELOG"]
|
48
|
+
s.rdoc_options += RDOC_OPTS + ['--exclude', '^(examples|extras)/']
|
49
|
+
s.summary = DESCRIPTION
|
50
|
+
s.description = DESCRIPTION
|
51
|
+
s.author = AUTHOR
|
52
|
+
s.email = EMAIL
|
53
|
+
s.homepage = HOMEPATH
|
54
|
+
s.executables = BIN_FILES
|
55
|
+
s.rubyforge_project = RUBYFORGE_PROJECT
|
56
|
+
s.bindir = "bin"
|
57
|
+
s.require_path = "lib"
|
58
|
+
s.autorequire = "magnolia"
|
59
|
+
|
60
|
+
#s.add_dependency('activesupport', '>=1.3.1')
|
61
|
+
#s.required_ruby_version = '>= 1.8.2'
|
62
|
+
|
63
|
+
s.files = %w(README CHANGELOG Rakefile) +
|
64
|
+
Dir.glob("{bin,doc,test,lib,templates,generator,extras,website,script}/**/*") +
|
65
|
+
Dir.glob("ext/**/*.{h,c,rb}") +
|
66
|
+
Dir.glob("examples/**/*.rb") +
|
67
|
+
Dir.glob("tools/*.rb")
|
68
|
+
|
69
|
+
# s.extensions = FileList["ext/**/extconf.rb"].to_a
|
70
|
+
end
|
71
|
+
|
72
|
+
Rake::GemPackageTask.new(spec) do |p|
|
73
|
+
p.need_tar = true
|
74
|
+
p.gem_spec = spec
|
75
|
+
end
|
76
|
+
|
77
|
+
task :install do
|
78
|
+
name = "#{NAME}-#{VERS}.gem"
|
79
|
+
sh %{rake package}
|
80
|
+
sh %{sudo gem install pkg/#{name}}
|
81
|
+
end
|
82
|
+
|
83
|
+
task :uninstall => [:clean] do
|
84
|
+
sh %{sudo gem uninstall #{NAME}}
|
85
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'magnolia'
|
2
|
+
|
3
|
+
# This is a test account I set up. Please do not use this key or mess with the test account. Thanks.
|
4
|
+
Magnolia.new('fc18b7bd1caf67b06b16a462b0b3c00890304ad9')
|
5
|
+
|
6
|
+
puts '---Testing the adding of a bookmark...'
|
7
|
+
begin
|
8
|
+
marks = Magnolia.add(:title => 'Addicted To New',
|
9
|
+
:description => 'A really cool site.',
|
10
|
+
:tags => 'me, addicting, cool',
|
11
|
+
:rating => 5,
|
12
|
+
:url => 'http://addictedtonew.com/')
|
13
|
+
addicted_mark = marks[0]
|
14
|
+
puts addicted_mark.title
|
15
|
+
rescue Magnolia::RequestError => msg
|
16
|
+
puts msg
|
17
|
+
marks = Magnolia.search(:url => 'http://addictedtonew.com/')
|
18
|
+
addicted_mark = marks[0] if marks.size > 0
|
19
|
+
end
|
20
|
+
|
21
|
+
puts
|
22
|
+
puts '---Testing the updating of a bookmark...'
|
23
|
+
marks = Magnolia.update(:id => addicted_mark.id, :title => 'Addicted To New by John Nunemaker')
|
24
|
+
markadd = marks[0]
|
25
|
+
puts markadd.title
|
26
|
+
|
27
|
+
puts
|
28
|
+
puts '---Testing Mark#save...'
|
29
|
+
begin
|
30
|
+
markol = Magnolia::Mark.new
|
31
|
+
markol.title = 'Ordered List'
|
32
|
+
markol.url = 'http://orderedlist.com'
|
33
|
+
markol.tags = 'steve smith, coding'
|
34
|
+
markol.save
|
35
|
+
puts 'new mark id: ' + markol.id
|
36
|
+
markol.title = 'Ordered List by Steve Smith'
|
37
|
+
puts 'Tags are: ' + markol.tags.inspect
|
38
|
+
markol.tags = nil
|
39
|
+
markol.save
|
40
|
+
marks = Magnolia.find(:id => markol.id)
|
41
|
+
upmark = marks[0]
|
42
|
+
puts 'Title updated to: ' + upmark.title
|
43
|
+
puts 'Tags are: ' + upmark.tags.inspect
|
44
|
+
rescue Magnolia::RequestError => msg
|
45
|
+
puts msg
|
46
|
+
marks = Magnolia.search(:url => 'http://orderedlist.com')
|
47
|
+
markol = marks[0] if marks.size > 0
|
48
|
+
end
|
49
|
+
|
50
|
+
puts
|
51
|
+
puts '---Testing the find method ...'
|
52
|
+
begin
|
53
|
+
marks = Magnolia.search(:person => 'magnoliaapitest')
|
54
|
+
marks.each do |mark|
|
55
|
+
puts mark.title, " #{mark.id}"
|
56
|
+
end
|
57
|
+
rescue Magnolia::RequestError => msg
|
58
|
+
puts msg
|
59
|
+
end
|
60
|
+
|
61
|
+
puts
|
62
|
+
puts '---Testing the get method ...'
|
63
|
+
marks = Magnolia.find(:id => addicted_mark.id)
|
64
|
+
marks.each do |mark|
|
65
|
+
puts mark.img_tag
|
66
|
+
puts mark.a_tag
|
67
|
+
end
|
68
|
+
|
69
|
+
puts
|
70
|
+
puts '---Testing the Mark#find method ...'
|
71
|
+
mark = Magnolia::Mark.find(addicted_mark.id)
|
72
|
+
puts mark.title
|
73
|
+
|
74
|
+
puts
|
75
|
+
puts '---Testing the adding of a tag...'
|
76
|
+
Magnolia.add_tags(:id => addicted_mark.id, :tags => 'john nunemaker')
|
77
|
+
marks = Magnolia.find(:id => addicted_mark.id)
|
78
|
+
puts marks[0].tags.inspect
|
79
|
+
|
80
|
+
Magnolia.delete_tags(:id => addicted_mark.id, :tags => 'john nunemaker')
|
81
|
+
marks = Magnolia.find(:id => addicted_mark.id)
|
82
|
+
puts marks[0].tags.inspect
|
83
|
+
|
84
|
+
puts
|
85
|
+
puts '---Testing the renaming of a tag...'
|
86
|
+
Magnolia.rename_tags(:id => 'all', :old => 'addicting', :new => 'very addicting')
|
87
|
+
marks = Magnolia.find(:id => addicted_mark.id)
|
88
|
+
puts marks[0].tags.inspect
|
89
|
+
Magnolia.rename_tags(:id => 'all', :old => 'very addicting', :new => 'addicting')
|
90
|
+
marks = Magnolia.find(:id => addicted_mark.id)
|
91
|
+
puts marks[0].tags.inspect
|
92
|
+
|
93
|
+
puts
|
94
|
+
puts '---Testing the deleting of addicted bookmark...'
|
95
|
+
Magnolia.delete(:id => addicted_mark.id)
|
96
|
+
puts '---Testing the deleting of ol bookmark...'
|
97
|
+
Magnolia.delete(:id => markol.id)
|
98
|
+
|
99
|
+
puts "---Testing the finding of a person's tags..."
|
100
|
+
tags = Magnolia.tags_find(:person => 'jnunemaker')
|
101
|
+
puts "Getting all of jnunemaker's tags...Total: #{tags.size}"
|
102
|
+
puts "Printing first ten tags..."
|
103
|
+
tags[0..10].each do |tag|
|
104
|
+
puts "#{tag.name} #{tag.count}"
|
105
|
+
end
|
106
|
+
|
107
|
+
puts
|
108
|
+
puts '---End of tests'
|
data/lib/magnolia.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Dir[File.join(File.dirname(__FILE__), 'magnolia/**/*.rb')].sort.each { |lib| require lib }
|
@@ -0,0 +1,486 @@
|
|
1
|
+
# :title:Addicted To Ma.gnolia by John Nunemaker
|
2
|
+
# = Addicted To Ma.gnolia
|
3
|
+
#
|
4
|
+
# This class makes it really simple to access your Ma.gnolia bookmarks
|
5
|
+
# using the Ma.gnolia API[http://ma.gnolia.com/support/api/].
|
6
|
+
#
|
7
|
+
# Author:: John Nunemaker
|
8
|
+
# Website:: http://addictedtonew.com
|
9
|
+
# Last Updated:: June 3, 2006 @ 12:57AM EST
|
10
|
+
# Copyright:: Copyright (c) 2006 John Nunemaker
|
11
|
+
# License:: MIT <http://www.opensource.org/licenses/mit-license.php>
|
12
|
+
#
|
13
|
+
# == URL's For Downloads and Information
|
14
|
+
#
|
15
|
+
# * Ruby Forge: http://rubyforge.org/projects/magnolia/
|
16
|
+
# * SVN: svn checkout http://svn.addictedtonew.com/libs/addicted-to-magnolia/
|
17
|
+
# * Blog Entry: http://addictedtonew.com/archives/155/ruby-magnolia-api-class/
|
18
|
+
# * Online RDocs: http://addictedtonew.com/examples/magnolia/
|
19
|
+
#
|
20
|
+
# == Examples
|
21
|
+
#
|
22
|
+
# my_latest = Magnolia.search(:person => 'jnunemaker') # will find my last ten bookmarks
|
23
|
+
# group_latest = Magnolia.search(:group => 'webmedia') # will find the last ten bookmarks of the webmedia group
|
24
|
+
#
|
25
|
+
#
|
26
|
+
# == Copyright
|
27
|
+
#
|
28
|
+
# Copyright (c) 2006 John Nunemaker
|
29
|
+
#
|
30
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
31
|
+
# a copy of this software and associated documentation files (the "Software"),
|
32
|
+
# to deal in the Software without restriction, including without limitation
|
33
|
+
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
34
|
+
# and/or sell copies of the Software, and to permit persons to whom the Software
|
35
|
+
# is furnished to do so, subject to the following conditions:
|
36
|
+
#
|
37
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
38
|
+
#
|
39
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
40
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
41
|
+
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
42
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
43
|
+
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
44
|
+
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
45
|
+
# DEALINGS IN THE SOFTWARE.
|
46
|
+
require 'net/http'
|
47
|
+
require 'rexml/document'
|
48
|
+
require 'cgi'
|
49
|
+
|
50
|
+
class Magnolia
|
51
|
+
# Exceptions
|
52
|
+
class MissingData < StandardError #:nodoc:
|
53
|
+
end
|
54
|
+
class RequestError < StandardError #:nodoc:
|
55
|
+
end
|
56
|
+
|
57
|
+
# This must be called before any of the other methods can be used. It sets a class variable named <tt>api_key</tt>
|
58
|
+
# which all the other class methods use when making requests.
|
59
|
+
#
|
60
|
+
# == Example
|
61
|
+
#
|
62
|
+
# Magnolia.new('yourgreatsuperapikey')
|
63
|
+
def initialize(api_key)
|
64
|
+
Magnolia.set_api_key(api_key)
|
65
|
+
end
|
66
|
+
|
67
|
+
class << self
|
68
|
+
# Sets the api key for all requests
|
69
|
+
def set_api_key(api_key)
|
70
|
+
@@api_key = api_key
|
71
|
+
end
|
72
|
+
|
73
|
+
# This method searches for bookmarks that match certain criteria provided by you. Ma.gnolia named this method <tt>bookmarks_find</tt>
|
74
|
+
# but I thought it was more appropriately named <tt>search</tt>.
|
75
|
+
#
|
76
|
+
# == Examples
|
77
|
+
#
|
78
|
+
# latest = Magnolia.find(:person => 'jnunemaker') # will find my last ten bookmarks
|
79
|
+
# recent = Magnolia.find(:person => 'jnunemaker', :limit => 20) # will find my last 20 bookmarks
|
80
|
+
# nice = Magnolia.find(:person => 'jnunemaker', :tags => 'nice', :limit => 5) # will find my last 5 bookmarks tagged 'nice'
|
81
|
+
#
|
82
|
+
# Let's get a bit trickier. Below will rescue from a request error such as not enough information or person not found, etc.
|
83
|
+
#
|
84
|
+
# begin
|
85
|
+
# marks = Magnolia.search(:person => 'jnunemaker')
|
86
|
+
# marks.each do |mark|
|
87
|
+
# puts mark.title, " #{mark.id}"
|
88
|
+
# end
|
89
|
+
# rescue Magnolia::RequestError => msg
|
90
|
+
# puts msg
|
91
|
+
# end
|
92
|
+
#
|
93
|
+
# == Options
|
94
|
+
#
|
95
|
+
# :tags - Multiple tags are treated as an AND search; seperate multiples with commas
|
96
|
+
# :person - Multiple screen names are treated as an ‘OR’ search; seperate multiples with commas
|
97
|
+
# :group - Multiple groups are treated as an ‘OR’ search; seperate multiples with commas
|
98
|
+
# :rating - Only bookmarks rated this value or higher will be returned
|
99
|
+
# :from - Only bookmarks created after this date time will be returned
|
100
|
+
# :to - Only bookmarks created before this date time will be returned
|
101
|
+
# :url - Only return bookmarks with this url
|
102
|
+
# :limit - A maximum number of bookmarks to return from search
|
103
|
+
#
|
104
|
+
# == Return Value
|
105
|
+
#
|
106
|
+
# Returns an array of Marks.
|
107
|
+
def search(options = {})
|
108
|
+
params = { :tags => nil,
|
109
|
+
:person => nil,
|
110
|
+
:group => nil,
|
111
|
+
:rating => nil,
|
112
|
+
:from => nil,
|
113
|
+
:to => nil,
|
114
|
+
:url => nil,
|
115
|
+
:limit => 10 }
|
116
|
+
params.update(options)
|
117
|
+
|
118
|
+
create_marks_from_xml(make_request('bookmarks_find', params))
|
119
|
+
end
|
120
|
+
|
121
|
+
# This method is basically like a Ruby on Rails <tt>find</tt> method. Pass it a short name (which is basically an id)
|
122
|
+
# or comma-seperated short names and
|
123
|
+
# it will return each mark that is found. Because it is similar to rails <tt>find</tt> method, I have aliased it.
|
124
|
+
#
|
125
|
+
# == Examples
|
126
|
+
#
|
127
|
+
# getone = Magnolia.get(:id => 'rubyonrails')
|
128
|
+
# getmultiple = Magnolia.get(:id => 'rubyonrails,ruby,someotherid')
|
129
|
+
#
|
130
|
+
# If you like Ruby on Rails and think <tt>find</tt> is a more appropriate name for the method, feel free to use it.
|
131
|
+
#
|
132
|
+
# getdiff = Magnolia.find(:id => 'id1')
|
133
|
+
#
|
134
|
+
# == Options
|
135
|
+
#
|
136
|
+
# :id - The short name for one or more bookmarks; seperate multiples with commas (required)
|
137
|
+
#
|
138
|
+
# == Return Value
|
139
|
+
#
|
140
|
+
# Returns an array of Marks.
|
141
|
+
def get(marks = {})
|
142
|
+
raise MissingData, 'The id must be included in order to know which bookmarks to get.' unless marks.include? :id
|
143
|
+
create_marks_from_xml(make_request('bookmarks_get', marks))
|
144
|
+
end
|
145
|
+
alias :find :get
|
146
|
+
|
147
|
+
# == Examples
|
148
|
+
#
|
149
|
+
# Magnolia.add(:title => 'Addicted To New',
|
150
|
+
# :description => 'A great site!',
|
151
|
+
# :url => 'http://addictedtonew.com/',
|
152
|
+
# :private => 'false',
|
153
|
+
# :tags => 'cool dude, lame tag, addicting',
|
154
|
+
# :rating => 5)
|
155
|
+
#
|
156
|
+
# == Options
|
157
|
+
#
|
158
|
+
# :url - A URL string. Must be valid (required)
|
159
|
+
# :title - A title string (optional)
|
160
|
+
# :description - A description string (optional)
|
161
|
+
# :private - The bookmark’s privacy status; either 'true' or 'false' (optional)
|
162
|
+
# :tags - A list of tags. This will completely replace any existing tags for each specified bookmark (optional)
|
163
|
+
# :rating - An integer representing a star rating; 1-5 (optional)
|
164
|
+
#
|
165
|
+
# == Return Value
|
166
|
+
#
|
167
|
+
# Returns an array containing the added mark
|
168
|
+
def add(mark = {})
|
169
|
+
raise MissingData, 'The url must be included to add a mark.' unless mark.include? :url
|
170
|
+
create_marks_from_xml(make_request('bookmarks_add', mark))
|
171
|
+
end
|
172
|
+
alias :create :add
|
173
|
+
|
174
|
+
# == Examples
|
175
|
+
#
|
176
|
+
# delone = Magnolia.delete(:id => 'java')
|
177
|
+
# delmultiple = Magnolia.delete(:id => 'java,perl,someotherid')
|
178
|
+
# deldiff = Magnolia.destroy(:id => 'someid')
|
179
|
+
#
|
180
|
+
# == Options
|
181
|
+
#
|
182
|
+
# :id - The short name for one or more bookmarks; seperate multiples with commas (required)
|
183
|
+
#
|
184
|
+
# == Return Value
|
185
|
+
#
|
186
|
+
# Nuttin
|
187
|
+
def delete(marks = {})
|
188
|
+
make_request('bookmarks_delete', marks)
|
189
|
+
end
|
190
|
+
alias :destroy :delete
|
191
|
+
|
192
|
+
# == Examples
|
193
|
+
#
|
194
|
+
# Magnolia.update(:id => 'someid',
|
195
|
+
# :title => 'Addicted To New',
|
196
|
+
# :description => 'A great site!',
|
197
|
+
# :url => 'http://addictedtonew.com/',
|
198
|
+
# :private => 'false',
|
199
|
+
# :tags => 'cool dude, lame tag, addicting',
|
200
|
+
# :rating => 5)
|
201
|
+
#
|
202
|
+
# == Options
|
203
|
+
#
|
204
|
+
# :id - The short name for one bookmark (required)
|
205
|
+
# :url - A URL string. Must be valid (optional)
|
206
|
+
# :title - A title string (optional)
|
207
|
+
# :description - A description string (optional)
|
208
|
+
# :private - The bookmark’s privacy status; either 'true' or 'false' (optional)
|
209
|
+
# :tags - A list of tags. This will completely replace any existing tags for each specified bookmark (optional)
|
210
|
+
# :rating - An integer representing a star rating; 1-5 (optional)
|
211
|
+
#
|
212
|
+
# == Return Value
|
213
|
+
#
|
214
|
+
# Returns an array containing the updated mark.
|
215
|
+
def update(mark = {})
|
216
|
+
raise MissingData, 'The id must be included in order to know which bookmark to update.' unless mark.include? :id
|
217
|
+
create_marks_from_xml(make_request('bookmarks_update', mark))
|
218
|
+
end
|
219
|
+
alias :edit :update
|
220
|
+
|
221
|
+
# == Examples
|
222
|
+
#
|
223
|
+
# Magnolia.tags_add(:id => 'rubyonrails', :tags => 'fast,simple')
|
224
|
+
#
|
225
|
+
# You can also use add_tags if tags_add seems backwards.
|
226
|
+
# Magnolia.add_tags(:id => 'rubyonrails', :tags => 'fast,simple')
|
227
|
+
#
|
228
|
+
# == Options
|
229
|
+
#
|
230
|
+
# :id - One or more bookmark short names to which the specified tags should be added
|
231
|
+
# :tags - Tags to be added to the specified bookmarks
|
232
|
+
#
|
233
|
+
# == Return Value
|
234
|
+
#
|
235
|
+
# Nuttin
|
236
|
+
def tags_add(mark = {})
|
237
|
+
raise MissingData, 'The id must be included in order to know which bookmark to add tags to.' unless mark.include? :id
|
238
|
+
raise MissingData, 'The tags must be included that you want to add.' unless mark.include? :tags
|
239
|
+
make_request('bookmarks_tags_add', mark)
|
240
|
+
end
|
241
|
+
alias :add_tags :tags_add
|
242
|
+
|
243
|
+
# == Examples
|
244
|
+
#
|
245
|
+
# Magnolia.tags_delete(:id => 'java', :tags => 'cool,fun')
|
246
|
+
#
|
247
|
+
# You can also use add_tags if tags_add seems backwards.
|
248
|
+
# Magnolia.add_tags(:id => 'id1', :tags => 'newtag1,newtag2')
|
249
|
+
#
|
250
|
+
# == Options
|
251
|
+
#
|
252
|
+
# :id - One or more bookmark short names to which the specified tags should be added
|
253
|
+
# :tags - Tags to be added to the specified bookmarks
|
254
|
+
#
|
255
|
+
# == Return Value
|
256
|
+
#
|
257
|
+
# Nuttin
|
258
|
+
def tags_delete(mark = {})
|
259
|
+
raise MissingData, 'The id must be included in order to know which bookmark to add tags to.' unless mark.include? :id
|
260
|
+
raise MissingData, 'The tags must be included that you want to add.' unless mark.include? :tags
|
261
|
+
make_request('bookmarks_tags_delete', mark)
|
262
|
+
end
|
263
|
+
alias :delete_tags :tags_delete
|
264
|
+
|
265
|
+
# == Examples
|
266
|
+
#
|
267
|
+
# Magnolia.tags_replace(:id => 'languages', :old => 'java', :new => 'rubyonrails')
|
268
|
+
#
|
269
|
+
# You can also use any of these below if you don't like tags_delete
|
270
|
+
# Magnolia.replace_tags(:id => 'languages', :old => 'java', :new => 'rubyonrails')
|
271
|
+
# Magnolia.rename_tags(:id => 'languages', :old => 'java', :new => 'rubyonrails')
|
272
|
+
# Magnolia.tags_rename(:id => 'languages', :old => 'java', :new => 'rubyonrails')
|
273
|
+
#
|
274
|
+
# == Options
|
275
|
+
#
|
276
|
+
# :id - One or more bookmark short names to which the specified tags should be added
|
277
|
+
# :old - Existing tag to be replaced
|
278
|
+
# :new - New tag to replace existing tag
|
279
|
+
#
|
280
|
+
# == Return Value
|
281
|
+
#
|
282
|
+
# Nuttin
|
283
|
+
def tags_replace(mark = {})
|
284
|
+
raise MissingData, 'The id must be included in order to know which bookmark to rename tags for.' unless mark.include? :id
|
285
|
+
raise MissingData, 'The old tag is required.' unless mark.include? :old
|
286
|
+
raise MissingData, 'The new tag is required.' unless mark.include? :new
|
287
|
+
make_request('bookmarks_tags_replace', mark)
|
288
|
+
end
|
289
|
+
alias :replace_tags :tags_replace
|
290
|
+
alias :rename_tags :tags_replace
|
291
|
+
alias :tags_rename :tags_replace
|
292
|
+
|
293
|
+
# == Examples
|
294
|
+
#
|
295
|
+
# tags = Magnolia.tags_find(:person => 'jnunemaker')
|
296
|
+
# tags.each do |tag|
|
297
|
+
# puts tag.name
|
298
|
+
# end
|
299
|
+
#
|
300
|
+
# You can also use the alias of find_tags if it makes more sense to you
|
301
|
+
#
|
302
|
+
# tags = Magnolia.find_tags(:person => 'jnunemaker')
|
303
|
+
#
|
304
|
+
# == Options
|
305
|
+
#
|
306
|
+
# :person - The person whose tags you would like to find
|
307
|
+
#
|
308
|
+
# == Return Value
|
309
|
+
#
|
310
|
+
# An array of Tag objects
|
311
|
+
def tags_find(mark = {})
|
312
|
+
raise MissingData, 'The person (screen name) is required.' unless mark.include? :person
|
313
|
+
root = make_request('tags_find', mark)
|
314
|
+
create_tags_from_xml(root)
|
315
|
+
end
|
316
|
+
alias :find_tags :tags_find
|
317
|
+
|
318
|
+
private
|
319
|
+
# Makes a request to magnolia and processes that request if need be
|
320
|
+
def make_request(api_method, params={})
|
321
|
+
params.update({ :api_key => @@api_key })
|
322
|
+
path = "/api/rest/1/#{api_method}"
|
323
|
+
http = Net::HTTP.new('ma.gnolia.com', 80)
|
324
|
+
response = http.post(path, hash_to_qs(params))
|
325
|
+
raise RequestError, "Cannot make request (#{response.message})!" unless response.message == 'OK'
|
326
|
+
|
327
|
+
# Find out if the request did in fact return xml, raise RequestError if it didn't
|
328
|
+
begin
|
329
|
+
doc = REXML::Document.new(response.body)
|
330
|
+
rescue
|
331
|
+
raise RequestError, 'XML was not returned as the response body.'
|
332
|
+
end
|
333
|
+
|
334
|
+
# We now have an xml document so let's see if it contains good stuff or a magnolia error message
|
335
|
+
# If magnolia error message, then raise a RequestError
|
336
|
+
root = doc.root
|
337
|
+
unless root.attributes['status'] == 'ok'
|
338
|
+
error_message = root.elements["error"].attributes['message']
|
339
|
+
error_code = root.elements["error"].attributes['code']
|
340
|
+
raise RequestError, "#{error_code}: #{error_message}"
|
341
|
+
end
|
342
|
+
root
|
343
|
+
end
|
344
|
+
|
345
|
+
# creates an array of bookmarks objects from xml
|
346
|
+
def create_marks_from_xml(xml)
|
347
|
+
marks = []
|
348
|
+
REXML::XPath.each(xml, "bookmarks/bookmark") do |mark|
|
349
|
+
marks << Mark.from_xml(mark)
|
350
|
+
end
|
351
|
+
marks
|
352
|
+
end
|
353
|
+
|
354
|
+
# creates an array of tag objects from xml
|
355
|
+
def create_tags_from_xml(xml)
|
356
|
+
tags = []
|
357
|
+
REXML::XPath.each(xml, "tags/tag") do |tag_xml|
|
358
|
+
tags << Tag.from_xml(tag_xml)
|
359
|
+
end
|
360
|
+
tags
|
361
|
+
end
|
362
|
+
|
363
|
+
# Converts a hash to a query string
|
364
|
+
def hash_to_qs(h)
|
365
|
+
str = ''
|
366
|
+
h.each { |key,val| str += "#{key}=#{CGI.escape(val.to_s)}&" unless val.nil? }
|
367
|
+
str
|
368
|
+
end
|
369
|
+
end # class self
|
370
|
+
|
371
|
+
# The mark class is used to store information about each bookmark after it is found, created or updated.
|
372
|
+
# Each method that is not in the DONT_PROCESS constant returns and array of <tt>Mark</tt> objects.
|
373
|
+
class Mark
|
374
|
+
def initialize
|
375
|
+
@tags = []
|
376
|
+
end
|
377
|
+
attr_accessor :id, :title, :url, :description
|
378
|
+
attr_accessor :screenshot, :rating, :private
|
379
|
+
attr_accessor :created, :updated, :owner, :tags
|
380
|
+
attr_reader :img_tag, :a_tag
|
381
|
+
|
382
|
+
# Creates an image tag for the screenshot image with the title as the alt text
|
383
|
+
def img_tag
|
384
|
+
"<img src='#{self.screenshot}' alt='#{self.title}' />"
|
385
|
+
end
|
386
|
+
|
387
|
+
# Creates a link to the url of the bookmark with the title as the text
|
388
|
+
def a_tag
|
389
|
+
"<a href='#{self.url}' title='Link to #{self.title}'>#{self.title}</a>"
|
390
|
+
end
|
391
|
+
|
392
|
+
# This method allows working with bookmarks much like ActiveRecord.
|
393
|
+
#
|
394
|
+
# == Examples
|
395
|
+
#
|
396
|
+
# mark = Magnolia::Mark.new
|
397
|
+
# mark.title = 'Addicted To New'
|
398
|
+
# mark.url = 'http://addictedtonew.com/'
|
399
|
+
# mark.tags = ['john nunemaker', 'me'] # you can also use comma-seperated list mark.tags = 'john nunemaker, me'
|
400
|
+
# mark.save
|
401
|
+
# puts mark.id # this is the id of the newly created bookmark
|
402
|
+
#
|
403
|
+
# You can also use it to update bookmarks like so:
|
404
|
+
#
|
405
|
+
# mark = Magnolia::Mark.find(:id => 'someshortname')
|
406
|
+
# mark.title = 'Addicted To New by John Nunemaker'
|
407
|
+
# mark.save
|
408
|
+
def save
|
409
|
+
if self.id == nil
|
410
|
+
# create a new bookmark
|
411
|
+
mark = to_h
|
412
|
+
marks = Magnolia.add(mark)
|
413
|
+
self.id = marks[0].id
|
414
|
+
else
|
415
|
+
# update an existing bookmark
|
416
|
+
mark = to_h
|
417
|
+
marks = Magnolia.update(mark)
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
# Returns the mark in hash form. This is used in the save method to pass the object in as a hash to the
|
422
|
+
# Magnolia <tt>add</tt> or <tt>update</tt> methods.
|
423
|
+
def to_h
|
424
|
+
mark = {:id => self.id,
|
425
|
+
:title => self.title,
|
426
|
+
:description => self.description,
|
427
|
+
:url => self.url,
|
428
|
+
:rating => self.rating,
|
429
|
+
:private => self.private}
|
430
|
+
if self.tags.nil?
|
431
|
+
mark.update({:tags => ''})
|
432
|
+
else
|
433
|
+
# allow for tags to be comma seperated list or array
|
434
|
+
if self.tags.is_a?(String)
|
435
|
+
mark.update({:tags => self.tags})
|
436
|
+
# turn the tags into an array
|
437
|
+
self.tags = self.tags.split(',')
|
438
|
+
elsif self.tags.is_a?(Array)
|
439
|
+
mark.update({:tags => self.tags.join(',')})
|
440
|
+
end
|
441
|
+
end
|
442
|
+
mark
|
443
|
+
end
|
444
|
+
private :to_h
|
445
|
+
|
446
|
+
class << self
|
447
|
+
# Finds a single bookmark by it's id (short name). If not found raises a Magnolia::RequestError
|
448
|
+
def find(id)
|
449
|
+
marks = Magnolia.get(:id =>id)
|
450
|
+
marks[0]
|
451
|
+
end
|
452
|
+
|
453
|
+
# Converts xml into a mark
|
454
|
+
def from_xml(xml)
|
455
|
+
mark = Mark.new()
|
456
|
+
mark.title = xml.elements['title'].text
|
457
|
+
mark.url = xml.elements['url'].text
|
458
|
+
mark.description = xml.elements['description'].text
|
459
|
+
mark.screenshot = xml.elements['screenshot'].text
|
460
|
+
mark.id = xml.attributes['id']
|
461
|
+
mark.rating = xml.attributes['rating']
|
462
|
+
mark.private = xml.attributes['private']
|
463
|
+
mark.created = xml.attributes['created']
|
464
|
+
mark.updated = xml.attributes['updated']
|
465
|
+
mark.owner = xml.attributes['owner']
|
466
|
+
REXML::XPath.each(xml, 'tags/tag') do |tag|
|
467
|
+
mark.tags << tag.attributes['name']
|
468
|
+
end
|
469
|
+
mark
|
470
|
+
end
|
471
|
+
end # class self
|
472
|
+
end # class Mark
|
473
|
+
|
474
|
+
class Tag
|
475
|
+
attr_accessor :name, :count
|
476
|
+
|
477
|
+
class << self
|
478
|
+
def from_xml(xml)
|
479
|
+
t = Tag.new
|
480
|
+
t.name = xml.attributes['name']
|
481
|
+
t.count = xml.attributes['count']
|
482
|
+
t
|
483
|
+
end
|
484
|
+
end
|
485
|
+
end
|
486
|
+
end # class Magnolia
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.11
|
3
|
+
specification_version: 1
|
4
|
+
name: magnolia
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 1.1.0
|
7
|
+
date: 2006-10-24 00:00:00 -04:00
|
8
|
+
summary: Library which makes it really easy to access your ma.gnolia bookmarks
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: nunemaker@gmail.com
|
12
|
+
homepage: http://magnolia.rubyforge.org
|
13
|
+
rubyforge_project: magnolia
|
14
|
+
description: Library which makes it really easy to access your ma.gnolia bookmarks
|
15
|
+
autorequire: magnolia
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
authors:
|
29
|
+
- John Nunemaker
|
30
|
+
files:
|
31
|
+
- README
|
32
|
+
- CHANGELOG
|
33
|
+
- Rakefile
|
34
|
+
- test/magnolia_test.rb
|
35
|
+
- test/test_helper.rb
|
36
|
+
- lib/magnolia
|
37
|
+
- lib/magnolia.rb
|
38
|
+
- lib/magnolia/magnolia.rb
|
39
|
+
- lib/magnolia/version.rb
|
40
|
+
- examples/examples.rb
|
41
|
+
test_files: []
|
42
|
+
|
43
|
+
rdoc_options:
|
44
|
+
- --quiet
|
45
|
+
- --title
|
46
|
+
- magnolia documentation
|
47
|
+
- --opname
|
48
|
+
- index.html
|
49
|
+
- --line-numbers
|
50
|
+
- --main
|
51
|
+
- README
|
52
|
+
- --inline-source
|
53
|
+
- --exclude
|
54
|
+
- ^(examples|extras)/
|
55
|
+
extra_rdoc_files:
|
56
|
+
- README
|
57
|
+
- CHANGELOG
|
58
|
+
executables: []
|
59
|
+
|
60
|
+
extensions: []
|
61
|
+
|
62
|
+
requirements: []
|
63
|
+
|
64
|
+
dependencies: []
|
65
|
+
|