Skip to content

Commit

Permalink
Merge branch 'feature/django_upgrade' of https://github.com/CenterFor…
Browse files Browse the repository at this point in the history
…OpenScience/osf.io into upgrade-markdown

* 'feature/django_upgrade' of https://github.com/CenterForOpenScience/osf.io:
  [ENG-3836] Follow-up: Add PyYAML to Requirements (CenterForOpenScience#9993)
  [ENG-3867] Create Storage Regions on post migration signal (CenterForOpenScience#9965)
  [ENG-3866] Move citation style population out of migration stream (CenterForOpenScience#9966)
  [ENG-3868] Move blocked email domains to post-migrate signal (CenterForOpenScience#9958)
  [ENG-3863] Move schema ensuring and schema blocks update to post-migrate signals (CenterForOpenScience#9974)
  [ENG-3865] Create Licenses using post-migrate signal (CenterForOpenScience#9961)
  [ENG-3836] Investigate waffle flags (CenterForOpenScience#9950)
  move createcachetable to post migrate signal (CenterForOpenScience#9944)
  remove post-migrate signals from migration stream (CenterForOpenScience#9964)
  [ENG-3898][ENG-3899]Model support for OutcomeArtifact update and delete (CenterForOpenScience#9989)
  Make OutcomeArtifact.identifier nullable (CenterForOpenScience#9986)
  [ENG-3894] Outcome models (CenterForOpenScience#9975)
  revert color picker to working version (CenterForOpenScience#9968)
  • Loading branch information
John Tordoff committed Jul 28, 2022
2 parents 9c110bb + 8052ea4 commit d00e268
Show file tree
Hide file tree
Showing 16 changed files with 1,675 additions and 306 deletions.
2 changes: 1 addition & 1 deletion admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"dependencies": {
"babel-core": "^6.0.0",
"babel-loader": "^6.4.1",
"bootstrap-colorpicker": "^3.4.0",
"bootstrap-colorpicker": "^2.5.2",
"bootstrap-tagsinput": "^0.7.1",
"bower": "^1.3.12",
"font-awesome": "^4.5.0",
Expand Down
1,169 changes: 873 additions & 296 deletions admin/yarn.lock

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions osf/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,21 @@ def __init__(self, response, invalid_responses=None, unsupported_keys=None):
)

super().__init__(error_message)


class IdentifierHasReferencesError(OSFError):
pass


class NoPIDError(OSFError):
pass


class CannotFinalizeArtifactError(OSFError):

def __init__(self, artifact, incomplete_fields):
self.incomplete_fields = incomplete_fields
self.message = (
f'Could not set `finalized=True` for OutcomeArtifact with id [{artifact._id}]. '
f'The following required fields are not set: {incomplete_fields}'
)
83 changes: 83 additions & 0 deletions osf/migrations/0246_add_outcomes_and_artifacts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.29 on 2022-07-14 18:50
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion
import django_extensions.db.fields
import osf.models.base
import osf.models.validators
import osf.utils.outcomes


class Migration(migrations.Migration):

dependencies = [
('osf', '0245_auto_20220621_1950'),
]

operations = [
migrations.CreateModel(
name='Outcome',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', django_extensions.db.fields.CreationDateTimeField(auto_now_add=True, verbose_name='created')),
('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')),
('_id', models.CharField(db_index=True, default=osf.models.base.generate_object_id, max_length=24, unique=True)),
('title', models.TextField(validators=[osf.models.validators.validate_title])),
('description', models.TextField(blank=True, default='')),
('category', models.CharField(blank=True, choices=[('analysis', 'Analysis'), ('communication', 'Communication'), ('data', 'Data'), ('hypothesis', 'Hypothesis'), ('instrumentation', 'Instrumentation'), ('methods and measures', 'Methods and Measures'), ('procedure', 'Procedure'), ('project', 'Project'), ('software', 'Software'), ('other', 'Other'), ('', 'Uncategorized')], default='', max_length=255)),
('affiliated_institutions', models.ManyToManyField(related_name='outcomes', to='osf.Institution')),
],
options={
'abstract': False,
},
bases=(models.Model, osf.models.base.QuerySetExplainMixin),
),
migrations.CreateModel(
name='OutcomeArtifact',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', django_extensions.db.fields.CreationDateTimeField(auto_now_add=True, verbose_name='created')),
('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')),
('_id', models.CharField(db_index=True, default=osf.models.base.generate_object_id, max_length=24, unique=True)),
('artifact_type', models.IntegerField(choices=[(0, 'UNDEFINED'), (1, 'DATA'), (11, 'CODE'), (21, 'MATERIALS'), (31, 'PAPERS'), (41, 'SUPPLEMENTS'), (1001, 'PRIMARY')], default=osf.utils.outcomes.ArtifactTypes(0))),
('title', models.TextField()),
('description', models.TextField()),
('identifier', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='artifact_metadata', to='osf.Identifier')),
('outcome', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='artifact_metadata', to='osf.Outcome')),
],
options={
'ordering': ['artifact_type', 'title'],
},
bases=(models.Model, osf.models.base.QuerySetExplainMixin),
),
migrations.AddField(
model_name='outcome',
name='artifacts',
field=models.ManyToManyField(through='osf.OutcomeArtifact', to='osf.Identifier'),
),
migrations.AddField(
model_name='outcome',
name='node_license',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='outcomes', to='osf.NodeLicenseRecord'),
),
migrations.AddField(
model_name='outcome',
name='subjects',
field=models.ManyToManyField(blank=True, related_name='outcomes', to='osf.Subject'),
),
migrations.AddField(
model_name='outcome',
name='tags',
field=models.ManyToManyField(related_name='outcome_tagged', to='osf.Tag'),
),
migrations.AddIndex(
model_name='outcomeartifact',
index=models.Index(fields=['outcome', 'artifact_type'], name='osf_outcome_outcome_a62f5c_idx'),
),
migrations.AlterUniqueTogether(
name='outcomeartifact',
unique_together=set([('outcome', 'identifier', 'artifact_type')]),
),
]
41 changes: 41 additions & 0 deletions osf/migrations/0247_artifact_finalized_and_deleted.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.29 on 2022-07-25 15:39
from __future__ import unicode_literals

from django.db import migrations, models
import osf.utils.fields


class Migration(migrations.Migration):

dependencies = [
('osf', '0246_add_outcomes_and_artifacts'),
]

operations = [
migrations.AddField(
model_name='outcomeartifact',
name='deleted',
field=osf.utils.fields.NonNaiveDateTimeField(blank=True, null=True),
),
migrations.AddField(
model_name='outcomeartifact',
name='finalized',
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name='outcomeartifact',
name='description',
field=models.TextField(blank=True),
),
migrations.AlterField(
model_name='outcomeartifact',
name='title',
field=models.TextField(blank=True),
),
migrations.AlterField(
model_name='outcomeartifact',
name='artifact_type',
field=models.IntegerField(choices=[(0, 'UNDEFINED'), (1, 'DATA'), (11, 'ANALYTIC_CODE'), (21, 'MATERIALS'), (31, 'PAPERS'), (41, 'SUPPLEMENTS'), (1001, 'PRIMARY')], default=osf.utils.outcomes.ArtifactTypes(0)),
),
]
2 changes: 2 additions & 0 deletions osf/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,5 @@
from osf.models.schema_response_block import SchemaResponseBlock # noqa
from osf.models.registration_bulk_upload_job import RegistrationBulkUploadJob # noqa
from osf.models.registration_bulk_upload_row import RegistrationBulkUploadRow # noqa
from osf.models.outcomes import Outcome # noqa
from osf.models.outcome_artifacts import OutcomeArtifact # noqa
8 changes: 8 additions & 0 deletions osf/models/identifiers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.utils import timezone

from osf.exceptions import IdentifierHasReferencesError
from osf.models.base import BaseModel, ObjectIDMixin
from osf.utils.fields import NonNaiveDateTimeField

Expand All @@ -28,6 +30,12 @@ def remove(self, save=True):
if save:
self.save()

def delete(self):
'''Used to delete an orphaned Identifier (distinct from setting `deleted`)'''
if self.object_id or self.artifact_metadata.filter(deleted__isnull=True).exists():
raise IdentifierHasReferencesError
super().delete()


class IdentifierMixin(models.Model):
"""Model mixin that adds methods for getting and setting Identifier objects
Expand Down
13 changes: 7 additions & 6 deletions osf/models/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -2247,7 +2247,7 @@ def stage_m2m_values(self, fieldname, resource, alternative_resource=None):
else:
return []

def copy_editable_fields(self, resource, auth=None, alternative_resource=None, save=True):
def copy_editable_fields(self, resource, auth=None, alternative_resource=None, include_contributors=True, save=True):
"""
Copy various editable fields from the 'resource' object to the current object.
Includes, title, description, category, contributors, node_license, tags, subjects, and affiliated_institutions
Expand All @@ -2261,11 +2261,12 @@ def copy_editable_fields(self, resource, auth=None, alternative_resource=None, s
self.set_editable_attribute('category', resource, alternative_resource)
self.set_editable_attribute('node_license', resource, alternative_resource)

# Contributors will always come from "resource", as contributor constraints
# will require contributors to be present on the resource
self.copy_contributors_from(resource)
# Copy unclaimed records for unregistered users
self.copy_unclaimed_records(resource)
if include_contributors:
# Contributors will always come from "resource", as contributor constraints
# will require contributors to be present on the resource
self.copy_contributors_from(resource)
# Copy unclaimed records for unregistered users
self.copy_unclaimed_records(resource)

self.tags.add(*self.stage_m2m_values('all_tags', resource, alternative_resource))
self.subjects.add(*self.stage_m2m_values('subjects', resource, alternative_resource))
Expand Down
7 changes: 6 additions & 1 deletion osf/models/nodelog.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ class NodeLog(ObjectIDMixin, BaseModel):

MIGRATED_QUICK_FILES = 'migrated_quickfiles'

RESOURCE_ADDED = 'resource_identifier_added'
RESOURCE_UPDATED = 'resource_identifier_udpated'
RESOURCE_REMOVED = 'resource_identifier_removed'

actions = ([CHECKED_IN, CHECKED_OUT, FILE_TAG_REMOVED, FILE_TAG_ADDED, CREATED_FROM, PROJECT_CREATED,
PROJECT_REGISTERED, PROJECT_DELETED, NODE_CREATED, NODE_FORKED, NODE_REMOVED,
NODE_ACCESS_REQUESTS_ENABLED, NODE_ACCESS_REQUESTS_DISABLED,
Expand All @@ -161,7 +165,8 @@ class NodeLog(ObjectIDMixin, BaseModel):
PREREG_REGISTRATION_INITIATED, PROJECT_CREATED_FROM_DRAFT_REG,
GROUP_ADDED, GROUP_UPDATED, GROUP_REMOVED,
AFFILIATED_INSTITUTION_ADDED, AFFILIATED_INSTITUTION_REMOVED, PREPRINT_INITIATED,
PREPRINT_FILE_UPDATED, PREPRINT_LICENSE_UPDATED, VIEW_ONLY_LINK_ADDED, VIEW_ONLY_LINK_REMOVED] + list(sum([
PREPRINT_FILE_UPDATED, PREPRINT_LICENSE_UPDATED, VIEW_ONLY_LINK_ADDED, VIEW_ONLY_LINK_REMOVED,
RESOURCE_ADDED, RESOURCE_UPDATED, RESOURCE_REMOVED] + list(sum([
config.actions for config in apps.get_app_configs() if config.name.startswith('addons.')
], tuple())))
action_choices = [(action, action.upper()) for action in actions]
Expand Down
Loading

0 comments on commit d00e268

Please sign in to comment.