google-workspace-mcp 1.0.4__py3-none-any.whl → 1.1.5__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.
- google_workspace_mcp/__main__.py +6 -5
- google_workspace_mcp/services/drive.py +39 -12
- google_workspace_mcp/services/slides.py +2033 -57
- google_workspace_mcp/tools/add_image.py +1781 -0
- google_workspace_mcp/tools/calendar.py +12 -17
- google_workspace_mcp/tools/docs_tools.py +24 -32
- google_workspace_mcp/tools/drive.py +264 -21
- google_workspace_mcp/tools/gmail.py +27 -36
- google_workspace_mcp/tools/sheets_tools.py +18 -25
- google_workspace_mcp/tools/slides.py +774 -55
- google_workspace_mcp/utils/unit_conversion.py +201 -0
- {google_workspace_mcp-1.0.4.dist-info → google_workspace_mcp-1.1.5.dist-info}/METADATA +2 -2
- {google_workspace_mcp-1.0.4.dist-info → google_workspace_mcp-1.1.5.dist-info}/RECORD +15 -13
- {google_workspace_mcp-1.0.4.dist-info → google_workspace_mcp-1.1.5.dist-info}/WHEEL +0 -0
- {google_workspace_mcp-1.0.4.dist-info → google_workspace_mcp-1.1.5.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,201 @@
|
|
1
|
+
"""
|
2
|
+
Unit conversion utilities for Google Slides API.
|
3
|
+
|
4
|
+
This module provides functions to convert between different units used in Google Slides:
|
5
|
+
- EMU (English Metric Units): 1 inch = 914,400 EMU, 1 point = 12,700 EMU
|
6
|
+
- PT (Points): 1 inch = 72 PT
|
7
|
+
- Inches
|
8
|
+
"""
|
9
|
+
|
10
|
+
import logging
|
11
|
+
from typing import Any, Dict, Union
|
12
|
+
|
13
|
+
logger = logging.getLogger(__name__)
|
14
|
+
|
15
|
+
# Conversion constants based on Google Slides API documentation
|
16
|
+
EMU_PER_INCH = 914400
|
17
|
+
EMU_PER_POINT = 12700
|
18
|
+
POINTS_PER_INCH = 72
|
19
|
+
|
20
|
+
|
21
|
+
def emu_to_pt(emu: Union[int, float]) -> float:
|
22
|
+
"""
|
23
|
+
Convert EMU (English Metric Units) to Points.
|
24
|
+
|
25
|
+
Args:
|
26
|
+
emu: Value in EMU units
|
27
|
+
|
28
|
+
Returns:
|
29
|
+
Value in Points
|
30
|
+
"""
|
31
|
+
return float(emu) / EMU_PER_POINT
|
32
|
+
|
33
|
+
|
34
|
+
def pt_to_emu(points: Union[int, float]) -> int:
|
35
|
+
"""
|
36
|
+
Convert Points to EMU (English Metric Units).
|
37
|
+
|
38
|
+
Args:
|
39
|
+
points: Value in Points
|
40
|
+
|
41
|
+
Returns:
|
42
|
+
Value in EMU units
|
43
|
+
"""
|
44
|
+
return int(float(points) * EMU_PER_POINT)
|
45
|
+
|
46
|
+
|
47
|
+
def emu_to_inches(emu: Union[int, float]) -> float:
|
48
|
+
"""
|
49
|
+
Convert EMU (English Metric Units) to inches.
|
50
|
+
|
51
|
+
Args:
|
52
|
+
emu: Value in EMU units
|
53
|
+
|
54
|
+
Returns:
|
55
|
+
Value in inches
|
56
|
+
"""
|
57
|
+
return float(emu) / EMU_PER_INCH
|
58
|
+
|
59
|
+
|
60
|
+
def inches_to_emu(inches: Union[int, float]) -> int:
|
61
|
+
"""
|
62
|
+
Convert inches to EMU (English Metric Units).
|
63
|
+
|
64
|
+
Args:
|
65
|
+
inches: Value in inches
|
66
|
+
|
67
|
+
Returns:
|
68
|
+
Value in EMU units
|
69
|
+
"""
|
70
|
+
return int(float(inches) * EMU_PER_INCH)
|
71
|
+
|
72
|
+
|
73
|
+
def pt_to_inches(points: Union[int, float]) -> float:
|
74
|
+
"""
|
75
|
+
Convert Points to inches.
|
76
|
+
|
77
|
+
Args:
|
78
|
+
points: Value in Points
|
79
|
+
|
80
|
+
Returns:
|
81
|
+
Value in inches
|
82
|
+
"""
|
83
|
+
return float(points) / POINTS_PER_INCH
|
84
|
+
|
85
|
+
|
86
|
+
def inches_to_pt(inches: Union[int, float]) -> float:
|
87
|
+
"""
|
88
|
+
Convert inches to Points.
|
89
|
+
|
90
|
+
Args:
|
91
|
+
inches: Value in inches
|
92
|
+
|
93
|
+
Returns:
|
94
|
+
Value in Points
|
95
|
+
"""
|
96
|
+
return float(inches) * POINTS_PER_INCH
|
97
|
+
|
98
|
+
|
99
|
+
def convert_template_zone_coordinates(
|
100
|
+
zone_data: Dict[str, Any], target_unit: str = "PT"
|
101
|
+
) -> Dict[str, Any]:
|
102
|
+
"""
|
103
|
+
Convert template zone coordinates from EMU to specified target unit.
|
104
|
+
|
105
|
+
Args:
|
106
|
+
zone_data: Dictionary containing zone information with EMU coordinates
|
107
|
+
target_unit: Target unit ("PT", "EMU", or "INCHES")
|
108
|
+
|
109
|
+
Returns:
|
110
|
+
Dictionary with additional coordinates in target unit
|
111
|
+
"""
|
112
|
+
if target_unit not in ["PT", "EMU", "INCHES"]:
|
113
|
+
raise ValueError("target_unit must be 'PT', 'EMU', or 'INCHES'")
|
114
|
+
|
115
|
+
# Create a copy to avoid modifying the original
|
116
|
+
converted_zone = zone_data.copy()
|
117
|
+
|
118
|
+
# Get EMU coordinates (these should always be present)
|
119
|
+
x_emu = zone_data.get("x_emu", 0)
|
120
|
+
y_emu = zone_data.get("y_emu", 0)
|
121
|
+
width_emu = zone_data.get("width_emu", 0)
|
122
|
+
height_emu = zone_data.get("height_emu", 0)
|
123
|
+
|
124
|
+
if target_unit == "PT":
|
125
|
+
converted_zone.update(
|
126
|
+
{
|
127
|
+
"x_pt": emu_to_pt(x_emu),
|
128
|
+
"y_pt": emu_to_pt(y_emu),
|
129
|
+
"width_pt": emu_to_pt(width_emu),
|
130
|
+
"height_pt": emu_to_pt(height_emu),
|
131
|
+
}
|
132
|
+
)
|
133
|
+
elif target_unit == "INCHES":
|
134
|
+
converted_zone.update(
|
135
|
+
{
|
136
|
+
"x_inches": emu_to_inches(x_emu),
|
137
|
+
"y_inches": emu_to_inches(y_emu),
|
138
|
+
"width_inches": emu_to_inches(width_emu),
|
139
|
+
"height_inches": emu_to_inches(height_emu),
|
140
|
+
}
|
141
|
+
)
|
142
|
+
# For EMU, coordinates are already present
|
143
|
+
|
144
|
+
return converted_zone
|
145
|
+
|
146
|
+
|
147
|
+
def convert_template_zones(
|
148
|
+
template_zones: Dict[str, Any], target_unit: str = "PT"
|
149
|
+
) -> Dict[str, Any]:
|
150
|
+
"""
|
151
|
+
Convert all template zones coordinates to specified target unit.
|
152
|
+
|
153
|
+
Args:
|
154
|
+
template_zones: Dictionary containing template zones data
|
155
|
+
target_unit: Target unit ("PT", "EMU", or "INCHES")
|
156
|
+
|
157
|
+
Returns:
|
158
|
+
Dictionary with converted template zones
|
159
|
+
"""
|
160
|
+
if not template_zones:
|
161
|
+
raise ValueError("template_zones cannot be empty")
|
162
|
+
|
163
|
+
converted_zones = {}
|
164
|
+
|
165
|
+
# Handle both nested structure (from extract_template_zones_only)
|
166
|
+
# and flat structure (single slide zones)
|
167
|
+
if "slides_analyzed" in template_zones:
|
168
|
+
# Nested structure from extract_template_zones_only
|
169
|
+
converted_zones = template_zones.copy()
|
170
|
+
converted_zones["slides_analyzed"] = []
|
171
|
+
|
172
|
+
for slide_data in template_zones["slides_analyzed"]:
|
173
|
+
converted_slide = slide_data.copy()
|
174
|
+
if "template_zones" in slide_data:
|
175
|
+
converted_slide["template_zones"] = {}
|
176
|
+
for zone_name, zone_data in slide_data["template_zones"].items():
|
177
|
+
converted_slide["template_zones"][zone_name] = (
|
178
|
+
convert_template_zone_coordinates(zone_data, target_unit)
|
179
|
+
)
|
180
|
+
converted_zones["slides_analyzed"].append(converted_slide)
|
181
|
+
|
182
|
+
elif "zones" in template_zones:
|
183
|
+
# Single slide structure from extract_template_zones_by_text
|
184
|
+
converted_zones = template_zones.copy()
|
185
|
+
converted_zones["zones"] = {}
|
186
|
+
|
187
|
+
for zone_name, zone_data in template_zones["zones"].items():
|
188
|
+
converted_zones["zones"][zone_name] = convert_template_zone_coordinates(
|
189
|
+
zone_data, target_unit
|
190
|
+
)
|
191
|
+
else:
|
192
|
+
# Direct zones dictionary
|
193
|
+
for zone_name, zone_data in template_zones.items():
|
194
|
+
converted_zones[zone_name] = convert_template_zone_coordinates(
|
195
|
+
zone_data, target_unit
|
196
|
+
)
|
197
|
+
|
198
|
+
logger.info(
|
199
|
+
f"Converted {len(template_zones)} template zones to {target_unit} coordinates"
|
200
|
+
)
|
201
|
+
return converted_zones
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: google-workspace-mcp
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.1.5
|
4
4
|
Summary: MCP server for Google Workspace integration
|
5
5
|
Author-email: Arclio Team <info@arclio.com>
|
6
6
|
License: MIT
|
@@ -11,7 +11,7 @@ Requires-Dist: google-auth-httplib2>=0.1.0
|
|
11
11
|
Requires-Dist: google-auth-oauthlib>=1.0.0
|
12
12
|
Requires-Dist: google-auth>=2.22.0
|
13
13
|
Requires-Dist: markdown>=3.5.0
|
14
|
-
Requires-Dist: markdowndeck>=0.1.
|
14
|
+
Requires-Dist: markdowndeck>=0.1.5
|
15
15
|
Requires-Dist: mcp>=1.7.0
|
16
16
|
Requires-Dist: python-dotenv>=1.0.0
|
17
17
|
Requires-Dist: pytz>=2023.3
|
@@ -1,5 +1,5 @@
|
|
1
1
|
google_workspace_mcp/__init__.py,sha256=CppIQ682LvBlR1IPwBOsryB6rk-P4tDy9bPK1OYtUmM,109
|
2
|
-
google_workspace_mcp/__main__.py,sha256=
|
2
|
+
google_workspace_mcp/__main__.py,sha256=wuz6n4pU6ScFpbSgjjKpyiw0lmeKdzAlWLH15zT9Gug,1855
|
3
3
|
google_workspace_mcp/app.py,sha256=ajasCHBQ8dWiBoLKDibrkj6SsGyt1pNupwQO9fcsZzE,160
|
4
4
|
google_workspace_mcp/config.py,sha256=DNac38UANs0A2RX4fTi1sMaJ5mTrOaaWnPEusL6Id_M,2578
|
5
5
|
google_workspace_mcp/auth/__init__.py,sha256=4SNTCWZqUJGn20vj8j5WekpwNnm87-KeiKFfOGG4b1M,126
|
@@ -19,20 +19,22 @@ google_workspace_mcp/services/__init__.py,sha256=crw4YinYFi7QDfJZUCcUqPliRtlViSE
|
|
19
19
|
google_workspace_mcp/services/base.py,sha256=uLtFB158kaY_n3JWKgW2kxQ2tx9SP9zxX-PWuPxydFI,2378
|
20
20
|
google_workspace_mcp/services/calendar.py,sha256=_FvgDKfMvFWIamDHOimY3cVK2zPk0o7iUbbKeJehaHY,8370
|
21
21
|
google_workspace_mcp/services/docs_service.py,sha256=e67bvDb0lAmDbSXYRxPAIH93rXPbHS0Fq07c-eBcy08,25286
|
22
|
-
google_workspace_mcp/services/drive.py,sha256=
|
22
|
+
google_workspace_mcp/services/drive.py,sha256=HqcQVqFyQ22ts84A85zwOJkVOjSeEAz3Q1SGWNX9aPQ,17819
|
23
23
|
google_workspace_mcp/services/gmail.py,sha256=M6trjL9uFOe5WnBORyic4Y7lU4Z0X9VnEq-yU7RY-No,24846
|
24
24
|
google_workspace_mcp/services/sheets_service.py,sha256=67glYCTuQynka_vAXxCsM2U5SMuRNXXpTff2G-X-fT0,18068
|
25
|
-
google_workspace_mcp/services/slides.py,sha256=
|
25
|
+
google_workspace_mcp/services/slides.py,sha256=GXwqBawlCLQHhQ4K4ZK69bHoBOXaa6zjqls_hC4sv2M,116062
|
26
26
|
google_workspace_mcp/tools/__init__.py,sha256=vwa7hV8HwrLqs3Sf7RTrt1MlVZ-KjptXuFDSJt5tWzA,107
|
27
|
-
google_workspace_mcp/tools/
|
28
|
-
google_workspace_mcp/tools/
|
29
|
-
google_workspace_mcp/tools/
|
30
|
-
google_workspace_mcp/tools/
|
31
|
-
google_workspace_mcp/tools/
|
32
|
-
google_workspace_mcp/tools/
|
27
|
+
google_workspace_mcp/tools/add_image.py,sha256=RzKH-U1IHGLjrWQys5gyrMtSTjug47K8nY3CW4YNHEg,68491
|
28
|
+
google_workspace_mcp/tools/calendar.py,sha256=KQFUAal-446NBK3FCGdCr8sHjABvCpI4SoUHeI9DuSw,7538
|
29
|
+
google_workspace_mcp/tools/docs_tools.py,sha256=KuzWeu7PBnFI-qLFmbAKleXx3qpRS7kJyMq5bnQvNj0,11566
|
30
|
+
google_workspace_mcp/tools/drive.py,sha256=u_fmWAo4I3zsnG6V-P-nOqxODu9yfCP4gi4cxMI8Dbc,15868
|
31
|
+
google_workspace_mcp/tools/gmail.py,sha256=3cS690MG5fEYl07EyyqY6qIx1LhMOvqK5Ylfu_-Kndc,10702
|
32
|
+
google_workspace_mcp/tools/sheets_tools.py,sha256=zCtcJzvB0P_cT67neHJhD5d10WCBQFDiNJngwUDuWws,11129
|
33
|
+
google_workspace_mcp/tools/slides.py,sha256=fPRAch6yFLzBlCwhF01ZUsS6onkbvFV6aS5YwKnBiMg,43516
|
33
34
|
google_workspace_mcp/utils/__init__.py,sha256=jKEfO2DhR_lwsRSoUgceixDwzkGVlp_vmbrz_6AHOk0,50
|
34
35
|
google_workspace_mcp/utils/markdown_slides.py,sha256=G7EbK3DDki90hNilGzbczs2e345v-HjYB5GWhFbEtw4,21015
|
35
|
-
google_workspace_mcp
|
36
|
-
google_workspace_mcp-1.
|
37
|
-
google_workspace_mcp-1.
|
38
|
-
google_workspace_mcp-1.
|
36
|
+
google_workspace_mcp/utils/unit_conversion.py,sha256=7Y3Q4iKUYetu1GeB_gMHYrHnK3wtNhyJD1x187V353I,5591
|
37
|
+
google_workspace_mcp-1.1.5.dist-info/METADATA,sha256=kWV2fXInKyjYckm4A7PeP7FpO7rziUXz1aF7YwQfCpA,25104
|
38
|
+
google_workspace_mcp-1.1.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
39
|
+
google_workspace_mcp-1.1.5.dist-info/entry_points.txt,sha256=t9eBYTnGzEBpiiRx_SCTqforubwM6Ebf5mszIj-MjeA,79
|
40
|
+
google_workspace_mcp-1.1.5.dist-info/RECORD,,
|
File without changes
|
{google_workspace_mcp-1.0.4.dist-info → google_workspace_mcp-1.1.5.dist-info}/entry_points.txt
RENAMED
File without changes
|