From 9b1a8e0975e783fb746850240051c79cb9d19a49 Mon Sep 17 00:00:00 2001
From: Jan Maximilian Michal <j.michal@stud.uni-goettingen.de>
Date: Sun, 11 Dec 2016 22:22:53 +0000
Subject: [PATCH] Added uploader script for simplified testing. Finally!

---
 README.md            |  9 ++++-
 grim.py              | 20 +++++++++++-
 hallgrim/uploader.py | 78 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 105 insertions(+), 2 deletions(-)
 create mode 100644 hallgrim/uploader.py

diff --git a/README.md b/README.md
index 2d0a45d..2617f6f 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,6 @@ implemented.
 * Add a good description / documentation.
 * Add more functionality (finalize gap, alignment)
 * Make parsers more robust.
-* setup test system in virtual box
 * Create whole test object with questions for direct import. Create two
 versions (one for internal use and one for the test.)
 * add zip support
@@ -38,6 +37,14 @@ data and assumes unknown properties)
 3. The XML structure for one or multiple questions, readable by Ilias.
 4. An Ilias object packed as .zip file, ready for upload.
 
+### Testing
+
+The tool will ship with a VirtualBox contaning Ilias Versions used in
+production. With `grim.py upload` it is possible to upload these scripts quickly
+and see a how they look like in a working ilias system.
+
+The upload script does not work with the university hosted servers.
+
 ### LaTeX Support
 
 Hallgrim supports the native latex approach by ILIAS. To typeset a formula just
diff --git a/grim.py b/grim.py
index 742a2b1..0c4e576 100755
--- a/grim.py
+++ b/grim.py
@@ -27,6 +27,7 @@ from hallgrim.IliasXMLCreator import packer
 from hallgrim.custom_markdown import get_markdown
 from hallgrim.messages import *
 from hallgrim.parser import *
+from hallgrim.uploader import send_script
 
 scaffolding = r'''
 meta = {{
@@ -126,10 +127,24 @@ def parseme():
         default=1,
         metavar='COUNT')
 
+    parser_gen = subparsers.add_parser(
+        "upload", help="Subcommand to upload created xml instances.")
+    parser_gen.add_argument(
+        '--host',
+        help='The hostname of the ilias test implementation',
+        metavar='HOST')
+    parser_gen.add_argument(
+        'script',
+        help='The script that should be uploaded',
+        type=file_exists,
+        metavar='FILE')
+
     args = parser.parse_args()
 
     if args.command == 'gen':
         delegator(args.out, args.input, args.instances)
+    if args.command == 'upload':
+        handle_upload(args.script, args.host)
     if args.command == 'new':
         handle_new_script(args.name, args.type, args.author, args.points)
     if args.command == None:
@@ -201,7 +216,10 @@ def handle_new_script(name, qtype, author, points):
             author, name, qtype, points, choice).strip(), file=new_script)
         info('Generated new script "{}."'.format(new_script.name))
 
+def handle_upload(script_path, hostname):
+    r = send_script(script_path)
+    info("Uploaded %s. Status code looks %s." % (script_path, "good" if r else "bad"))
+
 if __name__ == '__main__':
     markdown = get_markdown()
     parseme()
-    exit("All done. Goodbye.")
diff --git a/hallgrim/uploader.py b/hallgrim/uploader.py
new file mode 100644
index 0000000..7a8e02d
--- /dev/null
+++ b/hallgrim/uploader.py
@@ -0,0 +1,78 @@
+################################################################################
+#
+# This is the uploader. It simplifies the testing process immensely and  makes
+# autoILIAS finally obsolete, since this system uses a proper Ilias
+# implementation.
+#
+# The code is straight forward. You need to seed s couple of POST requests
+# in the right order an then the items appear at the right place. Currently
+# works for the Folder 'Sandkasten' of the test environment that ships
+# with hallgrim. Ilias changes often so maybe the urls have to be updated.
+#
+# The simplest way was to intercept the html traffic with wireshark.
+#
+# Sadly this script adds some ugly dependencies like requests_toolbelt.
+#
+################################################################################
+
+import os
+
+import requests
+from requests_toolbelt import MultipartEncoder
+from lxml import html
+
+__all__ = ['send_script']
+
+# static data
+host = "http://192.168.1.2/"
+login = {"username" : "root", "password" : "homer", "cmd[showLogin]" : "Login"}
+upload_url = host + "ilias/ilias.php?ref_id=65&cmd=post&cmdClass=ilobjquestionpoolgui&cmdNode=26:gb&baseClass=ilRepositoryGUI&fallbackCmd=upload&rtoken=fd2f3337a6d4ae0689b5163d6af186a9"
+import_url = host + "ilias/ilias.php?ref_id=65&cmd=post&cmdClass=ilobjquestionpoolgui&cmdNode=26:gb&baseClass=ilRepositoryGUI&fallbackCmd=questions&rtoken=fd2f3337a6d4ae0689b5163d6af186a9"
+confirm_url = host + "ilias/ilias.php?ref_id=65&cmd=post&cmdClass=ilobjquestionpoolgui&cmdNode=26:gb&baseClass=ilRepositoryGUI&rtoken=fd2f3337a6d4ae0689b5163d6af186a9"
+
+import_data = {
+    "title" : "",
+    "description" : "",
+    "author" : "",
+    "type" : "",
+    "tblfsqpl_qst_brows_65[]" : "description",
+    "tblfsqpl_qst_brows_65[]" : "type",
+    "tblfsqpl_qst_brows_65[]" : "points",
+    "tblfsqpl_qst_brows_65[]" : "statistics",
+    "tblfsqpl_qst_brows_65[]" : "author",
+    "tblfsqpl_qst_brows_65[]" : "created",
+    "tblfsqpl_qst_brows_65[]" : "tstamp",
+    "tblfsqpl_qst_brows_65[]" : "working_time",
+    "tblfshqpl_qst_brows_65" : "1",
+    "cmd[importQuestions]" : "Import",
+}
+
+confirm_data = {
+    "qpl_new" : "",
+    "ident[]" : "undefined", # this has to be based on the number of questions
+    "cmd[importVerifiedFile]" : "Import",
+    "questions_only" : "1",
+}
+
+
+def send_script(filepath):
+    m = MultipartEncoder(fields={
+        'xmldoc': (
+            os.path.basename(filepath),
+            open(filepath, 'r', encoding='utf-8').read(),
+            'text/xml'
+        ),
+        'ilfilehash': 'Is not validated suckers',
+        'cmd[upload]': 'Upload',
+    })
+
+    # session create and login
+    session = requests.Session()
+    r = session.post(host + "ilias/login.php", data=login)
+    r = session.get("http://192.168.1.2/ilias/ilias.php?ref_id=65&cmd=questions&cmdClass=ilobjquestionpoolgui&cmdNode=26:gb&baseClass=ilRepositoryGUI&ref_id=65")
+    r = session.post(import_url, data=import_data)
+    r = session.post(upload_url, data=m, headers={'Content-Type': m.content_type})
+    r = session.post(confirm_url, data=confirm_data)
+
+    return r.status_code == 500
+
-- 
GitLab