Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ariel++ #5

Draft
wants to merge 14 commits into
base: develop
Choose a base branch
from
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/*.egg-info
/dist/*
__pycache__
.dev
build
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@



## v0.3.1 minor release

New API for Ariel

## v0.3.1 minor release
Installation bugfixes.
Expand Down
9 changes: 9 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM python:3.9.6
WORKDIR /app
COPY pyproject.toml /app/pyproject.toml
COPY setup.cfg /app/setup.cfg
COPY LICENSE /app/LICENSE
COPY unimi_dl /app/unimi_dl
RUN pip install .
#COPY credentials.json /root/.local/share/unimi-dl/
ENTRYPOINT ["python3", "-m", "unimi_dl"]
14 changes: 14 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
USERNAME=`cut ~/.local/share/unimi-dl/credentials.json -d '"' -f4`
PASSWORD=`cut ~/.local/share/unimi-dl/credentials.json -d '"' -f8`

tests:
USERNAME=$(USERNAME) PASSWORD=$(PASSWORD) python3 -m unittest unimi_dl/test/test_*.py

test_ariel:
USERNAME=$(USERNAME) PASSWORD=$(PASSWORD) python3 -m unittest unimi_dl/test/test_ariel.py

test_utility:
USERNAME=$(USERNAME) PASSWORD=$(PASSWORD) python3 -m unittest unimi_dl/test/test_utility.py

setup:
#ln -sf ~/.local/share/unimi-dl/credentials.json credentials.json
9 changes: 9 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
version: '3'
services:
unimi_dl:
build: .
#context: .
# volumes:
# - type: bind
# source: .
# target: /app
32 changes: 32 additions & 0 deletions docs/dev/docker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Docker

L'utilizzo di Docker serve per creare un ambiente di sviluppo omogeneo.

## Inizializzazione

1. Nella root del progetto copiare `credentials.json`

```bash
cp ~/.local/share/unimi-dl/credentials.json ./
```

2. Buildare il container

```bash
docker-compose up
```

## Utilizzo

Si usa come unimi-dl passandogli gli argomenti ed opzioni.

```bash
docker-compose run unimi_dl
```

Se viene aggiornato il `Dockerfile` o `docker-compose.yml` è opportuno eseguire:

```bash
docker-compose down
docker-compose up --build
```
4 changes: 4 additions & 0 deletions pyrightconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"venvPath": ".",
"venv": "."
}
7 changes: 2 additions & 5 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,12 @@ scripts = unimi_dl/cmd.py


[options]
packages =
unimi_dl
unimi_dl.platform
python_requires = >=3.8
packages = find:
python_requires = >=3.6
install_requires =
requests
youtube-dl


[options.entry_points]
console_scripts =
unimi-dl = unimi_dl.cmd:main
Empty file.
64 changes: 64 additions & 0 deletions tests/test_ariel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from unimi_dl.course import Section, Course
import unittest
from ..platform import Ariel
import os


class TestAriel(unittest.TestCase):
def setUp(self) -> None:
username = os.getenv("USERNAME")
password = os.getenv("PASSWORD")
if username is None:
raise EnvironmentError("No Username provided")

if password is None:
raise EnvironmentError("No Password provided")

self.courses = []
self.instance = Ariel(email=username, password=password)
return super().setUp()

def tearDown(self) -> None:
self.instance.session.close()
return super().tearDown()

def test_create(self):
assert isinstance(self.instance, Ariel)

def test_getcourses(self):
ariel = self.instance

self.courses = ariel.getCourses()
for course in self.courses:
assert isinstance(course, Course)

def test_course_getAttachments_and_download(self):
ariel = self.instance

courses = ariel.getCourses()
course = courses[0]
for section in course.getSections():
assert isinstance(section, Section)
assert section != ""
attachments = section.getAttachments()
video = None
document = None
for attachment in attachments:
if video is not None and document is not None:
break

if video is None and attachment.filetype == "video":
video = attachment

if document is None and attachment.filetype == "document":
document = attachment

# if video is not None:
# video.download("./output/")

if document is not None:
document.download("./output/")


if __name__ == "__main__":
unittest.main()
83 changes: 83 additions & 0 deletions tests/test_utility.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
from unimi_dl.course import Course, Section
from pathlib import Path
import unittest
from ..platform import Ariel
import os


class TestUtility(unittest.TestCase):
def setUp(self) -> None:
self.username = os.getenv("USERNAME")
self.password = os.getenv("PASSWORD")
if self.username == None:
raise EnvironmentError("No Username provided")

if self.password == None:
raise EnvironmentError("No Password provided")

self.ariel = Ariel(self.username, self.password)

self.path_test = Path("./test/")
self.path_test.mkdir(parents=True, exist_ok=True)
return super().setUp()

def tearDown(self) -> None:
return super().tearDown()

def test_credential_manager(self):
from unimi_dl.utility.credentials_manager import CredentialsManager

credentials_manager = CredentialsManager(
"~/.local/share/unimi-dl/credentials.json"
)
credentials = credentials_manager.getCredentials()
assert credentials.email == self.username
assert credentials.password == self.password

def test_download_manager(self):
from unimi_dl.utility.download_manager import DownloadManager

download_manager = DownloadManager("./test/downloaded.json")

ariel = self.ariel
courses = ariel.getCourses()
course = courses[0]
video = None
document = None
for section in course.getSections():
if video is not None and document is not None:
download_manager.doDownload(
"ariel", document, str(self.path_test))
assert Path(str(self.path_test), document.name).exists()

# download_manager.doDownload("ariel", video, str(self.path_test))
# assert(Path(str(self.path_test), video.name).exists())

download_manager.save()
downloaded_json = read_from_json(str(download_manager.path))
# assert(video.url in downloaded_json["ariel"])
assert document.url in downloaded_json["ariel"]
break

attachments = section.getAttachments()
for attachment in attachments:
if video is not None and document is not None:
break

if video is None and attachment.filetype == "video":
video = attachment

if document is None and attachment.filetype == "document":
document = attachment


def read_from_json(path: str):
from json import dumps as json_dumps, load as json_load

with open(path, "r") as json_file:
dict = json_load(json_file)
return dict


if __name__ == "__main__":
unittest.main()
28 changes: 28 additions & 0 deletions tests/unimi_dl/platform/ariel/ariel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import os
from unittest import TestCase
from unittest import mock

from unimi_dl.platform.ariel.ariel import Ariel
from unimi_dl.platform.ariel.ariel_course import ArielCourse, ArielSection

OFFERTA_MYOF_STUB_PATH = os.path.join(
os.path.dirname(__file__), 'offerta_myof.html')


class ArielTestCase(TestCase):
@classmethod
def setUpClass(cls):
cls.email = "[email protected]"
cls.password = "secret"

def test_getCourses(self):
with mock.patch('unimi_dl.platform.ariel.utils.getPageHtml') \
as mock_getPageHtml, open(OFFERTA_MYOF_STUB_PATH, 'r') as myof:
mock_getPageHtml.return_value = myof.read()
self.ariel = Ariel(self.email, self.password)
courses = self.ariel.getCourses()
for course in courses:
for section in course.getSections():
print('section', section)
self.assertIsInstance(section, ArielSection)
self.assertIsInstance(course, ArielCourse)
68 changes: 68 additions & 0 deletions tests/unimi_dl/platform/ariel/ariel_course/ariel_course.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import os
from unittest import TestCase
from unittest import mock
from unimi_dl.downloadable.attachment import Attachment


from unimi_dl.platform.ariel.ariel import Ariel
from unimi_dl.platform.ariel.ariel_course import ArielCourse, ArielSection

from ..ariel import OFFERTA_MYOF_STUB_PATH

COURSE_MAIN_PAGE_STUB_PATH = os.path.join(
os.path.dirname(__file__), 'course_main_page.html')

COURSE_SUBSECTION_1_STUB_PATH = os.path.join(
os.path.dirname(__file__), 'subsection_1.html')

COURSE_SUBSECTION_2_STUB_PATH = os.path.join(
os.path.dirname(__file__), 'subsection_2.html')


class ArielCourseTestCase(TestCase):
@classmethod
def setUpClass(cls):
cls.email = "[email protected]"
cls.password = "secret"

def test_getCourses(self):
with mock.patch('unimi_dl.platform.ariel.utils.getPageHtml') \
as mock_getPageHtml,\
open(OFFERTA_MYOF_STUB_PATH, 'r') as myof,\
open(COURSE_MAIN_PAGE_STUB_PATH, 'r') as course_main_page,\
open(COURSE_SUBSECTION_1_STUB_PATH, 'r') as course_subsection1_page,\
open(COURSE_SUBSECTION_2_STUB_PATH, 'r') as course_subsection2_page:

mock_getPageHtml.side_effect = [
# parse all courses
myof.read(),
# select main page
course_main_page.read(),
# click on main page link
course_subsection1_page.read(),
# clink on subsection 1 link
course_subsection2_page.read(),
]

self.ariel = Ariel(self.email, self.password)
courses = self.ariel.getCourses()

test_course = next(filter(lambda course: course.name ==
"Architettura degli elaboratori II Edizione 1",
courses))

print('test_course', test_course)
self.assertIsInstance(test_course, ArielCourse)
test_section = next(filter(
lambda section: section.name == "Laboratorio 2021/2022 (VECCHIO)",
test_course.getSections()))
print('test_section', test_section)
self.assertIsInstance(test_section, ArielSection)
test_subsection = next(filter(
lambda subsection: subsection.name == "Turno B - Rivolta",
test_section.getSubsections()))
print('test_subsection', test_subsection.getAttachments())
self.assertIsInstance(test_subsection, ArielSection)
for attachment in test_subsection.getAttachments():
self.assertIsInstance(attachment, Attachment)
print(attachment, '\n\n')
Loading