From 2a2f58680b8d7961b4b1472870be2e1ec5c1cb51 Mon Sep 17 00:00:00 2001 From: gryf Date: Sat, 5 Jan 2019 16:48:36 +0100 Subject: [PATCH] Adapt to Slack file atachement API changes Couple of months ago, file attachments was treated differently, than now - API provides attached files as a list, instead of single object, and is directly coupled with a message object. This change provides support for such cases. --- slack_backup/client.py | 60 ++++++++++++++++++++++++----------------- slack_backup/objects.py | 4 +-- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/slack_backup/client.py b/slack_backup/client.py index 71918b9..ea07aba 100644 --- a/slack_backup/client.py +++ b/slack_backup/client.py @@ -238,7 +238,8 @@ class Client(object): user = self._get_user(data) - if not any((data.get('attachments'), data['text'].strip())): + if not any((data.get('attachments'), data['text'].strip(), + data.get('files'))): logging.info("Skipping message from `%s' since it's empty", user.name) return @@ -254,22 +255,25 @@ class Client(object): for reaction_data in data['reactions']: message.reactions.append(o.Reaction(reaction_data)) - if data.get('subtype') == 'file_share': - if (self._url_file_to_attachment and - data['file'].get('is_external')): - fdata = data['file'] - # change message type from file_share to default - message.type = '' - message.text = (message.text.split('shared a file:')[0] + - 'shared a file: ') - logging.debug("Found external file `%s'. Saving as " - "attachment.", fdata['url_private']) - self._att_data(message, [{'title': fdata['name'], - 'text': fdata['url_private'], - 'fallback': ''}]) - else: - self._file_data(message, data['file']) - elif data.get('subtype') == 'pinned_item': + if data.get('files'): + for fdata in data['files']: + if (self._url_file_to_attachment and fdata.get('is_external')): + logging.info('got external file') + message.text = (message.text.split('shared a file:')[0] + + 'shared a file: ') + logging.debug("Found external file `%s'. Saving as " + "attachment.", fdata['url_private']) + self._att_data(message, [{'title': fdata['name'], + 'text': fdata['url_private'], + 'fallback': ''}]) + else: + self._file_data(message, fdata) + + # TODO(gryf): subtype pinned_item coexistsing with pinned_info message + # key :C + # pinned_info however is just a mark, which point to the channlel + # where it is pinned to, who did that and when. To be resolved. + if data.get('subtype') == 'pinned_item': if data.get('attachments'): self._att_data(message, data['attachments']) elif data.get('item'): @@ -284,26 +288,34 @@ class Client(object): Process file data. Could be either represented as 'file' object or 'item' object in case of pinned items """ - message.file = o.File(data) + _file = o.File(data) + message.files.append(_file) + + if data.get('mode') == 'tombstone': + _file.title = 'This file was deleted' + return + if data.get('is_starred'): message.is_starred = True if data.get('is_external'): # Create a link and corresponding file name for manual download fname = str(uuid.uuid4()) - message.file.filepath = self.downloader.get_filepath(fname, 'file') + _file.filepath = self.downloader.get_filepath(fname, 'file') logging.info("Please, manually download an external file from " "URL `%s' to `%s'", data['url_private'], - message.file.filepath) + _file.filepath) self._dldata.append('%s --> %s\n' % (data['url_private'], - message.file.filepath)) - message.file.url = data['url_private'] + _file.filepath)) + _file.url = data['url_private'] else: logging.debug("Found internal file `%s'", data['url_private_download']) priv_url = data['url_private_download'] - message.file.filepath = self.downloader.download(priv_url, 'file') - self.session.add(message.file) + _file.filepath = self.downloader.download(priv_url, 'file', + data.get('filetype')) + + self.session.add(_file) def _att_data(self, message, data): """ diff --git a/slack_backup/objects.py b/slack_backup/objects.py index e4bb585..daf500d 100644 --- a/slack_backup/objects.py +++ b/slack_backup/objects.py @@ -228,7 +228,7 @@ class Message(Base): channel = relationship("Channel", back_populates="messages") reactions = relationship("Reaction", back_populates="message") - file = relationship("File", uselist=False, back_populates="message") + files = relationship("File", back_populates="message") attachments = relationship("Attachment", back_populates="message") def __init__(self, data_dict=None): @@ -255,7 +255,7 @@ class File(Base): filepath = Column(Text) message_id = Column(Integer, ForeignKey('messages.id')) - message = relationship('Message', back_populates='file') + message = relationship('Message', back_populates='files') def __init__(self, data_dict=None): self.update(data_dict)