Skip to content

Commit

Permalink
remove quickfiles from existence
Browse files Browse the repository at this point in the history
  • Loading branch information
John Tordoff committed Feb 1, 2022
1 parent 40d0788 commit ef2e101
Show file tree
Hide file tree
Showing 41 changed files with 75 additions and 766 deletions.
2 changes: 1 addition & 1 deletion README-docker-compose.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@
- Needed for api v2 citation style rendering.
- `docker-compose run --rm web python3 -m scripts.parse_citation_styles`
- Start ember_osf_web
- Needed for quickfiles feature:
- Needed for ember front-end:
- `docker-compose up -d ember_osf_web`
- OPTIONAL: Register OAuth Scopes
- Needed for things such as the ember-osf dummy app
Expand Down
17 changes: 3 additions & 14 deletions addons/base/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
from api.caching.tasks import update_storage_usage_with_size

from addons.base.models import BaseStorageAddon
from addons.osfstorage.models import OsfStorageFile
from addons.osfstorage.models import OsfStorageFileNode
from addons.osfstorage.utils import update_analytics

Expand All @@ -33,7 +32,7 @@
from framework.auth.decorators import collect_auth, must_be_logged_in, must_be_signed
from framework.exceptions import HTTPError
from framework.sentry import log_exception
from framework.routing import json_renderer, proxy_url
from framework.routing import json_renderer
from framework.transactions.handlers import no_auto_transaction
from website import mails
from website import settings
Expand Down Expand Up @@ -403,7 +402,7 @@ def get_auth(auth, **kwargs):

@must_be_signed
@no_auto_transaction
@must_be_valid_project(quickfiles_valid=True, preprints_valid=True)
@must_be_valid_project(preprints_valid=True)
def create_waterbutler_log(payload, **kwargs):
with transaction.atomic():
try:
Expand Down Expand Up @@ -523,7 +522,7 @@ def create_waterbutler_log(payload, **kwargs):
metadata = payload.get('metadata') or payload.get('destination')

target_node = AbstractNode.load(metadata.get('nid'))
if target_node and not target_node.is_quickfiles and payload['action'] != 'download_file':
if target_node and payload['action'] != 'download_file':
update_storage_usage_with_size(payload)

with transaction.atomic():
Expand Down Expand Up @@ -847,16 +846,6 @@ def persistent_file_download(auth, **kwargs):
)


def addon_view_or_download_quickfile(**kwargs):
fid = kwargs.get('fid', 'NOT_AN_FID')
file_ = OsfStorageFile.load(fid)
if not file_:
raise HTTPError(http_status.HTTP_404_NOT_FOUND, data={
'message_short': 'File Not Found',
'message_long': 'The requested file could not be found.'
})
return proxy_url('/project/{}/files/osfstorage/{}/'.format(file_.target._id, fid))

def addon_view_file(auth, node, file_node, version):
# TODO: resolve circular import issue
from addons.wiki import settings as wiki_settings
Expand Down
2 changes: 1 addition & 1 deletion addons/osfstorage/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from framework.auth import cas

from osf import features
from osf.models import Tag, QuickFilesNode
from osf.models import Tag
from osf.models import files as models
from addons.osfstorage.apps import osf_storage_root
from addons.osfstorage import utils
Expand Down
3 changes: 0 additions & 3 deletions addons/osfstorage/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,9 +314,6 @@ def osfstorage_create_child(file_node, payload, **kwargs):
if not (name or user) or '/' in name:
raise HTTPError(http_status.HTTP_400_BAD_REQUEST)

if getattr(file_node.target, 'is_quickfiles', False) and is_folder:
raise HTTPError(http_status.HTTP_400_BAD_REQUEST, data={'message_long': 'You may not create a folder for QuickFiles'})

try:
# Create a save point so that we can rollback and unlock
# the parent record
Expand Down
7 changes: 2 additions & 5 deletions api/caching/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def update_storage_usage_cache(target_id, target_guid, per_page=500000):
def update_storage_usage(target):
Preprint = apps.get_model('osf.preprint')

if settings.ENABLE_STORAGE_USAGE_CACHE and not isinstance(target, Preprint) and not target.is_quickfiles:
if settings.ENABLE_STORAGE_USAGE_CACHE and not isinstance(target, Preprint):
enqueue_postcommit_task(update_storage_usage_cache, (target.id, target._id,), {}, celery=True)

def update_storage_usage_with_size(payload):
Expand All @@ -151,9 +151,6 @@ def update_storage_usage_with_size(payload):
return
target_node = AbstractNode.load(metadata['nid'])

if target_node.is_quickfiles:
return

action = payload['action']
provider = metadata.get('provider', 'osfstorage')

Expand Down Expand Up @@ -182,7 +179,7 @@ def update_storage_usage_with_size(payload):
source_provider = payload['source']['provider']
if target_node == source_node and source_provider == provider:
return # Its not going anywhere.
if source_provider == 'osfstorage' and not source_node.is_quickfiles:
if source_provider == 'osfstorage':
if source_node.storage_limit_status is settings.StorageLimits.NOT_CALCULATED:
return update_storage_usage(source_node)

Expand Down
12 changes: 0 additions & 12 deletions api/files/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,18 +417,6 @@ class FileDetailSerializer(FileSerializer):
id = IDField(source='_id', required=True)


class QuickFilesSerializer(BaseFileSerializer):
user = RelationshipField(
related_view='users:user-detail',
related_view_kwargs={'user_id': '<target.creator._id>'},
help_text='The user who uploaded this file',
)


class QuickFilesDetailSerializer(QuickFilesSerializer):
id = IDField(source='_id', required=True)


class FileVersionSerializer(JSONAPISerializer):
filterable_fields = frozenset([
'id',
Expand Down
15 changes: 4 additions & 11 deletions api/files/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
Guid,
BaseFileNode,
FileVersion,
QuickFilesNode,
)

from api.base.exceptions import Gone
Expand All @@ -27,7 +26,7 @@
from api.files.permissions import CheckedOutOrAdmin
from api.files.permissions import FileMetadataRecordPermission
from api.files.serializers import FileSerializer
from api.files.serializers import FileDetailSerializer, QuickFilesDetailSerializer
from api.files.serializers import FileDetailSerializer
from api.files.serializers import FileMetadataRecordSerializer
from api.files.serializers import FileVersionSerializer
from osf.utils.permissions import ADMIN
Expand All @@ -54,10 +53,6 @@ def get_file(self, check_permissions=True):
if getattr(obj.target, 'deleted', None):
raise Gone(detail='The requested file is no longer available')

if getattr(obj.target, 'is_quickfiles', False) and getattr(obj.target, 'creator'):
if obj.target.creator.is_disabled:
raise Gone(detail='This user has been deactivated and their quickfiles are no longer available.')

if check_permissions:
# May raise a permission denied
self.check_object_permissions(self.request, obj)
Expand Down Expand Up @@ -86,12 +81,10 @@ class FileDetail(JSONAPIBaseView, generics.RetrieveUpdateAPIView, FileMixin):

def get_serializer_class(self):
try:
target = self.get_target()
self.get_target()
except (NotFound, Gone, PermissionDenied):
return FileDetailSerializer
else:
if isinstance(target, QuickFilesNode):
return QuickFilesDetailSerializer
return FileDetailSerializer

def get_target(self):
Expand All @@ -103,8 +96,8 @@ def get_object(self):
file = self.get_file()

if self.request.GET.get('create_guid', False):
# allows quickfiles to be given guids when another user wants a permanent link to it
if (self.get_target().has_permission(user, ADMIN) and utils.has_admin_scope(self.request)) or getattr(file.target, 'is_quickfiles', False):
# allows files to be given guids when another user wants a permanent link to it
if self.get_target().has_permission(user, ADMIN) and utils.has_admin_scope(self.request):
file.get_guid(create=True)
return file

Expand Down
51 changes: 2 additions & 49 deletions api/users/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,19 @@
VersionedDateTimeField,
HideIfDisabled,
IDField,
Link,
LinksField,
TypeField,
RelationshipField,
JSONAPIListField,
WaterbutlerLink,
ShowIfCurrentUser,
)

from api.base.utils import default_node_list_queryset
from osf.models import Registration, Node
from api.base.utils import absolute_reverse, get_user_auth, waterbutler_api_url_for, is_deprecated, hashids
from api.files.serializers import QuickFilesSerializer
from api.base.utils import absolute_reverse, get_user_auth, is_deprecated, hashids
from osf.models import Email
from osf.exceptions import ValidationValueError, ValidationError, BlockedEmailError
from osf.models import OSFUser, QuickFilesNode, Preprint, AbstractNode
from osf.models import OSFUser, Preprint
from osf.utils.requests import string_type_request_headers
from website.settings import MAILCHIMP_GENERAL_LIST, OSF_HELP_LIST, CONFIRM_REGISTRATIONS_BY_EMAIL
from osf.models.provider import AbstractProviderGroupObjectPermission
Expand All @@ -39,31 +36,6 @@
from api.base.versioning import get_kebab_snake_case_field


class QuickFilesRelationshipField(RelationshipField):

def to_representation(self, value):
relationship_links = super().to_representation(value)
try:
quickfiles_guid = value.nodes_created.get(
type=QuickFilesNode._typedmodels_type,
).values_list(
'guids___id', flat=True
).get()
except AbstractNode.DoesNotExist:
return relationship_links

upload_url = waterbutler_api_url_for(quickfiles_guid, 'osfstorage')
relationship_links['links']['upload'] = {
'href': upload_url,
'meta': {},
}
relationship_links['links']['download'] = {
'href': '{}?zip='.format(upload_url),
'meta': {},
}
return relationship_links


class SocialField(ser.DictField):
def __init__(self, min_version, **kwargs):
super(SocialField, self).__init__(**kwargs)
Expand Down Expand Up @@ -139,12 +111,6 @@ class UserSerializer(JSONAPISerializer):
related_view_kwargs={'user_id': '<_id>'},
))

quickfiles = HideIfDisabled(QuickFilesRelationshipField(
related_view='users:user-quickfiles',
related_view_kwargs={'user_id': '<_id>'},
related_meta={'count': 'get_quickfiles_count'},
))

registrations = HideIfDisabled(RelationshipField(
related_view='users:user-registrations',
related_view_kwargs={'user_id': '<_id>'},
Expand Down Expand Up @@ -211,9 +177,6 @@ def get_node_count(self, obj):
return Node.objects.get_nodes_for_user(auth.user, base_queryset=default_queryset, include_public=True).count()
return default_queryset.count()

def get_quickfiles_count(self, obj):
return QuickFilesNode.objects.get(contributor__user__id=obj.id).files.filter(type='osf.osfstoragefile').count()

def get_registration_count(self, obj):
auth = get_user_auth(self.context['request'])
user_registration = default_node_list_queryset(model_cls=Registration).filter(contributor__user__id=obj.id)
Expand Down Expand Up @@ -346,16 +309,6 @@ class UserDetailSerializer(UserSerializer):
id = IDField(source='_id', required=True)


class UserQuickFilesSerializer(QuickFilesSerializer):
links = LinksField({
'info': Link('files:file-detail', kwargs={'file_id': '<_id>'}),
'upload': WaterbutlerLink(),
'delete': WaterbutlerLink(),
'move': WaterbutlerLink(),
'download': WaterbutlerLink(must_be_file=True),
})


class ReadEmailUserDetailSerializer(UserDetailSerializer):

email = ser.CharField(source='username', read_only=True)
Expand Down
1 change: 0 additions & 1 deletion api/users/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
url(r'^(?P<user_id>\w+)/preprints/$', views.UserPreprints.as_view(), name=views.UserPreprints.view_name),
url(r'^(?P<user_id>\w+)/registrations/$', views.UserRegistrations.as_view(), name=views.UserRegistrations.view_name),
url(r'^(?P<user_id>\w+)/settings/$', views.UserSettings.as_view(), name=views.UserSettings.view_name),
url(r'^(?P<user_id>\w+)/quickfiles/$', views.UserQuickFiles.as_view(), name=views.UserQuickFiles.view_name),
url(r'^(?P<user_id>\w+)/relationships/institutions/$', views.UserInstitutionsRelationship.as_view(), name=views.UserInstitutionsRelationship.view_name),
url(r'^(?P<user_id>\w+)/settings/emails/$', views.UserEmailsList.as_view(), name=views.UserEmailsList.view_name),
url(r'^(?P<user_id>\w+)/settings/emails/(?P<email_id>\w+)/$', views.UserEmailsDetail.as_view(), name=views.UserEmailsDetail.view_name),
Expand Down
45 changes: 2 additions & 43 deletions api/users/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
hashids,
is_truthy,
)
from api.base.views import JSONAPIBaseView, WaterButlerMixin
from api.base.views import JSONAPIBaseView
from api.base.throttling import SendEmailThrottle, SendEmailDeactivationThrottle, NonCookieAuthThrottle, BurstRateThrottle
from api.institutions.serializers import InstitutionSerializer
from api.nodes.filters import NodesFilterMixin, UserNodesFilterMixin
Expand All @@ -51,7 +51,6 @@
UserNodeSerializer,
UserSettingsSerializer,
UserSettingsUpdateSerializer,
UserQuickFilesSerializer,
UserAccountExportSerializer,
ReadEmailUserDetailSerializer,
UserChangePasswordSerializer,
Expand All @@ -71,12 +70,11 @@
from rest_framework import generics
from rest_framework import status
from rest_framework.response import Response
from rest_framework.exceptions import NotAuthenticated, NotFound, ValidationError, Throttled, PermissionDenied
from rest_framework.exceptions import NotAuthenticated, NotFound, ValidationError, Throttled
from osf.models import (
Contributor,
ExternalAccount,
Guid,
QuickFilesNode,
AbstractNode,
Preprint,
Node,
Expand Down Expand Up @@ -363,45 +361,6 @@ def get_queryset(self):
return self.get_queryset_from_request()


class UserQuickFiles(JSONAPIBaseView, generics.ListAPIView, WaterButlerMixin, UserMixin, ListFilterMixin):

permission_classes = (
drf_permissions.IsAuthenticatedOrReadOnly,
base_permissions.TokenHasScope,
)

ordering = ('-last_touched')

required_read_scopes = [CoreScopes.USERS_READ]
required_write_scopes = [CoreScopes.USERS_WRITE]

serializer_class = UserQuickFilesSerializer
view_category = 'users'
view_name = 'user-quickfiles'

def get_node(self, check_object_permissions):
user = self.get_user()
node = QuickFilesNode.objects.get_for_user(user)
if not node:
raise NotFound()

if not node.is_public or node.deleted:
raise PermissionDenied()

return node

def get_default_queryset(self):
self.kwargs[self.path_lookup_url_kwarg] = '/'
self.kwargs[self.provider_lookup_url_kwarg] = 'osfstorage'
files_list = self.fetch_from_waterbutler()

return files_list.children.prefetch_related('versions', 'tags').include('guids')

# overrides ListAPIView
def get_queryset(self):
return self.get_queryset_from_request()


class UserPreprints(JSONAPIBaseView, generics.ListAPIView, UserMixin, PreprintFilterMixin):
"""The documentation for this endpoint can be found [here](https://developer.osf.io/#operation/users_preprints_list).
"""
Expand Down
6 changes: 1 addition & 5 deletions api_tests/files/views/test_file_detail.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from api.base.settings.defaults import API_BASE
from api_tests import utils as api_utils
from framework.auth.core import Auth
from osf.models import NodeLog, Session, QuickFilesNode
from osf.models import NodeLog, Session
from osf.utils.permissions import WRITE, READ
from osf.utils.workflows import DefaultStates
from osf_tests.factories import (
Expand Down Expand Up @@ -48,10 +48,6 @@ class TestFileView:
def node(self, user):
return ProjectFactory(creator=user, comment_level='public')

@pytest.fixture()
def quickfiles_node(self, user):
return QuickFilesNode.objects.get(creator=user)

@pytest.fixture()
def file(self, user, node):
return api_utils.create_test_file(node, user, create_guid=False)
Expand Down
Loading

0 comments on commit ef2e101

Please sign in to comment.