Spaces:
Runtime error
Runtime error
Update icons, text, and prompts (merge PR #28 from barun-saha/visual)
Browse filesThis view is limited to 50 files because it contains too many changes. Β
See raw diff
- README.md +8 -2
- app.py +5 -2
- bootstrap-icons-1.11.3/png128/bank2.png +0 -0
- bootstrap-icons-1.11.3/png128/flower3.png +0 -0
- global_config.py +1 -1
- helpers/image_search.py +30 -5
- helpers/pptx_helper.py +5 -2
- {bootstrap-icons-1.11.3 β icons}/png128/0-circle.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/1-circle.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/123.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/2-circle.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/3-circle.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/4-circle.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/5-circle.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/6-circle.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/7-circle.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/8-circle.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/9-circle.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/activity.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/airplane.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/alarm.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/alphabet.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/amazon.png +0 -0
- bootstrap-icons-1.11.3/png128/android2.png β icons/png128/android.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/apple.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/archive.png +0 -0
- icons/png128/artificial-intelligence-brain.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/award-fill.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/award.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/balloon.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/ban.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/bandaid.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/bank.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/bar-chart-line.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/basket.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/battery-charging.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/bell-slash.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/bell.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/bicycle.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/bing.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/binoculars.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/bluetooth.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/book.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/bookmark.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/bootstrap.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/briefcase.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/broadcast-pin.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/browser-chrome.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/browser-edge.png +0 -0
- {bootstrap-icons-1.11.3 β icons}/png128/browser-firefox.png +0 -0
README.md
CHANGED
|
@@ -41,10 +41,16 @@ A history of instructions is maintained.
|
|
| 41 |
Clicking on the button will download the file.
|
| 42 |
|
| 43 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
# Known Issues
|
| 45 |
|
| 46 |
-
- **Connection timeout**: Requests sent to the Hugging Face Inference endpoint might time out.
|
| 47 |
-
A maximum of five retries are attempted. If it still does not work, wait for a while and try again.
|
| 48 |
|
| 49 |
The following is not an issue but might appear as a strange behavior:
|
| 50 |
- **Cannot paste text in the input box**: If the length of the copied text is greater than the maximum
|
|
|
|
| 41 |
Clicking on the button will download the file.
|
| 42 |
|
| 43 |
|
| 44 |
+
# Icons
|
| 45 |
+
|
| 46 |
+
SlideDeck AI uses a subset of icons from [bootstrap-icons-1.11.3](https://github.com/twbs/icons)
|
| 47 |
+
(MIT license) in the slides. A few icons from [SVG Repo](https://www.svgrepo.com/)
|
| 48 |
+
(CC0, MIT, and Apache licenses) are also used.
|
| 49 |
+
|
| 50 |
+
|
| 51 |
# Known Issues
|
| 52 |
|
| 53 |
+
- **Connection timeout**: Requests sent to the Hugging Face Inference endpoint might time out. If it still does not work, wait for a while and try again.
|
|
|
|
| 54 |
|
| 55 |
The following is not an issue but might appear as a strange behavior:
|
| 56 |
- **Cannot paste text in the input box**: If the length of the copied text is greater than the maximum
|
app.py
CHANGED
|
@@ -212,7 +212,10 @@ def set_up_chat_ui():
|
|
| 212 |
|
| 213 |
# Update the progress bar
|
| 214 |
progress_percentage = min(len(response) / APPROX_TARGET_LENGTH, 0.95)
|
| 215 |
-
progress_bar.progress(
|
|
|
|
|
|
|
|
|
|
| 216 |
|
| 217 |
history.add_user_message(prompt)
|
| 218 |
history.add_ai_message(response)
|
|
@@ -226,7 +229,7 @@ def set_up_chat_ui():
|
|
| 226 |
'Cleaned JSON response:: original length: %d | cleaned length: %d',
|
| 227 |
len(response), len(response_cleaned)
|
| 228 |
)
|
| 229 |
-
logger.debug('Cleaned JSON: %s', response_cleaned)
|
| 230 |
|
| 231 |
# Now create the PPT file
|
| 232 |
progress_bar.progress(
|
|
|
|
| 212 |
|
| 213 |
# Update the progress bar
|
| 214 |
progress_percentage = min(len(response) / APPROX_TARGET_LENGTH, 0.95)
|
| 215 |
+
progress_bar.progress(
|
| 216 |
+
progress_percentage,
|
| 217 |
+
text='Streaming content...this might take a while...'
|
| 218 |
+
)
|
| 219 |
|
| 220 |
history.add_user_message(prompt)
|
| 221 |
history.add_ai_message(response)
|
|
|
|
| 229 |
'Cleaned JSON response:: original length: %d | cleaned length: %d',
|
| 230 |
len(response), len(response_cleaned)
|
| 231 |
)
|
| 232 |
+
# logger.debug('Cleaned JSON: %s', response_cleaned)
|
| 233 |
|
| 234 |
# Now create the PPT file
|
| 235 |
progress_bar.progress(
|
bootstrap-icons-1.11.3/png128/bank2.png
DELETED
|
Binary file (1.29 kB)
|
|
|
bootstrap-icons-1.11.3/png128/flower3.png
DELETED
|
Binary file (3.31 kB)
|
|
|
global_config.py
CHANGED
|
@@ -35,7 +35,7 @@ class GlobalConfig:
|
|
| 35 |
REFINEMENT_PROMPT_TEMPLATE = 'langchain_templates/chat_prompts/refinement_template_v4_two_cols_img.txt'
|
| 36 |
|
| 37 |
LLM_PROGRESS_MAX = 90
|
| 38 |
-
ICONS_DIR = '
|
| 39 |
|
| 40 |
PPTX_TEMPLATE_FILES = {
|
| 41 |
'Basic': {
|
|
|
|
| 35 |
REFINEMENT_PROMPT_TEMPLATE = 'langchain_templates/chat_prompts/refinement_template_v4_two_cols_img.txt'
|
| 36 |
|
| 37 |
LLM_PROGRESS_MAX = 90
|
| 38 |
+
ICONS_DIR = 'icons/png128/'
|
| 39 |
|
| 40 |
PPTX_TEMPLATE_FILES = {
|
| 41 |
'Basic': {
|
helpers/image_search.py
CHANGED
|
@@ -9,16 +9,20 @@ from typing import Union, Tuple, Literal
|
|
| 9 |
from urllib.parse import urlparse, parse_qs
|
| 10 |
|
| 11 |
import requests
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
|
| 13 |
|
| 14 |
REQUEST_TIMEOUT = 12
|
| 15 |
MAX_PHOTOS = 3
|
| 16 |
|
| 17 |
|
| 18 |
-
# Only show
|
| 19 |
-
logging.getLogger('urllib3').setLevel(logging.
|
| 20 |
# Disable all child loggers of urllib3, e.g. urllib3.connectionpool
|
| 21 |
-
logging.getLogger('urllib3').propagate =
|
| 22 |
|
| 23 |
|
| 24 |
|
|
@@ -33,6 +37,14 @@ def search_pexels(
|
|
| 33 |
This function sends a GET request to the Pexels API with the specified search query
|
| 34 |
and authorization header containing the API key. It returns the JSON response from the API.
|
| 35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
:param query: The search query for finding images.
|
| 37 |
:param size: The size of the images: small, medium, or large.
|
| 38 |
:param per_page: No. of results to be displayed per page.
|
|
@@ -42,7 +54,8 @@ def search_pexels(
|
|
| 42 |
|
| 43 |
url = 'https://api.pexels.com/v1/search'
|
| 44 |
headers = {
|
| 45 |
-
'Authorization': os.getenv('PEXEL_API_KEY')
|
|
|
|
| 46 |
}
|
| 47 |
params = {
|
| 48 |
'query': query,
|
|
@@ -101,7 +114,11 @@ def get_image_from_url(url: str) -> BytesIO:
|
|
| 101 |
:raises requests.exceptions.RequestException: If the request to the URL fails.
|
| 102 |
"""
|
| 103 |
|
| 104 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
response.raise_for_status()
|
| 106 |
image_data = BytesIO(response.content)
|
| 107 |
|
|
@@ -121,3 +138,11 @@ def extract_dimensions(url: str) -> Tuple[int, int]:
|
|
| 121 |
height = int(query_params.get('h', [0])[0])
|
| 122 |
|
| 123 |
return width, height
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 9 |
from urllib.parse import urlparse, parse_qs
|
| 10 |
|
| 11 |
import requests
|
| 12 |
+
from dotenv import load_dotenv
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
load_dotenv()
|
| 16 |
|
| 17 |
|
| 18 |
REQUEST_TIMEOUT = 12
|
| 19 |
MAX_PHOTOS = 3
|
| 20 |
|
| 21 |
|
| 22 |
+
# Only show errors
|
| 23 |
+
logging.getLogger('urllib3').setLevel(logging.ERROR)
|
| 24 |
# Disable all child loggers of urllib3, e.g. urllib3.connectionpool
|
| 25 |
+
# logging.getLogger('urllib3').propagate = True
|
| 26 |
|
| 27 |
|
| 28 |
|
|
|
|
| 37 |
This function sends a GET request to the Pexels API with the specified search query
|
| 38 |
and authorization header containing the API key. It returns the JSON response from the API.
|
| 39 |
|
| 40 |
+
[2024-08-31] Note:
|
| 41 |
+
`curl` succeeds but API call via Python `requests` fail. Apparently, this could be due to
|
| 42 |
+
Cloudflare (or others) blocking the requests, perhaps identifying as Web-scraping. So,
|
| 43 |
+
changing the user-agent to Firefox.
|
| 44 |
+
https://stackoverflow.com/a/74674276/147021
|
| 45 |
+
https://stackoverflow.com/a/51268523/147021
|
| 46 |
+
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent/Firefox#linux
|
| 47 |
+
|
| 48 |
:param query: The search query for finding images.
|
| 49 |
:param size: The size of the images: small, medium, or large.
|
| 50 |
:param per_page: No. of results to be displayed per page.
|
|
|
|
| 54 |
|
| 55 |
url = 'https://api.pexels.com/v1/search'
|
| 56 |
headers = {
|
| 57 |
+
'Authorization': os.getenv('PEXEL_API_KEY'),
|
| 58 |
+
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20100101 Firefox/10.0',
|
| 59 |
}
|
| 60 |
params = {
|
| 61 |
'query': query,
|
|
|
|
| 114 |
:raises requests.exceptions.RequestException: If the request to the URL fails.
|
| 115 |
"""
|
| 116 |
|
| 117 |
+
headers = {
|
| 118 |
+
'Authorization': os.getenv('PEXEL_API_KEY'),
|
| 119 |
+
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:10.0) Gecko/20100101 Firefox/10.0',
|
| 120 |
+
}
|
| 121 |
+
response = requests.get(url, headers=headers, stream=True, timeout=REQUEST_TIMEOUT)
|
| 122 |
response.raise_for_status()
|
| 123 |
image_data = BytesIO(response.content)
|
| 124 |
|
|
|
|
| 138 |
height = int(query_params.get('h', [0])[0])
|
| 139 |
|
| 140 |
return width, height
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
if __name__ == '__main__':
|
| 144 |
+
print(
|
| 145 |
+
search_pexels(
|
| 146 |
+
query='people'
|
| 147 |
+
)
|
| 148 |
+
)
|
helpers/pptx_helper.py
CHANGED
|
@@ -28,6 +28,7 @@ load_dotenv()
|
|
| 28 |
|
| 29 |
# English Metric Unit (used by PowerPoint) to inches
|
| 30 |
EMU_TO_INCH_SCALING_FACTOR = 1.0 / 914400
|
|
|
|
| 31 |
INCHES_2 = pptx.util.Inches(2)
|
| 32 |
INCHES_1_5 = pptx.util.Inches(1.5)
|
| 33 |
INCHES_1 = pptx.util.Inches(1)
|
|
@@ -499,7 +500,7 @@ def _handle_icons_ideas(
|
|
| 499 |
match = ICONS_REGEX.search(item)
|
| 500 |
|
| 501 |
if not match:
|
| 502 |
-
print('No icon/text pattern match found...skipping to the next item')
|
| 503 |
continue
|
| 504 |
|
| 505 |
icon_name = match.group(1)
|
|
@@ -507,7 +508,7 @@ def _handle_icons_ideas(
|
|
| 507 |
icon_path = f'{GlobalConfig.ICONS_DIR}/{icon_name}.png'
|
| 508 |
|
| 509 |
left = spacing + idx * (ICON_SIZE + spacing)
|
| 510 |
-
top =
|
| 511 |
|
| 512 |
# Calculate the center position for alignment
|
| 513 |
center = left + ICON_SIZE / 2
|
|
@@ -521,6 +522,7 @@ def _handle_icons_ideas(
|
|
| 521 |
INCHES_1, INCHES_1
|
| 522 |
)
|
| 523 |
shape.fill.solid()
|
|
|
|
| 524 |
|
| 525 |
# Set the icon's background shape color
|
| 526 |
color = random.choice(ICON_COLORS)
|
|
@@ -551,6 +553,7 @@ def _handle_icons_ideas(
|
|
| 551 |
text_frame = text_box.text_frame
|
| 552 |
text_frame.text = accompanying_text
|
| 553 |
text_frame.word_wrap = True
|
|
|
|
| 554 |
|
| 555 |
# Center the text vertically
|
| 556 |
text_frame.vertical_anchor = pptx.enum.text.MSO_ANCHOR.MIDDLE
|
|
|
|
| 28 |
|
| 29 |
# English Metric Unit (used by PowerPoint) to inches
|
| 30 |
EMU_TO_INCH_SCALING_FACTOR = 1.0 / 914400
|
| 31 |
+
INCHES_3 = pptx.util.Inches(3)
|
| 32 |
INCHES_2 = pptx.util.Inches(2)
|
| 33 |
INCHES_1_5 = pptx.util.Inches(1.5)
|
| 34 |
INCHES_1 = pptx.util.Inches(1)
|
|
|
|
| 500 |
match = ICONS_REGEX.search(item)
|
| 501 |
|
| 502 |
if not match:
|
| 503 |
+
# print('No icon/text pattern match found...skipping to the next item')
|
| 504 |
continue
|
| 505 |
|
| 506 |
icon_name = match.group(1)
|
|
|
|
| 508 |
icon_path = f'{GlobalConfig.ICONS_DIR}/{icon_name}.png'
|
| 509 |
|
| 510 |
left = spacing + idx * (ICON_SIZE + spacing)
|
| 511 |
+
top = INCHES_3
|
| 512 |
|
| 513 |
# Calculate the center position for alignment
|
| 514 |
center = left + ICON_SIZE / 2
|
|
|
|
| 522 |
INCHES_1, INCHES_1
|
| 523 |
)
|
| 524 |
shape.fill.solid()
|
| 525 |
+
shape.shadow.inherit = False
|
| 526 |
|
| 527 |
# Set the icon's background shape color
|
| 528 |
color = random.choice(ICON_COLORS)
|
|
|
|
| 553 |
text_frame = text_box.text_frame
|
| 554 |
text_frame.text = accompanying_text
|
| 555 |
text_frame.word_wrap = True
|
| 556 |
+
text_frame.paragraphs[0].alignment = pptx.enum.text.PP_ALIGN.CENTER
|
| 557 |
|
| 558 |
# Center the text vertically
|
| 559 |
text_frame.vertical_anchor = pptx.enum.text.MSO_ANCHOR.MIDDLE
|
{bootstrap-icons-1.11.3 β icons}/png128/0-circle.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/1-circle.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/123.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/2-circle.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/3-circle.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/4-circle.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/5-circle.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/6-circle.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/7-circle.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/8-circle.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/9-circle.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/activity.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/airplane.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/alarm.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/alphabet.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/amazon.png
RENAMED
|
File without changes
|
bootstrap-icons-1.11.3/png128/android2.png β icons/png128/android.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/apple.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/archive.png
RENAMED
|
File without changes
|
icons/png128/artificial-intelligence-brain.png
ADDED
|
|
{bootstrap-icons-1.11.3 β icons}/png128/award-fill.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/award.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/balloon.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/ban.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/bandaid.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/bank.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/bar-chart-line.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/basket.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/battery-charging.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/bell-slash.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/bell.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/bicycle.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/bing.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/binoculars.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/bluetooth.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/book.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/bookmark.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/bootstrap.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/briefcase.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/broadcast-pin.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/browser-chrome.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/browser-edge.png
RENAMED
|
File without changes
|
{bootstrap-icons-1.11.3 β icons}/png128/browser-firefox.png
RENAMED
|
File without changes
|