-
Notifications
You must be signed in to change notification settings - Fork 358
[ENG-10283] added ability to add/remove files of an archived registration under osf storage #11674
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
2e5fda0
4b51e36
910231d
caf7b21
60b11cd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,6 +23,7 @@ | |
| from admin.base.views import GuidView | ||
| from admin.nodes.forms import AddSystemTagForm, RegistrationDateForm | ||
| from admin.notifications.views import delete_selected_notifications | ||
| from addons.osfstorage.models import OsfStorageFolder | ||
| from api.caching.tasks import update_storage_usage_cache | ||
| from api.share.utils import update_share | ||
| from framework import status | ||
|
|
@@ -846,6 +847,59 @@ def _remove_file_from_schema_response_blocks(registration, removed_file_id): | |
| return redirect(self.get_success_url()) | ||
|
|
||
|
|
||
| class NodeAddOsfStorageFileView(NodeMixin, View): | ||
| """ Allows an authorized user to add a file to osfstorage of an archived node. | ||
| """ | ||
| permission_required = 'osf.change_node' | ||
|
|
||
| def post(self, request, *args, **kwargs): | ||
| registration = self.get_object() | ||
| guid_id = request.POST.get('file-guid', '').strip() | ||
| guid = Guid.load(guid_id) | ||
| if not guid: | ||
| messages.error(request, 'No file found with the provided guid.') | ||
| return redirect(self.get_success_url()) | ||
|
|
||
| file = guid.referent | ||
| parent_node = registration.registered_from | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nitpick: move this line after the file check |
||
| if not parent_node: | ||
| messages.error(request, 'The registration does not have the parent node.') | ||
| return redirect(self.get_success_url()) | ||
|
|
||
| if not parent_node.files.filter(id=file.id).exists(): | ||
| messages.error(request, 'The file with the provided guid is not part of the parent node.') | ||
| return redirect(self.get_success_url()) | ||
|
|
||
| osfstorage = registration.get_addon('osfstorage') | ||
| # copy file to Archive of OSF Storage folder | ||
| archive_folder = OsfStorageFolder.objects.filter( | ||
| parent=osfstorage.get_root(), | ||
| name=osfstorage.archive_folder_name | ||
| ).first() | ||
| file.copy_under(archive_folder) | ||
| messages.success(request, 'The file was successfully added.') | ||
| return redirect(self.get_success_url()) | ||
|
|
||
|
|
||
| class NodeRemoveOsfStorageFileView(NodeMixin, View): | ||
| """ Allows an authorized user to remove a file from osfstorage of an archived node. | ||
| """ | ||
| permission_required = 'osf.change_node' | ||
|
|
||
| def post(self, request, *args, **kwargs): | ||
| registration = self.get_object() | ||
| guid_id = request.POST.get('file-guid', '').strip() | ||
| guid = Guid.load(guid_id) | ||
| if not guid: | ||
| messages.error(request, 'No file found with the provided guid.') | ||
| return redirect(self.get_success_url()) | ||
|
|
||
| file = guid.referent | ||
|
felliott marked this conversation as resolved.
|
||
| registration.files.filter(id=file.id).delete() | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if the file exists, but not under the registration?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If I got it correctly, then nothing will happen as we query files of a specific registration, which means file won't be found. We should delete a file only if it's attached to a registration, not project (because in the project user can manually delete a file unlike in the archived registration, this is the purpose of this PR to add such a functionality for product team)
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. d'oh! You're absolutely right, sorry for the noise.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Resolved too soon. My first message was poorly worded. I meant that if the file isn't under the registration, shouldn't this return an error message? I know it won't delete the file, but I would expect it to complain instead of saying |
||
| messages.success(request, 'The file was successfully removed.') | ||
| return redirect(self.get_success_url()) | ||
|
|
||
|
|
||
| class RemoveStuckRegistrationsView(NodeMixin, View): | ||
| """ Allows an authorized user to remove a registrations if it's stuck in the archiving process. | ||
| """ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| {% if node.is_registration and node.archived %} | ||
| <a data-toggle="modal" data-target="#confirmAddFileModal" class="btn btn-primary"> | ||
| Add File (Osfstorage) | ||
| </a> | ||
| <div id="confirmAddFileModal" class="modal fade well" tabindex="-1" role="dialog"> | ||
| <div class="modal-dialog" role="document"> | ||
| <div class="modal-content"> | ||
| <form class="well" method="post" action="{% url 'nodes:add-osfstorage-file' guid=node.guid %}"> | ||
| <div class="modal-header"> | ||
| <button type="button" class="close" data-dismiss="modal">x</button> | ||
| <h3>Enter file to add</h3> | ||
| </div> | ||
| {% csrf_token %} | ||
|
|
||
| <div class="modal-body"> | ||
| <div style="display:flex; align-items:center; gap:12px;"> | ||
| <label for="file-guid" style="margin:0; white-space:nowrap;">File guid:</label> | ||
| <input id="file-guid" | ||
| type="text" | ||
| name="file-guid" | ||
| class="form-control" | ||
| required | ||
| style="flex:1; min-width:0;"> | ||
| </div> | ||
| </div> | ||
| <div class="modal-footer"> | ||
| <button class="btn btn-danger" name="action" value="ham" type="submit">Confirm</button> | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nitpick: |
||
| <button type="button" class="btn btn-default" data-dismiss="modal"> | ||
| Cancel | ||
| </button> | ||
| </div> | ||
| </form> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| {% endif %} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,7 +17,6 @@ | |
| <a href="{% url 'nodes:search' %}" class="btn btn-primary"> <i class="fa fa-search"></i></a> | ||
| <a href="{% url 'nodes:node-logs' guid=node.guid %}" class="btn btn-primary">View Logs</a> | ||
| {% include "nodes/remove_node.html" with node=node %} | ||
| {% include "nodes/remove_file.html" with node=node %} | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nitpick: Can we delete this file? Is it used anywhere else?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe I removed it accidentally because supposed I had to override this file removal workflow |
||
| {% include "nodes/registration_force_archive.html" with node=node %} | ||
| {% include "nodes/make_private.html" with node=node %} | ||
| {% include "nodes/make_public.html" with node=node %} | ||
|
|
@@ -29,6 +28,13 @@ | |
| </div> | ||
| </div> | ||
| </div> | ||
| <div class="row"> | ||
| <br> | ||
| <div class="col-md-12"> | ||
| {% include "nodes/add_file_to_osfstorage.html" with node=node %} | ||
| {% include "nodes/remove_file_from_osfstorage.html" with node=node %} | ||
| </div> | ||
| </div> | ||
| <div class="row" style="overflow-x: auto; width: 100%;"> | ||
| <h2>{{ node.type|cut:'osf.'|title }}: <b>{{ node.title }}</b> <a href="{{ node.absolute_url }}"> ({{node.guid}})</a> </h2> | ||
| <table class="table table-striped"> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| {% if node.is_registration and node.archived %} | ||
| <a data-toggle="modal" data-target="#confirmRemoveFileModal" class="btn btn-danger"> | ||
| Remove File (Osfstorage) | ||
| </a> | ||
| <div id="confirmRemoveFileModal" class="modal fade well" tabindex="-1" role="dialog"> | ||
| <div class="modal-dialog" role="document"> | ||
| <div class="modal-content"> | ||
| <form class="well" method="post" action="{% url 'nodes:remove-osfstorage-file' guid=node.guid %}"> | ||
| <div class="modal-header"> | ||
| <button type="button" class="close" data-dismiss="modal">x</button> | ||
| <h3>Enter file to remove</h3> | ||
| </div> | ||
| {% csrf_token %} | ||
|
|
||
| <div class="modal-body"> | ||
| <div style="display:flex; align-items:center; gap:12px;"> | ||
| <label for="file-guid" style="margin:0; white-space:nowrap;">File guid:</label> | ||
| <input id="file-guid" | ||
| type="text" | ||
| name="file-guid" | ||
| class="form-control" | ||
| required | ||
| style="flex:1; min-width:0;"> | ||
| </div> | ||
| </div> | ||
| <div class="modal-footer"> | ||
| <button class="btn btn-danger" name="action" value="ham" type="submit">Confirm</button> | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nitpick: |
||
| <button type="button" class="btn btn-default" data-dismiss="modal"> | ||
| Cancel | ||
| </button> | ||
| </div> | ||
| </form> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| {% endif %} | ||
Uh oh!
There was an error while loading. Please reload this page.