Beispiel #1
0
    def create_partner(self):
        """Create a new random partner"""
        partner = Partner()

        partner.is_active = random.random() < 0.75
        partner.name = "{} {}".format(_faker.company(),
                                      _faker.company_suffix())
        partner.slug = _faker.slug()
        partner.link = _faker.uri()

        igen = IconGenerator(5, 5)  # 5x5 blocks
        icon = igen.generate(
            partner.name,
            480,
            480,
            padding=(10, 10, 10, 10),
            output_format="jpeg",
        )  # 620x620 pixels, with 10 pixels padding on each side
        partner.logo.save(partner.name + ".jpeg", ContentFile(icon))

        partner.address = _faker.street_address()
        partner.zip_code = _faker.postcode()
        partner.city = _faker.city()

        partner.save()
Beispiel #2
0
    def create_vacancy(self, partners, categories):
        """
        Create a new random vacancy

        :param partners: the partners to choose a partner from
        :param categories: the categories to choose this vacancy from
        """
        vacancy = Vacancy()

        vacancy.title = _faker.job()
        vacancy.description = _faker.paragraph(nb_sentences=10)
        vacancy.link = _faker.uri()

        if random.random() < 0.75:
            vacancy.partner = random.choice(partners)
        else:
            vacancy.company_name = "{} {}".format(_faker.company(),
                                                  _faker.company_suffix())
            igen = IconGenerator(5, 5)  # 5x5 blocks
            icon = igen.generate(
                vacancy.company_name,
                480,
                480,
                padding=(10, 10, 10, 10),
                output_format="jpeg",
            )  # 620x620 pixels, with 10 pixels padding on each side
            vacancy.company_logo.save(vacancy.company_name + ".jpeg",
                                      ContentFile(icon))

        vacancy.save()

        vacancy.categories.set(
            random.sample(list(categories), random.randint(0, 3)))
Beispiel #3
0
    def create_member_group(self, group_model):
        """
        Create a MemberGroup
        """
        members = Member.objects.all()
        if len(members) < 6:
            self.stdout.write("Your database does not contain 6 users.")
            self.stdout.write(f"Creating {6 - len(members)} more users.")
            for __ in range(6 - len(members)):
                self.create_user()
            members = Member.objects.all()

        member_group = group_model()

        member_group.name_nl = _generate_title()
        member_group.name_en = member_group.name_nl
        member_group.description_nl = _faker.paragraph()
        member_group.description_en = _faker.paragraph()

        igen = IconGenerator(5, 5)  # 5x5 blocks
        icon = igen.generate(
            member_group.name_nl,
            480,
            480,
            padding=(10, 10, 10, 10),
            output_format="jpeg",
        )  # 620x620 pixels, with 10 pixels padding on each side
        member_group.photo.save(member_group.name_nl + ".jpeg",
                                ContentFile(icon))

        member_group.since = _faker.date_time_between("-10y", "+30d")

        if random.random() < 0.1:
            now = date.today()
            month = timedelta(days=30)
            member_group.until = _faker.date_time_between_dates(
                member_group.since, now + 2 * month).date()

        member_group.active = random.random() < 0.9
        member_group.contact_email = _faker.safe_email()

        member_group.save()

        # Add members
        committee_members = random.sample(list(members), random.randint(2, 6))
        for member in committee_members:
            self.create_member_group_membership(member, member_group)

        # Make one member the chair
        chair = random.choice(member_group.membergroupmembership_set.all())
        chair.until = None
        chair.chair = True
        chair.save()
    def create_board(self, lecture_year):
        """
        Create a new board

        :param int lecture_year: the  lecture year this board was active
        """
        self.stdout.write("Creating a board")
        members = Member.objects.all()
        if len(members) < 6:
            self.stdout.write("Your database does not contain 6 users.")
            self.stdout.write(f"Creating {6 - len(members)} more users.")
            for __ in range(6 - len(members)):
                self.create_user()

        board = Board()

        board.name = "Board {}-{}".format(lecture_year, lecture_year + 1)
        while Board.objects.filter(name=board.name).exists():
            lecture_year = lecture_year - 1
            board.name = "Board {}-{}".format(lecture_year, lecture_year + 1)

        board.description = _faker.paragraph()

        igen = IconGenerator(5, 5)  # 5x5 blocks
        icon = igen.generate(
            board.name,
            480,
            480,
            padding=(10, 10, 10, 10),
            output_format="jpeg"
        )  # 620x620 pixels, with 10 pixels padding on each side
        board.photo.save(f"{board.name}.jpeg", ContentFile(icon))

        board.since = date(year=lecture_year, month=9, day=1)
        board.until = date(year=lecture_year + 1, month=8, day=31)
        board.active = True
        board.contact_email = _faker.safe_email()

        board.save()

        # Add members
        board_members = random.sample(list(members), random.randint(5, 6))
        for member in board_members:
            self.create_member_group_membership(member, board)

        # Make one member the chair
        chair = random.choice(board.membergroupmembership_set.all())
        chair.until = None
        chair.chair = True
        chair.save()
    def test_generate_inverted_ascii(self, generate_ascii_mock):
        """
        Tests if the foreground and background are properly inverted when
        generating ASCII "images".
        """

        # Set-up some test data.
        data = "Some test data"

        # Set-up one foreground and background colour. These are not used for
        # ASCII itself (instead a plus/minus sign is used).
        foreground = "#ffffff"
        background = "#000000"

        # Set-up the generator.
        generator = Generator(5, 5, foreground=[foreground], background=background)

        # Verify that foreground/background is picked correctly when no
        # inverstion is requsted.
        generator.generate(data, 200, 200, inverted=False, output_format="ascii")
        generate_ascii_mock.assert_called_with(mock.ANY, "+", "-")

        # Verify that foreground/background is picked correctly when inversion
        # is requsted.
        generator.generate(data, 200, 200, inverted=True, output_format="ascii")
        generate_ascii_mock.assert_called_with(mock.ANY, "-", "+")
    def test_generate_matrix(self):
        """
        Verifies that the matrix is generated correctly based on passed hashed
        bytes.
        """

        # The resulting half-matrix should be as follows (first byte is for
        # ignored in matrix generation):
        #
        # 100
        # 011
        # 100
        # 001
        # 110
        hash_bytes = [0b11111111, 0b10101010, 0b01010101]

        expected_matrix = [
            [True, False, False, False, True],
            [False, True, True, True, False],
            [True, False, False, False, True],
            [False, False, True, False, False],
            [True, True, False, True, True],
            ]

        generator = Generator(5, 5)

        matrix = generator._generate_matrix(hash_bytes)

        self.assertEqual(matrix, expected_matrix)
Beispiel #7
0
def get_default_image():
    # TODO: change the random generator
    width = 200
    height = 200
    padding = [20, 20, 20, 20]
    foreground = [
        "rgb(45,79,255)", "rgb(254,180,44)", "rgb(226,121,234)",
        "rgb(30,179,253)", "rgb(232,77,65)", "rgb(49,203,115)",
        "rgb(141,69,170)"
    ]
    background = "rgb(224,224,224)"
    generator = Generator(5, 5, foreground=foreground, background=background)
    basestr = strftime("%H-%M-%S", gmtime()) + "-" + str(random.uniform(0, 59))
    raw_image = generator.generate(basestr, width, height, padding=padding)
    image_stream = BytesIO(raw_image)
    image = PIL.Image.open(image_stream)
    image_io = BytesIO()
    image.save(image_io, format='PNG')

    # Create a new Django file-like object to be used in models as ImageField using
    # InMemoryUploadedFile.  If you look at the source in Django, a
    # SimpleUploadedFile is essentially instantiated similarly to what is shown here
    image__in_memory_uploaded_file = InMemoryUploadedFile(
        image_io, None, 'avatar.png', 'image/png', image_io.seek(0, SEEK_END),
        None)
    # give your file to InMemoryUploadedFile to create django imagefield object
    return image__in_memory_uploaded_file
    def test_generate_ascii(self):
        """
        Tests the generated identicon in ASCII format.
        """

        # Set-up parameters that will be used for generating the image.
        foreground = "1"
        background = "0"
        matrix = [
            [0, 0, 1, 0, 0],
            [0, 0, 1, 0, 0],
            [0, 0, 1, 0, 0],
            [0, 1, 1, 1, 0],
            [0, 1, 1, 1, 0],
            ]

        # Set-up a generator.
        generator = Generator(5, 5)

        # Generate the ASCII image.
        ascii_image = generator._generate_ascii(matrix, foreground, background)

        # Verify that the result is as expected.
        expected_result = """00100
00100
00100
01110
01110"""
        self.assertEqual(ascii_image, expected_result)
Beispiel #9
0
    def test_generate_format(self):
        """
        Tests if identicons are generated in requested format.
        """

        # Set-up a generator.
        generator = Generator(5, 5)

        # Set-up some test data.
        data = "some test data"

        # Verify that PNG image is returned when requested.
        raw_image = generator.generate(data, 200, 200, output_format="png")
        image_stream = BytesIO(raw_image)
        image = PIL.Image.open(image_stream)
        self.assertEqual(image.format, "PNG")

        # Verify that JPEG image is returned when requested.
        raw_image = generator.generate(data, 200, 200, output_format="jpeg")
        image_stream = BytesIO(raw_image)
        image = PIL.Image.open(image_stream)
        self.assertEqual(image.format, "JPEG")

        # Verify that GIF image is returned when requested.
        raw_image = generator.generate(data, 200, 200, output_format="gif")
        image_stream = BytesIO(raw_image)
        image = PIL.Image.open(image_stream)
        self.assertEqual(image.format, "GIF")

        # Verify that ASCII "image" is returned when requested.
        raw_image = generator.generate(data, 200, 200, output_format="ascii")
        self.assertIsInstance(raw_image, str)
Beispiel #10
0
    def create_user(self):
        """Create a new random user"""
        self.stdout.write("Creating a user")

        fakeprofile = _faker.profile()
        fakeprofile["password"] = "".join(
            random.choice(string.ascii_uppercase + string.digits)
            for _ in range(16))
        user = get_user_model().objects.create_user(fakeprofile["username"],
                                                    fakeprofile["mail"],
                                                    fakeprofile["password"])
        user.first_name = fakeprofile["name"].split()[0]
        user.last_name = " ".join(fakeprofile["name"].split()[1:])

        profile = _ProfileFactory()
        profile.user_id = user.id
        profile.birthday = fakeprofile["birthdate"]
        profile.website = fakeprofile["website"][0]

        igen = IconGenerator(5, 5)  # 5x5 blocks
        icon = igen.generate(
            user.username,
            480,
            480,
            padding=(10, 10, 10, 10),
            output_format="jpeg",
        )  # 620x620 pixels, with 10 pixels padding on each side
        profile.photo.save(fakeprofile["username"] + ".jpeg",
                           ContentFile(icon))

        membership = Membership()
        membership.user_id = user.id
        membership.since = _faker.date_time_between(start_date="-4y",
                                                    end_date="now",
                                                    tzinfo=None)
        membership.until = random.choice([
            _faker.date_time_between(start_date=membership.since,
                                     end_date="+2y",
                                     tzinfo=None),
            None,
        ])
        membership.type = random.choice(
            [t[0] for t in Membership.MEMBERSHIP_TYPES])

        user.save()
        profile.save()
        membership.save()
    def test_generate_png_compare(self):
        """
        Tests generated PNG identicon against a set of pre-generated samples.
        """

        # Set-up a list of foreground colours (taken from Sigil). Same as used
        # for reference images.
        foreground = ["rgb(45,79,255)",
                      "rgb(254,180,44)",
                      "rgb(226,121,234)",
                      "rgb(30,179,253)",
                      "rgb(232,77,65)",
                      "rgb(49,203,115)",
                      "rgb(141,69,170)"]

        # Set-up a background colour (taken from Sigil). Same as used for
        # reference images.
        background = "rgb(224,224,224)"

        # Set-up parameters equivalent as used for samples.
        width = 200
        height = 200
        padding = (20, 20, 20, 20)

        # Load the reference images, making sure they're in RGB mode.
        test1_ref = PIL.Image.open("tests/samples/test1.png").convert(mode="RGB")
        test2_ref = PIL.Image.open("tests/samples/test2.png").convert(mode="RGB")
        test3_ref = PIL.Image.open("tests/samples/test3.png").convert(mode="RGB")

        # Set-up the Generator.
        generator = Generator(5, 5, foreground=foreground, background=background)

        # Generate first test identicon.
        raw_image = generator.generate("test1", width, height, padding=padding)
        image_stream = BytesIO(raw_image)
        test1 = PIL.Image.open(image_stream)

        # Generate second test identicon.
        raw_image = generator.generate("test2", width, height, padding=padding)
        image_stream = BytesIO(raw_image)
        test2 = PIL.Image.open(image_stream)

        # Generate third test identicon.
        raw_image = generator.generate("test3", width, height, padding=padding)
        image_stream = BytesIO(raw_image)
        test3 = PIL.Image.open(image_stream)

        # Calculate differences between generated identicons and references.
        diff1 = PIL.ImageChops.difference(test1, test1_ref)
        diff2 = PIL.ImageChops.difference(test2, test2_ref)
        diff3 = PIL.ImageChops.difference(test3, test3_ref)

        # Verify that all the diffs are essentially black (i.e. no differences
        # between generated identicons and reference samples).
        expected_extrema = ((0, 0), (0, 0), (0, 0))

        self.assertEqual(diff1.getextrema(), expected_extrema)
        self.assertEqual(diff2.getextrema(), expected_extrema)
        self.assertEqual(diff3.getextrema(), expected_extrema)
 def __init__(self):
     Resource.__init__(self)
     self.generator = Generator(
         SIZE,
         SIZE,
         foreground=FOREGROUND,
         background=BACKGROUND,
     )
Beispiel #13
0
    def create_photo(self, album):
        photo = Photo()

        photo.album = album

        name = _generate_title()

        igen = IconGenerator(5, 5)  # 5x5 blocks
        icon = igen.generate(
            name,
            480,
            480,
            padding=(10, 10, 10, 10),
            output_format="jpeg",
        )  # 620x620 pixels, with 10 pixels padding on each side
        photo.file.save(f"{name}.jpeg", ContentFile(icon))

        photo.save()
    def test_get_bit(self):
        """
        Tests if the check whether bit is 1 or 0 is performed correctly.
        """

        generator = Generator(5, 5)
        hash_bytes = [0b10010001, 0b10001000, 0b00111001]

        # Check a couple of bits from the above hash bytes.
        self.assertEqual(True, generator._get_bit(0, hash_bytes))
        self.assertEqual(True, generator._get_bit(7, hash_bytes))
        self.assertEqual(False, generator._get_bit(22, hash_bytes))
        self.assertEqual(True, generator._get_bit(23, hash_bytes))
    def test_generate_format_invalid(self):
        """
        Tests if an exception is raised in case an unsupported format is
        requested when generating the identicon.
        """

        # Set-up a generator.
        generator = Generator(5, 5)

        # Set-up some test data.
        data = "some test data"

        # Verify that an exception is raised in case of unsupported format.
        self.assertRaises(ValueError, generator.generate, data, 200, 200, output_format="invalid")
    def test_init_parameters(self):
        """
        Verifies that the constructor sets-up the instance properties correctly.
        """

        generator = Generator(5, 5, digest=hashlib.sha1, foreground=["#111111", "#222222"], background="#aabbcc")

        # sha1 provides 160 bits of entropy - 20 bytes.
        self.assertEqual(generator.digest_entropy, 20 * 8)
        self.assertEqual(generator.digest, hashlib.sha1)
        self.assertEqual(generator.rows, 5)
        self.assertEqual(generator.columns, 5)
        self.assertEqual(generator.foreground, ["#111111", "#222222"])
        self.assertEqual(generator.background, "#aabbcc")
    def test_data_to_digest_byte_list_hex(self):
        """
        Test if correct digest byte list is returned for passed hex digest
        string.
        """

        # Set-up some test hex digest (md5), and expected result.
        hex_digest = "e19c1283c925b3206685ff522acfe3e6"
        expected_digest_byte_list = [225, 156, 18, 131, 201, 37, 179, 32, 102, 133, 255, 82, 42, 207, 227, 230]

        # Instantiate a generator.
        generator = Generator(5, 5, digest=hashlib.md5)

        # Call the method and get the results.
        digest_byte_list = generator._data_to_digest_byte_list(hex_digest)

        # Verify the expected and actual result are identical.
        self.assertEqual(expected_digest_byte_list, digest_byte_list)
    def test_data_to_digest_byte_list_hex_lookalike(self):
        """
        Test if correct digest byte list is returned for passed raw data that
        has same length as hex digest string.
        """

        # Set-up some test hex digest (md5), and expected result.
        data = "qqwweerrttyyuuiiooppaassddffgghh"
        expected_digest_byte_list = [25, 182, 52, 218, 118, 220, 26, 145, 164, 222, 33, 221, 183, 140, 98, 246]

        # Instantiate a generator.
        generator = Generator(5, 5, digest=hashlib.md5)

        # Call the method and get the results.
        digest_byte_list = generator._data_to_digest_byte_list(data)

        # Verify the expected and actual result are identical.
        self.assertEqual(expected_digest_byte_list, digest_byte_list)
    def test_data_to_digest_byte_list_raw(self):
        """
        Test if correct digest byte list is returned for raw (non-hex-digest)
        data passed to the method.
        """

        # Set-up some raw data, and set-up the expected result.
        data = "this is a test\n"
        expected_digest_byte_list = [225, 156, 18, 131, 201, 37, 179, 32, 102, 133, 255, 82, 42, 207, 227, 230]

        # Instantiate a generator.
        generator = Generator(5, 5, digest=hashlib.md5)

        # Call the method and get the results.
        digest_byte_list = generator._data_to_digest_byte_list(data)

        # Verify the expected and actual result are identical.
        self.assertEqual(expected_digest_byte_list, digest_byte_list)
    def test_generate_png_basics(self):
        """
        Tests some basics about generated PNG identicon image. This includes:

        - Dimensions of generated image.
        - Format of generated image.
        - Mode of generated image.
        """

        # Set-up parameters that will be used for generating the image.
        width = 200
        height = 200
        padding = [20, 20, 20, 20]
        foreground = "#ffffff"
        background = "#000000"
        matrix = [
            [0, 0, 1, 0, 0],
            [0, 0, 1, 0, 0],
            [0, 0, 1, 0, 0],
            [0, 1, 1, 1, 0],
            [0, 1, 1, 1, 0],
            ]

        # Set-up a generator.
        generator = Generator(5, 5)

        # Generate the raw image.
        raw_image = generator._generate_png(matrix, width, height, padding, foreground, background)

        # Try to load the raw image.
        image_stream = BytesIO(raw_image)
        image = PIL.Image.open(image_stream)

        # Verify image size, format, and mode.
        self.assertEqual(image.size[0], 240)
        self.assertEqual(image.size[1], 240)
        self.assertEqual(image.format, "PNG")
        self.assertEqual(image.mode, "RGB")
    def test_generate_inverted_png(self, generate_png_mock):
        """
        Tests if the foreground and background are properly inverted when
        generating PNG images.
        """

        # Set-up some test data.
        data = "Some test data"

        # Set-up one foreground and background colour.
        foreground = "#ffffff"
        background = "#000000"

        # Set-up the generator.
        generator = Generator(5, 5, foreground=[foreground], background=background)

        # Verify that colours are picked correctly when no inverstion is requsted.
        generator.generate(data, 200, 200, inverted=False, output_format="png")
        generate_png_mock.assert_called_with(mock.ANY, mock.ANY, mock.ANY, mock.ANY, foreground, background)

        # Verify that colours are picked correctly when inversion is requsted.
        generator.generate(data, 200, 200, inverted=True, output_format="png")
        generate_png_mock.assert_called_with(mock.ANY, mock.ANY, mock.ANY, mock.ANY, background, foreground)
    def test_generate_foreground(self, generate_png_mock):
        """
        Tests if the foreground colour is picked correctly.
        """

        # Set-up some foreground colours and a single background colour.
        foreground = ["#000000", "#111111", "#222222", "#333333", "#444444", "#555555"]
        background = "#ffffff"

        # Set-up the generator.
        generator = Generator(5, 5, foreground=foreground, background=background)

        # The first byte of hex digest should be 121 for this data, which should
        # result in foreground colour of index '1'.
        data = "some test data"
        generator.generate(data, 200, 200)
        generate_png_mock.assert_called_with(mock.ANY, mock.ANY, mock.ANY, mock.ANY, foreground[1], background)

        # The first byte of hex digest should be 149 for this data, which should
        # result in foreground colour of index '5'.
        data = "some other test data"
        generator.generate(data, 200, 200)
        generate_png_mock.assert_called_with(mock.ANY, mock.ANY, mock.ANY, mock.ANY, foreground[5], background)
Beispiel #23
0
def get_avatar(md5):
    image = None

    # fetch image from redis or ldap
    if redis_store.exists(md5):
        user_dn = redis_store.get(md5)
        dn_sha1hex = hashlib.sha1(user_dn).hexdigest()

        try:
            if redis_store.exists(dn_sha1hex):
                image = _get_image_from_redis(dn_sha1hex)
            else:
                image = _get_image_from_ldap(user_dn.decode(), dn_sha1hex)

                # cache image on redis
                if current_app.config.get("AVATAR_CACHE", True):
                    img_ttl = current_app.config["AVATAR_TTL"]
                    redis_store.hset(dn_sha1hex, "raw", image)
                    redis_store.expire(dn_sha1hex, img_ttl)

                image = Image.open(BytesIO(image))
        except OSError:
            current_app.logger.warning(
                "Cannot read image of {0}".format(user_dn))
    else:
        current_app.logger.warning("MD5 {0} not in redis.".format(md5))

    # default image
    if image is None:
        default_args = ["d", "default"]
        default_image = current_app.config["AVATAR_DEFAULT_IMAGE"]
        keyword = _get_argval_from_request(default_args, default_image)
        static_images = current_app.config["AVATAR_STATIC_IMAGES"]
        static_path = current_app.config["AVATAR_STATIC"]
        identicon_enable = current_app.config["AVATAR_IDENTICON_ENABLE"]
        identicon_cache = current_app.config["AVATAR_IDENTICON_CACHE"]

        if identicon_enable == "true" and keyword == "identicon":
            redis_key = md5 + "-identicon"

            # fetch image from redis
            if identicon_cache == "true" and redis_store.exists(redis_key):
                image = _get_image_from_redis(redis_key)
            else:
                generator = Generator(
                    int(current_app.config["AVATAR_IDENTICON_SIZE"]),
                    int(current_app.config["AVATAR_IDENTICON_SIZE"]),
                    foreground=current_app.
                    config["AVATAR_IDENTICON_FOREGROUND"],
                    background=current_app.
                    config["AVATAR_IDENTICON_BACKGROUND"],
                )
                image = generator.generate(
                    md5,
                    int(current_app.config["AVATAR_MAX_SIZE"]),
                    int(current_app.config["AVATAR_MAX_SIZE"]),
                    padding=(0, -4, 0, -4),
                )

                # cache image on redis
                if identicon_cache == "true":
                    img_ttl = current_app.config["AVATAR_TTL"]
                    redis_store.hset(redis_key, "raw", image)
                    redis_store.expire(redis_key, img_ttl)

                image = Image.open(BytesIO(image))

        elif keyword not in static_images or keyword == "404":
            abort(404)
        else:
            image = Image.open(
                os.path.join(static_path, static_images[keyword]))

    # sizes
    default_size = int(current_app.config["AVATAR_DEFAULT_SIZE"])
    size = _get_argval_from_request(["s", "size"], default_size)
    width = _get_argval_from_request(["w", "width"], default_size)
    height = _get_argval_from_request(["h", "height"], default_size)

    # resize methods
    default_method = current_app.config["AVATAR_DEFAULT_METHOD"]
    resize_method = _get_argval_from_request(["m", "method"], default_method)
    if resize_method not in RESIZE_METHODS:
        resize_method = default_method

    if width == default_size and size != default_size:
        width = size
    if height == default_size and size != default_size:
        height = size

    if resize_method in ["crop", "cover", "contain", "thumbnail"]:
        size = (_max_size(width), _max_size(height))
    elif resize_method == "width":
        size = _max_size(width)
    elif resize_method == "height":
        size = _max_size(height)

    buffer_image = BytesIO()

    try:
        resized_image = resizeimage.resize(resize_method, image, size)
    except resizeimage.ImageSizeError:
        if resize_method in ["width", "height"]:
            resized_image = image
        else:
            size = image.height if image.height > image.width else image.width
            size = (size, size)
            resized_image = resizeimage.resize(resize_method, image, size)

    resized_image.save(buffer_image, image.format, quality=95)
    buffer_image.seek(0)

    mimetypes.init()
    mimetype = mimetypes.types_map["." + image.format.lower()]
    return send_file(buffer_image, mimetype=mimetype)
Beispiel #24
0
def image(request, data):
    """
    Generates identicon image based on passed data.

    Arguments:

      data - Data which should be used for generating an identicon. This data
      will be used in order to create a digest which is used for generating the
      identicon. If the data passed is a hex digest already, the digest will be
      used as-is.

    Returns:

      Identicon image in raw format.
    """

    # Get image width, height, padding, and format from GET parameters, or
    # fall-back to default values from settings.
    try:
        width = int(request.GET.get("w", PYDENTICON_WIDTH))
    except ValueError:
        raise SuspiciousOperation(
            "Identicon width must be a positive integer.")
    try:
        height = int(request.GET.get("h", PYDENTICON_HEIGHT))
    except ValueError:
        raise SuspiciousOperation(
            "Identicon height must be a positive integer.")
    output_format = request.GET.get("f", PYDENTICON_FORMAT)
    try:
        padding = [int(p) for p in request.GET["p"].split(",")]
    except KeyError:
        padding = PYDENTICON_PADDING
    except ValueError:
        raise SuspiciousOperation(
            "Identicon padding must consist out of 4 positive integers separated with commas."
        )
    if "i" in request.GET:
        inverted = request.GET.get("i")
        if inverted.lower() == "true":
            inverted = True
        elif inverted.lower() == "false":
            inverted = False
        else:
            raise SuspiciousOperation(
                "Inversion parameter must be a boolean (true/false).")
    else:
        inverted = PYDENTICON_INVERT

    # Validate the input parameters.
    if not isinstance(width, int) or width <= 0:
        raise SuspiciousOperation(
            "Identicon width must be a positive integer.")
    if not isinstance(height, int) or height <= 0:
        raise SuspiciousOperation(
            "Identicon height must be a positive integer.")
    if not all([isinstance(p, int) and p >= 0
                for p in padding]) or len(padding) != 4:
        raise SuspiciousOperation(
            "Padding must be a 4-element tuple consisting out of positive integers."
        )

    # Set-up correct content type based on requested identicon format.
    if output_format == "png":
        content_type = "image/png"
    elif output_format == "ascii":
        content_type = "text/plain"
    else:
        raise SuspiciousOperation(
            "Unsupported identicon format requested - '%s' % output_format")

    # Initialise a generator.
    generator = Generator(PYDENTICON_ROWS,
                          PYDENTICON_COLUMNS,
                          foreground=PYDENTICON_FOREGROUND,
                          background=PYDENTICON_BACKGROUND,
                          digest=PYDENTICON_DIGEST)

    # Generate the identicion.
    content = generator.generate(data,
                                 width,
                                 height,
                                 padding=padding,
                                 output_format=output_format,
                                 inverted=inverted)

    # Create and return the response.
    response = HttpResponse(content, content_type=content_type)

    return response
Beispiel #25
0
def get_avatar(md5):
    image = None

    # fetch image from redis or ldap
    if redis_store.exists(md5):
        user_dn = redis_store.get(md5)
        dn_sha1hex = hashlib.sha1(user_dn).hexdigest()

        try:
            if redis_store.exists(dn_sha1hex):
                image = _get_image_from_redis(dn_sha1hex)
            else:
                image = _get_image_from_ldap(user_dn.decode(), dn_sha1hex)

                # cache image on redis
                if current_app.config.get('AVATAR_CACHE', True):
                    img_ttl = current_app.config['AVATAR_TTL']
                    redis_store.hset(dn_sha1hex, 'raw', image)
                    redis_store.expire(dn_sha1hex, img_ttl)

                image = Image.open(BytesIO(image))
        except OSError:
            current_app.logger.warning(
                'Cannot read image of {0}'.format(user_dn))
    else:
        current_app.logger.warning('MD5 {0} not in redis.'.format(md5))

    # default image
    if image is None:
        default_args = ['d', 'default']
        default_image = current_app.config['AVATAR_DEFAULT_IMAGE']
        keyword = _get_argval_from_request(default_args, default_image)
        static_images = current_app.config['AVATAR_STATIC_IMAGES']
        static_path = current_app.config['AVATAR_STATIC']
        identicon_enable = current_app.config['AVATAR_IDENTICON_ENABLE']
        identicon_cache = current_app.config['AVATAR_IDENTICON_CACHE']

        if identicon_enable == 'true' and keyword == 'identicon':
            redis_key = md5 + "-identicon"

            # fetch image from redis
            if identicon_cache == 'true' and redis_store.exists(redis_key):
                image = _get_image_from_redis(redis_key)
            else:
                generator = Generator(
                    int(current_app.config['AVATAR_IDENTICON_SIZE']),
                    int(current_app.config['AVATAR_IDENTICON_SIZE']),
                    foreground=current_app.
                    config['AVATAR_IDENTICON_FOREGROUND'],
                    background=current_app.
                    config['AVATAR_IDENTICON_BACKGROUND'])
                image = generator.generate(
                    md5,
                    int(current_app.config['AVATAR_MAX_SIZE']),
                    int(current_app.config['AVATAR_MAX_SIZE']),
                    padding=(0, -4, 0, -4))

                # cache image on redis
                if identicon_cache == 'true':
                    img_ttl = current_app.config['AVATAR_TTL']
                    redis_store.hset(redis_key, 'raw', image)
                    redis_store.expire(redis_key, img_ttl)

                image = Image.open(BytesIO(image))

        elif keyword not in static_images or keyword == '404':
            abort(404)
        else:
            image = Image.open(
                os.path.join(static_path, static_images[keyword]))

    # sizes
    default_size = int(current_app.config['AVATAR_DEFAULT_SIZE'])
    size = _get_argval_from_request(['s', 'size'], default_size)
    width = _get_argval_from_request(['w', 'width'], default_size)
    height = _get_argval_from_request(['h', 'height'], default_size)

    # resize methods
    default_method = current_app.config['AVATAR_DEFAULT_METHOD']
    resize_method = _get_argval_from_request(['m', 'method'], default_method)
    if resize_method not in RESIZE_METHODS:
        resize_method = default_method

    if width == default_size and size != default_size:
        width = size
    if height == default_size and size != default_size:
        height = size

    if resize_method in ['crop', 'cover', 'contain', 'thumbnail']:
        size = (_max_size(width), _max_size(height))
    elif resize_method == 'width':
        size = _max_size(width)
    elif resize_method == 'height':
        size = _max_size(height)

    buffer_image = BytesIO()

    try:
        resized_image = resizeimage.resize(resize_method, image, size)
    except resizeimage.ImageSizeError:
        if resize_method in ['width', 'height']:
            resized_image = image
        else:
            size = image.height if image.height > image.width else image.width
            size = (size, size)
            resized_image = resizeimage.resize(resize_method, image, size)

    resized_image.save(buffer_image, image.format, quality=95)
    buffer_image.seek(0)

    mimetypes.init()
    mimetype = mimetypes.types_map['.' + image.format.lower()]
    return send_file(buffer_image, mimetype=mimetype)
Beispiel #26
0
except Exception as e:
    pass

from flask import Flask
import config

app = Flask('phobook')
app.config.from_object('config')

# Handling OPTION Method request for cross site
from flask_cors import CORS, cross_origin
cors = CORS(app, resources={r"/*":{"origins":"*"}})

# Identicon generator
from pydenticon import Generator
pydent = Generator(8, 8)

from app.db import init_db, db_session
init_db()

from app.login import *


@app.teardown_appcontext
def shutdown_session(exception):
    db_session.remove()

from app.controller import routes
routes(app)

from flask_socketio import SocketIO