Merge branch 'refs/heads/develop' into desktop
Conflicts: couchpotato/core/_base/updater/main.py
This commit is contained in:
commit
59590b3ac9
16 files changed
+85
-29
No files matched your search
@@ -32,7 +32,7 @@ class Updater(Plugin):
|
|||||||
self.updater = SourceUpdater()
|
self.updater = SourceUpdater()
|
||||||
|
|
||||||
fireEvent('schedule.interval', 'updater.check', self.autoUpdate, hours = 6)
|
fireEvent('schedule.interval', 'updater.check', self.autoUpdate, hours = 6)
|
||||||
addEvent('app.load', self.check)
|
addEvent('app.load', self.autoUpdate)
|
||||||
addEvent('updater.info', self.info)
|
addEvent('updater.info', self.info)
|
||||||
|
|
||||||
addApiView('updater.info', self.getInfo, docs = {
|
addApiView('updater.info', self.getInfo, docs = {
|
||||||
@@ -208,7 +208,7 @@ class GitUpdater(BaseUpdater):
|
|||||||
def check(self):
|
def check(self):
|
||||||
|
|
||||||
if self.update_version:
|
if self.update_version:
|
||||||
return
|
return True
|
||||||
|
|
||||||
log.info('Checking for new version on github for %s', self.repo_name)
|
log.info('Checking for new version on github for %s', self.repo_name)
|
||||||
if not Env.get('dev'):
|
if not Env.get('dev'):
|
||||||
|
|||||||
@@ -62,6 +62,8 @@ var UpdaterBase = new Class({
|
|||||||
createMessage: function(data){
|
createMessage: function(data){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
if(self.message) return;
|
||||||
|
|
||||||
var changelog = 'https://github.com/'+data.repo_name+'/compare/'+data.version.hash+'...'+data.branch;
|
var changelog = 'https://github.com/'+data.repo_name+'/compare/'+data.version.hash+'...'+data.branch;
|
||||||
if(data.update_version.changelog)
|
if(data.update_version.changelog)
|
||||||
changelog = data.update_version.changelog + '#' + data.version.hash+'...'+data.update_version.hash
|
changelog = data.update_version.changelog + '#' + data.version.hash+'...'+data.update_version.hash
|
||||||
|
|||||||
@@ -95,7 +95,10 @@ class Plugin(object):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
# http request
|
# http request
|
||||||
def urlopen(self, url, timeout = 30, params = {}, headers = {}, opener = None, multipart = False, show_error = True):
|
def urlopen(self, url, timeout = 30, params = None, headers = None, opener = None, multipart = False, show_error = True):
|
||||||
|
|
||||||
|
if not headers: headers = {}
|
||||||
|
if not params: params = {}
|
||||||
|
|
||||||
# Fill in some headers
|
# Fill in some headers
|
||||||
if not headers.get('Referer'):
|
if not headers.get('Referer'):
|
||||||
|
|||||||
@@ -73,6 +73,13 @@ class Manage(Plugin):
|
|||||||
for done_movie in done_movies:
|
for done_movie in done_movies:
|
||||||
if done_movie['library']['identifier'] not in added_identifiers:
|
if done_movie['library']['identifier'] not in added_identifiers:
|
||||||
fireEvent('movie.delete', movie_id = done_movie['id'], delete_from = 'all')
|
fireEvent('movie.delete', movie_id = done_movie['id'], delete_from = 'all')
|
||||||
|
else:
|
||||||
|
for release in done_movie.get('releases', []):
|
||||||
|
for release_file in release.get('files', []):
|
||||||
|
# Remove release not available anymore
|
||||||
|
if not os.path.isfile(release_file['path']):
|
||||||
|
fireEvent('release.clean', release['id'])
|
||||||
|
break
|
||||||
|
|
||||||
Env.prop('manage.last_update', time.time())
|
Env.prop('manage.last_update', time.time())
|
||||||
|
|
||||||
|
|||||||
@@ -357,7 +357,7 @@ var ReleaseAction = new Class({
|
|||||||
Array.each(self.movie.data.releases, function(release){
|
Array.each(self.movie.data.releases, function(release){
|
||||||
|
|
||||||
var status = Status.get(release.status_id),
|
var status = Status.get(release.status_id),
|
||||||
quality = Quality.getProfile(release.quality_id),
|
quality = Quality.getProfile(release.quality_id) || {},
|
||||||
info = release.info;
|
info = release.info;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -365,7 +365,8 @@ var ReleaseAction = new Class({
|
|||||||
} catch(e){}
|
} catch(e){}
|
||||||
|
|
||||||
new Element('div', {
|
new Element('div', {
|
||||||
'class': 'item '+status.identifier
|
'class': 'item '+status.identifier,
|
||||||
|
'id': 'release_'+release.id
|
||||||
}).adopt(
|
}).adopt(
|
||||||
new Element('span.name', {'text': self.get(release, 'name'), 'title': self.get(release, 'name')}),
|
new Element('span.name', {'text': self.get(release, 'name'), 'title': self.get(release, 'name')}),
|
||||||
new Element('span.status', {'text': status.identifier, 'class': 'release_status '+status.identifier}),
|
new Element('span.status', {'text': status.identifier, 'class': 'release_status '+status.identifier}),
|
||||||
@@ -382,7 +383,8 @@ var ReleaseAction = new Class({
|
|||||||
'events': {
|
'events': {
|
||||||
'click': function(e){
|
'click': function(e){
|
||||||
(e).preventDefault();
|
(e).preventDefault();
|
||||||
self.download(release);
|
if(!this.hasClass('completed'))
|
||||||
|
self.download(release);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
@@ -414,9 +416,21 @@ var ReleaseAction = new Class({
|
|||||||
download: function(release){
|
download: function(release){
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
var release_el = self.release_container.getElement('#release_'+release.id),
|
||||||
|
icon = release_el.getElement('.download.icon');
|
||||||
|
|
||||||
|
icon.addClass('spinner');
|
||||||
|
|
||||||
Api.request('release.download', {
|
Api.request('release.download', {
|
||||||
'data': {
|
'data': {
|
||||||
'id': release.id
|
'id': release.id
|
||||||
|
},
|
||||||
|
'onComplete': function(json){
|
||||||
|
icon.removeClass('spinner')
|
||||||
|
if(json.success)
|
||||||
|
icon.addClass('completed');
|
||||||
|
else
|
||||||
|
icon.addClass('attention').set('title', 'Something went wrong when downloading, please check logs.');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -456,7 +470,7 @@ var TrailerAction = new Class({
|
|||||||
|
|
||||||
var data_url = 'http://gdata.youtube.com/feeds/videos?vq="{title}" {year} trailer&max-results=1&alt=json-in-script&orderby=relevance&sortorder=descending&format=5&fmt=18'
|
var data_url = 'http://gdata.youtube.com/feeds/videos?vq="{title}" {year} trailer&max-results=1&alt=json-in-script&orderby=relevance&sortorder=descending&format=5&fmt=18'
|
||||||
var url = data_url.substitute({
|
var url = data_url.substitute({
|
||||||
'title': self.movie.getTitle(),
|
'title': encodeURI(self.movie.getTitle()),
|
||||||
'year': self.movie.get('year'),
|
'year': self.movie.get('year'),
|
||||||
'offset': offset || 1
|
'offset': offset || 1
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ from couchpotato.core.plugins.base import Plugin
|
|||||||
from couchpotato.core.plugins.scanner.main import Scanner
|
from couchpotato.core.plugins.scanner.main import Scanner
|
||||||
from couchpotato.core.settings.model import File, Release as Relea, Movie
|
from couchpotato.core.settings.model import File, Release as Relea, Movie
|
||||||
from sqlalchemy.sql.expression import and_, or_
|
from sqlalchemy.sql.expression import and_, or_
|
||||||
|
import os
|
||||||
|
|
||||||
log = CPLog(__name__)
|
log = CPLog(__name__)
|
||||||
|
|
||||||
@@ -22,7 +23,7 @@ class Release(Plugin):
|
|||||||
'id': {'type': 'id', 'desc': 'ID of the release object in release-table'}
|
'id': {'type': 'id', 'desc': 'ID of the release object in release-table'}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
addApiView('release.delete', self.delete, docs = {
|
addApiView('release.delete', self.deleteView, docs = {
|
||||||
'desc': 'Delete releases',
|
'desc': 'Delete releases',
|
||||||
'params': {
|
'params': {
|
||||||
'id': {'type': 'id', 'desc': 'ID of the release object in release-table'}
|
'id': {'type': 'id', 'desc': 'ID of the release object in release-table'}
|
||||||
@@ -35,6 +36,9 @@ class Release(Plugin):
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
addEvent('release.delete', self.delete)
|
||||||
|
addEvent('release.clean', self.clean)
|
||||||
|
|
||||||
def add(self, group):
|
def add(self, group):
|
||||||
db = get_session()
|
db = get_session()
|
||||||
|
|
||||||
@@ -99,20 +103,41 @@ class Release(Plugin):
|
|||||||
# Check database and update/insert if necessary
|
# Check database and update/insert if necessary
|
||||||
return fireEvent('file.add', path = filepath, part = fireEvent('scanner.partnumber', file, single = True), type_tuple = Scanner.file_types.get(type), properties = properties, single = True)
|
return fireEvent('file.add', path = filepath, part = fireEvent('scanner.partnumber', file, single = True), type_tuple = Scanner.file_types.get(type), properties = properties, single = True)
|
||||||
|
|
||||||
def delete(self):
|
def deleteView(self):
|
||||||
|
|
||||||
|
release_id = getParam('id')
|
||||||
|
|
||||||
|
#db.close()
|
||||||
|
return jsonified({
|
||||||
|
'success': self.delete(release_id)
|
||||||
|
})
|
||||||
|
|
||||||
|
def delete(self, id):
|
||||||
|
|
||||||
db = get_session()
|
db = get_session()
|
||||||
id = getParam('id')
|
|
||||||
|
|
||||||
rel = db.query(Relea).filter_by(id = id).first()
|
rel = db.query(Relea).filter_by(id = id).first()
|
||||||
if rel:
|
if rel:
|
||||||
rel.delete()
|
rel.delete()
|
||||||
db.commit()
|
db.commit()
|
||||||
|
return True
|
||||||
|
|
||||||
#db.close()
|
return False
|
||||||
return jsonified({
|
|
||||||
'success': True
|
def clean(self, id):
|
||||||
})
|
|
||||||
|
db = get_session()
|
||||||
|
|
||||||
|
rel = db.query(Relea).filter_by(id = id).first()
|
||||||
|
if rel:
|
||||||
|
for release_file in rel.files:
|
||||||
|
if not os.path.isfile(release_file.path):
|
||||||
|
db.delete(release_file)
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
def ignore(self):
|
def ignore(self):
|
||||||
|
|
||||||
@@ -146,16 +171,16 @@ class Release(Plugin):
|
|||||||
provider = fireEvent('provider.belongs_to', item['url'], provider = item.get('provider'), single = True)
|
provider = fireEvent('provider.belongs_to', item['url'], provider = item.get('provider'), single = True)
|
||||||
item['download'] = provider.download
|
item['download'] = provider.download
|
||||||
|
|
||||||
fireEvent('searcher.download', data = item, movie = rel.movie.to_dict({
|
success = fireEvent('searcher.download', data = item, movie = rel.movie.to_dict({
|
||||||
'profile': {'types': {'quality': {}}},
|
'profile': {'types': {'quality': {}}},
|
||||||
'releases': {'status': {}, 'quality': {}},
|
'releases': {'status': {}, 'quality': {}},
|
||||||
'library': {'titles': {}, 'files':{}},
|
'library': {'titles': {}, 'files':{}},
|
||||||
'files': {}
|
'files': {}
|
||||||
}), manual = True)
|
}), manual = True, single = True)
|
||||||
|
|
||||||
#db.close()
|
#db.close()
|
||||||
return jsonified({
|
return jsonified({
|
||||||
'success': True
|
'success': success
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
log.error('Couldn\'t find release with id: %s', id)
|
log.error('Couldn\'t find release with id: %s', id)
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ config = [{
|
|||||||
'advanced': True,
|
'advanced': True,
|
||||||
'name': 'separator',
|
'name': 'separator',
|
||||||
'label': 'Separator',
|
'label': 'Separator',
|
||||||
'description': 'Replace all the spaces with a character. Example: ".", "-". Leave empty to use spaces.',
|
'description': 'Replace all the spaces with a character. Example: ".", "-" (without quotes). Leave empty to use spaces.',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'advanced': True,
|
'advanced': True,
|
||||||
|
|||||||
@@ -165,7 +165,6 @@ class Renamer(Plugin):
|
|||||||
# Group filename without cd extension
|
# Group filename without cd extension
|
||||||
replacements['cd'] = ''
|
replacements['cd'] = ''
|
||||||
replacements['cd_nr'] = ''
|
replacements['cd_nr'] = ''
|
||||||
group['filename'] = self.doReplace(file_name, replacements)[:-(len(getExt(final_file_name)) + 1)]
|
|
||||||
|
|
||||||
# Meta naming
|
# Meta naming
|
||||||
if file_type is 'trailer':
|
if file_type is 'trailer':
|
||||||
@@ -238,6 +237,7 @@ class Renamer(Plugin):
|
|||||||
)
|
)
|
||||||
rename_files = mergeDicts(rename_files, rename_extras)
|
rename_files = mergeDicts(rename_files, rename_extras)
|
||||||
|
|
||||||
|
group['filename'] = self.doReplace(file_name, replacements)[:-(len(getExt(final_file_name)) + 1)]
|
||||||
group['destination_dir'] = os.path.join(destination, final_folder_name)
|
group['destination_dir'] = os.path.join(destination, final_folder_name)
|
||||||
|
|
||||||
if multiple:
|
if multiple:
|
||||||
|
|||||||
@@ -29,9 +29,6 @@ class Searcher(Plugin):
|
|||||||
# Schedule cronjob
|
# Schedule cronjob
|
||||||
fireEvent('schedule.cron', 'searcher.all', self.all_movies, day = self.conf('cron_day'), hour = self.conf('cron_hour'), minute = self.conf('cron_minute'))
|
fireEvent('schedule.cron', 'searcher.all', self.all_movies, day = self.conf('cron_day'), hour = self.conf('cron_hour'), minute = self.conf('cron_minute'))
|
||||||
|
|
||||||
|
|
||||||
addEvent('app.load', self.all_movies)
|
|
||||||
|
|
||||||
def all_movies(self):
|
def all_movies(self):
|
||||||
|
|
||||||
if self.in_progress:
|
if self.in_progress:
|
||||||
|
|||||||
@@ -54,11 +54,12 @@ class Subtitle(Plugin):
|
|||||||
for lang in self.getLanguages():
|
for lang in self.getLanguages():
|
||||||
if lang not in available_languages:
|
if lang not in available_languages:
|
||||||
download = subliminal.download_subtitles(files, multi = True, force = False, languages = [lang], services = self.services, cache_dir = Env.get('cache_dir'))
|
download = subliminal.download_subtitles(files, multi = True, force = False, languages = [lang], services = self.services, cache_dir = Env.get('cache_dir'))
|
||||||
downloaded.extend(download)
|
for subtitle in download:
|
||||||
|
downloaded.extend(download[subtitle])
|
||||||
|
|
||||||
for d_sub in downloaded:
|
for d_sub in downloaded:
|
||||||
group['files']['subtitle'].add(d_sub.path)
|
group['files']['subtitle'].add(d_sub.path)
|
||||||
group['subtitle_language'][d_sub.path] = [d_sub.language]
|
group['subtitle_language'][d_sub.path] = [d_sub.language.alpha2]
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
from couchpotato.core.event import fireEvent
|
from couchpotato.core.event import fireEvent
|
||||||
from couchpotato.core.helpers.variable import tryInt, getTitle
|
from couchpotato.core.helpers.variable import tryInt
|
||||||
from couchpotato.core.logger import CPLog
|
from couchpotato.core.logger import CPLog
|
||||||
from couchpotato.core.providers.torrent.base import TorrentProvider
|
from couchpotato.core.providers.torrent.base import TorrentProvider
|
||||||
import StringIO
|
import StringIO
|
||||||
@@ -16,7 +16,7 @@ class KickAssTorrents(TorrentProvider):
|
|||||||
urls = {
|
urls = {
|
||||||
'test': 'http://www.kat.ph/',
|
'test': 'http://www.kat.ph/',
|
||||||
'detail': 'http://www.kat.ph/%s-t%s.html',
|
'detail': 'http://www.kat.ph/%s-t%s.html',
|
||||||
'search': 'http://www.kat.ph/%s-i%s/',
|
'search': 'http://www.kat.ph/i%s/',
|
||||||
'download': 'http://torcache.net/',
|
'download': 'http://torcache.net/',
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,6 +30,7 @@ class KickAssTorrents(TorrentProvider):
|
|||||||
]
|
]
|
||||||
|
|
||||||
http_time_between_calls = 1 #seconds
|
http_time_between_calls = 1 #seconds
|
||||||
|
cat_backup_id = None
|
||||||
|
|
||||||
def search(self, movie, quality):
|
def search(self, movie, quality):
|
||||||
|
|
||||||
@@ -38,7 +39,7 @@ class KickAssTorrents(TorrentProvider):
|
|||||||
return results
|
return results
|
||||||
|
|
||||||
cache_key = 'kickasstorrents.%s.%s' % (movie['library']['identifier'], quality.get('identifier'))
|
cache_key = 'kickasstorrents.%s.%s' % (movie['library']['identifier'], quality.get('identifier'))
|
||||||
data = self.getCache(cache_key, self.urls['search'] % (getTitle(movie['library']), movie['library']['identifier'].replace('tt', '')))
|
data = self.getCache(cache_key, self.urls['search'] % (movie['library']['identifier'].replace('tt', '')))
|
||||||
if data:
|
if data:
|
||||||
|
|
||||||
cat_ids = self.getCatId(quality['identifier'])
|
cat_ids = self.getCatId(quality['identifier'])
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ class TorrentLeech(TorrentProvider):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
result_table = html.find('table', attrs = {'id' : 'torrenttable'})
|
result_table = html.find('table', attrs = {'id' : 'torrenttable'})
|
||||||
|
if not result_table:
|
||||||
|
return results
|
||||||
|
|
||||||
entries = result_table.find_all('tr')
|
entries = result_table.find_all('tr')
|
||||||
|
|
||||||
for result in entries[1:]:
|
for result in entries[1:]:
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
@@ -244,6 +244,7 @@ window.addEvent('domready', function(){
|
|||||||
MovieActions.Done = {
|
MovieActions.Done = {
|
||||||
'IMDB': IMDBAction
|
'IMDB': IMDBAction
|
||||||
,'Edit': MovieActions.Wanted.Edit
|
,'Edit': MovieActions.Wanted.Edit
|
||||||
|
,'Trailer': TrailerAction
|
||||||
,'Files': new Class({
|
,'Files': new Class({
|
||||||
|
|
||||||
Extends: MovieAction,
|
Extends: MovieAction,
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ body > .spinner, .mask{
|
|||||||
.icon.delete { background-image: url('../images/icon.delete.png'); }
|
.icon.delete { background-image: url('../images/icon.delete.png'); }
|
||||||
.icon.download { background-image: url('../images/icon.download.png'); }
|
.icon.download { background-image: url('../images/icon.download.png'); }
|
||||||
.icon.edit { background-image: url('../images/icon.edit.png'); }
|
.icon.edit { background-image: url('../images/icon.edit.png'); }
|
||||||
.icon.check { background-image: url('../images/icon.check.png'); }
|
.icon.completed { background-image: url('../images/icon.check.png'); }
|
||||||
.icon.folder { background-image: url('../images/icon.folder.png'); }
|
.icon.folder { background-image: url('../images/icon.folder.png'); }
|
||||||
.icon.imdb { background-image: url('../images/icon.imdb.png'); }
|
.icon.imdb { background-image: url('../images/icon.imdb.png'); }
|
||||||
.icon.refresh { background-image: url('../images/icon.refresh.png'); }
|
.icon.refresh { background-image: url('../images/icon.refresh.png'); }
|
||||||
@@ -155,6 +155,8 @@ body > .spinner, .mask{
|
|||||||
.icon.files { background-image: url('../images/icon.files.png'); }
|
.icon.files { background-image: url('../images/icon.files.png'); }
|
||||||
.icon.info { background-image: url('../images/icon.info.png'); }
|
.icon.info { background-image: url('../images/icon.info.png'); }
|
||||||
.icon.trailer { background-image: url('../images/icon.trailer.png'); }
|
.icon.trailer { background-image: url('../images/icon.trailer.png'); }
|
||||||
|
.icon.spinner { background-image: url('../images/icon.spinner.gif'); }
|
||||||
|
.icon.attention { background-image: url('../images/icon.attention.png'); }
|
||||||
|
|
||||||
/*** Navigation ***/
|
/*** Navigation ***/
|
||||||
.header {
|
.header {
|
||||||
@@ -313,7 +315,7 @@ body > .spinner, .mask{
|
|||||||
.header .message.update {
|
.header .message.update {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: -100px;
|
top: -70px;
|
||||||
padding: 2px 0;
|
padding: 2px 0;
|
||||||
background: #ff6134;
|
background: #ff6134;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
|||||||
Reference in new issue
Block a user