Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Pleroma
pleroma
Commits
61adf676
Commit
61adf676
authored
Sep 11, 2017
by
lain
Browse files
Add basic mastodon notification support.
parent
7616b202
Changes
8
Hide whitespace changes
Inline
Side-by-side
lib/pleroma/activity.ex
View file @
61adf676
defmodule
Pleroma
.
Activity
do
use
Ecto
.
Schema
alias
Pleroma
.
{
Repo
,
Activity
}
alias
Pleroma
.
{
Repo
,
Activity
,
Notification
}
import
Ecto
.
Query
schema
"activities"
do
field
:data
,
:map
field
:local
,
:boolean
,
default:
true
has_many
:notifications
,
Notification
timestamps
()
end
...
...
lib/pleroma/notification.ex
0 → 100644
View file @
61adf676
defmodule
Pleroma
.
Notification
do
use
Ecto
.
Schema
alias
Pleroma
.
{
User
,
Activity
,
Notification
,
Repo
}
import
Ecto
.
Query
schema
"notifications"
do
field
:seen
,
:boolean
,
default:
false
belongs_to
:user
,
Pleroma
.
User
belongs_to
:activity
,
Pleroma
.
Activity
timestamps
()
end
def
for_user
(
user
,
opts
\\
%{})
do
query
=
from
n
in
Notification
,
where:
n
.
user_id
==
^
user
.
id
,
order_by:
[
desc:
n
.
id
],
preload:
[
:activity
],
limit:
20
Repo
.
all
(
query
)
end
def
create_notifications
(%
Activity
{
id:
id
,
data:
%{
"to"
=>
to
,
"type"
=>
type
}}
=
activity
)
when
type
in
[
"Create"
]
do
users
=
User
.
get_notified_from_activity
(
activity
)
notifications
=
Enum
.
map
(
users
,
fn
(
user
)
->
create_notification
(
activity
,
user
)
end
)
{
:ok
,
notifications
}
end
def
create_notifications
(
_
),
do
:
{
:ok
,
[]}
# TODO move to sql, too.
def
create_notification
(%
Activity
{}
=
activity
,
%
User
{}
=
user
)
do
notification
=
%
Notification
{
user_id:
user
.
id
,
activity_id:
activity
.
id
}
{
:ok
,
notification
}
=
Repo
.
insert
(
notification
)
notification
end
end
lib/pleroma/user.ex
View file @
61adf676
...
...
@@ -2,7 +2,7 @@ defmodule Pleroma.User do
use
Ecto
.
Schema
import
Ecto
.
{
Changeset
,
Query
}
alias
Pleroma
.
{
Repo
,
User
,
Object
,
Web
}
alias
Pleroma
.
{
Repo
,
User
,
Object
,
Web
,
Activity
,
Notification
}
alias
Comeonin
.
Pbkdf2
alias
Pleroma
.
Web
.
{
OStatus
,
Websub
}
alias
Pleroma
.
Web
.
ActivityPub
.
ActivityPub
...
...
@@ -22,6 +22,7 @@ defmodule Pleroma.User do
field
:local
,
:boolean
,
default:
true
field
:info
,
:map
,
default:
%{}
field
:follower_address
,
:string
has_many
:notifications
,
Notification
timestamps
()
end
...
...
@@ -239,4 +240,12 @@ def update_follower_count(%User{} = user) do
Repo
.
update
(
cs
)
end
def
get_notified_from_activity
(%
Activity
{
data:
%{
"to"
=>
to
}}
=
activity
)
do
query
=
from
u
in
User
,
where:
u
.
ap_id
in
^
to
,
where:
u
.
local
==
true
Repo
.
all
(
query
)
end
end
lib/pleroma/web/activity_pub/activity_pub.ex
View file @
61adf676
defmodule
Pleroma
.
Web
.
ActivityPub
.
ActivityPub
do
alias
Pleroma
.
{
Activity
,
Repo
,
Object
,
Upload
,
User
,
Web
}
alias
Pleroma
.
{
Activity
,
Repo
,
Object
,
Upload
,
User
,
Web
,
Notification
}
alias
Ecto
.
{
Changeset
,
UUID
}
import
Ecto
.
Query
import
Pleroma
.
Web
.
ActivityPub
.
Utils
...
...
@@ -9,7 +9,9 @@ def insert(map, local \\ true) when is_map(map) do
with
nil
<-
Activity
.
get_by_ap_id
(
map
[
"id"
]),
map
<-
lazy_put_activity_defaults
(
map
),
:ok
<-
insert_full_object
(
map
)
do
Repo
.
insert
(%
Activity
{
data:
map
,
local:
local
})
{
:ok
,
activity
}
=
Repo
.
insert
(%
Activity
{
data:
map
,
local:
local
})
Notification
.
create_notifications
(
activity
)
{
:ok
,
activity
}
else
%
Activity
{}
=
activity
->
{
:ok
,
activity
}
error
->
{
:error
,
error
}
...
...
lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
View file @
61adf676
defmodule
Pleroma
.
Web
.
MastodonAPI
.
MastodonAPIController
do
use
Pleroma
.
Web
,
:controller
alias
Pleroma
.
{
Repo
,
Activity
,
User
}
alias
Pleroma
.
{
Repo
,
Activity
,
User
,
Notification
}
alias
Pleroma
.
Web
.
OAuth
.
App
alias
Pleroma
.
Web
alias
Pleroma
.
Web
.
MastodonAPI
.
{
StatusView
,
AccountView
}
...
...
@@ -132,6 +132,20 @@ def unfav_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
end
end
def
notifications
(%{
assigns:
%{
user:
user
}}
=
conn
,
params
)
do
notifications
=
Notification
.
for_user
(
user
,
params
)
result
=
Enum
.
map
(
notifications
,
fn
(%{
id:
id
,
activity:
activity
,
inserted_at:
created_at
})
->
actor
=
User
.
get_cached_by_ap_id
(
activity
.
data
[
"actor"
])
case
activity
.
data
[
"type"
]
do
"Create"
->
%{
id:
id
,
type:
"mention"
,
created_at:
created_at
,
account:
AccountView
.
render
(
"account.json"
,
%{
user:
actor
}),
status:
StatusView
.
render
(
"status.json"
,
%{
activity:
activity
})}
_
->
nil
end
end
)
|>
Enum
.
filter
(
&
(
&1
))
json
(
conn
,
result
)
end
def
empty_array
(
conn
,
_
)
do
Logger
.
debug
(
"Unimplemented, returning an empty array"
)
json
(
conn
,
[])
...
...
lib/pleroma/web/router.ex
View file @
61adf676
...
...
@@ -65,7 +65,7 @@ def user_fetcher(username) do
post
"/statuses/:id/favourite"
,
MastodonAPIController
,
:fav_status
post
"/statuses/:id/unfavourite"
,
MastodonAPIController
,
:unfav_status
get
"/notifications"
,
MastodonAPIController
,
:
empty_array
get
"/notifications"
,
MastodonAPIController
,
:
notifications
end
scope
"/api"
,
Pleroma
.
Web
do
...
...
priv/repo/migrations/20170911123607_create_notifications.exs
0 → 100644
View file @
61adf676
defmodule
Pleroma
.
Repo
.
Migrations
.
CreateNotifications
do
use
Ecto
.
Migration
def
change
do
create
table
(
:notifications
)
do
add
:user_id
,
references
(
:users
,
on_delete:
:delete_all
)
add
:activity_id
,
references
(
:activities
,
on_delete:
:delete_all
)
add
:seen
,
:boolean
,
default:
false
timestamps
()
end
create
index
(
:notifications
,
[
:user_id
])
end
end
test/notification_test.exs
0 → 100644
View file @
61adf676
defmodule
Pleroma
.
NotificationTest
do
use
Pleroma
.
DataCase
alias
Pleroma
.
Web
.
TwitterAPI
.
TwitterAPI
alias
Pleroma
.
{
User
,
Notification
}
import
Pleroma
.
Factory
describe
"create_notifications"
do
test
"notifies someone when they are directly addressed"
do
user
=
insert
(
:user
)
other_user
=
insert
(
:user
)
third_user
=
insert
(
:user
)
{
:ok
,
activity
}
=
TwitterAPI
.
create_status
(
user
,
%{
"status"
=>
"hey @
#{
other_user
.
nickname
}
and @
#{
third_user
.
nickname
}
"
})
{
:ok
,
[
notification
,
other_notification
]}
=
Notification
.
create_notifications
(
activity
)
assert
notification
.
user_id
==
other_user
.
id
assert
notification
.
activity_id
==
activity
.
id
assert
other_notification
.
user_id
==
third_user
.
id
assert
other_notification
.
activity_id
==
activity
.
id
end
end
end
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment