Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
 into feature/node_settings_apiV2
  • Loading branch information
pattisdr committed Jul 19, 2018
2 parents bee8d6a + c189c85 commit 6b9cb9c
Show file tree
Hide file tree
Showing 176 changed files with 3,787 additions and 777 deletions.
10 changes: 5 additions & 5 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[run]
include =
api/*
framework/*
scripts/*
website/*
omit =
*tests/*
*/migrations/*
*/settings/*
*/templates/*
*/wsgi.py

[report]
exclude_lines =
raise NotImplementedError
6 changes: 5 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,11 @@ install:

# Run Python tests (core and addon) and JS tests
script:
- invoke test_travis_$TEST_BUILD -n 4
- export COVERAGE=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "--coverage"; else echo ""; fi`
- invoke test_travis_$TEST_BUILD -n 4 $COVERAGE

after_success:
- if [[ "$TRAVIS_BRANCH" == "master" ]]; then coveralls; fi

before_cache:
- rm -Rf $HOME/.cache/pip/http
Expand Down
24 changes: 24 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,30 @@
Changelog
*********

0.148.0 (2018-07-18)
====================
- Create RegistrationProvider model
- Create PreprintWithdrawalRequest model
- Add collections logos to project overview
- Return None relationships for withdrawn preprints
- Fix "Other" Subject ordering
- Replace OSF-internal usage of preprint assets with ProviderAssetFiles
- Fix preprint download permissions checking
- Fix collectionSubmission ES mapping

0.147.0 (2018-07-11)
====================
- Add choices for ProviderAssetFileNames
- Add Comments to Reviews email
- Add ProviderAssetFile API endpoints, AbstractProvider relationship
- Admin View for creating/managing CollectionProviders
- Admin view for preprint spam removal
- Make v2/search accept POST for getting raw data
- Fix: Add provider to ES collectionSubmission documents
- Fix: CSS for banners created in OSF Admin
- Fix: Update preprint citation to use OSF Preprints
- Fix: Prevent ConcurrentObjectUseError with ProviderAssetFiles

0.146.0 (2018-07-02)
====================

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

The code for [https://osf.io](https://osf.io).

[![Coverage Status](https://coveralls.io/repos/github/CenterForOpenScience/osf.io/badge.svg)](https://coveralls.io/github/CenterForOpenScience/osf.io)

- `master` Build Status: [![Build Status](https://travis-ci.org/CenterForOpenScience/osf.io.svg?branch=master)](https://travis-ci.org/CenterForOpenScience/osf.io)
- `develop` Build Status: [![Build Status](https://travis-ci.org/CenterForOpenScience/osf.io.svg?branch=develop)](https://travis-ci.org/CenterForOpenScience/osf.io)
- Public Repo: https://github.com/CenterForOpenScience/osf.io/
Expand Down
6 changes: 3 additions & 3 deletions addons/base/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,16 +178,16 @@ def check_access(node, auth, action, cas_resp):

# Users attempting to register projects with components might not have
# `write` permissions for all components. This will result in a 403 for
# all `copyto` actions as well as `copyfrom` actions if the component
# all `upload` actions as well as `copyfrom` actions if the component
# in question is not public. To get around this, we have to recursively
# check the node's parent node to determine if they have `write`
# permissions up the stack.
# TODO(hrybacki): is there a way to tell if this is for a registration?
# All nodes being registered that receive the `copyto` action will have
# All nodes being registered that receive the `upload` action will have
# `node.is_registration` == True. However, we have no way of telling if
# `copyfrom` actions are originating from a node being registered.
# TODO This is raise UNAUTHORIZED for registrations that have not been archived yet
if action == 'copyfrom' or (action == 'copyto' and node.is_registration):
if action == 'copyfrom' or (action == 'upload' and node.is_registration):
parent = node.parent_node
while parent:
if parent.can_edit(auth):
Expand Down
11 changes: 10 additions & 1 deletion admin/asset_files/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@
class ProviderAssetFileForm(forms.ModelForm):
class Meta:
model = ProviderAssetFile
fields = ['name', 'file', 'providers']
fields = ['name', 'file', 'providers', 'id']

id = forms.IntegerField(required=False, widget=forms.HiddenInput())
providers = forms.ModelMultipleChoiceField(AbstractProvider.objects.all(), widget=forms.CheckboxSelectMultiple(), required=False)

def clean(self):
cleaned_data = super(ProviderAssetFileForm, self).clean()
obj_id = int(cleaned_data.get('id', None) or 0)
for provider in cleaned_data.get('providers', []):
if provider.asset_files.exclude(id=obj_id).filter(name=cleaned_data.get('name', '')).exists():
raise forms.ValidationError('Naming conflict detected on Provider "{}"'.format(provider.name))
return cleaned_data
20 changes: 10 additions & 10 deletions admin/asset_files/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@

class ProviderAssetFileList(PermissionRequiredMixin, ListView):
paginate_by = 25
template_name = 'asset_files/list.html'
template_name = 'osf/providerassetfile_list.html'
ordering = 'name'
permission_required = 'osf.view_asset_files'
permission_required = 'osf.view_providerassetfile'
raise_exception = True
model = ProviderAssetFile

Expand Down Expand Up @@ -47,8 +47,8 @@ def get_object(self, queryset=None):
return ProviderAssetFile.objects.get(id=self.kwargs.get('asset_id'))

class ProviderAssetFileDisplay(AssetFileMixin, PermissionRequiredMixin, DetailView):
permission_required = 'osf.view_asset_files'
template_name = 'asset_files/detail.html'
permission_required = 'osf.view_providerassetfile'
template_name = 'osf/providerassetfile_form.html'
form_class = ProviderAssetFileForm
raise_exception = True
model = ProviderAssetFile
Expand All @@ -61,7 +61,7 @@ def get_context_data(self, **kwargs):
return kwargs

class ProviderAssetFileChangeForm(AssetFileMixin, PermissionRequiredMixin, UpdateView):
permission_required = 'osf.change_asset_files'
permission_required = 'osf.change_providerassetfile'
raise_exception = True
model = ProviderAssetFile
form_class = ProviderAssetFileForm
Expand All @@ -70,14 +70,14 @@ def get_success_url(self, *args, **kwargs):
return reverse_lazy('asset_files:detail', kwargs={'asset_id': self.kwargs.get('asset_id')})

class ProviderAssetFileDelete(AssetFileMixin, PermissionRequiredMixin, DeleteView):
permission_required = 'osf.delete_asset_files'
permission_required = 'osf.delete_providerassetfile'
raise_exception = True
template_name = 'asset_files/confirm_delete.html'
template_name = 'osf/providerassetfile_confirm_delete.html'
success_url = reverse_lazy('asset_files:list')


class ProviderAssetFileDetail(PermissionRequiredMixin, View):
permission_required = 'osf.view_asset_files'
permission_required = 'osf.view_providerassetfile'
raise_exception = True
form_class = ProviderAssetFileForm

Expand All @@ -90,9 +90,9 @@ def post(self, request, *args, **kwargs):
return view(request, *args, **kwargs)

class ProviderAssetFileCreate(PermissionRequiredMixin, CreateView):
permission_required = 'osf.change_asset_files'
permission_required = 'osf.change_providerassetfile'
raise_exception = True
template_name = 'asset_files/create.html'
template_name = 'osf/providerassetfile_create.html'
success_url = reverse_lazy('asset_files:list')
model = ProviderAssetFile
form_class = ProviderAssetFileForm
1 change: 1 addition & 0 deletions admin/base/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
url(r'^spam/', include('admin.spam.urls', namespace='spam')),
url(r'^institutions/', include('admin.institutions.urls', namespace='institutions')),
url(r'^preprint_providers/', include('admin.preprint_providers.urls', namespace='preprint_providers')),
url(r'^collection_providers/', include('admin.collection_providers.urls', namespace='collection_providers')),
url(r'^account/', include('admin.common_auth.urls', namespace='auth')),
url(r'^password/', include('password_reset.urls')),
url(r'^nodes/', include('admin.nodes.urls', namespace='nodes')),
Expand Down
Empty file.
89 changes: 89 additions & 0 deletions admin/collection_providers/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import bleach
import json

from django import forms

from osf.models import CollectionProvider, CollectedGuidMetadata
from admin.base.utils import get_nodelicense_choices


class CollectionProviderForm(forms.ModelForm):
licenses_acceptable = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, required=False, choices=get_nodelicense_choices())
collected_type_choices = forms.CharField(widget=forms.HiddenInput, required=False)
status_choices = forms.CharField(widget=forms.HiddenInput, required=False)

class Meta:
model = CollectionProvider
exclude = ['primary_identifier_name', 'primary_collection', 'type', 'allow_commenting', 'advisory_board',
'example', 'domain', 'domain_redirect_enabled', 'reviews_comments_anonymous',
'reviews_comments_private', 'reviews_workflow']

def clean_description(self, *args, **kwargs):
if not self.data.get('description'):
return u''
return bleach.clean(
self.data.get('description'),
tags=['a', 'br', 'em', 'p', 'span', 'strong'],
attributes=['class', 'style', 'href', 'title', 'target'],
styles=['text-align', 'vertical-align'],
strip=True
)

def clean_footer_links(self, *args, **kwargs):
if not self.data.get('footer_links'):
return u''
return bleach.clean(
self.data.get('footer_links'),
tags=['a', 'br', 'div', 'em', 'p', 'span', 'strong'],
attributes=['class', 'style', 'href', 'title', 'target'],
styles=['text-align', 'vertical-align'],
strip=True
)

def clean_collected_type_choices(self):
collection_provider = self.instance
# if this is to modify an existing CollectionProvider
if collection_provider.primary_collection:
type_choices_old = set(collection_provider.primary_collection.collected_type_choices)
type_choices_new = set(json.loads(self.data.get('collected_type_choices')))
type_choices_added = type_choices_new - type_choices_old
type_choices_removed = type_choices_old - type_choices_new
for item in type_choices_removed:
if CollectedGuidMetadata.objects.filter(collection=collection_provider.primary_collection,
collected_type=item).exists():
raise forms.ValidationError(
'Cannot delete "{}" because it is used as metadata on objects.'.format(item)
)
else:
# if this is creating a CollectionProvider
type_choices_added = json.loads(self.data.get('collected_type_choices'))
type_choices_removed = []

return {
'added': type_choices_added,
'removed': type_choices_removed,
}

def clean_status_choices(self):
collection_provider = self.instance
# if this is to modify an existing CollectionProvider
if collection_provider.primary_collection:
status_choices_old = set(collection_provider.primary_collection.status_choices)
status_choices_new = set(json.loads(self.data.get('status_choices')))
status_choices_added = status_choices_new - status_choices_old
status_choices_removed = status_choices_old - status_choices_new
for item in status_choices_removed:
if CollectedGuidMetadata.objects.filter(collection=collection_provider.primary_collection,
status=item).exists():
raise forms.ValidationError(
'Cannot delete "{}" because it is used as metadata on objects.'.format(item)
)
else:
# if this is creating a CollectionProvider
status_choices_added = json.loads(self.data.get('status_choices'))
status_choices_removed = []

return {
'added': status_choices_added,
'removed': status_choices_removed,
}
14 changes: 14 additions & 0 deletions admin/collection_providers/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from django.conf.urls import url
from . import views

app_name = 'admin'

urlpatterns = [
url(r'^create/$', views.CreateCollectionProvider.as_view(), name='create'),
url(r'^$', views.CollectionProviderList.as_view(), name='list'),
url(r'^import/$', views.ImportCollectionProvider.as_view(), name='import'),
url(r'^(?P<collection_provider_id>[a-z0-9]+)/$', views.CollectionProviderDetail.as_view(), name='detail'),
url(r'^(?P<collection_provider_id>[a-z0-9]+)/delete/$', views.DeleteCollectionProvider.as_view(), name='delete'),
url(r'^(?P<collection_provider_id>[a-z0-9]+)/export/$', views.ExportColectionProvider.as_view(), name='export'),
url(r'^(?P<collection_provider_id>[a-z0-9]+)/import/$', views.ImportCollectionProvider.as_view(), name='import'),
]
Loading

0 comments on commit 6b9cb9c

Please sign in to comment.