From c0056a27d1aee53d0d2a529f4b6a4cd951e377c0 Mon Sep 17 00:00:00 2001
From: Boyan <boyan@confest.im>
Date: Sat, 6 Apr 2024 16:16:23 +0200
Subject: [PATCH] Migrated to mkdocs for documentation. Slight clean up of
 code.

---
 .gitignore                        |   5 +-
 .readthedocs.yaml                 |  13 +--
 Makefile                          |  20 -----
 docs/about.md                     |  10 +++
 docs/api.md                       | 141 ++++++++++++++++++++++++++++++
 docs/conf.py                      |  27 ------
 {images => docs/img}/rugemmie.gif | Bin
 docs/index.md                     |  14 +++
 docs/index.rst                    |  29 ------
 docs/requirements.txt             |   1 -
 mkdocs.yml                        |   6 ++
 src/Course.py                     |   6 --
 src/ExerciseGroup.py              |   4 +-
 src/Themis.py                     |   1 -
 src/Year.py                       |   2 +-
 15 files changed, 179 insertions(+), 100 deletions(-)
 delete mode 100644 Makefile
 create mode 100644 docs/about.md
 create mode 100644 docs/api.md
 delete mode 100644 docs/conf.py
 rename {images => docs/img}/rugemmie.gif (100%)
 create mode 100644 docs/index.md
 delete mode 100644 docs/index.rst
 delete mode 100644 docs/requirements.txt
 create mode 100644 mkdocs.yml

diff --git a/.gitignore b/.gitignore
index 0df7b3b..b486de6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,10 @@
-# Config
+# Config - Testing
 config.py
 baller.py 
 
+#Doc env
+.docs_env
+
 # Byte-compiled / optimized / DLL files
 __pycache__/
 *.py[cod]
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index 2960f5a..c017808 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -1,14 +1,5 @@
 
 version: 2
 
-build:
-  os: ubuntu-22.04
-  tools:
-    python: "3.12"
-
-sphinx:
-  configuration: docs/conf.py
-
-python:
-  install:
-    - requirements: docs/requirements.txt
\ No newline at end of file
+mkdocs:
+  configuration: mkdocs.yml
\ No newline at end of file
diff --git a/Makefile b/Makefile
deleted file mode 100644
index d0c3cbf..0000000
--- a/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-# Minimal makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line, and also
-# from the environment for the first two.
-SPHINXOPTS    ?=
-SPHINXBUILD   ?= sphinx-build
-SOURCEDIR     = source
-BUILDDIR      = build
-
-# Put it first so that "make" without argument is like "make help".
-help:
-	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
-
-.PHONY: help Makefile
-
-# Catch-all target: route all unknown targets to Sphinx using the new
-# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
-%: Makefile
-	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/about.md b/docs/about.md
new file mode 100644
index 0000000..27fc9da
--- /dev/null
+++ b/docs/about.md
@@ -0,0 +1,10 @@
+# This project was made with ❤️
+By [Boyan](https://confest.im) from the student organization [Code for Groningen](https://github.com/Code-For-Groningen/).
+
+It has **no** affiliation with the [University of Groningen](https://rug.nl).
+
+## Contact
+Shoot me an email: boyan(plus)cfg(at)bobokara.com.
+
+## License
+This project is licensed under the MIT License.
\ No newline at end of file
diff --git a/docs/api.md b/docs/api.md
new file mode 100644
index 0000000..91de2a3
--- /dev/null
+++ b/docs/api.md
@@ -0,0 +1,141 @@
+# Classes
+---
+## `Themis`
+Creates the initial connection to Themis.
+
+### Usage
+```python
+from temmies.Themis import Themis
+
+themis = Themis("s-number", "password")
+```
+
+### Methods
+#### `login()`
+Logs in to Themis. Runs automatically when the class is initialized.
+
+#### `getYear(start, end)`
+Returns an instance of a [`Year`](#year)(academic year) between `start` and `end`. 
+
+```python
+year = themis.getYear(2023, 2024)
+```
+
+#### `allYears()`
+Returns a list of `Year` instances corresponding to all years visible to the user.
+
+```python
+years = themis.allYears()
+```
+<sub> I don't see why you would need this, but it's here. </sub>
+
+----
+
+## `Year`
+
+### Usage
+```python
+year = themis.getYear(2023, 2024)
+```
+
+### Methods
+#### `getCourse(courseName)`
+Returns an instance of a [`Course`](#course) with the name `courseName`.
+
+```python
+pf = year.getCourse("Programming Fundamentals (for CS)")
+```
+
+#### `allCourses()`
+Returns a list of `Course` instances corresponding to all courses visible to the user in a given `Year`.
+
+```python
+courses = year.allCourses()
+```
+
+----
+
+## `Course`
+### Usage
+```python
+
+pf = year.getCourse("Programming Fundamentals (for CS)")
+print(pf.info) # <- course info attribute
+assignments = pf.getExerciseGroups()
+```
+
+### Methods
+#### `getExerciseGroups()`
+Returns a list of `ExerciseGroup` instances corresponding to all exercise groups visible to the user in a given `Course`.
+
+```python
+assignments = pf.getExerciseGroups()
+```
+
+## `ExerciseGroup`
+When this class is initialized, it will automatically fetch the exercise's info, files and test cases(it might be slow, because it indexes the entire course, which I will fix at some point).
+
+* Both folders and exercises are represented as `ExerciseGroup` instances.
+* Folders will have the `amExercise` attribute set to `False`.
+* Folders can have the `downloadFiles` method called on them.
+* Exercises can have the `submit`, `downloadFiles` and `downloadTCs` method called on them.
+
+
+### Usage
+```python
+pf = year.getCourse("Programming Fundamentals (for CS)")
+assignments = pf.getExerciseGroups()
+assignment = assignments[0]
+print(assignment.amExercise) # <- Exercise or folder attribute
+print(assignment.files) # <- Downloadable files attribute
+print(assignment.testCases) # <- Test cases attribute
+
+print(assignment.folders) # <- If the group contains folders, they will be here
+print(assignment.exercises) # <- If the group contains exercises, they will be here
+```
+
+### Example of folder traversal
+Let's say we have a folder structure like this:
+```
+- Course Name
+  - Week 1
+    - Exercise 1
+    - Exercise 2
+      - Part 1
+      - Part 2
+  - Week 2
+    - Exercise 1
+    - Exercise 2
+```
+And we want to get to `Part 2` of `Week 1`'s `Exercise 2`. We would do this:
+
+```python
+pf = year.getCourse("Programming Fundamentals (for CS)")
+assignments = pf.getExerciseGroups()
+week1 = assignments[0].folders[0]
+exercise2 = week1.exercises[1]
+part2 = exercise2.folders[1]
+```
+
+
+### Methods
+#### `downloadFiles(path=".")`
+Downloads all files in the exercise group to a directory `path`. Defaults to the current directory.
+
+```python
+  assignment.downloadFiles()
+```
+
+#### `downloadTCs(path=".")`
+Downloads all test cases in the exercise group to a directory `path`. Defaults to the current directory.
+
+```python
+  assignment.downloadTCs()
+```
+
+#### `submit(files)`
+Submits the files to the exercise group. (This is not implemented yet)
+
+```python
+  assignment.submit(["file1.py", "file2.py"])
+```
diff --git a/docs/conf.py b/docs/conf.py
deleted file mode 100644
index 21611d3..0000000
--- a/docs/conf.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Configuration file for the Sphinx documentation builder.
-#
-# For the full list of built-in configuration values, see the documentation:
-# https://www.sphinx-doc.org/en/master/usage/configuration.html
-
-# -- Project information -----------------------------------------------------
-# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
-
-project = 'temmies-docs'
-copyright = '2024, Boyan K.'
-author = 'Boyan K.'
-
-# -- General configuration ---------------------------------------------------
-# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
-
-extensions = []
-
-templates_path = ['_templates']
-exclude_patterns = []
-
-
-
-# -- Options for HTML output -------------------------------------------------
-# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
-
-html_theme = 'sphinx_rtd_theme'
-html_static_path = ['_static']
diff --git a/images/rugemmie.gif b/docs/img/rugemmie.gif
similarity index 100%
rename from images/rugemmie.gif
rename to docs/img/rugemmie.gif
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..b49860e
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,14 @@
+# Temmies!
+<center>![Temmie](img/rugemmie.gif)</center>
+
+
+## What is this?
+A python library which interacts with themis. Uses bs4. I'll try to end development on a somewhat working state.
+
+## Intended Features
+* Log in
+* Bulk download of test cases and files
+* Submitting files
+* Somewhat easy to use API to interact with courses
+
+## [Quickstart](quickstart.md)
\ No newline at end of file
diff --git a/docs/index.rst b/docs/index.rst
deleted file mode 100644
index 1e42761..0000000
--- a/docs/index.rst
+++ /dev/null
@@ -1,29 +0,0 @@
-.. temmies-docs documentation master file, created by
-   sphinx-quickstart on Tue Feb 13 20:53:28 2024.
-   You can adapt this file completely to your liking, but it should at least
-   contain the root `toctree` directive.
-
-Temmies!
-========================================
-.. image:: https://static.wikia.nocookie.net/undertale/images/7/7b/Temmie_battle_idle.gif
-   :align: center
-.. toctree::
-   :maxdepth: 2
-   :caption: Contents:
-
-
-
-Contents
---------
-
-.. toctree::
-
-   Home <self>
-   quickstart
-      install
-      usage
-   api
-      Themis
-      Year
-      Course
-      ExerciseGroup
\ No newline at end of file
diff --git a/docs/requirements.txt b/docs/requirements.txt
deleted file mode 100644
index 68273bc..0000000
--- a/docs/requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
-sphinx-rtd-theme==1.3.0
\ No newline at end of file
diff --git a/mkdocs.yml b/mkdocs.yml
new file mode 100644
index 0000000..017da75
--- /dev/null
+++ b/mkdocs.yml
@@ -0,0 +1,6 @@
+site_name: Temmies
+nav:
+  - Temmies: index.md
+  - API Reference: api.md
+  - About: about.md
+theme: readthedocs
\ No newline at end of file
diff --git a/src/Course.py b/src/Course.py
index a8f74a8..5ad5e6b 100644
--- a/src/Course.py
+++ b/src/Course.py
@@ -5,12 +5,6 @@ from ExerciseGroup import ExerciseGroup
 import re
 from exceptions.CourseUnavailable import CourseUnavailable
 
-# PROBLEM: This implementation is bad due to inconsistencies in the website 
-# The way we can tell the difference between an assignment and an exercise is by the presence of an a with the class "ass-submitable" 
-# As opposed to folders which contain exercises which are marked with "ass-group"
-# Therefore, we should take that into consideration and spawn the corresponding Exercise or Assignment class
-# Naming becomes a bit inconsistent like that as well, as Assignments could be Exercises. Might opt to call the "assignments" "exerciseGroups" or some shit.
-
 class Course:
   # Extend the Base class init
   def __init__(self, url:str, name:str, session:Session, parent):
diff --git a/src/ExerciseGroup.py b/src/ExerciseGroup.py
index 31e3e7c..40aad42 100644
--- a/src/ExerciseGroup.py
+++ b/src/ExerciseGroup.py
@@ -123,6 +123,4 @@ class ExerciseGroup():
                     session,
                     self)
       for x in folders]
-  
-  def recurse(self, folder:str):
-    print(self.url)
\ No newline at end of file
+  
\ No newline at end of file
diff --git a/src/Themis.py b/src/Themis.py
index 00d338e..c7c7e25 100644
--- a/src/Themis.py
+++ b/src/Themis.py
@@ -44,7 +44,6 @@ class Themis:
 
 
   def getYear(self, start:int, end:int):
-    # Get the current year
     return Year(self.session, self, start, end)
 
   def allYears(self): 
diff --git a/src/Year.py b/src/Year.py
index 52e2350..d89b298 100644
--- a/src/Year.py
+++ b/src/Year.py
@@ -18,7 +18,7 @@ class Year:
     return f"https://themis.housing.rug.nl/course/{self.start}-{self.year}"
 
   # Method to get the courses of the year
-  def getCourses(self, errors:bool=False) -> list[Course]:
+  def allCourses(self, errors:bool=False) -> list[Course]:
     # lis in a big ul 
     r = self.session.get(self.url)
     soup = BeautifulSoup(r.text, 'lxml')