mirror of
https://github.com/Code-For-Groningen/temmies.git
synced 2025-03-15 15:10:15 +01:00
Compare commits
6 Commits
6a63abf7ae
...
1a950c0eb2
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1a950c0eb2 | ||
![]() |
a3a9f5dfee | ||
![]() |
461b506be5 | ||
![]() |
a0aeca87b1 | ||
![]() |
17f0bd237a | ||
![]() |
2378be4d42 |
@ -1,12 +1,12 @@
|
||||
<p align="center">
|
||||
<img src="docs/img/rugemmie.gif" />
|
||||
<img src="https://github.com/Code-For-Groningen/temmies/blob/v1.1.0/docs/img/rugemmie.gif" />
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://temmies.confest.im"><img alt="Read the Docs" src="https://img.shields.io/readthedocs/temmies"></a>
|
||||
<img alt="GitHub" src="https://img.shields.io/github/license/Code-For-Groningen/temmies">
|
||||
</p>
|
||||
|
||||
A python library which interacts with themis. Uses bs4. I'll try to end development on a somewhat working state.
|
||||
A python library which interacts with [Themis](https://themis.housing.rug.nl/). Uses bs4. I'll try to end development on a somewhat working state.
|
||||
|
||||
## Intended Features
|
||||
* [x] Log in
|
||||
@ -15,11 +15,11 @@ A python library which interacts with themis. Uses bs4. I'll try to end developm
|
||||
* [x] Submission status
|
||||
|
||||
## Docs
|
||||
[here](http://temmies.confest.im/).
|
||||
- [here](http://temmies.confest.im/).
|
||||
|
||||
## Possible continuations
|
||||
* Discord bot
|
||||
* CLI program
|
||||
* [CLI program](https://github.com/Code-For-Groningen/temmies-cli)
|
||||
|
||||
## Thanks to
|
||||
* [Glitchcat](https://glitchcat.github.io/themis-api/), cool docs bro.
|
||||
|
@ -8,9 +8,11 @@ Creates the initial connection to Themis.
|
||||
```python
|
||||
from temmies.themis import Themis
|
||||
|
||||
themis = Themis("s-number", "password")
|
||||
themis = Themis("s-number")
|
||||
```
|
||||
|
||||
On the first run, you will be prompted for your password. Then, on the next run(s), you will be able to log in automatically, as the password is stored in the system keyring. If you want to delete it [click here](https://www.google.com/search?hl=en&q=delete%20a%20password%20from%20keyring).
|
||||
|
||||
### Methods
|
||||
#### `login()`
|
||||
Logs in to Themis. Runs automatically when the class is initialized.
|
||||
|
@ -11,4 +11,4 @@
|
||||
#### **Codebase**
|
||||
- Prepended `get_` to all methods in `Submission`
|
||||
- Created base `Group` from which `Course` and `ExerciseGroup` inherit.
|
||||
-
|
||||
- Using system keyring to store passwords (Issue #11)
|
@ -21,7 +21,7 @@ pip install temmies
|
||||
from temmies.themis import Themis
|
||||
|
||||
# Log in
|
||||
themis = Themis("s-number", "password")
|
||||
themis = Themis("s-number") # You will be prompted for your password
|
||||
|
||||
# Get a year
|
||||
year = themis.get_year(2023, 2024)
|
||||
|
19
requirements.txt
Normal file
19
requirements.txt
Normal file
@ -0,0 +1,19 @@
|
||||
beautifulsoup4==4.12.3
|
||||
bs4==0.0.2
|
||||
certifi==2024.8.30
|
||||
cffi==1.17.1
|
||||
charset-normalizer==3.4.0
|
||||
cryptography==43.0.3
|
||||
idna==3.10
|
||||
jaraco.classes==3.4.0
|
||||
jaraco.context==6.0.1
|
||||
jaraco.functools==4.1.0
|
||||
jeepney==0.8.0
|
||||
keyring==25.5.0
|
||||
lxml==5.3.0
|
||||
more-itertools==10.5.0
|
||||
pycparser==2.22
|
||||
requests==2.32.3
|
||||
SecretStorage==3.3.3
|
||||
soupsieve==2.6
|
||||
urllib3==2.2.3
|
@ -79,6 +79,6 @@ class Submission:
|
||||
def get_files(self) -> list[str] | None:
|
||||
"""Get a list of uploaded files in the format [(name, url)]"""
|
||||
if not self.__info:
|
||||
self.__info = self.info()
|
||||
self.__info = self.get_info()
|
||||
|
||||
return self.__info.get("files", None)
|
||||
|
@ -4,6 +4,8 @@ Main class for the Themis API
|
||||
"""
|
||||
|
||||
import urllib3
|
||||
import keyring
|
||||
import getpass
|
||||
from requests import Session
|
||||
from bs4 import BeautifulSoup
|
||||
from .year import Year
|
||||
@ -21,10 +23,22 @@ class Themis:
|
||||
all_years: Get all years
|
||||
"""
|
||||
|
||||
def __init__(self, user: str, passwd: str):
|
||||
self.session = self.login(user, passwd)
|
||||
self.years = []
|
||||
self.url = "https://themis.housing.rug.nl/course/"
|
||||
def __init__(self, user: str):
|
||||
self.user = user
|
||||
self.password = self.__get_password()
|
||||
self.session = self.login(user, self.password)
|
||||
|
||||
def __get_password(self) -> str:
|
||||
"""
|
||||
Retrieve the password from the keyring, prompting the user if not found.
|
||||
"""
|
||||
password = keyring.get_password(f'{self.user}-temmies', self.user)
|
||||
if not password:
|
||||
print(f"Password for user '{self.user}' not found in keyring.")
|
||||
password = getpass.getpass(prompt=f"Enter password for {self.user}: ")
|
||||
keyring.set_password(f'{self.user}-temmies', self.user, password)
|
||||
print("Password saved securely in keyring.")
|
||||
return password
|
||||
|
||||
def login(self, user: str, passwd: str) -> Session:
|
||||
"""
|
||||
@ -58,9 +72,13 @@ class Themis:
|
||||
|
||||
# check if login was successful
|
||||
log_out = "Welcome, logged in as" in r.text
|
||||
if not log_out:
|
||||
raise IllegalAction(message=f"Login for user {user} failed")
|
||||
|
||||
if "Invalid credentials" in r.text:
|
||||
# Prompt for password again
|
||||
print("Invalid credentials. Please try again.")
|
||||
passwd = getpass.getpass(prompt="Enter password: ")
|
||||
keyring.set_password(f'{self.user}-temmies', self.user, passwd)
|
||||
return self.login(user, passwd)
|
||||
|
||||
return s
|
||||
|
||||
def get_year(self, start: int, end: int) -> Year:
|
||||
|
Loading…
x
Reference in New Issue
Block a user