Ejemplo n.º 1
0
def render(site: Site) -> None:
    logger = logging.getLogger()
    site.resources.copytree(join('public', 'static'),
                            site.configuration.www_directory_path)
    static_environment = create_environment(site)
    render_tree(site.configuration.www_directory_path,
                static_environment, site.configuration)
    sass.render_tree(site.configuration.www_directory_path)
    for locale, locale_configuration in site.configuration.locales.items():
        localized_environment = create_environment(site, locale)
        if site.configuration.multilingual:
            www_directory_path = join(
                site.configuration.www_directory_path, locale_configuration.alias)
        else:
            www_directory_path = site.configuration.www_directory_path

        site.resources.copytree(
            join('public', 'localized'), www_directory_path)
        render_tree(www_directory_path,
                    localized_environment, site.configuration)

        _render_entity_type(www_directory_path, site.ancestry.files.values(
        ), 'file', site.configuration, locale, localized_environment)
        logger.info('Rendered %d files in %s.' %
                    (len(site.ancestry.files), locale))
        _render_entity_type(www_directory_path, site.ancestry.people.values(
        ), 'person', site.configuration, locale, localized_environment)
        logger.info('Rendered %d people in %s.' %
                    (len(site.ancestry.people), locale))
        _render_entity_type(www_directory_path, site.ancestry.places.values(
        ), 'place', site.configuration, locale, localized_environment)
        logger.info('Rendered %d places in %s.' %
                    (len(site.ancestry.places), locale))
        _render_entity_type(www_directory_path, site.ancestry.events.values(
        ), 'event', site.configuration, locale, localized_environment)
        logger.info('Rendered %d events in %s.' %
                    (len(site.ancestry.events), locale))
        _render_entity_type(www_directory_path, site.ancestry.citations.values(
        ), 'citation', site.configuration, locale, localized_environment)
        logger.info('Rendered %d citations in %s.' %
                    (len(site.ancestry.citations), locale))
        _render_entity_type(www_directory_path, site.ancestry.sources.values(
        ), 'source', site.configuration, locale, localized_environment)
        logger.info('Rendered %d sources in %s.' %
                    (len(site.ancestry.sources), locale))
        with Translations(site.translations[locale]):
            _render_openapi(www_directory_path, site)
        logger.info('Rendered OpenAPI documentation.')
    chmod(site.configuration.www_directory_path, 0o755)
    for directory_path, subdirectory_names, file_names in os.walk(site.configuration.www_directory_path):
        for subdirectory_name in subdirectory_names:
            chmod(join(directory_path, subdirectory_name), 0o755)
        for file_name in file_names:
            chmod(join(directory_path, file_name), 0o644)
    site.event_dispatcher.dispatch(PostRenderEvent())
Ejemplo n.º 2
0
 def test_with_unknown_plugin_class(self):
     with TemporaryDirectory() as www_directory_path:
         environment = create_environment(
             Site(Configuration(www_directory_path, 'https://example.com')))
         template = '{% if "betty.UnknownPlugin" in plugins %}true{% else %}false{% endif %}'
         self.assertEquals('false',
                           environment.from_string(template).render())
Ejemplo n.º 3
0
def render(site: Site) -> None:
    logger = logging.getLogger()
    environment = create_environment(site)
    _render_public(site, environment)
    _render_entity_type(site, environment, site.ancestry.files.values(),
                        'file')
    logger.info('Rendered %d files.' % len(site.ancestry.files))
    _render_entity_type(site, environment, site.ancestry.people.values(),
                        'person')
    logger.info('Rendered %d people.' % len(site.ancestry.people))
    _render_entity_type(site, environment, site.ancestry.places.values(),
                        'place')
    logger.info('Rendered %d places.' % len(site.ancestry.places))
    _render_entity_type(site, environment, site.ancestry.events.values(),
                        'event')
    logger.info('Rendered %d events.' % len(site.ancestry.events))
    _render_entity_type(site, environment, site.ancestry.citations.values(),
                        'citation')
    logger.info('Rendered %d citations.' % len(site.ancestry.citations))
    _render_entity_type(site, environment, site.ancestry.sources.values(),
                        'source')
    logger.info('Rendered %d sources.' % len(site.ancestry.sources))
    chmod(site.configuration.www_directory_path, 0o755)
    for directory_path, subdirectory_names, file_names in os.walk(
            site.configuration.www_directory_path):
        for subdirectory_name in subdirectory_names:
            chmod(join(directory_path, subdirectory_name), 0o755)
        for file_name in file_names:
            chmod(join(directory_path, file_name), 0o644)
    site.event_dispatcher.dispatch(PostRenderEvent(environment))
Ejemplo n.º 4
0
 def test(self, expected, template, data):
     with TemporaryDirectory() as www_directory_path:
         environment = create_environment(
             Site(Configuration(www_directory_path, 'https://example.com')))
         self.assertEquals(
             expected,
             environment.from_string(template).render(data=data))
Ejemplo n.º 5
0
    def test_filter(self, m_expanduser, m_requests):
        with TemporaryDirectory() as cache_directory_path:
            m_expanduser.side_effect = lambda _: cache_directory_path
            with TemporaryDirectory() as output_directory_path:
                configuration = Configuration(output_directory_path,
                                              'https://ancestry.example.com')
                configuration.plugins[Wikipedia] = {}

                environment = create_environment(Site(configuration))
                page_uri = 'https://en.wikipedia.org/wiki/Amsterdam'
                link = Link(page_uri)
                api_uri = 'https://en.wikipedia.org/w/api.php?action=query&titles=Amsterdam&prop=extracts&exintro&format=json&formatversion=2'
                title = 'Amstelredam'
                extract = 'De hoofdstad van Nederland.'
                api_response_body = {
                    'query': {
                        'pages': [
                            {
                                'title': title,
                                'extract': extract,
                            },
                        ],
                    }
                }
                m_requests.register_uri('GET', api_uri, json=api_response_body)
                actual = environment.from_string(
                    '{% for entry in ([link] | wikipedia) %}{{ entry.content }}{% endfor %}'
                ).render(link=link)
                self.assertEquals(extract, actual)
Ejemplo n.º 6
0
 def test_with_disabled_plugin(self):
     with TemporaryDirectory() as www_directory_path:
         environment = create_environment(
             Site(Configuration(www_directory_path, 'https://example.com')))
         template = '{% if "' + TestPlugin.__module__ + \
             '.TestPlugin" in plugins %}true{% else %}false{% endif %}'
         self.assertEquals('false',
                           environment.from_string(template).render())
Ejemplo n.º 7
0
 def test(self):
     with TemporaryDirectory() as www_directory_path:
         configuration = Configuration(www_directory_path,
                                       'https://example.com')
         environment = create_environment(Site(configuration))
         template = '{{ date | format_date }}'
         date = Date(1970, 1, 1)
         self.assertEquals(
             'January 1, 1970',
             environment.from_string(template).render(date=date))
Ejemplo n.º 8
0
 def test_with_empty_iterable(self):
     with TemporaryDirectory() as www_directory_path:
         configuration = Configuration(www_directory_path,
                                       'https://example.com')
         environment = create_environment(Site(configuration))
         template = '{{ data | sort_localizeds(localized_attribute="names", sort_attribute="name") }}'
         data = []
         self.assertEquals(
             '[]',
             environment.from_string(template).render(data=data))
Ejemplo n.º 9
0
 def test(self, expected, template, file):
     with TemporaryDirectory() as output_directory_path:
         configuration = Configuration(output_directory_path,
                                       'https://example.com')
         environment = create_environment(Site(configuration))
         actual = environment.from_string(template).render(file=file)
         self.assertEquals(expected, actual)
         for file_path in actual.split(':'):
             self.assertTrue(
                 exists(
                     join(configuration.www_directory_path, file_path[1:])))
Ejemplo n.º 10
0
    def test_empty(self):
        with TemporaryDirectory() as output_directory_path:
            configuration = Configuration(output_directory_path,
                                          'https://example.com')
            configuration.locales['en-US'] = LocaleConfiguration('en-US', 'en')
            configuration.locales['nl-NL'] = LocaleConfiguration('nl-NL', 'nl')
            site = Site(configuration)
            environment = create_environment(site)

            indexed = list(index(site, environment))

            self.assertEquals([], indexed)
Ejemplo n.º 11
0
    def _render_config(self) -> None:
        output_directory_path = os.path.join(self._site.configuration.output_directory_path, 'nginx')
        makedirs(output_directory_path)

        # Render the ngnix configuration.
        file_name = 'nginx.conf.j2'
        destination_file_path = os.path.join(output_directory_path, file_name)
        self._site.resources.copy2(file_name, destination_file_path)

        # Render the Dockerfile.
        render_file(destination_file_path, create_environment(self._site))
        copyfile(os.path.join(DOCKER_PATH, 'Dockerfile'), os.path.join(output_directory_path, 'Dockerfile'))
Ejemplo n.º 12
0
    def test_person_without_names(self):
        with TemporaryDirectory() as output_directory_path:
            configuration = Configuration(output_directory_path,
                                          'https://example.com')
            configuration.locales['en-US'] = LocaleConfiguration('en-US', 'en')
            configuration.locales['nl-NL'] = LocaleConfiguration('nl-NL', 'nl')
            site = Site(configuration)
            environment = create_environment(site)
            person_id = 'P1'
            person = Person(person_id)
            site.ancestry.people[person_id] = person

            indexed = list(index(site, environment))

            self.assertEquals([], indexed)
Ejemplo n.º 13
0
    def test_file_without_description(self):
        with TemporaryDirectory() as output_directory_path:
            configuration = Configuration(output_directory_path,
                                          'https://example.com')
            configuration.locales['en-US'] = LocaleConfiguration('en-US', 'en')
            configuration.locales['nl-NL'] = LocaleConfiguration('nl-NL', 'nl')
            site = Site(configuration)
            environment = create_environment(site)
            file_id = 'F1'
            file = File(file_id, __file__)
            site.ancestry.files[file_id] = file

            indexed = list(index(site, environment))

            self.assertEquals([], indexed)
Ejemplo n.º 14
0
    def test_person_with_affiliation_name(self, expected: str, locale: str):
        with TemporaryDirectory() as output_directory_path:
            configuration = Configuration(output_directory_path,
                                          'https://example.com')
            configuration.locales['en-US'] = LocaleConfiguration('en-US', 'en')
            configuration.locales['nl-NL'] = LocaleConfiguration('nl-NL', 'nl')
            site = Site(configuration)
            environment = create_environment(site, locale)
            person_id = 'P1'
            affiliation_name = 'Doughnut'
            person = Person(person_id)
            person.names.append(PersonName(None, affiliation_name))
            site.ancestry.people[person_id] = person

            indexed = list(index(site, environment))

            self.assertEquals('doughnut', indexed[0]['text'])
            self.assertIn(expected, indexed[0]['result'])
Ejemplo n.º 15
0
    def test_file(self, expected: str, locale: str):
        with TemporaryDirectory() as output_directory_path:
            configuration = Configuration(output_directory_path,
                                          'https://example.com')
            configuration.locales['en-US'] = LocaleConfiguration('en-US', 'en')
            configuration.locales['nl-NL'] = LocaleConfiguration('nl-NL', 'nl')
            site = Site(configuration)
            environment = create_environment(site, locale)
            file_id = 'F1'
            file = File(file_id, __file__)
            file.description = '"file" is Dutch for "traffic jam"'
            site.ancestry.files[file_id] = file

            indexed = list(index(site, environment))

            self.assertEquals('"file" is dutch for "traffic jam"',
                              indexed[0]['text'])
            self.assertIn(expected, indexed[0]['result'])
Ejemplo n.º 16
0
    def test_place(self, expected: str, locale: str):
        with TemporaryDirectory() as output_directory_path:
            configuration = Configuration(output_directory_path,
                                          'https://example.com')
            configuration.locales['en-US'] = LocaleConfiguration('en-US', 'en')
            configuration.locales['nl-NL'] = LocaleConfiguration('nl-NL', 'nl')
            site = Site(configuration)
            environment = create_environment(site, locale)
            place_id = 'P1'
            place = Place(place_id, [
                LocalizedName('Netherlands', 'en'),
                LocalizedName('Nederland', 'nl')
            ])
            site.ancestry.places[place_id] = place

            indexed = list(index(site, environment))

            self.assertEquals('netherlands nederland', indexed[0]['text'])
            self.assertIn(expected, indexed[0]['result'])
Ejemplo n.º 17
0
 def test(self):
     with TemporaryDirectory() as www_directory_path:
         configuration = Configuration(www_directory_path,
                                       'https://example.com')
         environment = create_environment(Site(configuration))
         template = '{{ data | sort_localizeds(localized_attribute="names", sort_attribute="name") }}'
         data = [
             self.WithLocalizedNames('third', [
                 LocalizedName('3', 'nl-NL'),
             ]),
             self.WithLocalizedNames('second', [
                 LocalizedName('2', 'en'),
                 LocalizedName('1', 'nl-NL'),
             ]),
             self.WithLocalizedNames('first', [
                 LocalizedName('2', 'nl-NL'),
                 LocalizedName('1', 'en-US'),
             ]),
         ]
         self.assertEquals(
             '[first, second, third]',
             environment.from_string(template).render(data=data))
Ejemplo n.º 18
0
 def _index(self) -> Iterable:
     # Create the environment here, because doing so in the initializer would be at a time when not all plugins have
     # been initialized yet
     environment = create_environment(self._site)
     for person in self._site.ancestry.people.values():
         yield {
             'text': ('%s %s' %
                      (person.individual_name, person.family_name)).lower(),
             'result':
             environment.get_template(
                 'search-result-person.html.j2').render({
                     'person': person,
                 })
         }
     for place in self._site.ancestry.places.values():
         yield {
             'text':
             place.name.lower(),
             'result':
             environment.get_template('search-result-place.html.j2').render(
                 {
                     'place': place,
                 })
         }
Ejemplo n.º 19
0
    def _render(self) -> None:
        js_plugins = list([plugin for plugin in self._site.plugins.values(
        ) if isinstance(plugin, JsPackageProvider)])
        js_plugin_names = [plugin.name() for plugin in js_plugins]
        build_id = hashlib.md5(':'.join(js_plugin_names).encode()).hexdigest()
        build_directory_path = path.join(
            self._site.configuration.cache_directory_path, self.name(), betty_instance_id(), build_id)

        # Build plugins' JavaScript assets.
        dependencies = {}
        environment = create_environment(self._site)
        for plugin in [self] + js_plugins:
            plugin_build_directory_path = path.join(
                build_directory_path, plugin.name())
            with _NodeModulesBackup(plugin_build_directory_path):
                try:
                    shutil.rmtree(plugin_build_directory_path)
                except FileNotFoundError:
                    pass
                shutil.copytree(path.join(plugin.resource_directory_path, 'js'),
                                plugin_build_directory_path)
            render_tree(plugin_build_directory_path, environment)
            if not isinstance(plugin, self.__class__):
                dependencies['%s' % plugin.name(
                )] = 'file:%s' % plugin_build_directory_path
                with open(path.join(plugin_build_directory_path, 'package.json'), 'r+') as package_json_f:
                    package_json = json.load(package_json_f)
                    package_json['name'] = plugin.name()
                    package_json_f.seek(0)
                    json.dump(package_json, package_json_f)

        js_plugin_build_directory_path = path.join(
            build_directory_path, self.name())

        # Add dependencies to the JavaScript plugin.
        with open(path.join(js_plugin_build_directory_path, 'package.json'), 'r+') as package_json_f:
            package_json = json.load(package_json_f)
            package_json['dependencies'].update(dependencies)
            package_json['scripts'] = {
                'webpack': 'webpack --config ./webpack.config.js',
            }
            package_json_f.seek(0)
            json.dump(package_json, package_json_f)

        # Install third-party dependencies.
        check_call(['npm', 'install', '--production'],
                   cwd=js_plugin_build_directory_path)

        # Run Webpack.
        self._site.resources.copy2(path.join(self._site.configuration.www_directory_path, 'betty.css'), path.join(
            js_plugin_build_directory_path, 'betty.css'))
        check_call(['npm', 'run', 'webpack'],
                   cwd=js_plugin_build_directory_path)
        try:
            shutil.copytree(path.join(build_directory_path, 'output', 'images'), path.join(
                self._site.configuration.www_directory_path, 'images'))
        except FileNotFoundError:
            # There may not be any images.
            pass
        shutil.copy2(path.join(build_directory_path, 'output', 'betty.css'), path.join(
            self._site.configuration.www_directory_path, 'betty.css'))
        shutil.copy2(path.join(build_directory_path, 'output', 'betty.js'), path.join(
            self._site.configuration.www_directory_path, 'betty.js'))