diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index 685b02ae6d..ff1fd4ca20 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true class AccountsController < ApplicationController + OFFSET = 0 PAGE_SIZE = 20 PAGE_SIZE_MAX = 200 @@ -20,17 +21,21 @@ class AccountsController < ApplicationController expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.hour) unless user_signed_in? end - format.rss do + format.any(:rss, :txt) do expires_in 1.minute, public: true limit = params[:limit].present? ? [params[:limit].to_i, PAGE_SIZE_MAX].min : PAGE_SIZE - @statuses = filtered_statuses.without_reblogs.limit(limit) - @statuses = preload_collection(@statuses, Status) + offset = params[:offset].present? ? params[:offset].to_i : OFFSET + @statuses = filtered_statuses.without_reblogs.limit(limit).offset(offset) + @statuses = cache_collection(@statuses, Status) end format.json do expires_in 3.minutes, public: !(authorized_fetch_mode? && signed_request_account.present?) - render_with_cache json: @account, content_type: 'application/activity+json', serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter + render_with_cache json: @account, + content_type: 'application/activity+json', + serializer: ActivityPub::ActorSerializer, + adapter: ActivityPub::Adapter end end end @@ -46,7 +51,7 @@ class AccountsController < ApplicationController end def default_statuses - @account.statuses.not_local_only.distributable_visibility + @account.statuses.not_local_only.where(visibility: [:public, :unlisted]) end def only_media_scope diff --git a/app/views/accounts/show.txt.erb b/app/views/accounts/show.txt.erb new file mode 100644 index 0000000000..64997f33e5 --- /dev/null +++ b/app/views/accounts/show.txt.erb @@ -0,0 +1,39 @@ +<% account_url = params[:tag].present? ? short_account_tag_url(@account, params[:tag]) : short_account_url(@account) %> +# Twtxt is an open, distributed microblogging platform that +# uses human-readable text files, common transport protocols, +# and free software. +# +# Learn more about twtxt at https://github.com/buckket/twtxt +# +# The numeric value between the date and the status text (#...) is the id +# of that toot, so you can easily find the URL of a toot. +# +# By default, you will only see the 20 most recent statuses. +# +# You can also set parameters "limit" and "offset" in your query string if +# you want to fetch more statuses. Please note that you can only fetch up +# to 200 statuses at a time. +# +# E.g. to get the latest 200 statuses: +# <%= account_url %>.txt?limit=200 +# +# E.g. to skip the latest 200 status, and fetch the 200 previous ones: +# <%= account_url %>.txt?offset=200&limit=200 +# +# nick = @<%= @account.local_username_and_domain %> +# url = <%= account_url %>.txt +# avatar = <%= full_asset_url(@account.avatar.url(:original)) %> +# description = <%= I18n.t('rss.descriptions.account', acct: @account.local_username_and_domain) %> + +<% @statuses.each do |status| %> +<% plain_text_status = (extract_status_plain_text status).gsub("\n", "\u2028") %> +<% status.ordered_media_attachments.each do |media| %> +<% media_url = full_asset_url(media.file.url(:original, false)) %> +<% media_description = media.description.nil? ? "" : media.description.gsub("\n", " ") %> +<% plain_text_status += " ![#{media_description}](#{media_url})" %> +<% end %> +<% if !plain_text_status.empty? %> +<% plain_text_status = " (\##{status.id}) #{plain_text_status}" %> +<%= status.created_at.rfc3339 %> <%= plain_text_status %> +<% end %> +<% end %> diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb index dde308cbc1..642bc1ed96 100644 --- a/config/initializers/mime_types.rb +++ b/config/initializers/mime_types.rb @@ -2,6 +2,7 @@ Mime::Type.register 'application/json', :json, %w(text/x-json application/jsonrequest application/jrd+json application/activity+json application/ld+json) Mime::Type.register 'text/xml', :xml, %w(application/xml application/atom+xml application/xrd+xml) +Mime::Type.register 'text/plain', :txt, %w(text/plain) # WebP is not defined in Rack 2.2. Rack::Mime::MIME_TYPES['.webp'] = 'image/webp'