File size: 4,567 Bytes
1b7e88c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import base64
import os
import platform
from collections import OrderedDict
from io import BytesIO
from pathlib import Path
from typing import Sequence

import requests
from PIL import Image


class LRUCache:
    # initializing capacity
    def __init__(self, capacity: int):
        self.cache = OrderedDict()
        self.capacity = capacity

    def has(self, key) -> bool:
        return key in self.cache

    # we return the value of the key
    # that is queried in O(1) and return -1 if we
    # don't find the key in out dict / cache.
    # And also move the key to the end
    # to show that it was recently used.
    def get(self, key, default=None):
        if key not in self.cache:
            return default
        else:
            self.cache.move_to_end(key)
            return self.cache[key]

    # first, we add / update the key by conventional methods.
    # And also move the key to the end to show that it was recently used.
    # But here we will also check whether the length of our
    # ordered dictionary has exceeded our capacity,
    # If so we remove the first key (least recently used)
    def put(self, key, value) -> None:
        self.cache[key] = value
        self.cache.move_to_end(key)
        if len(self.cache) > self.capacity:
            self.cache.popitem(last=False)

    def pop(self, key, value):
        self.cache.pop(key, None)


def handle_response(res, json, url):
    if res.status_code < 299:
        return res.json()
    elif res.status_code == 404:
        logging.error("Request URL: {} | Error[404]: 请求错误: 错误的地址".format(url))
        raise VQLError(516)
    elif res.status_code == 422:
        logging.error(
            "Request URL: {} | Request body: {} | Error[422]: 请求错误: 错误的请求格式".format(
                url, json
            )
        )
        raise VQLError(517)
    else:
        info = res.json()
        logging.error(
            "Request URL: {} | Request body: {} | Error: {}".format(url, json, info)
        )
        raise VQLError(511, detail=info)


def chunks(l: Sequence, win_len: int, stride_len: int):
    s_id = 0
    e_id = min(len(l), win_len)

    while True:
        yield l[s_id:e_id]

        if e_id == len(l):
            break

        s_id = s_id + stride_len
        e_id = min(s_id + win_len, len(l))


def encode_image(input):
    def _encode(img):
        output_buffer = BytesIO()
        img.save(output_buffer, format="JPEG")
        byte_data = output_buffer.getvalue()
        base64_str = base64.b64encode(byte_data)
        base64_str = str(base64_str, encoding="utf-8")
        return base64_str

    input = input.convert("RGB")
    if isinstance(input, list):
        res = []
        for img in input:
            res.append(_encode(img))
        return res
    else:
        return _encode(input)


def get_platform() -> str:
    """Get platform."""
    system = platform.system()
    if system == "Darwin":
        return "MacOS"
    return system


def read_image(input_source) -> Image.Image:
    """
    Read an image from a local path, URL, PIL Image object, or Path object.

    Args:
        input_source (str or PIL.Image.Image or Path): The source of the image.
            Can be a local file path, a URL, a PIL Image object, or a Path object.

    Returns:
        PIL.Image.Image: The image as a PIL Image object.

    Raises:
        ValueError: If the input source is invalid or the image cannot be read.
    """
    if isinstance(input_source, Image.Image):
        return input_source

    if isinstance(input_source, (str, Path)):
        if isinstance(input_source, str) and input_source.startswith(
            ("http://", "https://")
        ):
            # URL
            try:
                response = requests.get(input_source)
                response.raise_for_status()
                return Image.open(BytesIO(response.content))
            except requests.RequestException as e:
                raise ValueError(f"Failed to fetch image from URL: {e}")
        elif os.path.isfile(str(input_source)):
            # Local file path or Path object
            try:
                return Image.open(input_source)
            except IOError as e:
                raise ValueError(f"Failed to open local image file: {e}")
        else:
            raise ValueError(
                "Invalid input source. Must be a valid URL or local file path."
            )

    raise ValueError(
        "Invalid input type. Must be a string (URL or file path), Path object, or PIL Image object."
    )