Skip to content
Snippets Groups Projects
Commit d23f3e3c authored by lain's avatar lain
Browse files

Add webfinger and basic feed support.

parent 36e883cd
No related branches found
No related tags found
No related merge requests found
defmodule Pleroma.Web.OStatus.FeedRepresenter do
alias Pleroma.Web.OStatus
alias Pleroma.Web.OStatus.UserRepresenter
def to_simple_form(user, activities, users) do
most_recent_update = List.first(activities).updated_at
|> NaiveDateTime.to_iso8601
h = fn(str) -> [to_charlist(str)] end
entries = []
[{
:feed, [
xmlns: 'http://www.w3.org/2005/Atom',
"xmlns:activity": 'http://activitystrea.ms/spec/1.0/'
], [
{:id, h.(OStatus.feed_path(user))},
{:title, ['#{user.nickname}\'s timeline']},
{:updated, h.(most_recent_update)},
{:entries, []},
{:link, [rel: 'hub', href: h.(OStatus.pubsub_path)], []},
{:author, UserRepresenter.to_simple_form(user)}
]
}]
end
end
defmodule Pleroma.Web.OStatus do
alias Pleroma.Web
def feed_path(user) do
"#{user.ap_id}/feed.atom"
end
def pubsub_path() do
"#{Web.base_url}/push/hub"
end
def user_path(user) do
end
end
defmodule Pleroma.Web.OStatus.OStatusController do
use Pleroma.Web, :controller
alias Pleroma.{User, Activity}
alias Pleroma.Web.OStatus.FeedRepresenter
alias Pleroma.Repo
import Ecto.Query
def feed(conn, %{"nickname" => nickname}) do
user = User.get_cached_by_nickname(nickname)
query = from activity in Activity,
where: fragment("? @> ?", activity.data, ^%{actor: user.ap_id}),
limit: 20,
order_by: [desc: :inserted_at]
activities = query
|> Repo.all
response = FeedRepresenter.to_simple_form(user, activities, [user])
|> :xmerl.export_simple(:xmerl_xml)
conn
|> put_resp_content_type("application/atom+xml")
|> send_resp(200, response)
end
end
defmodule Pleroma.Web.OStatus.UserRepresenter do
alias Pleroma.User
def to_tuple(user, wrapper \\ :author) do
{
wrapper, [
{ :id, user.ap_id },
{ :"activity:object", "http://activitystrea.ms/schema/1.0/person" },
{ :uri, user.ap_id },
{ :name, user.nickname },
{ :link, %{rel: "avatar", href: User.avatar_url(user)}}
]
}
def to_simple_form(user) do
ap_id = to_charlist(user.ap_id)
nickname = to_charlist(user.nickname)
avatar_url = to_charlist(User.avatar_url(user))
[
{ :id, [ap_id] },
{ :"activity:object", ['http://activitystrea.ms/schema/1.0/person'] },
{ :uri, [ap_id] },
{ :name, [nickname] },
{ :link, [rel: 'avatar', href: avatar_url], []}
]
end
end
......@@ -54,6 +54,16 @@ def user_fetcher(username) do
post "/qvitter/update_avatar", TwitterAPI.Controller, :update_avatar
end
pipeline :ostatus do
plug :accepts, ["xml", "atom"]
end
scope "/users", Pleroma.Web do
pipe_through :ostatus
get "/:nickname/feed", OStatus.OStatusController, :feed
end
scope "/.well-known", Pleroma.Web do
pipe_through :well_known
......
defmodule Pleroma.Web.WebFinger do
alias Pleroma.XmlBuilder
alias Pleroma.User
alias Pleroma.Web.OStatus
def host_meta() do
base_url = Pleroma.Web.base_url
......@@ -30,7 +31,7 @@ def represent_user(user) do
[
{:Subject, "acct:#{user.nickname}@#{Pleroma.Web.host}"},
{:Alias, user.ap_id},
{:Link, %{rel: "http://schemas.google.com/g/2010#updates-from", type: "application/atom+xml", href: "#{user.ap_id}.atom"}}
{:Link, %{rel: "http://schemas.google.com/g/2010#updates-from", type: "application/atom+xml", href: OStatus.feed_path(user)}}
]
}
|> XmlBuilder.to_doc
......
defmodule Pleroma.Web.OStatus.FeedRepresenterTest do
use Pleroma.DataCase
import Pleroma.Factory
alias Pleroma.User
alias Pleroma.Web.OStatus.{FeedRepresenter, UserRepresenter}
alias Pleroma.Web.OStatus
test "returns a feed of the last 20 items of the user" do
note_activity = insert(:note_activity)
user = User.get_cached_by_ap_id(note_activity.data["actor"])
tuple = FeedRepresenter.to_simple_form(user, [note_activity], [user])
most_recent_update = note_activity.updated_at
|> NaiveDateTime.to_iso8601
res = :xmerl.export_simple_content(tuple, :xmerl_xml) |> IO.iodata_to_binary
user_xml = UserRepresenter.to_simple_form(user)
|> :xmerl.export_simple_content(:xmerl_xml)
expected = """
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:activity="http://activitystrea.ms/spec/1.0/">
<id>#{OStatus.feed_path(user)}</id>
<title>#{user.nickname}'s timeline</title>
<updated>#{most_recent_update}</updated>
<entries />
<link rel="hub" href="#{OStatus.pubsub_path}" />
<author>
#{user_xml}
</author>
</feed>
"""
assert clean(res) == clean(expected)
end
defp clean(string) do
String.replace(string, ~r/\s/, "")
end
end
defmodule Pleroma.Web.OStatus.OStatusControllerTest do
use Pleroma.Web.ConnCase
import Pleroma.Factory
alias Pleroma.User
test "gets a feed", %{conn: conn} do
note_activity = insert(:note_activity)
user = User.get_cached_by_ap_id(note_activity.data["actor"])
conn = conn
|> get("/users/#{user.nickname}/feed.atom")
assert response(conn, 200)
end
end
......@@ -3,15 +3,26 @@ defmodule Pleroma.Web.OStatus.UserRepresenterTest do
alias Pleroma.Web.OStatus.UserRepresenter
import Pleroma.Factory
alias Pleroma.User
test "returns a user with id, uri, name and link" do
user = build(:user)
tuple = UserRepresenter.to_tuple(user)
{:author, author} = tuple
tuple = UserRepresenter.to_simple_form(user)
[:id, :uri, :name, :link]
|> Enum.each(fn (tag) ->
assert Enum.find(author, fn(e) -> tag == elem(e, 0) end)
end)
res = :xmerl.export_simple_content(tuple, :xmerl_xml) |> IO.iodata_to_binary
expected = """
<id>#{user.ap_id}</id>
<activity:object>http://activitystrea.ms/schema/1.0/person</activity:object>
<uri>#{user.ap_id}</uri>
<name>#{user.nickname}</name>
<link rel="avatar" href="#{User.avatar_url(user)}" />
"""
assert clean(res) == clean(expected)
end
defp clean(string) do
String.replace(string, ~r/\s/, "")
end
end
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