コード例 #1
0
ファイル: avatars.py プロジェクト: UPCnet/max
def getUserAvatar(context, request):
    """
        Get user avatar
    """
    base_folder = request.registry.settings.get('avatar_folder')
    username = request.matchdict['username']
    named_size = request.matchdict.get('size', '')
    filename = ''

    # First attempt to find an existing named size avatar
    # If image is not sized, this will fallback to regular avatar.
    avatar_folder = get_avatar_folder(base_folder, 'people', username, size=named_size)
    if os.path.exists(os.path.join(avatar_folder, username)):
        filename = username

    # If we were loking for a named size avatar, reaching here
    # menans we did not found it, so fallback to base avatar
    elif named_size:
        avatar_folder = get_avatar_folder(base_folder, 'people', username)
        if os.path.exists(os.path.join(avatar_folder, username)):
            filename = username

    # At this point we should have a filename set, if not, it means that we
    # couldn't locate any size of the requested avatar. In this case, set the
    # missing avatar filename, based on context and size and located at root
    # avatars folder

    avatar_folder = avatar_folder if filename else get_avatar_folder(base_folder)
    named_size_sufix = '-{}'.format(named_size) if named_size else ''
    filename = filename if filename else 'missing-people.png'.format(context, named_size_sufix)

    data = open(os.path.join(avatar_folder, filename)).read()
    image = Response(data, status_int=200)
    image.content_type = 'image/png'
    return image
コード例 #2
0
ファイル: avatars.py プロジェクト: UPCnet/max
def getContextAvatar(context, request):
    """
        Get context avatar

        To the date, this is only implemented to
        work integrated with Twitter.
    """
    chash = context['hash']
    twitter_username = context['twitterUsername']

    base_folder = request.registry.settings.get('avatar_folder')
    avatar_folder = get_avatar_folder(base_folder, 'contexts', chash)

    context_image_filename = '%s/%s' % (avatar_folder, chash)

    api = get_twitter_api(request.registry)
    if not os.path.exists(context_image_filename):
        download_twitter_user_image(api, twitter_username, context_image_filename)

    if os.path.exists(context_image_filename):
        # Calculate time since last download and set if we have to re-download or not
        modification_time = os.path.getmtime(context_image_filename)
        hours_since_last_modification = (time.time() - modification_time) / 60 / 60
        if hours_since_last_modification > 3:
            download_twitter_user_image(api, twitter_username, context_image_filename)
    else:
        context_image_filename = '{}/missing-context.png'.format(base_folder)

    data = open(context_image_filename).read()
    image = Response(data, status_int=200)
    image.content_type = 'image/png'
    return image
コード例 #3
0
ファイル: base.py プロジェクト: UPCnet/max
 def get_user_avatar_dimensions(self, username, size=''):
     """
         Returns the (width, height) of an image for a especifi user, located
         in the designated folder for that user.
     """
     avatar_folder = get_avatar_folder(self.avatar_folder, 'people', username, size=size)
     return Image.open('{}/{}'.format(avatar_folder, username)).size
コード例 #4
0
ファイル: base.py プロジェクト: UPCnet/max
 def get_context_avatar_modification_time(self, context):
     """
         Returns the (width, height) of an image for a especifi user, located
         in the designated folder for that user.
     """
     avatar_folder = get_avatar_folder(self.avatar_folder, 'contexts', context)
     filename = '{}/{}'.format(avatar_folder, context)
     return os.path.getmtime(filename)
コード例 #5
0
ファイル: base.py プロジェクト: UPCnet/max
 def rewind_context_avatar_mod_time(self, context, hours):
     """
         Changes the contex's avatar file modifcation time x hours back in time
     """
     avatar_folder = get_avatar_folder(self.avatar_folder, 'contexts', context)
     filename = '{}/{}'.format(avatar_folder, context)
     modification_time = os.path.getmtime(filename)
     new_time = modification_time - (hours * 60 * 60)
     os.utime(filename, (new_time, new_time))
コード例 #6
0
ファイル: test_avatars.py プロジェクト: UPCnet/max
    def test_avatar_folder_with_context(self):
        """
            Given a base folder
            And a context with no extra params
            Then the subfolder contains the context
        """
        folder = get_avatar_folder(self.folder, 'people')

        expected_folder = '{}/people'.format(self.folder)

        self.assertEqual(folder, expected_folder)
        self.assertFileExists(expected_folder)
コード例 #7
0
ファイル: test_avatars.py プロジェクト: UPCnet/max
    def test_avatar_folder_without_params(self):
        """
            Given a base folder
            And no extra params
            Then there are no subfolders
        """
        folder = get_avatar_folder(self.folder)

        expected_folder = self.folder

        self.assertEqual(folder, expected_folder)
        self.assertFileExists(expected_folder)
コード例 #8
0
ファイル: test_avatars.py プロジェクト: UPCnet/max
    def test_get_user_avatar_large_missing_all(self):
        """
            Given a user without avatar
            When I retrieve the large avatar
            And the large avatars has disappeared
            Then I get the 48x48 version of that avatar
        """
        username = '******'
        self.create_user(username)
        self.upload_user_avatar(username, "avatar.png")

        avatar_folder = get_avatar_folder(self.avatar_folder, 'people', username, size='large')
        os.remove('{}/{}'.format(avatar_folder, username))

        avatar_folder = get_avatar_folder(self.avatar_folder, 'people', username)
        os.remove('{}/{}'.format(avatar_folder, username))

        response = self.testapp.get('/people/%s/avatar/%s' % (username, 'large'), '', {}, status=200)

        self.assertIn('image', response.content_type)
        self.assertIn('image', response.content_type)
        self.assertEqual(self.get_image_dimensions_from(response), (48, 48))
コード例 #9
0
ファイル: test_avatars.py プロジェクト: UPCnet/max
    def test_avatar_folder_with_context_and_id_2(self):
        """
            Given a base folder
            And a context and identifier
            Then the first subfolder contains the context
            And the second subfolder the trimmed identifier correspondint to the context
        """
        folder = get_avatar_folder(self.folder, 'contexts', 'e6847aed3105e85ae603c56eb2790ce85e212997')

        expected_folder = '{}/contexts/e6/84/7a'.format(self.folder)

        self.assertEqual(folder, expected_folder)
        self.assertFileExists(expected_folder)
コード例 #10
0
ファイル: test_avatars.py プロジェクト: UPCnet/max
    def test_avatar_folder_with_context_and_id(self):
        """
            Given a base folder
            And a context and identifier
            Then the first subfolder contains the context
            And the second subfolder the trimmed identifier correspondint to the context
        """
        folder = get_avatar_folder(self.folder, 'people', 'sheldon')

        expected_folder = '{}/people/sh'.format(self.folder)

        self.assertEqual(folder, expected_folder)
        self.assertFileExists(expected_folder)
コード例 #11
0
ファイル: test_avatars.py プロジェクト: UPCnet/max
    def test_avatar_folder_with_context_and_size(self):
        """
            Given a base folder
            And a context and size
            Then the first subfolder contains the context
            And the second subfolder contains the size
        """
        folder = get_avatar_folder(self.folder, 'people', size='large')

        expected_folder = '{}/people/large'.format(self.folder)

        self.assertEqual(folder, expected_folder)
        self.assertFileExists(expected_folder)
コード例 #12
0
ファイル: test_avatars.py プロジェクト: UPCnet/max
    def test_avatar_folder_with_unknown_context_and_id(self):
        """
            Given a base folder
            And a context and identifier
            And there is no identifier splitter for that context
            Then the first subfolder contains the context
            And the identifier is not used

        """
        folder = get_avatar_folder(self.folder, 'unknown', 'sheldon')

        expected_folder = '{}/unknown'.format(self.folder)

        self.assertEqual(folder, expected_folder)
        self.assertFileExists(expected_folder)
コード例 #13
0
ファイル: avatars.py プロジェクト: UPCnet/max
def postUserAvatar(user, request):
    """
        Upload user avatar
    """
    base_folder = request.registry.settings.get('avatar_folder')
    AVATAR_SIZE = (48, 48)
    LARGE_SIZE = (250, 250)

    username = request.matchdict['username']

    if request.content_type != 'multipart/form-data' and \
       len(request.POST.keys()) != 1:
        raise ValidationError('Not supported upload method.')

    file_key = request.POST.keys()[0]
    input_file = request.POST[file_key].file

    # Saving the standard avatar image in png format, resize if needed
    regular_avatar_folder = get_avatar_folder(base_folder, 'people', username)
    file_path = os.path.join(regular_avatar_folder, username)
    input_file.seek(0)
    image = Image.open(input_file)

    avatar = ImageOps.fit(image, AVATAR_SIZE, method=Image.ANTIALIAS, centering=(0, 0))
    avatar.save(file_path, 'PNG')

    # Saving the large avatar image in png format, resize if needed
    large_avatar_folder = get_avatar_folder(base_folder, 'people', username, size='large')
    file_path = os.path.join(large_avatar_folder, username)
    input_file.seek(0)
    image = Image.open(input_file)

    medium = ImageOps.fit(image, LARGE_SIZE, method=Image.ANTIALIAS, centering=(0, 0))
    medium.save(file_path, 'PNG')

    return Response("Uploaded", status_int=201)
コード例 #14
0
ファイル: avatars.py プロジェクト: UPCnet/max
def getConversationUserAvatar(conversation, request):
    """
        Get conversation avatar

        Returns conversation avatar. Public endpoint.
    """
    cid = request.matchdict['id']

    base_folder = request.registry.settings.get('avatar_folder')
    avatar_folder = get_avatar_folder('conversations', cid)

    missing_avatar = os.path.join(base_folder, 'missing-conversation.png')
    conversation_avatar = os.path.join(avatar_folder, cid)
    filename = conversation_avatar if os.path.exists(conversation_avatar) else missing_avatar

    data = open(filename).read()
    image = Response(data, status_int=200)
    image.content_type = 'image/png'
    return image
コード例 #15
0
ファイル: test_avatars.py プロジェクト: UPCnet/max
    def test_get_context_twitter_download_avatar(self):
        """
            Given a context with twitter username
            When i retrieve the context's avatar
            Then the twitter's user avatar is downloaded and stored
        """
        from hashlib import sha1
        from .mockers import create_context_full

        avatar_image = os.path.join(self.conf_dir, "avatar.png")
        http_mock_twitter_user_image(avatar_image)

        self.testapp.post('/contexts', json.dumps(create_context_full), oauth2Header(test_manager), status=201)
        url_hash = sha1(create_context_full['url']).hexdigest()

        response = self.testapp.get('/contexts/%s/avatar' % url_hash, '', {}, status=200)

        self.assertEqual(self.get_image_dimensions_from(response), (98, 98))
        avatar_folder = get_avatar_folder(self.avatar_folder, 'contexts', url_hash)
        self.assertFileExists(os.path.join(avatar_folder, url_hash))
コード例 #16
0
    if not excluded(filename):
        name = ''
        context = ''
        if SHA1_REGEX.match(filename):
            name = SHA1_REGEX.match(filename).groups()[0]
            context = 'contexts'
            size = ''
        elif OBJECT_ID_REGEX.match(filename):
            name = OBJECT_ID_REGEX.match(filename).groups()[0]
            context = 'conversations'
            size = ''
        elif USER_REGEX.match(filename):
            name, size = USER_REGEX.match(filename).groups()
            context = 'people'
            size = '' if size is None else size

        if name:
            avatar_folder = get_avatar_folder(os.getcwd(), context, name, size)
            new_filename = os.path.join(avatar_folder, name)

            shutil.move(filename, new_filename)
            print "MOVED {} --> {}".format(filename, new_filename)
        else:
            exclusions.append(filename)
    else:
        exclusions.append(filename)

print
for filename in exclusions:
    print 'EXCLUDED {}'.format(filename)
コード例 #17
0
ファイル: organize_avatars.py プロジェクト: UPCnet/maxserver
    if not excluded(filename):
        name = ''
        context = ''
        if SHA1_REGEX.match(filename):
            name = SHA1_REGEX.match(filename).groups()[0]
            context = 'contexts'
            size = ''
        elif OBJECT_ID_REGEX.match(filename):
            name = OBJECT_ID_REGEX.match(filename).groups()[0]
            context = 'conversations'
            size = ''
        elif USER_REGEX.match(filename):
            name, size = USER_REGEX.match(filename).groups()
            context = 'people'
            size = '' if size is None else size

        if name:
            avatar_folder = get_avatar_folder(os.getcwd(), context, name, size)
            new_filename = os.path.join(avatar_folder, name)

            shutil.move(filename, new_filename)
            print "MOVED {} --> {}".format(filename, new_filename)
        else:
            exclusions.append(filename)
    else:
        exclusions.append(filename)

print
for filename in exclusions:
    print 'EXCLUDED {}'.format(filename)