Spaces:
Sleeping
Sleeping
admin
commited on
Commit
·
fd41354
1
Parent(s):
3d1d388
update logo
Browse files- demo/logo.png +0 -0
- src/modules/app.py +42 -33
- src/modules/link.py +84 -70
demo/logo.png
ADDED
![]() |
src/modules/app.py
CHANGED
@@ -13,10 +13,12 @@ For more information, see
|
|
13 |
- https://app.bitly.com/settings/api
|
14 |
'''
|
15 |
|
16 |
-
def
|
17 |
-
|
18 |
x, y = 0, 0
|
19 |
-
pos_px, pos_py =
|
|
|
|
|
20 |
|
21 |
for i in range(image_count):
|
22 |
if x + item_size[0] > page_size[0]: # Check for horizontal overflow
|
@@ -27,10 +29,10 @@ def calculate_positions(image_count, item_size=(20, 20), page_size=(91, 55), pad
|
|
27 |
x = 0
|
28 |
y = 0
|
29 |
|
30 |
-
|
31 |
x += item_size[0] + pos_px
|
32 |
-
print(
|
33 |
-
return
|
34 |
|
35 |
with gr.Blocks() as demo:
|
36 |
gr.Markdown(description)
|
@@ -39,40 +41,37 @@ with gr.Blocks() as demo:
|
|
39 |
access_token = gr.Textbox(label="Access Token", placeholder="***")
|
40 |
api_url = gr.Textbox(label="API base URL", placeholder="https://")
|
41 |
txt_input = gr.TextArea(label="Enter Text with URLs")
|
42 |
-
count_url = gr.Dropdown(visible=False)
|
43 |
@gr.render(inputs=[txt_input])
|
44 |
def update_cnt(txt):
|
45 |
urls = re.findall(r'http[s]?://\S+', txt)
|
46 |
return urls
|
47 |
|
48 |
with gr.Row():
|
49 |
-
shorten_checkbox = gr.Checkbox(label="Shorten URL", value=
|
50 |
qr_checkbox = gr.Checkbox(label="Generate QR Code", value=True)
|
51 |
-
|
|
|
|
|
52 |
|
53 |
with gr.Accordion(open=False, label="Insert"):
|
54 |
with gr.Row():
|
55 |
-
|
56 |
-
|
|
|
|
|
57 |
|
58 |
-
headers = ['ImageId', 'PosX', 'PosY', 'PosPx', 'PosPy']
|
59 |
|
60 |
@gr.render(inputs=[count_url, cm_img_input, idv_img_input])
|
61 |
def update_df(*items):
|
62 |
image_count = sum(len(item) for item in items if item is not None)
|
63 |
if image_count is not None:
|
64 |
-
positions =
|
65 |
-
df = pd.DataFrame(positions, columns=
|
66 |
-
df.insert(0, 'ImageId', range(1, image_count + 1))
|
67 |
return df
|
68 |
|
69 |
-
pos_df = gr.Dataframe(headers=headers, label="Positions")
|
70 |
-
|
71 |
-
txt_input.change(update_cnt, txt_input, count_url)
|
72 |
-
count_url.change(update_df, count_url, pos_df)
|
73 |
-
cm_img_input.change(update_df, cm_img_input, pos_df)
|
74 |
-
idv_img_input.change(update_df, idv_img_input, pos_df)
|
75 |
-
|
76 |
with gr.Column():
|
77 |
file_output = gr.File(label="Download ZIP")
|
78 |
with gr.Accordion(open=True, label="Gallery"):
|
@@ -83,19 +82,29 @@ with gr.Blocks() as demo:
|
|
83 |
preview_output = gr.TextArea(label="Raw Text")
|
84 |
|
85 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
# example_temp_html = TextProcessor.apply_style('demo/demo.md', 'style.css') # TODO
|
87 |
with open('demo/demo.md') as f:
|
88 |
demo_txt = f.read()
|
89 |
-
examples = [
|
90 |
-
['https://example.com',
|
91 |
-
['demo/demo.jpg'],
|
92 |
-
['demo/demo.jpg']
|
93 |
-
]
|
94 |
-
]
|
95 |
-
inputs = [
|
96 |
-
txt_input, cm_img_input, idv_img_input
|
97 |
-
]
|
98 |
-
gr.Examples(examples, inputs)
|
99 |
|
100 |
submit_button.click(
|
101 |
UrlProcessor.shorten_and_generate_qr,
|
@@ -107,7 +116,7 @@ with gr.Blocks() as demo:
|
|
107 |
qr_checkbox,
|
108 |
cm_img_input,
|
109 |
idv_img_input,
|
110 |
-
|
111 |
],
|
112 |
outputs=[preview_output, gallery_output, file_output, json_output]
|
113 |
)
|
|
|
13 |
- https://app.bitly.com/settings/api
|
14 |
'''
|
15 |
|
16 |
+
def calculate_layout(image_count, item_size=(40, 40), page_size=(91, 55), position=(30, 67)):
|
17 |
+
layout = []
|
18 |
x, y = 0, 0
|
19 |
+
pos_px, pos_py = position
|
20 |
+
size_x, size_y = item_size
|
21 |
+
size_px, size_py = item_size
|
22 |
|
23 |
for i in range(image_count):
|
24 |
if x + item_size[0] > page_size[0]: # Check for horizontal overflow
|
|
|
29 |
x = 0
|
30 |
y = 0
|
31 |
|
32 |
+
layout.append((image_count, x, y, pos_px, pos_py, size_x, size_y, size_px, size_py))
|
33 |
x += item_size[0] + pos_px
|
34 |
+
# print(layout)
|
35 |
+
return layout
|
36 |
|
37 |
with gr.Blocks() as demo:
|
38 |
gr.Markdown(description)
|
|
|
41 |
access_token = gr.Textbox(label="Access Token", placeholder="***")
|
42 |
api_url = gr.Textbox(label="API base URL", placeholder="https://")
|
43 |
txt_input = gr.TextArea(label="Enter Text with URLs")
|
44 |
+
count_url = gr.Dropdown(visible=False, allow_custom_value=True)
|
45 |
@gr.render(inputs=[txt_input])
|
46 |
def update_cnt(txt):
|
47 |
urls = re.findall(r'http[s]?://\S+', txt)
|
48 |
return urls
|
49 |
|
50 |
with gr.Row():
|
51 |
+
shorten_checkbox = gr.Checkbox(label="Shorten URL", value=False)
|
52 |
qr_checkbox = gr.Checkbox(label="Generate QR Code", value=True)
|
53 |
+
with gr.Row():
|
54 |
+
clear_button = gr.ClearButton(txt_input)
|
55 |
+
submit_button = gr.Button("Process URLs", variant='primary')
|
56 |
|
57 |
with gr.Accordion(open=False, label="Insert"):
|
58 |
with gr.Row():
|
59 |
+
img_formats = ['png',
|
60 |
+
'jpeg', 'jpg', 'webp', 'svg', 'gif', 'tiff']
|
61 |
+
cm_img_input = gr.Files(file_types=img_formats, label='Insert common images')
|
62 |
+
idv_img_input = gr.Files(file_types=img_formats, label='Insert individual images')
|
63 |
|
64 |
+
headers = ['ImageId', 'PosX', 'PosY', 'PosPx', 'PosPy', 'SizeX', 'SizeY', 'SizePx', 'SizePy']
|
65 |
|
66 |
@gr.render(inputs=[count_url, cm_img_input, idv_img_input])
|
67 |
def update_df(*items):
|
68 |
image_count = sum(len(item) for item in items if item is not None)
|
69 |
if image_count is not None:
|
70 |
+
positions = calculate_layout(image_count)
|
71 |
+
df = pd.DataFrame(positions, columns=headers)
|
72 |
+
# df.insert(0, 'ImageId', range(1, image_count + 1))
|
73 |
return df
|
74 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
with gr.Column():
|
76 |
file_output = gr.File(label="Download ZIP")
|
77 |
with gr.Accordion(open=True, label="Gallery"):
|
|
|
82 |
preview_output = gr.TextArea(label="Raw Text")
|
83 |
|
84 |
|
85 |
+
with gr.Row():
|
86 |
+
inputs = [
|
87 |
+
txt_input, cm_img_input, idv_img_input
|
88 |
+
]
|
89 |
+
examples = [
|
90 |
+
['https://example.com',
|
91 |
+
['demo/demo.jpg'],
|
92 |
+
['demo/logo.png']
|
93 |
+
]
|
94 |
+
]
|
95 |
+
gr.Examples(examples, inputs)
|
96 |
+
|
97 |
+
with gr.Row():
|
98 |
+
df = gr.Dataframe(headers=headers, label="Positions")
|
99 |
+
|
100 |
+
txt_input.change(update_cnt, txt_input, count_url)
|
101 |
+
count_url.change(update_df, count_url, df)
|
102 |
+
cm_img_input.change(update_df, cm_img_input, df)
|
103 |
+
idv_img_input.change(update_df, idv_img_input, df)
|
104 |
+
|
105 |
# example_temp_html = TextProcessor.apply_style('demo/demo.md', 'style.css') # TODO
|
106 |
with open('demo/demo.md') as f:
|
107 |
demo_txt = f.read()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
|
109 |
submit_button.click(
|
110 |
UrlProcessor.shorten_and_generate_qr,
|
|
|
116 |
qr_checkbox,
|
117 |
cm_img_input,
|
118 |
idv_img_input,
|
119 |
+
df,
|
120 |
],
|
121 |
outputs=[preview_output, gallery_output, file_output, json_output]
|
122 |
)
|
src/modules/link.py
CHANGED
@@ -102,63 +102,63 @@ class UrlProcessor:
|
|
102 |
|
103 |
if urls is not None:
|
104 |
urls = urls if urls is not None else []
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
else:
|
115 |
-
url_to_process = url
|
116 |
-
|
117 |
-
if generate_qr and url_to_process:
|
118 |
-
if shorten_url:
|
119 |
-
qr_html, qr_png, qr_json = bitly.generate_qr_local(url_to_process)
|
120 |
-
else:
|
121 |
-
qr_html, qr_png, qr_json = bitly.generate_qr_local(url_to_process)
|
122 |
-
|
123 |
-
if qr_png:
|
124 |
-
os.makedirs(f'{tmpd}/img/qr', exist_ok=True)
|
125 |
-
qr_png_path = f'img/qr/QR{idx:05d}.png'
|
126 |
-
qr_path = os.path.join(tmpd, qr_png_path)
|
127 |
-
with open(qr_path, 'wb') as f:
|
128 |
-
f.write(qr_png)
|
129 |
-
markdown_links = markdown_links.replace(
|
130 |
-
url, f'<img src="{qr_png_path}" height="40"> [{url_to_process}]({url}) '
|
131 |
-
)
|
132 |
-
qr_pngs.append(qr_path)
|
133 |
-
qr_svgs.append(qr_html)
|
134 |
-
all_json_responses.append(qr_json)
|
135 |
else:
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
markdown_links = markdown_links.replace(
|
146 |
-
url, f'
|
147 |
)
|
148 |
-
|
149 |
-
qr_svgs.append(qr_html)
|
150 |
-
all_json_responses.append(qr_json)
|
151 |
else:
|
152 |
-
results.append(("Error
|
153 |
-
|
154 |
-
|
155 |
-
url, f'[{shorten_url}]({url}) '
|
156 |
-
)
|
157 |
-
results.append((None, shorten_url))
|
158 |
-
else:
|
159 |
-
results.append(("Error shortening URL", url))
|
160 |
-
except Exception as e:
|
161 |
-
results.append((str(e), url))
|
162 |
|
163 |
|
164 |
processor = ImageProcessor()
|
@@ -166,30 +166,45 @@ class UrlProcessor:
|
|
166 |
|
167 |
os.makedirs(f'{tmpd}/img/cards', exist_ok=True)
|
168 |
|
169 |
-
if qr_pngs
|
170 |
-
|
171 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
|
173 |
-
|
|
|
|
|
|
|
|
|
174 |
try:
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
|
180 |
-
|
|
|
|
|
|
|
181 |
|
|
|
182 |
if common_images:
|
183 |
for common_img in common_images:
|
184 |
-
layer = processor.combine_images(layer, common_img, size, (
|
185 |
-
if individual_images:
|
186 |
-
layer = processor.combine_images(layer, indv, size, (pos_x, pos_y))
|
187 |
|
188 |
-
if
|
189 |
-
|
190 |
-
qr_pos = (int(0.9 * pos_x * 3.7795), int(0.9 * pos_y * 3.7795))
|
191 |
-
layer = processor.combine_images(layer, qr, qr_size, qr_pos)
|
192 |
|
|
|
|
|
193 |
|
194 |
card_png_path = f'img/cards/CD{idx:05d}.png'
|
195 |
card_path = os.path.join(tmpd, card_png_path)
|
@@ -206,7 +221,6 @@ class UrlProcessor:
|
|
206 |
except Exception as e:
|
207 |
raise Exception(f"Error combining images: {e}")
|
208 |
|
209 |
-
|
210 |
try:
|
211 |
json_output_path = os.path.join(tmpd, 'response.json')
|
212 |
with open(json_output_path, 'w') as json_file:
|
|
|
102 |
|
103 |
if urls is not None:
|
104 |
urls = urls if urls is not None else []
|
105 |
+
for idx, url in enumerate(urls):
|
106 |
+
shorten_url, shorten_response_json = None, None
|
107 |
+
try:
|
108 |
+
if shorten:
|
109 |
+
shorten_url, shorten_response_json = bitly.shorten(url)
|
110 |
+
all_json_responses.append(shorten_response_json)
|
111 |
+
|
112 |
+
if shorten and shorten_url:
|
113 |
+
url_to_process = shorten_url
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
else:
|
115 |
+
url_to_process = url
|
116 |
+
|
117 |
+
if generate_qr and url_to_process:
|
118 |
+
if shorten_url:
|
119 |
+
qr_html, qr_png, qr_json = bitly.generate_qr_local(url_to_process)
|
120 |
+
else:
|
121 |
+
qr_html, qr_png, qr_json = bitly.generate_qr_local(url_to_process)
|
122 |
+
|
123 |
+
if qr_png:
|
124 |
+
os.makedirs(f'{tmpd}/img/qr', exist_ok=True)
|
125 |
+
qr_png_path = f'img/qr/QR{idx:05d}.png'
|
126 |
+
qr_path = os.path.join(tmpd, qr_png_path)
|
127 |
+
with open(qr_path, 'wb') as f:
|
128 |
+
f.write(qr_png)
|
129 |
+
markdown_links = markdown_links.replace(
|
130 |
+
url, f'<img src="{qr_png_path}" height="40"> [{url_to_process}]({url}) '
|
131 |
+
)
|
132 |
+
qr_pngs.append(qr_path)
|
133 |
+
qr_svgs.append(qr_html)
|
134 |
+
all_json_responses.append(qr_json)
|
135 |
+
else:
|
136 |
+
results.append(("Error generating QR code", url_to_process))
|
137 |
+
elif generate_qr:
|
138 |
+
qr_html, qr_png, qr_json = bitly.generate_qr_local(url)
|
139 |
+
if qr_png:
|
140 |
+
os.makedirs(f'{tmpd}/img/qr', exist_ok=True)
|
141 |
+
qr_png_path = f'img/qr/QR{idx:05d}.png'
|
142 |
+
qr_path = os.path.join(tmpd, qr_png_path)
|
143 |
+
with open(qr_path, 'wb') as f:
|
144 |
+
f.write(qr_png)
|
145 |
+
markdown_links = markdown_links.replace(
|
146 |
+
url, f'<img src="{qr_png_path}" height="40"> [{url}]({url}) '
|
147 |
+
)
|
148 |
+
qr_pngs.append(qr_path)
|
149 |
+
qr_svgs.append(qr_html)
|
150 |
+
all_json_responses.append(qr_json)
|
151 |
+
else:
|
152 |
+
results.append(("Error generating QR code", url))
|
153 |
+
elif shorten_url:
|
154 |
markdown_links = markdown_links.replace(
|
155 |
+
url, f'[{shorten_url}]({url}) '
|
156 |
)
|
157 |
+
results.append((None, shorten_url))
|
|
|
|
|
158 |
else:
|
159 |
+
results.append(("Error shortening URL", url))
|
160 |
+
except Exception as e:
|
161 |
+
results.append((str(e), url))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
162 |
|
163 |
|
164 |
processor = ImageProcessor()
|
|
|
166 |
|
167 |
os.makedirs(f'{tmpd}/img/cards', exist_ok=True)
|
168 |
|
169 |
+
if qr_pngs and individual_images:
|
170 |
+
num_iterations = len(qr_pngs) * len(individual_images)
|
171 |
+
elif qr_pngs:
|
172 |
+
num_iterations = len(qr_pngs)
|
173 |
+
elif individual_images:
|
174 |
+
num_iterations = len(individual_images)
|
175 |
+
else:
|
176 |
+
num_iterations = 1
|
177 |
+
|
178 |
+
for idx in range(num_iterations):
|
179 |
+
qr_idx = idx % len(qr_pngs) if qr_pngs else 0
|
180 |
+
indv_idx = idx // len(qr_pngs) if individual_images else 0
|
181 |
|
182 |
+
qr = qr_pngs[qr_idx] if qr_pngs else None
|
183 |
+
indv = individual_images[indv_idx] if individual_images else None
|
184 |
+
|
185 |
+
if qr or indv:
|
186 |
+
print(idx)
|
187 |
try:
|
188 |
+
pos_x = int(positions_df.loc[idx, 'PosX'])
|
189 |
+
pos_y = int(positions_df.loc[idx, 'PosY'])
|
190 |
+
pos_px = int(positions_df.loc[idx, 'PosPx'])
|
191 |
+
pos_py = int(positions_df.loc[idx, 'PosPy'])
|
192 |
|
193 |
+
size_x = int(positions_df.loc[idx, 'SizeX'])
|
194 |
+
size_y = int(positions_df.loc[idx, 'SizeY'])
|
195 |
+
size_px = int(positions_df.loc[idx, 'SizePx'])
|
196 |
+
size_py = int(positions_df.loc[idx, 'SizePy'])
|
197 |
|
198 |
+
size = (int(91 * 3.7795), int(55 * 3.7795))
|
199 |
if common_images:
|
200 |
for common_img in common_images:
|
201 |
+
layer = processor.combine_images(layer, common_img, size, (0, 0))
|
|
|
|
|
202 |
|
203 |
+
if indv:
|
204 |
+
layer = processor.combine_images(layer, indv, (size_x, size_y), (pos_x, pos_y))
|
|
|
|
|
205 |
|
206 |
+
if qr:
|
207 |
+
layer = processor.combine_images(layer, qr, (size_px, size_py), (pos_px, pos_py))
|
208 |
|
209 |
card_png_path = f'img/cards/CD{idx:05d}.png'
|
210 |
card_path = os.path.join(tmpd, card_png_path)
|
|
|
221 |
except Exception as e:
|
222 |
raise Exception(f"Error combining images: {e}")
|
223 |
|
|
|
224 |
try:
|
225 |
json_output_path = os.path.join(tmpd, 'response.json')
|
226 |
with open(json_output_path, 'w') as json_file:
|