예제 #1
0
 def restore(self):
     self.process_admin(self.data['admin'])
     Signal.send('restore',
                 'bearblog',
                 data=self.data,
                 directory=os.path.dirname(self.file_path))
     db.session.commit()
예제 #2
0
def edit_page():
    if request.method == 'POST':
        title = request.form['title']
        slug = request.form['slug']
        body = request.form['body']
        timestamp = datetime.utcfromtimestamp(int(request.form['timestamp']))
        page = Page.query.get(int(request.form['id']))
        if page.repository_id is None:
            repository_id = str(uuid4())
        else:
            repository_id = page.repository_id
        new_page = Page(title=title, slug=slug, body=body, timestamp=timestamp, author=page.author, repository_id=repository_id, status='published')
        Signal.send('duplicate', old_page=page, new_page=new_page)
        widgets_dict = json.loads(request.form['widgets'])
        for slug, js_data in widgets_dict.items():
            Signal.send('submit_edit_widget', slug=slug, js_data=js_data, page=new_page)
        db.session.add(new_page)
        db.session.commit()
    else:
        cleanup_temp_page()
        if 'id' in request.args:
            page = Page.query.get(int(request.args['id']))
        else:
            page = Page(status='temp')
            db.session.add(page)
            db.session.commit()
        widgets = []
        widgets.extend(Signal.send('edit_widget', page=page))
        return current_plugin.render_template('edit.html', page=page, widgets=widgets)
예제 #3
0
def restore(data):
    if 'page' in data:
        pages = data['page']
        for page in pages:
            p = Page(title=page['title'], slug=page['slug'], body=page['body'], timestamp=datetime.utcfromtimestamp(page['timestamp']), status=page['version']['status'], repository_id=page['version']['repository_id'], author=User.query.filter_by(username=page['author']).one())
            db.session.add(p)
            db.session.flush()
            Signal.send('restore', page=p, data=page)
예제 #4
0
파일: api.py 프로젝트: zhantong/penguin
def navbar():
    custom_navbar = {'brand': '', 'items': [], 'templates': []}

    def process_item(item):
        def insert_item(item):
            if item['type'] == 'brand':
                custom_navbar['brand'] = item['brand']
            elif item['type'] == 'item':
                item.pop('type')
                custom_navbar['items'].append(item)
            elif item['type'] == 'template':
                item.pop('type')
                custom_navbar['templates'].append(item)

        more = item.pop('more', None)
        if 'type' in item:
            insert_item(item)
        if more is not None:
            for item in more:
                insert_item(item)

    navbar_items = Signal.send('navbar_item')
    for navbar_item in navbar_items:
        process_item(navbar_item)
    return custom_navbar
예제 #5
0
 def to_json(self, level='brief'):
     json = {
         'id': self.id,
         'number': self.number,
         'title': self.title,
         'timestamp':
         self.timestamp.replace(tzinfo=timezone.utc).isoformat(),
         'author': self.author.to_json(level)
     }
     json['plugin'] = Signal.send('to_json', article=self, level=level)
     if level.startswith('admin_'):
         json['repositoryId'] = self.repository_id
         json['status'] = self.status
         json['versionTimestamp'] = self.version_timestamp
         if level == 'admin_brief':
             return json
         json['bodyAbstract'] = self.body_abstract
         if level == 'admin_basic':
             return json
         json['body'] = self.body
         if level == 'admin_full':
             return json
     else:
         if level == 'brief':
             return json
         json['bodyAbstract'] = self.body_abstract
         if level == 'basic':
             return json
         json['body'] = self.body
         json['bodyHtml'] = self.body_html
         if level == 'full':
             return json
예제 #6
0
파일: plugin.py 프로젝트: zhantong/penguin
def get_admin_widget_article_list(params):
    def get_articles(repository_id):
        return Article.query.filter_by(repository_id=repository_id).order_by(
            Article.version_timestamp.desc()).all()

    page = 1
    if 'page' in params:
        page = int(params['page'])
    query = db.session.query(Article.repository_id).group_by(
        Article.repository_id).order_by(Article.version_timestamp.desc())
    query = {'query': query}
    filter(query, request.args)
    query = query['query']
    pagination = query.paginate(page,
                                per_page=get_setting('items_per_page').value,
                                error_out=False)
    repository_ids = [item[0] for item in pagination.items]
    custom_columns = Signal.send('custom_list_column')
    return current_plugin.render_template('list.html',
                                          repository_ids=repository_ids,
                                          pagination={
                                              'pagination': pagination,
                                              'fragment': {},
                                              'url_for': plugin_url_for,
                                              'url_for_params': {
                                                  'args': ['list'],
                                                  'kwargs': {
                                                      '_component': 'admin'
                                                  }
                                              }
                                          },
                                          get_articles=get_articles,
                                          custom_columns=custom_columns)
예제 #7
0
파일: api.py 프로젝트: zhantong/penguin
def admin_api_proxy(id, path):
    article = Article.query.get(id)
    widget = path.split('/')[0]
    return Signal.send('admin_api_proxy',
                       widget=widget,
                       path=path,
                       request=request,
                       article=article)
예제 #8
0
파일: plugin.py 프로젝트: zhantong/penguin
def restore(data, directory):
    if 'article' in data:
        articles = data['article']
        for article in articles:
            a = Article(
                title=article['title'],
                body=article['body'],
                timestamp=datetime.utcfromtimestamp(article['timestamp']),
                author=User.query.filter_by(username=article['author']).one(),
                repository_id=article['version']['repository_id'],
                status=article['version']['status'])
            db.session.add(a)
            db.session.flush()
            Signal.send('restore',
                        article=a,
                        data=article,
                        directory=directory)
예제 #9
0
파일: api.py 프로젝트: zhantong/penguin
def api_proxy(number, path):
    article = Article.query.filter_by(number=number).first_or_404()
    widget = path.split('/')[0]
    return Signal.send('api_proxy',
                       widget=widget,
                       path=path,
                       request=request,
                       article=article)
예제 #10
0
파일: plugin.py 프로젝트: zhantong/penguin
def upload():
    if 'files[]' not in request.files:
        return jsonify({'code': 1, 'message': '上传文件不存在'})
    file = request.files['files[]']
    if file.filename == '':
        return jsonify({'code': 2, 'message': '未选择上传文件'})
    filename = file.filename
    if '.' not in filename or filename.rsplit('.', 1)[1].lower(
    ) not in get_setting('allowed_upload_file_extensions').value:
        return jsonify({'code': 3, 'message': '禁止上传的文件类型'})
    extension = filename.rsplit('.', 1)[1].lower()
    random_filename = uuid.uuid4().hex + '.' + extension
    abs_file_path = os.path.join(current_app.config['TEMP_FOLDER'],
                                 random_filename)
    os.makedirs(os.path.dirname(abs_file_path), exist_ok=True)
    file.save(abs_file_path)
    attachment = Attachment.create(abs_file_path,
                                   original_filename=filename,
                                   file_extension=extension,
                                   mime=file.mimetype)
    db.session.add(attachment)
    db.session.commit()
    meta = json.loads(request.form.get('meta', type=str))
    if 'article_id' in meta:
        article = Signal.send('get_article',
                              'article',
                              article_id=meta['article_id'])
        article.attachments.append(attachment)
        db.session.commit()
    if 'page_id' in meta:
        page = Signal.send('get_page', 'page', page_id=meta['page_id'])
        page.attachments.append(attachment)
        db.session.commit()
    return jsonify({
        'code':
        0,
        'message':
        '上传成功',
        'file_size':
        attachment.file_size,
        'relative_path':
        random_filename,
        'delete_url':
        component_url_for('.upload_delete', 'admin', id=attachment.id)
    })
예제 #11
0
파일: api.py 프로젝트: zhantong/penguin
def create_article():
    data = request.get_json()
    title = data['title']
    body = data['body']
    timestamp = dateutil.parser.parse(data['timestamp'])
    status = data['status']
    current_username = get_jwt_identity()
    user = User.query.filter_by(username=current_username).first()
    new_article = Article(title=title,
                          body=body,
                          timestamp=timestamp,
                          author=user,
                          repository_id=str(uuid4()),
                          status=status)
    Signal.send('update_article', article=new_article, data=data['plugin'])
    db.session.add(new_article)
    db.session.commit()
    return admin_article(new_article.id)
예제 #12
0
def pages():
    pages = Page.query.all()
    more = []
    for page in pages:
        more.append({'title': page.title, 'slug': page.slug})
    dynamic_pages = Signal.send('dynamic_page')
    for page in dynamic_pages:
        more.append({'title': page['title'], 'slug': page['slug']})
    return {'pages': more}
예제 #13
0
def index():
    widgets = Signal.send('widget', end_point='.index', request=request)
    main_widgets = widgets['main']
    left_widgets = widgets['left']
    right_widgets = widgets['right']

    return render_template('index.html',
                           main_widgets=main_widgets,
                           left_widgets=left_widgets,
                           right_widgets=right_widgets)
예제 #14
0
파일: plugin.py 프로젝트: zhantong/penguin
def get_comment_show_info(comment):
    if comment.article is not None:
        return {
            'title':
            comment.article.title,
            'url':
            Signal.send('article_url',
                        'article',
                        article=comment.article,
                        anchor='comment-' + str(comment.id))
        }
    if comment.page is not None:
        return {
            'title':
            comment.page.title,
            'url':
            Signal.send('page_url',
                        'page',
                        page=comment.page,
                        anchor='comment-' + str(comment.id))
        }
예제 #15
0
파일: plugin.py 프로젝트: zhantong/penguin
def on_changed_article_body(target, value, oldvalue, initiator):
    class Renderer(mistune.Renderer):
        def __init__(self):
            super().__init__()
            self.toc_count = 0

        def header(self, text, level, raw=None):
            rv = '<h%d id="toc-%d">%s</h%d>\n' % (level, self.toc_count, text,
                                                  level)
            self.toc_count += 1
            return rv

    renderer = Renderer()
    markdown = mistune.Markdown(renderer=renderer)

    if Signal.send('should_compile_markdown_when_body_change', article=target):
        html = markdown(value)
        target.body_html = html
        target.body_abstract = RE_HTML_TAGS.sub('',
                                                target.body_html)[:200] + '...'
        Signal.send('after_markdown_converted', article=target, html=html)
예제 #16
0
def update_page(id):
    data = request.get_json()
    title = data['title']
    body = data['body']
    timestamp = dateutil.parser.parse(data['timestamp'])
    page = Page.query.get(int(id))
    if page.repository_id is None:
        repository_id = str(uuid4())
    else:
        repository_id = page.repository_id
    new_page = Page(title=title,
                    body=body,
                    timestamp=timestamp,
                    author=page.author,
                    repository_id=repository_id,
                    status='published')
    Signal.send('duplicate', old_page=page, new_page=new_page)
    Signal.send('update_page', page=new_page, data=data['plugin'])
    db.session.add(new_page)
    db.session.commit()
    return admin_page(new_page.id)
예제 #17
0
파일: plugin.py 프로젝트: zhantong/penguin
def test_send_mail():
    if request.method == 'GET':
        return current_plugin.render_template('test_send_mail.html')
    elif request.method == 'POST':
        recipient = request.form.get('recipient')
        subject = request.form.get('subject')
        body = request.form.get('body')
        result = Signal.send('send_mail',
                             recipient=recipient,
                             subject=subject,
                             body=body)

        return jsonify(result)
예제 #18
0
파일: api.py 프로젝트: zhantong/penguin
def update_article(id):
    data = request.get_json()
    title = data['title']
    body = data['body']
    timestamp = dateutil.parser.parse(data['timestamp'])
    status = data['status']
    article = Article.query.get(int(id))
    if article.repository_id is None:
        repository_id = str(uuid4())
    else:
        repository_id = article.repository_id
    new_article = Article(title=title,
                          body=body,
                          timestamp=timestamp,
                          author=article.author,
                          repository_id=repository_id,
                          status=status)
    Signal.send('duplicate', old_article=article, new_article=new_article)
    Signal.send('update_article', article=new_article, data=data['plugin'])
    db.session.add(new_article)
    db.session.commit()
    return admin_article(new_article.id)
예제 #19
0
파일: plugin.py 프로젝트: zhantong/penguin
def submit_comment():
    js_captcha = request.form.get('js_captcha', type=str)
    print(js_captcha)
    print(session['js_captcha'])
    if js_captcha != session['js_captcha']:
        return jsonify({'code': 1, 'message': '发表失败'})
    if request.headers.getlist('X-Forwarded-For'):
        ip = request.headers.getlist('X-Forwarded-For')[0]
    else:
        ip = request.remote_addr
    if ENABLE_TENCENT_CAPTCHA:
        tencent_captcha = json.loads(
            request.form.get('tencent_captcha', type=str))
        params = {
            'aid': '2006905249',
            'AppSecretKey': '0L5LG6K3Qe09PGS3P6-6YMQ**',
            'Ticket': tencent_captcha['ticket'],
            'Randstr': tencent_captcha['randstr'],
            'UserIP': ip
        }
        with urllib.request.urlopen(
                'https://ssl.captcha.qq.com/ticket/verify' + '?' +
                urllib.parse.urlencode(params)) as f:
            result = json.loads(f.read().decode())
            if result['response'] != '1':
                return jsonify({'code': 1, 'message': '发表失败'})
    meta = json.loads(request.form.get('meta', type=str))
    parent = request.form.get('parent', type=int)
    name = request.form.get('name', type=str)
    email = request.form.get('email', None, type=str)
    body = request.form.get('body', type=str)
    if current_user.is_authenticated:
        author = current_user._get_current_object()
    else:
        author = User.create(role=Role.guest(), name=name, email=email)
        db.session.add(author)
        db.session.flush()
    agent = request.user_agent.string
    comment = Comment(body=body,
                      parent=parent,
                      author=author,
                      ip=ip,
                      agent=agent)
    db.session.add(comment)
    db.session.commit()
    if 'article_id' in meta:
        article = Signal.send('get_article',
                              'article',
                              article_id=meta['article_id'])
        article.comments.append(comment)
        db.session.commit()
    elif 'page_id' in meta:
        page = Signal.send('get_page', 'page', page_id=meta['page_id'])
        page.comments.append(comment)
        db.session.commit()
    Signal.send('on_new_comment', comment=comment, meta=meta)
    Signal.send('comment_submitted', comment=comment)
    return jsonify({'code': 0, 'message': '发表成功'})
예제 #20
0
def navbar_item():
    pages = Page.query.all()
    more = []
    for page in pages:
        more.append({
            'type': 'item',
            'name': page.title,
            'link': component_url_for('show_page', 'main', slug=page.slug)
        })
    dynamic_pages = Signal.send('dynamic_page')
    for page in dynamic_pages:
        more.append({
            'type': 'item',
            'name': page['title'],
            'link': component_url_for('show_page', 'main', slug=page['slug'])
        })
    return {
        'more': more
    }
예제 #21
0
파일: plugin.py 프로젝트: zhantong/penguin
def dynamic_page():
    articles = Article.query_published().order_by(
        Article.timestamp.desc()).all()
    custom_columns = Signal.send('custom_contents_column')
    return {
        'title':
        '文章目录',
        'slug':
        'list',
        'html':
        current_plugin.render_template('dynamic_page_contents',
                                       'contents.html',
                                       articles=articles,
                                       custom_columns=custom_columns),
        'script':
        current_plugin.render_template('dynamic_page_contents',
                                       'contents.js.html'),
        'style':
        ''
    }
예제 #22
0
def show_page(slug):
    def get_pages(repository_id):
        return Page.query.filter_by(repository_id=repository_id).order_by(Page.timestamp.desc()).all()

    page = Page.query.filter_by(slug=slug).order_by(Page.version_timestamp.desc())
    if 'version' in request.args:
        page = page.filter_by(number=request.args['version'])
    page = page.first()
    if page is not None:
        left_widgets = []
        right_widgets = []
        after_page_widgets = []
        cookies_to_set = {}
        metas = Signal.send('meta', page=page)
        widgets = Signal.send('show_page_widget', session=session, page=page)
        for widget in widgets:
            if widget['slug'] == 'comment':
                after_page_widgets.append(widget)
        Signal.send('on_showing_page', page=page, request=request, cookies_to_set=cookies_to_set)
        Signal.send('modify_page_when_showing', page=page)
        resp = make_response(current_plugin.render_template('page.html', page=page, after_page_widgets=after_page_widgets, left_widgets=left_widgets, right_widgets=right_widgets, get_pages=get_pages, metas=metas))
        for key, value in cookies_to_set.items():
            resp.set_cookie(key, value)
        return resp
    else:
        page = None
        dynamic_pages = Signal.send('dynamic_page')
        for dynamic_page in dynamic_pages:
            if dynamic_page['slug'] == slug:
                page = dynamic_page
                break
        if page is None:
            abort(404)
        left_widgets = []
        right_widgets = []
        scripts = []
        styles = []
        scripts.append(page['script'])
        styles.append(page['style'])
        resp = make_response(current_plugin.render_template('dynamic_page.html', page=page, left_widgets=left_widgets, right_widgets=right_widgets, scripts=scripts, styles=styles))
        return resp
예제 #23
0
파일: plugin.py 프로젝트: zhantong/penguin
def article_list():
    if request.method == 'POST':
        if request.form['action'] == 'delete':
            result = delete(request.form['id'])
            return jsonify(result)
        else:
            article_id = request.form['id']
            action = request.form['action']
            article = Article.query.get(article_id)
            if action == 'publish':
                article.status = 'published'
            elif action == 'archive':
                article.status = 'archived'
            elif action == 'draft':
                article.status = 'draft'
            elif action == 'hide':
                article.status = 'hidden'
            db.session.commit()

            return jsonify({'result': 'OK'})
    else:
        cleanup_temp_article()
        return Signal.send('get_admin_article_list', params=request.args)
예제 #24
0
파일: models.py 프로젝트: zhantong/penguin
    def __init__(self,
                 name,
                 directory,
                 slug=None,
                 show_in_sidebar=True,
                 config=None):
        if slug is None:
            caller = inspect.getframeinfo(inspect.stack()[1][0])
            caller_path = caller.filename
            slug = Path(caller_path).parent.name
        Plugin.plugins[slug] = self
        self.name = name
        self.slug = slug
        self.directory = directory
        self.show_in_sidebar = show_in_sidebar
        self.signal = Signal(self)
        self.rule_map = Map()
        self.view_functions = {}
        self.config = config or {}

        if 'default_setting_category' in self.config:
            add_default_cateogry(self.directory,
                                 self.config['default_setting_category'])
예제 #25
0
파일: plugin.py 프로젝트: zhantong/penguin
def show_article(number):
    def get_articles(repository_id):
        return Article.query.filter_by(repository_id=repository_id).order_by(
            Article.timestamp.desc()).all()

    article = Article.query.filter_by(number=number)
    if 'version' in request.args:
        article = article.filter_by(number=request.args['version'])
    article = article.first_or_404()
    cookies_to_set = {}
    metas = Signal.send('meta', article=article)
    header_keywords = Signal.send('header_keyword', article=article)
    widgets = Signal.send('show_article_widget',
                          session=session,
                          article=article)
    right_widgets = widgets['right']
    left_widgets = widgets['left']
    after_article_widgets = widgets['bottom']
    Signal.send('on_showing_article',
                article=article,
                request=request,
                cookies_to_set=cookies_to_set)
    Signal.send('modify_article_when_showing', article=article)
    resp = make_response(
        current_plugin.render_template(
            'article.html',
            article=article,
            after_article_widgets=after_article_widgets,
            left_widgets=left_widgets,
            right_widgets=right_widgets,
            get_articles=get_articles,
            metas=metas,
            header_keywords=header_keywords))
    for key, value in cookies_to_set.items():
        resp.set_cookie(key, value)
    return resp
예제 #26
0
def admin_article_list_url(**kwargs):
    return Signal.send('admin_article_list_url', 'article', params=kwargs)
예제 #27
0
def global_restore(data):
    if 'tag' in data:
        Signal.send('restore', tags=data['tag'], restored_tags=[])
예제 #28
0
def article_restore(article, data):
    if 'tags' in data:
        article.tags = Signal.send('restore', tags=data['tags'])
예제 #29
0
from flask import flash, jsonify, redirect, request

from bearblog.plugins import current_plugin, plugin_route, plugin_url_for
from .models import Tag
from bearblog.models import Signal
from bearblog.extensions import db
from bearblog.utils import slugify
from bearblog.settings import get_setting

Signal = Signal(None)
Signal.set_default_scope(current_plugin.slug)


@Signal.connect('restore')
def restore_tags(tags):
    restored_tags = []
    for tag in tags:
        if type(tag) is str:
            tag = {'name': tag}
        t = Tag.query.filter_by(name=tag['name']).first()
        if t is None:
            t = Tag.create(name=tag['name'],
                           slug=slugify(tag['name']),
                           description=tag.get('description', ''))
            db.session.add(t)
            db.session.flush()
        else:
            if t.description is None or t.description == '':
                t.description = tag.get('description', '')
        restored_tags.append(t)
    db.session.flush()
예제 #30
0
파일: api.py 프로젝트: zhantong/penguin
from flask import request, Response

from bearblog import current_component, component_route
from .models import Settings
from bearblog.models import Signal
from bearblog.extensions import db

Signal = Signal(None)
Signal.set_default_scope(current_component.slug)


@component_route('/settings/<category>',
                 'get_settings',
                 'api_admin',
                 methods=['GET'])
def get_settings(category):
    settings = Settings.query.filter_by(category=category).all()
    return {'value': [setting.to_json() for setting in settings]}


@component_route('/settings/<int:id>',
                 'update_settings',
                 'api_admin',
                 methods=['PATCH'])
def update_settings(id):
    setting = Settings.query.get(id)
    data = request.get_json()
    setting.value = data['rawValue']
    db.session.commit()
    return Response(status=200)