SolarFM/plugins/trasher/xdgtrash.py

162 lines
5.1 KiB
Python
Raw Normal View History

from .trash import Trash
import shutil
import os
import os.path
import datetime
import sys
import logging
try:
import configparser
except ImportError:
import ConfigParser as configparser
class XDGTrash(Trash):
"""XDG trash backend."""
def __init__(self):
self.trashdir = None
self.filedir = None
self.infodir = None
if os.getenv('XDG_DATA_HOME') is None:
self.trashdir = os.path.expanduser('~/.local/share/Trash')
else:
self.trashdir = os.getenv('XDG_DATA_HOME') + '/Trash'
try:
if not os.path.exists(self.trashdir):
os.mkdir(self.trashdir)
except OSError:
self.trashdir = os.path.join('tmp' 'TRASH')
raise('Couldnt access the proper directory, temporary trash is in in /tmp/TRASH')
self.filedir = self.trashdir + '/files/'
self.infodir = self.trashdir + '/info/'
def regenerate(self):
"""Regenerate the trash and recreate metadata."""
print('Regenerating the trash and recreating metadata...')
zerosize = False
if not os.path.exists(self.trashdir):
os.mkdir(self.trashdir)
zerosize = True
if ((not os.path.exists(self.filedir)) or
(not os.path.exists(self.infodir))):
os.mkdir(self.filedir)
os.mkdir(self.infodir)
zerosize = True
if not zerosize:
trashsize = (self.size_dir(self.filedir) + self.size_dir(self.infodir))
else:
trashsize = 0
infofile = '[Cached]\nSize=' + str(trashsize) + '\n'
fh = open(os.path.join(self.trashdir, 'metadata'), 'w')
fh.write(infofile)
fh.close()
def empty(self, verbose):
"""Empty the trash."""
print('emptying (verbose={})'.format(verbose))
shutil.rmtree(self.filedir)
shutil.rmtree(self.infodir)
self.regenerate()
if verbose:
sys.stderr.write(_('emptied the trash\n'))
def list(self, human=True):
"""List the trash contents."""
if human:
print('listing contents (on stdout; human=True)')
else:
print('listing contents (return; human=False)')
dirs = []
files = []
for f in os.listdir(self.filedir):
if os.path.isdir(self.filedir + f):
dirs.append(f)
else:
files.append(f)
dirs.sort()
files.sort()
allfiles = []
for i in dirs:
allfiles.append(i + '/')
for i in files:
allfiles.append(i)
if human:
if allfiles != []:
print('\n'.join(allfiles))
else:
return allfiles
def trash(self, filepath, verbose):
"""Move specified file to trash."""
print('trashing file {} (verbose={})'.format(filepath, verbose))
# Filename alteration, a big mess.
filename = os.path.basename(filepath)
fileext = os.path.splitext(filename)
tomove = filename
collision = True
i = 1
while collision:
if os.path.lexists(self.filedir + tomove):
tomove = fileext[0] + ' ' + str(i) + fileext[1]
i = i + 1
else:
collision = False
infofile = """[Trash Info]
Path={}
DeletionDate={}
""".format(os.path.realpath(filepath),
datetime.datetime.now().strftime('%Y-%m-%dT%H:%m:%S'))
os.rename(filepath, self.filedir + tomove)
f = open(os.path.join(self.infodir, tomove + '.trashinfo'), 'w')
f.write(infofile)
f.close()
self.regenerate()
if verbose:
sys.stderr.write(_('trashed \'{}\'\n').format(filename))
def restore(self, filename, verbose, tocwd=False):
"""Restore a file from trash."""
print('restoring file {} (verbose={}, tocwd={})'.format(filename, verbose, tocwd))
info = configparser.ConfigParser()
if os.path.exists(os.path.join(self.filedir, filename)):
info.read(os.path.join(self.infodir, filename + '.trashinfo'))
restname = os.path.basename(info.get('Trash Info', 'Path'))
if tocwd:
restdir = os.path.abspath('.')
else:
restdir = os.path.dirname(info.get('Trash Info', 'Path'))
restfile = os.path.join(restdir, restname)
if not os.path.exists(restdir):
raise TMError('restore', 'nodir', _('no such directory: {}'
' -- cannot restore').format(restdir))
os.rename(os.path.join(self.filedir, filename), restfile)
os.remove(os.path.join(self.infodir, filename + '.trashinfo'))
self.regenerate()
print('restored {} to {}'.format(filename, restfile))
if verbose:
sys.stderr.write(_('restored {} to {}\n').format(filename, restfile))
else:
print('couldn\'t find {} in trash'.format(filename))
raise TMError('restore', 'nofile', _('no such file in trash'))