Example #1
0
def delete_local_html_of_book(source_folder_path):
    build_folder_path = os.path.join(source_folder_path, "_build")
    logger.info(f"Build Folder: {build_folder_path}")
    if os.path.exists(build_folder_path):
        logger.info(
            f"Removing old version of build folder: {build_folder_path}")
        shutil.rmtree(build_folder_path)
Example #2
0
def gen_jupyter_book(source_folder_path, cwd=None):
    cmd_string = f"jupyter-book build {source_folder_path}"
    result = subprocess.run(cmd_string, shell=True, cwd=cwd)
    st_code = result.returncode
    logger.info(f"jupyter-book build STATUS CODE = {st_code}")
    if st_code != OK_CODE:
        print("Error in creating Jupyter Book.")
        exit(1)
Example #3
0
def upload_to_aws_s3(s3, local_file_path, bucket, s3_file_key):
    try:
        s3.upload_file(local_file_path,
                       bucket,
                       s3_file_key,
                       ExtraArgs={"ACL": "public-read"})
        logger.info(f"{local_file_path}: Upload Successful")
        return True
    except Exception as e:
        logger.error(f"{local_file_path}: Some Error occured uploading. \n", e,
                     "\n")
        return False
def cli(ctx, debug, source_dir, destination_dir, config_file):
    # click.echo(f"Debug mode is {'on' if debug else 'off'}")
    logger.info(f"Source dir is: {source_dir}")
    logger.info(f"Destination dir is: {destination_dir}")
    ctx.ensure_object(dict)
    ctx.obj["debug"] = debug
    ctx.obj["source_dir"] = os.path.abspath(source_dir)
    ctx.obj["destination_dir"] = os.path.abspath(destination_dir)
    if os.path.exists(config_file):
        ctx.obj["config_file"] = os.path.abspath(config_file)
    else:
        ctx.obj["config_file"] = None
    click.echo(pprint(ctx.obj))
Example #5
0
def read_toc_yaml(yaml_file):
    logger.info(f"Reading TOC yaml file: {yaml_file}")
    toc_dict = {}
    # tie yaml read in try+except to return empty if there is an error.
    try:
        with open(yaml_file, "r") as f:
            toc_dict = yaml.load(f, Loader=yaml.FullLoader)
            logger.debug(f"TOC dict: {toc_dict}")
    except Exception as e:
        logger.exception(
            f"Exception occured while reading TOC yaml file: {yaml_file}\n Exception: {e}"
        )
        exit(1)
    return toc_dict
Example #6
0
def setup_section_on_zendesk(hc, section_name, zendesk_category_id):
    data_dict = {
        "section": {
            "position": 0,
            "locale": "en-us",
            "name": section_name
        }
    }
    try:
        resp = hc.create_section(zendesk_category_id,
                                 json.dumps(data_dict),
                                 locale="en-us")
        logger.info(f"Created new section on Zendesk:\n {resp}")
        return resp
    except:
        logger.error(
            f"Error in creating section_name: {section_name} on Zendesk")
        return NOT_FOUND
Example #7
0
def handle_sections_on_zendesk(hc, html_files_list, zendesk_category_id):
    # will check if all sections exist on Zendesk in the category
    # if not, will create the section on Zendesk
    # will update
    sections_resp = hc.list_all_sections()

    html_files_for_zendesk = []

    for item in html_files_list:
        section_name = item["section_name"]
        section_id = find_section_name_in_list(section_name, sections_resp,
                                               zendesk_category_id)
        if section_id == NOT_FOUND:
            # set up section on zendesk
            section_resp = setup_section_on_zendesk(hc, section_name,
                                                    zendesk_category_id)
            if section_resp == NOT_FOUND:
                logger.error(
                    f"Could not create section name: {section_name} on Zendesk. Please check, cleanup and retry"
                )
                exit(1)
            else:
                # logger.info(sections_resp)
                logger.info("Here is 1 section")
                # logger.info(cpprint(section_resp))
                try:
                    sections_resp["sections"].append(section_resp["section"])
                    section_id = section_resp["section"]["id"]
                except Exception as e:
                    logger.warn("Exception adding section id")
                    logger.exception(e)

        html_files_for_zendesk.append({
            "section_name": item["section_name"],
            "section_id": section_id,
            "html_file_path": item["html_file_path"],
        })
    return html_files_for_zendesk
Example #8
0
def archive_book_from_zendesk(hc, zendesk_json_pre, zendesk_file_path):
    articles = zendesk_json_pre["articles"]
    if len(articles) < 1:
        logger.info("No articles found in the zendesk.json file to Archive")
        return
    for article in articles:
        article_id = article["article_id"]
        html_file_path = article["html_file_path"]
        logger.info(
            f"Archiving: {html_file_path} at Zendesk, Article ID:{article_id}")
        resp = hc.archive_article(article_id, locale="en-us")
        status_code = resp["status_code"]
        if status_code == 204:
            logger.info(f"{article_id} Successfully Archived")
        else:
            logger.warning(
                f"Error occured in Archiving: {article_id}. HTTP Code = {status_code}"
            )
    open(zendesk_file_path,
         "w").close()  # will rewrite zendesk.json to zero bytes
    logger.info(
        f"Book archived at Zendesk. You can delete it manually from the Admin UI"
    )
Example #9
0
def check_category_on_zendesk(hc, zendesk_category_name):
    # check if category exists on zendesk. If not create it.
    logger.info(f"Category Name: {zendesk_category_name}")
    zendesk_categories = hc.list_all_categories()
    for cat in zendesk_categories["categories"]:
        if zendesk_category_name == cat["name"]:
            logger.info(f"Category_ID: {cat['id']}")
            return cat["id"]

        data_dict = {
            "category": {
                "position": 0,
                "locale": "en-us",
                "name": zendesk_category_name,
            }
        }
    try:
        resp = hc.create_category(json.dumps(data_dict))
        logger.info(f"Created new Category on Zendesk:\n {resp}")
        return resp["id"]
    except:
        logger.error(
            f"Error in creating Category: {zendesk_category_name} on Zendesk")
        return NOT_FOUND
def command_sync(ctx, archive, draft, public):
    ctx.obj["archive_flag"] = archive
    ctx.obj["draft"] = draft
    ctx.obj["public"] = public
    logger.info("Syncing the Jupyterbook to ZenDesk")
    sync_to_zendesk.sync(ctx)
def command_build(ctx):
    """Console script for jupyterbook_to_zendesk."""
    logger.info("Building the jupyterbook")
    build_jupyterbook.build(ctx)
def sync(ctx):
    """Sync the jupyterbook to zendesk"""

    # 0. Initialize Zendesk router & S3

    App = md.Config(ctx.obj["config_file"])

    hc = md.HelpCenter(App.get("url"), App.get("username"), App.get("token"))
    try:
        hc.get_me()
    except Exception as e:
        logger.warn("Error authenticating as the ZenDesk User")
        logger.exception(e)
        exit(1)

    logger.info("Init s3 configuration")
    try:
        s3 = boto3.client(
            "s3",
            aws_access_key_id=App.get("aws_access_key"),
            aws_secret_access_key=App.get("aws_secret"),
        )
    except Exception as e:
        logger.warn("Error calling boto3.client")
        logger.exception(e)
        exit(1)

    # TODO add check that s3 bucket exists
    aws_s3_bucket = App.get("aws_s3_bucket")

    # check if user exists on Zendesk and can do something on it.
    md.check_user_on_zendesk(hc)

    # load any previous zendesk activity on this source folder
    zendesk_file_path = os.path.join(ctx.obj["destination_dir"],
                                     md.ZENDESK_FILE)

    category_id = md.check_category_on_zendesk(
        hc=hc, zendesk_category_name=App.get("zendesk_category_name"))
    zendesk_json_pre = hc.list_articles_by_category(category_id=category_id)

    if ctx.obj["archive_flag"]:  # archive the book on Zendesk and exit OK.
        md.archive_book_from_zendesk(hc, zendesk_json_pre, zendesk_file_path)
        md.delete_local_html_of_book(ctx.obj["destination_dir"])
        exit(0)

    aws_s3_bucket = App.get("aws_s3_bucket")

    try:
        html_files_for_zendesk = md.gen_list_of_sections_and_html_files(
            source_folder_path=ctx.obj["source_dir"])
    except Exception as e:
        logger.warn("Error creating html files for zendesk")
        logger.exception(e)
        exit(1)

    html_files_for_zendesk = md.handle_sections_on_zendesk(
        hc=hc,
        html_files_list=html_files_for_zendesk,
        zendesk_category_id=category_id)

    zendesk_json_pre = hc.list_articles_by_category(category_id=category_id)

    # now we iterate over list of files
    for f in html_files_for_zendesk:
        logger.info(f"Processing: {f}")
        article_dict = md.update_article_dict(f["html_file_path"], s3,
                                              aws_s3_bucket)

        section_id = f["section_id"]
        # article exists on zendesk
        # if article with same title and section_id is found
        # then article exists
        logger.info("Checking to see if article exists")
        article_info = md.article_exists(
            articles=zendesk_json_pre,
            title=article_dict["article"]["title"],
            section_id=section_id,
        )
        logger.info(f"Article Exists: {cpprint(article_info)}")

        if ctx.obj["public"]:
            article_dict["article"]["user_segment_id"] = None

        if not article_info:
            logger.info("Creating the article")
            response_json = hc.create_article(section_id,
                                              json.dumps(article_dict))
            article_id = response_json["article"]["id"]
            f.update({"article_id": article_id})
            article_html_url = response_json["article"]["html_url"]
            f.update({"article_html_url": article_html_url})
            md.logger.info(
                f"Article ID: {article_id}, Article URL: {article_html_url}")
        else:  # update_article
            logger.info("Updating the article")
            article_id = article_info["id"]
            article_html_url = article_info["html_url"]
            translation_dict = {
                "article": {
                    "user_segment_id":
                    article_dict["article"]["user_segment_id"]
                },
                "translation": {
                    "title": article_dict["article"]["title"],
                    "body": article_dict["article"]["body"],
                },
            }
            response_json = hc.update_article_metadata(
                article_id=article_id,
                data=json.dumps(article_dict["article"]),
                locale="en-us",
            )
            f.update({"article_id": article_id})
            f.update({"article_html_url": article_html_url})

    # 2nd pass to fix URLs
    for f in html_files_for_zendesk:
        logging.info(f"Processing (2nd Pass): {f}")
        article_dict = md.update_urls_in_article_dict(
            f["html_file_path"],
            html_files_for_zendesk,
        )

        draft = ctx.obj["draft"]
        article_dict["article"]["draft"] = draft

        if ctx.obj["public"]:
            article_dict["article"]["user_segment_id"] = None

        translation_dict = {
            "translation": {
                "title": article_dict["article"]["title"],
                "body": article_dict["article"]["body"],
                "draft": article_dict["article"]["draft"],
            }
        }
        logging.info("Syncing the jupyterbook to zendesk...")
        response_json = hc.update_article_metadata(
            article_id=article_id,
            data=json.dumps(article_dict["article"]),
            locale="en-us",
        )
        logging.info("Updating article visibility")
        logging.debug(cpprint(response_json))

        response_json = hc.update_article_translation(
            f["article_id"], json.dumps(translation_dict), locale="en-us")
        # get useful output
        del response_json["translation"]["body"]
        logging.debug(cpprint(response_json))

    # add the rest of the sync commands here
    return 0