From 761d5802549833078b8ed409d23a643322057cda Mon Sep 17 00:00:00 2001
From: Miguel Angel Reina Ortega <miguelangel.reinaortega@etsi.org>
Date: Fri, 6 Oct 2023 15:21:15 +0200
Subject: [PATCH] Add GitLab pages to host published spec versions

---
 .gitlab-ci.yml      | 23 +++++++++++++++++-
 index.html          | 48 ++++++++++++++++++++++++++++++++++++++
 publish_on_pages.sh | 41 ++++++++++++++++++++++++++++++++
 updateIndex.py      | 57 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 168 insertions(+), 1 deletion(-)
 create mode 100644 index.html
 create mode 100644 publish_on_pages.sh
 create mode 100644 updateIndex.py

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d8ce84a..8a53395 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -13,9 +13,10 @@ workflow:
 variables:
 
 stages:
+  - build
   - generation
   - publication
-  - build
+  - web
     
 Build pythonForPandocFilter docker image:
   stage: build
@@ -73,3 +74,23 @@ Publish spec:
     name: "${CI_PROJECT_NAME}_${CI_COMMIT_TAG}"
     paths:
       - "${CI_PROJECT_NAME}_${CI_COMMIT_TAG}.docx"
+
+pages:
+  stage: web
+  when: on_success
+  only:
+    - tags
+  before_script:
+    - |
+     curl "${CI_API_V4_URL}/projects/$TOOLS_SCRIPTS_PROJECT_ID/repository/files/publish_on_pages%2Esh/raw?ref=master" >> publish_on_pages.sh
+    - chmod +x publish_on_pages.sh
+    - |
+     curl "${CI_API_V4_URL}/projects/$TOOLS_SCRIPTS_PROJECT_ID/repository/files/updateIndex%2Epy/raw?ref=master" >> updateIndex.py
+    - |
+     curl "${CI_API_V4_URL}/projects/$TOOLS_SCRIPTS_PROJECT_ID/repository/files/index%2Ehtml/raw?ref=master" >> index.html
+  script:
+    - echo 'Publishing on pages'
+    - ./publish_on_pages.sh updateIndex.py $CI_PAGES_URL ${CI_PROJECT_NAME} $CI_COMMIT_REF_NAME index.html $CLEAN_WEB_PAGES
+  artifacts:
+    paths:
+      - public
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..a10aef7
--- /dev/null
+++ b/index.html
@@ -0,0 +1,48 @@
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+    <head>
+        <title>Directory Listing /</title>
+        <style type="text/css">
+            
+	body{font-size:0.8em}
+            a { text-decoration: none; }
+            a:hover { text-decoration: underline; }
+            th {text-align:left;}
+            .box {float: left;  min-height: 50px;  margin: 0.5em;}
+            .after-box {  clear: left;}
+	    .icon{width:22px;height:22px}	    
+        </style>
+    </head>
+    <body>
+        <header>
+            <div class="box">
+                <h2>
+                
+                        Available spec versions
+                         
+                    </h2>
+            </div>
+            <div class="after-box">
+            </div>
+            </header>
+
+        <form method="post" action="./" id="ctl00">
+			<div class="aspNetHidden">
+				<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="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" />
+			</div>
+
+			<div class="aspNetHidden">
+
+				<input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="BE8C5505" />
+			</div>
+            
+            <table style="margin-left:20px">
+                <tbody>
+					<ul id='document-list'>
+					</ul>
+                         
+                </tbody>
+            </table>
+        </form>
+    </body>
+</html>
\ No newline at end of file
diff --git a/publish_on_pages.sh b/publish_on_pages.sh
new file mode 100644
index 0000000..2aa41d2
--- /dev/null
+++ b/publish_on_pages.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+
+DOCKER_IMAGE=python:3.9-slim-bullseye
+
+echo "\n------ Checking for docker image --------"
+docker pull "$DOCKER_IMAGE"
+echo "Pages URL:" $2
+echo "PROJECT NAME:" $3
+echo "TAG NAME:" $4
+
+echo "------ Get the previous GitLab Pages content --------"
+set +e
+curl --fail "$2/content.zip" -o "content.zip"
+if [ -e "content.zip" ]; then unzip "content.zip"; rm "content.zip"; fi
+set -e
+
+echo "------ Add/update content --------"
+if [ $6 == 'true' ]; then 
+    echo 'Removing all web pages content...'
+	rm -r public/*;
+else
+	ls public/
+fi
+
+mkdir -p "public/$4"
+cp -r -f "$3_$4.docx" public/$4
+
+docker run --rm -v $(pwd):/tmp -w /tmp "$DOCKER_IMAGE" pip install bs4 && python3 $1 "$3_$4" "$4/$3_$4.docx" "$5"
+
+echo "------ Zip the content and publish the zip again ------"
+zip -r "content.zip" "public"
+mv "content.zip" "public/"
+ 
+exit 0
+
+#Parameters
+#updateIndex.py 
+#$CI_PAGES_URL
+#$CI_PROJECT_NAME
+#$CI_COMMIT_REF_NAME
+#index.html
diff --git a/updateIndex.py b/updateIndex.py
new file mode 100644
index 0000000..acef650
--- /dev/null
+++ b/updateIndex.py
@@ -0,0 +1,57 @@
+#
+#	updateIndex.py
+#
+#	Script to update index.htm file on Pages.
+#
+#	(c) 2023 by Miguel Angel Reina Ortega
+#	License: BSD 3-Clause License. See the LICENSE file for further details.
+#
+from bs4 import BeautifulSoup
+import argparse, os
+
+def updateIndex(args:argparse.Namespace) -> None:
+    
+    # Check if index.htm exists
+    if not os.path.exists('public/index.html'):
+        print("'index.html' does not exist yet, using template")
+        with open(args.indexTemplate, 'r', encoding='utf-8') as file:
+            html_content = file.read()
+    else:
+        # Read index HTML
+        with open('public/index.html', 'r', encoding='utf-8') as file:
+            html_content = file.read()
+
+    # Analyze index content with BeautifulSoup
+    soup = BeautifulSoup(html_content, 'html.parser')
+
+    # Find document list
+    # Assume there's a list (<ul>) with id "document-list"
+    document_list = soup.find('ul', id='document-list')
+
+    # Add the new element <li> for the new document
+    if args.documentLink is not None and args.documentName is not None:
+        li = soup.new_tag('li')
+        a = soup.new_tag('a', href=args.documentLink)
+        a.string = args.documentName
+        li.append(a)
+        document_list.append(li)
+
+    # Save the updated index.html file
+    with open('public/index.html', 'w', encoding='utf-8') as file:
+        file.write(str(soup))
+
+    print("Index.html updated")
+			
+
+
+if __name__ == '__main__':
+
+    # Parse command line arguments
+    parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+    parser.add_argument('documentName', help = 'Document name to add to the list')
+    parser.add_argument('documentLink', help = 'Document location to add to the list')
+    parser.add_argument('indexTemplate', help = 'Index template document')
+    args = parser.parse_args()
+
+    updateIndex(args)
+
-- 
GitLab