diff options
| -rw-r--r-- | lib/pleroma/web/ostatus/feed_representer.ex | 26 | ||||
| -rw-r--r-- | lib/pleroma/web/ostatus/ostatus.ex | 14 | ||||
| -rw-r--r-- | lib/pleroma/web/ostatus/ostatus_controller.ex | 26 | ||||
| -rw-r--r-- | lib/pleroma/web/ostatus/user_representer.ex | 21 | ||||
| -rw-r--r-- | lib/pleroma/web/router.ex | 10 | ||||
| -rw-r--r-- | lib/pleroma/web/web_finger/web_finger.ex | 3 | ||||
| -rw-r--r-- | test/web/ostatus/feed_representer_test.exs | 39 | ||||
| -rw-r--r-- | test/web/ostatus/ostatus_controller_test.exs | 15 | ||||
| -rw-r--r-- | test/web/ostatus/user_representer_test.exs | 23 | 
9 files changed, 160 insertions, 17 deletions
| diff --git a/lib/pleroma/web/ostatus/feed_representer.ex b/lib/pleroma/web/ostatus/feed_representer.ex new file mode 100644 index 000000000..cb76022fe --- /dev/null +++ b/lib/pleroma/web/ostatus/feed_representer.ex @@ -0,0 +1,26 @@ +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 diff --git a/lib/pleroma/web/ostatus/ostatus.ex b/lib/pleroma/web/ostatus/ostatus.ex new file mode 100644 index 000000000..9fcbe6cb0 --- /dev/null +++ b/lib/pleroma/web/ostatus/ostatus.ex @@ -0,0 +1,14 @@ +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 diff --git a/lib/pleroma/web/ostatus/ostatus_controller.ex b/lib/pleroma/web/ostatus/ostatus_controller.ex new file mode 100644 index 000000000..ff6d7301a --- /dev/null +++ b/lib/pleroma/web/ostatus/ostatus_controller.ex @@ -0,0 +1,26 @@ +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 diff --git a/lib/pleroma/web/ostatus/user_representer.ex b/lib/pleroma/web/ostatus/user_representer.ex index 66fc6e053..e7ee4cfeb 100644 --- a/lib/pleroma/web/ostatus/user_representer.ex +++ b/lib/pleroma/web/ostatus/user_representer.ex @@ -1,14 +1,15 @@  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 diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 99d1f69c2..cc1f0e165 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -54,6 +54,16 @@ defmodule Pleroma.Web.Router 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 diff --git a/lib/pleroma/web/web_finger/web_finger.ex b/lib/pleroma/web/web_finger/web_finger.ex index 258ff7671..eb540e92a 100644 --- a/lib/pleroma/web/web_finger/web_finger.ex +++ b/lib/pleroma/web/web_finger/web_finger.ex @@ -1,6 +1,7 @@  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 @@ defmodule Pleroma.Web.WebFinger 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 diff --git a/test/web/ostatus/feed_representer_test.exs b/test/web/ostatus/feed_representer_test.exs new file mode 100644 index 000000000..e252eca9f --- /dev/null +++ b/test/web/ostatus/feed_representer_test.exs @@ -0,0 +1,39 @@ +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 diff --git a/test/web/ostatus/ostatus_controller_test.exs b/test/web/ostatus/ostatus_controller_test.exs new file mode 100644 index 000000000..229cd9b1e --- /dev/null +++ b/test/web/ostatus/ostatus_controller_test.exs @@ -0,0 +1,15 @@ +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 diff --git a/test/web/ostatus/user_representer_test.exs b/test/web/ostatus/user_representer_test.exs index 02a4b5b14..a401a56da 100644 --- a/test/web/ostatus/user_representer_test.exs +++ b/test/web/ostatus/user_representer_test.exs @@ -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 | 
