@ -0,0 +1,14 @@ |
|||||
|
#So you feel like posting a bug, sending me a pull request or just telling me how awesome I am. No problem! |
||||
|
|
||||
|
##Just make sure you think of the following things: |
||||
|
|
||||
|
* Search through the existing (and closed) issues first. See if you can get your answer there. |
||||
|
* Double check the result manually, because it could be an external issue. |
||||
|
* Post logs! Without seeing what is going on, I can't reproduce the error. |
||||
|
* What are you settings for the specific problem |
||||
|
* What providers are you using. (While your logs include these, scanning through hundred of lines of log isn't my hobby) |
||||
|
* Give me a short step by step of how to reproduce |
||||
|
* What hardware / OS are you using and what are the limits? NAS can be slow and maybe have a different python installed then when you use CP on OSX or Windows for example. |
||||
|
* I will mark issues with the "can't reproduce" tag. Don't go asking me "why closed" if it clearly says the issue in the tag ;) |
||||
|
|
||||
|
**If I don't get enough info, the change of the issue getting closed is a lot bigger ;)** |
@ -1,39 +1,35 @@ |
|||||
from couchpotato.core.helpers.encoding import toUnicode, tryUrlencode |
from couchpotato.core.helpers.encoding import toUnicode |
||||
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 httplib import HTTPSConnection |
import traceback |
||||
|
|
||||
log = CPLog(__name__) |
log = CPLog(__name__) |
||||
|
|
||||
|
|
||||
class Prowl(Notification): |
class Prowl(Notification): |
||||
|
|
||||
|
urls = { |
||||
|
'api': 'https://api.prowlapp.com/publicapi/add' |
||||
|
} |
||||
|
|
||||
def notify(self, message = '', data = {}, listener = None): |
def notify(self, message = '', data = {}, listener = None): |
||||
if self.isDisabled(): return |
if self.isDisabled(): return |
||||
|
|
||||
http_handler = HTTPSConnection('api.prowlapp.com') |
|
||||
|
|
||||
data = { |
data = { |
||||
'apikey': self.conf('api_key'), |
'apikey': self.conf('api_key'), |
||||
'application': self.default_title, |
'application': self.default_title, |
||||
'description': toUnicode(message), |
'description': toUnicode(message), |
||||
'priority': self.conf('priority'), |
'priority': self.conf('priority'), |
||||
} |
} |
||||
|
headers = { |
||||
|
'Content-type': 'application/x-www-form-urlencoded' |
||||
|
} |
||||
|
|
||||
http_handler.request('POST', |
try: |
||||
'/publicapi/add', |
self.urlopen(self.urls['api'], headers = headers, params = data, multipart = True, show_error = False) |
||||
headers = {'Content-type': 'application/x-www-form-urlencoded'}, |
|
||||
body = tryUrlencode(data) |
|
||||
) |
|
||||
response = http_handler.getresponse() |
|
||||
request_status = response.status |
|
||||
|
|
||||
if request_status == 200: |
|
||||
log.info('Prowl notifications sent.') |
log.info('Prowl notifications sent.') |
||||
return True |
return True |
||||
elif request_status == 401: |
except: |
||||
log.error('Prowl auth failed: %s', response.reason) |
log.error('Prowl failed: %s', traceback.format_exc()) |
||||
return False |
|
||||
else: |
return False |
||||
log.error('Prowl notification failed.') |
|
||||
return False |
|
||||
|
@ -1,214 +1,266 @@ |
|||||
Page.Wizard = new Class({ |
Page.Wizard = new Class({ |
||||
|
|
||||
Extends: Page.Settings, |
Extends: Page.Settings, |
||||
|
|
||||
name: 'wizard', |
name: 'wizard', |
||||
has_tab: false, |
has_tab: false, |
||||
wizard_only: true, |
wizard_only: true, |
||||
|
|
||||
headers: { |
headers: { |
||||
'welcome': { |
'welcome': { |
||||
'title': 'Welcome to the new CouchPotato', |
'title': 'Welcome to the new CouchPotato', |
||||
'description': 'To get started, fill in each of the following settings as much as your can. <br />Maybe first start with importing your movies from the previous CouchPotato', |
'description': 'To get started, fill in each of the following settings as much as your can. <br />Maybe first start with importing your movies from the previous CouchPotato', |
||||
'content': new Element('div', { |
'content': new Element('div', { |
||||
'styles': { |
'styles': { |
||||
'margin': '0 0 0 30px' |
'margin': '0 0 0 30px' |
||||
} |
} |
||||
}).adopt( |
}).adopt( |
||||
new Element('div', { |
new Element('div', { |
||||
'html': 'Select the <strong>data.db</strong>. It should be in your CouchPotato root directory.' |
'html': 'Select the <strong>data.db</strong>. It should be in your CouchPotato root directory.' |
||||
}), |
}), |
||||
self.import_iframe = new Element('iframe', { |
self.import_iframe = new Element('iframe', { |
||||
'styles': { |
'styles': { |
||||
'height': 40, |
'height': 40, |
||||
'width': 300, |
'width': 300, |
||||
'border': 0, |
'border': 0, |
||||
'overflow': 'hidden' |
'overflow': 'hidden' |
||||
} |
} |
||||
}) |
}) |
||||
), |
), |
||||
'event': function(){ |
'event': function(){ |
||||
self.import_iframe.set('src', Api.createUrl('v1.import')) |
self.import_iframe.set('src', Api.createUrl('v1.import')) |
||||
} |
} |
||||
}, |
}, |
||||
'general': { |
'general': { |
||||
'title': 'General', |
'title': 'General', |
||||
'description': 'If you want to access CP from outside your local network, you better secure it a bit with a username & password.' |
'description': 'If you want to access CP from outside your local network, you better secure it a bit with a username & password.' |
||||
}, |
}, |
||||
'downloaders': { |
'downloaders': { |
||||
'title': 'What download apps are you using?', |
'title': 'What download apps are you using?', |
||||
'description': 'If you don\'t have any of these listed, you have to use Blackhole. Or drop me a line, maybe I\'ll support your download app.' |
'description': 'CP needs an external download app to work with. Choose one below. For more downloaders check settings after you have filled in the wizard. If your download app isn\'t in the list, use Blackhole.' |
||||
}, |
}, |
||||
'providers': { |
'providers': { |
||||
'title': 'Are you registered at any of these sites?', |
'title': 'Are you registered at any of these sites?', |
||||
'description': 'CP uses these sites to search for movies. A few free are enabled by default, but it\'s always better to have a few more.' |
'description': 'CP uses these sites to search for movies. A few free are enabled by default, but it\'s always better to have a few more. Check settings for the full list of available providers.', |
||||
}, |
'include': ['nzb_providers', 'torrent_providers'] |
||||
'renamer': { |
}, |
||||
'title': 'Move & rename the movies after downloading?', |
'renamer': { |
||||
'description': '' |
'title': 'Move & rename the movies after downloading?', |
||||
}, |
'description': 'The coolest part of CP is that it can move and organize your downloaded movies automagically. Check settings and you can even download trailers, subtitles and other data when it has finished downloading. It\'s awesome!' |
||||
'finish': { |
}, |
||||
'title': 'Finish Up', |
'automation': { |
||||
'description': 'Are you done? Did you fill in everything as much as possible? Yes, ok gogogo!', |
'title': 'Easily add movies to your wanted list!', |
||||
'content': new Element('div').adopt( |
'description': 'You can easily add movies from your favorite movie site, like IMDB, Rotten Tomatoes, Apple Trailers and more. Just install the userscript or drag the bookmarklet to your browsers bookmarks.' + |
||||
new Element('a.button.green', { |
'<br />Once installed, just click the bookmarklet on a movie page and watch the magic happen ;)', |
||||
'text': 'I\'m ready to start the awesomeness, wow this button is big and green!', |
'content': function(){ |
||||
'events': { |
return App.createUserscriptButtons().setStyles({ |
||||
'click': function(e){ |
'background-image': "url('"+Api.createUrl('static/userscript/userscript.png')+"')" |
||||
(e).preventDefault(); |
}) |
||||
Api.request('settings.save', { |
} |
||||
'data': { |
}, |
||||
'section': 'core', |
'finish': { |
||||
'name': 'show_wizard', |
'title': 'Finishing Up', |
||||
'value': 0 |
'description': 'Are you done? Did you fill in everything as much as possible?' + |
||||
}, |
'<br />Be sure to check the settings to see what more CP can do!<br /><br />' + |
||||
'useSpinner': true, |
'<div class="wizard_support">After you\'ve used CP for a while, and you like it (which of course you will), consider supporting CP. Maybe even by writing some code. <br />Or by getting a subscription at <a href="https://usenetserver.com/partners/?a_aid=couchpotato&a_bid=3f357c6f">Usenet Server</a> or <a href="http://www.newshosting.com/partners/?a_aid=couchpotato&a_bid=a0b022df">Newshosting</a>.</div>', |
||||
'spinnerOptions': { |
'content': new Element('div').adopt( |
||||
'target': self.el |
new Element('a.button.green', { |
||||
}, |
'styles': { |
||||
'onComplete': function(){ |
'margin-top': 20 |
||||
window.location = App.createUrl(); |
}, |
||||
} |
'text': 'I\'m ready to start the awesomeness, wow this button is big and green!', |
||||
}); |
'events': { |
||||
} |
'click': function(e){ |
||||
} |
(e).preventDefault(); |
||||
}) |
Api.request('settings.save', { |
||||
) |
'data': { |
||||
} |
'section': 'core', |
||||
}, |
'name': 'show_wizard', |
||||
groups: ['welcome', 'general', 'downloaders', 'searcher', 'providers', 'renamer', 'finish'], |
'value': 0 |
||||
|
}, |
||||
open: function(action, params){ |
'useSpinner': true, |
||||
var self = this; |
'spinnerOptions': { |
||||
|
'target': self.el |
||||
if(!self.initialized){ |
}, |
||||
App.fireEvent('unload'); |
'onComplete': function(){ |
||||
App.getBlock('header').hide(); |
window.location = App.createUrl(); |
||||
|
} |
||||
self.parent(action, params); |
}); |
||||
|
} |
||||
self.addEvent('create', function(){ |
} |
||||
self.order(); |
}) |
||||
}); |
) |
||||
|
} |
||||
self.initialized = true; |
}, |
||||
|
groups: ['welcome', 'general', 'downloaders', 'searcher', 'providers', 'renamer', 'automation', 'finish'], |
||||
self.scroll = new Fx.Scroll(document.body, { |
|
||||
'transition': 'quint:in:out' |
open: function(action, params){ |
||||
}); |
var self = this; |
||||
} |
|
||||
else |
if(!self.initialized){ |
||||
(function(){ |
App.fireEvent('unload'); |
||||
var sc = self.el.getElement('.wgroup_'+action); |
App.getBlock('header').hide(); |
||||
self.scroll.start(0, sc.getCoordinates().top-80); |
|
||||
}).delay(1) |
self.parent(action, params); |
||||
}, |
|
||||
|
self.addEvent('create', function(){ |
||||
order: function(){ |
self.order(); |
||||
var self = this; |
}); |
||||
|
|
||||
var form = self.el.getElement('.uniForm'); |
self.initialized = true; |
||||
var tabs = self.el.getElement('.tabs'); |
|
||||
|
self.scroll = new Fx.Scroll(document.body, { |
||||
self.groups.each(function(group){ |
'transition': 'quint:in:out' |
||||
if(self.headers[group]){ |
}); |
||||
group_container = new Element('.wgroup_'+group, { |
} |
||||
'styles': { |
else |
||||
'opacity': 0.2 |
(function(){ |
||||
}, |
var sc = self.el.getElement('.wgroup_'+action); |
||||
'tween': { |
self.scroll.start(0, sc.getCoordinates().top-80); |
||||
'duration': 350 |
}).delay(1) |
||||
} |
}, |
||||
}); |
|
||||
group_container.adopt( |
order: function(){ |
||||
new Element('h1', { |
var self = this; |
||||
'text': self.headers[group].title |
|
||||
}), |
var form = self.el.getElement('.uniForm'); |
||||
self.headers[group].description ? new Element('span.description', { |
var tabs = self.el.getElement('.tabs'); |
||||
'html': self.headers[group].description |
|
||||
}) : null, |
self.groups.each(function(group, nr){ |
||||
self.headers[group].content ? self.headers[group].content : null |
|
||||
).inject(form); |
if(self.headers[group]){ |
||||
} |
group_container = new Element('.wgroup_'+group, { |
||||
|
'styles': { |
||||
var tab_navigation = tabs.getElement('.t_'+group); |
'opacity': 0.2 |
||||
if(tab_navigation && group_container){ |
}, |
||||
tab_navigation.inject(tabs); // Tab navigation
|
'tween': { |
||||
self.el.getElement('.tab_'+group).inject(group_container); // Tab content
|
'duration': 350 |
||||
if(self.headers[group]){ |
} |
||||
var a = tab_navigation.getElement('a'); |
}); |
||||
a.set('text', (self.headers[group].label || group).capitalize()); |
|
||||
var url_split = a.get('href').split('wizard')[1].split('/'); |
if(self.headers[group].include){ |
||||
if(url_split.length > 3) |
self.headers[group].include.each(function(inc){ |
||||
a.set('href', a.get('href').replace(url_split[url_split.length-3]+'/', '')); |
group_container.addClass('wgroup_'+inc); |
||||
|
}) |
||||
} |
} |
||||
} |
|
||||
else { |
var content = self.headers[group].content |
||||
new Element('li.t_'+group).adopt( |
group_container.adopt( |
||||
new Element('a', { |
new Element('h1', { |
||||
'href': App.createUrl('wizard/'+group), |
'text': self.headers[group].title |
||||
'text': (self.headers[group].label || group).capitalize() |
}), |
||||
}) |
self.headers[group].description ? new Element('span.description', { |
||||
).inject(tabs); |
'html': self.headers[group].description |
||||
} |
}) : null, |
||||
|
content ? (typeOf(content) == 'function' ? content() : content) : null |
||||
if(self.headers[group] && self.headers[group].event) |
).inject(form); |
||||
self.headers[group].event.call() |
} |
||||
}); |
|
||||
|
var tab_navigation = tabs.getElement('.t_'+group); |
||||
// Remove toggle
|
|
||||
self.el.getElement('.advanced_toggle').destroy(); |
if(!tab_navigation && self.headers[group] && self.headers[group].include){ |
||||
|
tab_navigation = [] |
||||
// Hide retention
|
self.headers[group].include.each(function(inc){ |
||||
self.el.getElement('.tab_searcher').hide(); |
tab_navigation.include(tabs.getElement('.t_'+inc)); |
||||
self.el.getElement('.t_searcher').hide(); |
}) |
||||
|
} |
||||
// Add pointer
|
|
||||
new Element('.tab_wrapper').wraps(tabs).adopt( |
if(tab_navigation && group_container){ |
||||
self.pointer = new Element('.pointer', { |
tabs.adopt(tab_navigation); // Tab navigation
|
||||
'tween': { |
|
||||
'transition': 'quint:in:out' |
if(self.headers[group] && self.headers[group].include){ |
||||
} |
|
||||
}) |
self.headers[group].include.each(function(inc){ |
||||
); |
self.el.getElement('.tab_'+inc).inject(group_container); |
||||
|
}) |
||||
// Add nav
|
|
||||
var minimum = self.el.getSize().y-window.getSize().y; |
new Element('li.t_'+group).adopt( |
||||
self.groups.each(function(group, nr){ |
new Element('a', { |
||||
|
'href': App.createUrl('wizard/'+group), |
||||
var g = self.el.getElement('.wgroup_'+group); |
'text': (self.headers[group].label || group).capitalize() |
||||
if(!g || !g.isVisible()) return; |
}) |
||||
var t = self.el.getElement('.t_'+group); |
).inject(tabs); |
||||
if(!t) return; |
|
||||
|
} |
||||
var func = function(){ |
else |
||||
var ct = t.getCoordinates(); |
self.el.getElement('.tab_'+group).inject(group_container); // Tab content
|
||||
self.pointer.tween('left', ct.left+(ct.width/2)-(self.pointer.getWidth()/2)); |
|
||||
g.tween('opacity', 1); |
if(tab_navigation.getElement && self.headers[group]){ |
||||
} |
var a = tab_navigation.getElement('a'); |
||||
|
a.set('text', (self.headers[group].label || group).capitalize()); |
||||
if(nr == 0) |
var url_split = a.get('href').split('wizard')[1].split('/'); |
||||
func(); |
if(url_split.length > 3) |
||||
|
a.set('href', a.get('href').replace(url_split[url_split.length-3]+'/', '')); |
||||
|
|
||||
var ss = new ScrollSpy( { |
} |
||||
min: function(){ |
} |
||||
var c = g.getCoordinates(); |
else { |
||||
var top = c.top-(window.getSize().y/2); |
new Element('li.t_'+group).adopt( |
||||
return top > minimum ? minimum : top |
new Element('a', { |
||||
}, |
'href': App.createUrl('wizard/'+group), |
||||
max: function(){ |
'text': (self.headers[group].label || group).capitalize() |
||||
var c = g.getCoordinates(); |
}) |
||||
return c.top+(c.height/2) |
).inject(tabs); |
||||
}, |
} |
||||
onEnter: func, |
|
||||
onLeave: function(){ |
if(self.headers[group] && self.headers[group].event) |
||||
g.tween('opacity', 0.2) |
self.headers[group].event.call() |
||||
} |
}); |
||||
}); |
|
||||
}); |
// Remove toggle
|
||||
|
self.el.getElement('.advanced_toggle').destroy(); |
||||
} |
|
||||
|
// Hide retention
|
||||
|
self.el.getElement('.tab_searcher').hide(); |
||||
|
self.el.getElement('.t_searcher').hide(); |
||||
|
self.el.getElement('.t_nzb_providers').hide(); |
||||
|
self.el.getElement('.t_torrent_providers').hide(); |
||||
|
|
||||
|
// Add pointer
|
||||
|
new Element('.tab_wrapper').wraps(tabs).adopt( |
||||
|
self.pointer = new Element('.pointer', { |
||||
|
'tween': { |
||||
|
'transition': 'quint:in:out' |
||||
|
} |
||||
|
}) |
||||
|
); |
||||
|
|
||||
|
// Add nav
|
||||
|
var minimum = self.el.getSize().y-window.getSize().y; |
||||
|
self.groups.each(function(group, nr){ |
||||
|
|
||||
|
var g = self.el.getElement('.wgroup_'+group); |
||||
|
if(!g || !g.isVisible()) return; |
||||
|
var t = self.el.getElement('.t_'+group); |
||||
|
if(!t) return; |
||||
|
|
||||
|
var func = function(){ |
||||
|
var ct = t.getCoordinates(); |
||||
|
self.pointer.tween('left', ct.left+(ct.width/2)-(self.pointer.getWidth()/2)); |
||||
|
g.tween('opacity', 1); |
||||
|
} |
||||
|
|
||||
|
if(nr == 0) |
||||
|
func(); |
||||
|
|
||||
|
|
||||
|
var ss = new ScrollSpy( { |
||||
|
min: function(){ |
||||
|
var c = g.getCoordinates(); |
||||
|
var top = c.top-(window.getSize().y/2); |
||||
|
return top > minimum ? minimum : top |
||||
|
}, |
||||
|
max: function(){ |
||||
|
var c = g.getCoordinates(); |
||||
|
return c.top+(c.height/2) |
||||
|
}, |
||||
|
onEnter: func, |
||||
|
onLeave: function(){ |
||||
|
g.tween('opacity', 0.2) |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
} |
||||
|
|
||||
}); |
}); |
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 143 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 573 B |
Before Width: | Height: | Size: 451 B After Width: | Height: | Size: 352 B |
Before Width: | Height: | Size: 228 B After Width: | Height: | Size: 220 B |
Before Width: | Height: | Size: 502 B After Width: | Height: | Size: 306 B |
Before Width: | Height: | Size: 624 B After Width: | Height: | Size: 511 B |
Before Width: | Height: | Size: 840 B After Width: | Height: | Size: 763 B |
Before Width: | Height: | Size: 757 B After Width: | Height: | Size: 690 B |
Before Width: | Height: | Size: 159 B After Width: | Height: | Size: 152 B |
Before Width: | Height: | Size: 778 B After Width: | Height: | Size: 724 B |
Before Width: | Height: | Size: 283 B After Width: | Height: | Size: 239 B |
Before Width: | Height: | Size: 674 B After Width: | Height: | Size: 568 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 596 B After Width: | Height: | Size: 435 B |
Before Width: | Height: | Size: 587 B After Width: | Height: | Size: 585 B |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 223 B After Width: | Height: | Size: 151 B |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.8 KiB |