upload.py 2.6 KB
Newer Older
Link Mauve's avatar
Link Mauve committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
"""
Upload a file and auto-complete the input with its URL.

Usage
-----

This plugin adds a command to the chat tabs.

.. glossary::

    /upload
        **Usage:** ``/upload <filename>``

        Uploads the <filename> file to the preferred HTTP File Upload
        service (see XEP-0363) and fill the input with its URL.


"""
19 20 21

from typing import Optional

Link Mauve's avatar
Link Mauve committed
22
import asyncio
23
import traceback
Link Mauve's avatar
Link Mauve committed
24 25 26
from os.path import expanduser
from glob import glob

27
from slixmpp.plugins.xep_0363.http_upload import FileTooBig, HTTPError, UploadServiceNotFound
28

Link Mauve's avatar
Link Mauve committed
29 30 31 32 33 34
from poezio.plugin import BasePlugin
from poezio.core.structs import Completion
from poezio.decorators import command_args_parser
from poezio import tabs


mathieui's avatar
mathieui committed
35
class Plugin(BasePlugin):
36 37
    dependencies = {'embed'}

Link Mauve's avatar
Link Mauve committed
38
    def init(self):
39 40
        self.embed = self.refs['embed']

41 42
        if not self.core.xmpp['xep_0363']:
            raise Exception('slixmpp XEP-0363 plugin failed to load')
43
        for _class in (tabs.PrivateTab, tabs.StaticConversationTab, tabs.DynamicConversationTab, tabs.MucTab):
mathieui's avatar
mathieui committed
44 45 46 47 48 49 50 51
            self.api.add_tab_command(
                _class,
                'upload',
                self.command_upload,
                usage='<filename>',
                help='Upload a file and auto-complete the input with its URL.',
                short='Upload a file',
                completion=self.completion_filename)
Link Mauve's avatar
Link Mauve committed
52

53
    async def upload(self, filename) -> Optional[str]:
Link Mauve's avatar
Link Mauve committed
54
        try:
55
            url = await self.core.xmpp['xep_0363'].upload_file(filename)
56 57
        except UploadServiceNotFound:
            self.api.information('HTTP Upload service not found.', 'Error')
58
            return None
59 60 61
        except (FileTooBig, HTTPError) as exn:
            self.api.information(str(exn), 'Error')
            return None
62 63
        except Exception:
            exception = traceback.format_exc()
mathieui's avatar
mathieui committed
64 65
            self.api.information('Failed to upload file: %s' % exception,
                                 'Error')
66 67 68 69 70 71 72
            return None
        return url

    async def send_upload(self, filename):
        url = await self.upload(filename)
        if url is not None:
            self.embed.embed_image_url(url)
Link Mauve's avatar
Link Mauve committed
73 74 75 76 77 78 79 80

    @command_args_parser.quoted(1)
    def command_upload(self, args):
        if args is None:
            self.core.command.help('upload')
            return
        filename, = args
        filename = expanduser(filename)
81
        asyncio.ensure_future(self.send_upload(filename))
Link Mauve's avatar
Link Mauve committed
82 83 84 85 86 87

    @staticmethod
    def completion_filename(the_input):
        txt = expanduser(the_input.get_text()[8:])
        files = glob(txt + '*')
        return Completion(the_input.auto_completion, files, quotify=False)