Skip to content
Snippets Groups Projects
Commit 3b0bc18d authored by Eugen Rochko's avatar Eugen Rochko
Browse files

Improved Atom rendering templates, added README

parent 2bc48e90
No related branches found
No related tags found
No related merge requests found
Mastodon
========
Mastodon is a federated microblogging engine. An alternative implementation of the GNU Social project. Based on ActivityStreams, Webfinger, PubsubHubbub and Salmon.
The core ideals of this project are:
- Independence of legacy Twitter APIs - we don't want to be compatible with Twitter clients, we want our own clients
- In that vein, a strong and clean REST API and OAuth2
- Minimalism. Just because you can do almost anything with ActivityStreams doesn't mean you should. Limit the set of possible functions to what makes sense in a microblogging engine. This will make federation as well as UI design a lot easier
- Ease of deployment. The end-goal of this project is to be distributable as a Docker image.
**Current status of the project is early development. Documentation, licensing information &co will be added later**
== README
This README would normally document whatever steps are necessary to get the
application up and running.
Things you may want to cover:
* Ruby version
* System dependencies
* Configuration
* Database creation
* Database initialization
* How to run the test suite
* Services (job queues, cache servers, search engines, etc.)
* Deployment instructions
* ...
Please feel free to use a different markup language if you do not plan to run
<tt>rake doc:app</tt>.
module AtomHelper module AtomHelper
def stream_updated_at def stream_updated_at
@account.stream_entries.last ? @account.stream_entries.last.created_at.iso8601 : @account.updated_at.iso8601 @account.stream_entries.last ? @account.stream_entries.last.created_at : @account.updated_at
end
def entry(xml, is_root, &block)
if is_root
root_tag(xml, :entry, &block)
else
xml.entry &block
end
end
def feed(xml, &block)
root_tag(xml, :feed, &block)
end
def unique_id(xml, date, id, type)
xml.id_ unique_tag(date, id, type)
end
def simple_id(xml, id)
xml.id_ id
end
def published_at(xml, date)
xml.published date.iso8601
end
def updated_at(xml, date)
xml.updated date.iso8601
end
def verb(xml, verb)
xml['activity'].send('verb', "http://activitystrea.ms/schema/1.0/#{verb}")
end
def content(xml, content)
xml.content({ type: 'html' }, content)
end
def title(xml, title)
xml.title title
end
def author(xml, &block)
xml.author &block
end
def target(xml, &block)
xml['activity'].object &block
end
def object_type(xml, type)
xml['activity'].send('object-type', "http://activitystrea.ms/schema/1.0/#{type}")
end
def uri(xml, uri)
xml.uri uri
end
def name(xml, name)
xml.name name
end
def summary(xml, summary)
xml.summary summary
end
def subtitle(xml, subtitle)
xml.subtitle subtitle
end
def link_alternate(xml, url)
xml.link(rel: 'alternate', type: 'text/html', href: url)
end
def link_self(xml, url)
xml.link(rel: 'self', type: 'application/atom+xml', href: url)
end
def link_hub(xml, url)
xml.link(rel: 'hub', href: url)
end
def link_salmon(xml, url)
xml.link(rel: 'salmon', href: url)
end
def portable_contact(xml, account)
xml['poco'].preferredUsername account.username
xml['poco'].displayName account.display_name
xml['poco'].note account.note
end
private
def root_tag(xml, tag, &block)
xml.send(tag, {xmlns: 'http://www.w3.org/2005/Atom', 'xmlns:thr': 'http://purl.org/syndication/thread/1.0', 'xmlns:activity': 'http://activitystrea.ms/spec/1.0/', 'xmlns:poco': 'http://portablecontacts.net/spec/1.0'}, &block)
end end
end end
...@@ -6,7 +6,7 @@ class ProcessFeedService ...@@ -6,7 +6,7 @@ class ProcessFeedService
uri = entry.at_xpath('./xmlns:id').content uri = entry.at_xpath('./xmlns:id').content
status = Status.find_by(uri: uri) status = Status.find_by(uri: uri)
next unless status.nil? next if !status.nil?
status = Status.new status = Status.new
status.account = account status.account = account
...@@ -15,6 +15,9 @@ class ProcessFeedService ...@@ -15,6 +15,9 @@ class ProcessFeedService
status.created_at = entry.at_xpath('./xmlns:published').content status.created_at = entry.at_xpath('./xmlns:published').content
status.updated_at = entry.at_xpath('./xmlns:updated').content status.updated_at = entry.at_xpath('./xmlns:updated').content
status.save! status.save!
# todo: not everything is a status. there are follows, favourites
# todo: RTs
end end
end end
end end
...@@ -29,6 +29,7 @@ class ProcessInteractionService ...@@ -29,6 +29,7 @@ class ProcessInteractionService
private private
def involves_target_account(target_account) def involves_target_account(target_account)
# todo
end end
def salmon def salmon
......
Nokogiri::XML::Builder.new do |xml| Nokogiri::XML::Builder.new do |xml|
xml.entry(xmlns: 'http://www.w3.org/2005/Atom', 'xmlns:thr': 'http://purl.org/syndication/thread/1.0', 'xmlns:activity': 'http://activitystrea.ms/spec/1.0/', 'xmlns:poco': 'http://portablecontacts.net/spec/1.0') do entry(xml, true) do
xml.id_ unique_tag(@entry.created_at, @entry.activity_id, @entry.activity_type) unique_id xml, @entry.created_at, @entry.activity_id, @entry.activity_type
published_at xml, @entry.activity.created_at
updated_at xml, @entry.activity.updated_at
title xml, @entry.title
content xml, @entry.content
verb xml, @entry.verb
xml.published @entry.activity.created_at.iso8601 author(xml) do
xml.updated @entry.activity.updated_at.iso8601 object_type xml, :person
uri xml, profile_url(name: @entry.account.username)
xml.title @entry.title name xml, @entry.account.username
xml.content({ type: 'html' }, @entry.content) summary xml, @entry.account.note
xml['activity'].send('verb', "http://activitystrea.ms/schema/1.0/#{@entry.verb}") link_alternate xml, profile_url(name: @entry.account.username)
portable_contact xml, @entry.account
xml.author do
xml['activity'].send('object-type', 'http://activitystrea.ms/schema/1.0/person')
xml.uri profile_url(name: @entry.account.username)
xml.name @entry.account.username
xml.summary @entry.account.note
xml.link(rel: 'alternate', type: 'text/html', href: profile_url(name: @entry.account.username))
xml['poco'].preferredUsername @entry.account.username
xml['poco'].displayName @entry.account.display_name
xml['poco'].note @entry.account.note
end end
if @entry.targeted? if @entry.targeted?
xml['activity'].send('object') do target(xml) do
xml['activity'].send('object-type', "http://activitystrea.ms/schema/1.0/#{@entry.target.object_type}") object_type xml, @entry.target.object_type
xml.id_ @entry.target.uri simple_id xml, @entry.target.uri
xml.title @entry.target.title title xml, @entry.target.title
xml.summary @entry.target.summary summary xml, @entry.target.summary
xml.link(rel: 'alternate', type: 'text/html', href: @entry.target.uri) link_alternate xml, @entry.target.uri
if @entry.target.object_type == :person
portable_contact xml, @entry.target
end
end end
else else
xml['activity'].send('object-type', "http://activitystrea.ms/schema/1.0/#{@entry.object_type}") object_type xml, @entry.object_type
end end
xml.link(rel: 'self', type: 'application/atom+xml', href: atom_entry_url(id: @entry.id)) link_self xml, atom_entry_url(id: @entry.id)
end end
end.to_xml end
Nokogiri::XML::Builder.new do |xml| Nokogiri::XML::Builder.new do |xml|
xml.feed(xmlns: 'http://www.w3.org/2005/Atom', 'xmlns:thr': 'http://purl.org/syndication/thread/1.0', 'xmlns:activity': 'http://activitystrea.ms/spec/1.0/', 'xmlns:poco': 'http://portablecontacts.net/spec/1.0') do feed(xml) do
xml.id_ atom_user_stream_url(id: @account.id) simple_id xml, atom_user_stream_url(id: @account.id)
xml.title @account.display_name title xml, @account.display_name
xml.subtitle @account.note subtitle xml, @account.note
xml.updated stream_updated_at updated_at xml, stream_updated_at
xml.author do author(xml) do
xml['activity'].send('object-type', 'http://activitystrea.ms/schema/1.0/person') object_type xml, :person
xml.uri profile_url(name: @account.username) uri xml, profile_url(name: @account.username)
xml.name @account.username name xml, @account.username
xml.summary @account.note summary xml, @account.note
link_alternate xml, profile_url(name: @account.username)
xml.link(rel: 'alternate', type: 'text/html', href: profile_url(name: @account.username)) portable_contact xml, @account
xml['poco'].preferredUsername @account.username
xml['poco'].displayName @account.display_name
xml['poco'].note @account.note
end end
xml.link(rel: 'alternate', type: 'text/html', href: profile_url(name: @account.username)) link_alternate xml, profile_url(name: @account.username)
xml.link(rel: 'hub', href: HUB_URL) link_self xml, atom_user_stream_url(id: @account.id)
xml.link(rel: 'salmon', href: salmon_url(@account)) link_hub xml, HUB_URL
xml.link(rel: 'self', type: 'application/atom+xml', href: atom_user_stream_url(id: @account.id)) link_salmon xml, salmon_url(@account)
@account.stream_entries.order('id desc').each do |stream_entry| @account.stream_entries.order('id desc').each do |stream_entry|
xml.entry do entry(xml, false) do
xml.id_ unique_tag(stream_entry.created_at, stream_entry.activity_id, stream_entry.activity_type) unique_id xml, stream_entry.created_at, stream_entry.activity_id, stream_entry.activity_type
published_at xml, stream_entry.activity.created_at
xml.published stream_entry.activity.created_at.iso8601 updated_at xml, stream_entry.activity.updated_at
xml.updated stream_entry.activity.updated_at.iso8601 title xml, stream_entry.title
content xml, stream_entry.content
xml.title stream_entry.title verb xml, stream_entry.verb
xml.content({ type: 'html' }, stream_entry.content) link_self xml, atom_entry_url(id: stream_entry.id)
xml['activity'].send('verb', "http://activitystrea.ms/schema/1.0/#{stream_entry.verb}")
if stream_entry.targeted? if stream_entry.targeted?
xml['activity'].send('object') do target(xml) do
xml['activity'].send('object-type', "http://activitystrea.ms/schema/1.0/#{stream_entry.target.object_type}") object_type xml, stream_entry.target.object_type
xml.id_ stream_entry.target.uri simple_id xml, stream_entry.target.uri
xml.title stream_entry.target.title title xml, stream_entry.target.title
xml.summary stream_entry.target.summary summary xml, stream_entry.target.summary
xml.link(rel: 'alternate', type: 'text/html', href: stream_entry.target.uri) link_alternate xml, stream_entry.target.uri
if stream_entry.target.object_type == :person
portable_contact xml, stream_entry.target
end
end end
else else
xml['activity'].send('object-type', "http://activitystrea.ms/schema/1.0/#{stream_entry.object_type}") object_type xml, stream_entry.object_type
end end
xml.link(rel: 'self', type: 'application/atom+xml', href: atom_entry_url(id: stream_entry.id))
end end
end end
end end
......
...@@ -2,9 +2,9 @@ Rails.application.routes.draw do ...@@ -2,9 +2,9 @@ Rails.application.routes.draw do
get '.well-known/host-meta', to: 'xrd#host_meta', as: :host_meta get '.well-known/host-meta', to: 'xrd#host_meta', as: :host_meta
get '.well-known/webfinger', to: 'xrd#webfinger', as: :webfinger get '.well-known/webfinger', to: 'xrd#webfinger', as: :webfinger
get 'atom/entry/:id', to: 'atom#entry', as: :atom_entry get 'atom/entries/:id', to: 'atom#entry', as: :atom_entry
get 'atom/user/:id', to: 'atom#user_stream', as: :atom_user_stream get 'atom/users/:id', to: 'atom#user_stream', as: :atom_user_stream
get 'user/:name', to: 'profile#show', as: :profile get 'users/:name', to: 'profile#show', as: :profile
mount Mastodon::API => '/api/' mount Mastodon::API => '/api/'
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment