def init_docs(app): discourse_index_id = 1087 tutorials_index_topic_id = 2628 tutorials_url_prefix = "/tutorials" session = talisker.requests.get_session() discourse_docs = Docs( parser=DocParser( api=DiscourseAPI( base_url="https://discourse.charmhub.io/", session=session, api_key=DISCOURSE_API_KEY, api_username=DISCOURSE_API_USERNAME, get_topics_query_id=2, ), index_topic_id=discourse_index_id, url_prefix="/docs", tutorials_index_topic_id=tutorials_index_topic_id, tutorials_url_prefix=tutorials_url_prefix, ), document_template="docs/document.html", url_prefix="/docs", ) discourse_docs.init_app(app) sdk_docs_id = 4449 sdk_docs = Docs( parser=DocParser( api=DiscourseAPI( base_url="https://discourse.charmhub.io/", session=session, api_key=DISCOURSE_API_KEY, api_username=DISCOURSE_API_USERNAME, get_topics_query_id=2, ), index_topic_id=sdk_docs_id, url_prefix="/docs/sdk", tutorials_index_topic_id=tutorials_index_topic_id, tutorials_url_prefix=tutorials_url_prefix, ), document_template="docs/document.html", url_prefix="/docs/sdk", blueprint_name="sdk_docs", ) sdk_docs.init_app(app) app.add_url_rule( "/docs/search", "docs-search", build_search_view( session=session, site="juju.is/docs", template_path="docs/search.html", ), )
def init_docs(app, url_prefix): discourse_docs = Docs( parser=DocParser( api=DiscourseAPI( base_url="https://forum.snapcraft.io/", session=talisker.requests.get_session(), ), index_topic_id=11127, url_prefix=url_prefix, ), document_template="docs/document.html", url_prefix=url_prefix, ) discourse_docs.init_app(app) app.add_url_rule( "/docs/search", "docs-search", build_search_view( session=talisker.requests.get_session(), site="snapcraft.io/docs", template_path="docs/search.html", ), )
def init_tutorials(app, url_prefix): session = talisker.requests.get_session() discourse_docs = Docs( parser=DocParser( api=DiscourseAPI(base_url="https://discourse.charmhub.io/", session=session), index_topic_id=2628, category_id=34, url_prefix=url_prefix, ), document_template="tutorials/tutorial.html", url_prefix=url_prefix, blueprint_name="tutorials", ) @app.route(url_prefix) def index(): page = flask.request.args.get("page", default=1, type=int) posts_per_page = 12 discourse_docs.parser.parse() metadata = discourse_docs.parser.metadata total_pages = math.ceil(len(metadata) / posts_per_page) return flask.render_template( "tutorials/index.html", navigation=discourse_docs.parser.navigation, forum_url=discourse_docs.parser.api.base_url, metadata=metadata, page=page, posts_per_page=posts_per_page, total_pages=total_pages, active_section="tutorials", ) discourse_docs.init_app(app)
def init_docs(app, url_prefix): discourse_index_id = 3394 session = talisker.requests.get_session() discourse_docs = Docs( parser=DocParser( api=DiscourseAPI(base_url="https://discourse.charmhub.io/", session=session), index_topic_id=discourse_index_id, url_prefix=url_prefix, ), document_template="docs/document.html", url_prefix=url_prefix, ) discourse_docs.init_app(app) app.add_url_rule( "/docs/search", "docs-search", build_search_view( session=session, site="charmhub.io/docs", template_path="docs/search.html", ), )
def init_docs(app, url_prefix): session = talisker.requests.get_session() discourse_docs = Docs( parser=DocParser( api=DiscourseAPI( base_url="https://forum.snapcraft.io/", session=session, api_key=DISCOURSE_API_KEY, api_username=DISCOURSE_API_USERNAME, get_topics_query_id=2, ), index_topic_id=11127, url_prefix=url_prefix, tutorials_index_topic_id=15409, tutorials_url_prefix="/tutorials", ), document_template="docs/document.html", url_prefix=url_prefix, ) discourse_docs.init_app(app) app.add_url_rule( "/docs/search", "docs-search", build_search_view( session=session, site="snapcraft.io/docs", template_path="docs/search.html", ), )
def init_tutorials(app, url_prefix): session = talisker.requests.get_session() tutorials_discourse = Tutorials( parser=TutorialParser( api=DiscourseAPI( base_url="https://discourse.charmhub.io/", session=session, api_key=DISCOURSE_API_KEY, api_username=DISCOURSE_API_USERNAME, get_topics_query_id=2, ), index_topic_id=2628, url_prefix=url_prefix, ), document_template="tutorials/tutorial.html", url_prefix=url_prefix, blueprint_name="tutorials", ) @app.route(url_prefix) def index(): tutorials_discourse.parser.parse() tutorials_discourse.parser.parse_topic( tutorials_discourse.parser.index_topic) tutorials = tutorials_discourse.parser.tutorials topic_list = [] for item in tutorials: if item["categories"] not in topic_list: topic_list.append(item["categories"]) item["categories"] = { "slug": item["categories"], "name": " ".join([ word.capitalize() for word in item["categories"].split("-") ]), } topic_list.sort() topics = [] for topic in topic_list: topics.append({ "slug": topic, "name": " ".join([word.capitalize() for word in topic.split("-")]), }) return flask.render_template( "tutorials/index.html", tutorials=tutorials, topics=topics, ) tutorials_discourse.init_app(app)
def init_tutorials(app, url_prefix): discourse_index_id = 3393 category_id = 30 session = talisker.requests.get_session() tutorials_docs = Docs( parser=DocParser( api=DiscourseAPI(base_url="https://discourse.juju.is/", session=session), index_topic_id=discourse_index_id, category_id=category_id, url_prefix=url_prefix, ), document_template="tutorials/tutorial.html", url_prefix=url_prefix, blueprint_name="tutorials", ) @app.route(url_prefix) def tutorials(): page = flask.request.args.get("page", default=1, type=int) topic = flask.request.args.get("topic", default=None, type=str) sort = flask.request.args.get("sort", default=None, type=str) posts_per_page = 15 tutorials_docs.parser.parse() if not topic: metadata = tutorials_docs.parser.metadata else: metadata = [ doc for doc in tutorials_docs.parser.metadata if topic in doc["categories"] ] if sort == "difficulty-desc": metadata = sorted(metadata, key=lambda k: k["difficulty"], reverse=True) if sort == "difficulty-asc" or not sort: metadata = sorted(metadata, key=lambda k: k["difficulty"], reverse=False) total_pages = math.ceil(len(metadata) / posts_per_page) return flask.render_template( "tutorials/index.html", navigation=tutorials_docs.parser.navigation, forum_url=tutorials_docs.parser.api.base_url, metadata=metadata, page=page, topic=topic, sort=sort, posts_per_page=posts_per_page, total_pages=total_pages, ) tutorials_docs.init_app(app)
def init_docs(app): discourse_index_id = 1087 session = talisker.requests.get_session() discourse_docs = Docs( parser=DocParser( api=DiscourseAPI(base_url="https://discourse.charmhub.io/", session=session), index_topic_id=discourse_index_id, url_prefix="/docs", ), document_template="docs/document.html", url_prefix="/docs", ) discourse_docs.init_app(app) sdk_docs_id = 4449 sdk_docs = Docs( parser=DocParser( api=DiscourseAPI(base_url="https://discourse.charmhub.io/", session=session), index_topic_id=sdk_docs_id, url_prefix="/docs/sdk", ), document_template="docs/document.html", url_prefix="/docs/sdk", blueprint_name="sdk_docs", ) sdk_docs.init_app(app) app.add_url_rule( "/docs/search", "docs-search", build_search_view( session=session, site="juju.is/docs", template_path="docs/search.html", ), )
def init_tutorials(app, url_prefix): session = talisker.requests.get_session() tutorials_discourse = Tutorials( parser=TutorialParser( api=DiscourseAPI( base_url="https://discourse.charmhub.io/", session=session, api_key=DISCOURSE_API_KEY, api_username=DISCOURSE_API_USERNAME, get_topics_query_id=2, ), index_topic_id=2628, url_prefix=url_prefix, ), document_template="tutorials/tutorial.html", url_prefix=url_prefix, blueprint_name="tutorials", ) @app.route(url_prefix) def index(): page = flask.request.args.get("page", default=1, type=int) topics_request = flask.request.args.get("topic", default=None, type=str) posts_per_page = 12 tutorials_discourse.parser.parse() tutorials_discourse.parser.parse_topic( tutorials_discourse.parser.index_topic) if not topics_request: tutorials = tutorials_discourse.parser.tutorials else: topics = topics_request.split(",") tutorials = [ doc for doc in tutorials_discourse.parser.tutorials if doc["categories"] in topics ] total_pages = math.ceil(len(tutorials) / posts_per_page) return flask.render_template( "tutorials/index.html", forum_url=tutorials_discourse.parser.api.base_url, tutorials=tutorials, page=page, posts_per_page=posts_per_page, total_pages=total_pages, active_section="tutorials", topic=topics_request, ) tutorials_discourse.init_app(app)
def setUp(self): """ Set up Flask app with Discourse extension for testing And set up mocking for discourse.example.com """ this_dir = os.path.dirname(os.path.realpath(__file__)) template_folder = f"{this_dir}/fixtures/templates/engage.html" app = flask.Flask("main", template_folder=template_folder) self.discourse_api = DiscourseAPI( base_url="https://discourse.ubuntu.com/", session=requests.Session(), api_key="secretkey", api_username="******", ) self.parser = EngageParser( api=self.discourse_api, index_topic_id=17229, url_prefix="/engage", ) app = flask.Flask("main", template_folder=template_folder) self.client = app.test_client() return super(TestDiscourseAPI, self).setUp()
def setUp(self): app = flask.Flask("test-app") app.url_map.strict_slashes = False app.template_folder = f"{this_dir}/fixtures/templates" app.testing = True self.discourse_api = DiscourseAPI( base_url="https://discourse.ubuntu.com/", session=requests.Session(), ) self.engage_pages = EngagePages( parser=EngageParser( api=self.discourse_api, index_topic_id=17229, url_prefix="/engage", ), document_template="/engage.html", url_prefix="/engage", blueprint_name="engage-pages", ).init_app(app) self.client = app.test_client() return super().setUp()
def init_tutorials(app, url_prefix): session = talisker.requests.get_session() tutorials_discourse = Tutorials( parser=TutorialParser( api=DiscourseAPI(base_url="https://discourse.charmhub.io/", session=session), index_topic_id=2628, category_id=34, url_prefix=url_prefix, ), document_template="tutorials/tutorial.html", url_prefix=url_prefix, blueprint_name="tutorials", ) @app.route(url_prefix) def index(): page = flask.request.args.get("page", default=1, type=int) topic = flask.request.args.get("topic", default=None, type=str) posts_per_page = 12 tutorials_discourse.parser.parse() if not topic: metadata = tutorials_discourse.parser.metadata else: metadata = [ doc for doc in tutorials_discourse.parser.metadata if topic in doc["categories"] ] total_pages = math.ceil(len(metadata) / posts_per_page) return flask.render_template( "tutorials/index.html", navigation=tutorials_discourse.parser.navigation, forum_url=tutorials_discourse.parser.api.base_url, metadata=metadata, page=page, posts_per_page=posts_per_page, total_pages=total_pages, active_section="tutorials", topic=topic, ) tutorials_discourse.init_app(app)
def openstack_install(): """ Openstack install docs Instructions for openstack installation pulled from Discourse """ discourse_api = DiscourseAPI( base_url="https://discourse.ubuntu.com/", session=session ) openstack_install_parser = DocParser( api=discourse_api, index_topic_id=23346, url_prefix="/openstack/install", ) openstack_install_docs = Docs( parser=openstack_install_parser, document_template="/openstack/install.html", url_prefix="/openstack/install", blueprint_name="openstack-install-docs", ) singlenode_topic = openstack_install_docs.parser.api.get_topic(21427) singlenode_topic_soup = BeautifulSoup( singlenode_topic["post_stream"]["posts"][0]["cooked"], features="html.parser", ) singlenode_content = openstack_install_parser._process_topic_soup( singlenode_topic_soup ) openstack_install_docs.parser._replace_lightbox(singlenode_topic_soup) multinode_topic = openstack_install_docs.parser.api.get_topic(18259) multinode_topic_soup = BeautifulSoup( multinode_topic["post_stream"]["posts"][0]["cooked"], features="html.parser", ) multinode_content = openstack_install_docs.parser._process_topic_soup( multinode_topic_soup ) openstack_install_docs.parser._replace_lightbox(multinode_topic_soup) return flask.render_template( "openstack/install.html", single_node=str(singlenode_content), multi_node=str(multinode_content), )
class TestDiscourseAPI(VCRTestCase): def _get_vcr_kwargs(self): """ This removes the authorization header from VCR so we don't record auth parameters """ return {"filter_headers": ["Authorization"]} def setUp(self): """ Set up Flask app with Discourse extension for testing And set up mocking for discourse.example.com """ this_dir = os.path.dirname(os.path.realpath(__file__)) template_folder = f"{this_dir}/fixtures/templates/engage.html" app = flask.Flask("main", template_folder=template_folder) self.discourse_api = DiscourseAPI( base_url="https://discourse.ubuntu.com/", session=requests.Session(), api_key="secretkey", api_username="******", ) self.parser = EngageParser( api=self.discourse_api, index_topic_id=17229, url_prefix="/engage", ) app = flask.Flask("main", template_folder=template_folder) self.client = app.test_client() return super(TestDiscourseAPI, self).setUp() def test_get_topic(self): """ Check API retrieves a protected topic 17275 """ response = self.discourse_api.get_topic(17275) # # Check for success self.assertEqual(response["id"], 17275)
from bs4 import BeautifulSoup from mistune import Markdown, Renderer import humanize from canonicalwebteam.discourse import DiscourseAPI from dateutil import parser from flask import request from ruamel.yaml import YAML from talisker import requests DISCOURSE_API_KEY = os.getenv("DISCOURSE_API_KEY") DISCOURSE_API_USERNAME = os.getenv("DISCOURSE_API_USERNAME") session = requests.get_session() discourse_api = DiscourseAPI( base_url="https://discourse.juju.is/", session=session, api_key=DISCOURSE_API_KEY, api_username=DISCOURSE_API_USERNAME, ) _yaml = YAML(typ="rt") _yaml_safe = YAML(typ="safe") md_parser = Markdown(renderer=Renderer()) def get_yaml_loader(typ="safe"): if typ == "safe": return _yaml_safe return _yaml
import datetime import re import json from bs4 import BeautifulSoup from mistune import Markdown, Renderer import humanize from canonicalwebteam.discourse import DiscourseAPI from dateutil import parser from flask import request from ruamel.yaml import YAML from talisker import requests session = requests.get_session() discourse_api = DiscourseAPI( base_url="https://discourse.charmhub.io/", session=session, ) _yaml = YAML(typ="rt") _yaml_safe = YAML(typ="safe") md_parser = Markdown(renderer=Renderer()) def get_yaml_loader(typ="safe"): if typ == "safe": return _yaml_safe return _yaml def split_filters(filters):
class TestDiscourseAPI(VCRTestCase): def _get_vcr_kwargs(self): """ This removes the authorization header from VCR so we don't record auth parameters """ return {"filter_headers": ["Authorization"]} def setUp(self): app = flask.Flask("test-app") app.url_map.strict_slashes = False app.template_folder = f"{this_dir}/fixtures/templates" app.testing = True self.discourse_api = DiscourseAPI( base_url="https://discourse.ubuntu.com/", session=requests.Session(), ) self.engage_pages = EngagePages( parser=EngageParser( api=self.discourse_api, index_topic_id=17229, url_prefix="/engage", ), document_template="/engage.html", url_prefix="/engage", blueprint_name="engage-pages", ).init_app(app) self.client = app.test_client() return super().setUp() def test_get_topic(self): response = self.discourse_api.get_topic(17275) self.assertEqual(response["id"], 17275) def test_active_page_returns_200(self): response = self.client.get("/engage/finance") self.assertEqual(response.status_code, 200) soup = BeautifulSoup(response.data, "html.parser") self.assertIsNone(soup.find("meta")) def test_active_page_returns_adds_no_meta_with_preview_flag(self): response = self.client.get("/engage/finance?preview") self.assertEqual(response.status_code, 200) soup = BeautifulSoup(response.data, "html.parser") self.assertIsNone(soup.find("meta")) def test_inactive_page_returns_302(self): response = self.client.get("/engage/it/deployment-azienda-manuale") self.assertEqual(response.status_code, 302) def test_inactive_page_returns_page_with_preview_flag(self): response = self.client.get( "/engage/it/deployment-azienda-manuale?preview") self.assertEqual(response.status_code, 200) soup = BeautifulSoup(response.data, "html.parser") self.assertIsNotNone(soup.find("meta")) self.assertEqual(soup.find("meta").get("content"), "nofollow")
DiscourseAPI, Docs, DocParser, ) # Rename your project below app = FlaskBase( __name__, "microstack.run", template_folder="../templates", static_folder="../static", ) session = talisker.requests.get_session() doc_parser = DocParser( api=DiscourseAPI(base_url="https://discourse.ubuntu.com/", session=session), index_topic_id=18212, url_prefix="/docs", ) if app.debug: doc_parser.api.session.adapters["https://"].timeout = 99 discourse_docs = Docs( parser=doc_parser, document_template="docs/document.html", url_prefix="/docs", ) discourse_docs.init_app(app)
app = FlaskBase( __name__, "cn.ubuntu.com", template_folder="../templates", static_folder="../static", template_404="404.html", template_500="500.html", ) # Engage pages and takeovers from Discourse # This section needs to provide takeover data for / session = talisker.requests.get_session() discourse_api = DiscourseAPI( base_url="https://discourse.ubuntu.com/", session=session, api_key=os.getenv("DISCOURSE_API_KEY"), api_username=os.getenv("DISCOURSE_API_USERNAME"), ) engage_path = "/engage" engage_pages = EngagePages( parser=EngageParser( api=discourse_api, index_topic_id=19117, url_prefix=engage_path, ), document_template="/engage/base_engage.html", url_prefix=engage_path, blueprint_name="engage-pages", )
# Rename your project below app = FlaskBase( __name__, "dqlite.io", template_folder="../templates", static_folder="../static", template_404="404.html", template_500="500.html", ) session = talisker.requests.get_session() docs_url_prefix = "/docs" discourse_docs = Docs( parser=DocParser( api=DiscourseAPI( base_url="https://discourse.dqlite.io/", session=session, ), index_topic_id=34, url_prefix=docs_url_prefix, ), document_template="docs/document.html", url_prefix=docs_url_prefix, ) app.add_url_rule( "/docs/search", "docs-search", build_search_view( session=session, site="https://dqlite.io/docs", template_path="docs/search.html",
# Rename your project below app = FlaskBase( __name__, "microk8s.io", template_folder="../templates", static_folder="../static", template_404="404.html", template_500="500.html", ) session = talisker.requests.get_session() discourse = Docs( parser=DocParser( api=DiscourseAPI(base_url="https://discuss.kubernetes.io/", session=session), index_topic_id=11243, url_prefix="/docs", ), document_template="docs/document.html", url_prefix="/docs", ) app.add_url_rule( "/docs/search", "docs-search", build_search_view( session=session, site="microk8s.io/docs", template_path="docs/search.html", ), )
app = FlaskBase( __name__, "ubuntu.com", template_folder="../templates", template_404="404.html", template_500="500.html", static_folder="../static", ) sentry = app.extensions["sentry"] session = talisker.requests.get_session() discourse_api = DiscourseAPI( base_url="https://discourse.ubuntu.com/", session=session, api_key=DISCOURSE_API_KEY, api_username=DISCOURSE_API_USERNAME, get_topics_query_id=2, ) # Web tribe websites custom search ID # search_engine_id = "adb2397a224a1fe55" # Error pages @app.errorhandler(400) def bad_request_error(error): return flask.render_template("400.html", message=error.description), 400 @app.errorhandler(410)
def setUp(self): """ Set up Flask app with Discourse extension for testing And set up mocking for discourse.example.com """ # Suppress annoying warnings from HTTPretty # See: https://github.com/gabrielfalcao/HTTPretty/issues/368 warnings.filterwarnings("ignore", category=ResourceWarning, message="unclosed.*") # Enable HTTPretty and set up mock URLs httpretty.enable() register_uris() template_folder = f"{this_dir}/fixtures/templates" app = flask.Flask("main", template_folder=template_folder) app_no_nav = flask.Flask("no-nav", template_folder=template_folder) app_no_mappings = flask.Flask("no-mappings", template_folder=template_folder) app_broken_mappings = flask.Flask("broken-mappings", template_folder=template_folder) app_no_category = flask.Flask("no-category", template_folder=template_folder) app_url_prefix = flask.Flask("url-prefix", template_folder=template_folder) app.testing = True app_no_nav.testing = True app_no_mappings.testing = True app_broken_mappings.testing = True app_no_category.testing = True app_url_prefix.testing = True discourse_api = DiscourseAPI( base_url="https://discourse.example.com/", session=requests.Session(), ) Tutorials( parser=TutorialParser( api=discourse_api, category_id=2, index_topic_id=34, url_prefix="/", ), document_template="document.html", url_prefix="/", ).init_app(app) Tutorials( parser=TutorialParser( api=discourse_api, category_id=2, index_topic_id=42, url_prefix="/", ), document_template="document.html", url_prefix="/", ).init_app(app_no_nav) Tutorials( parser=TutorialParser( api=discourse_api, category_id=2, index_topic_id=35, url_prefix="/", ), document_template="document.html", url_prefix="/", ).init_app(app_no_mappings) Tutorials( parser=TutorialParser( api=discourse_api, category_id=2, index_topic_id=36, url_prefix="/", ), document_template="document.html", url_prefix="/", ).init_app(app_broken_mappings) Tutorials( parser=TutorialParser(api=discourse_api, index_topic_id=37, url_prefix="/"), document_template="document.html", url_prefix="/", ).init_app(app_no_category) Tutorials( parser=TutorialParser(api=discourse_api, index_topic_id=38, url_prefix="/docs"), document_template="document.html", url_prefix="/tutorials", ).init_app(app_url_prefix) self.client = app.test_client() self.client_no_nav = app_no_nav.test_client() self.client_no_mappings = app_no_mappings.test_client() self.client_broken_mappings = app_broken_mappings.test_client() self.client_no_category = app_no_category.test_client() self.client_url_prefix = app_url_prefix.test_client()
"ubuntu.com", template_folder="../templates", template_404="404.html", template_500="500.html", static_folder="../static", ) # Settings app.config["CONTRACTS_API_URL"] = os.getenv( "CONTRACTS_API_URL", "https://contracts.canonical.com").rstrip("/") app.config["CANONICAL_LOGIN_URL"] = os.getenv( "CANONICAL_LOGIN_URL", "https://login.ubuntu.com").rstrip("/") session = talisker.requests.get_session() authenticated_session = talisker.requests.get_session() discourse_api = DiscourseAPI(base_url="https://discourse.ubuntu.com/", session=session) authenticated_discourse_api = DiscourseAPI( base_url="https://discourse.ubuntu.com/", session=authenticated_session, api_key=os.getenv("DISCOURSE_API_KEY"), api_username=os.getenv("DISCOURSE_API_USERNAME"), ) # Error pages @app.errorhandler(400) def bad_request_error(error): return flask.render_template("400.html"), 400