Exemple #1
0
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>&lsaquo; First</p>',
                '<p>Page 1 of 3, items 1 to 2</p>',
                '<a href="/blogs/pagina2.html">Página 2</a> &rsaquo;'
            ],
            '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>&lsaquo; <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> &rsaquo;'
            ],
            'pagina3.html': [
                '<li><a href="/blogs/2012_01_05_post5.html">Post5</a></li>',
                '<p>&lsaquo; <a href="/blogs/pagina2.html">Página 2</a></p>',
                '<p>Page 3 of 3, item 5</p>',
                '<p>&rsaquo; 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)
Exemple #3
0
            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()
Exemple #4
0
            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)
Exemple #7
0
            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_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)
Exemple #10
0
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_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)
Exemple #12
0
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_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>&lsaquo; First</p>', '<p>Page 1 of 3, items 1 to 2</p>',
                '<a href="/blogs/pagina2.html">Página 2</a> &rsaquo;'
            ],
            '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>&lsaquo; <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> &rsaquo;'
            ],
            'pagina3.html': [
                '<li><a href="/blogs/2012_01_05_post5.html">Post5</a></li>',
                '<p>&lsaquo; <a href="/blogs/pagina2.html">Página 2</a></p>',
                '<p>Page 3 of 3, item 5</p>', '<p>&rsaquo; 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 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)
Exemple #17
0
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()
Exemple #18
0
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)
Exemple #19
0
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()
Exemple #20
0
def test_missing_category_site(config):
    with pytest.raises(NotImplementedError):
        strange_case(config)