API notifications
This commit is contained in:
@@ -18,6 +18,7 @@ class Notification(Provider):
|
|||||||
listen_to = [
|
listen_to = [
|
||||||
'renamer.after', 'movie.snatched',
|
'renamer.after', 'movie.snatched',
|
||||||
'updater.available', 'updater.updated',
|
'updater.available', 'updater.updated',
|
||||||
|
'core.message',
|
||||||
]
|
]
|
||||||
dont_listen_to = []
|
dont_listen_to = []
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
from couchpotato import get_session
|
from couchpotato import get_session
|
||||||
from couchpotato.api import addApiView, addNonBlockApiView
|
from couchpotato.api import addApiView, addNonBlockApiView
|
||||||
from couchpotato.core.event import addEvent
|
from couchpotato.core.event import addEvent, fireEvent
|
||||||
from couchpotato.core.helpers.encoding import toUnicode
|
from couchpotato.core.helpers.encoding import toUnicode
|
||||||
from couchpotato.core.helpers.request import jsonified, getParam
|
from couchpotato.core.helpers.request import jsonified, getParam
|
||||||
from couchpotato.core.helpers.variable import tryInt, splitString
|
from couchpotato.core.helpers.variable import tryInt, splitString
|
||||||
from couchpotato.core.logger import CPLog
|
from couchpotato.core.logger import CPLog
|
||||||
from couchpotato.core.notifications.base import Notification
|
from couchpotato.core.notifications.base import Notification
|
||||||
from couchpotato.core.settings.model import Notification as Notif
|
from couchpotato.core.settings.model import Notification as Notif
|
||||||
|
from couchpotato.environment import Env
|
||||||
from sqlalchemy.sql.expression import or_
|
from sqlalchemy.sql.expression import or_
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
@@ -21,11 +22,6 @@ class CoreNotifier(Notification):
|
|||||||
messages = []
|
messages = []
|
||||||
listeners = []
|
listeners = []
|
||||||
|
|
||||||
listen_to = [
|
|
||||||
'renamer.after', 'movie.snatched',
|
|
||||||
'updater.available', 'updater.updated',
|
|
||||||
]
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(CoreNotifier, self).__init__()
|
super(CoreNotifier, self).__init__()
|
||||||
|
|
||||||
@@ -54,7 +50,10 @@ class CoreNotifier(Notification):
|
|||||||
addNonBlockApiView('notification.listener', (self.addListener, self.removeListener))
|
addNonBlockApiView('notification.listener', (self.addListener, self.removeListener))
|
||||||
addApiView('notification.listener', self.listener)
|
addApiView('notification.listener', self.listener)
|
||||||
|
|
||||||
|
fireEvent('schedule.interval', 'core.check_messages', self.checkMessages, hours = 12, single = True)
|
||||||
|
|
||||||
addEvent('app.load', self.clean)
|
addEvent('app.load', self.clean)
|
||||||
|
addEvent('app.load', self.checkMessages)
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
|
|
||||||
@@ -112,6 +111,23 @@ class CoreNotifier(Notification):
|
|||||||
'notifications': notifications
|
'notifications': notifications
|
||||||
})
|
})
|
||||||
|
|
||||||
|
def checkMessages(self):
|
||||||
|
|
||||||
|
prop_name = 'messages.last_check'
|
||||||
|
last_check = tryInt(Env.prop(prop_name, default = 0))
|
||||||
|
|
||||||
|
messages = fireEvent('cp.messages', last_check = last_check, single = True)
|
||||||
|
|
||||||
|
last_time = 0
|
||||||
|
for message in messages:
|
||||||
|
if message.get('time') > last_check:
|
||||||
|
fireEvent('core.message', message = message.get('message'), data = message)
|
||||||
|
|
||||||
|
if last_time < message.get('time'):
|
||||||
|
last_time = message.get('time')
|
||||||
|
|
||||||
|
Env.prop(prop_name, value = last_time)
|
||||||
|
|
||||||
def notify(self, message = '', data = {}, listener = None):
|
def notify(self, message = '', data = {}, listener = None):
|
||||||
|
|
||||||
db = get_session()
|
db = get_session()
|
||||||
|
|||||||
@@ -44,14 +44,19 @@ var NotificationBase = new Class({
|
|||||||
|
|
||||||
result.el = App.getBlock('notification').addLink(
|
result.el = App.getBlock('notification').addLink(
|
||||||
new Element('span.'+(result.read ? 'read' : '' )).adopt(
|
new Element('span.'+(result.read ? 'read' : '' )).adopt(
|
||||||
new Element('span.message', {'text': result.message}),
|
new Element('span.message', {'html': result.message}),
|
||||||
new Element('span.added', {'text': added.timeDiffInWords(), 'title': added})
|
new Element('span.added', {'text': added.timeDiffInWords(), 'title': added})
|
||||||
)
|
)
|
||||||
, 'top');
|
, 'top');
|
||||||
self.notifications.include(result);
|
self.notifications.include(result);
|
||||||
|
|
||||||
if(!result.read)
|
if(result.data.important !== undefined && !result.read){
|
||||||
|
var sticky = true
|
||||||
|
App.fireEvent('message', [result.message, sticky, result])
|
||||||
|
}
|
||||||
|
else if(!result.read){
|
||||||
self.setBadge(self.notifications.filter(function(n){ return !n.read}).length)
|
self.setBadge(self.notifications.filter(function(n){ return !n.read}).length)
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -61,20 +66,26 @@ var NotificationBase = new Class({
|
|||||||
self.badge[value ? 'show' : 'hide']()
|
self.badge[value ? 'show' : 'hide']()
|
||||||
},
|
},
|
||||||
|
|
||||||
markAsRead: function(){
|
markAsRead: function(force_ids){
|
||||||
var self = this;
|
var self = this,
|
||||||
|
ids = force_ids;
|
||||||
|
|
||||||
var rn = self.notifications.filter(function(n){
|
if(!force_ids) {
|
||||||
return !n.read
|
var rn = self.notifications.filter(function(n){
|
||||||
})
|
return !n.read && n.data.important === undefined
|
||||||
|
})
|
||||||
|
|
||||||
var ids = []
|
var ids = []
|
||||||
rn.each(function(n){
|
rn.each(function(n){
|
||||||
ids.include(n.id)
|
ids.include(n.id)
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if(ids.length > 0)
|
if(ids.length > 0)
|
||||||
Api.request('notification.markread', {
|
Api.request('notification.markread', {
|
||||||
|
'data': {
|
||||||
|
'ids': ids.join(',')
|
||||||
|
},
|
||||||
'onSuccess': function(){
|
'onSuccess': function(){
|
||||||
self.setBadge('')
|
self.setBadge('')
|
||||||
}
|
}
|
||||||
@@ -140,26 +151,41 @@ var NotificationBase = new Class({
|
|||||||
self.startPoll()
|
self.startPoll()
|
||||||
},
|
},
|
||||||
|
|
||||||
showMessage: function(message){
|
showMessage: function(message, sticky, data){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if(!self.message_container)
|
if(!self.message_container)
|
||||||
self.message_container = new Element('div.messages').inject(document.body);
|
self.message_container = new Element('div.messages').inject(document.body);
|
||||||
|
|
||||||
var new_message = new Element('div.message', {
|
var new_message = new Element('div', {
|
||||||
'text': message
|
'class': 'message' + (sticky ? ' sticky' : ''),
|
||||||
}).inject(self.message_container);
|
'html': message
|
||||||
|
}).inject(self.message_container, 'top');
|
||||||
|
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
new_message.addClass('show')
|
new_message.addClass('show')
|
||||||
}, 10);
|
}, 10);
|
||||||
|
|
||||||
setTimeout(function(){
|
var hide_message = function(){
|
||||||
new_message.addClass('hide')
|
new_message.addClass('hide')
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
new_message.destroy();
|
new_message.destroy();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}, 4000);
|
}
|
||||||
|
|
||||||
|
if(sticky)
|
||||||
|
new_message.grab(
|
||||||
|
new Element('a.close.icon2', {
|
||||||
|
'events': {
|
||||||
|
'click': function(){
|
||||||
|
self.markAsRead([data.id]);
|
||||||
|
hide_message();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
else
|
||||||
|
setTimeout(hide_message, 4000);
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ from couchpotato import get_session
|
|||||||
from couchpotato.core.event import addEvent, fireEvent
|
from couchpotato.core.event import addEvent, fireEvent
|
||||||
from couchpotato.core.helpers.encoding import tryUrlencode
|
from couchpotato.core.helpers.encoding import tryUrlencode
|
||||||
from couchpotato.core.helpers.request import jsonified, getParams
|
from couchpotato.core.helpers.request import jsonified, getParams
|
||||||
|
from couchpotato.core.helpers.variable import tryInt
|
||||||
from couchpotato.core.logger import CPLog
|
from couchpotato.core.logger import CPLog
|
||||||
from couchpotato.core.providers.movie.base import MovieProvider
|
from couchpotato.core.providers.movie.base import MovieProvider
|
||||||
from couchpotato.core.settings.model import Movie
|
from couchpotato.core.settings.model import Movie
|
||||||
@@ -20,6 +21,7 @@ class CouchPotatoApi(MovieProvider):
|
|||||||
'eta': 'https://couchpota.to/api/eta/%s/',
|
'eta': 'https://couchpota.to/api/eta/%s/',
|
||||||
'suggest': 'https://couchpota.to/api/suggest/',
|
'suggest': 'https://couchpota.to/api/suggest/',
|
||||||
'updater': 'https://couchpota.to/api/updater/?%s',
|
'updater': 'https://couchpota.to/api/updater/?%s',
|
||||||
|
'messages': 'https://couchpota.to/api/messages/?%s',
|
||||||
}
|
}
|
||||||
http_time_between_calls = 0
|
http_time_between_calls = 0
|
||||||
api_version = 1
|
api_version = 1
|
||||||
@@ -32,6 +34,15 @@ class CouchPotatoApi(MovieProvider):
|
|||||||
addEvent('movie.is_movie', self.isMovie)
|
addEvent('movie.is_movie', self.isMovie)
|
||||||
|
|
||||||
addEvent('cp.source_url', self.getSourceUrl)
|
addEvent('cp.source_url', self.getSourceUrl)
|
||||||
|
addEvent('cp.messages', self.getMessages)
|
||||||
|
|
||||||
|
def getMessages(self, last_check = 0):
|
||||||
|
|
||||||
|
data = self.getJsonData(self.urls['messages'] % tryUrlencode({
|
||||||
|
'last_check': last_check,
|
||||||
|
}), headers = self.getRequestHeaders(), cache_timeout = 10)
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
def getSourceUrl(self, repo = None, repo_name = None, branch = None):
|
def getSourceUrl(self, repo = None, repo_name = None, branch = None):
|
||||||
return self.getJsonData(self.urls['updater'] % tryUrlencode({
|
return self.getJsonData(self.urls['updater'] % tryUrlencode({
|
||||||
|
|||||||
@@ -160,6 +160,7 @@ body > .spinner, .mask{
|
|||||||
.icon2.eye-open:before { content: "\e09d"; }
|
.icon2.eye-open:before { content: "\e09d"; }
|
||||||
.icon2.search:before { content: "\e03e"; }
|
.icon2.search:before { content: "\e03e"; }
|
||||||
.icon2.return-key:before { content: "\e111"; }
|
.icon2.return-key:before { content: "\e111"; }
|
||||||
|
.icon2.close:before { content: "\e04e"; }
|
||||||
.icon2.menu:before {
|
.icon2.menu:before {
|
||||||
content: "\e076 \e076 \e076";
|
content: "\e076 \e076 \e076";
|
||||||
line-height: 6px;
|
line-height: 6px;
|
||||||
@@ -715,43 +716,51 @@ body > .spinner, .mask{
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
padding: 2px;
|
width: 320px;
|
||||||
width: 240px;
|
|
||||||
z-index: 20;
|
z-index: 20;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
@media all and (max-width: 480px) {
|
||||||
|
.messages {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.messages .message {
|
.messages .message {
|
||||||
text-align: center;
|
|
||||||
border-radius: 2px;
|
|
||||||
margin: 2px 0 0 0;
|
|
||||||
height: 0;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: all .6s cubic-bezier(0.9,0,0.1,1);
|
transition: all .6s cubic-bezier(0.9,0,0.1,1);
|
||||||
box-shadow: 0 1px 1px rgba(0,0,0,0.35), inset 0 1px 0px rgba(255,255,255,0.20);
|
background: #5b9bd1;
|
||||||
background-image: linear-gradient(
|
|
||||||
180deg,
|
|
||||||
#5b9bd1 0%,
|
|
||||||
#406db8 100%
|
|
||||||
);
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0 5px;
|
position: relative;
|
||||||
visibility: hidden;
|
margin: 1px 0 0;
|
||||||
max-height: 0;
|
max-height: 0;
|
||||||
|
padding: 0 30px 0 20px;
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-weight: normal;
|
||||||
|
transform: scale(0);
|
||||||
}
|
}
|
||||||
|
.messages .message.sticky {
|
||||||
|
background-color: #c84040;
|
||||||
|
}
|
||||||
.messages .message.show {
|
.messages .message.show {
|
||||||
visibility: visible;
|
max-height: 100px;
|
||||||
height: auto;
|
padding: 15px 30px 15px 20px;
|
||||||
padding-top: 3px;
|
transform: scale(1);
|
||||||
padding-bottom: 3px;
|
|
||||||
min-height: 1px;
|
|
||||||
max-height: 400px;
|
|
||||||
}
|
}
|
||||||
.messages .message.hide {
|
.messages .message.hide {
|
||||||
margin-left: 240px;
|
max-height: 0;
|
||||||
opacity: 0;
|
padding: 0 20px;
|
||||||
|
margin: 0;
|
||||||
|
transform: scale(0);
|
||||||
|
}
|
||||||
|
.messages .close {
|
||||||
|
position: absolute;
|
||||||
|
padding: 10px 8px;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
color: #FFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fonts */
|
/* Fonts */
|
||||||
|
|||||||
Reference in New Issue
Block a user