mirror of
https://github.com/Code-For-Groningen/temmies.git
synced 2025-03-15 07:10:15 +01:00
Migrated to mkdocs for documentation. Slight clean up of code.
This commit is contained in:
parent
cff77bcc95
commit
c0056a27d1
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,7 +1,10 @@
|
|||||||
# Config
|
# Config - Testing
|
||||||
config.py
|
config.py
|
||||||
baller.py
|
baller.py
|
||||||
|
|
||||||
|
#Doc env
|
||||||
|
.docs_env
|
||||||
|
|
||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled / optimized / DLL files
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
|
@ -1,14 +1,5 @@
|
|||||||
|
|
||||||
version: 2
|
version: 2
|
||||||
|
|
||||||
build:
|
mkdocs:
|
||||||
os: ubuntu-22.04
|
configuration: mkdocs.yml
|
||||||
tools:
|
|
||||||
python: "3.12"
|
|
||||||
|
|
||||||
sphinx:
|
|
||||||
configuration: docs/conf.py
|
|
||||||
|
|
||||||
python:
|
|
||||||
install:
|
|
||||||
- requirements: docs/requirements.txt
|
|
20
Makefile
20
Makefile
@ -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)
|
|
10
docs/about.md
Normal file
10
docs/about.md
Normal file
@ -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.
|
141
docs/api.md
Normal file
141
docs/api.md
Normal file
@ -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"])
|
||||||
|
```
|
27
docs/conf.py
27
docs/conf.py
@ -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']
|
|
Before Width: | Height: | Size: 190 KiB After Width: | Height: | Size: 190 KiB |
14
docs/index.md
Normal file
14
docs/index.md
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# Temmies!
|
||||||
|
<center></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)
|
@ -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
|
|
@ -1 +0,0 @@
|
|||||||
sphinx-rtd-theme==1.3.0
|
|
6
mkdocs.yml
Normal file
6
mkdocs.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
site_name: Temmies
|
||||||
|
nav:
|
||||||
|
- Temmies: index.md
|
||||||
|
- API Reference: api.md
|
||||||
|
- About: about.md
|
||||||
|
theme: readthedocs
|
@ -5,12 +5,6 @@ from ExerciseGroup import ExerciseGroup
|
|||||||
import re
|
import re
|
||||||
from exceptions.CourseUnavailable import CourseUnavailable
|
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:
|
class Course:
|
||||||
# Extend the Base class init
|
# Extend the Base class init
|
||||||
def __init__(self, url:str, name:str, session:Session, parent):
|
def __init__(self, url:str, name:str, session:Session, parent):
|
||||||
|
@ -123,6 +123,4 @@ class ExerciseGroup():
|
|||||||
session,
|
session,
|
||||||
self)
|
self)
|
||||||
for x in folders]
|
for x in folders]
|
||||||
|
|
||||||
def recurse(self, folder:str):
|
|
||||||
print(self.url)
|
|
@ -44,7 +44,6 @@ class Themis:
|
|||||||
|
|
||||||
|
|
||||||
def getYear(self, start:int, end:int):
|
def getYear(self, start:int, end:int):
|
||||||
# Get the current year
|
|
||||||
return Year(self.session, self, start, end)
|
return Year(self.session, self, start, end)
|
||||||
|
|
||||||
def allYears(self):
|
def allYears(self):
|
||||||
|
@ -18,7 +18,7 @@ class Year:
|
|||||||
return f"https://themis.housing.rug.nl/course/{self.start}-{self.year}"
|
return f"https://themis.housing.rug.nl/course/{self.start}-{self.year}"
|
||||||
|
|
||||||
# Method to get the courses of the 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
|
# lis in a big ul
|
||||||
r = self.session.get(self.url)
|
r = self.session.get(self.url)
|
||||||
soup = BeautifulSoup(r.text, 'lxml')
|
soup = BeautifulSoup(r.text, 'lxml')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user