示例#1
0
 def test_get_flag_type(self):
     for fo in USERFLAG_TYPES:
         flag_name = fo[1]
         flag_item = UserFlag.get_flag_type(flag_name)
         flag_type = flag_item[0]
         self.assertEqual(fo[0], flag_type)
     # And this one should not exist
     self.assertRaises(IndexError, UserFlag.get_flag_type, 'fdgkfhgPMq')
示例#2
0
def profile_flag(request, flag_name, username):
    data = []
    user = get_object_or_404(User, username=username)

    if request.method == 'POST':
        # Set a flag on another user.
        try:
            UserFlag.set_flag(flag_name, sender=request.user, receiver=user)
        except IndexError:
            return HttpResponseNotFound()

    elif request.method == 'DELETE':
        try:
            UserFlag.remove_flag(flag_name, sender=request.user, receiver=user)
        except IndexError:
            return HttpResponseNotFound()

    return HttpResponse(json.dumps(data), {'content_type': 'application/json'})
示例#3
0
def can_send_msg(sender, receiver):
    """Returns True if sender has permission to message receiver.

    sender User object of message author, most likely request.user
    receiver User object of message receipient.
    """
    f_block = UserFlag.get_flag_type('block')[0]
    return not UserFlag.objects.filter(
        # Careful: "receiver" of flag is "sender" of message.
        receiver=sender,
        sender=receiver,
        flag_type=f_block).exists()
示例#4
0
    def test_one_way_flag(self):
        for flag_name in ['block', 'favorite', 'viewed']:
            flag_type = UserFlag.get_flag_type(flag_name)[0]

            # Set user1 sets flag on user2
            UserFlag.set_flag(flag_name, self.user1, self.user2)
            # Verify "manually" the flag is set
            f = UserFlag.objects.filter(sender=self.user1,
                                        receiver=self.user2,
                                        flag_type=flag_type)
            self.assertEqual(f.count(), 1, msg='should find exactly one entry')

            # Have user1 cancel the flag
            UserFlag.remove_flag(flag_name, self.user1, self.user2)
            # Verify there is no flag
            f = UserFlag.get_one_way_flags(self.user1, self.user2)
            f = f.filter(flag_type=flag_type)
            self.assertEqual(f.count(), 0, msg='should find no entry')
示例#5
0
def profile_api_view(request, q, use):
    """Return a JSON view with extensive data on one user.

    Either by the user's pk or the username.
    """
    if use == 'username':
        user = get_object_or_404(User, username=q)
    elif use == 'user_id':
        user = get_object_or_404(User, pk=q)
    elif use == 'authuser':
        user = request.user
    else:
        raise Http404

    if request.method == "POST":
        # get data payload
        if request.body:
            jsonstr = request.body.decode("utf-8")

            if type(jsonstr) != str:
                jsonstr = jsonstr.decode('utf-8')  # bytes -> Unicode

            body = json.loads(jsonstr)
        else:
            body = {}

        if body.get('pic', None) is not None:
            # Set "pic" as authuser's main profile picture.
            try:
                pic = UserPic.objects.get(pk=body.get('pic', None))
                request.user.profile.pic = pic
            except UserPic.DoesNotExist:
                pass

        if body.get('city', None) is not None:
            try:
                city = City.objects.get(pk=body.get('city', None))
                request.user.profile.city = city
                request.user.profile.country = city.country
                request.user.profile.lat = city.lat
                request.user.profile.lng = city.lng
            except City.DoesNotExist:
                # the user selected no city
                request.user.profile.city = None
                request.user.profile.country = None
                # Do not accept country-only data!
                # try:
                #    # but maybe we have a country?
                #    country = Country.objects.get(pk=body.get('country', None))
                #    request.user.profile.country = country
                # except country.DoesNotExist:
                #    # nope, then set to "unknown" too
                #    request.user.profile.country = None

        if body.get('lat', None) is not None \
                and body.get('lng', None) is not None:
            # maybe overwrite with more precise lat/lng given?
            request.user.profile.lat = body.get('lat', None)
            request.user.profile.lng = body.get('lng', None)

        if body.get('new_password_1', None) is not None\
                or body.get('new_password_2', None) is not None:
            pw_1 = body.get('new_password_1', '')
            pw_2 = body.get('new_password_2', None)
            if not request.user.check_password(body.get('old_password', None)):
                return HttpResponseBadRequest('old_password')
            if len(pw_1) < 6 or pw_1 != pw_2:
                return HttpResponseBadRequest('new_password_1')
            request.user.set_password(pw_1)
            request.user.save()

        if body.get('email', None) is not None:
            if not request.user.check_password(body.get('old_password', None)):
                return HttpResponseBadRequest('old_password')
            request.user.email = body.get('email')
            request.user.save()

        # all the other standard data fields on "User.profile"
        fields = [
            'aboutme',
            'aboutbooks',
            'aboutmovies',
            'aboutmusic',
            'aboutarts',
            'abouttravel',
            'aboutfood',
            'aboutquotes',
            'aboutsports',
            'drink',
            'diet',
            'figure',
            'fitness',
            'pot',
            'education',
            'eyecolor',
            'gender',
            'lookingfor',
            'has_children',
            'height',
            'haircolor',
            'income',
            'jobfield',
            'longest_relationship',
            'looks',
            'relationship_status',
            'religion',
            'religiosity',
            'smoke',
            'spirituality',
            'sports',
            'style',
            'want_children',
            'weight',
            'would_relocate',
        ]
        for field in fields:
            field_value = body.get(field, None)
            if field_value is not None:
                setattr(request.user.profile, field, field_value)
        # Set "dob" manually, to catch cases were it is "" empty.
        dob = body.get('dob', '')
        if dob:
            # Verify that dob is well formated
            re_dob = re.compile(r'^(19|20)[0-9][0-9]-[01][0-9]-[0123][0-9]$')
            if re_dob.match(dob):
                request.user.profile.dob = dob
            else:
                request.user.profile.dob = None
        # If style contained some css, then activate it.
        if body.get('style', None) is not None:
            request.user.profile.style_active = body.get('style_active', True)

        # all done, save user
        request.user.profile.save()
        return HttpResponse()  # 200

    if request.method == "DELETE":
        # delete user's profile. Either user's own profile or authuser is_staff
        # and deletes another user's profile.
        if request.user.is_staff:
            # noinspection PyUnusedLocal
            ownprofile = False
        elif request.user.id == user.id:
            # noinspection PyUnusedLocal
            ownprofile = True
        else:
            return HttpResponseForbidden()

        # Deleted accounts should be completely removed.

        # Text content from all public posts should be replaced by a message
        # that the user account was deleted, user field must be set to None.
        Talk.objects.filter(user=user).update(text='')

        # Text content from all private messages should be preserved, if the
        # user deleted their own account. If the account was removed by staff,
        # then the content should be removed as well (to remove spam)
        # if ownprofile:
        #    UserMsg.objects.filter(from_user=user).update(from_user=None)
        #    Should happen automatically because models.SET_NULL in model def.
        # else:
        #    UserMsg.objects.filter(
        #        from_user=user).update(text='', from_user=None)

        # For some reason I get IntegrityError when trying to set them to NULL
        # so instead just delete all messages send or received by the user.
        # That's BAD UX becasue the other user's "private" inbox is affected
        # and they will feel loss-of-control, but no time now to figure out why
        # the DB contrains don't work as expected...
        UserMsg.objects.filter(from_user=user).delete()
        UserMsg.objects.filter(to_user=user).delete()

        # Preserve all messges sent to the user, but remove association.
        # Should happen automatically because models.SET_NULL in model def.
        # UserMsg.objects.filter(to_user=user).update(to_user=None)

        # All flags on the account should be removed, as well as the related
        # Profile object. The cascading should happen automatically when
        # deleting the User object.
        user.delete()

        # Confirm
        return HttpResponse()  # 200

    if request.method == "GET":
        flags = {}
        if user != request.user:
            # translate the flags into profileuser API flields
            for f in UserFlag.get_one_way_flags(request.user, user):
                name = [x[1] for x in USERFLAG_TYPES if x[0] == f.flag_type][0]
                if f.sender == request.user:
                    flags[name] = f.created.isoformat()
                elif f.sender == user:
                    flags[name + '_received'] = f.created.isoformat()

            for f in UserFlag.get_two_way_flags(request.user, user):
                name = [x[1] for x in USERFLAG_TYPES if x[0] == f.flag_type][0]
                if f.sender == request.user:
                    flags[name] = f.created.isoformat()
                    if f.confirmed is not None:
                        flags[name + '_received'] = f.confirmed.isoformat()
                elif f.sender == user:
                    flags[name + '_received'] = f.created.isoformat()
                    if f.confirmed:
                        flags[name] = f.confirmed.isoformat()

            # count the view, this is not authuser looking at their own profile
            user.profile.views_counter += 1  # no F('views_counter') + 1
            user.profile.save(update_fields=['views_counter'])

        data = {
            "flags": flags,
            # META
            "id": user.pk,
            "is_staff": user.is_staff,
            "last_modified": user.profile.last_modified.isoformat(),
            "last_active": user.profile.last_active.isoformat(),
            "created": user.date_joined.isoformat(),
            "last_login": user.last_login.isoformat(),
            # PNASL
            "pic": user.profile.pic_id,
            "pics": [x.pk for x in user.pics.all().order_by('-pk')],
            "username": user.username,
            "age": user.profile.age,
            "gender": user.profile.gender,
            "city": user.profile.city_id,
            "country": user.profile.country_id,
            "lat": user.profile.lat,
            "lng": user.profile.lng,
            # SETTINGS
            "language": user.profile.language,
            "style_active": user.profile.style_active,
            "style": user.profile.style,
            # COUTNER
            "friend_open_invites_recv_counter":
            user.profile.friend_open_invites_recv_counter,
            "friend_mutual_confirmed_counter":
            user.profile.friend_mutual_confirmed_counter,
            "match_open_invites_recv_counter":
            user.profile.match_open_invites_recv_counter,
            "match_mutual_confirmed_counter":
            user.profile.match_mutual_confirmed_counter,
            "mail_recv_counter": user.profile.mail_recv_counter,
            "mail_sent_counter": user.profile.mail_sent_counter,
            "mail_unread_counter": user.profile.mail_unread_counter,
            "views_counter": user.profile.views_counter,
            # BLAH
            "aboutme": user.profile.aboutme,
            "aboutbooks": user.profile.aboutbooks,
            "aboutmovies": user.profile.aboutmovies,
            "aboutmusic": user.profile.aboutmusic,
            "aboutarts": user.profile.aboutarts,
            "abouttravel": user.profile.abouttravel,
            "aboutfood": user.profile.aboutfood,
            "aboutquotes": user.profile.aboutquotes,
            "aboutsports": user.profile.aboutsports,
            # STUFF
            "lookingfor": user.profile.lookingfor,
            "height": user.profile.height,
            "weight": user.profile.weight,
            "eyecolor": user.profile.eyecolor,
            "haircolor": user.profile.haircolor,
            "relationship_status": user.profile.relationship_status,
            "has_children": user.profile.has_children,
            "want_children": user.profile.want_children,
            "would_relocate": user.profile.would_relocate,
            "smoke": user.profile.smoke,
            "pot": user.profile.pot,
            "drink": user.profile.drink,
            "longest_relationship": user.profile.longest_relationship,
            "looks": user.profile.looks,
            "figure": user.profile.figure,
            "fitness": user.profile.fitness,
            "education": user.profile.education,
            "diet": user.profile.diet,
            "sports": user.profile.sports,
            "religion": user.profile.religion,
            "religiosity": user.profile.religiosity,
            "spirituality": user.profile.spirituality,
            "jobfield": user.profile.jobfield,
            "income": user.profile.income,
            "western_zodiac": user.profile.western_zodiac,
            "eastern_zodiac": user.profile.eastern_zodiac,
        }
        try:
            data['crc'] = user.profile.crc
        except AttributeError:
            data['crc'] = ''
        # attach a list of basic user data of profileuser's friends
        data['friends'] = []
        # Fetch all i18n'ed geonames at once and join onto user.profile instance
        friends_li = user.profile.get_friends()  # ret User instances, ugh!
        friends_city_id_li = [x.profile.city_id for x in friends_li]
        friends_city_li = UserProfile.get_crc_list(friends_city_id_li)
        for x in user.profile.get_friends():
            data['friends'].append({
                'id':
                x.id,
                'username':
                x.username,
                'pic':
                x.profile.pic_id or 0,
                'age':
                x.profile.age,
                'gender':
                x.profile.gender,
                'crc':
                friends_city_li.get(x.profile.city_id, ''),
            })
        # add some extras, depending if authuser is looking at his own
        # profile, of looking at somebody else's profile page
        if user == request.user:
            # authuser can see (and edit) their own profile birthdate
            # noinspection PyBroadException
            try:
                data['dob'] = user.profile.dob.isoformat()
            except:
                data['dob'] = ''
            # tell authuser how many unread mail she has
            data['mail_unread_counter'] = UserMsg.objects.filter(
                is_read=False, to_user=request.user, is_blocked=False).count()
        else:
            # if this is not authuser looking at his own profile, then add the
            # date of the last time profileuser looked at authuser's  profile.
            try:
                data["last_viewed"] = UserFlag.last_viewed(
                    user, request.user).isoformat()
            except AttributeError:
                data['last_viewed'] = 0
            # also, remember this profile view in UserFlags
            flag, created = UserFlag.objects.get_or_create(flag_type=5,
                                                           sender=request.user,
                                                           receiver=user)
            flag.created = datetime.utcnow().replace(tzinfo=utc)
            flag.save()

        if settings.ENABLE_DEBUG_TOOLBAR:
            return HttpResponse('<html><body>{}</body></html>'.format(data))

        return HttpResponse(json.dumps(data),
                            {'content_type': 'application/json'})
示例#6
0
 def test_get_friends(self):
     uli = [['oieyriiwhbv', 'hunter2', '*****@*****.**'],
            ['8hfwieuhfvv', 'hunter2', '*****@*****.**'],
            ['Opc8s9nsdfb', 'hunter2', '*****@*****.**']]
     for u in uli:
         user = User.objects.create_user(u[0], email=u[2], password=u[1])
         self.user.append(user)
     # Set user[0] to be 'friends' with both user[1] and user[2]
     UserFlag.set_flag('friend', self.user[0], self.user[1])
     UserFlag.set_flag('friend', self.user[0], self.user[2])
     UserFlag.set_flag('friend', self.user[1], self.user[0])
     UserFlag.set_flag('friend', self.user[2], self.user[0])
     self.assertEqual(len(self.user[0].profile.get_friends()), 2)
     UserFlag.remove_flag('friend', self.user[0], self.user[1])
     self.assertEqual(len(self.user[0].profile.get_friends()), 1)
     UserFlag.remove_flag('friend', self.user[2], self.user[0])
     self.assertEqual(len(self.user[0].profile.get_friends()), 0)
示例#7
0
    def import_dtrprofile_flag(self):
        print('Starting import of UserFlag data...')
        print('Flags have to be converted, there is no way to '
              'count-and-compare them.')
        print('Each time we need to trunate the new table and start over.')
        UserFlag.objects.all().delete()
        print('All NEW UserFlag data deleted for fresh import.')

        cursor = conn.cursor()
        cursor.execute('SELECT COUNT(*) FROM dtrflag_flag '
                       'WHERE otype=2')  # only flags on profiles
        count_old = cursor.fetchone()[0]
        cursor = conn.cursor()
        cursor.execute('SELECT * FROM dtrflag_flag WHERE otype=2 '
                       'ORDER BY id ASC')  # only flags on profiles
        i = 0  # rows worked on
        j = 0  # individual flags imported.

        for row in cursor:
            i += 1
            print('{0}/{1} ~ '.format(i, count_old), end='', flush=True)

            try:
                sender = User.objects.get(pk=row[1])
                receiver = User.objects.get(pk=row[4])
            except User.DoesNotExist:
                print('user not found, skip entry.', flush=True)
                continue  # skip if either user does not exist.

            print('{0} -> {1} ~ '.format(sender.pk, receiver.pk),
                  end='', flush=True)

            # All this needs to be converted, differently for every FLAG TYPE!
            # 1--friend ------- 0x0100 ( NOT 2 )
            # 2--like --------- 0x0010 ( NOT 1 )
            # 3--favourite ---- 0x0200 -- NO ENTRIES, SKIP!
            # 4--block -------- 0x0080

            if row[5] & 0x0080:  # block - 4
                print('"block" flag found! ', end='', flush=True)
                # noinspection PyUnusedLocal
                flag = UserFlag(sender=sender, receiver=receiver, flag_type=4)
                print('user {0} BLOCKED by user {1}, skip other flags.'.format(
                                receiver.username, sender.username), flush=True)
                j += 1
                continue  # blocked is blocked, no other relationship possible.

            if row[5] & 0x0010:  # like - 2
                print('"like" flag found... ', end='', flush=True)
                # This is a reciprocal flag, so first check if there is already
                # a flag set coming the otehr way!
                try:
                    # Roles reversed!
                    flag = UserFlag.objects.get(sender=receiver, flag_type=2,
                                                receiver=sender)
                    flag.confirmed = datetime.utcnow().replace(tzinfo=utc)
                    flag.save()
                    print('this was a MATCH! ', end='', flush=True)
                except:
                    # Roles straight again.
                    # noinspection PyUnusedLocal
                    flag = UserFlag.objects.create(sender=sender, flag_type=2,
                                                   receiver=receiver)
                    print('added! ', end='', flush=True)
                # Count flags added.
                j += 1

            if row[5] & 0x0100:  # friend - 1
                print('"friend" flag found! ', end='', flush=True)
                # Again, check for reciprocal.
                try:
                    # Roles reversed!
                    flag = UserFlag.objects.get(sender=receiver,
                                                receiver=sender, flag_type=1)
                    flag.confirmed = datetime.utcnow().replace(tzinfo=utc)
                    flag.save()
                    print('confirmed friends! ', end='', flush=True)
                except:
                    # Roles straight again.
                    # noinspection PyUnusedLocal
                    flag = UserFlag.objects.create(sender=sender, flag_type=1,
                                                   receiver=receiver)
                    print('friend invite added! ', end='', flush=True)
                # Count flags added.
                j += 1

            print(' done!', flush=True)

            # dtrflag_flag
            # ------------------------------------------------------------
            # 0 | id       | int(11)              | NO   | PRI | NULL    |
            # 1 | user_id  | int(11)              | NO   | MUL | NULL    |
            # 2 | otype    | smallint(5) unsigned | NO   |     | NULL    |
            # 3 | oid      | int(10) unsigned     | NO   | MUL | NULL    |
            # 4 | ouser_id | int(11)              | YES  | MUL | NULL    |
            # 5 | flags    | int(10) unsigned     | NO   |     | NULL    |
            # 6 | created  | datetime             | NO   |     | NULL    |
            # 7 | text     | varchar(250)         | NO   |     | NULL    |

        print('All done.')
        print('Finished dtrprofile_userflag table.')
示例#8
0
    def test_like_flag(self):
        """Using UserFlag methods, user1 creates a 'like' on user2, then user2
        likes back to create a match, then user1 removes the like, then user2
        removes the like. Test every step."""
        flag_name = 'like'
        flag_type = UserFlag.get_flag_type(flag_name)[0]

        # Set user1 'likes' user2
        UserFlag.set_flag('like', self.user1, self.user2)
        # Verify the 'like' is set
        f = UserFlag.objects.filter(sender=self.user1,
                                    receiver=self.user2,
                                    flag_type=flag_type)
        self.assertEqual(f.count(), 1, msg='should find exactly one entry')
        self.assertEqual(f.first().confirmed, None, msg='shoud be unconfirmed')

        # Have user2 'like' user1 back.
        UserFlag.set_flag(flag_name, self.user2, self.user1)
        # Verify there is a match
        f = UserFlag.get_two_way_flags(self.user1, self.user2)
        f = f.filter(flag_type=flag_type)
        self.assertEqual(f.count(), 1, msg='should find exactly one entry')
        self.assertNotEqual(f.first().confirmed,
                            None,
                            msg='should be confirm.')

        # Have user1 cancel the 'like' flag
        UserFlag.remove_flag(flag_name, self.user1, self.user2)
        # Verify there is no match, but user2 'likes' user1
        f = UserFlag.get_two_way_flags(self.user1, self.user2)
        f = f.filter(flag_type=flag_type)
        self.assertEqual(f.count(), 1, msg='should find one entry')
        self.assertEqual(f.first().confirmed,
                         None,
                         msg='should be unconfirmed')

        # Have user2 remove the 'like' flag, too
        UserFlag.remove_flag(flag_name, self.user2, self.user1)
        # Verify there is no 'friends' entry for the users
        f = UserFlag.objects.filter(
            (Q(sender=self.user1, receiver=self.user2)
             | Q(sender=self.user2, receiver=self.user1)),
            flag_type=flag_type)
        self.assertEqual(f.count(), 0, msg='should find no entries')
示例#9
0
    def test_friends_flag(self):
        """Using UserFlag methods, create a 'friends' relation between two
        users, then delete the relation again, test every step.

        Two way flags: this is the same as below `test_like_flag()`, but keep
        as separate test methods to make it more obvious where errors are.
        """
        flag_name = 'friend'
        flag_type = UserFlag.get_flag_type(flag_name)[0]

        # Have user1 send a friend invite to user2
        UserFlag.set_flag(flag_name, self.user1, self.user2)
        # Verify there is an "invited" entry in UserFlag
        f = UserFlag.objects.filter(sender=self.user1,
                                    receiver=self.user2,
                                    flag_type=flag_type)
        self.assertEqual(f.count(), 1, msg='should find exactly one entry')
        self.assertEqual(f.first().confirmed, None, msg='shoud be unconfirmed')

        # Have user2 confirm the open invite
        UserFlag.set_flag(flag_name, self.user2, self.user1)
        # Verify there is a confirmed friends entry in UserFlag
        f = UserFlag.get_two_way_flags(self.user1, self.user2)
        f = f.filter(flag_type=flag_type)  # only filter 'friends' flags
        self.assertEqual(f.count(), 1, msg='should find exactly one entry')
        self.assertNotEqual(f.first().confirmed,
                            None,
                            msg='should be confirm.')

        # Have user1 cancel the 'friends' flag
        UserFlag.remove_flag(flag_name, self.user1, self.user2)
        # Verify there is no confirmed friends entry in UserFlag
        f = UserFlag.get_two_way_flags(self.user1, self.user2)
        f = f.filter(flag_type=flag_type)  # only filter 'friends' flags
        self.assertEqual(f.count(), 1, msg='should find one entry')
        self.assertEqual(f.first().confirmed,
                         None,
                         msg='should be unconfirmed')

        # Have user2 cancel the 'friends' flag, too
        UserFlag.remove_flag(flag_name, self.user2, self.user1)
        # Verify there is no 'friends' entry for the users.
        f = UserFlag.objects.filter(
            (Q(sender=self.user1, receiver=self.user2)
             | Q(sender=self.user2, receiver=self.user1)),
            flag_type=flag_type)
        self.assertEqual(f.count(), 0, msg='should find no entries')