mirror of
https://github.com/Kunsi/pretalx-plugin-broadcast-tools
synced 2024-09-29 00:17:13 +00:00
Compare commits
No commits in common. "main" and "v2.0.0" have entirely different histories.
18 changed files with 326 additions and 395 deletions
112
.github/workflows/style.yml
vendored
112
.github/workflows/style.yml
vendored
|
@ -18,14 +18,14 @@ jobs:
|
||||||
name: isort
|
name: isort
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v2
|
||||||
- name: install gettext
|
- name: install gettext
|
||||||
run: sudo apt install gettext
|
run: sudo apt install gettext
|
||||||
- name: Set up Python 3.12
|
- name: Set up Python 3.8
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v1
|
||||||
with:
|
with:
|
||||||
python-version: 3.12
|
python-version: 3.8
|
||||||
- uses: actions/cache@v4
|
- uses: actions/cache@v1
|
||||||
with:
|
with:
|
||||||
path: ~/.cache/pip
|
path: ~/.cache/pip
|
||||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }}
|
key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }}
|
||||||
|
@ -41,14 +41,14 @@ jobs:
|
||||||
name: flake8
|
name: flake8
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v2
|
||||||
- name: install gettext
|
- name: install gettext
|
||||||
run: sudo apt install gettext
|
run: sudo apt install gettext
|
||||||
- name: Set up Python 3.12
|
- name: Set up Python 3.8
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v1
|
||||||
with:
|
with:
|
||||||
python-version: 3.12
|
python-version: 3.8
|
||||||
- uses: actions/cache@v4
|
- uses: actions/cache@v1
|
||||||
with:
|
with:
|
||||||
path: ~/.cache/pip
|
path: ~/.cache/pip
|
||||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }}
|
key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }}
|
||||||
|
@ -65,14 +65,14 @@ jobs:
|
||||||
name: black
|
name: black
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v2
|
||||||
- name: install gettext
|
- name: install gettext
|
||||||
run: sudo apt install gettext
|
run: sudo apt install gettext
|
||||||
- name: Set up Python 3.12
|
- name: Set up Python 3.8
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v1
|
||||||
with:
|
with:
|
||||||
python-version: 3.12
|
python-version: 3.8
|
||||||
- uses: actions/cache@v4
|
- uses: actions/cache@v1
|
||||||
with:
|
with:
|
||||||
path: ~/.cache/pip
|
path: ~/.cache/pip
|
||||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }}
|
key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }}
|
||||||
|
@ -89,14 +89,14 @@ jobs:
|
||||||
name: docformatter
|
name: docformatter
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v2
|
||||||
- name: install gettext
|
- name: install gettext
|
||||||
run: sudo apt install gettext
|
run: sudo apt install gettext
|
||||||
- name: Set up Python 3.12
|
- name: Set up Python 3.8
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v1
|
||||||
with:
|
with:
|
||||||
python-version: 3.12
|
python-version: 3.8
|
||||||
- uses: actions/cache@v4
|
- uses: actions/cache@v1
|
||||||
with:
|
with:
|
||||||
path: ~/.cache/pip
|
path: ~/.cache/pip
|
||||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }}
|
key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }}
|
||||||
|
@ -113,14 +113,14 @@ jobs:
|
||||||
name: djhtml
|
name: djhtml
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v2
|
||||||
- name: install gettext
|
- name: install gettext
|
||||||
run: sudo apt install gettext
|
run: sudo apt install gettext
|
||||||
- name: Set up Python 3.12
|
- name: Set up Python 3.8
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v1
|
||||||
with:
|
with:
|
||||||
python-version: 3.12
|
python-version: 3.8
|
||||||
- uses: actions/cache@v4
|
- uses: actions/cache@v1
|
||||||
with:
|
with:
|
||||||
path: ~/.cache/pip
|
path: ~/.cache/pip
|
||||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }}
|
key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }}
|
||||||
|
@ -133,34 +133,34 @@ jobs:
|
||||||
- name: Run docformatter
|
- name: Run docformatter
|
||||||
run: find -name "*.html" | xargs djhtml -c
|
run: find -name "*.html" | xargs djhtml -c
|
||||||
working-directory: .
|
working-directory: .
|
||||||
# packaging:
|
packaging:
|
||||||
# name: packaging
|
name: packaging
|
||||||
# runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
# steps:
|
steps:
|
||||||
# - uses: actions/checkout@v4
|
- uses: actions/checkout@v2
|
||||||
# - name: install gettext
|
- name: install gettext
|
||||||
# run: sudo apt install gettext
|
run: sudo apt install gettext
|
||||||
# - name: Set up Python 3.12
|
- name: Set up Python 3.8
|
||||||
# uses: actions/setup-python@v5
|
uses: actions/setup-python@v1
|
||||||
# with:
|
with:
|
||||||
# python-version: 3.12
|
python-version: 3.8
|
||||||
# - uses: actions/cache@v4
|
- uses: actions/cache@v1
|
||||||
# with:
|
with:
|
||||||
# path: ~/.cache/pip
|
path: ~/.cache/pip
|
||||||
# key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }}
|
key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }}
|
||||||
# restore-keys: |
|
restore-keys: |
|
||||||
# ${{ runner.os }}-pip-
|
${{ runner.os }}-pip-
|
||||||
# - name: Install pretalx
|
- name: Install pretalx
|
||||||
# run: pip3 install pretalx
|
run: pip3 install pretalx
|
||||||
# - name: Install Dependencies
|
- name: Install Dependencies
|
||||||
# run: pip3 install twine check-manifest -Ue .
|
run: pip3 install twine check-manifest -Ue .
|
||||||
# - name: Run check-manifest
|
- name: Run check-manifest
|
||||||
# run: check-manifest .
|
run: check-manifest .
|
||||||
# working-directory: .
|
working-directory: .
|
||||||
# - name: Build package
|
- name: Build package
|
||||||
# run: python setup.py sdist
|
run: python setup.py sdist
|
||||||
# working-directory: .
|
working-directory: .
|
||||||
# - name: Check package
|
- name: Check package
|
||||||
# run: twine check dist/*
|
run: twine check dist/*
|
||||||
# working-directory: .
|
working-directory: .
|
||||||
#
|
|
||||||
|
|
19
CHANGELOG.md
19
CHANGELOG.md
|
@ -1,22 +1,3 @@
|
||||||
# 2.2.0
|
|
||||||
|
|
||||||
* add plugin category (#16)
|
|
||||||
* add placeholders `{TRACK_NAME}` and `{TRACK_NAME_COLOURED}`
|
|
||||||
|
|
||||||
# 2.1.0
|
|
||||||
|
|
||||||
* fixed installation procedure
|
|
||||||
* add some more information to the json outputs to be able to be compatible
|
|
||||||
with [scheduled-plugin-pretalx-broadcast-tools](https://github.com/Kunsi/scheduled-plugin-pretalx-broadcast-tools)
|
|
||||||
(a plugin for [info-beamer hosted](https://info-beamer.com/))
|
|
||||||
|
|
||||||
# 2.0.1 (no longer available due to bugs during installation)
|
|
||||||
|
|
||||||
* fixes to support pretalx 2023.1.0
|
|
||||||
* use non-deprecated gettext call
|
|
||||||
* safe timezone handling
|
|
||||||
* usage of pyproject.toml
|
|
||||||
|
|
||||||
# 2.0.0
|
# 2.0.0
|
||||||
|
|
||||||
* room info page can now show more content on the lower half of the view
|
* room info page can now show more content on the lower half of the view
|
||||||
|
|
|
@ -59,7 +59,7 @@ Development setup
|
||||||
|
|
||||||
3. Activate the virtual environment you use for pretalx development.
|
3. Activate the virtual environment you use for pretalx development.
|
||||||
|
|
||||||
4. Execute ``python -m pip install -e .`` within this directory to register
|
4. Execute ``python setup.py develop`` within this directory to register
|
||||||
this application with pretalx's plugin registry.
|
this application with pretalx's plugin registry.
|
||||||
|
|
||||||
5. Execute ``make`` within this directory to compile translations.
|
5. Execute ``make`` within this directory to compile translations.
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
__version__ = "2.2.1"
|
|
|
@ -1,8 +1,6 @@
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
from django.utils.translation import gettext_lazy
|
from django.utils.translation import gettext_lazy
|
||||||
|
|
||||||
from pretalx_broadcast_tools import __version__
|
|
||||||
|
|
||||||
|
|
||||||
class PluginApp(AppConfig):
|
class PluginApp(AppConfig):
|
||||||
name = "pretalx_broadcast_tools"
|
name = "pretalx_broadcast_tools"
|
||||||
|
@ -17,8 +15,7 @@ class PluginApp(AppConfig):
|
||||||
"embedded into your broadcasting software"
|
"embedded into your broadcasting software"
|
||||||
)
|
)
|
||||||
visible = True
|
visible = True
|
||||||
version = __version__
|
version = "2.0.0"
|
||||||
category = "FEATURE"
|
|
||||||
|
|
||||||
def ready(self):
|
def ready(self):
|
||||||
from . import signals # NOQA
|
from . import signals # NOQA
|
||||||
|
|
|
@ -17,7 +17,7 @@ from reportlab.platypus import (
|
||||||
TableStyle,
|
TableStyle,
|
||||||
)
|
)
|
||||||
|
|
||||||
from pretalx_broadcast_tools.utils.placeholders import placeholders
|
from .utils.placeholders import placeholders
|
||||||
|
|
||||||
A4_WIDTH, A4_HEIGHT = A4
|
A4_WIDTH, A4_HEIGHT = A4
|
||||||
PAGE_PADDING = 10 * mm
|
PAGE_PADDING = 10 * mm
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.urls import resolve, reverse
|
from django.urls import resolve, reverse
|
||||||
from django.utils.translation import gettext_lazy as _
|
|
||||||
from django.utils.translation import gettext_noop
|
from django.utils.translation import gettext_noop
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from i18nfield.strings import LazyI18nString
|
from i18nfield.strings import LazyI18nString
|
||||||
from pretalx.common.models.settings import hierarkey
|
from pretalx.common.models.settings import hierarkey
|
||||||
from pretalx.common.signals import register_data_exporters
|
from pretalx.common.signals import register_data_exporters
|
||||||
|
|
|
@ -32,22 +32,19 @@
|
||||||
</p>
|
</p>
|
||||||
<dl>
|
<dl>
|
||||||
<dt><code>{CODE}</code></dt>
|
<dt><code>{CODE}</code></dt>
|
||||||
<dd>talk code (<code>MUX9U3</code> for example) - most useful in combination with pretalx-proposal-redirects or something like that</dd>
|
<dd>Use to embed the talk code (<code>MUX9U3</code> for example).</dd>
|
||||||
|
|
||||||
<dt><code>{EVENT_SLUG}</code></dt>
|
<dt><code>{EVENT_SLUG}</code></dt>
|
||||||
<dd>The event slug (<code>{{ request.event.slug }}</code>)</dd>
|
<dd>Use to embed the event slug.</dd>
|
||||||
|
|
||||||
<dt><code>{FEEDBACK_URL}</code></dt>
|
<dt><code>{FEEDBACK_URL}</code></dt>
|
||||||
<dd>URL to the talk feedback page.</dd>
|
<dd>URL to the talk feedback page.</dd>
|
||||||
|
|
||||||
<dt><code>{TALK_SLUG}</code></dt>
|
<dt><code>{TALK_SLUG}</code></dt>
|
||||||
<dd>The talk slug (<code>{{ request.event.slug }}-1-my-super-great-talk</code>)</dd>
|
<dd>Use to embed the talk slug.</dd>
|
||||||
|
|
||||||
<dt><code>{TALK_URL}</code></dt>
|
<dt><code>{TALK_URL}</code></dt>
|
||||||
<dd>URL to the talk detail page.</dd>
|
<dd>URL to the talk detail page.</dd>
|
||||||
|
|
||||||
<dt><code>{TRACK_NAME}</code> or <code>{TRACK_NAME_COLOURED}</code></dt>
|
|
||||||
<dd>Track name in plain text or coloured using the track colour.</dd>
|
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
|
|
|
@ -1,46 +1,42 @@
|
||||||
from django.urls import re_path
|
from django.urls import re_path
|
||||||
from pretalx.event.models.event import SLUG_REGEX
|
from pretalx.event.models.event import SLUG_CHARS
|
||||||
|
|
||||||
from .views.event_info import BroadcastToolsEventInfoView
|
from . import views
|
||||||
from .views.orga import BroadcastToolsOrgaView
|
|
||||||
from .views.qr import BroadcastToolsFeedbackQrCodeSvg, BroadcastToolsPublicQrCodeSvg
|
|
||||||
from .views.schedule import BroadcastToolsScheduleView
|
|
||||||
from .views.static_html import BroadcastToolsLowerThirdsView, BroadcastToolsRoomInfoView
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
re_path(
|
re_path(
|
||||||
rf"^(?P<event>{SLUG_REGEX})/p/broadcast-tools/event.json$",
|
f"^(?P<event>[{SLUG_CHARS}]+)/p/broadcast-tools/event.json$",
|
||||||
BroadcastToolsEventInfoView.as_view(),
|
views.BroadcastToolsEventInfoView.as_view(),
|
||||||
name="event_info",
|
name="event_info",
|
||||||
),
|
),
|
||||||
re_path(
|
re_path(
|
||||||
f"^(?P<event>{SLUG_REGEX})/p/broadcast-tools/schedule.json$",
|
f"^(?P<event>[{SLUG_CHARS}]+)/p/broadcast-tools/schedule.json$",
|
||||||
BroadcastToolsScheduleView.as_view(),
|
views.BroadcastToolsScheduleView.as_view(),
|
||||||
name="schedule",
|
name="schedule",
|
||||||
),
|
),
|
||||||
re_path(
|
re_path(
|
||||||
f"^(?P<event>{SLUG_REGEX})/p/broadcast-tools/lower-thirds/$",
|
f"^(?P<event>[{SLUG_CHARS}]+)/p/broadcast-tools/lower-thirds/$",
|
||||||
BroadcastToolsLowerThirdsView.as_view(),
|
views.BroadcastToolsLowerThirdsView.as_view(),
|
||||||
name="lowerthirds",
|
name="lowerthirds",
|
||||||
),
|
),
|
||||||
re_path(
|
re_path(
|
||||||
f"^(?P<event>{SLUG_REGEX})/p/broadcast-tools/feedback-qr/(?P<talk>[0-9]+).svg$",
|
f"^(?P<event>[{SLUG_CHARS}]+)/p/broadcast-tools/feedback-qr/(?P<talk>[0-9]+).svg$",
|
||||||
BroadcastToolsFeedbackQrCodeSvg.as_view(),
|
views.BroadcastToolsFeedbackQrCodeSvg.as_view(),
|
||||||
name="feedback_qr_id",
|
name="feedback_qr_id",
|
||||||
),
|
),
|
||||||
re_path(
|
re_path(
|
||||||
f"^(?P<event>{SLUG_REGEX})/p/broadcast-tools/public-qr/(?P<talk>[0-9]+).svg$",
|
f"^(?P<event>[{SLUG_CHARS}]+)/p/broadcast-tools/public-qr/(?P<talk>[0-9]+).svg$",
|
||||||
BroadcastToolsPublicQrCodeSvg.as_view(),
|
views.BroadcastToolsPublicQrCodeSvg.as_view(),
|
||||||
name="public_qr_id",
|
name="public_qr_id",
|
||||||
),
|
),
|
||||||
re_path(
|
re_path(
|
||||||
f"^(?P<event>{SLUG_REGEX})/p/broadcast-tools/room-info/$",
|
f"^(?P<event>[{SLUG_CHARS}]+)/p/broadcast-tools/room-info/$",
|
||||||
BroadcastToolsRoomInfoView.as_view(),
|
views.BroadcastToolsRoomInfoView.as_view(),
|
||||||
name="room_info",
|
name="room_info",
|
||||||
),
|
),
|
||||||
re_path(
|
re_path(
|
||||||
f"^orga/event/(?P<event>{SLUG_REGEX})/settings/p/broadcast-tools/$",
|
f"^orga/event/(?P<event>[{SLUG_CHARS}]+)/settings/p/broadcast-tools/$",
|
||||||
BroadcastToolsOrgaView.as_view(),
|
views.BroadcastToolsOrgaView.as_view(),
|
||||||
name="orga",
|
name="orga",
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
def placeholders(schedule, talk, supports_html_colour=False):
|
def placeholders(schedule, talk):
|
||||||
track_name = str(talk.submission.track.name) if talk.submission.track else ""
|
return {
|
||||||
|
|
||||||
result = {
|
|
||||||
"CODE": talk.submission.code,
|
"CODE": talk.submission.code,
|
||||||
"EVENT_SLUG": str(schedule.event.slug),
|
"EVENT_SLUG": str(schedule.event.slug),
|
||||||
"FEEDBACK_URL": "{}{}".format(
|
"FEEDBACK_URL": "{}{}".format(
|
||||||
|
@ -16,17 +14,4 @@ def placeholders(schedule, talk, supports_html_colour=False):
|
||||||
schedule.event.custom_domain or settings.SITE_URL,
|
schedule.event.custom_domain or settings.SITE_URL,
|
||||||
talk.submission.urls.public,
|
talk.submission.urls.public,
|
||||||
),
|
),
|
||||||
"TRACK_NAME": track_name,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if talk.submission.track and supports_html_colour:
|
|
||||||
result["TRACK_NAME_COLOURED"] = '<span style="color: {}">{}</span>'.format(
|
|
||||||
talk.submission.track.color, track_name
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
result["TRACK_NAME_COLOURED"] = track_name
|
|
||||||
|
|
||||||
# for the americans
|
|
||||||
result["TRACK_NAME_COLORED"] = result["TRACK_NAME_COLOURED"]
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
199
pretalx_broadcast_tools/views.py
Normal file
199
pretalx_broadcast_tools/views.py
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
import datetime as dt
|
||||||
|
from xml.etree import ElementTree as ET
|
||||||
|
|
||||||
|
import pytz
|
||||||
|
import qrcode
|
||||||
|
import qrcode.image.svg
|
||||||
|
from django.conf import settings
|
||||||
|
from django.http import HttpResponse, JsonResponse
|
||||||
|
from django.urls import reverse
|
||||||
|
from django.utils.safestring import mark_safe
|
||||||
|
from django.views import View
|
||||||
|
from django.views.generic import FormView
|
||||||
|
from django.views.generic.base import TemplateView
|
||||||
|
from pretalx.agenda.views.schedule import ScheduleMixin
|
||||||
|
from pretalx.common.mixins.views import EventPermissionRequired, PermissionRequired
|
||||||
|
from pretalx.schedule.exporters import ScheduleData
|
||||||
|
|
||||||
|
from .forms import BroadcastToolsSettingsForm
|
||||||
|
from .utils.placeholders import placeholders
|
||||||
|
|
||||||
|
|
||||||
|
class BroadcastToolsLowerThirdsView(TemplateView):
|
||||||
|
template_name = "pretalx_broadcast_tools/lower_thirds.html"
|
||||||
|
|
||||||
|
|
||||||
|
class BroadcastToolsRoomInfoView(TemplateView):
|
||||||
|
template_name = "pretalx_broadcast_tools/room_info.html"
|
||||||
|
|
||||||
|
|
||||||
|
class BroadcastToolsOrgaView(PermissionRequired, FormView):
|
||||||
|
form_class = BroadcastToolsSettingsForm
|
||||||
|
permission_required = "orga.change_settings"
|
||||||
|
template_name = "pretalx_broadcast_tools/orga.html"
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
return self.request.path
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context["localized_rooms"] = [
|
||||||
|
room.name.localize(self.request.event.locale)
|
||||||
|
for room in self.request.event.rooms.all()
|
||||||
|
]
|
||||||
|
return context
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
form.save()
|
||||||
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
def get_object(self):
|
||||||
|
return self.request.event
|
||||||
|
|
||||||
|
def get_form_kwargs(self):
|
||||||
|
kwargs = super().get_form_kwargs()
|
||||||
|
return {
|
||||||
|
"obj": self.request.event,
|
||||||
|
"attribute_name": "settings",
|
||||||
|
"locales": self.request.event.locales,
|
||||||
|
**kwargs,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class BroadcastToolsEventInfoView(View):
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
color = self.request.event.primary_color or "#3aa57c"
|
||||||
|
return JsonResponse(
|
||||||
|
{
|
||||||
|
"color": color,
|
||||||
|
"name": str(self.request.event.name),
|
||||||
|
"no_talk": str(
|
||||||
|
self.request.event.settings.broadcast_tools_lower_thirds_no_talk_info
|
||||||
|
),
|
||||||
|
"room-info": {
|
||||||
|
"lower_info": self.request.event.settings.broadcast_tools_room_info_lower_content
|
||||||
|
or "",
|
||||||
|
"show_next_talk": True
|
||||||
|
if self.request.event.settings.broadcast_tools_room_info_show_next_talk
|
||||||
|
else False,
|
||||||
|
},
|
||||||
|
"slug": self.request.event.slug,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BroadcastToolsFeedbackQrCodeSvg(View):
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
talk = self.request.event.submissions.filter(id=kwargs["talk"]).first()
|
||||||
|
domain = request.event.custom_domain or settings.SITE_URL
|
||||||
|
image = qrcode.make(
|
||||||
|
f"{domain}{talk.urls.feedback}", image_factory=qrcode.image.svg.SvgImage
|
||||||
|
)
|
||||||
|
svg_data = mark_safe(ET.tostring(image.get_image()).decode())
|
||||||
|
return HttpResponse(svg_data, content_type="image/svg+xml")
|
||||||
|
|
||||||
|
|
||||||
|
class BroadcastToolsPublicQrCodeSvg(View):
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
talk = self.request.event.submissions.filter(id=kwargs["talk"]).first()
|
||||||
|
domain = request.event.custom_domain or settings.SITE_URL
|
||||||
|
image = qrcode.make(
|
||||||
|
f"{domain}{talk.urls.public}", image_factory=qrcode.image.svg.SvgImage
|
||||||
|
)
|
||||||
|
svg_data = mark_safe(ET.tostring(image.get_image()).decode())
|
||||||
|
return HttpResponse(svg_data, content_type="image/svg+xml")
|
||||||
|
|
||||||
|
|
||||||
|
class BroadcastToolsScheduleView(EventPermissionRequired, ScheduleMixin, View):
|
||||||
|
permission_required = "agenda.view_schedule"
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
schedule = ScheduleData(
|
||||||
|
event=self.request.event,
|
||||||
|
schedule=self.schedule,
|
||||||
|
)
|
||||||
|
tz = pytz.timezone(schedule.event.timezone)
|
||||||
|
infoline = str(
|
||||||
|
schedule.event.settings.broadcast_tools_lower_thirds_info_string or ""
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
return JsonResponse(
|
||||||
|
{
|
||||||
|
"rooms": sorted(
|
||||||
|
{
|
||||||
|
room["name"].localize(schedule.event.locale)
|
||||||
|
for day in schedule.data
|
||||||
|
for room in day["rooms"]
|
||||||
|
}
|
||||||
|
),
|
||||||
|
"talks": [
|
||||||
|
{
|
||||||
|
"id": talk.submission.id,
|
||||||
|
"start": talk.start.astimezone(tz).isoformat(),
|
||||||
|
"end": (talk.start + dt.timedelta(minutes=talk.duration))
|
||||||
|
.astimezone(tz)
|
||||||
|
.isoformat(),
|
||||||
|
"slug": talk.frab_slug,
|
||||||
|
"title": talk.submission.title,
|
||||||
|
"persons": [
|
||||||
|
person.get_display_name()
|
||||||
|
for person in talk.submission.speakers.all()
|
||||||
|
],
|
||||||
|
"track": {
|
||||||
|
"color": talk.submission.track.color,
|
||||||
|
"name": str(talk.submission.track.name),
|
||||||
|
}
|
||||||
|
if talk.submission.track
|
||||||
|
else None,
|
||||||
|
"room": room["name"].localize(schedule.event.locale),
|
||||||
|
"infoline": infoline.format(**placeholders(schedule, talk)),
|
||||||
|
"image_url": talk.submission.image_url,
|
||||||
|
"urls": {
|
||||||
|
"feedback": "{}{}".format(
|
||||||
|
schedule.event.custom_domain or settings.SITE_URL,
|
||||||
|
talk.submission.urls.feedback,
|
||||||
|
),
|
||||||
|
"feedback_qr": reverse(
|
||||||
|
"plugins:pretalx_broadcast_tools:feedback_qr_id",
|
||||||
|
kwargs={
|
||||||
|
"event": schedule.event.slug,
|
||||||
|
"talk": talk.submission.id,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
"public": "{}{}".format(
|
||||||
|
schedule.event.custom_domain or settings.SITE_URL,
|
||||||
|
talk.submission.urls.public,
|
||||||
|
),
|
||||||
|
"public_qr": reverse(
|
||||||
|
"plugins:pretalx_broadcast_tools:public_qr_id",
|
||||||
|
kwargs={
|
||||||
|
"event": schedule.event.slug,
|
||||||
|
"talk": talk.submission.id,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for day in schedule.data
|
||||||
|
for room in day["rooms"]
|
||||||
|
for talk in room["talks"]
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
except KeyError as e:
|
||||||
|
key = str(e)[1:-1]
|
||||||
|
return JsonResponse(
|
||||||
|
{
|
||||||
|
"error": [
|
||||||
|
f"Could not find value for placeholder {{{key}}} in info line.",
|
||||||
|
f"If you want to use {{{key}}} without evaluating it, please use as follows: {{{{{key}}}}}",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
return JsonResponse(
|
||||||
|
{
|
||||||
|
"error": [
|
||||||
|
repr(e),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
)
|
|
@ -1,30 +0,0 @@
|
||||||
from django.http import JsonResponse
|
|
||||||
from django.views import View
|
|
||||||
|
|
||||||
|
|
||||||
class BroadcastToolsEventInfoView(View):
|
|
||||||
def get(self, request, *args, **kwargs):
|
|
||||||
color = self.request.event.primary_color or "#3aa57c"
|
|
||||||
return JsonResponse(
|
|
||||||
{
|
|
||||||
"color": color,
|
|
||||||
"name": self.request.event.name.localize(self.request.event.locale),
|
|
||||||
"no_talk": str(
|
|
||||||
self.request.event.settings.broadcast_tools_lower_thirds_no_talk_info
|
|
||||||
),
|
|
||||||
"room-info": {
|
|
||||||
"lower_info": self.request.event.settings.broadcast_tools_room_info_lower_content
|
|
||||||
or "",
|
|
||||||
"show_next_talk": (
|
|
||||||
True
|
|
||||||
if self.request.event.settings.broadcast_tools_room_info_show_next_talk
|
|
||||||
else False
|
|
||||||
),
|
|
||||||
},
|
|
||||||
"slug": self.request.event.slug,
|
|
||||||
"start": self.request.event.date_from.isoformat(),
|
|
||||||
"end": self.request.event.date_to.isoformat(),
|
|
||||||
"timezone": str(self.request.event.tz),
|
|
||||||
"locale": self.request.event.locale,
|
|
||||||
},
|
|
||||||
)
|
|
|
@ -1,37 +0,0 @@
|
||||||
from django.views.generic import FormView
|
|
||||||
from pretalx.common.views.mixins import PermissionRequired
|
|
||||||
|
|
||||||
from ..forms import BroadcastToolsSettingsForm
|
|
||||||
|
|
||||||
|
|
||||||
class BroadcastToolsOrgaView(PermissionRequired, FormView):
|
|
||||||
form_class = BroadcastToolsSettingsForm
|
|
||||||
permission_required = "orga.change_settings"
|
|
||||||
template_name = "pretalx_broadcast_tools/orga.html"
|
|
||||||
|
|
||||||
def get_success_url(self):
|
|
||||||
return self.request.path
|
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
context = super().get_context_data(**kwargs)
|
|
||||||
context["localized_rooms"] = [
|
|
||||||
room.name.localize(self.request.event.locale)
|
|
||||||
for room in self.request.event.rooms.all()
|
|
||||||
]
|
|
||||||
return context
|
|
||||||
|
|
||||||
def form_valid(self, form):
|
|
||||||
form.save()
|
|
||||||
return super().form_valid(form)
|
|
||||||
|
|
||||||
def get_object(self):
|
|
||||||
return self.request.event
|
|
||||||
|
|
||||||
def get_form_kwargs(self):
|
|
||||||
kwargs = super().get_form_kwargs()
|
|
||||||
return {
|
|
||||||
"obj": self.request.event,
|
|
||||||
"attribute_name": "settings",
|
|
||||||
"locales": self.request.event.locales,
|
|
||||||
**kwargs,
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
from xml.etree import ElementTree
|
|
||||||
|
|
||||||
import qrcode
|
|
||||||
import qrcode.image.svg
|
|
||||||
from django.conf import settings
|
|
||||||
from django.http import HttpResponse
|
|
||||||
from django.utils.safestring import mark_safe
|
|
||||||
from django.views import View
|
|
||||||
|
|
||||||
|
|
||||||
class BroadcastToolsFeedbackQrCodeSvg(View):
|
|
||||||
def get(self, request, *args, **kwargs):
|
|
||||||
talk = self.request.event.submissions.filter(id=kwargs["talk"]).first()
|
|
||||||
domain = request.event.custom_domain or settings.SITE_URL
|
|
||||||
image = qrcode.make(
|
|
||||||
f"{domain}{talk.urls.feedback}", image_factory=qrcode.image.svg.SvgImage
|
|
||||||
)
|
|
||||||
svg_data = mark_safe(ElementTree.tostring(image.get_image()).decode())
|
|
||||||
return HttpResponse(svg_data, content_type="image/svg+xml")
|
|
||||||
|
|
||||||
|
|
||||||
class BroadcastToolsPublicQrCodeSvg(View):
|
|
||||||
def get(self, request, *args, **kwargs):
|
|
||||||
talk = self.request.event.submissions.filter(id=kwargs["talk"]).first()
|
|
||||||
domain = request.event.custom_domain or settings.SITE_URL
|
|
||||||
image = qrcode.make(
|
|
||||||
f"{domain}{talk.urls.public}", image_factory=qrcode.image.svg.SvgImage
|
|
||||||
)
|
|
||||||
svg_data = mark_safe(ElementTree.tostring(image.get_image()).decode())
|
|
||||||
return HttpResponse(svg_data, content_type="image/svg+xml")
|
|
|
@ -1,122 +0,0 @@
|
||||||
import datetime as dt
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.http import JsonResponse
|
|
||||||
from django.urls import reverse
|
|
||||||
from django.views import View
|
|
||||||
from pretalx.agenda.views.schedule import ScheduleMixin
|
|
||||||
from pretalx.common.views.mixins import EventPermissionRequired
|
|
||||||
from pretalx.schedule.exporters import ScheduleData
|
|
||||||
|
|
||||||
from ..utils.placeholders import placeholders
|
|
||||||
|
|
||||||
|
|
||||||
class BroadcastToolsScheduleView(EventPermissionRequired, ScheduleMixin, View):
|
|
||||||
permission_required = "agenda.view_schedule"
|
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
|
||||||
schedule = ScheduleData(
|
|
||||||
event=self.request.event,
|
|
||||||
schedule=self.schedule,
|
|
||||||
)
|
|
||||||
infoline = str(
|
|
||||||
schedule.event.settings.broadcast_tools_lower_thirds_info_string or ""
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
return JsonResponse(
|
|
||||||
{
|
|
||||||
"rooms": sorted(
|
|
||||||
{
|
|
||||||
room["name"].localize(schedule.event.locale)
|
|
||||||
for day in schedule.data
|
|
||||||
for room in day["rooms"]
|
|
||||||
}
|
|
||||||
),
|
|
||||||
"talks": [
|
|
||||||
{
|
|
||||||
"id": talk.submission.id,
|
|
||||||
"start": talk.start.astimezone(
|
|
||||||
schedule.event.tz
|
|
||||||
).isoformat(),
|
|
||||||
"start_ts": int(talk.start.timestamp()),
|
|
||||||
"end": (talk.start + dt.timedelta(minutes=talk.duration))
|
|
||||||
.astimezone(schedule.event.tz)
|
|
||||||
.isoformat(),
|
|
||||||
"end_ts": int(
|
|
||||||
(
|
|
||||||
talk.start + dt.timedelta(minutes=talk.duration)
|
|
||||||
).timestamp()
|
|
||||||
),
|
|
||||||
"slug": talk.frab_slug,
|
|
||||||
"title": talk.submission.title,
|
|
||||||
"persons": [
|
|
||||||
person.get_display_name()
|
|
||||||
for person in talk.submission.speakers.all()
|
|
||||||
],
|
|
||||||
"track": (
|
|
||||||
{
|
|
||||||
"color": talk.submission.track.color,
|
|
||||||
"name": str(talk.submission.track.name),
|
|
||||||
}
|
|
||||||
if talk.submission.track
|
|
||||||
else None
|
|
||||||
),
|
|
||||||
"room": room["name"].localize(schedule.event.locale),
|
|
||||||
"infoline": infoline.format(
|
|
||||||
**placeholders(
|
|
||||||
schedule, talk, supports_html_colour=True
|
|
||||||
)
|
|
||||||
),
|
|
||||||
"image_url": talk.submission.image_url,
|
|
||||||
"locale": talk.submission.content_locale,
|
|
||||||
"do_not_record": talk.submission.do_not_record,
|
|
||||||
"abstract": talk.submission.abstract,
|
|
||||||
"urls": {
|
|
||||||
"feedback": "{}{}".format(
|
|
||||||
schedule.event.custom_domain or settings.SITE_URL,
|
|
||||||
talk.submission.urls.feedback,
|
|
||||||
),
|
|
||||||
"feedback_qr": reverse(
|
|
||||||
"plugins:pretalx_broadcast_tools:feedback_qr_id",
|
|
||||||
kwargs={
|
|
||||||
"event": schedule.event.slug,
|
|
||||||
"talk": talk.submission.id,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
"public": "{}{}".format(
|
|
||||||
schedule.event.custom_domain or settings.SITE_URL,
|
|
||||||
talk.submission.urls.public,
|
|
||||||
),
|
|
||||||
"public_qr": reverse(
|
|
||||||
"plugins:pretalx_broadcast_tools:public_qr_id",
|
|
||||||
kwargs={
|
|
||||||
"event": schedule.event.slug,
|
|
||||||
"talk": talk.submission.id,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for day in schedule.data
|
|
||||||
for room in day["rooms"]
|
|
||||||
for talk in room["talks"]
|
|
||||||
],
|
|
||||||
},
|
|
||||||
)
|
|
||||||
except KeyError as e:
|
|
||||||
key = str(e)[1:-1]
|
|
||||||
return JsonResponse(
|
|
||||||
{
|
|
||||||
"error": [
|
|
||||||
f"Could not find value for placeholder {{{key}}} in info line.",
|
|
||||||
f"If you want to use {{{key}}} without evaluating it, please use as follows: {{{{{key}}}}}",
|
|
||||||
],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
return JsonResponse(
|
|
||||||
{
|
|
||||||
"error": [
|
|
||||||
repr(e),
|
|
||||||
],
|
|
||||||
}
|
|
||||||
)
|
|
|
@ -1,9 +0,0 @@
|
||||||
from django.views.generic.base import TemplateView
|
|
||||||
|
|
||||||
|
|
||||||
class BroadcastToolsLowerThirdsView(TemplateView):
|
|
||||||
template_name = "pretalx_broadcast_tools/lower_thirds.html"
|
|
||||||
|
|
||||||
|
|
||||||
class BroadcastToolsRoomInfoView(TemplateView):
|
|
||||||
template_name = "pretalx_broadcast_tools/room_info.html"
|
|
|
@ -1,41 +0,0 @@
|
||||||
[project]
|
|
||||||
name = "pretalx-broadcast-tools"
|
|
||||||
dynamic = ["version"]
|
|
||||||
description = """
|
|
||||||
Some tools which can be used for supporting a broadcasting software.
|
|
||||||
This currently includes a generator for PDF printouts, a 'lower thirds'
|
|
||||||
endpoint, and a full-screen webpage showing information about the
|
|
||||||
currently running talk.
|
|
||||||
"""
|
|
||||||
readme = "README.rst"
|
|
||||||
license = {text = "Apache Software License"}
|
|
||||||
keywords = ["pretalx"]
|
|
||||||
authors = [
|
|
||||||
{name = "Franziska Kunsmann", email = "git@kunsmann.eu"},
|
|
||||||
]
|
|
||||||
maintainers = [
|
|
||||||
{name = "Franziska Kunsmann", email = "git@kunsmann.eu"},
|
|
||||||
]
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
]
|
|
||||||
|
|
||||||
[project.entry-points."pretalx.plugin"]
|
|
||||||
pretalx_broadcast_tools = "pretalx_broadcast_tools:PretalxPluginMeta"
|
|
||||||
|
|
||||||
[build-system]
|
|
||||||
build-backend = "setuptools.build_meta"
|
|
||||||
requires = ["setuptools", "wheel"]
|
|
||||||
|
|
||||||
[project.urls]
|
|
||||||
homepage = "https://github.com/Kunsi/pretalx-plugin-broadcast-tools"
|
|
||||||
repository = "https://github.com/Kunsi/pretalx-plugin-broadcast-tools.git"
|
|
||||||
|
|
||||||
[tool.setuptools]
|
|
||||||
include-package-data = true
|
|
||||||
|
|
||||||
[tool.setuptools.dynamic]
|
|
||||||
version = {attr = "pretalx_broadcast_tools.__version__"}
|
|
||||||
|
|
||||||
[tool.setuptools.packages.find]
|
|
||||||
include = ["pretalx*"]
|
|
46
setup.py
Normal file
46
setup.py
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
import os
|
||||||
|
from distutils.command.build import build
|
||||||
|
|
||||||
|
from django.core import management
|
||||||
|
from setuptools import find_packages, setup
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(
|
||||||
|
os.path.join(os.path.dirname(__file__), "README.rst"), encoding="utf-8"
|
||||||
|
) as f:
|
||||||
|
long_description = f.read()
|
||||||
|
except FileNotFoundError:
|
||||||
|
long_description = ""
|
||||||
|
|
||||||
|
|
||||||
|
class CustomBuild(build):
|
||||||
|
def run(self):
|
||||||
|
management.call_command("compilemessages", verbosity=1)
|
||||||
|
build.run(self)
|
||||||
|
|
||||||
|
|
||||||
|
cmdclass = {"build": CustomBuild}
|
||||||
|
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name="pretalx-plugin-broadcast-tools",
|
||||||
|
version="2.0.0",
|
||||||
|
description=(
|
||||||
|
"Some tools which can be used for supporting a broadcasting "
|
||||||
|
"software, for example a 'lower third' page which can be "
|
||||||
|
"embedded into your broadcasting software"
|
||||||
|
),
|
||||||
|
long_description=long_description,
|
||||||
|
url="https://github.com/Kunsi/pretalx-plugin-broadcast-tools",
|
||||||
|
author="kunsi",
|
||||||
|
author_email="git@kunsmann.eu",
|
||||||
|
license="Apache Software License",
|
||||||
|
install_requires=[],
|
||||||
|
packages=find_packages(exclude=["tests", "tests.*"]),
|
||||||
|
include_package_data=True,
|
||||||
|
cmdclass=cmdclass,
|
||||||
|
entry_points="""
|
||||||
|
[pretalx.plugin]
|
||||||
|
pretalx_broadcast_tools=pretalx_broadcast_tools:PretalxPluginMeta
|
||||||
|
""",
|
||||||
|
)
|
Loading…
Reference in a new issue