oos4ruby 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/History.txt +4 -0
- data/License.txt +20 -0
- data/Manifest.txt +39 -0
- data/README.txt +1 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +70 -0
- data/config/requirements.rb +17 -0
- data/lib/oos4ruby/auth.rb +39 -0
- data/lib/oos4ruby/bean.rb +189 -0
- data/lib/oos4ruby/category.rb +28 -0
- data/lib/oos4ruby/collection.rb +96 -0
- data/lib/oos4ruby/contact.rb +72 -0
- data/lib/oos4ruby/contacts.rb +11 -0
- data/lib/oos4ruby/entry.rb +91 -0
- data/lib/oos4ruby/feed.rb +65 -0
- data/lib/oos4ruby/http_invoker.rb +140 -0
- data/lib/oos4ruby/oos.rb +54 -0
- data/lib/oos4ruby/search.rb +75 -0
- data/lib/oos4ruby/service.rb +13 -0
- data/lib/oos4ruby/site.rb +220 -0
- data/lib/oos4ruby/sites.rb +11 -0
- data/lib/oos4ruby/user.rb +122 -0
- data/lib/oos4ruby/version.rb +9 -0
- data/lib/oos4ruby.rb +72 -0
- data/log/debug.log +0 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +74 -0
- data/setup.rb +1585 -0
- data/tasks/deployment.rake +27 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +17 -0
- data/test/test_helper.rb +2 -0
- data/test/test_oos4ruby.rb +85 -0
- data/website/index.html +131 -0
- data/website/index.txt +62 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +138 -0
- data/website/template.rhtml +48 -0
- metadata +98 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
require 'rexml/xpath'
|
3
|
+
|
4
|
+
module Oos4ruby
|
5
|
+
class Feed
|
6
|
+
|
7
|
+
attr_reader :previous, :next, :entries, :xml
|
8
|
+
|
9
|
+
def initialize(entries, xml)
|
10
|
+
@entries = entries
|
11
|
+
@xml = xml
|
12
|
+
@next = Feed.get_link('next', xml)
|
13
|
+
@previous = Feed.get_link 'previous', xml
|
14
|
+
@self = Feed.get_link 'self', xml
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.get_link(rel, xml)
|
18
|
+
link = REXML::XPath.first(xml, "./atom:link[@rel=\"#{rel}\"]", XmlNamespaces)
|
19
|
+
if link
|
20
|
+
uri = URI.parse link.attributes['href']
|
21
|
+
if uri.absolute?
|
22
|
+
return uri
|
23
|
+
else
|
24
|
+
return URI.parse(OOS_URL).merge(uri)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def Feed.read(body)
|
30
|
+
|
31
|
+
feed = nil
|
32
|
+
begin
|
33
|
+
feed = REXML::Document.new(body, { :raw => nil }).root
|
34
|
+
|
35
|
+
entries = REXML::XPath.match(feed, "./atom:entry", XmlNamespaces)
|
36
|
+
|
37
|
+
entries.map! { |entry| Entry.new(entry) }
|
38
|
+
feed = Feed.new( entries, feed )
|
39
|
+
rescue => ex
|
40
|
+
puts ex.message
|
41
|
+
puts ex.backtrace.join("\n")
|
42
|
+
end
|
43
|
+
|
44
|
+
return feed
|
45
|
+
end
|
46
|
+
|
47
|
+
def self_link
|
48
|
+
@self
|
49
|
+
end
|
50
|
+
|
51
|
+
def self_link?
|
52
|
+
!@self.nil?
|
53
|
+
end
|
54
|
+
|
55
|
+
def previous?
|
56
|
+
!@previous.nil?
|
57
|
+
end
|
58
|
+
|
59
|
+
def next?
|
60
|
+
!@next.nil?
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,140 @@
|
|
1
|
+
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
module Oos4ruby
|
5
|
+
class HTTPInvoker
|
6
|
+
|
7
|
+
attr_reader :response, :headers, :entry, :body
|
8
|
+
|
9
|
+
def initialize(uri, authent)
|
10
|
+
@uri = (uri if uri.kind_of?URI) || URI.parse(uri)
|
11
|
+
@authent = authent
|
12
|
+
|
13
|
+
@headers = {}
|
14
|
+
@entry = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def set_header(name, val)
|
18
|
+
@headers[name] = val
|
19
|
+
end
|
20
|
+
|
21
|
+
def get(depth = 0, req = nil)
|
22
|
+
return false unless is_authenticate?depth, req
|
23
|
+
|
24
|
+
http, req = prepare_http req, :get
|
25
|
+
|
26
|
+
http.start do |connection|
|
27
|
+
@response = connection.request(req)
|
28
|
+
|
29
|
+
return get(depth + 1, req) if need_authentication?(req)
|
30
|
+
|
31
|
+
if @response.kind_of?Net::HTTPSuccess
|
32
|
+
@body = @response.body
|
33
|
+
return true
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
return false
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
def post(contentType, body, depth = 0, req = nil)
|
43
|
+
return false unless is_authenticate?depth, req
|
44
|
+
|
45
|
+
http, req = prepare_http req, :post
|
46
|
+
|
47
|
+
req.set_content_type contentType
|
48
|
+
@headers.each { |k, v| req[k]= v }
|
49
|
+
|
50
|
+
http.start do |connection|
|
51
|
+
@response = connection.request(req, body)
|
52
|
+
|
53
|
+
return post(contentType, body, depth + 1, req) if need_authentication?(req)
|
54
|
+
|
55
|
+
return false if @response.code != '201'
|
56
|
+
|
57
|
+
begin
|
58
|
+
@entry = Entry.new @response.body
|
59
|
+
return true
|
60
|
+
rescue ArgumentError
|
61
|
+
return false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
def put(contentType, body, depth = 0, req = nil)
|
68
|
+
return false unless is_authenticate?depth, req
|
69
|
+
|
70
|
+
http, req = prepare_http req, :put
|
71
|
+
|
72
|
+
req.set_content_type contentType
|
73
|
+
@headers.each { |k, v| req[k]= v }
|
74
|
+
|
75
|
+
http.start do |connection|
|
76
|
+
@response = connection.request(req, body)
|
77
|
+
|
78
|
+
return put(contentType, body, depth +1, req) if need_authentication?(req)
|
79
|
+
|
80
|
+
return true if @response.kind_of? Net::HTTPSuccess
|
81
|
+
|
82
|
+
return false
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
def delete( req = nil, depth = 0 )
|
88
|
+
return false unless is_authenticate?depth, req
|
89
|
+
|
90
|
+
http, req = prepare_http req, :delete
|
91
|
+
|
92
|
+
http.start do |connection|
|
93
|
+
@response = connection.request(req)
|
94
|
+
|
95
|
+
return delete(req, depth + 1) if need_authentication?(req)
|
96
|
+
|
97
|
+
return true if @response.kind_of? Net::HTTPSuccess
|
98
|
+
|
99
|
+
return false
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
def header(which)
|
106
|
+
@response[which]
|
107
|
+
end
|
108
|
+
|
109
|
+
def prepare_http( req, option )
|
110
|
+
http = Net::HTTP.new(@uri.host, @uri.port)
|
111
|
+
http.use_ssl = true if @uri.scheme == 'https'
|
112
|
+
|
113
|
+
unless req
|
114
|
+
url = @uri.path
|
115
|
+
url += "?#{@uri.query}" if @uri.query
|
116
|
+
req = Net::HTTP::Get.new( url ) if option == :get
|
117
|
+
req = Net::HTTP::Post.new( url ) if option == :post
|
118
|
+
req = Net::HTTP::Put.new( url ) if option == :put
|
119
|
+
req = Net::HTTP::Delete.new( url ) if option == :delete
|
120
|
+
end
|
121
|
+
|
122
|
+
return http, req
|
123
|
+
end
|
124
|
+
|
125
|
+
def need_authentication?(req)
|
126
|
+
if @response.instance_of?(Net::HTTPUnauthorized) && @authent
|
127
|
+
@authent.add_to req
|
128
|
+
req.body = nil unless req.body.nil?
|
129
|
+
return true
|
130
|
+
end
|
131
|
+
return false
|
132
|
+
end
|
133
|
+
|
134
|
+
def is_authenticate?(depth, req)
|
135
|
+
return false if depth > 2 and need_authentication?(req)
|
136
|
+
return true
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
end
|
data/lib/oos4ruby/oos.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
|
2
|
+
require 'rexml/document'
|
3
|
+
require 'rexml/xpath'
|
4
|
+
|
5
|
+
module Oos4ruby
|
6
|
+
class Oos
|
7
|
+
def auth_app(app_token, secret_key)
|
8
|
+
@auth = Auth.new(app_token, secret_key, :app)
|
9
|
+
end
|
10
|
+
|
11
|
+
def auth_user(email, api_token)
|
12
|
+
@auth = Auth.new(email, api_token, :wsse)
|
13
|
+
document_service
|
14
|
+
end
|
15
|
+
|
16
|
+
def user(slug = nil)
|
17
|
+
User.find( @auth, slug )
|
18
|
+
end
|
19
|
+
|
20
|
+
def search(opts)
|
21
|
+
Search.find @auth, opts
|
22
|
+
end
|
23
|
+
|
24
|
+
def privacy_cats
|
25
|
+
return @privacy_cats if @privacy_cats
|
26
|
+
getter = HTTPInvoker.new PRIVACY_URL, @auth
|
27
|
+
|
28
|
+
worked = getter.get
|
29
|
+
|
30
|
+
if worked
|
31
|
+
@privacy_cats = {}
|
32
|
+
cats = REXML::Document.new( getter.body ).root
|
33
|
+
REXML::XPath.match(cats, './atom:category', XmlNamespaces).each { |cat|
|
34
|
+
cat.add_attribute('scheme', cats.attributes['scheme'])
|
35
|
+
@privacy_cats[cat.attributes['term'].underscore.to_sym] = Category.new(cat)
|
36
|
+
}
|
37
|
+
end
|
38
|
+
return @privacy_cats
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
def document_service
|
43
|
+
getter = HTTPInvoker.new API_URL, @auth
|
44
|
+
|
45
|
+
worked = getter.get
|
46
|
+
|
47
|
+
if worked
|
48
|
+
@service = Service.new(REXML::Document.new( getter.body ).root)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
|
@@ -0,0 +1,75 @@
|
|
1
|
+
|
2
|
+
require 'cgi'
|
3
|
+
|
4
|
+
module Oos4ruby
|
5
|
+
class Search
|
6
|
+
|
7
|
+
=begin rdoc
|
8
|
+
Method to search places into 11870
|
9
|
+
available parameters:
|
10
|
+
<tt>q</tt>:: string that represents a siple query.
|
11
|
+
<tt>bbox</tt>:: array of points that delimiters a rectangle, SW and NE.
|
12
|
+
<tt>as</tt>:: area specified by a slug. I.E: /es/madrid.
|
13
|
+
<tt>tags</tt>:: array of tags.
|
14
|
+
<tt>tag_op</tt>:: tags operator, "and" or "or".
|
15
|
+
<tt>lat</tt>:: latitude of the center point of an area.
|
16
|
+
<tt>lon</tt>:: longitude of the center point of an area.
|
17
|
+
<tt>radius</tt>:: radius to create a rectangle from the center point of an area.
|
18
|
+
<tt>page</tt>:: page number in the search results
|
19
|
+
=end
|
20
|
+
def Search.find(auth, opts)
|
21
|
+
query = SEARCH_URL
|
22
|
+
|
23
|
+
more_params = false
|
24
|
+
unless opts.empty?
|
25
|
+
query += "?"
|
26
|
+
if opts[:q]
|
27
|
+
query += "q=#{CGI.escape(opts[:q])}"
|
28
|
+
more_params = true
|
29
|
+
end
|
30
|
+
if opts[:bbox]
|
31
|
+
query += "&" if more_params
|
32
|
+
query += "bbox=#{opts[:bbox].join(",")}"
|
33
|
+
more_params = true
|
34
|
+
end
|
35
|
+
if opts[:as]
|
36
|
+
query += "&" if more_params
|
37
|
+
query += "as=#{opts[:as]}"
|
38
|
+
more_params = true
|
39
|
+
end
|
40
|
+
if opts[:tags]
|
41
|
+
query += "&" if more_params
|
42
|
+
opts[:tags].each_with_index do |tag, index|
|
43
|
+
query += "tag=#{CGI.escape(tag)}"
|
44
|
+
query += "&" if index < opts[:tags].length - 1
|
45
|
+
end
|
46
|
+
more_params = true
|
47
|
+
end
|
48
|
+
if opts[:tag_op]
|
49
|
+
query += "&" if more_params
|
50
|
+
query += "tagOp=#{opts[:tag_op]}"
|
51
|
+
more_params = true
|
52
|
+
end
|
53
|
+
if opts[:lat] and opts[:lon] and opts[:radius]
|
54
|
+
query += "&" if more_params
|
55
|
+
query += "lat=#{opts[:lat]}&lon=#{opts[:lon]}&radius=#{opts[:radius]}"
|
56
|
+
more_params = true
|
57
|
+
end
|
58
|
+
if opts[:page]
|
59
|
+
query += "&" if more_params
|
60
|
+
query += "page=#{opts[:page]}"
|
61
|
+
end
|
62
|
+
else
|
63
|
+
raise RuntimeError('a parameter is obligatory at least')
|
64
|
+
end
|
65
|
+
|
66
|
+
getter = HTTPInvoker.new query, auth
|
67
|
+
|
68
|
+
worked = getter.get
|
69
|
+
raise RuntimeError.new(getter.response.message) unless worked
|
70
|
+
Sites.new(Feed.read(getter.body), auth, nil)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
|
@@ -0,0 +1,220 @@
|
|
1
|
+
|
2
|
+
include Bean
|
3
|
+
|
4
|
+
module Oos4ruby
|
5
|
+
class Site < Bean::BeanClass
|
6
|
+
|
7
|
+
define_el_reader(
|
8
|
+
{
|
9
|
+
OosNamespace => [:id, :user_address, :url, :locality, :subadministrativearea, :country, :telephone],
|
10
|
+
AppNamespace => [:edited],
|
11
|
+
AtomNamespace => [:title, :updated, :summary, :content]
|
12
|
+
}
|
13
|
+
)
|
14
|
+
|
15
|
+
define_attr_reader OosNamespace => {:country => :slug, :locality => :slug}
|
16
|
+
|
17
|
+
alias :oos_id :id
|
18
|
+
alias :name :title
|
19
|
+
alias :review_title :summary
|
20
|
+
alias :review_content :content
|
21
|
+
|
22
|
+
attr_writer :review_title, :review_content, :user_address, :url, :locality, :telephone
|
23
|
+
|
24
|
+
def country=(name, slug)
|
25
|
+
@country = REXML::Element.new('oos:country')
|
26
|
+
@country.add_namespace('oos', OosNamespace)
|
27
|
+
@country.add_text name
|
28
|
+
@country.add_attribute 'slug', slug
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize(xml, auth, slug = nil)
|
32
|
+
@xml = xml
|
33
|
+
@auth = auth
|
34
|
+
if slug
|
35
|
+
@slug = slug
|
36
|
+
@tags_scheme = "#{TAGS_URL}/#{@slug}"
|
37
|
+
@lists_scheme = "#{LISTS_URL}/#{@slug}"
|
38
|
+
end
|
39
|
+
@categories_added = []
|
40
|
+
@categories_removed = []
|
41
|
+
end
|
42
|
+
|
43
|
+
def Site.find_by_user( auth, slug, opts = {} )
|
44
|
+
raise Oos4ruby::UnknownUser if slug.nil?
|
45
|
+
|
46
|
+
uri = SITES_URL + "/#{slug}"
|
47
|
+
|
48
|
+
getter = HTTPInvoker.new uri, auth
|
49
|
+
|
50
|
+
worked = getter.get
|
51
|
+
|
52
|
+
Sites.new(Feed.read(getter.body), auth, slug) if worked
|
53
|
+
end
|
54
|
+
|
55
|
+
def Site.dump!(opts, slug)
|
56
|
+
entry = create_entry
|
57
|
+
|
58
|
+
entry.add_element opts[:author]
|
59
|
+
|
60
|
+
add_element entry, 'updated', DateTime.now
|
61
|
+
add_element entry, 'id', make_id
|
62
|
+
add_element entry, 'oos:id', opts[:id] if opts[:id]
|
63
|
+
add_element entry, 'title', opts[:title] if opts[:title]
|
64
|
+
add_element entry, 'oos:useraddress', opts[:user_address] if opts[:user_address]
|
65
|
+
add_element entry, 'oos:url', opts[:url] if opts[:url]
|
66
|
+
add_element entry, 'summary', opts[:review_title] if opts[:review_title]
|
67
|
+
add_element entry, 'summary', opts[:summary] if opts[:summary] and REXML::XPath.first(entry, 'summary', XmlNamespaces).nil?
|
68
|
+
|
69
|
+
if opts[:privacy]
|
70
|
+
if opts[:privacy].is_a?REXML::Element
|
71
|
+
entry.add_element opts[:privacy]
|
72
|
+
elsif opts[:privacy].is_a?String
|
73
|
+
add_category entry, opts[:privacy], PRIVACY_URL
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
if opts[:review_content] || opts[:content]
|
78
|
+
content = opts[:review_content] || opts[:content]
|
79
|
+
attrs = {}
|
80
|
+
text = nil
|
81
|
+
if content.is_a?String
|
82
|
+
text = content
|
83
|
+
elsif content.is_a?Hash
|
84
|
+
text = content[:text]
|
85
|
+
content.delete :text
|
86
|
+
content.each_pair {|key, value| attrs[key.to_s] = value}
|
87
|
+
end
|
88
|
+
add_element entry, 'content', text, attrs
|
89
|
+
end
|
90
|
+
|
91
|
+
if opts[:locality]
|
92
|
+
name = nil
|
93
|
+
local_slug = nil
|
94
|
+
attrs = {}
|
95
|
+
if opts[:locality].is_a?Hash
|
96
|
+
name = opts[:locality][:name]
|
97
|
+
local_slug = opts[:locality][:slug]
|
98
|
+
elsif opts[:locality].is_a?String
|
99
|
+
name = opts[:locality]
|
100
|
+
end
|
101
|
+
attrs['slug'] = local_slug if local_slug
|
102
|
+
add_element entry, 'oos:locality', name, attrs
|
103
|
+
end
|
104
|
+
|
105
|
+
if opts[:country]
|
106
|
+
name = opts[:country][:name]
|
107
|
+
opts[:country].delete :name
|
108
|
+
attrs = {}
|
109
|
+
opts[:country].each_pair {|key, value| attrs[key.to_s] = value}
|
110
|
+
add_element entry, 'oos:country', name, attrs
|
111
|
+
end
|
112
|
+
|
113
|
+
opts[:tags].each { |tag| add_category entry, tag.to_s, "#{TAGS_URL}/#{slug}"} if opts[:tags]
|
114
|
+
opts[:lists].each { |list| add_category entry, list.to_s, "#{LISTS_URL}/#{slug}"} if opts[:lists]
|
115
|
+
|
116
|
+
entry
|
117
|
+
end
|
118
|
+
|
119
|
+
def tags
|
120
|
+
return @tags if @tags
|
121
|
+
categories = @xml.match("./atom:category[@scheme=\"#{@tags_scheme}\"]")
|
122
|
+
if categories
|
123
|
+
@tags = categories.map { |cat|
|
124
|
+
Category.new cat
|
125
|
+
}
|
126
|
+
end
|
127
|
+
@tags
|
128
|
+
end
|
129
|
+
|
130
|
+
def lists
|
131
|
+
return @lists if @lists
|
132
|
+
categories = @xml.match("./atom:category[@scheme=\"#{@lists_scheme}\"]")
|
133
|
+
if categories
|
134
|
+
@lists = categories.map { |cat|
|
135
|
+
Category.new cat
|
136
|
+
}
|
137
|
+
end
|
138
|
+
@lists
|
139
|
+
end
|
140
|
+
|
141
|
+
def latitude
|
142
|
+
@xml.first('./georss:where/gml:Point/gml:pos').text.
|
143
|
+
split[0] if @xml.first('./georss:where')
|
144
|
+
end
|
145
|
+
|
146
|
+
def longitude
|
147
|
+
@xml.first('./georss:where/gml:Point/gml:pos').text.
|
148
|
+
split[1] if @xml.first('./georss:where')
|
149
|
+
end
|
150
|
+
|
151
|
+
def add_tag(tag)
|
152
|
+
tag = Category.new(tag, @tags_scheme )
|
153
|
+
@categories_added << tag
|
154
|
+
end
|
155
|
+
|
156
|
+
def add_list(list)
|
157
|
+
list = Category.new(list, @lists_scheme )
|
158
|
+
@categories_added << list
|
159
|
+
end
|
160
|
+
|
161
|
+
def remove_tag(tag)
|
162
|
+
tag = Category.new(tag, @tags_scheme )
|
163
|
+
@categories_removed << tag
|
164
|
+
end
|
165
|
+
|
166
|
+
def remove_list(list)
|
167
|
+
list = Category.new(list, @lists_scheme )
|
168
|
+
@categories_removed << list
|
169
|
+
end
|
170
|
+
|
171
|
+
def privacy
|
172
|
+
return @privacy if @privacy
|
173
|
+
@privacy = @xml.category({:scheme => PRIVACY_URL}).attributes['term']
|
174
|
+
@privacy
|
175
|
+
end
|
176
|
+
|
177
|
+
def privacy=(privacy)
|
178
|
+
@privacy_updated = privacy
|
179
|
+
end
|
180
|
+
|
181
|
+
private
|
182
|
+
def load!
|
183
|
+
if @title_review
|
184
|
+
summary = @xml.child('summary') || @xml.add_child('summary')
|
185
|
+
summary.text = @title_review
|
186
|
+
end
|
187
|
+
|
188
|
+
if @content_review
|
189
|
+
content = @xml.child('content') || @xml.add_child('content', nil, nil, {:type => 'html'})
|
190
|
+
content.text = @content_review
|
191
|
+
end
|
192
|
+
|
193
|
+
if @categories_added
|
194
|
+
@categories_added.each { |cat|
|
195
|
+
add_category cat.term, cat.scheme
|
196
|
+
@tags << cat if cat.scheme == @tags_scheme
|
197
|
+
@lists << cat if cat.scheme == @lists_scheme
|
198
|
+
}
|
199
|
+
@categories_added.clear
|
200
|
+
end
|
201
|
+
|
202
|
+
if @categories_removed
|
203
|
+
@categories_removed.each { |cat|
|
204
|
+
remove_category cat.term, cat.scheme
|
205
|
+
@tags = @tags.reject { |tag|
|
206
|
+
tag.term == cat.term and tag.scheme == cat.scheme
|
207
|
+
}
|
208
|
+
}
|
209
|
+
@categories_removed.clear
|
210
|
+
end
|
211
|
+
|
212
|
+
update_category @privacy_updated.term, @privacy_updated.scheme,
|
213
|
+
nil, @privacy_updated.scheme if @privacy_updated
|
214
|
+
|
215
|
+
end
|
216
|
+
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
|
@@ -0,0 +1,122 @@
|
|
1
|
+
|
2
|
+
require 'mime/types'
|
3
|
+
|
4
|
+
include Bean
|
5
|
+
|
6
|
+
module Oos4ruby
|
7
|
+
class User < Bean::BeanClass
|
8
|
+
|
9
|
+
define_el_reader({
|
10
|
+
OosNamespace => [:name, :surname, :no_mails, :only_contacts, :no_newsletter],
|
11
|
+
AtomNamespace => [:title, :updated, :content]
|
12
|
+
})
|
13
|
+
|
14
|
+
alias :nick :title
|
15
|
+
alias :about_me :content
|
16
|
+
|
17
|
+
attr_writer :nick, :about_me, :name, :surname, :no_mails, :only_contacts, :no_newsletter
|
18
|
+
|
19
|
+
def initialize(entry, auth, slug = nil)
|
20
|
+
@xml = entry
|
21
|
+
@auth = auth
|
22
|
+
@slug = slug || @xml.child('slug', OosNamespace).text
|
23
|
+
end
|
24
|
+
|
25
|
+
def User.find( auth, slug = nil )
|
26
|
+
raise Oos4ruby::UnknownUser if auth.method?(:app) && slug.nil?
|
27
|
+
|
28
|
+
begin
|
29
|
+
uri = URI.parse(slug)
|
30
|
+
rescue
|
31
|
+
uri = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
unless uri
|
35
|
+
uri = USERS_URL
|
36
|
+
uri = uri + "/#{slug}" if slug
|
37
|
+
end
|
38
|
+
|
39
|
+
getter = HTTPInvoker.new uri.to_s, auth
|
40
|
+
|
41
|
+
worked = getter.get
|
42
|
+
|
43
|
+
if worked
|
44
|
+
if slug #response is an Entry
|
45
|
+
entry = Entry.new getter.body
|
46
|
+
return User.new(entry, auth, slug)
|
47
|
+
else
|
48
|
+
#response is a feed
|
49
|
+
feed = Feed.read getter.body
|
50
|
+
rel_edit = feed.entries[0].link('edit')
|
51
|
+
|
52
|
+
getter = HTTPInvoker.new rel_edit, auth
|
53
|
+
worked = getter.get
|
54
|
+
if worked
|
55
|
+
entry = Entry.new getter.body
|
56
|
+
return User.new(entry, auth)
|
57
|
+
else
|
58
|
+
raise Oos4ruby::UnknownUser
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_xml
|
65
|
+
@xml.to_s
|
66
|
+
end
|
67
|
+
|
68
|
+
def sites( opts = {} )
|
69
|
+
@sites_collection = Site.find_by_user(@auth, @slug, opts) unless @sites_collection
|
70
|
+
@sites_collection
|
71
|
+
end
|
72
|
+
|
73
|
+
def contacts( opts = {} )
|
74
|
+
@contacts_collection = Contact.find_by_user(@auth, @slug, opts) unless @contacts_collection
|
75
|
+
@contacts_collection
|
76
|
+
end
|
77
|
+
|
78
|
+
def avatar
|
79
|
+
@xml.link('avatar')
|
80
|
+
end
|
81
|
+
|
82
|
+
def avatar!(file_path)
|
83
|
+
getter = HTTPInvoker.new @xml.link('edit-media'), @auth
|
84
|
+
worked = getter.get
|
85
|
+
|
86
|
+
if worked
|
87
|
+
file = File.new(file_path, 'w+')
|
88
|
+
file << getter.body
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def update_avatar!(file_path)
|
93
|
+
file = File.open(file_path, "rb") { |f| f.read }
|
94
|
+
|
95
|
+
putter = HTTPInvoker.new(@xml.link('edit-media'), @auth)
|
96
|
+
|
97
|
+
putter.set_header 'Content-Length', File.size(file_path)
|
98
|
+
|
99
|
+
worked = putter.put MIME::Types.type_for(file_path)[0].to_s, file
|
100
|
+
|
101
|
+
raise RuntimeError unless worked
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
def load!
|
106
|
+
@xml.child('title').text = @nick if @nick
|
107
|
+
if @about_me
|
108
|
+
about = @xml.child('content') || @xml.add_child('content', nil, nil, {:type => 'text'})
|
109
|
+
about.text = @about_me
|
110
|
+
end
|
111
|
+
|
112
|
+
@xml.child('name', OosNamespace).text = @name if @name
|
113
|
+
@xml.child('surname', OosNamespace).text = @surname if @surname
|
114
|
+
@xml.child('nomails', OosNamespace).text = @no_mails.to_s if !@no_mails.nil?
|
115
|
+
@xml.child('nonewsletter', OosNamespace).text = @no_newsletter.to_s if !@no_newsletter.nil?
|
116
|
+
@xml.child('onlycontacts', OosNamespace).text = @only_contacts.to_s if !@only_contacts.nil?
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
|