Esempio n. 1
0
 def get_settings_keys_config(self, keys_config_path):
     if not isinstance(keys_config_path, string_types):
         return {}
     keys_config = get_json_content_by_path(
         self.bucket, keys_config_path
     ) or builtin_site_settings_keys_config_info.get(keys_config_path)
     if not isinstance(keys_config, dict):
         keys_config = {}
     return keys_config
Esempio n. 2
0
 def get_settings_from_json(self, config_path):
     if not isinstance(config_path, string_types):
         return {}
     if not re.match("__\w+\.json", config_path):
         return {}
     if not self.bucket:
         return {}
     settings_from_json = get_json_content_by_path(self.bucket, config_path)
     if not isinstance(settings_from_json, dict):
         settings_from_json = {}
     return settings_from_json
Esempio n. 3
0
File: my.py Progetto: zhiiker/FarBox
def setting_settings_view():
    bucket = get_logined_bucket(check=True)
    if not bucket:
        return abort(410)
    data_obj = get_json_content_by_path(bucket, 'settings.json') or {}
    if request.method == "POST":
        keys = request.values.keys()
        data_obj = get_data_obj_from_POST(keys)
        sync_file_by_server_side(bucket,
                                 "settings.json",
                                 content=json_dumps(data_obj, indent=4))

    return render_api_template_as_response("page_user_site_settings.jade",
                                           data_obj=data_obj)
Esempio n. 4
0
def get_nav_items_from_site_configs(bucket):
    # nav_configs & user_nav_disabled 两个属性,是在线编辑 nav 时写入 configs/nav_config.json 中的
    if not bucket:
        return []
    nav_config = get_json_content_by_path(bucket, 'nav.json') or {}
    if not nav_config:
        return []
    site_nav_configs = nav_config.get('nav_configs') or []
    if nav_config.get('user_nav_disabled', False):
        # 用户(拖拽)自定义的导航被禁用了
        site_nav_configs = []
    if not isinstance(site_nav_configs, (list, tuple)):
        return []
    nav_items = []
    for nav_item in site_nav_configs:
        if isinstance(nav_item, dict) and 'name' in nav_item and 'url' in nav_item:
            nav_items.append(nav_item)
    return nav_items
Esempio n. 5
0
def get_auto_nav_items(bucket):  # 自动生成的
    pages_configs = get_bucket_pages_configs(bucket)
    nav_items = []
    homepage_url = '/'
    if request.args.get('status') == 'loaded':
        homepage_url = '/?status=loaded'
    homepage_nav_item = dict(name='Home', url=homepage_url)
    nav_items.append(homepage_nav_item)

    site_configs = get_bucket_site_configs(bucket)
    albums_root = smart_unicode(site_configs.get("albums_root", "")).strip()
    if albums_root:
        nav_items.append(dict(name="Album", url="/album"))

    wiki_configs = get_json_content_by_path(bucket,
                                            "__wiki.json",
                                            force_dict=True)
    wiki_root = wiki_configs.get("wiki_root")
    enable_wiki_nodes = auto_type(wiki_configs.get("enable_wiki_nodes", True))
    if wiki_root:
        nav_items.append(dict(name="Wiki", url="/wiki"))

        if enable_wiki_nodes:
            nav_items.append(dict(name="Wiki Nodes", url="/wiki_nodes"))

    if 'categories.jade' in pages_configs:
        # 有 categories.jade 的呈现
        nav_items.append(dict(name='Categories', url='/categories'))
    if 'archive.jade' in pages_configs:  # archive 页面
        nav_items.append(dict(name='Archive', url='/archive'))

    if has_markdown_record_by_path_prefix(bucket, "links"):
        nav_items.append(dict(name='Links', url='/__page/links'))

    if has_markdown_record_by_path_prefix(bucket, "about"):
        nav_items.append(dict(name='About', url='/__page/about'))

    if has_markdown_record_by_path_prefix(bucket, "contact"):
        nav_items.append(dict(name='Contact', url='/__page/contact'))

    if 'feed.jade' in pages_configs:
        nav_items.append(dict(name='Feed', url='/feed'))

    return nav_items
Esempio n. 6
0
 def update_json(self, path, **kwargs):
     # 更新一个 json 文件,用 simple_sync 的调用
     # 注意,调用这个函数的时候,并不需要管理员权限,所以,要慎重处理!!!!
     if not path.lower().endswith('.json'):
         return 'must be a json file'
     json_data = get_json_content_by_path(self.bucket, path)
     if not isinstance(json_data, dict):
         return 'update_json failed, not a dict obj'
     to_update = False
     for key, value in kwargs.items():
         old_value = json_data.get(key)
         if value != old_value:
             to_update = True
             break
     if to_update:
         json_data.update(kwargs)
         new_content = json.dumps(json_data, indent=4)
         sync_file_by_server_side(bucket=self.bucket, relative_path=path, content=new_content, is_dir=False, is_deleted=False)
     return ''
Esempio n. 7
0
def show_wiki_nodes_as_sub_site():
    bucket = get_bucket_in_request_context()
    if not bucket:
        return
    request_path = get_request_path().strip("/")
    if not re.match("wiki_nodes(/|$)", request_path):
        return
    wiki_configs = get_json_content_by_path(bucket, "__wiki.json", force_dict=True)
    enable_wiki_nodes = auto_type(wiki_configs.get("enable_wiki_nodes", True))
    if not enable_wiki_nodes:
        return
    wiki_root = smart_unicode(wiki_configs.get("wiki_root", ""))
    if not wiki_root:
        return
    wiki_root = wiki_root.strip("/")
    wiki_title = wiki_configs.get("wiki_title") or get_just_name(wiki_root, for_folder=True)
    path = request.values.get("path", "").strip("/")
    if request.values.get("type") == "data":
        # return json data
        wiki_root = wiki_root.lower()
        under = "%s/%s" % (wiki_root, path)
        posts_info = get_bucket_posts_info(bucket)
        data = filter_and_get_posts_link_points_info(posts_info, under=under)
        nodes = data.get("nodes")
        if nodes:
            for node in nodes:
                node_id = node.get("id")
                if node_id and isinstance(node_id, string_types):
                    if node_id.startswith("#"):
                        tag = node_id.lstrip("#")
                        url = "/wiki/tag/%s" % tag
                        node["url"] = url
                    else:
                        relative_path = get_relative_path(node_id.strip("/"), wiki_root, return_name_if_fail=False)
                        if relative_path:
                            url = "/wiki/post/%s" % relative_path
                            node["url"] =  url
        return force_response(data)
    else:
        return render_api_template("builtin_theme_wiki_nodes.jade", wiki_title=wiki_title)
def wechat_text_image_handler(wechat_user_id, bucket, xml_data):
    msg_id = xml_data.get("MsgId")
    create_time = xml_data.get("CreateTime")
    msg_type = xml_data.get("MsgType")

    # post_root, auto_add_date(bool), silent_reply(bool), image_folder, image_insert_type(image/markdown_syntax)
    wechat_configs = get_json_content_by_path(bucket,
                                              "__wechat.json",
                                              force_dict=True)

    today = get_now_from_bucket(bucket, "%Y-%m-%d")
    silent_reply = wechat_configs.get("silent_reply") or False
    post_root = (wechat_configs.get("post_folder") or "").strip("/")
    auto_add_date = wechat_configs.get("auto_add_date", False)
    add_nickname = wechat_configs.get("add_nickname", False)
    draft_by_default = wechat_configs.get("draft_by_default", False)
    one_user_one_post = wechat_configs.get("one_user_one_post", False)
    user_post_per_day = wechat_configs.get("user_post_per_day", False)

    if msg_type == "image":  # 纯图片
        pic_url = xml_data.get("PicUrl")
        if not pic_url:
            return "error: PicUrl is blank"
        filename = "%s.jpg" % (msg_id or create_time)
        image_insert_type = wechat_configs.get("image_insert_type")
        raw_image_folder = smart_unicode(
            wechat_configs.get("image_folder") or "").strip("/")
        image_folder = smart_unicode(raw_image_folder) or today
        if image_insert_type == "image":  # 直接保存图片
            path = "%s/%s" % (image_folder, filename)
            download_from_internet_and_sync(bucket=bucket,
                                            url=pic_url,
                                            path=path,
                                            timeout=60)  # 下载图片并进行保存
            if silent_reply:
                return ""
            else:
                return u"将保存到 %s" % path
        else:
            if raw_image_folder:
                # 还是按照 day 增加一层子目录,避免多了找不到的情况
                path = "/%s/%s/%s" % (raw_image_folder, today, filename)
            else:
                path = "/_image/%s/%s" % (today, filename)
            text_to_append = "![](%s)" % path  # 插入图片的语法
            download_from_internet_and_sync(bucket=bucket,
                                            url=pic_url,
                                            path=path,
                                            timeout=60)
    else:
        text_to_append = xml_data.get("Content") or xml_data.get(
            "Recognition") or xml_data.get("EventKey") or ""

    text_to_append = text_to_append.strip()

    if "\n" not in text_to_append and re.match(u"name ", text_to_append):
        name = text_to_append[5:].strip()
        if name:
            set_name_by_wechat_user_id(wechat_user_id, name)
            return u"昵称已设定为 %s" % name

    if one_user_one_post:
        if user_post_per_day:
            today_string = get_now_from_bucket(bucket, "%Y-%m-%d")
        else:
            today_string = ""
        if post_root:
            if today_string:
                post_path = "%s/%s/%s.txt" % (post_root, wechat_user_id,
                                              today_string)
            else:
                post_path = "%s/%s.txt" % (post_root, wechat_user_id)
        else:
            if today_string:
                post_path = "%s/%s.txt" % (wechat_user_id, today_string)
            else:
                post_path = "%s.txt" % wechat_user_id
    else:
        if post_root:
            post_path = post_root + "/" + get_now_from_bucket(
                bucket, "%Y-%m-%d.txt")
        else:
            post_path = get_now_from_bucket(bucket, "%Y/%Y-%m-%d.txt")

    if text_to_append.strip() == "reset":
        if one_user_one_post:
            sync_file_by_server_side(bucket=bucket,
                                     relative_path=post_path,
                                     content=" ")
            return u"%s 已重置" % post_path
        else:
            return u"只有 `One User One Post` 的时候才能使用 reset 命令。"

    if text_to_append:
        if add_nickname:
            nickname = get_name_by_wechat_user_id(wechat_user_id)
            if nickname:
                text_to_append = "%s: %s" % (nickname, text_to_append)

        if auto_add_date and "\n" not in text_to_append:
            if text_to_append.startswith("---") or re.match(
                    u"\w+[:\uff1a]", text_to_append):
                auto_add_date = False
        if auto_add_date:  # 添加时间戳
            bucket_now = get_now_from_bucket(bucket, "%Y-%m-%d %H:%M:%S")
            text_to_append = "%s %s" % (bucket_now, text_to_append)

        is_voice = True if xml_data.get("Recognition") else False
        text_to_append = compile_tag_to_wiki_link_syntax(text_to_append,
                                                         is_voice=is_voice)

        # 保存文章, 5 分钟的间隔自动多一个空line
        append_to_markdown_doc_and_sync(bucket=bucket,
                                        path=post_path,
                                        content=text_to_append,
                                        lines_more_diff=5 * 60,
                                        draft_by_default=draft_by_default)

        if silent_reply:
            return ""
        else:
            return u"已保存至 %s" % post_path
Esempio n. 9
0
    def settings_json_editor(self,
                             keys_config_path,
                             private_config_keys=None,
                             formats=None,
                             **kwargs):
        # 对站点的 config 文件的编辑
        # 如果指定了 private_config_keys, 则只是更新到非公开的 update_bucket_private_configs
        if not self.bucket:
            return ""
        logined = need_login(bucket=self.bucket)
        if not logined:
            return ""
        if private_config_keys and not isinstance(private_config_keys,
                                                  (list, tuple)):
            private_config_keys = None
        keys_config = self.get_settings_keys_config(keys_config_path)
        if keys_config_path in builtin_site_settings_keys_config_info:
            private_config_keys_for_builtin = keys_config.get("private_keys")
            if private_config_keys_for_builtin:
                private_config_keys = private_config_keys_for_builtin

        hide_submit_button = False
        config_store_path = None
        config_keys = None
        if keys_config and isinstance(keys_config, dict):
            config_store_path = keys_config.get("path")
            config_keys = keys_config.get("keys")
            hide_submit_button = keys_config.get("hide_submit_button", False)

        if not private_config_keys:
            if not isinstance(config_store_path,
                              string_types) or not isinstance(
                                  config_keys, (list, tuple)):
                return "config_keys format error, not allowed"
            if not config_store_path or not config_keys:
                return "config_store_path is invalid or config_keys is invalid, not allowed"
            if not re.match("__\w+\.json", config_store_path):
                return "path should be __xxxx.json, not allowed"

        def settings_json_editor_callback(new_data_obj):
            for key, value in new_data_obj.items():
                if value and isinstance(value,
                                        (str, unicode)) and len(value) > 20000:
                    return 'error: the length of value is too long'
            if private_config_keys:
                private_configs_to_update = {
                    key: new_data_obj.get(key)
                    for key in private_config_keys
                }
                update_bucket_private_configs(self.bucket,
                                              **private_configs_to_update)
            else:
                content = json.dumps(new_data_obj, indent=4)
                sync_file_by_server_side(bucket=self.bucket,
                                         relative_path=config_store_path,
                                         content=content)

        if request.method != "POST":
            # 处理 data
            if private_config_keys:
                data_obj = get_bucket_private_configs_by_keys(
                    self.bucket, private_config_keys)
            else:
                data_obj = get_json_content_by_path(self.bucket,
                                                    config_store_path) or {}
            if not isinstance(data_obj, dict):  # 必须是 dict 类型,否则数据会被重置
                data_obj = {}
        else:
            data_obj = None  # will get from request.form automatic

        formats = formats or {}

        return Html.grid_form(data_obj,
                              config_keys,
                              formats=formats,
                              callback_func=settings_json_editor_callback,
                              hide_submit_button=hide_submit_button,
                              **kwargs)
Esempio n. 10
0
 def nav_disabled(self):
     nav_config = get_json_content_by_path(self.bucket, 'nav.json') or {}
     return nav_config.get('user_nav_disabled', False)
Esempio n. 11
0
 def nav_configs(self):
     nav_config = get_json_content_by_path(self.bucket, 'nav.json') or {}
     nav_configs = nav_config.get('nav_configs') or []
     return nav_configs
Esempio n. 12
0
def show_wiki_as_sub_site():
    bucket = get_bucket_in_request_context()
    if not bucket:
        return
    request_path = get_request_path().strip("/")
    if not re.match("wiki(/|$)", request_path):
        return
    wiki_configs = get_json_content_by_path(bucket, "__wiki.json", force_dict=True)
    wiki_root = smart_unicode(wiki_configs.get("wiki_root", ""))
    if not wiki_root:
        return
    set_data_root_in_request(wiki_root) # set data_root to request
    wiki_root = wiki_root.strip("/")
    wiki_title = wiki_configs.get("wiki_title") or get_just_name(wiki_root, for_folder=True)
    wiki_root = wiki_root.lower()

    kwargs = dict(wiki_root=wiki_root, wiki_title=wiki_title, wiki_configs=wiki_configs)

    if re.match("wiki/?$", request_path):
        # index
        docs = []
        user_categories = wiki_configs.get("categories")
        if not isinstance(user_categories, (list, tuple)):
            user_categories = []
        for user_category in user_categories:
            if not isinstance(user_category, dict): continue
            category_path = user_category.get("path")
            summary = smart_unicode(user_category.get("summary") or "")
            icon = smart_unicode(user_category.get("icon") or "")
            doc = get_record_by_path(bucket=bucket, path=category_path)
            if not doc:
                category_path = "%s/%s" % (wiki_root, category_path.strip("/"))
                doc = get_record_by_path(bucket=bucket, path=category_path)
                if not doc:
                    continue
            doc_type = get_type_from_record(doc)
            if doc_type not in ["post", "folder"]:
                continue
            doc["icon"] = icon or get_value_from_data(doc, "metadata.icon")
            doc["summary"] = summary or get_value_from_data(doc, "metadata.summary")
            docs.append(doc)
        if not docs: # by default
            docs = Data.get_data(type='folder', level=1, limit=50, with_page=False, path=wiki_root)

        # 处理 url, 取 relative
        index_docs = []
        for doc in docs:
            wiki_url = get_wiki_url_for_doc(wiki_root, doc)
            if not wiki_url:
                continue
            doc["wiki_url"] = wiki_url
            index_docs.append(doc)

        return render_api_template("builtin_theme_knowbase_index.jade", docs=index_docs, **kwargs)

    elif re.match("wiki/tag/", request_path):
        current_tag = get_offset_path(request_path, 2)
        if not current_tag:
            abort(404, "no tag?")
        docs = get_records_by_tag(bucket, current_tag, sort_by="-date")
        for doc in docs:
            doc["wiki_url"] = get_wiki_url_for_doc(wiki_root, doc)
        return render_api_template("builtin_theme_knowbase_tag.jade", current_tag=current_tag, docs=docs, **kwargs)

    elif re.search("wiki/search(/|$)", request_path):
        keywords = request.values.get("s")
        data_namespace = get_data_namespace()
        docs = data_namespace.get_data(bucket=bucket, keywords=keywords, pager_name="wiki", path=wiki_root,
                                       sort_by='-date', min_limit=8)
        for doc in docs:
            doc["wiki_url"] = get_wiki_url_for_doc(wiki_root, doc)
        return render_api_template("builtin_theme_knowbase_search.jade", docs=docs, **kwargs)

    elif re.match("wiki/category/", request_path):
        # category
        category_path = get_offset_path(request_path, 2).lower()
        wiki_nodes_url = "/wiki_nodes?path=%s" % category_path
        category_path = "%s/%s" % (wiki_root, category_path)
        folder_doc = get_record_by_path(bucket, category_path)
        enable_wiki_nodes = auto_type(wiki_configs.get("enable_wiki_nodes", True))
        if not enable_wiki_nodes:
            wiki_nodes_url = ""
        if not folder_doc or get_type_from_record(folder_doc) != "folder":
            abort(404, "no category found")
        else:
            category = Category(folder_doc)
            docs = auto_pg(bucket=bucket, data_type="post", pager_name="wiki", path=category.path,
                           ignore_marked_id=True, prefix_to_ignore='_', sort_by='-date', min_limit=8)
            for doc in docs:
                doc["wiki_url"] = get_wiki_url_for_doc(wiki_root, doc)
            return render_api_template("builtin_theme_knowbase_category.jade", category=category, docs=docs,
                                       wiki_nodes_url=wiki_nodes_url, **kwargs)

    elif re.match("wiki/post/", request_path):
        # detail
        doc_path = get_offset_path(request_path, 2)
        doc_path = "%s/%s" % (wiki_root, doc_path)
        doc = get_record_by_path(bucket, doc_path)
        if not doc:
            abort(404, "no doc found")
        else:
            return render_api_template("builtin_theme_knowbase_post.jade", doc=doc, **kwargs)
Esempio n. 13
0
def get_wiki_root(bucket):
    wiki_configs = get_json_content_by_path(bucket,
                                            "__wiki.json",
                                            force_dict=True)
    wiki_root = smart_unicode(wiki_configs.get("wiki_root", ""))
    return wiki_root