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

task(department-name): Adiciona nome dos departamentos ao banco de dados #211

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
6 changes: 3 additions & 3 deletions api/api/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

@admin.register(Department)
class DepartmentAdmin(admin.ModelAdmin):
list_display = ['code', 'year', 'period']
search_fields = ['code']
ordering = ['year', 'period']
list_display = ['name', 'code', 'year', 'period']
search_fields = ['code', 'name']
ordering = ['year', 'period', 'name']


@admin.register(Discipline)
Expand Down
28 changes: 15 additions & 13 deletions api/api/management/commands/updatedb.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,20 @@ def handle(self, *args: Any, **options: Any):
target=self.delete_period, args=(year, period,))
threads.append(thread)
thread.start()

for thread in threads:
thread.join()
threads.clear()

return

departments_ids = get_list_of_departments()

if departments_ids is None:
self.display_error_message("department_ids")
departments_data = get_list_of_departments()
if departments_data is None:
self.display_error_message("get_list_of_departments")
return
departments_ids, departments_names = departments_data
if departments_ids is None or departments_names is None:
self.display_error_message("get_list_of_departments")

print("Atualizando o banco de dados...")

Expand All @@ -81,7 +83,7 @@ def start_update_year_period(year: str, period: str):
print(f"Começando atualização de {year}/{period}")
with transaction.atomic():
self.update_departments(
departments_ids, year, period, options)
departments_ids=departments_ids, departments_names=departments_names, year=year, period=period, options=options)

self.display_success_update_message(
operation=f"{year}/{period}", start_time=start_time)
Expand All @@ -105,9 +107,9 @@ def start_update_year_period(year: str, period: str):

print(f"\nTempo total de execução: {(time() - start_tot_time):.1f}s")

def update_departments(self, departments_ids: list, year: str, period: str, options: Any) -> None:
def update_departments(self, departments_ids: list, departments_names: list, year: str, period: str, options: Any) -> None:
GabrielCastelo-31 marked this conversation as resolved.
Show resolved Hide resolved
"""Atualiza os departamentos do banco de dados e suas respectivas disciplinas."""
def execute_update(department_id):
def execute_update(department_id, department_name) -> None:
scraper = DisciplineWebScraper(department_id, year, period)
fingerprint = scraper.create_page_fingerprint()

Expand All @@ -124,7 +126,7 @@ def execute_update(department_id):

disciplines_list = scraper.get_disciplines()
department = dbh.get_or_create_department(
code=department_id, year=year, period=period)
code=department_id, name=department_name, year=year, period=period)

if options['descriptive']:
print(f"Departamento ({department_id}) desatualizado, operação necessária")
Expand All @@ -146,14 +148,14 @@ def execute_update(department_id):
days=class_info["days"], _class=class_info["class_code"], discipline=discipline, special_dates=class_info["special_dates"])

cache.set(cache_key, fingerprint, timeout=THIRTY_DAYS_IN_SECS)

if options['descriptive']:
print(f'Operação de atualização finalizada para o departamento ({department_id})')

threads = deque()
for department_id in departments_ids:
for department_id, department_name in zip(departments_ids, departments_names):
thread = threading.Thread(
target=execute_update, args=(department_id,))
target=execute_update, args=(department_id, department_name))
threads.append(thread)
thread.start()

Expand Down
18 changes: 18 additions & 0 deletions api/api/migrations/0009_department_name.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.2.10 on 2024-02-22 01:02

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api', '0008_schedule_created_at'),
]

operations = [
migrations.AddField(
model_name='department',
name='name',
field=models.CharField(default='', max_length=128),
),
]
3 changes: 2 additions & 1 deletion api/api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def delete(self, *args, **kwargs):
try:
cache.delete(kwargs['cache_key'])
kwargs.pop('cache_key')
except: # pragma: no cover
except: # pragma: no cover
raise ValueError(cache_error_msg)
else:
super(CustomModel, self).delete()
Expand All @@ -29,6 +29,7 @@ class Department(CustomModel):
year:str -> Ano do departamento
period:str -> Período do departamento
"""
name = models.CharField(max_length=128, default='')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Encontrei um departamento que possui 123 caracteres: PROGRAMA DE PÓS-GRADUAÇÃO EM PROFNIT - PROPRIEDADE INTELECTUAL E TRANSFERÊNCIA DE TECNOLOGIA PARA A INOVAÇÃO (PROFISSIONAL).

Acredito que esse é um dos casos que podemos deixar o tamanho máximo um pouco maior para garantir (em longo prazo) a ausência de erros com esse sistema. O que acha?

code = models.CharField(max_length=10)
year = models.CharField(max_length=4, default='0000')
period = models.CharField(max_length=1, default='1')
Expand Down
79 changes: 44 additions & 35 deletions api/api/tests/test_generate_schedule_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
from random import randint
import json


class TestGenerateScheduleAPI(APITestCase):
def setUp(self):
self.factory = APIRequestFactory()
self.content_type = 'application/json'
self.api_url = '/courses/schedules/generate/'
self.department = get_or_create_department(
code='518', year='2023', period='2')
code='518', name='Departamento de Matemática e Estatística', year='2023', period='2')
self.discipline = get_or_create_discipline(
name='CÁLCULO 1', code='MAT518', department=self.department)
self.class_1 = create_class(teachers=['RICARDO FRAGELLI'], classroom='S9', schedule='46M34', days=[
Expand All @@ -22,7 +23,7 @@ def setUp(self):
'Segunda-Feira 10:00 às 11:50', 'Quarta-Feira 10:00 às 11:50'], _class="1", special_dates=[], discipline=self.discipline_2)
self.class_4 = create_class(teachers=['Tatiana'], classroom='S1', schedule='7M1234', days=[
'Sábado 08:00 às 11:50'], _class="2", special_dates=[], discipline=self.discipline_2)

def test_with_correct_parameters(self):
"""
Testa a geração de horários com todos os parâmetros corretos
Expand All @@ -32,12 +33,13 @@ def test_with_correct_parameters(self):
'preference': [3, 2, 1],
'classes': [self.class_1.id, self.class_2.id, self.class_3.id, self.class_4.id]
})

response = self.client.post(self.api_url, body, content_type=self.content_type)


response = self.client.post(
self.api_url, body, content_type=self.content_type)

self.assertEqual(response.status_code, 200)
self.assertTrue(len(response.data["schedules"]) > 0)

def test_with_conflicting_classes(self):
"""
Testa a geração de horários com classes conflitantes
Expand All @@ -46,32 +48,35 @@ def test_with_conflicting_classes(self):
'preference': [3, 2, 1],
'classes': [self.class_1.id, self.class_3.id]
})

response = self.client.post(self.api_url, body, content_type=self.content_type)


response = self.client.post(
self.api_url, body, content_type=self.content_type)

self.assertEqual(response.status_code, 200)
self.assertFalse(len(response.data["schedules"]))

def test_with_invalid_class(self):
"""
Testa a geração de horários com uma classe inválida
"""

classes_ids = [self.class_1.id, self.class_2.id, self.class_3.id, self.class_4.id]

classes_ids = [self.class_1.id, self.class_2.id,
self.class_3.id, self.class_4.id]
random_id = randint(1, 10000)
while(random_id in classes_ids): # pragma: no cover

while (random_id in classes_ids): # pragma: no cover
random_id = randint(1, 10000)

body = json.dumps({
'preference': [3, 2, 1],
'classes': classes_ids + [random_id]
})

response = self.client.post(self.api_url, body, content_type=self.content_type)


response = self.client.post(
self.api_url, body, content_type=self.content_type)

self.assertEqual(response.status_code, 400)

def test_with_invalid_preference(self):
"""
Testa a geração de horários com uma preferência inválida
Expand All @@ -80,11 +85,12 @@ def test_with_invalid_preference(self):
'preference': [3, 2, 1, 4],
'classes': [self.class_1.id, self.class_2.id, self.class_3.id, self.class_4.id]
})

response = self.client.post(self.api_url, body, content_type=self.content_type)


response = self.client.post(
self.api_url, body, content_type=self.content_type)

self.assertEqual(response.status_code, 400)

def test_with_invalid_preference_type(self):
"""
Testa a geração de horários com uma preferência inválida (tipo)
Expand All @@ -93,32 +99,35 @@ def test_with_invalid_preference_type(self):
'preference': [3, 2, '1'],
'classes': [self.class_1.id, self.class_2.id, self.class_3.id, self.class_4.id]
})

response = self.client.post(self.api_url, body, content_type=self.content_type)


response = self.client.post(
self.api_url, body, content_type=self.content_type)

self.assertEqual(response.status_code, 400)

def test_with_no_classes(self):
"""
Testa a geração de horários sem classes
"""
body = json.dumps({
'classes': []
})

response = self.client.post(self.api_url, body, content_type=self.content_type)


response = self.client.post(
self.api_url, body, content_type=self.content_type)

self.assertEqual(response.status_code, 400)

def test_with_no_preference(self):
"""
Testa a geração de horários sem preferência
"""
body = json.dumps({
'classes': [self.class_1.id]
})

response = self.client.post(self.api_url, body, content_type=self.content_type)


response = self.client.post(
self.api_url, body, content_type=self.content_type)

self.assertEqual(response.status_code, 200)
self.assertTrue(len(response.data["schedules"]) > 0)
self.assertTrue(len(response.data["schedules"]) > 0)
3 changes: 2 additions & 1 deletion api/api/tests/test_get_schedules_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@

class TestGetSchedules(APITestCase):
def setUp(self):
self.department = dbh.get_or_create_department('518', '2023', '2')
self.department = dbh.get_or_create_department(
'518', 'Departamento de matematica', '2023', '2')
self.discipline = dbh.get_or_create_discipline(
'CÁLCULO 1', 'MAT0025', self.department)
self._class = dbh.create_class(['EDSON ALVES DA COSTA JUNIOR'], 'FGA - I8', '35T23', [
Expand Down
3 changes: 2 additions & 1 deletion api/api/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
class ModelsTest(TestCase):
def create_data(self):
self.department = Department.objects.create(
name='Instituto de Informática',
code='INF',
year="2023",
period="2"
Expand Down Expand Up @@ -46,6 +47,7 @@ def test_create_class(self):
self.assertEqual(self._class.discipline, self.discipline)

def test_create_department(self):
self.assertEqual(self.department.name, 'Instituto de Informática')
self.assertEqual(self.department.code, 'INF')
self.assertEqual(self.department.year, '2023')
self.assertEqual(self.department.period, '2')
Expand Down Expand Up @@ -85,4 +87,3 @@ def test_delete_class_with_cache_handle(self):

self.assertTrue(empty_model)
self.assertTrue(empty_cache)

3 changes: 2 additions & 1 deletion api/api/tests/test_schedule_delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@

class TestDeleteSchedules(APITestCase):
def setUp(self):
self.department = dbh.get_or_create_department('518', '2023', '2')
self.department = dbh.get_or_create_department(
'518', 'Departamento de Matemática e Estatística', '2023', '2')
self.discipline = dbh.get_or_create_discipline(
'CÁLCULO 1', 'MAT0025', self.department)
self._class = dbh.create_class(['EDSON ALVES DA COSTA JUNIOR'], 'FGA - I8', '35T23', [
Expand Down
10 changes: 6 additions & 4 deletions api/api/tests/test_schedule_save.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ class TestScheduleSaveAPI(APITestCase, ErrorRequestBodyScheduleSave):

def setDepartmentInfos(self):
self.department_infos = [
('518', '2023', '2'), ('673', '2023', '2'),
('518', '2024', '1'), ('673', '2024', '1')
('518', 'Departamento de Matemática e Estatística',
'2023', '2'), ('673', 'Departamento de Matemática e Estatística', '2023', '2'),
('518', 'Departamento de Matemática e Estatística', '2024',
'1'), ('673', 'Departamento de Matemática e Estatística', '2024', '1')
]

def setDisciplineInfos(self):
Expand Down Expand Up @@ -98,9 +100,9 @@ def setUpDepartments(self):
self.departments = {}
self.setDepartmentInfos()
for i, infos in enumerate(self.department_infos):
code, year, period = infos
code, name, year, period = infos
new_department = dbh.get_or_create_department(
code=code, year=year, period=period
code=code, name=name, year=year, period=period
)
self.departments[f'department_{i}_{year}_{period}'] = new_department

Expand Down
2 changes: 1 addition & 1 deletion api/api/tests/test_search_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
class TestSearchAPI(APITestCase):
def setUp(self) -> None:
self.department = get_or_create_department(
code='518', year='2023', period='2')
code='518', name='Departamento de Computação', year='2023', period='2')
self.discipline_1 = get_or_create_discipline(
name='CÁLCULO 1', code='MAT518', department=self.department)
self.discipline_2 = get_or_create_discipline(
Expand Down
4 changes: 2 additions & 2 deletions api/utils/db_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
"""Este módulo lida com as operações de banco de dados."""


def get_or_create_department(code: str, year: str, period: str) -> Department:
def get_or_create_department(code: str, name: str, year: str, period: str) -> Department:
"""Cria um departamento."""
return Department.objects.get_or_create(code=code, year=year, period=period)[0]
return Department.objects.get_or_create(code=code, name=name, year=year, period=period)[0]


def get_or_create_discipline(name: str, code: str, department: Department) -> Discipline:
Expand Down
Loading
Loading