def test_root_url_site(config): config['root_url'] = 'root' strange_case(config) path_contents = { '001_2012_01_16_file.html': '1. 2012-01-16', 'index.html': """<doctype html> <body> <h1 id="welcome-to-my-blog">Welcome to my blog!</h1> <p>It is pretty great.</p> </body>""", 'blogs': { 'index.html': """<doctype html> <body> <p>My blogs:</p> <ol> <li><p><a href="/root/blogs/2012_01_01_post1.html">Post1</a></p></li> <li><p><a href="/root/blogs/2012_01_02_post2.html">Post2</a></p></li> </ol> <p>Hi!</p> </body>""", '2012_01_01_post1.html': True, '2012_01_02_post2.html': True, }, } check_path_contents(config['deploy_path'], path_contents)
def test_paginated_site(config): strange_case(config) path_contents = { 'index.html': True, 'blogs': { 'index.html': [ '<li><a href="/blogs/2012_01_01_post1.html">Post1</a></li>', '<li><a href="/blogs/2012_01_02_post2.html">Post2</a></li>', '<p>‹ First</p>', '<p>Page 1 of 3, items 1 to 2</p>', '<a href="/blogs/pagina2.html">Página 2</a> ›' ], 'pagina2.html': [ '<li><a href="/blogs/2012_01_03_post3.html">Post3</a></li>', '<li><a href="/blogs/2012_01_04_post4.html">Post4</a></li>', '<p>‹ <a href="/blogs/">Blogs</a></p>', '<p>Page 2 of 3, items 3 to 4</p>', '<a href="/blogs/pagina3.html">Página 3</a> ›' ], 'pagina3.html': [ '<li><a href="/blogs/2012_01_05_post5.html">Post5</a></li>', '<p>‹ <a href="/blogs/pagina2.html">Página 2</a></p>', '<p>Page 3 of 3, item 5</p>', '<p>› Last</p>' ], '2012_01_01_post1.html': True, '2012_01_02_post2.html': True, '2012_01_03_post3.html': True, '2012_01_04_post4.html': True, '2012_01_05_post5.html': True, }, } check_path_contents(config['deploy_path'], path_contents)
def on_any_event(self, event, alert=True): if self.last_run and time.time() - self.last_run < .1: return if alert: sys.stderr.write("Change detected. Running StrangeCase\n") strange_case(CONFIG) sys.stderr.write("StrangeCase generated at %i\n" % int(time.time())) self.last_run = time.time()
def on_any_event(self, event, alert=True): if self.last_run and time.time() - self.last_run < .1: return if alert: sys.stderr.write("Change detected. Running StrangeCase\n") try: strange_case(CONFIG) except Exception as e: exc_type, exc_value, exc_traceback = sys.exc_info() traceback.print_exception(exc_type, exc_value, exc_traceback, file=sys.stderr) sys.stderr.write("Error (%s): %s\n" % (type(e).__name__, e.message)) else: sys.stderr.write("StrangeCase generated at %i\n" % int(time.time())) self.last_run = time.time()
def test_override(config): # override configs that are otherwise not inherited, # but config.yaml and front matter should # override *that* strange_case(config) path_contents = { 'overridden_from_files.html': '<h1>Overridden from files</h1>', 'overridden_from_front_matter.html': '<h1>Overridden from front matter</h1>', 'not_overridden.html': '<h1>Overridden</h1>', 'index.html': '''<h1>Root title</h1> /not_overridden.html => <h2>Overridden</h2> /overridden_from_files.html => <h2>Overridden from files</h2> /overridden_from_front_matter.html => <h2>Overridden from front matter</h2>''', } check_path_contents(config['deploy_path'], path_contents)
def test_filters_site(config): strange_case(config) path_contents = { 'index.html': """ 12 May 2012 Sat May 12 09:59:11 2012 <p>Some <em>markdown</em> text</p> d8f4590320e1343a915b6394170650a8f35d6926 words ["more\\n\\ttext"] d15aacfd-62b6-594e-93cf-85baa5e441ec""", } check_path_contents(config['deploy_path'], path_contents)
def on_any_event(self, event, alert=True): if self.last_run and time.time() - self.last_run < .1: return if alert: sys.stderr.write("Change detected. Running StrangeCase\n") try: strange_case(CONFIG) except Exception as e: exc_type, exc_value, exc_traceback = sys.exc_info() traceback.print_exception(exc_type, exc_value, exc_traceback, file=sys.stderr) sys.stderr.write("Error (%s): %s\n" % (type(e).__name__, str(e))) else: sys.stderr.write("StrangeCase generated at %i\n" % int(time.time())) self.last_run = time.time()
def test_basic_site_remove_existing(config): # create extra files # this file does not exist in path_contents, and so # should be removed os.mkdir(config['deploy_path']) with open(join(config['deploy_path'], 'rm_this'), 'w') as f: f.write('blablabla') strange_case(config) path_contents = { '001_2012_01_16_file.html': True, 'index.html': True, 'blogs': { 'index.html': True, '2012_01_01_post1.html': True, '2012_01_02_post2.html': True, }, } check_path_contents(config['deploy_path'], path_contents)
def test_strip_extensions_site(config): config['configurators'].append('strange_case.extensions.configurators.strip_extensions') try: strange_case(config) except Exception: tree(config['site_path'], config['project_path']) tree(config['deploy_path'], config['project_path']) raise path_contents = { '001_2012_01_16_file.html': '1. 2012-01-16', 'index.html': """<doctype html> <body> <h1 id="welcome-to-my-blog">Welcome to my blog!</h1> <p>It is pretty great.</p> </body>""", 'blogs': { 'index.html': """<doctype html> <body> <p>My blogs:</p> <ol> <li><p><a href="/blogs/2012_01_01_post1">Post1</a></p></li> <li><p><a href="/blogs/2012_01_02_post2">Post2</a></p></li> </ol> <p>Hi!</p> </body>""", '2012_01_01_post1.html': """<doctype html> <body> <p>My first post, on 2012-01-01.</p> </body>""", '2012_01_02_post2.html': """<doctype html> <body> <p>My second post, on 2012-01-02.</p> </body>""", }, } check_path_contents(config['deploy_path'], path_contents)
def test_category_site(config): strange_case(config) path_contents = { 'index.html': True, 'blogs': { 'index.html': True, '2012_01_01_post1.html': True, '2012_01_02_post2.html': True, }, 'zee_categories': { 'index.html': [ 'Categories (2)', '<a href="/zee_categories/good.html">good</a>', '<a href="/zee_categories/bad.html">bad</a>' ], 'good.html': ['Category: good', 'Boring category page.'], 'bad.html': ['Category: bad', 'This category is bad.'], }, } check_path_contents(config['deploy_path'], path_contents)
def test_strip_extensions_and_meta_site(config): config['configurators'].append('strange_case.extensions.configurators.strip_extensions') config['strip_metadata_from_name'] = True config['strip_metadata_from_target_name'] = True strange_case(config) path_contents = { 'file.html': '1. 2012-01-16', 'index.html': """<doctype html> <body> <h1 id="welcome-to-my-blog">Welcome to my blog!</h1> <p>It is pretty great.</p> </body>""", 'blogs': { 'index.html': """<doctype html> <body> <p>My blogs:</p> <ol> <li><p><a href="/blogs/post1">Post1</a></p></li> <li><p><a href="/blogs/post2">Post2</a></p></li> </ol> <p>Hi!</p> </body>""", 'post1.html': """<doctype html> <body> <p>My first post, on 2012-01-01.</p> </body>""", 'post2.html': """<doctype html> <body> <p>My second post, on 2012-01-02.</p> </body>""", }, } check_path_contents(config['deploy_path'], path_contents)
def test_filters_site(config): strange_case(config) path_contents = { 'index.html': """ 12 May 2012 Sat May 12 09:59:11 2012 12 May 2012 Sat May 12 09:59:11 2012 <p>Some <em>markdown</em> text</p> d8f4590320e1343a915b6394170650a8f35d6926 words ["more\\n\\ttext"] d15aacfd-62b6-594e-93cf-85baa5e441ec""", } check_path_contents(config['deploy_path'], path_contents)
def test_basic_site(basic_config): strange_case(basic_config) path_contents = { '001_2012_01_16_file.html': '1. 2012-01-16', 'index.html': """<doctype html> <body> <h1 id="welcome-to-my-blog">Welcome to my blog!</h1> <p>It is pretty great.</p> </body>""", 'blogs': { 'index.html': """<doctype html> <body> <p>My blogs:</p> <ol> <li><p><a href="/blogs/2012_01_01_post1.html">Post1</a></p></li> <li><p><a href="/blogs/2012_01_02_post2.html">Post2</a></p></li> </ol> <p>Hi!</p> </body>""", '2012_01_01_post1.html': """<doctype html> <body> <p>My first post, on 2012-01-01.</p> </body>""", '2012_01_02_post2.html': """<doctype html> <body> <p>My second post, on 2012-01-02.</p> </body>""", }, } check_path_contents(basic_config['deploy_path'], path_contents)
def run(): import logging logging.basicConfig() import argparse parser = argparse.ArgumentParser(description=__doc__.splitlines()[0]) parser.add_argument('-w', '--watch', dest='watch', action='store_const', const=True, default=False, help='watch the site_path for changes') conf_overrides = [ 'project_path', 'site_path', 'deploy_path', 'remove_stale_files', 'config_file', '__verbose', ] parser.add_argument('-x', '--exclude', nargs='*', dest='exclude_paths', default=None) parser.add_argument('-p', '--project', dest='project_path') parser.add_argument('-s', '--site', dest='site_path') parser.add_argument('-d', '--deploy', dest='deploy_path') parser.add_argument('-r', '--remove', dest='remove_stale_files', action='store_true', default=None) parser.add_argument('-n', '--no-remove', dest='remove_stale_files', action='store_false', default=None) parser.add_argument('-c', '--config', dest='config_file') parser.add_argument('-v', '--verbose', dest='__verbose', action='store_true', default=False) parser.add_argument('--serve', dest='port', nargs="?", type=int, default=argparse.SUPPRESS, const=8000) parser.add_argument('configs', nargs='*') args = parser.parse_args() if args.project_path: if args.project_path[0] == '~': project_path = os.path.expanduser(args.project_path) else: project_path = os.path.abspath(args.project_path) else: project_path = os.getcwd() # config section catches assertion errors and prints them as error messages from strange_case.strange_case_config import CONFIG CONFIG['project_path'] = project_path if 'site_path' not in CONFIG: CONFIG['site_path'] = os.path.join(project_path, u'site/') if 'deploy_path' not in CONFIG: CONFIG['deploy_path'] = os.path.join(project_path, u'public/') # normalize paths for conf in ['site_path', 'deploy_path']: if CONFIG[conf][0] == '~': CONFIG[conf] = os.path.expanduser(CONFIG[conf]) elif CONFIG[conf][0] == '.': CONFIG[conf] = os.path.abspath(CONFIG[conf]) # now we can look for the app config if os.path.isfile(os.path.join(project_path, 'config.py')): config_module = imp.load_source('config', os.path.join(project_path, 'config.py')) if hasattr(config_module, 'CONFIG'): CONFIG.update(config_module.CONFIG) config_path = os.path.join(project_path, CONFIG['config_file']) if os.path.isfile(config_path): with open(config_path, 'r') as config_file: yaml_config = yaml.load(config_file) if yaml_config: CONFIG.update(yaml_config) for conf in conf_overrides: if getattr(args, conf) is not None: CONFIG[conf] = getattr(args, conf) for conf in args.configs: if ':' not in conf: raise TypeError('Cannot read config "{0}". Does not contain a ":"'.format(conf)) key, val = conf.split(':', 1) assign = CONFIG while ('.' in key) or ('[' in key and ']' in key): if '.' in key: dot = key.index('.') assign_key = key[:dot] key = key[dot + 1:] elif key[0] == '[': closing_bracket = key.index(']') assign_key = key[1:closing_bracket] key = key[closing_bracket + 1:] else: opening_bracket = key.index('[') assign_key = key[:opening_bracket] key = key[opening_bracket:] assign = CONFIG.get(assign_key, {}) assign[key] = val if CONFIG['config_hook']: CONFIG['config_hook'](CONFIG) del CONFIG['config_hook'] try: assert CONFIG['project_path'], "project_path is required" assert CONFIG['site_path'], "site_path is required" assert CONFIG['deploy_path'], "deploy_path is required" except AssertionError as e: sys.stderr.write("\033[1;31mError:\033[0m \033[1m" + e.message + "\033[0m\n") return if args.watch: import time from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler class Regenerate(FileSystemEventHandler): last_run = None def on_any_event(self, event, alert=True): if self.last_run and time.time() - self.last_run < .1: return if alert: sys.stderr.write("Change detected. Running StrangeCase\n") try: strange_case(CONFIG) except Exception as e: exc_type, exc_value, exc_traceback = sys.exc_info() traceback.print_exception(exc_type, exc_value, exc_traceback, file=sys.stderr) sys.stderr.write("Error (%s): %s\n" % (type(e).__name__, e.message)) else: sys.stderr.write("StrangeCase generated at %i\n" % int(time.time())) self.last_run = time.time() exclude_paths = [ os.path.abspath('.git'), os.path.abspath(CONFIG['deploy_path']), ] if args.exclude_paths: exclude_paths.extend([os.path.abspath(path) for path in args.exclude_paths]) observer = Observer() handler = Regenerate() for path in os.listdir(project_path): path = os.path.abspath(path) if os.path.isdir(path) and path not in exclude_paths: sys.stderr.write('Watching "%s" for changes\n' % path) observer.schedule(handler, path=path, recursive=True) observer.start() try: handler.on_any_event(None, False) # run the first time, no alert while True: time.sleep(1) except KeyboardInterrupt: sys.stderr.write("Stopping\n") observer.stop() observer.join() else: strange_case(CONFIG) if hasattr(args, 'port'): import SimpleHTTPServer import SocketServer args.port = args.port os.chdir(CONFIG['deploy_path']) Handler = SimpleHTTPServer.SimpleHTTPRequestHandler httpd = SocketServer.TCPServer(("", args.port), Handler) sys.stderr.write("serving at http://localhost:{port}\n".format(port=args.port)) httpd.serve_forever()
def run(): import logging logging.basicConfig() # so that strange_case.py can be executed from any project folder, add CWD to the import paths sys.path.insert(0, os.getcwd()) import argparse parser = argparse.ArgumentParser(description='Process some integers.') parser.add_argument('-w', '--watch', dest='watch', action='store_const', const=True, default=False, help='watch the site_path for changes (default: find the max)') conf_overrides = [ 'project_path', 'site_path', 'deploy_path', 'remove_stale_files', 'config_file', ] parser.add_argument('-x', '--exclude', nargs='*', dest='exclude_paths', default=None) parser.add_argument('-p', '--project', dest='project_path') parser.add_argument('-s', '--site', dest='site_path') parser.add_argument('-d', '--deploy', dest='deploy_path') parser.add_argument('-r', '--remove', dest='remove_stale_files', action='store_true', default=None) parser.add_argument('-n', '--no-remove', dest='remove_stale_files', action='store_false', default=None) parser.add_argument('-c', '--config', dest='config_file') parser.add_argument('configs', nargs='*') # config section catches assertion errors and prints them as error messages try: if os.path.isfile(os.path.join(os.getcwd(), 'config.py')): from config import CONFIG if not isinstance(CONFIG, ConfigDict): CONFIG = ConfigDict(CONFIG) else: from strange_case.strange_case_config import CONFIG # normalize paths for conf in ['project_path', 'site_path', 'deploy_path']: if CONFIG[conf][0] == '~': CONFIG[conf] = os.path.expanduser(CONFIG[conf]) elif CONFIG[conf][0] == '.': CONFIG[conf] = os.path.abspath(CONFIG[conf]) # now we can look for the app config config_path = os.path.join(CONFIG['project_path'], CONFIG['config_file']) if os.path.isfile(config_path): with open(config_path, 'r') as config_file: yaml_config = yaml.load(config_file) if yaml_config: CONFIG.update(yaml_config) args = parser.parse_args() for conf in conf_overrides: if getattr(args, conf) is not None: CONFIG[conf] = getattr(args, conf) assign = None for confs in args.configs: if assign: CONFIG[assign] = confs assign = None elif ':' in confs: key, val = confs.split(':', 1) CONFIG[key] = val else: assign = confs if CONFIG['config_hook']: CONFIG['config_hook'](CONFIG) del CONFIG['config_hook'] assert CONFIG['project_path'], "project_path is required" assert CONFIG['site_path'], "site_path is required" assert CONFIG['deploy_path'], "deploy_path is required" except AssertionError as e: sys.stderr.write("\033[1;31mError:\033[0m \033[1m" + e.message + "\033[0m\n") return if not os.path.isdir(CONFIG['deploy_path']): os.mkdir(CONFIG['deploy_path']) from strange_case.support.jinja import StrangeCaseEnvironment extensions = [] if 'extensions' in CONFIG: for extension in CONFIG['extensions']: if isinstance(extension, basestring): try: extension = fancy_import(extension) except ImportError: sys.error.write('Error in processors: Could not find "%s"\n' % extension) raise extensions.append(extension) del CONFIG['extensions'] if not Registry.get('jinja_environment', None): jinja_environment = StrangeCaseEnvironment(extensions=extensions, project_path=CONFIG['project_path']) Registry.set('jinja_environment', jinja_environment) else: jinja_environment = Registry.get('jinja_environment') if 'filters' in CONFIG: for filter_name, method in CONFIG['filters'].iteritems(): if isinstance(method, basestring): try: method = fancy_import(method) except ImportError: sys.error.write('Error in filters: Could not find "%s"\n' % method) raise jinja_environment.filters[filter_name] = method del CONFIG['filters'] if 'processors' in CONFIG: for processor in CONFIG['processors']: try: fancy_import(processor) except ImportError: sys.error.write('Error in processors: Could not find "%s"\n' % processor) raise del CONFIG['processors'] configurators = [] if 'configurators' in CONFIG: for configurator in CONFIG['configurators']: if isinstance(configurator, basestring): configurator = fancy_import(configurator) configurators.append(configurator) Registry.add_configurator(configurator) del CONFIG['configurators'] # additional configurators, in addition to the all-important defaults if 'configurators +' in CONFIG: for configurator in CONFIG['configurators +']: if isinstance(configurator, basestring): configurator = fancy_import(configurator) configurators.append(configurator) Registry.add_configurator(configurator) del CONFIG['configurators +'] # additional file_types for entry in Registry.file_types: CONFIG['file_types'].append(entry) if 'file_types +' in CONFIG: CONFIG['file_types'].extend(CONFIG['file_types +']) # read timestamps file timestamps_file = os.path.join(CONFIG['project_path'], '.timestamps') if os.path.exists(timestamps_file): CONFIG['file_mtimes'] = pickle.load(open(timestamps_file)) timestamps = {} for file_tracked in Node.files_tracked: f = os.path.abspath(file_tracked) timestamps[f] = os.stat(file_tracked).st_mtime if args.watch: import time from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler class Regenerate(FileSystemEventHandler): last_run = None def on_any_event(self, event, alert=True): if self.last_run and time.time() - self.last_run < .1: return if alert: sys.stderr.write("Change detected. Running StrangeCase\n") strange_case(CONFIG) sys.stderr.write("StrangeCase generated at %i\n" % int(time.time())) self.last_run = time.time() exclude_paths = [ os.path.abspath('.git'), os.path.abspath(CONFIG['deploy_path']), ] if args.exclude_paths: exclude_paths.extend([os.path.abspath(path) for path in args.exclude_paths]) observer = Observer() handler = Regenerate() for path in os.listdir(os.getcwd()): path = os.path.abspath(path) if os.path.isdir(path) and path not in exclude_paths: sys.stderr.write('Watching "%s" for changes\n' % path) observer.schedule(handler, path=path, recursive=True) observer.start() try: handler.on_any_event(None, False) # run the first time, no alert while True: time.sleep(1) except KeyboardInterrupt: sys.stderr.write("Stopping\n") observer.stop() observer.join() else: strange_case(CONFIG)
def run(): import logging logging.basicConfig() import argparse parser = argparse.ArgumentParser(description=__doc__.splitlines()[0]) parser.add_argument('-w', '--watch', dest='watch', action='store_const', const=True, default=False, help='watch the site_path for changes') conf_overrides = [ 'project_path', 'site_path', 'deploy_path', 'remove_stale_files', 'config_file', '__verbose', ] parser.add_argument('-x', '--exclude', nargs='*', dest='exclude_paths', default=None) parser.add_argument('-p', '--project', dest='project_path') parser.add_argument('-s', '--site', dest='site_path') parser.add_argument('-d', '--deploy', dest='deploy_path') parser.add_argument('-r', '--remove', dest='remove_stale_files', action='store_true', default=None) parser.add_argument('-n', '--no-remove', dest='remove_stale_files', action='store_false', default=None) parser.add_argument('-c', '--config', dest='config_file') parser.add_argument('-v', '--verbose', dest='__verbose', action='store_true', default=False) parser.add_argument('--serve', dest='port', nargs="?", type=int, default=argparse.SUPPRESS, const=8000) parser.add_argument('configs', nargs='*') args = parser.parse_args() if args.project_path: if args.project_path[0] == '~': project_path = os.path.expanduser(args.project_path) else: project_path = os.path.abspath(args.project_path) else: project_path = os.getcwd() # config section catches assertion errors and prints them as error messages from strange_case.strange_case_config import CONFIG CONFIG['project_path'] = project_path if 'site_path' not in CONFIG: CONFIG['site_path'] = os.path.join(project_path, u'site/') if 'deploy_path' not in CONFIG: CONFIG['deploy_path'] = os.path.join(project_path, u'public/') # normalize paths for conf in ['site_path', 'deploy_path']: if CONFIG[conf][0] == '~': CONFIG[conf] = os.path.expanduser(CONFIG[conf]) elif CONFIG[conf][0] == '.': CONFIG[conf] = os.path.abspath(CONFIG[conf]) # now we can look for the app config if os.path.isfile(os.path.join(project_path, 'config.py')): config_module = imp.load_source( 'config', os.path.join(project_path, 'config.py')) if hasattr(config_module, 'CONFIG'): CONFIG.update(config_module.CONFIG) config_path = os.path.join(project_path, CONFIG['config_file']) if os.path.isfile(config_path): with open(config_path, 'r') as config_file: yaml_config = yaml.load(config_file) if yaml_config: CONFIG.update(yaml_config) for conf in conf_overrides: if getattr(args, conf) is not None: CONFIG[conf] = getattr(args, conf) for conf in args.configs: if ':' not in conf: raise TypeError( 'Cannot read config "{0}". Does not contain a ":"'.format( conf)) key, val = conf.split(':', 1) assign = CONFIG while ('.' in key) or ('[' in key and ']' in key): if '.' in key: dot = key.index('.') assign_key = key[:dot] key = key[dot + 1:] elif key[0] == '[': closing_bracket = key.index(']') assign_key = key[1:closing_bracket] key = key[closing_bracket + 1:] else: opening_bracket = key.index('[') assign_key = key[:opening_bracket] key = key[opening_bracket:] assign = CONFIG.get(assign_key, {}) assign[key] = val if CONFIG['config_hook']: CONFIG['config_hook'](CONFIG) del CONFIG['config_hook'] try: assert CONFIG['project_path'], "project_path is required" assert CONFIG['site_path'], "site_path is required" assert CONFIG['deploy_path'], "deploy_path is required" except AssertionError as e: sys.stderr.write("\033[1;31mError:\033[0m \033[1m" + str(e) + "\033[0m\n") return if args.watch: import time from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler class Regenerate(FileSystemEventHandler): last_run = None def on_any_event(self, event, alert=True): if self.last_run and time.time() - self.last_run < .1: return if alert: sys.stderr.write("Change detected. Running StrangeCase\n") try: strange_case(CONFIG) except Exception as e: exc_type, exc_value, exc_traceback = sys.exc_info() traceback.print_exception(exc_type, exc_value, exc_traceback, file=sys.stderr) sys.stderr.write("Error (%s): %s\n" % (type(e).__name__, str(e))) else: sys.stderr.write("StrangeCase generated at %i\n" % int(time.time())) self.last_run = time.time() exclude_paths = [ os.path.abspath('.git'), os.path.abspath('.hg'), os.path.abspath('.svn'), os.path.abspath(CONFIG['deploy_path']), ] if args.exclude_paths: exclude_paths.extend( [os.path.abspath(path) for path in args.exclude_paths]) observer = Observer() handler = Regenerate() for path in os.listdir(project_path): path = os.path.abspath(path) if os.path.isdir(path) and path not in exclude_paths: sys.stderr.write('Watching "%s" for changes\n' % path) observer.schedule(handler, path=path, recursive=True) observer.start() try: handler.on_any_event(None, False) # run the first time, no alert while True: time.sleep(1) except KeyboardInterrupt: sys.stderr.write("Stopping\n") observer.stop() observer.join() else: strange_case(CONFIG) if hasattr(args, 'port'): import SimpleHTTPServer import SocketServer args.port = args.port os.chdir(CONFIG['deploy_path']) Handler = SimpleHTTPServer.SimpleHTTPRequestHandler httpd = SocketServer.TCPServer(("", args.port), Handler) sys.stderr.write( "serving at http://localhost:{port}\n".format(port=args.port)) httpd.serve_forever()
def test_missing_category_site(config): with pytest.raises(NotImplementedError): strange_case(config)