Improved Atom rendering templates, added README
This commit is contained in:
		
							
								
								
									
										13
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| 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** | ||||
							
								
								
									
										28
									
								
								README.rdoc
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								README.rdoc
									
									
									
									
									
								
							| @@ -1,28 +0,0 @@ | ||||
| == 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>. | ||||
| @@ -1,5 +1,101 @@ | ||||
| module AtomHelper | ||||
|   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 | ||||
|   | ||||
| @@ -6,7 +6,7 @@ class ProcessFeedService | ||||
|       uri    = entry.at_xpath('./xmlns:id').content | ||||
|       status = Status.find_by(uri: uri) | ||||
|  | ||||
|       next unless status.nil? | ||||
|       next if !status.nil? | ||||
|  | ||||
|       status = Status.new | ||||
|       status.account    = account | ||||
| @@ -15,6 +15,9 @@ class ProcessFeedService | ||||
|       status.created_at = entry.at_xpath('./xmlns:published').content | ||||
|       status.updated_at = entry.at_xpath('./xmlns:updated').content | ||||
|       status.save! | ||||
|  | ||||
|       # todo: not everything is a status. there are follows, favourites | ||||
|       # todo: RTs | ||||
|     end | ||||
|   end | ||||
| end | ||||
|   | ||||
| @@ -29,6 +29,7 @@ class ProcessInteractionService | ||||
|   private | ||||
|  | ||||
|   def involves_target_account(target_account) | ||||
|     # todo | ||||
|   end | ||||
|  | ||||
|   def salmon | ||||
|   | ||||
| @@ -1,39 +1,37 @@ | ||||
| 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 | ||||
|     xml.id_ unique_tag(@entry.created_at, @entry.activity_id, @entry.activity_type) | ||||
|   entry(xml, true) do | ||||
|     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 | ||||
|     xml.updated   @entry.activity.updated_at.iso8601 | ||||
|  | ||||
|     xml.title @entry.title | ||||
|     xml.content({ type: 'html' }, @entry.content) | ||||
|     xml['activity'].send('verb', "http://activitystrea.ms/schema/1.0/#{@entry.verb}") | ||||
|  | ||||
|     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 | ||||
|     author(xml) do | ||||
|       object_type      xml, :person | ||||
|       uri              xml, profile_url(name: @entry.account.username) | ||||
|       name             xml, @entry.account.username | ||||
|       summary          xml, @entry.account.note | ||||
|       link_alternate   xml, profile_url(name: @entry.account.username) | ||||
|       portable_contact xml, @entry.account | ||||
|     end | ||||
|  | ||||
|     if @entry.targeted? | ||||
|       xml['activity'].send('object') do | ||||
|         xml['activity'].send('object-type', "http://activitystrea.ms/schema/1.0/#{@entry.target.object_type}") | ||||
|         xml.id_ @entry.target.uri | ||||
|         xml.title @entry.target.title | ||||
|         xml.summary @entry.target.summary | ||||
|         xml.link(rel: 'alternate', type: 'text/html', href: @entry.target.uri) | ||||
|       target(xml) do | ||||
|         object_type    xml, @entry.target.object_type | ||||
|         simple_id      xml, @entry.target.uri | ||||
|         title          xml, @entry.target.title | ||||
|         summary        xml, @entry.target.summary | ||||
|         link_alternate xml, @entry.target.uri | ||||
|  | ||||
|         if @entry.target.object_type == :person | ||||
|           portable_contact xml, @entry.target | ||||
|         end | ||||
|       end | ||||
|     else | ||||
|       xml['activity'].send('object-type', "http://activitystrea.ms/schema/1.0/#{@entry.object_type}") | ||||
|       object_type xml, @entry.object_type | ||||
|     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.to_xml | ||||
| end | ||||
|   | ||||
| @@ -1,52 +1,49 @@ | ||||
| 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 | ||||
|     xml.id_ atom_user_stream_url(id: @account.id) | ||||
|     xml.title @account.display_name | ||||
|     xml.subtitle @account.note | ||||
|     xml.updated stream_updated_at | ||||
|   feed(xml) do | ||||
|     simple_id  xml, atom_user_stream_url(id: @account.id) | ||||
|     title      xml, @account.display_name | ||||
|     subtitle   xml, @account.note | ||||
|     updated_at xml, stream_updated_at | ||||
|  | ||||
|     xml.author do | ||||
|       xml['activity'].send('object-type', 'http://activitystrea.ms/schema/1.0/person') | ||||
|       xml.uri profile_url(name: @account.username) | ||||
|       xml.name @account.username | ||||
|       xml.summary @account.note | ||||
|  | ||||
|       xml.link(rel: 'alternate', type: 'text/html', href: profile_url(name: @account.username)) | ||||
|  | ||||
|       xml['poco'].preferredUsername @account.username | ||||
|       xml['poco'].displayName @account.display_name | ||||
|       xml['poco'].note @account.note | ||||
|     author(xml) do | ||||
|       object_type      xml, :person | ||||
|       uri              xml, profile_url(name: @account.username) | ||||
|       name             xml, @account.username | ||||
|       summary          xml, @account.note | ||||
|       link_alternate   xml, profile_url(name: @account.username) | ||||
|       portable_contact xml, @account | ||||
|     end | ||||
|  | ||||
|     xml.link(rel: 'alternate', type: 'text/html', href: profile_url(name: @account.username)) | ||||
|     xml.link(rel: 'hub', href: HUB_URL) | ||||
|     xml.link(rel: 'salmon', href: salmon_url(@account)) | ||||
|     xml.link(rel: 'self', type: 'application/atom+xml', href: atom_user_stream_url(id: @account.id)) | ||||
|     link_alternate xml, profile_url(name: @account.username) | ||||
|     link_self      xml, atom_user_stream_url(id: @account.id) | ||||
|     link_hub       xml, HUB_URL | ||||
|     link_salmon    xml, salmon_url(@account) | ||||
|  | ||||
|     @account.stream_entries.order('id desc').each do |stream_entry| | ||||
|       xml.entry do | ||||
|         xml.id_ unique_tag(stream_entry.created_at, stream_entry.activity_id, stream_entry.activity_type) | ||||
|  | ||||
|         xml.published stream_entry.activity.created_at.iso8601 | ||||
|         xml.updated   stream_entry.activity.updated_at.iso8601 | ||||
|  | ||||
|         xml.title stream_entry.title | ||||
|         xml.content({ type: 'html' }, stream_entry.content) | ||||
|         xml['activity'].send('verb', "http://activitystrea.ms/schema/1.0/#{stream_entry.verb}") | ||||
|       entry(xml, false) do | ||||
|         unique_id    xml, stream_entry.created_at, stream_entry.activity_id, stream_entry.activity_type | ||||
|         published_at xml, stream_entry.activity.created_at | ||||
|         updated_at   xml, stream_entry.activity.updated_at | ||||
|         title        xml, stream_entry.title | ||||
|         content      xml, stream_entry.content | ||||
|         verb         xml, stream_entry.verb | ||||
|         link_self    xml, atom_entry_url(id: stream_entry.id) | ||||
|  | ||||
|         if stream_entry.targeted? | ||||
|           xml['activity'].send('object') do | ||||
|             xml['activity'].send('object-type', "http://activitystrea.ms/schema/1.0/#{stream_entry.target.object_type}") | ||||
|             xml.id_ stream_entry.target.uri | ||||
|             xml.title stream_entry.target.title | ||||
|             xml.summary stream_entry.target.summary | ||||
|             xml.link(rel: 'alternate', type: 'text/html', href: stream_entry.target.uri) | ||||
|           target(xml) do | ||||
|             object_type    xml, stream_entry.target.object_type | ||||
|             simple_id      xml, stream_entry.target.uri | ||||
|             title          xml, stream_entry.target.title | ||||
|             summary        xml, stream_entry.target.summary | ||||
|             link_alternate xml, stream_entry.target.uri | ||||
|  | ||||
|             if stream_entry.target.object_type == :person | ||||
|               portable_contact xml, stream_entry.target | ||||
|             end | ||||
|           end | ||||
|         else | ||||
|           xml['activity'].send('object-type', "http://activitystrea.ms/schema/1.0/#{stream_entry.object_type}") | ||||
|           object_type xml, stream_entry.object_type | ||||
|         end | ||||
|  | ||||
|         xml.link(rel: 'self', type: 'application/atom+xml', href: atom_entry_url(id: stream_entry.id)) | ||||
|       end | ||||
|     end | ||||
|   end | ||||
|   | ||||
| @@ -2,9 +2,9 @@ Rails.application.routes.draw do | ||||
|   get '.well-known/host-meta', to: 'xrd#host_meta', as: :host_meta | ||||
|   get '.well-known/webfinger', to: 'xrd#webfinger', as: :webfinger | ||||
|  | ||||
|   get 'atom/entry/:id', to: 'atom#entry',       as: :atom_entry | ||||
|   get 'atom/user/:id',  to: 'atom#user_stream', as: :atom_user_stream | ||||
|   get 'user/:name',     to: 'profile#show',     as: :profile | ||||
|   get 'atom/entries/:id', to: 'atom#entry',       as: :atom_entry | ||||
|   get 'atom/users/:id',   to: 'atom#user_stream', as: :atom_user_stream | ||||
|   get 'users/:name',      to: 'profile#show',     as: :profile | ||||
|  | ||||
|   mount Mastodon::API => '/api/' | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user