Пример #1
0
def index_route(page_index=1):
    page_url = "/index/{0}/".format(page_index)
    localtime = time.localtime(time.time())
    global last_build_year
    if last_build_year != localtime[0]:
        last_build_year = localtime[0]
        cache_index.clear()
        cache_post.clear()
    if page_url in cache_index:
        console.log("Success", "Get cache Success: {0}".format(page_url))
        return cache_index[page_url]
    console.log("Info", "Trying to build: {0}".format(page_url))
    page_row = page.get_page_row(system_config["Paging"], len(page_list))
    if page_index == 0 or page_index > page_row:
        abort(404)
    result = page.build_index(page_index, page_row, system_config, page_list,
                              menu_list, template_config, i18n)
    if result is None:
        abort(404)
    console.log("Info", "Writing to cache: {0}".format(page_url))
    if len(cache_index) >= 50:
        page_keys = sorted(cache_index.keys())
        console.log("Info", "Delete cache: {0}".format(page_keys[0]))
        del cache_index[page_keys[0]]
    cache_index[page_url] = result
    console.log("Success", "Get success: {0}".format(page_url))
    return result
Пример #2
0
def new_post_init(config, independent=False):
    title = config["title"]
    name = get.filter_name(config["name"])
    if not os.path.exists("./document/{}.md".format(name)):
        editor = system_info["Editor"]
        os.system("{0} ./document/{1}.md".format(editor, name))
    post_info = {"name": name, "title": title, "time": time.time()}
    if not os.path.exists("./document/{}.md".format(name)):
        console.log("Error",
                    "Cannot find [./document/{}.md] file".format(name))
        return
    if not independent:
        excerpt = get.get_excerpt("./document/{}.md".format(name))
        post_info["excerpt"] = excerpt

    write_json = post_info
    page_config = "./document/{}.json".format(name)

    if not independent:
        write_json = json.loads(file.read_file("./config/page.json"))
        write_json.insert(0, post_info)
        page_config = "./config/page.json"

    file.write_file(
        page_config,
        json.dumps(write_json, indent=4, sort_keys=False, ensure_ascii=False))

    console.log("Success", "Create a new article successfully!")
Пример #3
0
def get_orgs_list():
    console.log("info", "Getting the list of theme...")
    try:
        return requests.get("https://api.github.com/orgs/silverblogtheme/repos").json()
    except  requests.exceptions.RequestException:
        console.log("Error", "Get the theme list error.")
        exit(1)
Пример #4
0
def write_post_cache(page_url, content):
    console.log("Info", "Writing to cache: {0}".format(page_url))
    if len(cache_post) >= 50:
        page_keys = sorted(cache_post.keys())
        console.log("Info", "Delete cache: {0}".format(page_keys[0]))
        del cache_post[page_keys[0]]
    cache_post[page_url] = content
Пример #5
0
def post_route(file_name=None):
    if file_name is None or not os.path.exists(
            "./document/{0}.md".format(file_name)):
        abort(404)
    page_url = "/post/{0}/".format(file_name)
    global last_build_year
    localtime = time.localtime(time.time())
    if last_build_year != localtime[0]:
        console.log("Info", "Found a year change, cache cleanup.")
        last_build_year = localtime[0]
        cache_index.clear()
        cache_post.clear()
    if page_url in cache_post:
        console.log("Success", "Get cache Success: {0}".format(page_url))
        return cache_post[page_url]
    page_info = None
    if file_name in page_name_list:
        this_page_index = page_name_list.index(file_name)
        page_info = page_list[this_page_index]
    result = page.build_page(file_name, system_config, page_info, menu_list,
                             template_config, i18n)
    console.log("Info", "Writing to cache: {0}".format(page_url))
    if len(cache_post) >= 50:
        page_keys = sorted(cache_post.keys())
        console.log("Info", "Delete cache: {0}".format(page_keys[0]))
        del cache_post[page_keys[0]]
    cache_post[page_url] = result
    console.log("Success", "Get success: {0}".format(page_url))

    return result
Пример #6
0
def edit_post(post_list, post_index, config, editor=None, is_menu=False):
    safe_name = get.filter_name(config["name"])
    if post_list[post_index]["name"] is not config["name"]:
        shutil.move("./document/{}.md".format(post_list[post_index]["name"]),
                    "./document/{}.md".format(safe_name))
        if os.path.exists("./document/{}.json".format(
                post_list[post_index]["name"])):
            shutil.move(
                "./document/{}.json".format(post_list[post_index]["name"]),
                "./document/{}.json".format(safe_name))
            config_file = json.loads(
                file.read_file("./document/{}.json".format(safe_name)))
            config_file["title"] = config["title"]
            if "time" in config:
                config_file = config["time"]
            file.write_file("./document/{}.json".format(safe_name),
                            file.json_format_dump(config_file))
        post_list[post_index]["name"] = safe_name
    if editor is not None:
        os.system("{0} ./document/{1}.md".format(editor, safe_name))
    post_list[post_index]["title"] = config["title"]
    file_url = "./config/page.json"
    if is_menu:
        file_url = "./config/menu.json"
    file.write_file(file_url, file.json_format_dump(post_list))
    console.log("Success", "Edit a new article successfully!")
Пример #7
0
def new_post(config, independent=False):
    system_info = json.loads(file.read_file("./config/system.json"))
    title = config["title"]
    name = get.filter_name(config["name"])
    post_uuid = str(uuid.uuid5(uuid.NAMESPACE_URL, name))
    if "uuid" in config:
        post_uuid = config["uuid"]
    if not os.path.exists("./document/{}.md".format(name)):
        editor = system_info["Editor"]
        os.system("{0} ./document/{1}.md".format(editor, name))
    post_info = {
        "uuid": post_uuid,
        "name": name,
        "title": title,
        "time": round(time.time())
    }
    if not os.path.exists("./document/{}.md".format(name)):
        console.log("Error", "Cannot find [./document/{}.md]".format(name))
        exit(1)
    if not independent:
        excerpt = get.get_excerpt("./document/{}.md".format(name))
        post_info["excerpt"] = excerpt

    write_json = post_info
    page_config = "./document/{}.json".format(name)

    if not independent:
        write_json = json.loads(file.read_file("./config/page.json"))
        write_json.insert(0, post_info)
        page_config = "./config/page.json"

    file.write_file(page_config, file.json_format_dump(write_json))

    console.log("Success", "Create a new article successfully!")
Пример #8
0
def get_system_config():
    global system_config, template_config, i18n
    load_file = yield from file.async_read_file("./config/system.json")
    system_config = yield from async_json_loads(load_file)
    del system_config["API_Password"]
    if len(system_config["Theme"]) == 0:
        console.log(
            "Error",
            "If you do not get the Theme you installed, check your configuration file and the Theme installation."
        )
        exit(78)
    if os.path.exists("./templates/{0}/config.json".format(
            system_config["Theme"])):
        template_config_file = yield from file.async_read_file(
            "./templates/{0}/config.json".format(system_config["Theme"]))
        template_config = yield from async_json_loads(template_config_file)
    if os.path.exists("./templates/{}/i18n".format(system_config["Theme"])):
        i18n_name = "en-US"
        if "i18n" in system_config and len(system_config["i18n"]) != 0:
            i18n_name = system_config["i18n"]
        i18n_filename = "./templates/{0}/i18n/{1}.json".format(
            system_config["Theme"], i18n_name)
        if os.path.exists(i18n_filename):
            i18n_file = yield from file.async_read_file(i18n_filename)
            i18n = yield from async_json_loads(i18n_file)
Пример #9
0
def remove_theme(theme_name):
    static_symlink = "./templates/static/{}".format(theme_name)
    if os.path.exists(static_symlink):
        os.remove(static_symlink)

    shutil.rmtree("./templates/" + theme_name)
    console.log("Success", "The theme is removed successfully!")
Пример #10
0
def get_system_config():
    global system_config, template_config, i18n, static_file_dict
    load_file = yield from file.async_read_file("./config/system.json")
    system_config = yield from async_json_loads(load_file)
    if len(system_config["Theme"]) == 0:
        console.log("Error",
                    "If you do not get the Theme you installed, check your configuration file and the Theme installation.")
        exit(1)
    template_location = "./templates/{0}/".format(system_config["Theme"])
    if os.path.exists(template_location + "config.json"):
        template_config_file = yield from file.async_read_file(template_location + "config.json")
        template_config = yield from async_json_loads(template_config_file)

    if os.path.exists(template_location + "cdn"):
        cdn_config_file = None
        if os.path.exists(template_location + "cdn/custom.json"):
            cdn_config_file = template_location + "cdn/custom.json"
        if cdn_config_file is None:
            cdn_config_file = template_location + "cdn/local.json"
            if system_config["Use_CDN"]:
                cdn_config_file = template_location + "cdn/cdn.json"
        cdn_file = yield from file.async_read_file(cdn_config_file)
        static_file_dict = yield from async_json_loads(cdn_file)

    if os.path.exists("./templates/{}/i18n".format(system_config["Theme"])):
        i18n_name = "en-US"
        if "i18n" in system_config and len(system_config["i18n"]) != 0:
            i18n_name = system_config["i18n"]
        i18n_filename = "./templates/{0}/i18n/{1}.json".format(system_config["Theme"], i18n_name)
        if os.path.exists(i18n_filename):
            i18n_file = yield from file.async_read_file(i18n_filename)
            i18n = yield from async_json_loads(i18n_file)
Пример #11
0
def use_text_mode(args):
    if args.command == "qrcode":
        system_config = json.loads(file.read_file("./config/system.json"))
        from common import install_module
        install_module.install_and_import("qrcode_terminal")
        import qrcode_terminal
        if len(system_config["API_Password"]) == 0 or len(system_config["Project_URL"]) == 0:
            console.log("Error", "Check the API_Password and Project_URL configuration items")
            exit(1)
        try:
            password_md5 = json.loads(system_config["API_Password"])["hash_password"]
        except (ValueError, KeyError, TypeError):
            exit(1)
        console.log("Info", "Please use the client to scan the following QR Code")
        config_json = json.dumps({"url": system_config["Project_URL"], "password": password_md5})
        qrcode_terminal.draw(config_json)
        exit(0)
    if args.command == "upgrade":
        from manage import upgrade
        if upgrade.upgrade_check():
            if not args.yes:
                start_to_pull = input('Find new version, do you want to upgrade? [y/N]')
            if start_to_pull.lower() == 'yes' or start_to_pull.lower() == 'y' or args.yes:
                upgrade.upgrade_pull()
                exit(0)
        console.log("Info", "No upgrade found")
        exit(0)
    if args.command == "build-page":
        from manage import build_static_page
        build_static_page.publish()
        exit(0)
    from manage import build_rss, post_manage
    if args.command == "new":
        config = None
        if args.config is not None:
            config = json.loads(file.read_file(args.config))
        if config is None:
            print("Please enter the title of the article:")
            title = input().strip()
            if len(title) == 0:
                console.log("Error", "The title can not be blank.")
                exit(1)
            name = get.get_name(title)
            print("Please enter the slug [{}]:".format(name))
            name2 = input().strip()
            if len(name2) != 0:
                name = get.filter_name(name2)
            if os.path.exists("./document/{}.md".format(name)):
                console.log("Error", "File [./document/{}.md] already exists".format(name))
                exit(1)
        if len(name) != 0 and len(title) != 0:
            config = {"title": title, "name": name}
            post_manage.new_post(config, args.independent)
            build_rss.build_rss()
        exit(0)
    if args.command == "update":
        if post_manage.update_post():
            build_rss.build_rss()
        exit(0)
Пример #12
0
def check_build_year():
    global last_build_year
    localtime = time.localtime(time.time())
    if last_build_year != localtime[0]:
        console.log("Info", "Found a year change, cache cleanup.")
        last_build_year = localtime[0]
        cache_index.clear()
        cache_post.clear()
Пример #13
0
def get_readme(theme_name):
    console.log("Info", "Getting the readme of theme...")
    try:
        r = requests.get(
            "https://raw.githubusercontent.com/silverblog-theme/{}/master/README.md"
            .format(theme_name))
        return r.text
    except requests.exceptions.RequestException:
        console.log("Error", "Get the readme error.")
        exit(1)
Пример #14
0
def install_and_import(package):
    try:
        importlib.import_module(package)
    except ImportError:
        console.log("Error", "Please install the [{}] package to support this feature".format(package))
        install_dependency = input('Do you want to install [{}] now? [y/N]'.format(package))
        if install_dependency.lower() == 'yes' or install_dependency.lower() == 'y':
            install_package(package)
    finally:
        globals()[package] = importlib.import_module(package)
Пример #15
0
def build_rss():
    system_config = json.loads(file.read_file("./config/system.json"))
    system_config["Lazyload"] = False
    page_list = json.loads(file.read_file("./config/page.json"))
    file.write_file(
        "./document/rss.xml",
        make_rss(system_config["Project_Name"], system_config["Project_URL"],
                 system_config["Project_Description"], page_list,
                 system_config))
    console.log("Success", "Build rss success!")
Пример #16
0
def build_rss():
    system_config = json.loads(file.read_file("./config/system.json"))
    page_list = json.loads(file.read_file("./config/page.json"))
    if "Rss_Full_Content" in system_config:
        full_content = system_config["Rss_Full_Content"]
    file.write_file(
        "./document/rss.xml",
        make_rss(system_config["Project_Name"], system_config["Project_URL"],
                 system_config["Project_Description"], page_list,
                 system_config))
    console.log("Success", "Build Rss Success!")
Пример #17
0
def get_gravatar(author_name):
    import requests
    console.log("info", "Get Gravatar URL...")
    gravatar_hash = ""
    try:
        r = requests.get(
            "https://en.gravatar.com/{0}.json".format(author_name)).json()
        gravatar_hash = r["entry"][0]["hash"]
    except (TypeError, ValueError, requests.exceptions.RequestException):
        console.log("Error", "Get Gravatar URL error,use default avatar.")
    return "https://secure.gravatar.com/avatar/{0}".format(gravatar_hash)
Пример #18
0
def build_post_page(filename, page_name_list, page_list, system_config, menu_list, template_config, i18n):
    file_name = os.path.basename(filename).replace(".md", "")
    console.log("Build", "Processing file: ./static_page/post/{0}.html".format(file_name))
    page_info = None
    if file_name in page_name_list:
        this_page_index = page_name_list.index(file_name)
        page_info = page_list[this_page_index]
    content = yield from async_build_page(file_name, system_config, page_info, menu_list,
                                          template_config, i18n)
    if content is not None:
        yield from file.async_write_file("./static_page/post/{0}.html".format(file_name), content)
Пример #19
0
def upgrade_data():
    if current_data_version != new_data_version:
        from manage import backup
        backup.backup(str(current_data_version))
        for index in range(current_data_version, new_data_version):
            if os.path.exists("./upgrade/upgrade_from_{}.py".format(index)):
                upgrade_item = importlib.import_module(
                    "upgrade.upgrade_from_{}".format(index), __package__)
                upgrade_item.main()
        file.write_file("./upgrade/current_version.json",
                        json.dumps({"current_data_version": new_data_version}))
        console.log("Success", "Upgrade data Successful!")
Пример #20
0
def build_excerpt(item):
    global page_list
    processing_file = "./document/{}.md".format(item["name"])
    console.log("Build", "Processing file: {}".format(processing_file))
    custom_config_file = "./document/{}.json".format(item["name"])
    if os.path.exists(custom_config_file):
        console.log("Build", "Processing file: {}".format(custom_config_file))
        custom_config_content = yield from file.async_read_file(custom_config_file)
        custom_config = json.loads(custom_config_content)
        page_list[page_list.index(item)].update(custom_config)
        if "excerpt" in custom_config:
            return
    page_list[page_list.index(item)]["excerpt"] = yield from async_get_excerpt(processing_file)
Пример #21
0
def upgrade_pull():
    if not os.path.exists("./.git"):
        console.log("Error", "Not a git repository.")
        return False
    repo, remote = git_init()
    console.log("Info", "On branch {}".format(repo.active_branch))
    if repo.is_dirty():
        console.log("Error",
                    "The current warehouse is modified and can not be upgraded automatically.")
        checkout_repo = input('Do you want to restore these changes? [y/N]')
        if checkout_repo.lower() == 'yes' or checkout_repo.lower() == 'y':
            repo.index.checkout(force=True)
        if repo.is_dirty():
            exit(1)
    remote.pull()
    if current_env_version != new_env_version:
        os.system("cd ./install && bash install_python_dependency.sh")
        file.write_file("./upgrade/current_version.json",
                        json.dumps({"current_data_version": new_data_version, "current_env_version": new_env_version}))
    if current_data_version != new_data_version and os.path.exists(
            "./upgrade/upgrade_from_{}.py".format(current_data_version)):
        os.system("python3 ./upgrade/upgrade_from_{}.py".format(current_data_version))
        file.write_file("./upgrade/current_version.json",
                        json.dumps({"current_data_version": new_data_version, "current_env_version": new_env_version}))
    console.log("Success", "Upgrade Successful!")
    exit(0)
Пример #22
0
def index_route(page_index=1):
    page_url = "/index/{0}/".format(page_index)
    result = get_index_cache(page_url)
    if result is None:
        page_row = page.get_page_row(system_config["Paging"], len(page_list))
        if page_index == 0 or page_index > page_row:
            abort(404)
        result = page.build_index(page_index, page_row, system_config,
                                  page_list, menu_list, template_config, i18n,
                                  static_file_dict)
    if result is None:
        abort(404)
    write_index_cache(page_url, result)
    console.log("Success", "Get success: {0}".format(page_url))
    return result
Пример #23
0
def upgrade_check(fetch=True):
    if not os.path.exists("./.git"):
        if fetch:
            console.log("Error", "Not a git repository.")
        return False
    repo, remote = git_init()
    if fetch:
        remote.fetch(repo.active_branch)
        try:
            if repo.rev_parse("HEAD") != repo.rev_parse("FETCH_HEAD"):
                return True
        except:
            pass
        if current_data_version != new_data_version:
            return True
    return False
Пример #24
0
def post_route(file_name=None):
    if file_name is None or not os.path.exists(
            "./document/{0}.md".format(file_name)):
        abort(404)
    page_url = "/post/{0}/".format(file_name)
    result = get_post_cache(page_url)
    if result is None:
        page_info = None
        if file_name in page_name_list:
            this_page_index = page_name_list.index(file_name)
            page_info = page_list[this_page_index]
        result = page.build_page(file_name, system_config, page_info,
                                 menu_list, template_config, i18n,
                                 static_file_dict)
        write_post_cache(page_url, result)
    console.log("Success", "Get success: {0}".format(page_url))
    return result
Пример #25
0
def article_manager():
    from manage import build_rss, post_manage
    while True:
        dialog.title = "Article manager"
        menu_list = [
            "New", "Update", "Edit", "Delete", "=" * 25, "Back", "Exit"
        ]
        result = dialog.menu("Please select an action", menu_list)
        if result == "Exit":
            exit(0)
        if result == "Back":
            break
        if result == "New":
            dialog.title = "New post"
            post_info = get_post_info()
            if os.path.exists("./document/{}.md".format(post_info["name"])):
                console.log(
                    "Error", "File [./document/{}.md] already exists".format(
                        post_info["name"]))
                exit(1)
            if post_info["name"] is not None:
                post_manage.new_post(
                    post_info,
                    dialog.confirm("Is this an independent page?", "no"))
        if result == "Edit":
            dialog.title = "Edit post"
            page_list, post_index = select_list("./config/page.json")
            if page_list:
                config = get_post_info(page_list[post_index]["title"],
                                       page_list[post_index]["name"],
                                       page_list[post_index]["time"])
                system_info = json.loads(
                    file.read_file("./config/system.json"))
                post_manage.edit_post(page_list, post_index, config,
                                      system_info["Editor"])
            post_manage.update_post()
        if result == "Delete":
            page_list, post_index = select_list("./config/page.json")
            if page_list and dialog.confirm(
                    "Are you sure you want to delete this article?", "no"):
                post_manage.delete_post(page_list, post_index)
        if result == "Update":
            post_manage.update_post()
        build_rss.build_rss()
        time.sleep(0.5)
Пример #26
0
def upgrade_check(fetch=True):
    if not check_is_git():
        if fetch:
            console.log("Error", "Not a git repository.")
            exit(1)
        return False
    repo = git.Repo("./")
    remote = repo.remote()
    if fetch:
        remote.fetch(repo.active_branch)
        try:
            if repo.rev_parse("HEAD") != repo.rev_parse("FETCH_HEAD"):
                return True
        except git.BadObject:
            pass
        if current_data_version != new_data_version:
            return True
    return False
Пример #27
0
def install_theme(theme_name, custom):
    import git
    if not os.path.exists("./templates/static"):
        os.mkdir("./templates/static")
    repo_dir = "./templates/{}".format(theme_name)
    if os.path.exists(repo_dir):
        console.log("Error", "This theme has been installed.")
        exit(1)
    console.log("Info", "Get the theme repository...")
    git_repo = "https://github.com/silverblog-theme/{}.git".format(theme_name)
    if custom:
        git_repo = theme_name
    try:
        git.Repo.clone_from(url=git_repo, to_path=repo_dir, depth=1)
    except git.exc.GitCommandError:
        console.log("Error", "Unable to clone theme repository.")
        exit(1)
    if os.path.exists("{}/package-metadata.json".format(repo_dir)):
        config_example_file = "{}/config.example.json".format(repo_dir)
        static_symlink = "./templates/static/{}".format(theme_name)

        if not os.path.exists(static_symlink):
            os.symlink(
                "{}/templates/{}/static".format(os.getcwd(), theme_name),
                static_symlink)

        if os.path.exists(config_example_file):
            shutil.copyfile(config_example_file,
                            "{}/config.json".format(repo_dir))

        download_static_file(theme_name)
    if not os.path.exists(
            "{}/package-metadata.json".format(repo_dir)) and os.path.exists(
                "{}/install.sh".format(repo_dir)):
        result_code = os.system(
            "cd templates && bash {}/install.sh".format(theme_name))
        if (result_code >> 8) != 0:
            console.log(
                "Error",
                "An error occurred while executing the install script.")
            exit(1)
    console.log("Success", "The theme is install successfully!")
Пример #28
0
def edit(page_list, post_index, config, editor=None, is_menu=False):
    if page_list[post_index]["name"] is not config["name"]:
        safe_name = get.filter_name(config["name"])
        shutil.move("./document/{}.md".format(page_list[post_index]["name"]),
                    "./document/{}.md".format(safe_name))
        if os.path.exists("./document/{}.json".format(page_list[post_index]["name"])):
            shutil.move("./document/{}.json".format(page_list[post_index]["name"]),
                        "./document/{}.json".format(safe_name))
            config_file = json.loads(file.read_file("./document/{}.json".format(safe_name)))
            config_file["title"] = config["title"]
            file.write_file("./document/{}.json".format(safe_name),
                            json.dumps(config_file, indent=4, sort_keys=False, ensure_ascii=False))
        page_list[post_index]["name"] = safe_name
    if editor is not None:
        os.system("{0} ./document/{1}.md".format(editor, safe_name))
    page_list[post_index]["title"] = config["title"]
    file_url = "./config/page.json"
    if is_menu:
        file_url = "./config/menu.json"
    file.write_file(file_url, json.dumps(page_list, indent=4, sort_keys=False, ensure_ascii=False))
    console.log("Success", "Edit a new article successfully!")
Пример #29
0
def update():
    global page_list, page_list_file
    page_list_file = json.loads(file.read_file("./config/page.json"))
    if len(page_list_file) == 0:
        console.log("Error", "The page list can not be blank.")
        return False
    page_list = page_list_file

    for item in page_list_file:
        processing_file = "./document/{0}.md".format(item["name"])
        file_exists = os.path.exists(processing_file)
        if not file_exists:
            console.log("Remove",
                        "Removing from list: {0}".format(processing_file))
            del page_list[item]
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    tasks = [build_excerpt(item) for item in page_list]
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()
    file.write_file(
        "./config/page.json",
        json.dumps(page_list, ensure_ascii=False, indent=4, sort_keys=False))
    console.log("Success", "Update article metadata is successful!")
    return True
Пример #30
0
def use_whiptail_mode():
    dialog.title = "SilverBlog management tool"
    menu_list = ["Article manager", "Menu manager", "Build static page", "Setting", "=========================", "Exit"]
    upgrade_text = None
    if os.path.exists("./.git"):
        upgrade_text = "Upgrade"
        upgrade_check = False
        last_fetch_time = 0
        if os.path.exists("./upgrade/last_fetch_time.json"):
            last_fetch_time = json.loads(file.read_file("./upgrade/last_fetch_time.json"))["last_fetch_time"]
        if upgrade.upgrade_check(False):
            upgrade_text = "⚠ Upgrade"
            upgrade_check = True
        if (time.time() - last_fetch_time) > 259200 and not upgrade_check:
            console.log("Info", "Checking for updates...")
            file.write_file("./upgrade/last_fetch_time.json", json.dumps({"last_fetch_time": time.time()}))
            if upgrade.upgrade_check():
                upgrade_text = "⚠ Upgrade"
        menu_list = ["Article manager", "Menu manager", "Build static page", upgrade_text, "Setting",
                     "=========================", "Exit"]
    while True:
        result = dialog.menu("Please select an action", menu_list)
        if result == "Exit":
            exit(0)
        if result == "Article manager":
            article_manager()
        if result == "Menu manager":
            menu_manager()
        if upgrade_text is not None:
            if result == upgrade_text:
                upgrade_system()
        if result == "Build static page":
            from manage import build_static_page
            dialog.title = "Build static page"
            build_static_page.publish()
            time.sleep(0.5)
        if result == "Setting":
            from manage import setting
            setting.setting_menu()