mirror of https://gitlab.com/litecord/litecord.git
Merge branch 'impl/bulk-ack' into 'master'
Implement Bulk ACK endpoint Closes #52 See merge request litecord/litecord!73
This commit is contained in:
commit
16665e5692
|
|
@ -33,6 +33,7 @@ from .nodeinfo import bp as nodeinfo
|
|||
from .static import bp as static
|
||||
from .attachments import bp as attachments
|
||||
from .dm_channels import bp as dm_channels
|
||||
from .read_states import bp as read_states
|
||||
|
||||
__all__ = [
|
||||
"gateway",
|
||||
|
|
@ -51,4 +52,5 @@ __all__ = [
|
|||
"static",
|
||||
"attachments",
|
||||
"dm_channels",
|
||||
"read_states",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -42,10 +42,8 @@ from litecord.system_messages import send_sys_message
|
|||
from litecord.blueprints.dm_channels import gdm_remove_recipient, gdm_destroy
|
||||
from litecord.utils import search_result_from_list
|
||||
from litecord.embed.messages import process_url_embed, msg_update_embeds
|
||||
from litecord.common.channels import channel_ack
|
||||
from litecord.pubsub.user import dispatch_user
|
||||
from litecord.permissions import get_permissions, Permissions
|
||||
from litecord.errors import GuildNotFound
|
||||
|
||||
log = Logger(__name__)
|
||||
bp = Blueprint("channels", __name__)
|
||||
|
|
@ -653,50 +651,6 @@ async def trigger_typing(channel_id):
|
|||
return "", 204
|
||||
|
||||
|
||||
@bp.route("/<int:channel_id>/messages/<int:message_id>/ack", methods=["POST"])
|
||||
async def ack_channel(channel_id, message_id):
|
||||
"""Acknowledge a channel."""
|
||||
user_id = await token_check()
|
||||
ctype, guild_id = await channel_check(user_id, channel_id)
|
||||
|
||||
if ctype == ChannelType.DM:
|
||||
guild_id = None
|
||||
|
||||
await channel_ack(user_id, guild_id, channel_id, message_id)
|
||||
|
||||
return jsonify(
|
||||
{
|
||||
# token seems to be used for
|
||||
# data collection activities,
|
||||
# so we never use it.
|
||||
"token": None
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/<int:channel_id>/messages/ack", methods=["DELETE"])
|
||||
async def delete_read_state(channel_id):
|
||||
"""Delete the read state of a channel."""
|
||||
user_id = await token_check()
|
||||
try:
|
||||
await channel_check(user_id, channel_id)
|
||||
except GuildNotFound:
|
||||
# ignore when guild isn't found because we're deleting the
|
||||
# read state regardless.
|
||||
pass
|
||||
|
||||
await app.db.execute(
|
||||
"""
|
||||
DELETE FROM user_read_state
|
||||
WHERE user_id = $1 AND channel_id = $2
|
||||
""",
|
||||
user_id,
|
||||
channel_id,
|
||||
)
|
||||
|
||||
return "", 204
|
||||
|
||||
|
||||
@bp.route("/<int:channel_id>/messages/search", methods=["GET"])
|
||||
async def _search_channel(channel_id):
|
||||
"""Search in DMs or group DMs"""
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ from ..schemas import (
|
|||
VANITY_URL_PATCH,
|
||||
)
|
||||
from .checks import guild_check, guild_owner_check, guild_perm_check
|
||||
from ..common.channels import channel_ack
|
||||
from litecord.utils import to_update, search_result_from_list
|
||||
from litecord.errors import BadRequest
|
||||
from litecord.permissions import get_permissions
|
||||
|
|
@ -438,20 +437,6 @@ async def search_messages(guild_id):
|
|||
return jsonify(await search_result_from_list(rows))
|
||||
|
||||
|
||||
@bp.route("/<int:guild_id>/ack", methods=["POST"])
|
||||
async def ack_guild(guild_id):
|
||||
"""ACKnowledge all messages in the guild."""
|
||||
user_id = await token_check()
|
||||
await guild_check(user_id, guild_id)
|
||||
|
||||
chan_ids = await app.storage.get_channel_ids(guild_id)
|
||||
|
||||
for chan_id in chan_ids:
|
||||
await channel_ack(user_id, guild_id, chan_id)
|
||||
|
||||
return "", 204
|
||||
|
||||
|
||||
@bp.route("/<int:guild_id>/vanity-url", methods=["GET"])
|
||||
async def get_vanity_url(guild_id: int):
|
||||
"""Get the vanity url of a guild."""
|
||||
|
|
|
|||
|
|
@ -0,0 +1,105 @@
|
|||
"""
|
||||
|
||||
Litecord
|
||||
Copyright (C) 2018-2019 Luna Mendes
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, version 3 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
from quart import Blueprint, current_app as app, jsonify, request
|
||||
from litecord.auth import token_check
|
||||
from litecord.common.channels import channel_ack
|
||||
from litecord.errors import GuildNotFound
|
||||
from litecord.blueprints.checks import channel_check, guild_check
|
||||
from litecord.schemas import validate, BULK_ACK
|
||||
from litecord.enums import GUILD_CHANS
|
||||
|
||||
|
||||
bp = Blueprint("read_states", __name__)
|
||||
|
||||
|
||||
@bp.route("/channels/<int:channel_id>/messages/<int:message_id>/ack", methods=["POST"])
|
||||
async def ack_channel(channel_id, message_id):
|
||||
"""Acknowledge a channel."""
|
||||
user_id = await token_check()
|
||||
ctype, guild_id = await channel_check(user_id, channel_id)
|
||||
|
||||
if ctype not in GUILD_CHANS:
|
||||
guild_id = None
|
||||
|
||||
await channel_ack(user_id, channel_id, guild_id, message_id)
|
||||
|
||||
return jsonify(
|
||||
{
|
||||
# token seems to be used for
|
||||
# data collection activities,
|
||||
# so we never use it.
|
||||
"token": None
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/read-states/ack-bulk", methods=["POST"])
|
||||
async def bulk_ack():
|
||||
"""Acknowledge multiple channels in a row"""
|
||||
user_id = await token_check()
|
||||
j = validate(await request.get_json(), BULK_ACK)
|
||||
for ack_request in j:
|
||||
channel_id, message_id = ack_request["channel_id"], ack_request["message_id"]
|
||||
ctype, guild_id = await channel_check(user_id, channel_id)
|
||||
if ctype not in GUILD_CHANS:
|
||||
guild_id = None
|
||||
|
||||
await channel_ack(user_id, channel_id, guild_id, message_id)
|
||||
|
||||
# TODO: validate if this is the correct response
|
||||
return "", 204
|
||||
|
||||
|
||||
@bp.route("/channels/<int:channel_id>/messages/ack", methods=["DELETE"])
|
||||
async def delete_read_state(channel_id):
|
||||
"""Delete the read state of a channel."""
|
||||
user_id = await token_check()
|
||||
try:
|
||||
await channel_check(user_id, channel_id)
|
||||
except GuildNotFound:
|
||||
# ignore when guild isn't found because we're deleting the
|
||||
# read state regardless.
|
||||
pass
|
||||
|
||||
await app.db.execute(
|
||||
"""
|
||||
DELETE FROM user_read_state
|
||||
WHERE user_id = $1 AND channel_id = $2
|
||||
""",
|
||||
user_id,
|
||||
channel_id,
|
||||
)
|
||||
|
||||
return "", 204
|
||||
|
||||
|
||||
@bp.route("/guilds/<int:guild_id>/ack", methods=["POST"])
|
||||
async def ack_guild(guild_id):
|
||||
"""ACKnowledge all messages in the guild."""
|
||||
user_id = await token_check()
|
||||
await guild_check(user_id, guild_id)
|
||||
|
||||
chan_ids = await app.storage.get_channel_ids(guild_id)
|
||||
|
||||
for chan_id in chan_ids:
|
||||
await channel_ack(user_id, chan_id, guild_id)
|
||||
|
||||
return "", 204
|
||||
|
|
@ -27,7 +27,10 @@ from litecord.pubsub.user import dispatch_user
|
|||
|
||||
|
||||
async def channel_ack(
|
||||
user_id: int, guild_id: int, channel_id: int, message_id: Optional[int] = None
|
||||
user_id: int,
|
||||
channel_id: int,
|
||||
guild_id: Optional[int] = None,
|
||||
message_id: Optional[int] = None,
|
||||
):
|
||||
"""ACK a channel."""
|
||||
|
||||
|
|
|
|||
|
|
@ -619,3 +619,16 @@ BULK_DELETE = {
|
|||
"schema": {"coerce": int},
|
||||
}
|
||||
}
|
||||
|
||||
BULK_ACK = {
|
||||
"read_states": {
|
||||
"type": "list",
|
||||
"required": True,
|
||||
"minlength": 0,
|
||||
"maxlength": 100,
|
||||
"schema": {
|
||||
"channel_id": {"coerce": int},
|
||||
"message_id": {"coerce": int},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2
run.py
2
run.py
|
|
@ -50,6 +50,7 @@ from litecord.blueprints import (
|
|||
static,
|
||||
attachments,
|
||||
dm_channels,
|
||||
read_states,
|
||||
)
|
||||
|
||||
# those blueprints are separated from the "main" ones
|
||||
|
|
@ -167,6 +168,7 @@ def set_blueprints(app_):
|
|||
guilds_admin: "/admin/guilds",
|
||||
users_admin: "/admin/users",
|
||||
instance_invites: "/admin/instance/invites",
|
||||
read_states: "",
|
||||
}
|
||||
|
||||
for bp, suffix in bps.items():
|
||||
|
|
|
|||
Loading…
Reference in New Issue