Skip to content

Commit

Permalink
Merge 4c5b641 into e0f40b6
Browse files Browse the repository at this point in the history
  • Loading branch information
yanickdi committed Apr 1, 2019
2 parents e0f40b6 + 4c5b641 commit 09aafac
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 15 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,11 @@ pip-log.txt
# Translations
*.mo

# VirtualEnv
/env

# IDE
/.idea

# Sphinx
docs/_build
95 changes: 80 additions & 15 deletions sphinx_autobuild/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@
Automatic builder for Sphinx based documentation sets.
MIT License. See LICENSE for more details.
Copyright (c) 2013, Jonathan Stoppani
Copyright (c) 2013, Jonathan Stoppani, Fork by Carrot & Company
"""


import argparse
import fnmatch
import os
import re
import subprocess
import sys
import port_for
from threading import Thread, Lock
from collections import deque
import time

try:
import pty
Expand All @@ -25,30 +27,74 @@
from watchdog.observers.polling import PollingObserver
from watchdog.events import FileSystemEventHandler


__version__ = '0.7.1'
__url__ = 'https://github.com/GaretJax/sphinx-autobuild'

__url__ = 'https://github.com/carrotandcompany/sphinx-autobuild'

DEFAULT_IGNORE_REGEX = [
r'__pycache__/.*\.py',
r'.*\.pyc',
r'.*\.kate-swp',
]

DEFAULT_EVENT_DELAY_TIME = 5


class EventActionData(object):
def __init__(self):
self.lock = Lock()
self.queue = deque()


class EventActionThread(Thread):
"""
This Thread runs an endless loop which checks every defined interval time
if the the FileSystemEvent Queue has entries.
If the queue has entries it empties the queue and invokes an action
"""

def __init__(self, event_action_data, action, watcher,
check_interval=DEFAULT_EVENT_DELAY_TIME):
super().__init__()
self.action = action
self.event_action_data = event_action_data
self.watcher = watcher
self.check_interval = check_interval
self._kill_received = False

def run(self):
print('EventActionThread is running.')
while not self._kill_received:
with self.event_action_data.lock:
if len(self.event_action_data.queue) > 0:
print('{} files changed. Building...'.format(
len(self.event_action_data.queue)))
# clear queue and remember the last_event
last_event = self.event_action_data.queue.popleft()
self.event_action_data.queue.clear()
# call the action
self.action(self.watcher,
getattr(last_event, 'dest_path',
last_event.src_path))
time.sleep(self.check_interval)

def kill(self):
self._kill_received = True


class _WatchdogHandler(FileSystemEventHandler):

def __init__(self, watcher, action):
def __init__(self, watcher, action, event_action_data):
super(_WatchdogHandler, self).__init__()
self._watcher = watcher
self._action = action
self.event_action_data = event_action_data

def on_any_event(self, event):
if event.is_directory:
return
self._action(self._watcher,
getattr(event, 'dest_path', event.src_path))
with self.event_action_data.lock:
self.event_action_data.queue.append(event)


def _set_changed(w, _):
Expand All @@ -59,7 +105,8 @@ class LivereloadWatchdogWatcher(object):
"""
File system watch dog.
"""
def __init__(self, use_polling=False):

def __init__(self, event_queue, use_polling=False):
super(LivereloadWatchdogWatcher, self).__init__()
self._changed = False
# TODO: Hack.
Expand All @@ -70,7 +117,7 @@ def __init__(self, use_polling=False):
if use_polling:
self._observer = PollingObserver()
else:
self._observer = Observer()
self._observer = Observer(timeout=1000)
self._observer.start()

# Compatibility with livereload's builtin watcher
Expand All @@ -87,6 +134,8 @@ def __init__(self, use_polling=False):
# LiveReloadHandler's poll_tasks method.
self._changes = []

self.event_queue = event_queue

def set_changed(self):
self._changed = True

Expand All @@ -112,7 +161,7 @@ def watch(self, path, action, *args, **kwargs):
"""
if action is None:
action = _set_changed
event_handler = _WatchdogHandler(self, action)
event_handler = _WatchdogHandler(self, action, self.event_queue)
self._observer.schedule(event_handler, path=path, recursive=True)

def start(self, callback):
Expand All @@ -129,6 +178,7 @@ class SphinxBuilder(object):
"""
Helper class to run sphinx-build command.
"""

def __init__(self, outdir, args, ignored=None, regex_ignored=None):
self._outdir = outdir
self._args = args
Expand All @@ -149,6 +199,7 @@ def is_ignored(self, src_path):
return True

def __call__(self, watcher, src_path):

path = self.get_relative_path(src_path)

if self.is_ignored(src_path):
Expand All @@ -167,7 +218,6 @@ def build(self, path=None):
sys.stdout.write(pre)
sys.stdout.write('-' * (81 - len(pre)))
sys.stdout.write('\n')

args = ['sphinx-build'] + self._args
if pty:
master, slave = pty.openpty()
Expand Down Expand Up @@ -228,6 +278,8 @@ def get_parser():
parser = argparse.ArgumentParser()
parser.add_argument('-p', '--port', type=int, default=8000)
parser.add_argument('-H', '--host', type=str, default='127.0.0.1')
parser.add_argument('-ed', '--event-delay', type=int,
default=DEFAULT_EVENT_DELAY_TIME)
parser.add_argument('-r', '--re-ignore', action='append', default=[])
parser.add_argument('-i', '--ignore', action='append', default=[])
parser.add_argument('--poll', dest='use_polling',
Expand Down Expand Up @@ -297,10 +349,17 @@ def main():
else:
portn = port_for.select_random()

event_action_data = EventActionData()

builder = SphinxBuilder(outdir, build_args, ignored, re_ignore)
server = Server(
watcher=LivereloadWatchdogWatcher(use_polling=args.use_polling),
)
watcher = LivereloadWatchdogWatcher(event_action_data,
use_polling=args.use_polling)
action_thread = EventActionThread(
event_action_data, action=builder, watcher=watcher,
check_interval=args.event_delay)

server = Server(watcher=watcher)
action_thread.start()

server.watch(srcdir, builder)
for dirpath in args.additional_watched_dirs:
Expand All @@ -316,3 +375,9 @@ def main():
root=outdir, open_url_delay=args.delay)
else:
server.serve(port=portn, host=args.host, root=outdir)

try:
action_thread.kill()
action_thread.join()
except KeyboardInterrupt:
pass

0 comments on commit 09aafac

Please sign in to comment.