Skip to content

Commit

Permalink
Merge pull request #10902 from opaduchak/feature/ENG-6831
Browse files Browse the repository at this point in the history
[ENG-6831] Remove _LegacyConfigsForWBKey from osf.io
  • Loading branch information
adlius authored Jan 10, 2025
2 parents 20d4af7 + 8438af4 commit 94004f8
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 158 deletions.
100 changes: 48 additions & 52 deletions osf/external/gravy_valet/request_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ def _make_gv_request(
return response


def get_gv_citation_url_list_for_project(auth, addon_short_name, project, request=None, pid=None) -> list:
def get_gv_citation_url_list_for_project(auth, project, request=None, pid=None) -> dict:
if pid:
project_url = settings.DOMAIN + pid
else:
Expand All @@ -252,21 +252,18 @@ def get_gv_citation_url_list_for_project(auth, addon_short_name, project, reques
params={'filter[resource_uri]': project_url},
)
if not resource_references_response:
return []
configured_citation_addons_url = resource_references_response.get_related_link(
'configured_citation_addons')
addons_url_list = get_raw_gv_result(
return {}
configured_citation_addons_url = resource_references_response.get_related_link('configured_citation_addons')
addon_list = get_raw_gv_result(
endpoint_url=configured_citation_addons_url,
requesting_user=auth.user,
requested_resource=project,
request_method='GET',
params={}
)
gv_addon_name = addon_short_name if addon_short_name != 'zotero' else 'zotero_org'
citation_url_list = list(
filter(lambda x: x['attributes']['external_service_name'] == gv_addon_name, addons_url_list))
return citation_url_list

return {
addon['attributes']['external_service_name']: addon for addon in addon_list
}

def _invoke_gv_citation_operation_invocations(auth, addon, project, list_id):
data = {
Expand Down Expand Up @@ -300,51 +297,49 @@ def _invoke_gv_citation_operation_invocations(auth, addon, project, list_id):
def citation_list_gv_request(auth, request, addon_short_name, list_id, show):
from osf.models import Node

response = {'contents': []}
contents = []
project = Node.objects.filter(guids___id__in=[request.view_args.get('pid')]).first()
citation_url_list = get_gv_citation_url_list_for_project(
addon = get_gv_citation_url_list_for_project(
auth=auth,
request=request,
addon_short_name=addon_short_name,
project=project
)[addon_short_name]
gv_response = _invoke_gv_citation_operation_invocations(
auth=auth,
addon=addon,
project=project,
list_id=list_id
)
for addon in citation_url_list:
gv_response = _invoke_gv_citation_operation_invocations(
auth=auth,
addon=addon,
project=project,
list_id=list_id
)
if gv_response.status_code == 201:
attributes_dict = gv_response.json()['data']['attributes']
items = attributes_dict.get('operation_result').get('items')
for item in items:
item_id = item.get('item_id', '')
kind = CITATION_ITEM_TYPE_ALIASES.get(item.get('item_type', ''))
if 'csl' in item.keys():
change_response = item
change_response['kind'] = kind
change_response['id'] = item_id
else:
change_response = {
'data': {
'addon': addon_short_name,
'kind': kind,
'id': item_id,
'name': item.get('item_name', ''),
'path': item.get('item_path', '/'),
'parent_list_id': item.get('parent_list_id', 'ROOT'),
'provider_list_id': item_id,
},
if gv_response.status_code == 201:
attributes_dict = gv_response.json()['data']['attributes']
items = attributes_dict.get('operation_result').get('items')
for item in items:
item_id = item.get('item_id', '')
kind = CITATION_ITEM_TYPE_ALIASES.get(item.get('item_type', ''))
if 'csl' in item.keys():
change_response = item
change_response['kind'] = kind
change_response['id'] = item_id
else:
change_response = {
'data': {
'addon': addon_short_name,
'kind': kind,
'name': item.get('item_name', ''),
'id': item_id,
'urls': {
'fetch': f'/api/v1/project/{project._id}/{addon_short_name}/citations/{item_id}/',
}
'name': item.get('item_name', ''),
'path': item.get('item_path', '/'),
'parent_list_id': item.get('parent_list_id', 'ROOT'),
'provider_list_id': item_id,
},
'kind': kind,
'name': item.get('item_name', ''),
'id': item_id,
'urls': {
'fetch': f'/api/v1/project/{project._id}/{addon_short_name}/citations/{item_id}/',
}
response['contents'].append(change_response)
return response
}
contents.append(change_response)
return {'contents': contents}


def _format_included_entities(included_entities_json):
Expand Down Expand Up @@ -394,13 +389,14 @@ def get_related_id(self, relationship_name):
def get_related_link(self, relationship_name):
return self._relationships[relationship_name].related_link

def get_included_member(self, relationship_name):
return self._includes.get(relationship_name)
def get_included_member(self, *relationship_path: str):
related_object = self
for relationship_name in relationship_path:
related_object = related_object._includes.get(relationship_name)
return related_object

def get_included_attribute(self, include_path: typing.Iterable[str], attribute_name: str):
related_object = self
for relationship_name in include_path:
related_object = related_object.get_included_member(relationship_name)
related_object = self.get_included_member(*include_path)
if related_object:
return related_object.get_attribute(attribute_name)

Expand Down
96 changes: 24 additions & 72 deletions osf/external/gravy_valet/translations.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,10 @@
import dataclasses
import enum
from dataclasses import asdict
from dataclasses import asdict, InitVar
from typing import TYPE_CHECKING

import markupsafe

from addons.bitbucket.apps import BitbucketAddonConfig
from addons.boa.apps import BoaAddonAppConfig
from addons.box.apps import BoxAddonAppConfig
from addons.dataverse.apps import DataverseAddonAppConfig
from addons.dropbox.apps import DropboxAddonAppConfig
from addons.figshare.apps import FigshareAddonAppConfig
from addons.github.apps import GitHubAddonConfig
from addons.gitlab.apps import GitLabAddonConfig
from addons.googledrive.apps import GoogleDriveAddonConfig
from addons.zotero.apps import ZoteroAddonAppConfig
from addons.mendeley.apps import MendeleyAddonConfig
from addons.s3.apps import S3AddonAppConfig
from addons.onedrive.apps import OneDriveAddonAppConfig
from addons.owncloud.apps import OwnCloudAddonAppConfig
from . import request_helpers as gv_requests

if TYPE_CHECKING:
Expand All @@ -29,34 +15,12 @@ class AddonType(enum.StrEnum):
CITATION = enum.auto()
COMPUTING = enum.auto()

class _LegacyConfigsForWBKey(enum.Enum):
"""Mapping from a GV ExternalStorageService's waterbutler key to the legacy Addon config."""

box = BoxAddonAppConfig
bitbucket = BitbucketAddonConfig
dataverse = DataverseAddonAppConfig
dropbox = DropboxAddonAppConfig
figshare = FigshareAddonAppConfig
github = GitHubAddonConfig
gitlab = GitLabAddonConfig
googledrive = GoogleDriveAddonConfig
onedrive = OneDriveAddonAppConfig
owncloud = OwnCloudAddonAppConfig
s3 = S3AddonAppConfig
zotero_org = ZoteroAddonAppConfig
mendeley = MendeleyAddonConfig
boa = BoaAddonAppConfig


def make_ephemeral_user_settings(gv_account_data, requesting_user):
include_path = f'external_{gv_account_data.resource_type.split('-')[1]}_service',
service_wb_key = gv_account_data.get_included_attribute(
include_path=include_path,
attribute_name='wb_key'
)
legacy_config = _LegacyConfigsForWBKey[service_wb_key].value
include_path = f'external_{gv_account_data.resource_type.split('-')[1]}_service'
raw_config = gv_account_data.get_included_member(include_path)
config = EphemeralAddonConfig(raw_config)
return EphemeralUserSettings(
config=EphemeralAddonConfig.from_legacy_config(legacy_config),
config=config,
gv_data=gv_account_data,
active_user=requesting_user,
)
Expand All @@ -65,50 +29,38 @@ def make_ephemeral_user_settings(gv_account_data, requesting_user):
def make_ephemeral_node_settings(gv_addon_data: gv_requests.JSONAPIResultEntry, requested_resource, requesting_user):
addon_type = gv_addon_data.resource_type.split('-')[1]
include_path = ('base_account', f'external_{addon_type}_service')
service_wb_key = gv_addon_data.get_included_attribute(
include_path=include_path,
attribute_name='wb_key'
)
legacy_config = _LegacyConfigsForWBKey[service_wb_key].value
config = EphemeralAddonConfig(gv_addon_data.get_included_member(*include_path))
settings_class = get_settings_class(addon_type)
return settings_class(
config=EphemeralAddonConfig.from_legacy_config(legacy_config),
config=config,
gv_data=gv_addon_data,
user_settings=make_ephemeral_user_settings(gv_addon_data.get_included_member('base_account'), requesting_user),
configured_resource=requested_resource,
active_user=requesting_user,
wb_key=service_wb_key,
wb_key=config.wb_key,
)


@dataclasses.dataclass
class EphemeralAddonConfig:
"""Minimalist dataclass for storing the actually used properties of an AddonConfig"""

name: str
label: str
short_name: str
full_name: str
has_hgrid_files: bool
gv_data: InitVar[gv_requests.JSONAPIResultEntry]
# name: str = dataclasses.field(init=False, default=False)
# label: str = dataclasses.field(init=False, default=False)
short_name: str = dataclasses.field(init=False)
full_name: str = dataclasses.field(init=False)
has_hgrid_files: bool = dataclasses.field(init=False, default=False)
has_widget: bool = dataclasses.field(init=False, default=False)

def __post_init__(self):
if self.short_name in ['zotero', 'mendeley']:
self.has_widget = True

@property
def icon_url(self):
return ''

@classmethod
def from_legacy_config(cls, legacy_config):
return cls(
name=legacy_config.name,
label=legacy_config.label,
full_name=legacy_config.full_name,
short_name=legacy_config.short_name,
has_hgrid_files=legacy_config.has_hgrid_files
)
icon_url: str = dataclasses.field(init=False)
wb_key: str = dataclasses.field(init=False)

def __post_init__(self, gv_data: gv_requests.JSONAPIResultEntry):
self.short_name = gv_data.get_attribute('external_service_name')
self.full_name = gv_data.get_attribute('display_name')
self.has_hgrid_files = gv_data.resource_type == 'external-storage-services'
self.has_widget = gv_data.resource_type == 'external-citation-services'
self.icon_url = gv_data.get_attribute('icon_url')
self.wb_key = gv_data.get_attribute('wb_key')

def to_json(self):
return asdict(self)
Expand Down
1 change: 1 addition & 0 deletions osf_tests/external/gravy_valet/gv_fakes.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ class _FakeAddonProvider(_FakeGVEntity):

def _serialize_attributes(self):
return {
'external_service_name': self.wb_key or self.name,
'display_name': self.name,
'max_upload_mb': self.max_upload_mb,
'max_concurrent_uploads': self.max_concurrent_uploads,
Expand Down
2 changes: 0 additions & 2 deletions osf_tests/test_gv_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,6 @@ def test_make_ephemeral_user_settings(self, contributor, fake_box_account, fake_
ephemeral_config = translations.make_ephemeral_user_settings(account_data, requesting_user=contributor)
assert ephemeral_config.short_name == 'box'
assert ephemeral_config.gv_id == fake_box_account.pk
assert ephemeral_config.config.name == 'addons.box'

def test_make_ephemeral_node_settings(self, contributor, project, fake_box_addon, fake_gv):
with fake_gv.run_fake():
Expand All @@ -547,7 +546,6 @@ def test_make_ephemeral_node_settings(self, contributor, project, fake_box_addon
)
assert ephemeral_config.short_name == 'box'
assert ephemeral_config.gv_id == fake_box_addon.pk
assert ephemeral_config.config.name == 'addons.box'
assert ephemeral_config.serialize_waterbutler_settings() == {
'folder': fake_box_addon.root_folder.split(':')[1],
'service': 'box'
Expand Down
49 changes: 17 additions & 32 deletions website/project/views/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,31 +447,17 @@ def configure_requests(node, **kwargs):
##############################################################################
# View Project
##############################################################################

CITATION_WIDGET_DATA = {
'mendeley': {
'addon_capabilities': '\n\n<h3>Mendeley Add-on Terms</h3>\n\n<table class="table table-bordered table-addon-terms">\n\n <thead>\n <tr>\n ...n allows you to store files using an external service. Files added to this add-on are not stored within the OSF.</li>\n</ul>\n',
'capabilities': True,
'full_name': 'Mendeley',
'has_page': False,
'has_widget': True,
'icon': '/static/addons/mendeley/comicon.png',
'list_id': 'ROOT',
'short_name': 'mendeley'
},
'zotero': {
'addon_capabilities': '\n\n<h3>Zotero Add-on Terms</h3>\n\n<table class="table table-bordered table-addon-terms">\n\n <thead>\n <tr>\n ...n allows you to store files using an external service. Files added to this add-on are not stored within the OSF.</li>\n</ul>\n',
def make_citation_widget_data(addon_name: str):
return {
'addon_capabilities': '',
'capabilities': True,
'full_name': 'Zotero',
'full_name': addon_name.capitalize(),
'has_page': False,
'has_widget': True,
'icon': '/static/addons/zotero/comicon.png',
'library_id': 'personal',
'icon': f'/static/addons/{addon_name}/comicon.png',
'list_id': 'ROOT',
'short_name': 'zotero'
},
}

'short_name': addon_name
}

@process_token_or_pass
@must_be_valid_project(retractions_valid=True)
Expand Down Expand Up @@ -516,18 +502,17 @@ def view_project(auth, node, **kwargs):

if waffle.flag_is_active(request, features.ENABLE_GV):
project = Node.objects.filter(guids___id__in=[kwargs['pid']]).first()
for item in ['zotero', 'mendeley']:
citation_list_urls = get_gv_citation_url_list_for_project(
auth=auth,
pid=kwargs.get('pid'),
addon_short_name=item,
project=project
)
data = CITATION_WIDGET_DATA[item]
data['complete'] = bool(citation_list_urls)
citation_list_urls = get_gv_citation_url_list_for_project(
auth=auth,
pid=kwargs.get('pid'),
project=project
)
for key, value in citation_list_urls.items():
data = make_citation_widget_data(key)
data['complete'] = bool(value)
if data['complete']:
data['list_id'] = citation_list_urls[0]['attributes']['root_folder']
addons_widget_data[item] = data
data['list_id'] = value['attributes']['root_folder']
addons_widget_data[key] = data
else:
if 'zotero' in ret['addons']:
node_addon = node.get_addon('zotero')
Expand Down

0 comments on commit 94004f8

Please sign in to comment.