arcade-google-slides 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- arcade_google_slides/__init__.py +17 -0
- arcade_google_slides/converters.py +329 -0
- arcade_google_slides/decorators.py +24 -0
- arcade_google_slides/enum.py +165 -0
- arcade_google_slides/file_picker.py +49 -0
- arcade_google_slides/templates.py +5 -0
- arcade_google_slides/tools/__init__.py +18 -0
- arcade_google_slides/tools/comment.py +99 -0
- arcade_google_slides/tools/create.py +122 -0
- arcade_google_slides/tools/get.py +33 -0
- arcade_google_slides/tools/search.py +125 -0
- arcade_google_slides/types.py +223 -0
- arcade_google_slides/utils.py +166 -0
- arcade_google_slides-0.1.0.dist-info/METADATA +27 -0
- arcade_google_slides-0.1.0.dist-info/RECORD +17 -0
- arcade_google_slides-0.1.0.dist-info/WHEEL +4 -0
- arcade_google_slides-0.1.0.dist-info/licenses/LICENSE +35 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Any, cast
|
|
3
|
+
|
|
4
|
+
from google.oauth2.credentials import Credentials
|
|
5
|
+
from googleapiclient.discovery import Resource, build
|
|
6
|
+
|
|
7
|
+
from arcade_google_slides.converters import PresentationMarkdownConverter
|
|
8
|
+
from arcade_google_slides.enum import Corpora, OrderBy
|
|
9
|
+
from arcade_google_slides.types import Presentation
|
|
10
|
+
|
|
11
|
+
## Set up basic configuration for logging to the console with DEBUG level and a specific format.
|
|
12
|
+
logging.basicConfig(
|
|
13
|
+
level=logging.DEBUG,
|
|
14
|
+
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger(__name__)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def build_slides_service(auth_token: str | None) -> Resource: # type: ignore[no-any-unimported]
|
|
21
|
+
"""
|
|
22
|
+
Build a Slides service object.
|
|
23
|
+
"""
|
|
24
|
+
auth_token = auth_token or ""
|
|
25
|
+
return build("slides", "v1", credentials=Credentials(auth_token))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def build_drive_service(auth_token: str | None) -> Resource: # type: ignore[no-any-unimported]
|
|
29
|
+
"""
|
|
30
|
+
Build a Drive service object.
|
|
31
|
+
"""
|
|
32
|
+
auth_token = auth_token or ""
|
|
33
|
+
return build("drive", "v3", credentials=Credentials(auth_token))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def create_blank_presentation( # type: ignore[no-any-unimported]
|
|
37
|
+
slides_service: Resource,
|
|
38
|
+
title: str,
|
|
39
|
+
) -> Presentation:
|
|
40
|
+
"""
|
|
41
|
+
Create a blank Google Slides presentation with the specified title.
|
|
42
|
+
|
|
43
|
+
Requires the https://www.googleapis.com/auth/drive.file scope
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
slides_service: The Slides service to use
|
|
47
|
+
title: The title of the presentation to create
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
The created presentation
|
|
51
|
+
"""
|
|
52
|
+
blank_presentation: Presentation = {
|
|
53
|
+
"title": title,
|
|
54
|
+
"presentationId": None,
|
|
55
|
+
"slides": [],
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
request = slides_service.presentations().create(body=blank_presentation)
|
|
59
|
+
response = request.execute()
|
|
60
|
+
|
|
61
|
+
return cast(Presentation, response)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def convert_presentation_to_markdown(presentation: Presentation) -> str:
|
|
65
|
+
"""
|
|
66
|
+
Convert a Google Slides presentation to markdown format.
|
|
67
|
+
|
|
68
|
+
This function uses the PresentationMarkdownConverter class to perform
|
|
69
|
+
the conversion following the strict TypedDict structure.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
presentation: Presentation TypedDict
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
A markdown string representation of the presentation
|
|
76
|
+
"""
|
|
77
|
+
converter = PresentationMarkdownConverter()
|
|
78
|
+
return converter.convert(presentation)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def build_files_list_params(
|
|
82
|
+
mime_type: str,
|
|
83
|
+
page_size: int,
|
|
84
|
+
order_by: list[OrderBy],
|
|
85
|
+
pagination_token: str | None,
|
|
86
|
+
include_shared_drives: bool,
|
|
87
|
+
search_only_in_shared_drive_id: str | None,
|
|
88
|
+
include_organization_domain_documents: bool,
|
|
89
|
+
document_contains: list[str] | None = None,
|
|
90
|
+
document_not_contains: list[str] | None = None,
|
|
91
|
+
) -> dict[str, Any]:
|
|
92
|
+
query = build_files_list_query(
|
|
93
|
+
mime_type=mime_type,
|
|
94
|
+
document_contains=document_contains,
|
|
95
|
+
document_not_contains=document_not_contains,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
params = {
|
|
99
|
+
"q": query,
|
|
100
|
+
"pageSize": page_size,
|
|
101
|
+
"orderBy": ",".join([item.value for item in order_by]),
|
|
102
|
+
"pageToken": pagination_token,
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (
|
|
106
|
+
include_shared_drives
|
|
107
|
+
or search_only_in_shared_drive_id
|
|
108
|
+
or include_organization_domain_documents
|
|
109
|
+
):
|
|
110
|
+
params["includeItemsFromAllDrives"] = "true"
|
|
111
|
+
params["supportsAllDrives"] = "true"
|
|
112
|
+
|
|
113
|
+
if search_only_in_shared_drive_id:
|
|
114
|
+
params["driveId"] = search_only_in_shared_drive_id
|
|
115
|
+
params["corpora"] = Corpora.DRIVE.value
|
|
116
|
+
|
|
117
|
+
if include_organization_domain_documents:
|
|
118
|
+
params["corpora"] = Corpora.DOMAIN.value
|
|
119
|
+
|
|
120
|
+
params = remove_none_values(params)
|
|
121
|
+
|
|
122
|
+
return params
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def build_files_list_query(
|
|
126
|
+
mime_type: str,
|
|
127
|
+
document_contains: list[str] | None = None,
|
|
128
|
+
document_not_contains: list[str] | None = None,
|
|
129
|
+
) -> str:
|
|
130
|
+
query = [f"(mimeType = '{mime_type}' and trashed = false)"]
|
|
131
|
+
|
|
132
|
+
if isinstance(document_contains, str):
|
|
133
|
+
document_contains = [document_contains]
|
|
134
|
+
|
|
135
|
+
if isinstance(document_not_contains, str):
|
|
136
|
+
document_not_contains = [document_not_contains]
|
|
137
|
+
|
|
138
|
+
if document_contains:
|
|
139
|
+
for keyword in document_contains:
|
|
140
|
+
name_contains = keyword.replace("'", "\\'")
|
|
141
|
+
full_text_contains = keyword.replace("'", "\\'")
|
|
142
|
+
keyword_query = (
|
|
143
|
+
f"(name contains '{name_contains}' or fullText contains '{full_text_contains}')"
|
|
144
|
+
)
|
|
145
|
+
query.append(keyword_query)
|
|
146
|
+
|
|
147
|
+
if document_not_contains:
|
|
148
|
+
for keyword in document_not_contains:
|
|
149
|
+
name_not_contains = keyword.replace("'", "\\'")
|
|
150
|
+
full_text_not_contains = keyword.replace("'", "\\'")
|
|
151
|
+
keyword_query = (
|
|
152
|
+
f"(name not contains '{name_not_contains}' and "
|
|
153
|
+
f"fullText not contains '{full_text_not_contains}')"
|
|
154
|
+
)
|
|
155
|
+
query.append(keyword_query)
|
|
156
|
+
|
|
157
|
+
return " and ".join(query)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def remove_none_values(params: dict) -> dict:
|
|
161
|
+
"""
|
|
162
|
+
Remove None values from a dictionary.
|
|
163
|
+
:param params: The dictionary to clean
|
|
164
|
+
:return: A new dictionary with None values removed
|
|
165
|
+
"""
|
|
166
|
+
return {k: v for k, v in params.items() if v is not None}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: arcade_google_slides
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Arcade.dev LLM tools for Google Slides
|
|
5
|
+
Author-email: Arcade <dev@arcade.dev>
|
|
6
|
+
License: Proprietary - Arcade Software License Agreement v1.0
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Requires-Dist: arcade-ai>=2.1.4
|
|
10
|
+
Requires-Dist: arcade-serve>=2.0.0
|
|
11
|
+
Requires-Dist: arcade-tdk<3.0.0,>=2.0.0
|
|
12
|
+
Requires-Dist: google-api-core<3.0.0,>=2.19.1
|
|
13
|
+
Requires-Dist: google-api-python-client<3.0.0,>=2.137.0
|
|
14
|
+
Requires-Dist: google-auth-httplib2<1.0.0,>=0.2.0
|
|
15
|
+
Requires-Dist: google-auth<3.0.0,>=2.32.0
|
|
16
|
+
Requires-Dist: googleapis-common-protos<2.0.0,>=1.63.2
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: arcade-ai[evals]<3.0.0,>=2.0.4; extra == 'dev'
|
|
19
|
+
Requires-Dist: arcade-serve<3.0.0,>=2.0.0; extra == 'dev'
|
|
20
|
+
Requires-Dist: mypy<1.6.0,>=1.5.1; extra == 'dev'
|
|
21
|
+
Requires-Dist: pre-commit<3.5.0,>=3.4.0; extra == 'dev'
|
|
22
|
+
Requires-Dist: pytest-asyncio<0.25.0,>=0.24.0; extra == 'dev'
|
|
23
|
+
Requires-Dist: pytest-cov<4.1.0,>=4.0.0; extra == 'dev'
|
|
24
|
+
Requires-Dist: pytest-mock<3.12.0,>=3.11.1; extra == 'dev'
|
|
25
|
+
Requires-Dist: pytest<8.4.0,>=8.3.0; extra == 'dev'
|
|
26
|
+
Requires-Dist: ruff<0.8.0,>=0.7.4; extra == 'dev'
|
|
27
|
+
Requires-Dist: tox<4.12.0,>=4.11.1; extra == 'dev'
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
arcade_google_slides/__init__.py,sha256=NJk6XPdTtpKDTdDYxzP_rOVqTxjdfSF0yQVde1KliV0,398
|
|
2
|
+
arcade_google_slides/converters.py,sha256=kKxTeuQX_Q4-QpZWCCKteAMAZ0o2McpaWimxg-6IxHI,9870
|
|
3
|
+
arcade_google_slides/decorators.py,sha256=SQeS2_fa3UOgUgGiYuY5eugguIyRPvHVc85TSracSZY,753
|
|
4
|
+
arcade_google_slides/enum.py,sha256=uRBfvSfDpbZaunuA6upPP3GvXArOW8r7k6YYPsa9X9M,5289
|
|
5
|
+
arcade_google_slides/file_picker.py,sha256=kGfUVfH5QVlIW1sL-_gAwPokt7TwVEcPk3Vnk53GKUE,2005
|
|
6
|
+
arcade_google_slides/templates.py,sha256=pxbdMj57eV3-ImW3CixDWscpVKS94Z8nTNyTxDhUfGY,283
|
|
7
|
+
arcade_google_slides/types.py,sha256=osCGae3PXl9U_eA7zqVEA6kcju6W-npXLUlsbJZIuqc,6664
|
|
8
|
+
arcade_google_slides/utils.py,sha256=OBBFKEfGse6ohWSvhF85Cgtzlz3svn8BOMi-RfBigVo,5099
|
|
9
|
+
arcade_google_slides/tools/__init__.py,sha256=JMWqB_57Nul0mF6vwSJsqzHp91cimmy9cvqcgM-tacw,531
|
|
10
|
+
arcade_google_slides/tools/comment.py,sha256=SCLONR43ZXBHjLFkaNnIbWvxO3qV0tG-li8HkHi1Npk,2960
|
|
11
|
+
arcade_google_slides/tools/create.py,sha256=JbKhvZH5jbj7dFXLdUhm9mHDWYChXQZ66BSilersYMA,3955
|
|
12
|
+
arcade_google_slides/tools/get.py,sha256=ZqV8gtDJR0I7wMugholR59zCtHfT5CjiaG3kwl9XCZk,1209
|
|
13
|
+
arcade_google_slides/tools/search.py,sha256=8S0MhqrgDCuF1kVM48S_GiB8rZWCutCAsdiofAb0b9A,4932
|
|
14
|
+
arcade_google_slides-0.1.0.dist-info/METADATA,sha256=S0CxSh8uvoiYFFJPw2fE8BT7lNKf_EOjuqc04oBEAEM,1190
|
|
15
|
+
arcade_google_slides-0.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
16
|
+
arcade_google_slides-0.1.0.dist-info/licenses/LICENSE,sha256=ixeE7aL9b2B-_ZYHTY1vQcJB4NufKeo-LWwKNObGDN0,1960
|
|
17
|
+
arcade_google_slides-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# The Arcade Software License Agreement
|
|
2
|
+
|
|
3
|
+
- Version 1.0
|
|
4
|
+
- Effective Date: July 24, 2025
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This software and associated documentation (collectively, the “Software”) are the intellectual property of Arcade Technologies, Inc. (“Arcade”). All rights are reserved.
|
|
9
|
+
|
|
10
|
+
1. License Grant
|
|
11
|
+
|
|
12
|
+
No license or other rights are granted to any party under this Agreement, whether by implication, estoppel, or otherwise. This Software is proprietary and confidential. Use, reproduction, modification, distribution, display, or creation of derivative works based on the Software is strictly prohibited without the prior written consent of Arcade.
|
|
13
|
+
|
|
14
|
+
2. Commercial Use Only
|
|
15
|
+
|
|
16
|
+
Any use of this Software requires a commercial license agreement with Arcade. You may not use any part of the Software for any purpose—including but not limited to evaluation, testing, or internal use—without first obtaining explicit written permission and entering into a commercial licensing arrangement.
|
|
17
|
+
|
|
18
|
+
To inquire about licensing terms, contact Arcade at:
|
|
19
|
+
🔗 www.arcade.dev
|
|
20
|
+
|
|
21
|
+
3. No Open Source Rights
|
|
22
|
+
|
|
23
|
+
This Software is not licensed under an open-source license. No part of it may be incorporated into open-source or publicly available projects under any open-source terms or licenses.
|
|
24
|
+
|
|
25
|
+
4. Ownership
|
|
26
|
+
|
|
27
|
+
Arcade retains all right, title, and interest in and to the Software, including all intellectual property rights therein. No ownership or license rights are transferred under this Agreement.
|
|
28
|
+
|
|
29
|
+
5. Disclaimer of Warranty
|
|
30
|
+
|
|
31
|
+
The Software is provided “as is” without warranty of any kind. Arcade disclaims all warranties, express or implied, including but not limited to warranties of merchantability, fitness for a particular purpose, and noninfringement.
|
|
32
|
+
|
|
33
|
+
6. Limitation of Liability
|
|
34
|
+
|
|
35
|
+
In no event shall Arcade be liable for any damages arising out of or in connection with the use or performance of the Software, whether in an action of contract, tort (including negligence), or otherwise.
|