Merge branch 'feld/pleroma-feld-mastodon-usersearch' into develop

This commit is contained in:
Roger Braun 2017-10-30 19:25:32 +01:00
commit f23edd2d6b
19 changed files with 104 additions and 31 deletions

View file

@ -24,7 +24,7 @@ defmodule Pleroma.Object do
def get_by_ap_id(nil), do: nil
def get_by_ap_id(ap_id) do
Repo.one(from object in Object,
where: fragment("? @> ?", object.data, ^%{id: ap_id}))
where: fragment("(?)->>'id' = ?", object.data, ^ap_id))
end
def get_cached_by_ap_id(ap_id) do

View file

@ -241,7 +241,7 @@ defmodule Pleroma.User do
def update_note_count(%User{} = user) do
note_count_query = from a in Object,
where: fragment("? @> ?", a.data, ^%{actor: user.ap_id, type: "Note"}),
where: fragment("?->>'actor' = ? and ?->>'type' = 'Note'", a.data, ^user.ap_id, a.data),
select: count(a.id)
note_count = Repo.one(note_count_query)
@ -274,4 +274,14 @@ defmodule Pleroma.User do
Repo.all(query)
end
def search(query, resolve) do
if resolve do
User.get_or_fetch_by_nickname(query)
end
q = from u in User,
where: fragment("(to_tsvector('english', ?) || to_tsvector('english', ?)) @@ plainto_tsquery('english', ?)", u.nickname, u.name, ^query),
limit: 20
Repo.all(q)
end
end

View file

@ -90,7 +90,11 @@ defmodule Pleroma.Web.ActivityPub.Utils do
"""
def get_existing_like(actor, %{data: %{"id" => id}} = object) do
query = from activity in Activity,
where: fragment("? @> ?", activity.data, ^%{actor: actor, object: id, type: "Like"})
where: fragment("(?)->>'actor' = ?", activity.data, ^actor),
# this is to use the index
where: fragment("coalesce((?)->'object'->>'id', (?)->>'object') = ?", activity.data, activity.data, ^id),
where: fragment("(?)->>'type' = 'Like'", activity.data)
Repo.one(query)
end

View file

@ -271,9 +271,27 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
def follow(%{assigns: %{user: follower}} = conn, %{"id" => id}) do
with %User{} = followed <- Repo.get(User, id),
{:ok, follower} <- User.follow(follower, followed),
{:ok, activity} <- ActivityPub.follow(follower, followed) do
{:ok, follower} <- User.follow(follower, followed),
{:ok, activity} <- ActivityPub.follow(follower, followed) do
render conn, AccountView, "relationship.json", %{user: follower, target: followed}
else
{:error, message} = err ->
conn
|> put_resp_content_type("application/json")
|> send_resp(403, Poison.encode!(%{"error" => message}))
end
end
def follow(%{assigns: %{user: follower}} = conn, %{"uri" => uri}) do
with %User{} = followed <- Repo.get_by(User, nickname: uri),
{:ok, follower} <- User.follow(follower, followed),
{:ok, activity} <- ActivityPub.follow(follower, followed) do
render conn, AccountView, "account.json", %{user: followed}
else
{:error, message} = err ->
conn
|> put_resp_content_type("application/json")
|> send_resp(403, Poison.encode!(%{"error" => message}))
end
end
@ -291,14 +309,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
end
def search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
if params["resolve"] == "true" do
User.get_or_fetch_by_nickname(query)
end
q = from u in User,
where: fragment("(to_tsvector('english', ?) || to_tsvector('english', ?)) @@ plainto_tsquery('english', ?)", u.nickname, u.name, ^query),
limit: 20
accounts = Repo.all(q)
accounts = User.search(query, params["resolve"] == "true")
q = from a in Activity,
where: fragment("?->>'type' = 'Create'", a.data),
@ -315,6 +326,14 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
json(conn, res)
end
def account_search(%{assigns: %{user: user}} = conn, %{"q" => query} = params) do
accounts = User.search(query, params["resolve"] == "true")
res = AccountView.render("accounts.json", users: accounts, for: user, as: :user)
json(conn, res)
end
def favourites(%{assigns: %{user: user}} = conn, params) do
params = conn
|> Map.put("type", "Create")

View file

@ -55,6 +55,7 @@ defmodule Pleroma.Web.Router do
get "/accounts/verify_credentials", MastodonAPIController, :verify_credentials
get "/accounts/relationships", MastodonAPIController, :relationships
get "/accounts/search", MastodonAPIController, :account_search
post "/accounts/:id/follow", MastodonAPIController, :follow
post "/accounts/:id/unfollow", MastodonAPIController, :unfollow
post "/accounts/:id/block", MastodonAPIController, :relationship_noop
@ -62,6 +63,8 @@ defmodule Pleroma.Web.Router do
post "/accounts/:id/mute", MastodonAPIController, :relationship_noop
post "/accounts/:id/unmute", MastodonAPIController, :relationship_noop
post "/follows", MastodonAPIController, :follow
get "/blocks", MastodonAPIController, :empty_array
get "/domain_blocks", MastodonAPIController, :empty_array
get "/follow_requests", MastodonAPIController, :empty_array

View file

@ -0,0 +1,7 @@
defmodule Pleroma.Repo.Migrations.DropObjectIndex do
use Ecto.Migration
def change do
drop_if_exists index(:objects, [:data], using: :gin)
end
end

View file

@ -0,0 +1,9 @@
defmodule Pleroma.Repo.Migrations.AddObjectActorIndex do
use Ecto.Migration
@disable_ddl_transaction true
def change do
create index(:objects, ["(data->>'actor')", "(data->>'type')"], concurrently: true, name: :objects_actor_type)
end
end

View file

@ -1 +1 @@
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Pleroma</title><link rel=stylesheet href=/static/font/css/fontello.css><link rel=stylesheet href=/static/font/css/animation.css><link href=/static/css/app.9cfa0ec1ee2d157fc360f5a3f1ee687c.css rel=stylesheet></head><body style="display: none"><div id=app></div><script type=text/javascript src=/static/js/manifest.13905a962b52e27fb039.js></script><script type=text/javascript src=/static/js/vendor.5ae36edd0f238a1334af.js></script><script type=text/javascript src=/static/js/app.437f43ecaf6ade101b9a.js></script></body></html>
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Pleroma</title><link rel=stylesheet href=/static/font/css/fontello.css><link rel=stylesheet href=/static/font/css/animation.css><link href=/static/css/app.9cfa0ec1ee2d157fc360f5a3f1ee687c.css rel=stylesheet></head><body style="display: none"><div id=app></div><script type=text/javascript src=/static/js/manifest.5e2e6cbffed3dea6be7c.js></script><script type=text/javascript src=/static/js/vendor.a940853cbf3c748efda4.js></script><script type=text/javascript src=/static/js/app.37dc091547e5c8fb0a0e.js></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,2 +0,0 @@
!function(e){function t(a){if(n[a])return n[a].exports;var r=n[a]={exports:{},id:a,loaded:!1};return e[a].call(r.exports,r,r.exports,t),r.loaded=!0,r.exports}var a=window.webpackJsonp;window.webpackJsonp=function(o,c){for(var p,s,l=0,i=[];l<o.length;l++)s=o[l],r[s]&&i.push.apply(i,r[s]),r[s]=0;for(p in c)e[p]=c[p];for(a&&a(o,c);i.length;)i.shift().call(null,t);if(c[0])return n[0]=0,t(0)};var n={},r={0:0};t.e=function(e,a){if(0===r[e])return a.call(null,t);if(void 0!==r[e])r[e].push(a);else{r[e]=[a];var n=document.getElementsByTagName("head")[0],o=document.createElement("script");o.type="text/javascript",o.charset="utf-8",o.async=!0,o.src=t.p+"static/js/"+e+"."+{1:"5ae36edd0f238a1334af",2:"437f43ecaf6ade101b9a"}[e]+".js",n.appendChild(o)}},t.m=e,t.c=n,t.p="/"}([]);
//# sourceMappingURL=manifest.13905a962b52e27fb039.js.map

View file

@ -0,0 +1,2 @@
!function(e){function t(n){if(a[n])return a[n].exports;var r=a[n]={exports:{},id:n,loaded:!1};return e[n].call(r.exports,r,r.exports,t),r.loaded=!0,r.exports}var n=window.webpackJsonp;window.webpackJsonp=function(c,o){for(var p,s,l=0,i=[];l<c.length;l++)s=c[l],r[s]&&i.push.apply(i,r[s]),r[s]=0;for(p in o)e[p]=o[p];for(n&&n(c,o);i.length;)i.shift().call(null,t);if(o[0])return a[0]=0,t(0)};var a={},r={0:0};t.e=function(e,n){if(0===r[e])return n.call(null,t);if(void 0!==r[e])r[e].push(n);else{r[e]=[n];var a=document.getElementsByTagName("head")[0],c=document.createElement("script");c.type="text/javascript",c.charset="utf-8",c.async=!0,c.src=t.p+"static/js/"+e+"."+{1:"a940853cbf3c748efda4",2:"37dc091547e5c8fb0a0e"}[e]+".js",a.appendChild(c)}},t.m=e,t.c=a,t.p="/"}([]);
//# sourceMappingURL=manifest.5e2e6cbffed3dea6be7c.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -281,6 +281,14 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
|> post("/api/v1/accounts/#{other_user.id}/unfollow")
assert %{"id" => id, "following" => false} = json_response(conn, 200)
user = Repo.get(User, user.id)
conn = build_conn()
|> assign(:user, user)
|> post("/api/v1/follows", %{"uri" => other_user.nickname})
assert %{"id" => id} = json_response(conn, 200)
assert id == other_user.id
end
test "unimplemented block/mute endpoints" do
@ -311,6 +319,19 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
end)
end
test "account seach", %{conn: conn} do
user = insert(:user)
user_two = insert(:user, %{nickname: "shp@shitposter.club"})
user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"})
conn = conn
|> assign(:user, user)
|> get("/api/v1/accounts/search", %{"q" => "2hu"})
assert [account] = json_response(conn, 200)
assert account["id"] == user_three.id
end
test "search", %{conn: conn} do
user = insert(:user)
user_two = insert(:user, %{nickname: "shp@shitposter.club"})