Module: Lotus

Defined in:
lib/lotus.rb,
lib/lotus/feed.rb,
lib/lotus/link.rb,
lib/lotus/author.rb,
lib/lotus/crypto.rb,
lib/lotus/version.rb,
lib/lotus/activity.rb,
lib/lotus/category.rb,
lib/lotus/identity.rb,
lib/lotus/atom/feed.rb,
lib/lotus/atom/link.rb,
lib/lotus/atom/name.rb,
lib/lotus/generator.rb,
lib/lotus/publisher.rb,
lib/lotus/atom/entry.rb,
lib/lotus/atom/author.rb,
lib/lotus/atom/source.rb,
lib/lotus/atom/thread.rb,
lib/lotus/atom/account.rb,
lib/lotus/atom/address.rb,
lib/lotus/notification.rb,
lib/lotus/subscription.rb,
lib/lotus/atom/category.rb,
lib/lotus/atom/generator.rb,
lib/lotus/atom/organization.rb,
lib/lotus/atom/portable_contacts.rb

Overview

This module contains elements that allow federated interaction. It also contains methods to construct these objects from external sources.

Defined Under Namespace

Modules: Atom, Crypto Classes: Activity, Author, Category, Feed, Generator, Identity, Link, Notification, Publisher, Subscription

Constant Summary collapse

MIME_ORDER =

The order to respect atom links

['application/atom+xml',
'application/rss+xml',
'application/xml']
VERSION =
"0.0.12"

Class Method Summary collapse

Class Method Details

.activity_from_string(string, content_type = "application/atom+xml") ⇒ Object

Yield a Lotus::Activity from the given string content.



191
192
193
194
195
196
197
198
# File 'lib/lotus.rb', line 191

def self.activity_from_string(string, content_type = "application/atom+xml")
  content_type ||= "application/atom+xml"

  case content_type
  when 'application/atom+xml', 'application/rss+xml', 'application/xml'
    Lotus::Atom::Entry.new(XML::Reader.string(string)).to_canonical
  end
end

.activity_from_url(url, content_type = nil) ⇒ Object

Yield a Lotus::Activity from the given url.



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/lotus.rb', line 173

def self.activity_from_url(url, content_type = nil)
  # Atom is default type to attempt to retrieve
  content_type ||= "application/atom+xml"

  response = Lotus.pull_url(url, content_type)

  return nil unless response.is_a?(Net::HTTPSuccess)

  content_type = response.content_type

  case content_type
  when 'application/atom+xml', 'application/rss+xml', 'application/xml'
    xml_str = response.body
    self.entry_from_string(xml_str, response.content_type)
  end
end

.discover_activity(url) ⇒ Object



168
169
170
# File 'lib/lotus.rb', line 168

def self.discover_activity(url)
  self.activity_from_url(url)
end

.discover_author(identity) ⇒ Object

Will yield an Lotus::Author for the given person.

identity: Can be a String containing a fully qualified name (i.e. “[email protected]”) or a previously resolved Lotus::Identity.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/lotus.rb', line 64

def self.discover_author(identity)
  if identity.is_a? String
    identity = self.discover_identity(identity)
  end

  return nil if identity.nil? || identity.profile_page.nil?

  # Discover Author information

  # Pull profile page
  # Look for a feed to pull
  feed = self.discover_feed(identity.profile_page)
  feed.authors.first
end

.discover_feed(url_or_identity, content_type = "application/atom+xml") ⇒ Object

Will yield a Lotus::Feed object representing the feed at the given url or identity.

Usage:

feed = Lotus.discover_feed("https://rstat.us/users/wilkieii/feed")

i = Lotus.discover_identity("[email protected]")
feed = Lotus.discover_feed(i)


87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/lotus.rb', line 87

def self.discover_feed(url_or_identity, content_type = "application/atom+xml")
  if url_or_identity =~ /^(?:acct:)?[^@]+@[^@]+\.[^@]+$/
    url_or_identity = Lotus::discover_identity(url_or_identity)
  end

  if url_or_identity.is_a? Lotus::Identity
    return self.discover_feed(url_or_identity.profile_page)
  end

  # Atom is default type to attempt to retrieve
  content_type ||= "application/atom+xml"

  url = url_or_identity

  if url =~ /^http[s]?:\/\//
    # Url is an internet resource
    response = Lotus::pull_url(url, content_type)

    return nil unless response.is_a?(Net::HTTPSuccess)

    content_type = response.content_type
    str = response.body
  else
    str = open(url).read
  end

  case content_type
  when 'application/atom+xml', 'application/rss+xml', 'application/xml',
       'xml', 'atom', 'rss', 'atom+xml', 'rss+xml'
    xml_str = str

    self.feed_from_string(xml_str, content_type)
  when 'text/html'
    html_str = str

    # Discover the feed
    doc = Nokogiri::HTML::Document.parse(html_str)
    links = doc.xpath("//link[@rel='alternate']").map {|el|
      {:type => el.attributes['type'].to_s,
       :href => el.attributes['href'].to_s}
    }.select{|e|
      MIME_ORDER.include? e[:type]
    }.sort {|a, b|
      MIME_ORDER.index(a[:type]) <=>
      MIME_ORDER.index(b[:type])
    }

    return nil if links.empty?

    # Resolve relative links
    link = URI::parse(links.first[:href]) rescue URI.new

    unless link.scheme
      link.scheme = URI::parse(url).scheme
    end

    unless link.host
      link.host = URI::parse(url).host rescue nil
    end

    unless link.absolute?
      link.path = File::dirname(URI::parse(url).path) \
        + '/' + link.path rescue nil
    end

    url = link.to_s
    self.discover_feed(url, links.first[:type])
  end
end

.discover_identity(name) ⇒ Object

Will yield an OStatus::Identity for the given fully qualified name (i.e. “[email protected]”)



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/lotus.rb', line 32

def self.discover_identity(name)
  xrd = Redfinger.finger(name)

  # magic-envelope public key
  public_key = find_link(xrd, 'magic-public-key')
  public_key = public_key.split(",")[1] || ""

  # ostatus notification endpoint
  salmon_url = find_link(xrd, 'salmon')

  # pump.io authentication endpoint
  dialback_url = find_link(xrd, 'dialback')

  # pump.io activity endpoints
  activity_inbox_endpoint = find_link(xrd, 'activity-inbox')
  activity_outbox_endpoint = find_link(xrd, 'activity-outbox')

  # profile page
  profile_page = find_link(xrd, 'http://webfinger.net/rel/profile-page')

  Identity.new(:public_key        => public_key,
               :profile_page      => profile_page,
               :salmon_endpoint   => salmon_url,
               :dialback_endpoint => dialback_url,
               :activity_inbox_endpoint => activity_inbox_endpoint,
               :activity_outbox_endpoint => activity_outbox_endpoint)
end

.feed_from_string(string, content_type = nil) ⇒ Object

Yield a Lotus::Feed from the given string content.



158
159
160
161
162
163
164
165
166
# File 'lib/lotus.rb', line 158

def self.feed_from_string(string, content_type = nil)
  # Atom is default type to attempt to retrieve
  content_type ||= "application/atom+xml"

  case content_type
  when 'application/atom+xml', 'application/rss+xml', 'application/xml'
    Lotus::Atom::Feed.new(XML::Reader.string(string)).to_canonical
  end
end