comparison sat/memory/memory.py @ 2928:c0f6fd75af5f

core (memory, memory/sqlite): implemented fileDelete
author Goffi <goffi@goffi.org>
date Sun, 28 Apr 2019 08:55:13 +0200
parents 4cd7545c4ebb
children 94708a7d3ecf
comparison
equal deleted inserted replaced
2927:69e4716d6268 2928:c0f6fd75af5f
1539 the method will take older value as argument, and must update it in place 1539 the method will take older value as argument, and must update it in place
1540 Note that the callable must be thread-safe 1540 Note that the callable must be thread-safe
1541 """ 1541 """
1542 return self.storage.fileUpdate(file_id, column, update_cb) 1542 return self.storage.fileUpdate(file_id, column, update_cb)
1543 1543
1544 @defer.inlineCallbacks
1545 def _deleteFile(self, client, peer_jid, recursive, files_path, file_data):
1546 """Internal method to delete files/directories recursively
1547
1548 @param peer_jid(jid.JID): entity requesting the deletion (must be owner of files
1549 to delete)
1550 @param recursive(boolean): True if recursive deletion is needed
1551 @param files_path(unicode): path of the directory containing the actual files
1552 @param file_data(dict): data of the file to delete
1553 """
1554 if file_data[u'owner'] != peer_jid:
1555 raise exceptions.PermissionError(
1556 u"file {file_name} can't be deleted, {peer_jid} is not the owner"
1557 .format(file_name=file_data[u'name'], peer_jid=peer_jid.full()))
1558 if file_data[u'type'] == C.FILE_TYPE_DIRECTORY:
1559 sub_files = yield self.getFiles(client, peer_jid, parent=file_data[u'id'])
1560 if sub_files and not recursive:
1561 raise exceptions.DataError(_(u"Can't delete directory, it is not empty"))
1562 # we first delete the sub-files
1563 for sub_file_data in sub_files:
1564 yield self._deleteFile(client, peer_jid, recursive, sub_file_data)
1565 # then the directory itself
1566 yield self.storage.fileDelete(file_data[u'id'])
1567 elif file_data[u'type'] == C.FILE_TYPE_FILE:
1568 log.info(_(u"deleting file {name} with hash {file_hash}").format(
1569 name=file_data[u'name'], file_hash=file_data[u'file_hash']))
1570 yield self.storage.fileDelete(file_data[u'id'])
1571 references = yield self.getFiles(
1572 client, peer_jid, file_hash=file_data[u'file_hash'])
1573 if references:
1574 log.debug(u"there are still references to the file, we keep it")
1575 else:
1576 file_path = os.path.join(files_path, file_data[u'file_hash'])
1577 log.info(_(u"no reference left to {file_path}, deleting").format(
1578 file_path=file_path))
1579 os.unlink(file_path)
1580 else:
1581 raise exceptions.InternalError(u'Unexpected file type: {file_type}'
1582 .format(file_type=file_data[u'type']))
1583
1584 @defer.inlineCallbacks
1585 def fileDelete(self, client, peer_jid, file_id, recursive=False):
1586 """Delete a single file or a directory and all its sub-files
1587
1588 @param file_id(unicode): id of the file to delete
1589 @param peer_jid(jid.JID): entity requesting the deletion,
1590 must be owner of all files to delete
1591 @param recursive(boolean): must be True to delete a directory and all sub-files
1592 """
1593 # FIXME: we only allow owner of file to delete files for now, but WRITE access
1594 # should be checked too
1595 files_data = yield self.getFiles(client, peer_jid, file_id)
1596 if not files_data:
1597 raise exceptions.NotFound(u"Can't find the file with id {file_id}".format(
1598 file_id=file_id))
1599 file_data = files_data[0]
1600 if file_data[u"type"] != C.FILE_TYPE_DIRECTORY and recursive:
1601 raise ValueError(u"recursive can only be set for directories")
1602 files_path = self.host.getLocalPath(None, C.FILES_DIR, profile=False)
1603 yield self._deleteFile(client, peer_jid, recursive, files_path, file_data)
1604
1544 ## Misc ## 1605 ## Misc ##
1545 1606
1546 def isEntityAvailable(self, client, entity_jid): 1607 def isEntityAvailable(self, client, entity_jid):
1547 """Tell from the presence information if the given entity is available. 1608 """Tell from the presence information if the given entity is available.
1548 1609