This commit is contained in:
danrega
2024-09-02 17:03:46 +02:00
parent 367538af5e
commit 89189d10ef

View File

@@ -2413,26 +2413,40 @@ To check out examples in demo classes, expand the collapsible sections below.
<br> <br>
``` abap ``` abap
CLASS zcl_some_class DEFINITION PUBLIC FINAL CREATE PUBLIC. CLASS zcl_some_class DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION. PUBLIC SECTION.
INTERFACES if_oo_adt_classrun. INTERFACES if_oo_adt_classrun.
PROTECTED SECTION.
PRIVATE SECTION. PRIVATE SECTION.
"Markdown URLs
CONSTANTS url_cs TYPE string VALUE `https://api.github.com/repos/SAP-samples/abap-cheat-sheets/git/trees/main`. CONSTANTS url_cs TYPE string VALUE `https://api.github.com/repos/SAP-samples/abap-cheat-sheets/git/trees/main`.
CONSTANTS url_gh TYPE string VALUE `https://raw.githubusercontent.com/SAP-samples/abap-cheat-sheets/main/`. CONSTANTS url_gh TYPE string VALUE `https://raw.githubusercontent.com/SAP-samples/abap-cheat-sheets/main/`.
CONSTANTS url_api TYPE string VALUE `https://api.github.com/markdown`. "Here go email addresses
DATA url TYPE string. CONSTANTS sender_addr TYPE cl_bcs_mail_message=>ty_address VALUE '...@...'.
CONSTANTS recipient_addr TYPE cl_bcs_mail_message=>ty_address VALUE '...@...'.
TYPES: BEGIN OF s, TYPES: BEGIN OF s,
file_name TYPE string, file_name TYPE string,
title TYPE string, markdown TYPE string,
code_snippets TYPE string_table, error TYPE abap_boolean,
error TYPE abap_boolean,
END OF s. END OF s.
DATA tab TYPE TABLE OF s WITH EMPTY KEY. DATA tab TYPE TABLE OF s WITH EMPTY KEY.
DATA snippets TYPE string_table. DATA url TYPE string.
DATA html TYPE string.
ENDCLASS. ENDCLASS.
CLASS zcl_some_class IMPLEMENTATION. CLASS zcl_some_class IMPLEMENTATION.
METHOD if_oo_adt_classrun~main. METHOD if_oo_adt_classrun~main.
"----------- Retrieving all Markdown file names in the ABAP cheat sheet GitHub repository -----------
TRY. TRY.
"Creating a client object using a destination "Creating a client object using a destination
"In the example, the HTTP destination is created using a plain URL. "In the example, the HTTP destination is created using a plain URL.
@@ -2441,9 +2455,19 @@ CLASS zcl_some_class IMPLEMENTATION.
"Sending an HTTP GET request and returning the response "Sending an HTTP GET request and returning the response
"In the example, the HTTP body is retrieved as string data. "In the example, the HTTP body is retrieved as string data.
DATA(response) = http_client->execute( if_web_http_client=>get )->get_text( ). DATA(response) = http_client->execute( if_web_http_client=>get )->get_text( ).
IF response CS `API rate limit exceeded`.
out->write( `API rate limit exceeded` ).
RETURN.
ENDIF.
CATCH cx_root INTO DATA(err). CATCH cx_root INTO DATA(err).
out->write( err->get_text( ) ). out->write( err->get_text( ) ).
RETURN.
ENDTRY. ENDTRY.
"----------- Retrieving Markdown content from ABAP cheat sheet GitHub repository -----------
IF err IS INITIAL. IF err IS INITIAL.
"Markdown file names are contained in the returned string in a specific "Markdown file names are contained in the returned string in a specific
"pattern. In the following code, the markdown file names are extracted "pattern. In the following code, the markdown file names are extracted
@@ -2465,7 +2489,7 @@ CLASS zcl_some_class IMPLEMENTATION.
ENDLOOP. ENDLOOP.
SORT tab BY file_name ASCENDING. SORT tab BY file_name ASCENDING.
"In the following loop, the raw markdown content is retrieved using an HTTP GET request, also "In the following loop, the Markdown content is retrieved using an HTTP GET request, also
"by creating a client object and using a destination (another plain URL). The URL is constructed "by creating a client object and using a destination (another plain URL). The URL is constructed
"using the constant value plus the markdown file that was retrieved before. "using the constant value plus the markdown file that was retrieved before.
LOOP AT tab REFERENCE INTO DATA(cs). LOOP AT tab REFERENCE INTO DATA(cs).
@@ -2473,143 +2497,59 @@ CLASS zcl_some_class IMPLEMENTATION.
TRY. TRY.
http_client = cl_web_http_client_manager=>create_by_http_destination( i_destination = cl_http_destination_provider=>create_by_url( i_url = url ) ). http_client = cl_web_http_client_manager=>create_by_http_destination( i_destination = cl_http_destination_provider=>create_by_url( i_url = url ) ).
DATA(raw_md) = http_client->execute( if_web_http_client=>get )->get_text( ). DATA(raw_md) = http_client->execute( if_web_http_client=>get )->get_text( ).
"Putting the long string that was retrieved in an internal table of type string cs->markdown = raw_md.
"for further processing (extracting the code snippets). CATCH cx_root.
SPLIT raw_md AT |\n| INTO TABLE snippets.
DATA(flag) = ''.
"In the loop, all content from the markdown that is not part of a code
"snippet (indicated by the triple ```) is deleted.
"The replacements with dummy content in the loop are only done so that
"the POST request further down can work with the provided content
"(i.e. avoiding issues with characters such as "; they are inserted later again).
LOOP AT snippets REFERENCE INTO DATA(line).
DATA(tabix) = sy-tabix.
FIND PCRE '^\s*```' IN line->*.
IF sy-subrc = 0 AND flag = ''.
line->* = `%%%--START--%%%%`.
flag = 'X'.
ELSEIF sy-subrc = 0 AND flag = 'X'.
line->* = `%%%--END--%%%%`.
flag = ''.
ELSEIF flag <> 'X'.
DELETE snippets INDEX tabix.
ELSE.
FIND PCRE `^\s*"` IN line->*.
IF sy-subrc = 0.
DATA(comment1) = 'X'.
ENDIF.
FIND PCRE `^\*` IN line->*.
IF sy-subrc = 0.
DATA(comment2) = 'X'.
ENDIF.
FIND `***********************************************************************`
IN line->*.
IF sy-subrc = 0.
DATA(divider) = 'X'.
ENDIF.
IF comment1 = 'X' OR comment2 = 'X' OR divider = 'X'.
DELETE snippets INDEX tabix.
CLEAR: comment1, comment2, divider.
ELSE.
REPLACE ALL OCCURRENCES OF `"` IN line->* WITH `§§§§§`.
REPLACE ALL OCCURRENCES OF `\` IN line->* WITH `%%%%%`.
ENDIF.
ENDIF.
ENDLOOP.
"Adding the code snippets to the information table
cs->code_snippets = snippets.
CLEAR snippets.
CATCH cx_root INTO err.
cs->error = abap_true. cs->error = abap_true.
ENDTRY. ENDTRY.
DELETE ADJACENT DUPLICATES FROM cs->code_snippets COMPARING table_line.
ENDLOOP. ENDLOOP.
"Creating the final html to be displayed
LOOP AT tab REFERENCE INTO cs WHERE code_snippets IS NOT INITIAL AND error = abap_false. "----------- Creating a zip file containing all ABAP cheat sheet Markdown documents -----------
LOOP AT cs->code_snippets REFERENCE INTO DATA(code).
tabix = sy-tabix. DATA(zip) = NEW cl_abap_zip( ).
IF code->* = `%%%--START--%%%%`.
code->* = |```|. "Iteratively adding the ABAP cheat sheet Markdown documents to the zip file
ENDIF. LOOP AT tab REFERENCE INTO cs WHERE error = abap_false.
IF code->* = `%%%--END--%%%%`. cs->file_name = cs->file_name.
code->* = |```|.
INSERT `*****************` && |\\n|
INTO cs->code_snippets INDEX tabix + 1.
ENDIF.
code->* = code->* && |\\n|.
ENDLOOP.
"For the POST request, concatenating the string table to a single string.
DATA(code_string) = concat_lines_of( table = cs->code_snippets ).
TRY. TRY.
"Another creation of a client object using a destination DATA(conv_xstring) = cl_abap_conv_codepage=>create_out( codepage = `UTF-8` )->convert( cs->markdown ).
"This example deals with a POST request. CATCH cx_sy_conversion_codepage.
http_client = cl_web_http_client_manager=>create_by_http_destination( i_destination = cl_http_destination_provider=>create_by_url( i_url = url_api ) ).
DATA(request) = http_client->get_http_request( ).
request->set_text( `{"text":"` && code_string && `"}` ).
request->set_header_fields( VALUE #( ( name = 'Accept' value = 'application/vnd.github+json' ) ) ).
DATA(post) = http_client->execute( if_web_http_client=>post ).
DATA(status) = post->get_status( ).
IF status-code <> 200.
cs->error = abap_true.
DATA(status_error) = |Post request error: { status-code } / { status-reason }|.
ELSE.
"Retrieving the created html code
DATA(html_code) = post->get_text( ).
REPLACE ALL OCCURRENCES OF `§§§§§` IN html_code WITH `"`.
REPLACE ALL OCCURRENCES OF `%%%%%` IN html_code WITH `\`.
REPLACE ALL OCCURRENCES OF PCRE `(<code>)(\w.*)` IN html_code WITH `$1 $2`.
ENDIF.
CATCH cx_root INTO DATA(error).
cs->error = abap_true.
ENDTRY. ENDTRY.
"Preparing the title for expandable sections
DATA(title) = cs->file_name. "Adding the xstring content as file content to zip
REPLACE ALL OCCURRENCES OF `_` IN title WITH ` `. zip->add( name = cs->file_name
REPLACE PCRE `^..` IN title WITH ``. content = conv_xstring ).
REPLACE `.md` IN title WITH ``.
"Assembling expandable sections
html = html &&
`<br><details>` &&
` <summary>` && title && `</summary>` &&
COND #( WHEN cs->error = abap_false THEN html_code ELSE COND #( WHEN error IS INITIAL THEN status_error ELSE error->get_text( ) ) ) &&
`</details>`.
ENDLOOP. ENDLOOP.
"Providing the html skeleton and inserting the assembled expandable sections from above
DATA(final_html) = "Saving the zip file
`<!DOCTYPE html>` && DATA(zipped_file) = zip->save( ).
`<html>` &&
`<head>` && "----------- Creating a ZIP file containing all ABAP cheat sheet Markdown documents -----------
`<title>ABAP Cheat Sheet Code Snippets</title>` &&
`<style>` && "Sending email
` body {background-color: #F8F8F8;}` && TRY.
` h1 {color: blue; font-family: verdana;}` && "Creating a new mail instance
` pre {background: #f4f4f4;border: 1px solid #ddd;border-left: 3px solid #0070f2;color: #36454F;` && DATA(mail) = cl_bcs_mail_message=>create_instance( ).
` page-break-inside: avoid;font-size: 14px;line-height: 1.3;max-width: 100%;overflow: auto;padding: 1em 1.5em;` && "Settings
` display: block;word-wrap: break-word;} ` && mail->set_sender( sender_addr ).
`</style>` && mail->add_recipient( recipient_addr ).
`</head>` && mail->set_subject( 'Test Mail' ).
`<body>` && "Main document
`<h1>ABAP Cheat Sheet Code Snippets</h1>` && mail->set_main( cl_bcs_mail_textpart=>create_instance(
`<a href="https://github.com/SAP-samples/abap-cheat-sheets">https://github.com/SAP-samples/abap-cheat-sheets</a><br><br>` && iv_content = '<h3>Test Mail</h3><p>Please find ABAP cheat sheet markdown files attached.<br>Cheers</p>'
html && iv_content_type = 'text/html' ) ).
`<script>` && "Adding an attachment
` const snippets = document.querySelectorAll("code");` && mail->add_attachment( cl_bcs_mail_binarypart=>create_instance(
` snippets.forEach(elem => {` && iv_content = zipped_file
` var abap = elem.innerHTML;` && iv_content_type = 'application/x-zip-compressed'
` abap = abap.replace(/(\b[A-Z]{2,}\b)/g, "<strong>$1</strong>");` && iv_filename = 'abap_cheat_sheets.zip' ) ).
` elem.innerHTML = abap;` &&
` });` && "Sending mail synchronously, displaying the status for each recipient
`</script>` && mail->send( IMPORTING et_status = DATA(status_table) ).
`</body>` && out->write( status_table ).
`</html>`. CATCH cx_bcs_mail INTO DATA(error_mail).
"Displaying the html result in the ADT console out->write( |Mail sending error: { error_mail->get_text( ) }| ).
"Note: Before running the class, clear the ADT console. ENDTRY.
"When the html code is displayed in the ADT console, you can, for example,
"create a file named ABAP_cheat_sheet_code.html on your local machine.
"Open the file in an editor, copy & paste the entire ADT console content and
"save the local file. In doing so, you have various code snippets at your
"disposal offline.
out->write( final_html ).
ENDIF. ENDIF.
ENDMETHOD. ENDMETHOD.
ENDCLASS. ENDCLASS.
@@ -3293,7 +3233,7 @@ ENDCLASS.
<td> <code>CL_ABAP_ZIP</code> </td> <td> <code>CL_ABAP_ZIP</code> </td>
<td> <td>
The following example creates a zip file and adds three txt files with sample content. The following example creates a zip file and adds three txt files with sample content.
```abap ```abap
"Create zip file "Create zip file