Beispiel #1
0
 def setUp(self):
     directory = os.path.dirname(os.path.realpath(__file__))
     delogx = os.path.dirname(os.path.dirname(directory))
     sys.path.insert(0, delogx)
     filename = os.path.join(directory, 'test_app', 'config.json')
     from DelogX.utils.config import Config
     self.config = Config(filename)
Beispiel #2
0
    def __init__(self, app_path, framework, config='config.json'):
        '''Initialize DelogX object.

        Args:

            app_path (str): Absolute path of the blog application.
            framework (Flask): Flask application object.
            config (str): Config file of DelogX, defaults `config.json`.
        '''
        self.framework = framework
        app_path = os.path.realpath(app_path)
        config = Path.abs_path(app_path, config)
        config = Config(config)
        runtime = Config()
        module_path = os.path.dirname(os.path.realpath(__file__))
        runtime.let('path.app', app_path)
        runtime.let('path.module', module_path)
        ver_file = os.path.join(module_path, 'VERSION')
        with codecs.open(ver_file, encoding='utf-8') as f:
            version = ''.join(f.readlines()).strip()
        runtime.let('blog.version', version)
        self.config = config
        self.runtime = runtime
        self.markdown_ext = list()
        self.init_runtime()
        self.init_plugins()
        self.init_bundles()
        self.init_route()
        self.update_header()
Beispiel #3
0
class DelogFeed(Plugin):

    config = None
    feed_url = None
    feed_limit = 10

    def run(self):
        self.config = Config(os.path.join(self.workspace, 'config.json'))
        self.feed_url = self.config.get('delog_feed.url')
        self.feed_limit = self.config.get('delog_feed.limit')
        if not self.feed_url:
            self.feed_url = '/feed'
        if not self.feed_limit:
            self.feed_limit = 10
        self.feed_url = Path.format_url(self.feed_url)
        if not self.feed_url.endswith('/'):
            self.feed_url += '/'
        self.blog.add_url_rule(self.feed_url, 'delog_feed', self.make_feed)
        self.manager.add_filter('dx_render', self.add_link)

    def add_link(self, render):
        site_name = self.blog.default_conf('site.name')
        copy = render.lower()
        search = '<head>'
        tag = ('<link href="{href}" rel="alternate" '
               'title="{title}" type="application/atom+xml">').format(
                   href=self.feed_url, title=site_name)
        try:
            index = copy.index(search) + len(search)
            render = render[:index] + tag + render[index:]
        except ValueError:
            render = render + tag
        return render

    def make_feed(self):
        site_name = self.blog.default_conf('site.name')
        feed = AtomFeed(site_name, feed_url=request.url, url=request.url_root)
        posts = self.blog.post_bundle.get_list(1, self.feed_limit)
        for post in posts:
            post = self.manager.do_filter('dx_post', post)
            ext_url = request.url_root
            if ext_url.endswith('/'):
                ext_url = ext_url[:-1]
            ext_url = ext_url + post.cooked_url
            update_time = datetime.datetime.fromtimestamp(post.time)
            content = Markdown.markdown(post.markdown, self.blog.markdown_ext)
            feed.add(title=post.title,
                     title_type='text',
                     content=content,
                     content_type='html',
                     url=ext_url,
                     author=site_name,
                     updated=update_time,
                     published=update_time)
        return feed.get_response()
Beispiel #4
0
 def run(self):
     self.config = Config(os.path.join(self.workspace, 'config.json'))
     self.feed_url = self.config.get('delog_feed.url')
     self.feed_limit = self.config.get('delog_feed.limit')
     if not self.feed_url:
         self.feed_url = '/feed'
     if not self.feed_limit:
         self.feed_limit = 10
     self.feed_url = Path.format_url(self.feed_url)
     if not self.feed_url.endswith('/'):
         self.feed_url += '/'
     self.blog.add_url_rule(self.feed_url, 'delog_feed', self.make_feed)
     self.manager.add_filter('dx_render', self.add_link)
Beispiel #5
0
 def run(self):
     conf = self.blog.default_conf
     self.config = Config(os.path.join(self.workspace, 'config.json'))
     self.i18n = I18n(
         Path.format_url(self.workspace, 'locale'), conf('local.locale'))
     self.tags_url = self.config.get('delog_tags.url')
     if not self.tags_url:
         self.tags_url = '/tag'
     self.tags_url = Path.format_url(self.tags_url)
     tag_rule = Path.format_url(self.tags_url, '<tag_id>/')
     tag_list_rule = Path.format_url(tag_rule, '<int:number>/')
     self.blog.add_url_rule(tag_rule, 'delog_tag', self.make_tag)
     self.blog.add_url_rule(
         tag_list_rule, 'delog_tag_list', self.make_tag_list)
     self.manager.add_action('dx_post_update', self.load_tags)
Beispiel #6
0
    def __init__(self, directory, locale):
        '''Initialize i18n manager.

        Args:

            directory (str): Name of the i18n directory.
            locale (str): Current locale.
        '''
        self.directory = directory
        self.locale = locale
        self.data = Config(os.path.join(directory, locale, 'locale.json'))
Beispiel #7
0
def init(init_args):
    '''Create a new blog application.'''
    module_path = os.path.dirname(os.path.realpath(__file__))
    sys.path.append(os.path.dirname(module_path))
    from DelogX.utils.config import Config
    cwd = os.getcwd()
    defaults = os.path.join(module_path, 'defaults')
    if os.listdir(cwd) and not init_args.force:
        print('''The current directory is not empty,\n'''
              '''use `delogx init --force' if you want to overwrite.''')
        return
    locale_dir = os.path.join(module_path, 'locale')
    locales = list()
    for lang in os.listdir(locale_dir):
        if os.path.isdir(os.path.join(locale_dir, lang)):
            locales.append(lang)
    locale = ''
    if init_args.locale and init_args.locale in locales:
        locale = init_args.locale
    elif init_args.locale:
        print('''Unknown locale '{}'. Abort.'''.format(init_args.locale))
        sys.exit(1)
    else:
        while locale not in locales:
            print('Choose Language({0}):'.format(','.join(locales)))
            locale = input('> ')
    copytree(defaults, cwd)
    print('Setting language', locale)
    config = Config(os.path.join(cwd, 'config.json'))
    config.let('local.locale', locale)
    config.save()
    print('Creating demo post')
    post_dir = os.path.join(cwd, 'posts')
    print(' Creating {0}'.format(post_dir))
    if os.path.isfile(post_dir):
        os.remove(post_dir)
    if not os.path.exists(post_dir):
        os.makedirs(post_dir)
    post_path = os.path.join(post_dir, 'hello-delogx.md')
    print(' Copying {0}'.format(post_path))
    shutil.copyfile(os.path.join(locale_dir, locale, 'hello-delogx.md'),
                    post_path)
    print('Creating demo page')
    page_dir = os.path.join(cwd, 'pages')
    print(' Creating {0}'.format(page_dir))
    if os.path.isfile(page_dir):
        os.remove(page_dir)
    if not os.path.exists(page_dir):
        os.makedirs(page_dir)
    page_path = os.path.join(page_dir, 'demo.md')
    print(' Copying {0}'.format(page_path))
    shutil.copyfile(os.path.join(locale_dir, locale, 'demo.md'), page_path)
    print('''Blog created successfully, edit 'config.json' to configure.''')
Beispiel #8
0
    def load(self, plugin_name):
        '''Load a plugin by name.

        Args:

            plugin_name (str): Name of the plugin.

        Returns:

            object: Entry object of the plugin.
        '''
        plugin_dir = os.path.join(self.directory, plugin_name)
        plugin_meta = os.path.join(plugin_dir, 'plugin.json')
        name_re = re.compile(r'^[A-Za-z_][0-9A-Za-z_]*$')
        if (not os.path.isfile(plugin_meta)
                or name_re.match(plugin_name) is None):
            return None
        init_py = os.path.join(plugin_dir, '__init__.py')
        if not os.path.exists(init_py):
            open(init_py, 'a').close()
        meta = Config(plugin_meta)
        entry_name = meta.get('entry').strip(". \n\r\t")
        author = meta.get('author', '')
        version = meta.get('version', '')
        description = meta.get('description', '')
        if not entry_name or plugin_name in self.plugins:
            return None
        module_name = [plugin_name]
        module_name.extend(entry_name.split('.')[:-1])
        module_name = '.'.join(module_name)
        class_name = ''.join(entry_name.split('.')[-1:])
        module = importlib.import_module(module_name)
        entry = getattr(module, class_name)(self.blog)
        entry.name = plugin_name
        entry.workspace = plugin_dir
        self.plugins[plugin_name] = {
            'entry': entry,
            'author': author,
            'version': version,
            'description': description
        }
        return entry
Beispiel #9
0
class DelogTags(Plugin):

    config = None
    tags_url = None
    i18n = None

    def run(self):
        conf = self.blog.default_conf
        self.config = Config(os.path.join(self.workspace, 'config.json'))
        self.i18n = I18n(
            Path.format_url(self.workspace, 'locale'), conf('local.locale'))
        self.tags_url = self.config.get('delog_tags.url')
        if not self.tags_url:
            self.tags_url = '/tag'
        self.tags_url = Path.format_url(self.tags_url)
        tag_rule = Path.format_url(self.tags_url, '<tag_id>/')
        tag_list_rule = Path.format_url(tag_rule, '<int:number>/')
        self.blog.add_url_rule(tag_rule, 'delog_tag', self.make_tag)
        self.blog.add_url_rule(
            tag_list_rule, 'delog_tag_list', self.make_tag_list)
        self.manager.add_action('dx_post_update', self.load_tags)

    def load_tags(self, *args, **kwargs):
        post = kwargs.get('post')
        if not post:
            return
        post.tags = list()
        title = post.title
        title_split = list(filter(None, title.split('::', 1)))
        if title_split:
            post.title = title_split[0].strip()
            tags = ''.join(title_split[1:]).split(',')
            post.tags = list(filter(None, list(map(str.strip, tags))))
            tags_link = list()
            tags_html = '<div class="post-tags">{0}</div>'
            for tag in post.tags:
                tags_link.append('<a href="{0}">{1}</a>'.format(
                    Path.format_url(self.tags_url, Path.urlencode(tag)), tag))
            if tags_link:
                tags_html = tags_html.format(' '.join(tags_link))
                post.content = tags_html + post.content

    def make_tag(self, tag_id):
        return self.make_tag_list(tag_id, 1)

    def make_tag_list(self, tag_id, number):
        tag_id = Path.urldecode(tag_id)
        conf = self.blog.default_conf
        list_size = conf('local.list_size')
        bundle = self.blog.post_bundle.bundle_list
        tagged = [
            post for post in bundle.values()
            if not post.hidden and tag_id in post.tags
        ]
        list_count = int(math.ceil(float(len(tagged)) / float(list_size)))
        if not 0 < number <= list_count:
            abort(404)
        if tagged is None or list_count < 1:
            abort(404)
        post_list = tagged[
            list_size * (number - 1):list_size * number
        ]
        for post in post_list:
            post = self.blog.plugin_manager.do_filter('dx_post', post)
        prev_page = next_page = True
        if number == 1:
            prev_page = False
        if number == list_count:
            next_page = False
        list_url = Path.format_url(self.tags_url, tag_id)
        url = list_url if list_url.endswith('/') else list_url + '/'
        web_title = self.i18n.get('{0} - Page {1}', tag_id, number)
        return self.blog.get_render(
            'list.html', posts=post_list,
            list_id=number, list_url=url,
            prev_page=prev_page, next_page=next_page,
            web_title=web_title)
Beispiel #10
0
class TestConfig(unittest.TestCase):
    def setUp(self):
        directory = os.path.dirname(os.path.realpath(__file__))
        delogx = os.path.dirname(os.path.dirname(directory))
        sys.path.insert(0, delogx)
        filename = os.path.join(directory, 'test_app', 'config.json')
        from DelogX.utils.config import Config
        self.config = Config(filename)

    def test_string(self):
        self.assertEqual(self.config.get('entry_a.key_1_1'), 'String')

    def test_number(self):
        self.assertEqual(self.config.get('entry_a.key_1_2'), 1000)
        self.assertAlmostEqual(self.config.get('entry_a.key_1_3'), -30.75)

    def test_null(self):
        self.assertIsNone(self.config.get('entry_b.key_2_1'))

    def test_bool(self):
        self.assertTrue(self.config.get('entry_b.key_2_2'))
        self.assertFalse(self.config.get('entry_b.key_2_3'))

    def test_list(self):
        equal_list = ["List_1_1", "List_1_2"]
        self.assertListEqual(self.config.get('entry_c.key_3_1'), equal_list)

    def test_nest(self):
        self.assertEqual(self.config.get('entry_c.key_3_2.key_3_2_1.test_1'),
                         'Test 1')
        self.assertEqual(
            self.config.get('entry_c.key_3_2.key_3_2_1.key_3_2_2.test_2'),
            'Test 2')
        self.assertEqual(self.config.get('entry_c.key_3_2.key_3_2_3.test_3'),
                         'Test 3')

    def test_let(self):
        self.config.let('test', 'Test A')
        self.config.let('test2.a.b.c', 'Test B')
        self.config.let('entry_a.test', 'Test C')
        self.config.let('entry_a.test2', 'Test D')
        self.assertEqual(self.config.get('test'), 'Test A')
        self.assertEqual(self.config.get('test2.a.b.c'), 'Test B')
        self.assertEqual(self.config.get('entry_a.test'), 'Test C')
        self.assertEqual(self.config.get('entry_a.test2'), 'Test D')

    def test_delete(self):
        self.config.let('test', 'Test A')
        self.config.let('test2.a.b.c', 'Test B')
        self.assertEqual(self.config.get('test'), 'Test A')
        self.assertEqual(self.config.get('test2.a.b.c'), 'Test B')
        value_a = self.config.delete('test')
        value_b = self.config.delete('test2.a.b.c')
        self.assertEqual(value_a, 'Test A')
        self.assertEqual(value_b, 'Test B')
        self.assertIsNone(self.config.get('test'))
        self.assertIsNone(self.config.get('test2.a.b.c'))