Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ctfcli/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from ctfcli.cli.config import Config
from ctfcli.cli.plugins import Plugins
from ctfcli.cli.templates import Templates
from ctfcli.cli.pages import Pages
from ctfcli.utils.plugins import get_plugin_dir


Expand Down Expand Up @@ -47,6 +48,9 @@ def config(self):
def challenge(self):
return COMMANDS.get("challenge")

def pages(self):
return COMMANDS.get("pages")

def plugins(self):
return COMMANDS.get("plugins")

Expand All @@ -57,6 +61,7 @@ def templates(self):
COMMANDS = {
"challenge": Challenge(),
"config": Config(),
"pages": Pages(),
"plugins": Plugins(),
"templates": Templates(),
"cli": CTFCLI(),
Expand Down
44 changes: 44 additions & 0 deletions ctfcli/cli/pages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import sys
from pathlib import Path
import frontmatter

import click

from ctfcli.utils.config import load_config
from ctfcli.utils.pages import (
get_current_pages,
get_existing_page,
sync_page,
install_page,
)


class Pages(object):
def install(self):
try:
_config = load_config()
except:
click.secho("No ctfcli configuration found", fg="red")
sys.exit(1)

pages = Path("./pages")
if pages.is_dir() is False:
click.secho(
f'"pages" folder not found. All pages must exist in the "pages" folder.',
fg="red",
)
sys.exit(1)
else:
current_pages = get_current_pages()

pagefiles = list(pages.glob("**/*.md")) + list(pages.glob("**/*.html"))
for path_obj in pagefiles:
page = frontmatter.load(path_obj)
existing_page = get_existing_page(
route=page["route"], pageset=current_pages
)

if existing_page:
sync_page(page, path_obj, existing_page["id"])
else:
install_page(page, path_obj)
71 changes: 71 additions & 0 deletions ctfcli/utils/pages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from .config import generate_session

FORMATS = {
".md": "markdown",
".html": "html",
".htm": "html",
}


def get_current_pages():
s = generate_session()
return s.get(f"/api/v1/pages", json=True).json()["data"]


def get_existing_page(route, pageset=None):
if pageset is None:
pageset = get_current_pages()
for page in pageset:
if route == page["route"]:
return page
return None


def get_format(ext):
return FORMATS[ext]


def sync_page(matter, path_obj, page_id):
route = matter["route"]
title = matter["title"]
content = matter.content
draft = bool(matter.get("draft"))
hidden = bool(matter.get("hidden"))
auth_required = bool(matter.get("auth_required"))
format = get_format(path_obj.suffix)

s = generate_session()
data = {
"route": route,
"title": title,
"content": content,
"draft": draft,
"hidden": hidden,
"auth_required": auth_required,
"format": format,
}
r = s.patch(f"/api/v1/pages/{page_id}", json=data)
r.raise_for_status()


def install_page(matter, path_obj):
route = matter["route"]
title = matter["title"]
content = matter.content
draft = bool(matter.get("draft"))
hidden = bool(matter.get("hidden"))
auth_required = bool(matter.get("auth_required"))
format = get_format(path_obj.suffix)

s = generate_session()
data = {
"route": route,
"title": title,
"content": content,
"draft": draft,
"hidden": hidden,
"auth_required": auth_required,
"format": format,
}
r = s.post(f"/api/v1/pages", json=data)
r.raise_for_status()
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ Pygments==2.7.4
requests==2.22.0
colorama==0.4.3
appdirs==1.4.3
python-frontmatter==1.0.0
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def read(fname):
"requests==2.22.0",
"colorama==0.4.3",
"appdirs==1.4.3",
"python-frontmatter==1.0.0",
],
packages=find_packages(),
include_package_data=True,
Expand Down