Дистанционное управление презентацией со смартфона

    Делал я недавно доклад (на Percona Live). И как-то ночью (jet-lag все-таки) подумал, что неплохо бы как-нибудь видеть свои комментарии к слайдам — подсказки — и переключать слайды не подходя к ноутбуку. Чудо-устройства, чтоб и слайды переключало и комментарии показывало, у меня не было. Но был смартфон с Андроидом. Гугл-маркет разочаровал. Большинство подобных приложений работало только с PowerPoint, для LibreOffice я нашел только одно, платное, и выглядело оно как-то не так.

    Но есть простое решение — браузер. Можно поднять http-сервер на ноутбуке, зайти с телефона, и по ссылкам переключать слайды. И будет работать не только с Андроидом, а и с яблочными, и с виндофонами. Да вообще смартфон не нужен, можно хоть через WAP заходить, или с другого ноутбука.

    Получилось довольно просто. Около 70 строк на питоне, никаких внешних зависимостей (почти).

    Комментарии читаются из файла (заморачиваться с вытаскиванием их из презентации я не стал). Поднимаем BaseHTTPServer на каком-то порту, я пробую все от 8000 до 9000 в случайном порядке, пока не получится. По инструкции со StackOverflow определяем свой IP. И вдобавок генерируем большое случайное число — оно будет частью URL-а, чтобы никто из аудитории не переключал нам слайды. Как мелкое удобство открываю браузер, чтобы показал QR-код для доступа к серверу. Если доступа в Интернет во время конференции не будет — не беда, придется ввести URL руками, и все. А для работы достаточно внутреннего вайфая.

    По инструкции к BaseHTTPServer, чтобы обрабатывать GET запросы надо создать do_GET метод. Создаем. Первым делом надо проверить, чтоб было наше случайное число. Если есть, и URL заканчивается на next или prev, то имитируем нажатие пробела или, соответственно, backspace, и возвращаем страничку с комментариями для следующей или предыдущей страницы.

    У меня стоит fvwm, так что с имитацией нажатий проблем не возникло. Для других менеджеров окон можно использовать отдельную программку или даже специальный модуль для питона, такие есть — я проверял.

    Ну, собственно, и все. Только шрифт в настройках мобильного браузера нужно делать покрупнее. И комментарии писать покороче, иначе их долго читать — получаются неприятные паузы во время доклада. Да, и таймаут на отключение экрана убрать на смартфоне и в ноутбуке.

    Испытание в боевых условиях прошло успешно.

    #!/usr/bin/python
    
    import sys
    import os
    import random
    import socket
    import BaseHTTPServer
    import re
    
    handler_class=BaseHTTPServer.BaseHTTPRequestHandler
    token="/" + str(random.randint(0, sys.maxint)) + "/"
    page = 1
    validate = re.compile(token + "(prev|next)$")
    
    def send_key(key):
      os.system("FvwmCommand 'All (VCLSalFrame) FakeKeypress press {}'".format(key))
    
    class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
      def link(self,s,n):
        if n < 0 or n >= len(data):
          return " "
        return '<a href="{}{}">{}</a>'.format(token,s,s)
    
      def do_GET(self):
        cmd = validate.match(self.path)
        if cmd is None:
          self.send_response(404)
          self.send_header("Content-type", 'text/html')
          self.end_headers()
          self.wfile.write('<h1>OK</h1>')
          return
    
        global page
        if cmd.group(1) == 'prev' and page > 0:
          page = page - 1
          send_key('BackSpace')
        elif cmd.group(1) == 'next' and page < len(data)-1:
          page = page + 1
          send_key('space')
         
        self.send_response(200)
        self.send_header("Content-type", 'text/html; charset=utf-8')
        self.end_headers()
        self.wfile.write("""
    {pagenum} - {next}
    <hr> {data} <hr>
    {prev} - {pagenum}
    """.format(prev = self.link('prev', page - 1), pagenum = page + 1,
               next = self.link('next', page + 1), data = data[page]))
    
    def read_file(s):
      with open(s) as f:
        return re.split('--- *\n?', f.read())
    
    def ip():
      s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
      s.connect(('192.168.1.1', 0)) # fake, but nobody cares
      return s.getsockname()[0]
    
    def make_url(port):
      url="http://{}:{}{}prev".format(ip(), port, token)
      print url
      os.system("firefox 'http://chart.apis.google.com/chart?cht=qr&chs=200x200&chl={}' &".format(url))
    
    def run():
      for port in random.sample(xrange(8000, 9000),1000):
        try:
          httpd = BaseHTTPServer.HTTPServer(('',port), Handler)
          httpd.server_activate()
          make_url(port)
          httpd.serve_forever()
        except socket.error, e:
          if e.errno not in (98,):
            print e
            exit()
        except KeyboardInterrupt:
          print "\nExiting"
          exit()
    
    data = read_file('notes.txt')
    print "Got {} slides".format(len(data))
    run()
    
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 10

      –13
      Используйте node.js или по крайней мере Tornado
        0
        Ну и нормальный движок для презентаций, конечно же.
          +12
          Смешно.

          Тут ~70 строк на чистом питоне без зависимостей. Можно, конечно, много чего поставить и использовать, но зачем?
            0
            Про принцип KISS забывать не нужно!
            Иногда для подобных целей вообще ставят apache + mysql. Сам видел многократно (
            –1
            Немного влезу не в тему, извиняюсь )
            На то же питоне сейчас разрабатываю похожий проект.
            Программа — а ля клавиатура лебедева. То есть можно настраивать виртуальные кнопки на экране смартфона и прибиндить к ним любые сочетания клавиш.
            Клиент и сервер написаны на питоне, работает на win, linux.
            Нужны бета тестеры и помощь в написании доков, в readme все написано: extkeys.mobile-master.org/static/extKeys_beta.zip
              +2
              Чуть не забыл: клиент и сервер написаны тоже на питоне ) статью на хабре напишу )
              0
              Пусть полежит здесь.
              itunes.apple.com/ru/app/keynote-remote/id300719251?mt=8
              Платно, platform-specific, но кому-то может и пригодится.
                0
                чтобы никто из аудитории не переключал нам слайды.

                используйте HTTPS, чтобы не украли секретные ссылки снифером трафика. кажется, это просто www.piware.de/2011/01/creating-an-https-server-in-python/.
                  0
                  Попробовал, работает! Спасибо.
                    0
                    А я пользовался этим:
                    www.c-blues.com/products/muance

                    Only users with full accounts can post comments. Log in, please.