Commit 09347b4a authored by echel0n's avatar echel0n

Adding announcement feature to sickrage app

parent ede5d4dc
......@@ -42,6 +42,7 @@ from keycloak.realm import KeycloakRealm
from tornado.ioloop import IOLoop
import sickrage
from sickrage.core.announcements import Announcements
from sickrage.core.api import API
from sickrage.core.api.account import AccountAPI
from sickrage.core.caches.name_cache import NameCache
......@@ -167,6 +168,7 @@ class Core(object):
self.upnp_client = None
self.oidc_client = None
self.quicksearch_cache = None
self.announcements = None
def start(self):
self.started = True
......@@ -203,6 +205,7 @@ class Core(object):
self.auto_postprocessor = AutoPostProcessor()
self.upnp_client = UPNPClient()
self.quicksearch_cache = QuicksearchCache()
self.announcements = Announcements()
# setup oidc client
realm = KeycloakRealm(server_url='https://auth.sickrage.ca', realm_name='sickrage')
......@@ -526,6 +529,11 @@ class Core(object):
self.log.info("SiCKRAGE :: URL:[{}://{}:{}{}]".format(('http', 'https')[self.config.enable_https], self.config.web_host, self.config.web_port,
self.config.web_root))
self.announcements.add('test', 'test', 'test', 'test')
self.announcements.add('test', 'test', 'test', 'test')
self.announcements.add('test', 'test', 'test', 'test')
self.announcements.add('test', 'test', 'test', 'test')
# start io_loop
self.io_loop.add_callback(started)
self.io_loop.start()
......
# ##############################################################################
# Author: echel0n <[email protected]>
# URL: https://sickrage.ca/
# Git: https://git.sickrage.ca/SiCKRAGE/sickrage.git
# -
# This file is part of SiCKRAGE.
# -
# SiCKRAGE 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, either version 3 of the License, or
# (at your option) any later version.
# -
# SiCKRAGE 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 SiCKRAGE. If not, see <http://www.gnu.org/licenses/>.
# ##############################################################################
class Announcement(object):
"""
Represents an announcement.
"""
def __init__(self, title, description, image, date):
self.title = title
self.description = description
self.image = image
self.date = date
class Announcements(object):
"""
Keeps a static list of (announcement) UIErrors to be displayed on the UI and allows
the list to be cleared.
"""
def __init__(self):
self.announcements = []
def add(self, title, description, image, date):
self.announcements += [Announcement(title, description, image, date)]
def clear(self):
self.announcements = []
def get(self):
return self.announcements
def count(self):
return len(self.announcements)
# ##############################################################################
# Author: echel0n <[email protected]>
# URL: https://sickrage.ca/
# Git: https://git.sickrage.ca/SiCKRAGE/sickrage.git
# -
# This file is part of SiCKRAGE.
# -
# SiCKRAGE 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, either version 3 of the License, or
# (at your option) any later version.
# -
# SiCKRAGE 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 SiCKRAGE. If not, see <http://www.gnu.org/licenses/>.
# ##############################################################################
from sickrage.core.api import API
class AnnouncementsAPI(API):
def get_announcements(self):
return self._request('GET', 'announcements')
......@@ -178,6 +178,9 @@ class ErrorViewer(object):
def get(self):
return self.errors
def count(self):
return len(self.errors)
class WarningViewer(object):
"""
......@@ -195,3 +198,6 @@ class WarningViewer(object):
def get(self):
return self.warnings
def count(self):
return len(self.warnings)
......@@ -186,8 +186,7 @@ class Logger(logging.getLoggerClass()):
# sending record to UI
if record.levelno in [WARNING, ERROR]:
(self.warning_viewer, self.error_viewer)[record.levelno == ERROR].add(
"{}::{}".format(record.threadName, record.msg), True)
(self.warning_viewer, self.error_viewer)[record.levelno == ERROR].add("{}::{}".format(record.threadName, record.msg), True)
return record
......
......@@ -81,7 +81,7 @@ from sickrage.core.webserver.handlers.manage.queues import ManageQueuesHandler,
from sickrage.core.webserver.handlers.root import RobotsDotTxtHandler, MessagesDotPoHandler, \
APIBulderHandler, SetHomeLayoutHandler, SetPosterSortByHandler, SetPosterSortDirHandler, \
ToggleDisplayShowSpecialsHandler, SetScheduleLayoutHandler, ToggleScheduleDisplayPausedHandler, \
SetScheduleSortHandler, ScheduleHandler, UnlinkHandler, QuicksearchDotJsonHandler, SetHistoryLayoutHandler, ForceSchedulerJobHandler
SetScheduleSortHandler, ScheduleHandler, UnlinkHandler, QuicksearchDotJsonHandler, SetHistoryLayoutHandler, ForceSchedulerJobHandler, AnnouncementsHandler
from sickrage.core.webserver.handlers.web_file_browser import WebFileBrowserHandler, WebFileBrowserCompleteHandler
from sickrage.core.websocket import WebSocketUIHandler
......@@ -226,6 +226,7 @@ class WebServer(object):
(r'%s/toggleScheduleDisplayPaused(/?)' % sickrage.app.config.web_root, ToggleScheduleDisplayPausedHandler),
(r'%s/setScheduleSort(/?)' % sickrage.app.config.web_root, SetScheduleSortHandler),
(r'%s/forceSchedulerJob(/?)' % sickrage.app.config.web_root, ForceSchedulerJobHandler),
(r'%s/announcements(/?)' % sickrage.app.config.web_root, AnnouncementsHandler),
(r'%s/schedule(/?)' % sickrage.app.config.web_root, ScheduleHandler),
(r'%s/unlink(/?)' % sickrage.app.config.web_root, UnlinkHandler),
(r'%s/setScheduleLayout(/?)' % sickrage.app.config.web_root, SetScheduleLayoutHandler),
......
......@@ -135,8 +135,9 @@ class BaseHandler(RequestHandler, ABC):
'srWebRoot': sickrage.app.config.web_root,
'srLocale': self.get_user_locale().code,
'srLocaleDir': sickrage.LOCALE_DIR,
'numErrors': len(sickrage.app.log.error_viewer.get()),
'numWarnings': len(sickrage.app.log.warning_viewer.get()),
'numErrors': sickrage.app.log.error_viewer.count(),
'numWarnings': sickrage.app.log.warning_viewer.count(),
'numAnnouncements': sickrage.app.announcements.count(),
'srStartTime': self.startTime,
'makoStartTime': time.time(),
'overall_stats': None,
......
......@@ -31,6 +31,7 @@ from tornado.web import authenticated
import sickrage
from sickrage.core import AccountAPI
from sickrage.core.api import API
from sickrage.core.api.announcements import AnnouncementsAPI
from sickrage.core.helpers import remove_article
from sickrage.core.tv.episode import TVEpisode
from sickrage.core.tv.show.coming_episodes import ComingEpisodes
......@@ -271,3 +272,16 @@ class ForceSchedulerJobHandler(BaseHandler, ABC):
service = getattr(sickrage.app, name, None)
if service:
job = sickrage.app.scheduler.get_job(service.name).func(True)
class AnnouncementsHandler(BaseHandler, ABC):
@authenticated
async def get(self, *args, **kwargs):
return self.render(
'announcements.mako',
title=_('Announcements'),
header=_('Announcements'),
topmenu='announcements',
controller='root',
action='announcements'
)
% for announcement in announcements:
<div class="announcement-container">
<div class="card card-block text-white bg-dark m-1 shadow">
<h4>${announcement['title']}</h4>
<img src="${announcement['image']}"/>
<div class="date">${announcement['date']}</div>
<div class="description">${announcement['description']}</div>
</div>
<%inherit file="./layouts/main.mako"/>
<%!
import sickrage
%>
<%block name="content">
<div class="row">
% for announcement in sickrage.app.announcements.get():
<div class="col-lg-2 mx-auto">
<div class="announcement-container">
<div class="card mb-3" style="max-width: 540px;">
<div class="row no-gutters">
<div class="col-md-4">
<img src="${announcement.image}" class="card-img" alt="">
</div>
<div class="col-md-8">
<div class="card-body">
<h5 class="card-title">${announcement.title}</h5>
<p class="card-text">${announcement.description}</p>
<p class="card-text"><small class="text-muted">${announcement.date}</small></p>
</div>
</div>
</div>
</div>
</div>
</div>
% endfor
</div>
% endfor
\ No newline at end of file
</%block>
\ No newline at end of file
......@@ -73,17 +73,18 @@
% if current_user:
<%
numCombined = numErrors + numWarnings
toolsBadge = ''
numCombined = numErrors + numWarnings + numAnnouncements
if numCombined:
toolsBadgeClass = ''
if numErrors:
toolsBadgeClass = 'badge-danger'
elif numWarnings:
toolsBadgeClass = 'badge-warning'
elif numAnnouncements:
toolsBadgeClass = 'badge-info'
toolsBadge = '<span class="badge badge-pill ' + toolsBadgeClass + '" style="float:right;margin-bottom:-10px;">' + str(numCombined) + '</span>'
else:
toolsBadge = ''
%>
% if current_user and sickrage.app.newest_version_string:
......@@ -286,6 +287,12 @@
onclick="window.open('${sickrage.app.config.anon_redirect}' + this.href); return false;">
<i class="fas fa-fw fa-donate"></i>&nbsp;${_('Donate')}
</a>
<a class="dropdown-item" href="${srWebRoot}/announcements/">
<i class="fas fa-fw fa-circle"></i>&nbsp;${_('Announcements')}
%if numAnnouncements:
<span class="badge badge-info">${numAnnouncements}</span>
%endif
</a>
<div class="dropdown-divider"></div>
%if numErrors:
<a class="dropdown-item" href="${srWebRoot}/logs/">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment