-
Notifications
You must be signed in to change notification settings - Fork 10
Remodela institutições (versão 3) - wip #1263
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
base: main
Are you sure you want to change the base?
Changes from all commits
0257877
705e99e
eb53cf4
5bb8309
b562cd3
4d4c094
c6a4845
43ee9a9
622ce38
5fae7ac
c0b9c32
49a7a92
ed0106c
98d4dc8
5577f16
5120139
6681bb5
4bc2a5f
0ffb28d
d8fbd6c
50c3166
7c38bad
773af41
be13dd5
bcd79b0
27ff8b2
78b8da7
bfea2f5
761e01f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| # Generated by Django 5.2.7 on 2026-01-31 21:41 | ||
|
|
||
| import django.db.models.deletion | ||
| import modelcluster.fields | ||
| from django.db import migrations, models | ||
|
|
||
|
|
||
| class Migration(migrations.Migration): | ||
|
|
||
| dependencies = [ | ||
| ("collection", "0007_collection_platform_status"), | ||
| ("organization", "0011_organizationallevel_raworganization_and_more"), | ||
| ] | ||
|
|
||
| operations = [ | ||
| migrations.CreateModel( | ||
| name="CollectionOrganization", | ||
| fields=[ | ||
| ( | ||
| "id", | ||
| models.BigAutoField( | ||
| auto_created=True, | ||
| primary_key=True, | ||
| serialize=False, | ||
| verbose_name="ID", | ||
| ), | ||
| ), | ||
| ( | ||
| "sort_order", | ||
| models.IntegerField(blank=True, editable=False, null=True), | ||
| ), | ||
| ( | ||
| "initial_date", | ||
| models.CharField( | ||
| blank=True, | ||
| max_length=10, | ||
| null=True, | ||
| verbose_name="Initial Date", | ||
| ), | ||
| ), | ||
| ( | ||
| "final_date", | ||
| models.CharField( | ||
| blank=True, max_length=10, null=True, verbose_name="Final Date" | ||
| ), | ||
| ), | ||
| ( | ||
| "role", | ||
| models.CharField( | ||
| choices=[ | ||
| ("coordinator", "Coordinator"), | ||
| ("owner", "Owner"), | ||
| ("publisher", "Publisher"), | ||
| ("sponsor", "Sponsor"), | ||
| ("copyright_holder", "Copyright Holder"), | ||
| ("partner", "Partner"), | ||
| ("funder", "Funder"), | ||
| ("host", "Host"), | ||
| ("provider", "Provider"), | ||
| ("company", "Company"), | ||
| ], | ||
| max_length=50, | ||
| verbose_name="Role", | ||
| ), | ||
| ), | ||
| ( | ||
| "collection", | ||
| modelcluster.fields.ParentalKey( | ||
| null=True, | ||
| on_delete=django.db.models.deletion.SET_NULL, | ||
| related_name="organizations", | ||
| to="collection.collection", | ||
| ), | ||
| ), | ||
| ( | ||
| "organization", | ||
| models.ForeignKey( | ||
| blank=True, | ||
| help_text="Select the standardized organization data", | ||
| null=True, | ||
| on_delete=django.db.models.deletion.SET_NULL, | ||
| to="organization.organization", | ||
| ), | ||
| ), | ||
| ], | ||
| options={ | ||
| "verbose_name": "Collection Organization", | ||
| "verbose_name_plural": "Collection Organizations", | ||
| "unique_together": { | ||
| ("collection", "organization", "role", "initial_date", "final_date") | ||
| }, | ||
| }, | ||
| ), | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,7 +18,7 @@ | |
| TextWithLang, | ||
| ) | ||
| from core.utils.utils import fetch_data | ||
| from organization.models import HELP_TEXT_ORGANIZATION, Organization | ||
| from organization.models import HELP_TEXT_ORGANIZATION, Organization, BaseOrganizationRole | ||
|
|
||
| from . import choices | ||
|
|
||
|
|
@@ -116,11 +116,9 @@ def autocomplete_label(self): | |
| logo_panels = [ | ||
| InlinePanel("logos", label=_("Logos"), min_num=0), | ||
| ] | ||
| supporting_organization_panels = [ | ||
| InlinePanel("supporting_organization", label=_("Supporting Organization")), | ||
| ] | ||
| executing_organization_panels = [ | ||
| InlinePanel("executing_organization", label=_("Executing Organization")), | ||
|
|
||
| organization_panels = [ | ||
| InlinePanel("organizations", label=_("Organizations")), | ||
| ] | ||
|
|
||
| social_network_panels = [ | ||
|
|
@@ -136,10 +134,7 @@ def autocomplete_label(self): | |
| ), | ||
| ObjectList(logo_panels, heading=_("Logos")), | ||
| ObjectList( | ||
| supporting_organization_panels, heading=_("Supporting Organizations") | ||
| ), | ||
| ObjectList( | ||
| executing_organization_panels, heading=_("Executing Organization") | ||
| organization_panels, heading=_("Organizations") | ||
| ), | ||
| ObjectList(social_network_panels, heading=_("Social networks")), | ||
| ] | ||
|
|
@@ -330,6 +325,24 @@ class CollectionSocialNetwork(Orderable, SocialNetwork): | |
| ) | ||
|
|
||
|
|
||
| class CollectionOrganization(BaseOrganizationRole, Orderable): | ||
| # substitui CollectionSupportingOrganization e CollectionExecutingOrganization | ||
| collection = ParentalKey( | ||
| Collection, | ||
| on_delete=models.SET_NULL, | ||
| null=True, | ||
| related_name="organizations", | ||
| ) | ||
| panels = BaseOrganizationRole.panels | ||
|
|
||
| class Meta: | ||
| verbose_name = _("Collection Organization") | ||
| verbose_name_plural = _("Collection Organizations") | ||
| unique_together = [ | ||
| ("collection", "organization", "role", "initial_date", "final_date"), | ||
| ] | ||
|
Comment on lines
+341
to
+343
|
||
|
|
||
|
|
||
| class CollectionSupportingOrganization(Orderable, ClusterableModel, BaseHistory): | ||
| collection = ParentalKey( | ||
| Collection, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -629,6 +629,41 @@ class BaseHistory(models.Model): | |
| class Meta: | ||
| abstract = True | ||
|
|
||
| @property | ||
| def initial_date_isoformat(self): | ||
| if self.initial_date: | ||
| return self.initial_date.isoformat() | ||
| return None | ||
|
|
||
| @property | ||
| def final_date_isoformat(self): | ||
| if self.final_date: | ||
| return self.final_date.isoformat() | ||
| return None | ||
|
|
||
|
|
||
| class BaseDateRange(models.Model): | ||
| initial_date = models.CharField(_("Initial Date"), max_length=10, null=True, blank=True) | ||
| final_date = models.CharField(_("Final Date"), max_length=10, null=True, blank=True) | ||
|
|
||
| panels = [ | ||
| FieldPanel("initial_date"), | ||
| FieldPanel("final_date"), | ||
| ] | ||
|
Comment on lines
+645
to
+652
|
||
|
|
||
| class Meta: | ||
| abstract = True | ||
|
|
||
| @property | ||
| def range(self): | ||
| if self.initial_date and self.final_date: | ||
| return f"{self.initial_date} - {self.final_date}" | ||
| elif self.initial_date: | ||
| return f"from {self.initial_date}" | ||
| elif self.final_date: | ||
| return f"until {self.final_date}" | ||
| return None | ||
|
|
||
|
Comment on lines
+645
to
+666
|
||
|
|
||
| class BaseLogo(models.Model): | ||
| """ | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -13,6 +13,45 @@ def remove_extra_spaces(text): | |||||||||||||||||||
| # Padroniza a quantidade de espaços | ||||||||||||||||||||
| return " ".join(text.split()) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| def remove_html_tags(text): | ||||||||||||||||||||
| if not text: | ||||||||||||||||||||
| return text | ||||||||||||||||||||
| text = text.replace("<", "BREAKTAG<") | ||||||||||||||||||||
| text = text.replace(">", ">BREAKTAG") | ||||||||||||||||||||
| for part in text.split("BREAKTAG"): | ||||||||||||||||||||
| if part.startswith("<") and part.endswith(">"): | ||||||||||||||||||||
| continue | ||||||||||||||||||||
| if part.startswith("<"): | ||||||||||||||||||||
| continue | ||||||||||||||||||||
| if part.endswith(">"): | ||||||||||||||||||||
| continue | ||||||||||||||||||||
| yield part | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
||||||||||||||||||||
| def has_only_alpha_or_space(text): | ||||||||||||||||||||
| """ Verifica se o conteúdo do texto é válido como string, ou seja, | ||||||||||||||||||||
| não é vazio e não contém números. """ | ||||||||||||||||||||
| if not text: | ||||||||||||||||||||
| return False | ||||||||||||||||||||
| parts = text.split() | ||||||||||||||||||||
| for part in parts: | ||||||||||||||||||||
| if not part.isalpha(): | ||||||||||||||||||||
| return False | ||||||||||||||||||||
| return True | ||||||||||||||||||||
|
Comment on lines
+31
to
+40
|
||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
||||||||||||||||||||
| def clean_xml_tag_content(text, assert_string=True): | ||||||||||||||||||||
| if not text: | ||||||||||||||||||||
| return text | ||||||||||||||||||||
| text = "".join(remove_html_tags(text)) | ||||||||||||||||||||
| text_ = remove_extra_spaces(text) | ||||||||||||||||||||
| if assert_string: | ||||||||||||||||||||
| if has_only_alpha_or_space(text_): | ||||||||||||||||||||
| return text_ | ||||||||||||||||||||
| else: | ||||||||||||||||||||
| return None | ||||||||||||||||||||
|
Comment on lines
+49
to
+52
|
||||||||||||||||||||
| if has_only_alpha_or_space(text_): | |
| return text_ | |
| else: | |
| return None | |
| if not has_only_alpha_or_space(text_): | |
| logging.warning( | |
| "clean_xml_tag_content: text failed alpha/space assertion; preserving value: %r", | |
| text_, | |
| ) |
Copilot
AI
Jan 31, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The clean_xml_tag_content function has a logic issue. When assert_string=True, it returns None if the text contains any non-alphabetic characters (line 39). This means valid organization names with numbers, spaces, or special characters (e.g., "USP 2023", "Fiocruz-RJ") will be discarded. Consider removing the isalpha() check or making it more lenient to allow alphanumeric text with common punctuation.
Copilot
AI
Feb 1, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The clean_xml_tag_content function has an assert_string parameter that when True will return None if the text contains numbers. This behavior could silently discard valid organization names that contain numbers (e.g., "Lab 21", "Unit 3", "Building 5A"). Consider if this validation is too strict for organization names, or document why numeric content should be rejected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment on line 112 says "FIXME - deprecated - usar CollectionOrganizationSerializer" but it's placed above the supporting_organizations and executing_organizations fields which are actually deprecated. Line 116 then says the same thing above the organizations field, which is the NEW field. The comment on line 112 should be moved to line 116, or line 112's comment should say these fields are deprecated, not that CollectionOrganizationSerializer is deprecated.