Skip to content
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

Update metrics on transfer/owner change #810

Merged
merged 3 commits into from
Feb 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
[#808](https://github.com/opendatateam/udata/pull/808)
- Fix user default metrics not being set [migration]
[#809](https://github.com/opendatateam/udata/pull/809)
- Fix metric update after transfer
[#810](https://github.com/opendatateam/udata/pull/810)

## 1.0.3 (2017-02-21)

Expand Down
22 changes: 6 additions & 16 deletions udata/core/dataset/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
from werkzeug import cached_property

from udata.frontend.markdown import mdstrip
from udata.models import (
db, WithMetrics, BadgeMixin, SpatialCoverage, OwnedByQuerySet
)
from udata.models import db, WithMetrics, BadgeMixin, SpatialCoverage
from udata.i18n import lazy_gettext as _
from udata.utils import hash_url

Expand Down Expand Up @@ -107,7 +105,7 @@ def __unicode__(self):
return self.title


class DatasetQuerySet(OwnedByQuerySet):
class DatasetQuerySet(db.OwnedQuerySet):
def visible(self):
return self(private__ne=True, resources__0__exists=True, deleted=None)

Expand Down Expand Up @@ -236,7 +234,7 @@ class Resource(ResourceMixin, WithMetrics, db.EmbeddedDocument):
on_deleted = signal('Resource.on_deleted')


class Dataset(WithMetrics, BadgeMixin, db.Document):
class Dataset(WithMetrics, BadgeMixin, db.Owned, db.Document):
created_at = DateTimeField(verbose_name=_('Creation date'),
default=datetime.now, required=True)
last_modified = DateTimeField(verbose_name=_('Last modification date'),
Expand All @@ -251,9 +249,6 @@ class Dataset(WithMetrics, BadgeMixin, db.Document):
resources = db.ListField(db.EmbeddedDocumentField(Resource))

private = db.BooleanField()
owner = db.ReferenceField('User', reverse_delete_rule=db.NULLIFY)
organization = db.ReferenceField('Organization',
reverse_delete_rule=db.NULLIFY)
frequency = db.StringField(choices=UPDATE_FREQUENCIES.keys())
frequency_date = db.DateTimeField(verbose_name=_('Future date of update'))
temporal_coverage = db.EmbeddedDocumentField(db.DateRange)
Expand All @@ -276,14 +271,12 @@ def __str__(self):
}

meta = {
'allow_inheritance': True,
'indexes': [
'-created_at',
'slug',
'organization',
'resources.id',
'resources.urlhash',
],
] + db.Owned.meta['indexes'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if db.Owned.INDEXES is easier to understand. Here it looks to be dynamic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But where does it come from ?
The meta['indexes'] the only way (I know) to get the mixin default indexes.
It relies on mongoengine default (documented) behavior in which meta is a dictionary

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, I thought it was udata-related. My bad.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

;)

'ordering': ['-created_at'],
'queryset_class': DatasetQuerySet,
}
Expand Down Expand Up @@ -560,19 +553,16 @@ def get_json_ld_extra(key, value):
post_save.connect(Dataset.post_save, sender=Dataset)


class CommunityResource(ResourceMixin, WithMetrics, db.Document):
class CommunityResource(ResourceMixin, WithMetrics, db.Owned, db.Document):
'''
Local file, remote file or API added by the community of the users to the
original dataset
'''
dataset = db.ReferenceField(Dataset)
owner = db.ReferenceField('User', reverse_delete_rule=db.NULLIFY)
organization = db.ReferenceField(
'Organization', reverse_delete_rule=db.NULLIFY)

meta = {
'ordering': ['-created_at'],
'queryset_class': OwnedByQuerySet,
'queryset_class': db.OwnedQuerySet,
}

@property
Expand Down
14 changes: 13 additions & 1 deletion udata/core/organization/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from udata.i18n import lazy_gettext as _
from udata.core.followers.metrics import FollowersMetric
from udata.core.badges.metrics import BadgesMetric
from udata.models import Dataset, Reuse, Organization
from udata.models import db, Dataset, Reuse, Organization

__all__ = (
'DatasetsMetric', 'ReusesMetric', 'MembersMetric', 'OrgFollowersMetric',
Expand Down Expand Up @@ -37,6 +37,7 @@ class ReusesMetric(Metric):
def get_value(self):
return Reuse.objects(organization=self.target).count()


ReusesMetric.connect(Reuse.on_create, Reuse.on_update)


Expand All @@ -59,6 +60,7 @@ class MembersMetric(Metric):
def get_value(self):
return len(self.target.members)


MembersMetric.connect(Organization.on_create, Organization.on_update)


Expand All @@ -68,3 +70,13 @@ class OrgFollowersMetric(FollowersMetric):

class OrgBadgesMetric(BadgesMetric):
model = Organization


@db.Owned.on_owner_change.connect
def update_downer_metrics(document, previous):
if not isinstance(previous, Organization):
return
if isinstance(document, Dataset):
DatasetsMetric(previous).trigger_update()
elif isinstance(document, Reuse):
ReusesMetric(previous).trigger_update()
12 changes: 4 additions & 8 deletions udata/core/reuse/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from udata.core.storages import images, default_image_basename
from udata.frontend.markdown import mdstrip
from udata.i18n import lazy_gettext as _
from udata.models import db, BadgeMixin, WithMetrics, OwnedByQuerySet
from udata.models import db, BadgeMixin, WithMetrics
from udata.utils import hash_url

__all__ = ('Reuse', 'REUSE_TYPES')
Expand All @@ -31,7 +31,7 @@
IMAGE_MAX_SIZE = 800


class ReuseQuerySet(OwnedByQuerySet):
class ReuseQuerySet(db.OwnedQuerySet):
def visible(self):
return self(private__ne=True, datasets__0__exists=True, deleted=None)

Expand All @@ -41,7 +41,7 @@ def hidden(self):
db.Q(deleted__ne=None))


class Reuse(db.Datetimed, WithMetrics, BadgeMixin, db.Document):
class Reuse(db.Datetimed, WithMetrics, BadgeMixin, db.Owned, db.Document):
title = db.StringField(required=True)
slug = db.SlugField(
max_length=255, required=True, populate_from='title', update=True)
Expand All @@ -59,9 +59,6 @@ class Reuse(db.Datetimed, WithMetrics, BadgeMixin, db.Document):
# badges = db.ListField(db.EmbeddedDocumentField(ReuseBadge))

private = db.BooleanField()
owner = db.ReferenceField('User', reverse_delete_rule=db.NULLIFY)
organization = db.ReferenceField(
'Organization', reverse_delete_rule=db.NULLIFY)

ext = db.MapField(db.GenericEmbeddedDocumentField())
extras = db.ExtrasField()
Expand All @@ -77,8 +74,7 @@ def __str__(self):
__badges__ = {}

meta = {
'allow_inheritance': True,
'indexes': ['-created_at', 'owner', 'urlhash'],
'indexes': ['-created_at', 'urlhash'] + db.Owned.meta['indexes'],
'ordering': ['-created_at'],
'queryset_class': ReuseQuerySet,
}
Expand Down
13 changes: 12 additions & 1 deletion udata/core/user/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from udata.core.metrics import Metric
from udata.i18n import lazy_gettext as _
from udata.models import Dataset, Reuse, User, Follow
from udata.models import db, Dataset, Reuse, User, Follow

from udata.core.followers.metrics import FollowersMetric
from udata.core.followers.signals import on_follow, on_unfollow
Expand Down Expand Up @@ -44,9 +44,20 @@ class ReusesMetric(UserMetric):
def get_value(self):
return Reuse.objects(owner=self.user).count()


ReusesMetric.connect(Reuse.on_create, Reuse.on_update)


@db.Owned.on_owner_change.connect
def update_downer_metrics(document, previous):
if not isinstance(previous, User):
return
if isinstance(document, Dataset):
DatasetsMetric(previous).trigger_update()
elif isinstance(document, Reuse):
ReusesMetric(previous).trigger_update()


class UserFollowersMetric(FollowersMetric):
model = User

Expand Down
2 changes: 0 additions & 2 deletions udata/features/transfer/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,8 @@ def accept_transfer(transfer, comment=None):
recipient = transfer.recipient
if isinstance(recipient, Organization):
subject.organization = recipient
subject.owner = None
elif isinstance(recipient, User):
subject.owner = recipient
subject.organization = None

subject.save()

Expand Down
14 changes: 4 additions & 10 deletions udata/harvest/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from werkzeug import cached_property

from udata.models import db, Dataset, OwnedByQuerySet
from udata.models import db, Dataset
from udata.i18n import lazy_gettext as _


Expand Down Expand Up @@ -82,12 +82,12 @@ class HarvestSourceValidation(db.EmbeddedDocument):
comment = db.StringField()


class HarvestSourceQuerySet(OwnedByQuerySet):
class HarvestSourceQuerySet(db.OwnedQuerySet):
def visible(self):
return self(deleted=None)


class HarvestSource(db.Document):
class HarvestSource(db.Owned, db.Document):
name = db.StringField(max_length=255)
slug = db.SlugField(max_length=255, required=True, unique=True,
populate_from='name', update=True)
Expand All @@ -107,10 +107,6 @@ class HarvestSource(db.Document):

deleted = db.DateTimeField()

owner = db.ReferenceField('User', reverse_delete_rule=db.NULLIFY)
organization = db.ReferenceField('Organization',
reverse_delete_rule=db.NULLIFY)

@property
def domain(self):
parsed = urlparse(self.url)
Expand All @@ -131,10 +127,8 @@ def last_job(self):
'indexes': [
'-created_at',
'slug',
'organization',
'owner',
'deleted',
],
] + db.Owned.meta['indexes'],
'ordering': ['-created_at'],
'queryset_class': HarvestSourceQuerySet,
}
Expand Down