obs_ppt.pyon commit add keyboard shortcuts, icons, preloading (d403fb6)
   1# -*- coding: utf-8 -*-
   2
   3import obspython as obs
   4# pip install pywin32
   5import win32com.client
   6import pywintypes
   7import os
   8import shutil
   9import http_server_39 as server
  10#import http.server as server
  11import socketserver
  12import threading
  13import functools
  14
  15powerpoint = None
  16hotkey_id_frst = None
  17hotkey_id_prev = None
  18hotkey_id_next = None
  19hotkey_id_last = None
  20hotkey_id_black = None
  21
  22HOTKEY_NAME_FRST = 'powerpoint_slides.first'
  23HOTKEY_NAME_PREV = 'powerpoint_slides.previous'
  24HOTKEY_NAME_NEXT = 'powerpoint_slides.next'
  25HOTKEY_NAME_LAST = 'powerpoint_slides.last'
  26HOTKEY_NAME_BLACK = 'powerpoint_slides.black'
  27HOTKEY_NAME_WHITE = 'powerpoint_slides.white'
  28
  29HOTKEY_DESC_FRST = 'First PowerPoint slide'
  30HOTKEY_DESC_PREV = 'Previous PowerPoint slide'
  31HOTKEY_DESC_NEXT = 'Next PowerPoint slide'
  32HOTKEY_DESC_LAST = 'Last PowerPoint slide'
  33HOTKEY_DESC_BLACK = 'Black PowerPoint slide'
  34HOTKEY_DESC_WHITE = 'White PowerPoint slide'
  35
  36class Handler(server.CGIHTTPRequestHandler):
  37    def __init__(self, *args, **kwargs):
  38        super().__init__(*args, directory=os.path.dirname(os.path.realpath(__file__)))
  39
  40def run_http():
  41    httpd = server.HTTPServer(("", 8000), Handler)
  42    httpd.serve_forever()
  43    
  44
  45
  46
  47# ------------------------------------------------------------
  48# global functions for script plugins
  49
  50def script_load(settings):
  51    global hotkey_id_frst
  52    global hotkey_id_prev
  53    global hotkey_id_next
  54    global hotkey_id_last
  55    global hotkey_id_black
  56    global hotkey_id_white
  57
  58    hotkey_id_frst = register_and_load_hotkey(settings, HOTKEY_NAME_FRST, HOTKEY_DESC_FRST, slideshow_view_first)
  59    hotkey_id_prev = register_and_load_hotkey(settings, HOTKEY_NAME_PREV, HOTKEY_DESC_PREV, slideshow_view_previous)
  60    hotkey_id_next = register_and_load_hotkey(settings, HOTKEY_NAME_NEXT, HOTKEY_DESC_NEXT, slideshow_view_next)
  61    hotkey_id_last = register_and_load_hotkey(settings, HOTKEY_NAME_LAST, HOTKEY_DESC_LAST, slideshow_view_last)
  62    hotkey_id_black = register_and_load_hotkey(settings, HOTKEY_NAME_BLACK, HOTKEY_DESC_BLACK, slideshow_view_black)
  63    hotkey_id_white = register_and_load_hotkey(settings, HOTKEY_NAME_WHITE, HOTKEY_DESC_WHITE, slideshow_view_white)
  64
  65    daemon = threading.Thread(name="daemon_server", target=run_http)
  66    daemon.setDaemon(True)
  67    daemon.start()
  68
  69def script_unload():
  70    obs.obs_hotkey_unregister(slideshow_view_first)
  71    obs.obs_hotkey_unregister(slideshow_view_previous)
  72    obs.obs_hotkey_unregister(slideshow_view_next)
  73    obs.obs_hotkey_unregister(slideshow_view_last)
  74    obs.obs_hotkey_unregister(slideshow_view_black)
  75    obs.obs_hotkey_unregister(slideshow_view_white)
  76
  77def script_save(settings):
  78    save_hotkey(settings, HOTKEY_NAME_FRST, hotkey_id_frst)
  79    save_hotkey(settings, HOTKEY_NAME_PREV, hotkey_id_prev)
  80    save_hotkey(settings, HOTKEY_NAME_NEXT, hotkey_id_next)
  81    save_hotkey(settings, HOTKEY_NAME_LAST, hotkey_id_last)
  82    save_hotkey(settings, HOTKEY_NAME_BLACK, hotkey_id_black)
  83    save_hotkey(settings, HOTKEY_NAME_WHITE, hotkey_id_white)
  84
  85def script_description():
  86    return 'Navigate Powerpoint Slides.'
  87
  88def script_defaults(settings):
  89    obs.obs_data_set_default_string(settings, 'cache', r'''C:\Windows\Temp''')
  90
  91def script_properties():
  92    props = obs.obs_properties_create()
  93
  94    obs.obs_properties_add_path(props, "cache", "Slide cache: ", obs.OBS_PATH_DIRECTORY, "*.jpg", r'''C:\Windows\Temp''')
  95    return props
  96
  97def script_update(settings):
  98    global cache
  99    cache = obs.obs_data_get_string(settings, "cache").replace("/", "\\")
 100
 101def register_and_load_hotkey(settings, name, description, callback):
 102    hotkey_id = obs.obs_hotkey_register_frontend(name, description, callback)
 103    hotkey_save_array = obs.obs_data_get_array(settings, name)
 104    obs.obs_hotkey_load(hotkey_id, hotkey_save_array)
 105    obs.obs_data_array_release(hotkey_save_array)
 106
 107    return hotkey_id
 108
 109def save_hotkey(settings, name, hotkey_id):
 110    hotkey_save_array = obs.obs_hotkey_save(hotkey_id)
 111    obs.obs_data_set_array(settings, name, hotkey_save_array)
 112    obs.obs_data_array_release(hotkey_save_array)
 113
 114#-------------------------------------
 115
 116def get_slideshow_view():
 117    global powerpoint
 118
 119    if powerpoint is None:
 120        powerpoint = win32com.client.Dispatch('Powerpoint.Application')
 121
 122    if powerpoint is None:
 123        return
 124
 125    ssw = powerpoint.SlideShowWindows
 126    if ssw.Count == 0:
 127        return
 128
 129    # https://docs.microsoft.com/en-us/office/vba/api/powerpoint.slideshowwindow.view
 130    ssv = ssw[0].View
 131
 132    return ssv
 133
 134def get_activepresentation():
 135    global powerpoint
 136
 137    if powerpoint is None:
 138        powerpoint = win32com.client.Dispatch('Powerpoint.Application')
 139
 140    if powerpoint is None:
 141        return
 142
 143    activepres = powerpoint.ActivePresentation
 144    return activepres
 145
 146def export_next(slide):
 147    global cache
 148    ssp = get_activepresentation()
 149    if ssp:
 150        if slide < len(ssp.Slides):
 151            ssp.Slides(slide + 1).Export(cache + r'''\slide0.jpg''', "JPG")
 152            attempts = 0
 153            while attempts < 3:
 154                try:
 155                    os.replace(cache + r'''\slide0.jpg''', cache + r'''\slide.jpg''')
 156                except:
 157                    pass
 158                attempts += 1
 159        else:
 160            shutil.copyfileobj(open(os.path.dirname(os.path.realpath(__file__)) + r'''\blank.jpg''', 'rb'), open(cache + r'''\slide.jpg''', 'wb'))
 161
 162def slideshow_view_first(pressed):
 163    if pressed:
 164        ssv = get_slideshow_view()
 165        if ssv:
 166            ssv.First()
 167            ssv.State = 1
 168
 169def slideshow_view_previous(pressed):
 170    if pressed:
 171        ssv = get_slideshow_view()
 172        if ssv:
 173            ssv.Previous()
 174            ssv.State = 1
 175            export_next(ssv.CurrentShowPosition)
 176
 177def slideshow_view_next(pressed):
 178    if pressed:
 179        ssv = get_slideshow_view()
 180        if ssv:
 181            ssv.Next()
 182            ssv.State = 1
 183            export_next(ssv.CurrentShowPosition)
 184            
 185
 186def slideshow_view_last(pressed):
 187    if pressed:
 188        ssv = get_slideshow_view()
 189        if ssv:
 190            ssv.Last()
 191            ssv.State = 1
 192
 193def slideshow_view_black(pressed):
 194    if pressed:
 195        ssv = get_slideshow_view()
 196        if ssv:
 197            if ssv.State == 3 or ssv.State == 4:
 198                ssv.State = 1
 199            else:
 200                ssv.State = 3
 201
 202def slideshow_view_white(pressed):
 203    if pressed:
 204        ssv = get_slideshow_view()
 205        if ssv:
 206            if ssv.State == 4 or ssv.State == 3:
 207                ssv.State = 1
 208            else:
 209                ssv.State = 4