Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions events.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from django.core.management import call_command

from plugins.hydra import models, events


def distribute_articles(**kwargs):
print('We are distributing articles')
article = kwargs.get('article')
journal = article.journal

# Try direct access via reverse relation
try:
linked_group = journal.linked_journals
except models.LinkedJournals.DoesNotExist:
try:
linked_group = models.LinkedJournals.objects.get(links=journal)
except models.LinkedJournals.DoesNotExist:
return

# Build set of journals: primary + linked ones
group_journals = {linked_group.journal}
group_journals.update(
link.to_journal for link in
linked_group.journal_link.select_related("to_journal")
)

# Exclude the current journal
group_journals.discard(journal)

results = []

for journal in group_journals:
try:
call_command(
"copy_articles",
journal.code,
article=article.pk,
target_lang="en",
)
results.append(
{
"journal": journal.code,
"status": "success",
}
)
except Exception as e:
print(e)


return group_journals
44 changes: 44 additions & 0 deletions forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from django import forms


from utils import setting_handler, models
from plugins.hydra import plugin_settings


class HydraAdminForm(forms.Form):
hydra_enable_sidebar = forms.BooleanField(label="Enable Hydra Sidebar", required=False)

def __init__(self, *args, journal=None, **kwargs):
"""Initialize form with current plugin settings and apply help text."""
super().__init__(*args, **kwargs)
self.journal = journal
self.plugin = models.Plugin.objects.get(
name=plugin_settings.SHORT_NAME,
)

# Initialize fields with settings values and help texts
hydra_enable_sidebar_setting = setting_handler.get_plugin_setting(
self.plugin,
'hydra_enable_sidebar',
self.journal,
create=True,
pretty='Enable Hydra Sidebar',
types='boolean'
)
self.fields[
'hydra_enable_sidebar'
].initial = hydra_enable_sidebar_setting.processed_value

def save(self):
"""Save each setting in the cleaned data to the plugin settings."""
for setting_name, setting_value in self.cleaned_data.items():
if setting_value:
setting_value = 'On'
else:
setting_value = ''
setting_handler.save_plugin_setting(
plugin=self.plugin,
setting_name=setting_name,
value=setting_value,
journal=self.journal
)
218 changes: 170 additions & 48 deletions hooks.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
from itertools import groupby
from operator import attrgetter
from urllib.parse import urlparse

from django.db.models import Q, Subquery
from django.apps import apps
from django.http import Http404
from django.template.loader import render_to_string
from django.utils.translation import get_language_info

from plugins.hydra import models
from plugins.hydra import models, utils
from utils.logger import get_logger
from submission import models as submission_models

from utils import setting_handler


logger = get_logger(__name__)
Expand Down Expand Up @@ -36,7 +38,8 @@ def sidebar_article_links(context, article):

def language_header_switcher(context):
"""
Provides a language switcher for linked journal sites.
Provides a language switcher for journals linked by LinkedArticle records,
or (when not on an article page) switches to equivalent paths on linked journals.
"""

request = context["request"]
Expand All @@ -47,64 +50,183 @@ def language_header_switcher(context):
if not journal:
return ""

# Find the linked group this journal belongs to
try:
linked_group = journal.linked_journals
except models.LinkedJournals.DoesNotExist:
links = []

# Normalise path
prefix = f"/{journal.code}/"
stripped_path = path[len(prefix):] if path.startswith(prefix) else path
normalised_path = stripped_path.lstrip("/")

if not normalised_path:
corrected_path = "/"
elif normalised_path.startswith("issue/"):
corrected_path = "/issues/"
else:
corrected_path = f"/{normalised_path}"

if article:
# Build set of transitive linked article PKs
visited = set()
to_visit = {article.pk}

while to_visit:
current_ids = to_visit
to_visit = set()

linked = models.LinkedArticle.objects.filter(
Q(from_article_id__in=current_ids) | Q(to_article_id__in=current_ids)
).values("from_article_id", "to_article_id")

for link in linked:
from_id = link["from_article_id"]
to_id = link["to_article_id"]

if from_id not in visited:
to_visit.add(from_id)
if to_id not in visited:
to_visit.add(to_id)

visited.update(current_ids)

linked_articles = submission_models.Article.objects.filter(
pk__in=visited - {article.pk},
).select_related("journal")

for linked_article in linked_articles:
linked_journal = linked_article.journal

try:
linked_language = linked_journal.get_setting(
group_name="general",
setting_name="default_journal_language",
)
except Exception:
continue

links.append({
"name_local": get_language_info(linked_language)["name_local"],
"url": linked_journal.site_url(path=corrected_path),
})

else:
# No article: find the LinkedJournals group
try:
linked_group = models.LinkedJournals.objects.get(links=journal)
linked_set = journal.linked_journals
except models.LinkedJournals.DoesNotExist:
return ""
try:
journal_link = models.JournalLink.objects.get(to_journal=journal)
linked_set = journal_link.parent
except models.JournalLink.DoesNotExist:
linked_set = None

if linked_set:
for linked_journal in linked_set.links.all():
if linked_journal == journal:
continue

try:
linked_language = linked_journal.get_setting(
group_name="general",
setting_name="default_journal_language",
)
except Exception:
continue

links.append({
"name_local": get_language_info(linked_language)["name_local"],
"url": linked_journal.site_url(path=corrected_path),
})

# Add parent journal if we're not it
if linked_set.journal != journal:
try:
parent_language = linked_set.journal.get_setting(
group_name="general",
setting_name="default_journal_language",
)
links.append({
"name_local": get_language_info(parent_language)["name_local"],
"url": linked_set.journal.site_url(path=corrected_path),
})
except Exception:
pass

if not linked_group.journal_link.exists():
if not links:
return ""

# Strip the journal-specific path prefix
prefix = f"/{journal.code}/"
stripped_path = path[len(prefix):] if path.startswith(prefix) else path
corrected_path = "/issues/" if stripped_path.startswith("issue/") else f"/{stripped_path}"

# Build the full set of group journals
group_journals = {linked_group.journal}
group_journals.update(
link.to_journal for link in linked_group.journal_link.select_related("to_journal")
return render_to_string(
"hydra/elements/language_links.html",
{
"language_links": links,
}
)




def editor_nav_article_switcher(context):
"""
Adds backend links to linked articles.
"""
request = context["request"]
journal = getattr(request, "journal", None)
article = context.get("article")

sidebar_enabled = setting_handler.get_setting(
"plugin:hydra",
"hydra_enable_sidebar",
journal=journal,
).processed_value

if not sidebar_enabled:
return ""

if not article or not journal:
return ""

related = article.linked_from.select_related(
"from_article__journal",
"to_article__journal",
).all()
related |= article.linked_to.select_related(
"from_article__journal",
"to_article__journal",
).all()

linked_articles = utils.get_interlinked_articles(article.pk)
linked_articles = {a for a in linked_articles if a.pk != article.pk}

if not linked_articles:
return ""

current_code = journal.code
links = []

for linked_journal in group_journals:
if linked_journal.pk == journal.pk:
continue
for a in linked_articles:
raw_url = a.current_workflow_element_url or ""
parsed = urlparse(raw_url)
path_parts = parsed.path.strip("/").split("/")

try:
linked_language = linked_journal.get_setting(
group_name="general",
setting_name="default_journal_language",
)
except Exception:
continue

if article:
related = article.linked_from.select_related("from_article__journal", "to_article__journal").all()
related |= article.linked_to.select_related("from_article__journal", "to_article__journal").all()
if not any(
a.to_article.journal_id == linked_journal.pk
or a.from_article.journal_id == linked_journal.pk
for a in related
):
continue
# If the current journal code appears early AND this is a *different* journal
if (
current_code in path_parts[:2]
and a.journal_id != journal.pk
):
path_parts = [part for part in path_parts if part != current_code]

cleaned_path = "/" + "/".join(path_parts)

links.append({
"name_local": get_language_info(linked_language)["name_local"],
"url": linked_journal.site_url(path=corrected_path),
"article": a,
"journal": a.journal.code if hasattr(a, "journal") else "",
"url": cleaned_path,
})

if not links:
return ""

return render_to_string(
"hydra/elements/language_links.html",
"hydra/elements/linked_article_admin_links.html",
{
"language_links": links,
"article_links": links,
}
)


17 changes: 17 additions & 0 deletions install/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[
{
"group": {
"name": "plugin:hydra"
},
"setting": {
"description": "Enable Hydra Sidebar",
"is_translatable": true,
"name": "hydra_enable_sidebar",
"pretty_name": "Enable Hydra Sidebar",
"type": "char"
},
"value": {
"default": ""
}
}
]
Loading