Browse Source

Added button to remove files when deleting media - take two

pull/7194/head
CaptainQwark 8 years ago
parent
commit
89341c272b
  1. 71
      couchpotato/core/media/_base/media/main.py
  2. 62
      couchpotato/core/media/movie/_base/static/movie.actions.js
  3. 4
      couchpotato/core/plugins/profile/static/profile.js
  4. 2
      couchpotato/static/style/main.scss

71
couchpotato/core/media/_base/media/main.py

@ -1,6 +1,7 @@
from datetime import timedelta
import os
import time
import traceback
from datetime import timedelta
from string import ascii_lowercase
from CodernityDB.database import RecordNotFound, RecordDeleted
@ -68,6 +69,7 @@ class MediaPlugin(MediaBase):
'params': {
'id': {'desc': 'Media ID(s) you want to delete.', 'type': 'int (comma separated)'},
'delete_from': {'desc': 'Delete media from this page', 'type': 'string: all (default), wanted, manage'},
'with_files': {'desc': 'Delete the files as well', 'type': 'bool (true or false)'},
}
})
@ -416,12 +418,62 @@ class MediaPlugin(MediaBase):
tempChar = lambda *args, **kwargs : self.charView(type = media_type, **kwargs)
addApiView('%s.available_chars' % media_type, tempChar)
def delete(self, media_id, delete_from = None):
def deleteFiles(self, instance):
directories = dict()
# Walk through all files in the Couch database
for name, paths in instance['files'].iteritems():
log.info('Removing %s', name)
for path in paths:
# Add the directories and filename prefixes to a list so we can
# remove the directories and related files as well
directory = os.path.dirname(path)
if directory not in directories:
directories[directory] = set()
directories[directory].add(os.path.splitext(path)[0])
if os.path.isfile(path):
try:
os.remove(path)
log.info('Removed %s', path)
except:
log.error('Unable to remove %s', path)
# Walk through the directories and file prefixes for removal if
# possible
for directory, prefixes in directories.iteritems():
if os.path.isdir(directory):
# If the files in the directory have the same name as the
# expected files (except for extensions and stuff), remove them
files = os.listdir(directory)
removed = 0
for file_ in files:
for prefix in prefixes:
if file_.startswith(prefix):
try:
os.remove(file_)
removed += 1
log.info('Removed %s', file_)
except:
log.error('Unable to remove %s', file_)
try:
if len(files) == removed:
os.rmdir(directory)
log.info('Removed %s', directory)
else:
log.info('Not removing %s, %d files in directory',
(directory, len(files) - removed))
except Exception:
log.error('Unable to remove %s', directory)
def delete(self, media_id, delete_from = None, with_files = False):
try:
db = get_db()
media = db.get('id', media_id)
if media:
deleted = False
@ -430,8 +482,14 @@ class MediaPlugin(MediaBase):
if delete_from == 'all':
# Delete connected releases
for release in media_releases:
if with_files:
self.deleteFiles(release)
db.delete(release)
if with_files:
self.deleteFiles(media)
db.delete(media)
deleted = True
else:
@ -450,8 +508,13 @@ class MediaPlugin(MediaBase):
if release.get('status') == 'done' or media.get('status') == 'done':
db.delete(release)
total_deleted += 1
if with_files:
self.deleteFiles(release)
if (total_releases == total_deleted) or (total_releases == 0 and not new_media_status) or (not new_media_status and delete_from == 'late'):
if with_files:
self.deleteFiles(media)
db.delete(media)
deleted = True
elif new_media_status:
@ -460,7 +523,7 @@ class MediaPlugin(MediaBase):
# Remove profile (no use for in manage)
if new_media_status == 'done':
media['profile_id'] = None
db.update(media)
fireEvent('media.untag', media['_id'], 'recent', single = True)
@ -478,7 +541,7 @@ class MediaPlugin(MediaBase):
ids = splitString(id)
for media_id in ids:
self.delete(media_id, delete_from = kwargs.get('delete_from', 'all'))
self.delete(media_id, delete_from = kwargs.get('delete_from', 'all'), with_files = kwargs.get('with_files'))
return {
'success': True,

62
couchpotato/core/media/movie/_base/static/movie.actions.js

@ -841,9 +841,10 @@ MA.Delete = new Class({
var self = this;
return new Element('a.delete', {
'text': 'Delete',
'title': 'Remove the movie from this CP list',
'title': 'Remove the movie from this CP list, and optionally delete files from disk',
'events': {
'click': self.showConfirm.bind(self)
'click': self.movie.list.options.identifier === 'manage' ?
self.showConfirmWithFiles.bind(self) : self.showConfirm.bind(self)
}
});
},
@ -859,7 +860,7 @@ MA.Delete = new Class({
'click': function(e){
e.target.set('text', 'Deleting...');
self.del();
self.del(false);
}
}
}, {
@ -869,7 +870,57 @@ MA.Delete = new Class({
},
del: function(){
showConfirmWithFiles: function(e){
var self = this;
(e).stopPropagation();
self.question = new Question('Are you sure you want to delete <strong>' + self.getTitle() + '</strong>?', '', [{
'text': 'Yes, delete',
'class': 'delete',
'events': {
'click': function(e){
e.target.set('text', 'Deleting...');
self.del(false);
}
}
}, {
'text': 'Yes, and also delete files from disk',
'class': 'delete',
'events': {
'click': self.showConfirmWithFilesReally.bind(self)
}
}, {
'text': 'Cancel',
'cancel': true
}]);
},
showConfirmWithFilesReally: function(e){
var self = this;
(e).stopPropagation();
if(self.question)
self.question.close();
self.question = new Question('Are you sure you want to delete <strong>all media files</strong> for <strong>' + self.getTitle() + '</strong>?', '', [{
'text': 'Yes, really delete all files for '+self.getTitle(),
'class': 'delete',
'events': {
'click': function(e){
e.target.set('text', 'Deleting from cp and disk...');
self.del(true);
}
}
}, {
'text': 'Cancel',
'cancel': true
}]);
},
del: function(withFiles){
var self = this;
var movie = $(self.movie);
@ -877,7 +928,8 @@ MA.Delete = new Class({
Api.request('media.delete', {
'data': {
'id': self.movie.get('_id'),
'delete_from': self.movie.list.options.identifier
'delete_from': self.movie.list.options.identifier,
'with_files': !!withFiles
},
'onComplete': function(){
if(self.question)

4
couchpotato/core/plugins/profile/static/profile.js

@ -140,7 +140,7 @@ var Profile = new Class({
};
Array.each(self.type_container.getElements('.type'), function(type){
if(!type.hasClass('deleted') && type.getElement('select').get('value') != -1 && type.getElement('select').get('value') != "")
if(!type.hasClass('deleted') && type.getElement('select').get('value') != -1 && type.getElement('select').get('value') !== "")
data.types.include({
'quality': type.getElement('select').get('value'),
'finish': +type.getElement('input.finish[type=checkbox]').checked,
@ -258,7 +258,7 @@ Profile.Type = new Class({
self.create();
self.addEvent('change', function(){
var has_quality = !(self.qualities.get('value') == '-1' || self.qualities.get('value') == '');
var has_quality = !(self.qualities.get('value') == '-1' || self.qualities.get('value') === '');
self.el[!has_quality ? 'addClass' : 'removeClass']('is_empty');
self.el[has_quality && Quality.getQuality(self.qualities.get('value')).allow_3d ? 'addClass': 'removeClass']('allow_3d');
self.deleted = !has_quality;

2
couchpotato/static/style/main.scss

@ -745,7 +745,7 @@ input[type=text], textarea {
.inner {
width: 100%;
max-width: 500px;
max-width: 600px;
}
h3 {

Loading…
Cancel
Save