Skip to content

Conversation

@Saksham-Sirohi
Copy link
Contributor

@Saksham-Sirohi Saksham-Sirohi commented Nov 20, 2025

Fixes #1326

Summary by Sourcery

Add Korean and Indonesian language support and introduce independent content language configuration for events

New Features:

  • Add Korean and Indonesian entries to global language settings in Eventyay and Pretalx
  • Introduce a new content_locales setting to let events choose submission languages separately from interface locales

Enhancements:

  • Implement update_language_configuration and cache clearing in Event model for language updates
  • Extend webhook processing to handle separate content_locales
  • Add content_locales field to event settings forms, views, and templates
  • Validate that content_locales is always a subset of active locales

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Nov 20, 2025

Reviewer's Guide

This PR introduces a distinct content_locales setting alongside existing locales, updating the Event model to respect settings overrides and clear caches, extending default config and validation, wiring through tasks, forms, views, and templates, and also adds Korean and Indonesian language entries across system configurations.

ER diagram for new content_locales event setting

erDiagram
    EVENT {
        locale_array varchar
        content_locale_array varchar
    }
    EVENT ||--o{ SETTINGS : has
    SETTINGS {
        locales list
        content_locales list
        locale varchar
    }
Loading

Class diagram for updated Event model language configuration

classDiagram
    class Event {
        +locale_array: str
        +content_locale_array: str
        +locales: list[str]
        +content_locales: list[str]
        +update_language_configuration(locales: list[str]|None, content_locales: list[str]|None, default_locale: str|None)
        +_clear_language_caches()
    }
Loading

File-Level Changes

Change Details Files
Enhanced Event model to support dynamic locale and content_locale settings
  • Refactored locales and content_locales getters to use settings cache with fallback
  • Implemented _clear_language_caches to reset cached properties
  • Added update_language_configuration method to sync arrays and clear caches
app/eventyay/base/models/event.py
Added content_locales setting definition in default settings
  • Introduced content_locales config block with defaults, serializer, and form parameters
  • Renamed Available languages label to Active languages
app/eventyay/base/configurations/default_setting.py
Registered Indonesian and Korean in language lists
  • Appended 'id' and 'ko' entries in eventyay settings languages and metadata
  • Added same entries in pretalx settings for talk service
app/eventyay/config/settings.py
talk/src/pretalx/settings.py
Adapted event webhook processing to handle content_locales
  • Extract locales and content_locales from payload with fallback
  • Updated locale_array and content_locale_array assignments on create and update
talk/src/pretalx/eventyay_common/tasks.py
Integrated content_locales into event settings forms and views
  • Added content_locales to auto_fields and initial value in EventCommonSettingsForm
  • Hooked update_language_configuration calls in control and common event views
  • Saved content_locales in settings during wizard done steps
app/eventyay/eventyay_common/forms/event.py
app/eventyay/eventyay_common/views/event.py
app/eventyay/control/views/event.py
app/eventyay/control/views/main.py
Enforced validation for content_locales subset
  • Added check to ensure content_locales is subset of locales in validate_event_settings
app/eventyay/base/settings.py
Updated event settings template to show content_locales field
  • Conditionally rendered content_locales input alongside locales
app/eventyay/eventyay_common/templates/eventyay_common/event/settings.html

Assessment against linked issues

Issue Objective Addressed Explanation
#1326 Add Korean and Indonesian to the list of available language choices in the unified system.
#1326 Restore the three language configuration options (Default Language, Active Languages, Content Languages) in the common event settings.
#1326 Ensure the talk component displays and applies the selected event languages correctly, not just English.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes and they look great!

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location> `app/eventyay/base/models/event.py:2119-2120` </location>
<code_context>
+        content_locales: list[str] | None = None,
+        default_locale: str | None = None,
+    ) -> None:
+        locales_list = list(locales or [])
+        content_locales_list = list(content_locales or []) or locales_list
+        if locales_list:
+            self.locale_array = ','.join(locales_list)
</code_context>

<issue_to_address>
**suggestion:** The fallback for content_locales_list may lead to unexpected results if content_locales is an empty list.

If content_locales is an empty list, content_locales_list defaults to locales_list, which may not match the caller's intent. Please handle None and empty lists separately to avoid this ambiguity.

```suggestion
        locales_list = list(locales or [])
        if content_locales is None:
            content_locales_list = locales_list
        else:
            content_locales_list = list(content_locales)
```
</issue_to_address>

### Comment 2
<location> `app/eventyay/base/settings.py:115-124` </location>
<code_context>
     locales = settings_dict.get('locales', [])
     if default_locale and default_locale not in locales:
         raise ValidationError({'locale': _('Your default locale must also be enabled for your event (see box above).')})
+    content_locales = settings_dict.get('content_locales') or locales
+    if content_locales:
+        invalid_content_locales = set(content_locales) - set(locales)
+        if invalid_content_locales:
+            raise ValidationError(
+                {'content_locales': _('Content languages must be a subset of the active languages.')}
+            )
     if settings_dict.get('attendee_names_required') and not settings_dict.get('attendee_names_asked'):
         raise ValidationError(
</code_context>

<issue_to_address>
**suggestion:** Validation for content_locales assumes locales is a list; ensure type consistency.

Set operations may fail if locales or content_locales are not lists. Add type checks or convert them to lists before using set().

```suggestion
    locales = settings_dict.get('locales', [])
    if not isinstance(locales, list):
        locales = list(locales)
    if default_locale and default_locale not in locales:
        raise ValidationError({'locale': _('Your default locale must also be enabled for your event (see box above).')})
    content_locales = settings_dict.get('content_locales') or locales
    if content_locales:
        if not isinstance(content_locales, list):
            content_locales = list(content_locales)
        invalid_content_locales = set(content_locales) - set(locales)
        if invalid_content_locales:
            raise ValidationError(
                {'content_locales': _('Content languages must be a subset of the active languages.')}
            )
```
</issue_to_address>

### Comment 3
<location> `app/eventyay/base/configurations/default_setting.py:864-870` </location>
<code_context>
+            choices=settings.LANGUAGES,
+            widget=MultipleLanguagesWidget,
+            required=True,
+            label=_('Content languages'),
+            help_text=_('Languages that speakers can select for their submissions.'),
         ),
     },
</code_context>

<issue_to_address>
**suggestion:** Help text for content_locales could clarify relationship to active languages.

Update the help text to specify that content languages should be a subset of active languages to avoid confusion.

```suggestion
        'form_kwargs': dict(
            choices=settings.LANGUAGES,
            widget=MultipleLanguagesWidget,
            required=True,
            label=_('Content languages'),
            help_text=_('Languages that speakers can select for their submissions. Content languages should be a subset of active languages to avoid confusion.'),
        ),
```
</issue_to_address>

### Comment 4
<location> `app/eventyay/base/models/event.py:2084-2085` </location>
<code_context>
    @cached_property
    def locales(self) -> list[str]:
        """Is a list of active event locales."""
        if hasattr(self, 'settings') and 'locales' in self.settings._cache():
            locales = self.settings.get('locales', as_type=list)
            if locales:
                return locales
        return [code for code in self.locale_array.split(',') if code]

</code_context>

<issue_to_address>
**suggestion (code-quality):** Use named expression to simplify assignment and conditional ([`use-named-expression`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/use-named-expression/))

```suggestion
            if locales := self.settings.get('locales', as_type=list):
```
</issue_to_address>

### Comment 5
<location> `app/eventyay/base/models/event.py:2093-2094` </location>
<code_context>
    @cached_property
    def content_locales(self) -> list[str]:
        """Is a list of active content locales."""
        if hasattr(self, 'settings') and 'content_locales' in self.settings._cache():
            locales = self.settings.get('content_locales', as_type=list)
            if locales:
                return locales
        fallback = [code for code in self.content_locale_array.split(',') if code]
        return fallback or self.locales

</code_context>

<issue_to_address>
**suggestion (code-quality):** Use named expression to simplify assignment and conditional ([`use-named-expression`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/use-named-expression/))

```suggestion
            if locales := self.settings.get('content_locales', as_type=list):
```
</issue_to_address>

### Comment 6
<location> `app/eventyay/base/settings.py:118-121` </location>
<code_context>
def validate_event_settings(event, settings_dict):
    from eventyay.base.models import Event
    from eventyay.base.signals import validate_event_settings

    default_locale = settings_dict.get('locale')
    locales = settings_dict.get('locales', [])
    if default_locale and default_locale not in locales:
        raise ValidationError({'locale': _('Your default locale must also be enabled for your event (see box above).')})
    content_locales = settings_dict.get('content_locales') or locales
    if content_locales:
        invalid_content_locales = set(content_locales) - set(locales)
        if invalid_content_locales:
            raise ValidationError(
                {'content_locales': _('Content languages must be a subset of the active languages.')}
            )
    if settings_dict.get('attendee_names_required') and not settings_dict.get('attendee_names_asked'):
        raise ValidationError(
            {'attendee_names_required': _('You cannot require specifying attendee names if you do not ask for them.')}
        )
    if settings_dict.get('attendee_emails_required') and not settings_dict.get('attendee_emails_asked'):
        raise ValidationError(
            {'attendee_emails_required': _('You have to ask for attendee emails if you want to make them required.')}
        )
    if settings_dict.get('invoice_address_required') and not settings_dict.get('invoice_address_asked'):
        raise ValidationError(
            {'invoice_address_required': _('You have to ask for invoice addresses if you want to make them required.')}
        )
    if settings_dict.get('invoice_address_company_required') and not settings_dict.get('invoice_address_required'):
        raise ValidationError(
            {
                'invoice_address_company_required': _(
                    'You have to require invoice addresses to require for company names.'
                )
            }
        )

    payment_term_last = settings_dict.get('payment_term_last')
    if payment_term_last and event.presale_end:
        if payment_term_last.date(event) < event.presale_end.date():
            raise ValidationError(
                {'payment_term_last': _('The last payment date cannot be before the end of presale.')}
            )

    if isinstance(event, Event):
        validate_event_settings.send(sender=event, settings_dict=settings_dict)

</code_context>

<issue_to_address>
**suggestion (code-quality):** Use named expression to simplify assignment and conditional [×2] ([`use-named-expression`](https://docs.sourcery.ai/Reference/Default-Rules/refactorings/use-named-expression/))

```suggestion
    if content_locales := settings_dict.get('content_locales') or locales:
        if invalid_content_locales := set(content_locales) - set(locales):
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@mariobehling mariobehling merged commit 8cda595 into fossasia:enext Nov 20, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Missing Korean & Indonesian languages and missing language options in Talk Component

2 participants