Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webhook API #516

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/syncplay-server.1
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ Enable server statistics using the SQLite database file.
.B \-\-tls [path]
Enable TLS connections using the certificate files in path.

.TP
.B \-\-webhook-port [port]
Enables the Webhook API over port port. This API enables adding entries to the playlist over HTTP.

.SH SEE ALSO
.BR syncplay (1).

15 changes: 13 additions & 2 deletions syncplay/ep_server.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import sys

from twisted.internet import reactor
from twisted.internet import reactor, endpoints
from twisted.internet.endpoints import TCP4ServerEndpoint, TCP6ServerEndpoint
from twisted.internet.error import CannotListenError

from twisted.web import server, resource

from syncplay.server import SyncFactory, ConfigurationGetter
from syncplay.webapi import WebAPI

class ServerStatus: pass

Expand All @@ -27,6 +30,7 @@ def failed4(f):
print(f.value)
print("IPv4 listening failed.")


def main():
argsGetter = ConfigurationGetter()
args = argsGetter.getConfiguration()
Expand All @@ -45,6 +49,12 @@ def main():
args.stats_db_file,
args.tls
)
if args.webhook_port:
site = server.Site(WebAPI(factory))
webapi6 = TCP6ServerEndpoint(reactor, int(args.webhook_port))
webapi6.listen(site)
#webapi4 = TCP4ServerEndpoint(reactor, int(args.webhook_port))
#webapi4.listen(site)
endpoint6 = TCP6ServerEndpoint(reactor, int(args.port))
endpoint6.listen(factory).addCallbacks(isListening6, failed6)
endpoint4 = TCP4ServerEndpoint(reactor, int(args.port))
Expand All @@ -56,4 +66,5 @@ def main():
sys.exit()

if __name__ == "__main__":
main()
main()

1 change: 1 addition & 0 deletions syncplay/messages_de.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@
"server-maxusernamelength-argument": "Maximale Zeichenzahl in einem Benutzernamen (Standard ist {})",
"server-stats-db-file-argument": "Aktiviere Server-Statistiken mithilfe der bereitgestellten SQLite-db-Datei",
"server-startTLS-argument": "Erlaube TLS-Verbindungen mit den Zertifikatdateien im Angegebenen Pfad",
"server-webhook-port-argument": 'Server Webhook TCP-port',
"server-messed-up-motd-unescaped-placeholders": "Die Nachricht des Tages hat unmaskierte Platzhalter. Alle $-Zeichen sollten verdoppelt werden ($$).",
"server-messed-up-motd-too-long": "Die Nachricht des Tages ist zu lang - Maximal {} Zeichen, aktuell {}.",

Expand Down
1 change: 1 addition & 0 deletions syncplay/messages_en.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@
"server-maxusernamelength-argument": "Maximum number of characters in a username (default is {})",
"server-stats-db-file-argument": "Enable server stats using the SQLite db file provided",
"server-startTLS-argument": "Enable TLS connections using the certificate files in the path provided",
"server-webhook-port-argument": 'server Webhook TCP port',
"server-messed-up-motd-unescaped-placeholders": "Message of the Day has unescaped placeholders. All $ signs should be doubled ($$).",
"server-messed-up-motd-too-long": "Message of the Day is too long - maximum of {} chars, {} given.",

Expand Down
1 change: 1 addition & 0 deletions syncplay/messages_es.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@
"server-maxusernamelength-argument": "Número máximo de caracteres para el nombre de usuario (el valor predeterminado es {})",
"server-stats-db-file-argument": "Habilitar estadísticas del servidor utilizando el archivo db SQLite proporcionado",
"server-startTLS-argument": "Habilitar conexiones TLS usando los archivos de certificado en la ruta provista",
"server-webhook-port-argument": 'server Webhook TCP port', #TODO translate
"server-messed-up-motd-unescaped-placeholders": "El mensaje del dia contiene marcadores de posición sin escapar. Todos los signos $ deberían ser dobles ($$).",
"server-messed-up-motd-too-long": "El mensaje del día es muy largo - máximo de {} caracteres, se recibieron {}.",

Expand Down
1 change: 1 addition & 0 deletions syncplay/messages_fr.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@
"server-maxusernamelength-argument": "Nombre maximum de caractères dans un nom d'utilisateur (la valeur par défaut est {})",
"server-stats-db-file-argument": "Activer les statistiques du serveur à l'aide du fichier db SQLite fourni",
"server-startTLS-argument": "Activer les connexions TLS à l'aide des fichiers de certificat dans le chemin fourni",
"server-webhook-port-argument": 'server Webhook TCP port', # TODO translate
"server-messed-up-motd-unescaped-placeholders": "Le message du jour a des espaces réservés non échappés. Tous les signes $ doivent être doublés ($$).",
"server-messed-up-motd-too-long": "Le message du jour est trop long: {}caractères maximum, {} donnés.",

Expand Down
1 change: 1 addition & 0 deletions syncplay/messages_it.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@
"server-maxusernamelength-argument": "Numero massimo di caratteri in un nome utente (default è {})",
"server-stats-db-file-argument": "Abilita la raccolta dei dati statistici nel file SQLite indicato",
"server-startTLS-argument": "Abilita il protocollo TLS usando i certificati contenuti nel percorso indicato",
"server-webhook-port-argument": 'server Webhook TCP port', # TODO translate
"server-messed-up-motd-unescaped-placeholders": "Il messaggio del giorno ha dei caratteri non 'escaped'. Tutti i simboli $ devono essere doppi ($$).",
"server-messed-up-motd-too-long": "Il messaggio del giorno è troppo lungo - numero massimo di caratteri è {}, {} trovati.",

Expand Down
1 change: 1 addition & 0 deletions syncplay/messages_pt_BR.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@
"server-maxusernamelength-argument": "Número máximos de caracteres num nome de usuário (o padrão é {})",
"server-stats-db-file-argument": "Habilita estatísticas de servidor usando o arquivo db SQLite fornecido",
"server-startTLS-argument": "Habilita conexões TLS usando os arquivos de certificado no caminho fornecido",
"server-webhook-port-argument": 'server Webhook TCP port', # TODO translate
"server-messed-up-motd-unescaped-placeholders": "A Mensagem do Dia possui placeholders não escapados. Todos os sinais de $ devem ser dobrados (como em $$).",
"server-messed-up-motd-too-long": "A Mensagem do Dia é muito longa - máximo de {} caracteres, {} foram dados.",

Expand Down
1 change: 1 addition & 0 deletions syncplay/messages_pt_PT.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@
"server-maxusernamelength-argument": "Número máximos de caracteres num nome de utilizador (o padrão é {})",
"server-stats-db-file-argument": "Habilita estatísticas de servidor usando o arquivo db SQLite fornecido",
"server-startTLS-argument": "Habilita conexões TLS usando os arquivos de certificado no caminho fornecido",
"server-webhook-port-argument": 'server Webhook TCP port', # TODO translate
"server-messed-up-motd-unescaped-placeholders": "A Mensagem do Dia possui placeholders não escapados. Todos os sinais de $ devem ser dobrados (como em $$).",
"server-messed-up-motd-too-long": "A Mensagem do Dia é muito longa - máximo de {} caracteres, {} foram dados.",

Expand Down
1 change: 1 addition & 0 deletions syncplay/messages_ru.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,7 @@
"server-maxusernamelength-argument": "Максимальное число символов в именах пользователей (по умолчанию {})",
"server-stats-db-file-argument": "Включить статистику сервера в указанном файле SQLite",
"server-startTLS-argument": "Включить TLS-соединения используя файлы сертификатов в указанном пути",
"server-webhook-port-argument": 'server Webhook TCP port', # TODO translate
"server-messed-up-motd-unescaped-placeholders": "MOTD-сообщение содержит неэкранированные спецсимволы. Все знаки $ должны быть продублированы ($$).",
"server-messed-up-motd-too-long": "MOTD-сообщение слишком длинное: максимальная длина - {} символ(ов), текущая длина - {} символ(ов).",

Expand Down
1 change: 1 addition & 0 deletions syncplay/messages_tr.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@
"server-maxusernamelength-argument": "Bir kullanıcı adındaki maksimum karakter sayısı (varsayılan {})",
"server-stats-db-file-argument": "SQLite db dosyasını kullanarak sunucu istatistiklerini etkinleştirin",
"server-startTLS-argument": "Dosya yolundaki sertifika dosyalarını kullanarak TLS bağlantılarını etkinleştirin",
"server-webhook-port-argument": 'server Webhook TCP port', # TODO translate
"server-messed-up-motd-unescaped-placeholders": "Günün Mesajında çıkış karaktersiz yer tutucular var. Tüm $ işaretleri iki katına çıkarılmalıdır ($$).",
"server-messed-up-motd-too-long": "Günün Mesajı çok uzun - maksimum {} karakter olmalı, {} verildi.",

Expand Down
1 change: 1 addition & 0 deletions syncplay/messages_zh_CN.py
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@
"server-maxusernamelength-argument": "用户名中的最大字符数(默认为{})。",
"server-stats-db-file-argument": "使用提供的SQLite db文件启用服务器统计功能",
"server-startTLS-argument": "使用提供的路径中的证书文件启用TLS连接",
"server-webhook-port-argument": 'server Webhook TCP port', # TODO translate
"server-messed-up-motd-unescaped-placeholders": "每日信息中有未转义的占位符。所有 $ 字符应当重复两遍 ($$).",
"server-messed-up-motd-too-long": "每日信息过长 - 最大{}个chars, 给出的长度{}",

Expand Down
4 changes: 4 additions & 0 deletions syncplay/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,9 @@ def updateTLSContextFactory(self):
if self._TLSattempts < constants.TLS_CERT_ROTATION_MAX_RETRIES:
self.serverAcceptsTLS = True

def _getRoomManager(self):
return self._roomManager


class StatsRecorder(object):
def __init__(self, dbHandle, roomManager):
Expand Down Expand Up @@ -889,3 +892,4 @@ def _prepareArgParser(self):
self._argparser.add_argument('--max-username-length', metavar='maxUsernameLength', type=int, nargs='?', help=getMessage("server-maxusernamelength-argument").format(constants.MAX_USERNAME_LENGTH))
self._argparser.add_argument('--stats-db-file', metavar='file', type=str, nargs='?', help=getMessage("server-stats-db-file-argument"))
self._argparser.add_argument('--tls', metavar='path', type=str, nargs='?', help=getMessage("server-startTLS-argument"))
self._argparser.add_argument('--webhook-port', metavar='webhook_port', type=str, nargs='?', help=getMessage("server-webhook-port-argument"))
41 changes: 41 additions & 0 deletions syncplay/webapi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from syncplay.utils import RoomPasswordProvider, NotControlledRoom, RandomStringGenerator, meetsMinVersion, playlistIsValid, truncateText
from twisted.web import server, resource
import syncplay
from syncplay import constants
import json

class WebAPI(resource.Resource):
isLeaf = True
def __init__(self, factory):
self._factory = factory

def render_GET(self, request):
# return a simple form for browsers
return (b"<!DOCTYPE html><html><head><meta charset='utf-8'>"
b"<title></title></head><body>"
b"<form method='POST'><label for='room'>Room:</label><input name='room'><br/>"
b"<label for='url'>URL:</label><input name='url'><br/>"
b"<input type='submit'/></form></body></html>")

def render_POST(self, request):
url = ""
r = ""
if b"url" in request.args and b"room" in request.args:
url = request.args[b"url"][0].decode("utf-8")
r = request.args[b"room"][0].decode("utf-8")
else:
obj = json.load(request.content)
#print(obj)
url = obj["text"]
r = obj["channel_name"]

room = self._factory._getRoomManager()._getRoom(r)
pl = room.getPlaylist()
pl += [url]
room.setPlaylist(pl)
#print("Room: " + r + " - adding: " + url)
for receiver in room.getWatchers():
receiver.setPlaylist(room.getName(), room.getPlaylist())

return b"<html>Inserted</html>"