Code Monkey home page Code Monkey logo

Comments (16)

adamn avatar adamn commented on May 23, 2024

Any update on this?

from stream-django.

tschellenbach avatar tschellenbach commented on May 23, 2024

This is an issue with the stream-django integration. You can work around this by using the stream-python library directly. (or patching up this issue in stream-django)

from stream-django.

murdav avatar murdav commented on May 23, 2024

Afer almost one year is the bug still present? I'm in the same situation.

from stream-django.

tbarbugli avatar tbarbugli commented on May 23, 2024

@murdav can you share the model that uses UUID as PK? (and the lib that you use to support that)

from stream-django.

murdav avatar murdav commented on May 23, 2024

Thanks a lof @tbarbugli for replying!

Django==1.10.5
stream-django==1.3.1
stream-python==2.3.9

I extend the Django User model like:

# core.models
from django.contrib.auth.models import AbstractUser
from django.contrib.postgres.fields import JSONField
from django.db import models
from django.utils.translation import ugettext_lazy as _

class User(AbstractUser):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    is_email_visible = models.BooleanField(default=True)
    avatar = models.ImageField(('avatar'), max_length=1024, upload_to=_avatar_upload_to, blank=True)
    stream_token = models.CharField(_('stream token'), max_length=100, blank=True, null=True,
                                    help_text=_('User token from GetStream'))
    params = JSONField(_('params'), null=True, blank=True,)

Basically using:
https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#reusable-apps-and-auth-user-model

Furthermore from the example: https://github.com/GetStream/django_twitter/blob/master/stream_twitter/models.py

# apps.posts.models

# Third-party app imports
from stream_django.activity import Activity
from stream_django.feed_manager import feed_manager

# Imports from local apps
from proj.apps.vote.models import VoteModel
from proj.core.models import User

class Post(VoteModel, Activity):
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    text = models.TextField(_('text'), )
    created_at = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name = _('post')
        verbose_name_plural = _('posts')

    def __str__(self):
        return 'post by {0}'.format(self.user.username)

    @property
    def activity_time(self):
        return self.created

    @property
    def print_self(self):
        print(self.text)

    @property
    def activity_object_attr(self):
        return self

    def save(self, **kwargs):
        self.create_hashtags()
        super(Post, self).save()

    def create_hashtags(self):
        hashtag_set = set(self.parse_hashtags())
        for hashtag in hashtag_set:
            h, _ = Hashtag.objects.get_or_create(name=hashtag)
            h.save()
        Hashtag.objects.filter(name__in=hashtag_set).update(occurrences=F('occurrences')+1)

    def parse_hashtags(self):
        return [slugify(i) for i in self.text.split() if i.startswith("#")]

    def parse_mentions(self):
        mentions = [slugify(i) for i in self.text.split() if i.startswith("@")]
        return User.objects.filter(username__in=mentions)

    def parse_all(self):
        parts = self.text.split()
        hashtag_counter = 0
        mention_counter = 0
        result = {"parsed_text": "", "hashtags": [], "mentions": []}
        for index, value in enumerate(parts):
            if value.startswith("#"):
                parts[index] = "{hashtag" + str(hashtag_counter) + "}"
                hashtag_counter += 1
                result[u'hashtags'].append(slugify(value))
            if value.startswith("@"):
                parts[index] = "{mention" + str(mention_counter) + "}"
                mention_counter += 1
                result[u'mentions'].append(slugify(value))
        result[u'parsed_text'] = " ".join(parts)
        return result

    @property
    def activity_notify(self):
        targets = [feed_manager.get_news_feeds(self.user_id)['timeline']]
        for hashtag in self.parse_hashtags():
            targets.append(feed_manager.get_feed('user', 'hash_%s' % hashtag))
        for user in self.parse_mentions():
            targets.append(feed_manager.get_news_feeds(user.id)['timeline'])
        return targets

I have a Django Rest framework view like

http://localhost:8000/api/v1/users/<username  or uuid>/timeline/

class TimelineViewSet(ViewSet):
    """
    View to list user timeline.
    """
    throttle_scope = 'timelines'

    def list(self, request, *args, **kwargs):
        # get user from <username  or uuid>
        user = get_user_from_url(self.kwargs, self.request.user)

        enricher = Enrich()
        # The news feeds (or timelines) store the activities from the people you follow. There is both a simple timeline
        # newsfeed (similar to twitter) and an aggregated version (like facebook).
        feed = feed_manager.get_feed('timeline_aggregated', user.id)
        activities = feed.get(limit=25)['results']
        enriched_activities = enricher.enrich_activities(activities)
`# !!!!!!! need to be serialized and paginated !!!!!`
        return Response(enriched_activities)

But the result of enricher.enrich_activities(activities) is not enriched, also if I have enriched=True

[
    {
        "updated_at": "2017-02-24T15:54:37.730000",
        "created_at": "2017-02-24T15:54:37.730000",
        "group": "37326_2017-02-24",
        "actor_count": 1,
        "verb": "post",
        "id": "8b720ea8-faa9-11e6-8080-800060963a97",
        "activity_count": 1,
        "activities": [
            {
                "verb": "post",
                "actor": "core.User:5212346d-1315-4ee4-bb71-5ce3c3df80f3",
                "time": "2017-02-24T15:54:37.730372",
                "id": "8b720ea8-faa9-11e6-8080-800060963a97",
                "to": [
                    "timeline:5212346d-1315-4ee4-bb71-5ce3c3df80f3"
                ],
                "foreign_id": "posts.Post:20",
                "target": null,
                "origin": "user:5212346d-1315-4ee4-bb71-5ce3c3df80f3",
                "object": "posts.Post:20"
            }
        ]
    }
]

from stream-django.

JelteF avatar JelteF commented on May 23, 2024

@murdav Could you try out the code from #55, to see if that fixes your issue?

from stream-django.

murdav avatar murdav commented on May 23, 2024

Dear @JelteF,

It doesn't work. I try to copy and paste the objects while debugging.
Basically the activities object (line 2 below) or within TimelineViewSet my previous comments.

feed = feed_manager.get_feed('timeline_aggregated', user.id)
activities = feed.get(limit=25)['results']

is

[{'activities': [{'actor': 'core.User:5212346d-1315-4ee4-bb71-5ce3c3df80f3',
                  'foreign_id': 'posts.Post:36',
                  'id': 'e24b49bc-fce1-11e6-8080-80011a798ab0',
                  'object': 'posts.Post:36',
                  'origin': 'user:5212346d-1315-4ee4-bb71-5ce3c3df80f3',
                  'target': None,
                  'time': datetime.datetime(2017, 2, 27, 11, 42, 57, 580486),
                  'to': ['timeline:5212346d-1315-4ee4-bb71-5ce3c3df80f3'],
                  'verb': 'post'}],
  'activity_count': 1,
  'actor_count': 1,
  'created_at': datetime.datetime(2017, 2, 27, 11, 42, 57, 580000),
  'group': '37326_2017-02-27',
  'id': 'e24b49bc-fce1-11e6-8080-80011a798ab0',
  'updated_at': datetime.datetime(2017, 2, 27, 11, 42, 57, 580000),
  'verb': 'post'}]

Then in my view I do:

enriched_activities = enricher.enrich_activities(activities)

In enrich_activities(self, activities) the result of
activities = self.wrap_activities(activities): https://github.com/GetStream/stream-django/blob/master/stream_django/enrich.py#L73 is

[EnrichedActivity(activity_data={
	'actor_count': 1,
	'activities': [{'object': 'posts.Post:36',
			'target': None,
			'origin': 'user:5212346d-1315-4ee4-bb71-5ce3c3df80f3',
			'foreign_id': 'posts.Post:36', 
			'to': ['timeline:5212346d-1315-4ee4-bb71-5ce3c3df80f3'],
			'time': datetime.datetime(2017, 2, 27, 11, 42, 57, 580486),
			'id': 'e24b49bc-fce1-11e6-8080-80011a798ab0',
			'actor': 'core.User:5212346d-1315-4ee4-bb71-5ce3c3df80f3',
			'verb': 'post'}], 
	'group': '37326_2017-02-27',
	'id': 'e24b49bc-fce1-11e6-8080-80011a798ab0',
	'activity_count': 1,
	'updated_at': datetime.datetime(2017, 2, 27, 11, 42, 57, 580000),
	'verb': 'post',
	'created_at': datetime.datetime(2017, 2, 27, 11, 42, 57, 580000)}, 
	not_enriched_data={})
]

In the _collect_references we have the issue, fields is <class 'tuple'>: ('actor', 'object') (https://github.com/GetStream/stream-django/blob/master/stream_django/enrich.py#L88)

        for activity, field in itertools.product(activities, fields):
            if not self.is_ref(activity, field):
                continue

I got a KeyError: 'actor for activity[field] in

    def is_ref(self, activity, field):
        return len(activity[field].split(':')) == 2 if activity.get(field) else False

from stream-django.

JelteF avatar JelteF commented on May 23, 2024

The KeyError you are receiving sounds super strange, because existence of the field key gets checked by the get after it (although this is done in a bit of a weird way).

Is that the only error you are getting?

Edit: Nvm, I think I might know where the problem is

from stream-django.

murdav avatar murdav commented on May 23, 2024

Is that the only error you are getting?
Yes it's the only issue I get, and it enters in continue (https://github.com/GetStream/stream-django/blob/master/stream_django/enrich.py#L89) and https://github.com/GetStream/stream-django/blob/master/stream_django/enrich.py#L92 is returned.

later if it's needed I could create a second test_app within https://github.com/GetStream/stream-django/tree/master/stream_django/tests.

D

from stream-django.

JelteF avatar JelteF commented on May 23, 2024

I cannot reproduce the issue after all.

One thing that I think you're doing wrong and which might be the cause of the error is that you are using enrich_activities instead of enrich_aggregated_activities for timeline_aggregated feed. Could you try that out and let me know what happens?

If the error still occurs it would be great of you could make a test app. That would make it a lot easier to debug your problem for me.

from stream-django.

murdav avatar murdav commented on May 23, 2024

I further spot the problem here (

instance = objects[f_ct].get(f_id)
)

The objects['core.User'] contains
dict: {UUID('5212346d-1315-4ee4-bb71-5ce3c3df80f3'): <User:my username>} and the result of instance = objects[f_ct].get(f_id) is always None.
While having objects['core.User']['5212346d-1315-4ee4-bb71-5ce3c3df80f3'] works.

from stream-django.

JelteF avatar JelteF commented on May 23, 2024

Alright, that makes sense, UUID('5212346d-1315-4ee4-bb71-5ce3c3df80f3') is not the same as the string '5212346d-1315-4ee4-bb71-5ce3c3df80f3'. I just pushed an extra piece of code to #55, could you check if it now works?

from stream-django.

murdav avatar murdav commented on May 23, 2024

Yeap, it works like a charm 👍

from stream-django.

JelteF avatar JelteF commented on May 23, 2024

Good to hear! I'll let one of my colleagues review it and we'll merge it into master afterwards.

from stream-django.

JelteF avatar JelteF commented on May 23, 2024

I changed the #55 fix to use django functionality to know if it should use the int or UUID function. Could you check if the new fix still works for you?

from stream-django.

murdav avatar murdav commented on May 23, 2024

Yes, it works, nice implementation:

model = get_model(*f_ct.split('.'))
f_id = model._meta.pk._**to_python**_(f_id)

Thanks again!

from stream-django.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.