core (memory, memory/sqlite): implemented fileDelete
This commit is contained in:
parent
a3c67e1072
commit
80da9a6591
2 changed files with 71 additions and 1 deletions
|
|
@ -1541,6 +1541,67 @@ class Memory(object):
|
|||
"""
|
||||
return self.storage.fileUpdate(file_id, column, update_cb)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def _deleteFile(self, client, peer_jid, recursive, files_path, file_data):
|
||||
"""Internal method to delete files/directories recursively
|
||||
|
||||
@param peer_jid(jid.JID): entity requesting the deletion (must be owner of files
|
||||
to delete)
|
||||
@param recursive(boolean): True if recursive deletion is needed
|
||||
@param files_path(unicode): path of the directory containing the actual files
|
||||
@param file_data(dict): data of the file to delete
|
||||
"""
|
||||
if file_data[u'owner'] != peer_jid:
|
||||
raise exceptions.PermissionError(
|
||||
u"file {file_name} can't be deleted, {peer_jid} is not the owner"
|
||||
.format(file_name=file_data[u'name'], peer_jid=peer_jid.full()))
|
||||
if file_data[u'type'] == C.FILE_TYPE_DIRECTORY:
|
||||
sub_files = yield self.getFiles(client, peer_jid, parent=file_data[u'id'])
|
||||
if sub_files and not recursive:
|
||||
raise exceptions.DataError(_(u"Can't delete directory, it is not empty"))
|
||||
# we first delete the sub-files
|
||||
for sub_file_data in sub_files:
|
||||
yield self._deleteFile(client, peer_jid, recursive, sub_file_data)
|
||||
# then the directory itself
|
||||
yield self.storage.fileDelete(file_data[u'id'])
|
||||
elif file_data[u'type'] == C.FILE_TYPE_FILE:
|
||||
log.info(_(u"deleting file {name} with hash {file_hash}").format(
|
||||
name=file_data[u'name'], file_hash=file_data[u'file_hash']))
|
||||
yield self.storage.fileDelete(file_data[u'id'])
|
||||
references = yield self.getFiles(
|
||||
client, peer_jid, file_hash=file_data[u'file_hash'])
|
||||
if references:
|
||||
log.debug(u"there are still references to the file, we keep it")
|
||||
else:
|
||||
file_path = os.path.join(files_path, file_data[u'file_hash'])
|
||||
log.info(_(u"no reference left to {file_path}, deleting").format(
|
||||
file_path=file_path))
|
||||
os.unlink(file_path)
|
||||
else:
|
||||
raise exceptions.InternalError(u'Unexpected file type: {file_type}'
|
||||
.format(file_type=file_data[u'type']))
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def fileDelete(self, client, peer_jid, file_id, recursive=False):
|
||||
"""Delete a single file or a directory and all its sub-files
|
||||
|
||||
@param file_id(unicode): id of the file to delete
|
||||
@param peer_jid(jid.JID): entity requesting the deletion,
|
||||
must be owner of all files to delete
|
||||
@param recursive(boolean): must be True to delete a directory and all sub-files
|
||||
"""
|
||||
# FIXME: we only allow owner of file to delete files for now, but WRITE access
|
||||
# should be checked too
|
||||
files_data = yield self.getFiles(client, peer_jid, file_id)
|
||||
if not files_data:
|
||||
raise exceptions.NotFound(u"Can't find the file with id {file_id}".format(
|
||||
file_id=file_id))
|
||||
file_data = files_data[0]
|
||||
if file_data[u"type"] != C.FILE_TYPE_DIRECTORY and recursive:
|
||||
raise ValueError(u"recursive can only be set for directories")
|
||||
files_path = self.host.getLocalPath(None, C.FILES_DIR, profile=False)
|
||||
yield self._deleteFile(client, peer_jid, recursive, files_path, file_data)
|
||||
|
||||
## Misc ##
|
||||
|
||||
def isEntityAvailable(self, client, entity_jid):
|
||||
|
|
|
|||
|
|
@ -931,7 +931,7 @@ class SqliteStorage(object):
|
|||
log.error(_(u"Can't update file table"))
|
||||
|
||||
def fileUpdate(self, file_id, column, update_cb):
|
||||
"""update a column value using a method to avoid race conditions
|
||||
"""Update a column value using a method to avoid race conditions
|
||||
|
||||
the older value will be retrieved from database, then update_cb will be applied
|
||||
to update it, and file will be updated checking that older value has not been changed meanwhile
|
||||
|
|
@ -948,6 +948,15 @@ class SqliteStorage(object):
|
|||
raise exceptions.InternalError('bad column name')
|
||||
return self.dbpool.runInteraction(self._fileUpdate, file_id, column, update_cb)
|
||||
|
||||
def fileDelete(self, file_id):
|
||||
"""Delete file metadata from the database
|
||||
|
||||
@param file_id(unicode): id of the file to delete
|
||||
NOTE: file itself must still be removed, this method only handle metadata in
|
||||
database
|
||||
"""
|
||||
return self.dbpool.runQuery("DELETE FROM files WHERE id = ?", (file_id,))
|
||||
|
||||
##Helper methods##
|
||||
|
||||
def __getFirstResult(self, result):
|
||||
|
|
|
|||
Loading…
Reference in a new issue