Skip to content

Commit

Permalink
fix and refactor syncremote command (#1517, #1518)
Browse files Browse the repository at this point in the history
  • Loading branch information
mikkonie committed Dec 9, 2024
1 parent eb24009 commit a61cf6c
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 40 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Changed
- **Projectroles**
- Update default OIDC login button template (#1503)
- Update ownership transfer timeline event data (#1514)
- Refactor ``syncremote`` management command (#1518)

Fixed
-----
Expand All @@ -38,6 +39,7 @@ Fixed
- Add workaround to ``ProjectInviteCreateView`` returning 404 with category and query string (#1510)
- Broken tour help attachments in ``ProjectRoleView`` (#1512)
- ``RoleAssignmentCreateView`` crash as delegate with promoting and delegate limit reached (#1515)
- ``syncremote`` command crash from legacy API media type and version (#1517)


v1.0.2 (2024-09-09)
Expand Down
1 change: 1 addition & 0 deletions docs/source/major_changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Release Highlights
- Fix invite create view redirect failing in categories
- Fix role promoting crash as delegate with delegate limit reached
- Fix requiring deprecated SODAR API settings in tests
- Fix syncremote management command crash
- General bug fixes and minor updates

Breaking Changes
Expand Down
51 changes: 11 additions & 40 deletions projectroles/management/commands/syncremote.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
"""Syncremote management command for synchronizing remote projects"""

import json
import ssl
import sys
import urllib.request

from django.conf import settings
from django.core.management.base import BaseCommand
from django.urls import reverse

from projectroles.management.logging import ManagementCommandLogger
from projectroles.models import RemoteSite, SODAR_CONSTANTS
from projectroles.remote_projects import RemoteProjectAPI
from projectroles.views_api import CORE_API_MEDIA_TYPE, CORE_API_DEFAULT_VERSION


logger = ManagementCommandLogger(__name__)
Expand All @@ -24,12 +19,13 @@


class Command(BaseCommand):
help = 'Synchronizes user and project data from a remote site'
help = 'Synchronizes user and project data from the source site'

def add_arguments(self, parser):
pass

def handle(self, *args, **options):
remote_api = RemoteProjectAPI()
if getattr(settings, 'PROJECTROLES_DISABLE_CATEGORIES', False):
logger.info(
'Project categories and nesting disabled, '
Expand All @@ -39,11 +35,10 @@ def handle(self, *args, **options):
if settings.PROJECTROLES_SITE_MODE != SITE_MODE_TARGET:
logger.error('Site not in TARGET mode, unable to sync')
sys.exit(1)

try:
site = RemoteSite.objects.get(mode=SITE_MODE_SOURCE)
source_site = RemoteSite.objects.get(mode=SITE_MODE_SOURCE)
except RemoteSite.DoesNotExist:
logger.error('No source site defined, unable to sync')
logger.error('No source site set, unable to sync')
sys.exit(1)

if getattr(settings, 'PROJECTROLES_ALLOW_LOCAL_USERS', False):
Expand All @@ -52,46 +47,22 @@ def handle(self, *args, **options):
'roles for existing local users'
)
logger.info(
'Retrieving data from remote site "{}" ({})..'.format(
site.name, site.get_url()
'Retrieving data from source site "{}" ({})..'.format(
source_site.name, source_site.get_url()
)
)
api_url = site.get_url() + reverse(
'projectroles:api_remote_get', kwargs={'secret': site.secret}
)

try:
api_req = urllib.request.Request(api_url)
api_req.add_header(
'accept',
'{}; version={}'.format(
CORE_API_MEDIA_TYPE, CORE_API_DEFAULT_VERSION
),
)
response = urllib.request.urlopen(api_req)
remote_data = json.loads(response.read())

remote_data = remote_api.get_remote_data(source_site)
except Exception as ex:
helper_text = ''
if (
isinstance(ex, urllib.error.URLError)
and isinstance(ex.reason, ssl.SSLError)
and ex.reason.reason == 'WRONG_VERSION_NUMBER'
):
helper_text = (
' (most likely the server cannot handle HTTPS requests)'
)
logger.error(
'Unable to retrieve data from remote site: {}{}'.format(
ex, helper_text
)
'Failed to retrieve data from source site: {}'.format(ex)
)
sys.exit(1)

remote_api = RemoteProjectAPI()
logger.info('Synchronizing remote data from source site..')
try:
remote_api.sync_remote_data(site, remote_data)
remote_api.sync_remote_data(source_site, remote_data)
except Exception as ex:
logger.error('Remote sync cancelled with exception: {}'.format(ex))
logger.error('Remote sync failed with exception: {}'.format(ex))
sys.exit(1)
logger.info('Syncremote command OK')

0 comments on commit a61cf6c

Please sign in to comment.