Merge branch 'refs/heads/develop' into desktop
Conflicts: couchpotato/core/_base/updater/main.py
This commit is contained in:
@@ -32,7 +32,7 @@ class Updater(Plugin):
|
||||
self.updater = SourceUpdater()
|
||||
|
||||
fireEvent('schedule.interval', 'updater.check', self.autoUpdate, hours = 6)
|
||||
addEvent('app.load', self.check)
|
||||
addEvent('app.load', self.autoUpdate)
|
||||
addEvent('updater.info', self.info)
|
||||
|
||||
addApiView('updater.info', self.getInfo, docs = {
|
||||
@@ -208,7 +208,7 @@ class GitUpdater(BaseUpdater):
|
||||
def check(self):
|
||||
|
||||
if self.update_version:
|
||||
return
|
||||
return True
|
||||
|
||||
log.info('Checking for new version on github for %s', self.repo_name)
|
||||
if not Env.get('dev'):
|
||||
|
||||
@@ -62,6 +62,8 @@ var UpdaterBase = new Class({
|
||||
createMessage: function(data){
|
||||
var self = this;
|
||||
|
||||
if(self.message) return;
|
||||
|
||||
var changelog = 'https://github.com/'+data.repo_name+'/compare/'+data.version.hash+'...'+data.branch;
|
||||
if(data.update_version.changelog)
|
||||
changelog = data.update_version.changelog + '#' + data.version.hash+'...'+data.update_version.hash
|
||||
|
||||
@@ -95,7 +95,10 @@ class Plugin(object):
|
||||
return False
|
||||
|
||||
# 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
|
||||
if not headers.get('Referer'):
|
||||
|
||||
@@ -73,6 +73,13 @@ class Manage(Plugin):
|
||||
for done_movie in done_movies:
|
||||
if done_movie['library']['identifier'] not in added_identifiers:
|
||||
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())
|
||||
|
||||
|
||||
@@ -357,7 +357,7 @@ var ReleaseAction = new Class({
|
||||
Array.each(self.movie.data.releases, function(release){
|
||||
|
||||
var status = Status.get(release.status_id),
|
||||
quality = Quality.getProfile(release.quality_id),
|
||||
quality = Quality.getProfile(release.quality_id) || {},
|
||||
info = release.info;
|
||||
|
||||
try {
|
||||
@@ -365,7 +365,8 @@ var ReleaseAction = new Class({
|
||||
} catch(e){}
|
||||
|
||||
new Element('div', {
|
||||
'class': 'item '+status.identifier
|
||||
'class': 'item '+status.identifier,
|
||||
'id': 'release_'+release.id
|
||||
}).adopt(
|
||||
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}),
|
||||
@@ -382,7 +383,8 @@ var ReleaseAction = new Class({
|
||||
'events': {
|
||||
'click': function(e){
|
||||
(e).preventDefault();
|
||||
self.download(release);
|
||||
if(!this.hasClass('completed'))
|
||||
self.download(release);
|
||||
}
|
||||
}
|
||||
}),
|
||||
@@ -414,9 +416,21 @@ var ReleaseAction = new Class({
|
||||
download: function(release){
|
||||
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', {
|
||||
'data': {
|
||||
'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 url = data_url.substitute({
|
||||
'title': self.movie.getTitle(),
|
||||
'title': encodeURI(self.movie.getTitle()),
|
||||
'year': self.movie.get('year'),
|
||||
'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.settings.model import File, Release as Relea, Movie
|
||||
from sqlalchemy.sql.expression import and_, or_
|
||||
import os
|
||||
|
||||
log = CPLog(__name__)
|
||||
|
||||
@@ -22,7 +23,7 @@ class Release(Plugin):
|
||||
'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',
|
||||
'params': {
|
||||
'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):
|
||||
db = get_session()
|
||||
|
||||
@@ -99,20 +103,41 @@ class Release(Plugin):
|
||||
# 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)
|
||||
|
||||
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()
|
||||
id = getParam('id')
|
||||
|
||||
rel = db.query(Relea).filter_by(id = id).first()
|
||||
if rel:
|
||||
rel.delete()
|
||||
db.commit()
|
||||
return True
|
||||
|
||||
#db.close()
|
||||
return jsonified({
|
||||
'success': True
|
||||
})
|
||||
return False
|
||||
|
||||
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):
|
||||
|
||||
@@ -146,16 +171,16 @@ class Release(Plugin):
|
||||
provider = fireEvent('provider.belongs_to', item['url'], provider = item.get('provider'), single = True)
|
||||
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': {}}},
|
||||
'releases': {'status': {}, 'quality': {}},
|
||||
'library': {'titles': {}, 'files':{}},
|
||||
'files': {}
|
||||
}), manual = True)
|
||||
}), manual = True, single = True)
|
||||
|
||||
#db.close()
|
||||
return jsonified({
|
||||
'success': True
|
||||
'success': success
|
||||
})
|
||||
else:
|
||||
log.error('Couldn\'t find release with id: %s', id)
|
||||
|
||||
@@ -84,7 +84,7 @@ config = [{
|
||||
'advanced': True,
|
||||
'name': '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,
|
||||
|
||||
@@ -165,7 +165,6 @@ class Renamer(Plugin):
|
||||
# Group filename without cd extension
|
||||
replacements['cd'] = ''
|
||||
replacements['cd_nr'] = ''
|
||||
group['filename'] = self.doReplace(file_name, replacements)[:-(len(getExt(final_file_name)) + 1)]
|
||||
|
||||
# Meta naming
|
||||
if file_type is 'trailer':
|
||||
@@ -238,6 +237,7 @@ class Renamer(Plugin):
|
||||
)
|
||||
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)
|
||||
|
||||
if multiple:
|
||||
|
||||
@@ -29,9 +29,6 @@ class Searcher(Plugin):
|
||||
# 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'))
|
||||
|
||||
|
||||
addEvent('app.load', self.all_movies)
|
||||
|
||||
def all_movies(self):
|
||||
|
||||
if self.in_progress:
|
||||
|
||||
@@ -54,11 +54,12 @@ class Subtitle(Plugin):
|
||||
for lang in self.getLanguages():
|
||||
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'))
|
||||
downloaded.extend(download)
|
||||
for subtitle in download:
|
||||
downloaded.extend(download[subtitle])
|
||||
|
||||
for d_sub in downloaded:
|
||||
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
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from bs4 import BeautifulSoup
|
||||
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.providers.torrent.base import TorrentProvider
|
||||
import StringIO
|
||||
@@ -16,7 +16,7 @@ class KickAssTorrents(TorrentProvider):
|
||||
urls = {
|
||||
'test': 'http://www.kat.ph/',
|
||||
'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/',
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ class KickAssTorrents(TorrentProvider):
|
||||
]
|
||||
|
||||
http_time_between_calls = 1 #seconds
|
||||
cat_backup_id = None
|
||||
|
||||
def search(self, movie, quality):
|
||||
|
||||
@@ -38,7 +39,7 @@ class KickAssTorrents(TorrentProvider):
|
||||
return results
|
||||
|
||||
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:
|
||||
|
||||
cat_ids = self.getCatId(quality['identifier'])
|
||||
|
||||
@@ -52,6 +52,9 @@ class TorrentLeech(TorrentProvider):
|
||||
|
||||
try:
|
||||
result_table = html.find('table', attrs = {'id' : 'torrenttable'})
|
||||
if not result_table:
|
||||
return results
|
||||
|
||||
entries = result_table.find_all('tr')
|
||||
|
||||
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 = {
|
||||
'IMDB': IMDBAction
|
||||
,'Edit': MovieActions.Wanted.Edit
|
||||
,'Trailer': TrailerAction
|
||||
,'Files': new Class({
|
||||
|
||||
Extends: MovieAction,
|
||||
|
||||
@@ -147,7 +147,7 @@ body > .spinner, .mask{
|
||||
.icon.delete { background-image: url('../images/icon.delete.png'); }
|
||||
.icon.download { background-image: url('../images/icon.download.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.imdb { background-image: url('../images/icon.imdb.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.info { background-image: url('../images/icon.info.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 ***/
|
||||
.header {
|
||||
@@ -313,7 +315,7 @@ body > .spinner, .mask{
|
||||
.header .message.update {
|
||||
text-align: center;
|
||||
position: relative;
|
||||
top: -100px;
|
||||
top: -70px;
|
||||
padding: 2px 0;
|
||||
background: #ff6134;
|
||||
font-size: 12px;
|
||||
|
||||
Reference in New Issue
Block a user