gamsapi 52.5.0__cp312-cp312-win_amd64.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.
- gams/__init__.py +27 -0
- gams/_version.py +1 -0
- gams/connect/__init__.py +28 -0
- gams/connect/agents/__init__.py +24 -0
- gams/connect/agents/_excel/__init__.py +32 -0
- gams/connect/agents/_excel/excelagent.py +312 -0
- gams/connect/agents/_excel/workbook.py +155 -0
- gams/connect/agents/_sqlconnectors/__init__.py +42 -0
- gams/connect/agents/_sqlconnectors/_accesshandler.py +211 -0
- gams/connect/agents/_sqlconnectors/_databasehandler.py +250 -0
- gams/connect/agents/_sqlconnectors/_mysqlhandler.py +168 -0
- gams/connect/agents/_sqlconnectors/_postgreshandler.py +131 -0
- gams/connect/agents/_sqlconnectors/_pyodbchandler.py +112 -0
- gams/connect/agents/_sqlconnectors/_sqlalchemyhandler.py +74 -0
- gams/connect/agents/_sqlconnectors/_sqlitehandler.py +262 -0
- gams/connect/agents/_sqlconnectors/_sqlserverhandler.py +179 -0
- gams/connect/agents/concatenate.py +440 -0
- gams/connect/agents/connectagent.py +743 -0
- gams/connect/agents/csvreader.py +675 -0
- gams/connect/agents/csvwriter.py +151 -0
- gams/connect/agents/domainwriter.py +143 -0
- gams/connect/agents/excelreader.py +756 -0
- gams/connect/agents/excelwriter.py +467 -0
- gams/connect/agents/filter.py +223 -0
- gams/connect/agents/gamsreader.py +112 -0
- gams/connect/agents/gamswriter.py +239 -0
- gams/connect/agents/gdxreader.py +109 -0
- gams/connect/agents/gdxwriter.py +146 -0
- gams/connect/agents/labelmanipulator.py +303 -0
- gams/connect/agents/projection.py +539 -0
- gams/connect/agents/pythoncode.py +71 -0
- gams/connect/agents/rawcsvreader.py +248 -0
- gams/connect/agents/rawexcelreader.py +312 -0
- gams/connect/agents/schema/CSVReader.yaml +92 -0
- gams/connect/agents/schema/CSVWriter.yaml +44 -0
- gams/connect/agents/schema/Concatenate.yaml +52 -0
- gams/connect/agents/schema/DomainWriter.yaml +25 -0
- gams/connect/agents/schema/ExcelReader.yaml +121 -0
- gams/connect/agents/schema/ExcelWriter.yaml +78 -0
- gams/connect/agents/schema/Filter.yaml +74 -0
- gams/connect/agents/schema/GAMSReader.yaml +20 -0
- gams/connect/agents/schema/GAMSWriter.yaml +47 -0
- gams/connect/agents/schema/GDXReader.yaml +23 -0
- gams/connect/agents/schema/GDXWriter.yaml +32 -0
- gams/connect/agents/schema/LabelManipulator.yaml +99 -0
- gams/connect/agents/schema/Projection.yaml +24 -0
- gams/connect/agents/schema/PythonCode.yaml +6 -0
- gams/connect/agents/schema/RawCSVReader.yaml +34 -0
- gams/connect/agents/schema/RawExcelReader.yaml +42 -0
- gams/connect/agents/schema/SQLReader.yaml +75 -0
- gams/connect/agents/schema/SQLWriter.yaml +103 -0
- gams/connect/agents/sqlreader.py +301 -0
- gams/connect/agents/sqlwriter.py +276 -0
- gams/connect/connectdatabase.py +275 -0
- gams/connect/connectvalidator.py +93 -0
- gams/connect/errors.py +34 -0
- gams/control/__init__.py +136 -0
- gams/control/database.py +2231 -0
- gams/control/execution.py +1900 -0
- gams/control/options.py +2792 -0
- gams/control/workspace.py +1198 -0
- gams/core/__init__.py +24 -0
- gams/core/cfg/__init__.py +26 -0
- gams/core/cfg/_cfgmcc.cp312-win_amd64.pyd +0 -0
- gams/core/cfg/cfgmcc.py +519 -0
- gams/core/dct/__init__.py +26 -0
- gams/core/dct/_dctmcc.cp312-win_amd64.pyd +0 -0
- gams/core/dct/dctmcc.py +574 -0
- gams/core/embedded/__init__.py +26 -0
- gams/core/embedded/gamsemb.py +1024 -0
- gams/core/emp/__init__.py +24 -0
- gams/core/emp/emplexer.py +89 -0
- gams/core/emp/empyacc.py +281 -0
- gams/core/gdx/__init__.py +26 -0
- gams/core/gdx/_gdxcc.cp312-win_amd64.pyd +0 -0
- gams/core/gdx/gdxcc.py +866 -0
- gams/core/gev/__init__.py +26 -0
- gams/core/gev/_gevmcc.cp312-win_amd64.pyd +0 -0
- gams/core/gev/gevmcc.py +855 -0
- gams/core/gmd/__init__.py +26 -0
- gams/core/gmd/_gmdcc.cp312-win_amd64.pyd +0 -0
- gams/core/gmd/gmdcc.py +917 -0
- gams/core/gmo/__init__.py +26 -0
- gams/core/gmo/_gmomcc.cp312-win_amd64.pyd +0 -0
- gams/core/gmo/gmomcc.py +2046 -0
- gams/core/idx/__init__.py +26 -0
- gams/core/idx/_idxcc.cp312-win_amd64.pyd +0 -0
- gams/core/idx/idxcc.py +510 -0
- gams/core/numpy/__init__.py +29 -0
- gams/core/numpy/_gams2numpy.cp312-win_amd64.pyd +0 -0
- gams/core/numpy/gams2numpy.py +1048 -0
- gams/core/opt/__init__.py +26 -0
- gams/core/opt/_optcc.cp312-win_amd64.pyd +0 -0
- gams/core/opt/optcc.py +840 -0
- gams/engine/__init__.py +204 -0
- gams/engine/api/__init__.py +13 -0
- gams/engine/api/auth_api.py +7653 -0
- gams/engine/api/cleanup_api.py +751 -0
- gams/engine/api/default_api.py +887 -0
- gams/engine/api/hypercube_api.py +2629 -0
- gams/engine/api/jobs_api.py +5229 -0
- gams/engine/api/licenses_api.py +2220 -0
- gams/engine/api/namespaces_api.py +7783 -0
- gams/engine/api/usage_api.py +5627 -0
- gams/engine/api/users_api.py +5931 -0
- gams/engine/api_client.py +804 -0
- gams/engine/api_response.py +21 -0
- gams/engine/configuration.py +601 -0
- gams/engine/exceptions.py +216 -0
- gams/engine/models/__init__.py +86 -0
- gams/engine/models/bad_input.py +89 -0
- gams/engine/models/cleanable_job_result.py +104 -0
- gams/engine/models/cleanable_job_result_page.py +113 -0
- gams/engine/models/engine_license.py +107 -0
- gams/engine/models/files_not_found.py +93 -0
- gams/engine/models/forwarded_token_response.py +112 -0
- gams/engine/models/generic_key_value_pair.py +89 -0
- gams/engine/models/hypercube.py +160 -0
- gams/engine/models/hypercube_page.py +111 -0
- gams/engine/models/hypercube_summary.py +91 -0
- gams/engine/models/hypercube_token.py +97 -0
- gams/engine/models/identity_provider.py +107 -0
- gams/engine/models/identity_provider_ldap.py +121 -0
- gams/engine/models/identity_provider_oauth2.py +146 -0
- gams/engine/models/identity_provider_oauth2_scope.py +89 -0
- gams/engine/models/identity_provider_oauth2_with_secret.py +152 -0
- gams/engine/models/identity_provider_oidc.py +133 -0
- gams/engine/models/identity_provider_oidc_with_secret.py +143 -0
- gams/engine/models/inex.py +91 -0
- gams/engine/models/invitation.py +136 -0
- gams/engine/models/invitation_quota.py +106 -0
- gams/engine/models/invitation_token.py +87 -0
- gams/engine/models/job.py +165 -0
- gams/engine/models/job_no_text_entry.py +138 -0
- gams/engine/models/job_no_text_entry_page.py +111 -0
- gams/engine/models/license.py +91 -0
- gams/engine/models/log_piece.py +96 -0
- gams/engine/models/message.py +87 -0
- gams/engine/models/message_and_token.py +99 -0
- gams/engine/models/message_with_webhook_id.py +89 -0
- gams/engine/models/model_auth_token.py +87 -0
- gams/engine/models/model_configuration.py +125 -0
- gams/engine/models/model_default_instance.py +99 -0
- gams/engine/models/model_default_user_instance.py +98 -0
- gams/engine/models/model_hypercube_job.py +106 -0
- gams/engine/models/model_hypercube_usage.py +130 -0
- gams/engine/models/model_instance_info.py +116 -0
- gams/engine/models/model_instance_info_full.py +123 -0
- gams/engine/models/model_instance_pool_info.py +112 -0
- gams/engine/models/model_job_labels.py +179 -0
- gams/engine/models/model_job_usage.py +133 -0
- gams/engine/models/model_pool_usage.py +124 -0
- gams/engine/models/model_usage.py +115 -0
- gams/engine/models/model_user.py +96 -0
- gams/engine/models/model_userinstance_info.py +119 -0
- gams/engine/models/model_userinstancepool_info.py +95 -0
- gams/engine/models/model_version.py +91 -0
- gams/engine/models/models.py +120 -0
- gams/engine/models/namespace.py +104 -0
- gams/engine/models/namespace_quota.py +96 -0
- gams/engine/models/namespace_with_permission.py +96 -0
- gams/engine/models/not_found.py +91 -0
- gams/engine/models/password_policy.py +97 -0
- gams/engine/models/perm_and_username.py +89 -0
- gams/engine/models/quota.py +117 -0
- gams/engine/models/quota_exceeded.py +97 -0
- gams/engine/models/status_code_meaning.py +89 -0
- gams/engine/models/stream_entry.py +89 -0
- gams/engine/models/system_wide_license.py +92 -0
- gams/engine/models/text_entries.py +87 -0
- gams/engine/models/text_entry.py +101 -0
- gams/engine/models/time_span.py +95 -0
- gams/engine/models/time_span_pool_worker.py +99 -0
- gams/engine/models/token_forward_error.py +87 -0
- gams/engine/models/user.py +127 -0
- gams/engine/models/user_group_member.py +96 -0
- gams/engine/models/user_groups.py +108 -0
- gams/engine/models/vapid_info.py +87 -0
- gams/engine/models/webhook.py +138 -0
- gams/engine/models/webhook_parameterized_event.py +99 -0
- gams/engine/py.typed +0 -0
- gams/engine/rest.py +258 -0
- gams/magic/__init__.py +32 -0
- gams/magic/gams_magic.py +142 -0
- gams/magic/interactive.py +402 -0
- gams/tools/__init__.py +30 -0
- gams/tools/errors.py +34 -0
- gams/tools/toolcollection/__init__.py +24 -0
- gams/tools/toolcollection/alg/__init__.py +24 -0
- gams/tools/toolcollection/alg/rank.py +51 -0
- gams/tools/toolcollection/data/__init__.py +24 -0
- gams/tools/toolcollection/data/csvread.py +444 -0
- gams/tools/toolcollection/data/csvwrite.py +311 -0
- gams/tools/toolcollection/data/exceldump.py +47 -0
- gams/tools/toolcollection/data/sqlitewrite.py +276 -0
- gams/tools/toolcollection/gdxservice/__init__.py +24 -0
- gams/tools/toolcollection/gdxservice/gdxencoding.py +104 -0
- gams/tools/toolcollection/gdxservice/gdxrename.py +94 -0
- gams/tools/toolcollection/linalg/__init__.py +24 -0
- gams/tools/toolcollection/linalg/cholesky.py +57 -0
- gams/tools/toolcollection/linalg/eigenvalue.py +56 -0
- gams/tools/toolcollection/linalg/eigenvector.py +58 -0
- gams/tools/toolcollection/linalg/invert.py +55 -0
- gams/tools/toolcollection/linalg/ols.py +138 -0
- gams/tools/toolcollection/tooltemplate.py +321 -0
- gams/tools/toolcollection/win32/__init__.py +24 -0
- gams/tools/toolcollection/win32/excelmerge.py +93 -0
- gams/tools/toolcollection/win32/exceltalk.py +76 -0
- gams/tools/toolcollection/win32/msappavail.py +49 -0
- gams/tools/toolcollection/win32/shellexecute.py +54 -0
- gams/tools/tools.py +116 -0
- gams/transfer/__init__.py +35 -0
- gams/transfer/_abcs/__init__.py +37 -0
- gams/transfer/_abcs/container_abcs.py +433 -0
- gams/transfer/_internals/__init__.py +63 -0
- gams/transfer/_internals/algorithms.py +436 -0
- gams/transfer/_internals/casepreservingdict.py +124 -0
- gams/transfer/_internals/constants.py +270 -0
- gams/transfer/_internals/domainviolation.py +103 -0
- gams/transfer/_internals/specialvalues.py +172 -0
- gams/transfer/containers/__init__.py +26 -0
- gams/transfer/containers/_container.py +1794 -0
- gams/transfer/containers/_io/__init__.py +28 -0
- gams/transfer/containers/_io/containers.py +164 -0
- gams/transfer/containers/_io/gdx.py +1029 -0
- gams/transfer/containers/_io/gmd.py +872 -0
- gams/transfer/containers/_mixins/__init__.py +26 -0
- gams/transfer/containers/_mixins/ccc.py +1274 -0
- gams/transfer/syms/__init__.py +33 -0
- gams/transfer/syms/_methods/__init__.py +24 -0
- gams/transfer/syms/_methods/tables.py +120 -0
- gams/transfer/syms/_methods/toDict.py +115 -0
- gams/transfer/syms/_methods/toList.py +83 -0
- gams/transfer/syms/_methods/toValue.py +60 -0
- gams/transfer/syms/_mixins/__init__.py +32 -0
- gams/transfer/syms/_mixins/equals.py +626 -0
- gams/transfer/syms/_mixins/generateRecords.py +499 -0
- gams/transfer/syms/_mixins/pivot.py +313 -0
- gams/transfer/syms/_mixins/pve.py +627 -0
- gams/transfer/syms/_mixins/sa.py +27 -0
- gams/transfer/syms/_mixins/sapve.py +27 -0
- gams/transfer/syms/_mixins/saua.py +27 -0
- gams/transfer/syms/_mixins/sauapve.py +199 -0
- gams/transfer/syms/_mixins/spve.py +1528 -0
- gams/transfer/syms/_mixins/ve.py +936 -0
- gams/transfer/syms/container_syms/__init__.py +31 -0
- gams/transfer/syms/container_syms/_alias.py +984 -0
- gams/transfer/syms/container_syms/_equation.py +333 -0
- gams/transfer/syms/container_syms/_parameter.py +973 -0
- gams/transfer/syms/container_syms/_set.py +604 -0
- gams/transfer/syms/container_syms/_universe_alias.py +461 -0
- gams/transfer/syms/container_syms/_variable.py +321 -0
- gamsapi-52.5.0.dist-info/METADATA +150 -0
- gamsapi-52.5.0.dist-info/RECORD +257 -0
- gamsapi-52.5.0.dist-info/WHEEL +5 -0
- gamsapi-52.5.0.dist-info/licenses/LICENSE +22 -0
- gamsapi-52.5.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
#
|
|
2
|
+
# GAMS - General Algebraic Modeling System Python API
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
|
|
5
|
+
# Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
|
|
26
|
+
from abc import ABC, abstractmethod
|
|
27
|
+
import string
|
|
28
|
+
import shlex
|
|
29
|
+
import os
|
|
30
|
+
import numpy as np
|
|
31
|
+
from gams.tools.errors import GamsToolsException
|
|
32
|
+
|
|
33
|
+
class ToolTemplate(ABC):
|
|
34
|
+
def __init__(self, system_directory, tools):
|
|
35
|
+
'''
|
|
36
|
+
:param system_directory: GAMS system directory to be used.
|
|
37
|
+
:param tools: An instance of gams.tools.tools.Tools.
|
|
38
|
+
'''
|
|
39
|
+
self._system_directory = system_directory
|
|
40
|
+
self._tools = tools
|
|
41
|
+
self._knowntypes = ["id.in", "id.in.list", "id.out", "id.out.list", "str", "str.list", "float", "float.list", "int", "int.list", "fnExist", "fnWriteable"]
|
|
42
|
+
self._posargsdef = {}
|
|
43
|
+
self._namedargsdef = {}
|
|
44
|
+
self.add_namedargdef("trace=traceLevel","int","Set tracing level",0)
|
|
45
|
+
self._trace = 0
|
|
46
|
+
self._lastpositem = {}
|
|
47
|
+
self.posargs = []
|
|
48
|
+
self.namedargs = {}
|
|
49
|
+
self.namedargs_list = []
|
|
50
|
+
|
|
51
|
+
def add_posargdef(self, argid, argtype, argtext):
|
|
52
|
+
if ":" in argtype:
|
|
53
|
+
t = argtype.split(':')[0]
|
|
54
|
+
else:
|
|
55
|
+
t = argtype
|
|
56
|
+
if not t in self._knowntypes:
|
|
57
|
+
self.tool_error(f'Unknown argument type {t} for positional arguent {argid}')
|
|
58
|
+
if self._lastpositem.get("argtype",'').endswith('.list'):
|
|
59
|
+
self.tool_error(f'Cannot have additional positional arguments after entry of type list')
|
|
60
|
+
self._posargsdef[argid.lower()] = {"argid":argid, "argtype":argtype, "argtext":argtext}
|
|
61
|
+
self._lastpositem = self._posargsdef[argid.lower()]
|
|
62
|
+
|
|
63
|
+
def add_namedargdef(self, argid, argtype, argtext, argdefault=None, shell_req=False, multi_occurance=False):
|
|
64
|
+
if not argtype.split(':')[0] in self._knowntypes:
|
|
65
|
+
self.tool_error(f'Unknown argument type {argtype} for named arguent {argid}')
|
|
66
|
+
self._namedargsdef[argid.split('=')[0].lower()] = {"argid":argid, "argtype":argtype, "argtext":argtext, "argdefault":argdefault, "shell_req":shell_req, "multi_occurance":multi_occurance}
|
|
67
|
+
|
|
68
|
+
def check_gt_sym(self, m, id, argtype):
|
|
69
|
+
import gams.transfer as gt
|
|
70
|
+
typemap = {gt.Set:'set', gt.Alias:'set', gt.Parameter:'par', gt.Variable:'var', gt.Equation:'equ'}
|
|
71
|
+
try:
|
|
72
|
+
sym = m[id]
|
|
73
|
+
except:
|
|
74
|
+
self.tool_error(f'Could not find symbol "{id}" in GTP container')
|
|
75
|
+
|
|
76
|
+
ign, id_type, id_dim = argtype.split(':')
|
|
77
|
+
id_dim = int(id_dim)
|
|
78
|
+
if id_dim != -1 and id_dim != sym.dimension:
|
|
79
|
+
self.tool_error(f'Dimension of symbols "{id}" does not match expected {id_dim}<>{sym.dimension} (actual)')
|
|
80
|
+
if id_type != 'any' and typemap[type(sym)] not in id_type:
|
|
81
|
+
self.tool_error(f'Unexpected type {typemap[type(sym)]} of symbol "{id}", allow is/are {id_type}')
|
|
82
|
+
|
|
83
|
+
def convert_type(self, val, val_type='any'):
|
|
84
|
+
if "." in val_type:
|
|
85
|
+
v_type = val_type.split('.')[0]
|
|
86
|
+
else:
|
|
87
|
+
v_type = val_type
|
|
88
|
+
if v_type == "int":
|
|
89
|
+
try:
|
|
90
|
+
return int(val)
|
|
91
|
+
except:
|
|
92
|
+
self.tool_error(f'Cannot convert option value "{val}" into an integer')
|
|
93
|
+
elif v_type == "float":
|
|
94
|
+
try:
|
|
95
|
+
return float(val)
|
|
96
|
+
except:
|
|
97
|
+
self.tool_error(f'Cannot convert option value "{val}" into a float')
|
|
98
|
+
elif v_type == "id":
|
|
99
|
+
allowed = set(string.ascii_lowercase + string.ascii_uppercase + string.digits + '_')
|
|
100
|
+
if not set(val) <= allowed or len(val) == 0 or val[0] == "_" or len(val) > 63:
|
|
101
|
+
self.tool_error(f'String "{val}" is not a good GAMS identifier')
|
|
102
|
+
return val
|
|
103
|
+
elif v_type == "fnExist":
|
|
104
|
+
if not (os.path.isfile(val) and os.access(val, os.R_OK)):
|
|
105
|
+
self.tool_error(f'File "{val}" does not exist or cannot be read')
|
|
106
|
+
return val
|
|
107
|
+
else:
|
|
108
|
+
return val
|
|
109
|
+
|
|
110
|
+
def namedargs_val(self, key):
|
|
111
|
+
key = key.lower()
|
|
112
|
+
if key in self.namedargs:
|
|
113
|
+
if self._namedargsdef[key]["multi_occurance"]:
|
|
114
|
+
return [ self.namedargs_list[i][1] for i in self.namedargs[key] ]
|
|
115
|
+
else:
|
|
116
|
+
return self.namedargs[key]
|
|
117
|
+
else:
|
|
118
|
+
return self._namedargsdef[key]["argdefault"]
|
|
119
|
+
|
|
120
|
+
def _check_ids(self, m, io):
|
|
121
|
+
# positional arguments
|
|
122
|
+
for n,ko in enumerate(self._posargsdef.items()):
|
|
123
|
+
k,o = ko
|
|
124
|
+
if o["argtype"].startswith(f'id.{io}'):
|
|
125
|
+
self.check_gt_sym(m,self.posargs[n],o["argtype"])
|
|
126
|
+
if len(self._posargsdef) < len(self.posargs) and self._lastpositem["argtype"] == f'id.{io}.list':
|
|
127
|
+
for id in self.posargs[len(self._posargsdef):]:
|
|
128
|
+
self.check_gt_sym(m,id,self._lastpositem["argtype"])
|
|
129
|
+
# named arguments
|
|
130
|
+
for k,o in self._namedargsdef.items():
|
|
131
|
+
if k in self.namedargs and o["argtype"].startswith(f'id.{io}'):
|
|
132
|
+
if o["multi_occurance"]:
|
|
133
|
+
for lp in self.namedargs[k]:
|
|
134
|
+
self.check_gt_sym(m,self.namedargs_list[lp][1],o["argtype"])
|
|
135
|
+
else:
|
|
136
|
+
self.check_gt_sym(m,self.namedargs[k],o["argtype"])
|
|
137
|
+
|
|
138
|
+
def check_input_ids(self, m):
|
|
139
|
+
self._check_ids(m,'in')
|
|
140
|
+
|
|
141
|
+
def check_output_ids(self, m):
|
|
142
|
+
self._check_ids(m,'out')
|
|
143
|
+
|
|
144
|
+
def process_args(self):
|
|
145
|
+
numpos = 0
|
|
146
|
+
argv_start = 1
|
|
147
|
+
posarglist = False
|
|
148
|
+
# Process positional arguments
|
|
149
|
+
for s in self._tools._argv[argv_start:]:
|
|
150
|
+
if posarglist: # stop when we have a named argument
|
|
151
|
+
if "=" in s: break
|
|
152
|
+
if s[0] == "-": break
|
|
153
|
+
if s.lower() in self._namedargsdef: break
|
|
154
|
+
else:
|
|
155
|
+
if numpos == len(self._posargsdef):
|
|
156
|
+
break
|
|
157
|
+
numpos += 1
|
|
158
|
+
if ("=" in s) and ((s.split('=')[0]).lower() in self._namedargsdef):
|
|
159
|
+
self.tool_error(f'Looking for positional argument no {numpos}. Got positional argument {(s.split("=")[0]).lower()}')
|
|
160
|
+
if s[0] == "-":
|
|
161
|
+
self.tool_error(f'Looking for positional argument no {numpos}. Got token ({s}) starting with "-"')
|
|
162
|
+
posarglist = len(self._posargsdef) == numpos and self._lastpositem["argtype"].endswith('.list')
|
|
163
|
+
arg_value = self.convert_type(s,list(self._posargsdef.items())[numpos-1][1]["argtype"])
|
|
164
|
+
self.posargs.append(arg_value)
|
|
165
|
+
argv_start += 1
|
|
166
|
+
|
|
167
|
+
if not posarglist and len(self.posargs) != len(self._posargsdef):
|
|
168
|
+
self.tool_error(f'Expect {len(self._posargsdef)} argument(s), got {self.posargs}.')
|
|
169
|
+
|
|
170
|
+
# Process named arguments
|
|
171
|
+
proc_value = False
|
|
172
|
+
alist = self._tools._argv[argv_start:]
|
|
173
|
+
while len(alist):
|
|
174
|
+
if not proc_value:
|
|
175
|
+
key = alist.pop(0)
|
|
176
|
+
if "=" in key:
|
|
177
|
+
kv = key.split('=')
|
|
178
|
+
if len(kv) > 2:
|
|
179
|
+
self.tool_error(f'More than one "=" in argument token "{key}"')
|
|
180
|
+
key = kv[0]
|
|
181
|
+
if len(kv[1]):
|
|
182
|
+
alist.insert(0,kv[1])
|
|
183
|
+
if key[0] == "-": key = key[1:]
|
|
184
|
+
key = key.lower()
|
|
185
|
+
if not key in self._namedargsdef:
|
|
186
|
+
#self.help()
|
|
187
|
+
self.tool_error(f'Unknown named argument "{key}"')
|
|
188
|
+
if self._namedargsdef[key]["argtype"] == "None":
|
|
189
|
+
address = len(self.namedargs_list)
|
|
190
|
+
self.namedargs_list.append((key,None))
|
|
191
|
+
if self._namedargsdef[key]["multi_occurance"]:
|
|
192
|
+
if key in self.namedargs:
|
|
193
|
+
self.namedargs[key].append(address)
|
|
194
|
+
else:
|
|
195
|
+
self.namedargs[key] = [address]
|
|
196
|
+
else:
|
|
197
|
+
self.namedargs[key] = None # set or update
|
|
198
|
+
if len(alist) == 0:
|
|
199
|
+
break
|
|
200
|
+
else:
|
|
201
|
+
proc_value = True
|
|
202
|
+
continue
|
|
203
|
+
else: # process value
|
|
204
|
+
val = alist.pop(0)
|
|
205
|
+
if val == "=":
|
|
206
|
+
continue
|
|
207
|
+
if val[0] == "=": val = val[1:]
|
|
208
|
+
address = len(self.namedargs_list)
|
|
209
|
+
if self._namedargsdef[key]["argtype"].endswith('.list'):
|
|
210
|
+
val_list = [ self.convert_type(li.strip(),self._namedargsdef[key]["argtype"]) for li in val.split(',') if len(li)]
|
|
211
|
+
self.namedargs_list.append((key,val_list))
|
|
212
|
+
else:
|
|
213
|
+
self.namedargs_list.append((key,self.convert_type(val,self._namedargsdef[key]["argtype"])))
|
|
214
|
+
if self._namedargsdef[key]["multi_occurance"]:
|
|
215
|
+
if key in self.namedargs:
|
|
216
|
+
self.namedargs[key].append(address)
|
|
217
|
+
else:
|
|
218
|
+
self.namedargs[key] = [address]
|
|
219
|
+
else:
|
|
220
|
+
self.namedargs[key] = self.namedargs_list[-1][1] # set or update
|
|
221
|
+
proc_value = False
|
|
222
|
+
if proc_value:
|
|
223
|
+
self.tool_error(f'Unexpected end while processing value for argument {key}')
|
|
224
|
+
|
|
225
|
+
if not self._tools._ecdb:
|
|
226
|
+
for k,o in self._namedargsdef.items():
|
|
227
|
+
if o["shell_req"] and not k in self.namedargs:
|
|
228
|
+
self.tool_error(f'Command line use requires {o["argid"]}.')
|
|
229
|
+
if "trace" in self.namedargs:
|
|
230
|
+
self._trace = int(self.namedargs["trace"])
|
|
231
|
+
|
|
232
|
+
def read_id_inputs(self, m, inputs):
|
|
233
|
+
if 'gdxin' in self.namedargs: # get data from GDX
|
|
234
|
+
try:
|
|
235
|
+
m.read(self.namedargs['gdxin'], inputs)
|
|
236
|
+
except Exception as e:
|
|
237
|
+
self.tool_error(str(e))
|
|
238
|
+
else:
|
|
239
|
+
try:
|
|
240
|
+
m.read(self._tools._ecdb._gmd, inputs)
|
|
241
|
+
except Exception as e:
|
|
242
|
+
self.tool_error(str(e))
|
|
243
|
+
self.check_input_ids(m)
|
|
244
|
+
|
|
245
|
+
def write_id_outputs(self, m, outputs):
|
|
246
|
+
self.check_output_ids(m)
|
|
247
|
+
if 'gdxout' in self.namedargs: # write data to GDX
|
|
248
|
+
try:
|
|
249
|
+
m.write(self.namedargs['gdxout'], outputs)
|
|
250
|
+
except Exception as e:
|
|
251
|
+
self.tool_error(str(e))
|
|
252
|
+
else:
|
|
253
|
+
try:
|
|
254
|
+
m.write(self._tools._ecdb._gmd, outputs)
|
|
255
|
+
except Exception as e:
|
|
256
|
+
self.tool_error(str(e))
|
|
257
|
+
|
|
258
|
+
def dohelp(self):
|
|
259
|
+
if len(self._tools._argv) == 1 or self._tools._argv[1].lower() == "-h":
|
|
260
|
+
self.help(long=False)
|
|
261
|
+
return True
|
|
262
|
+
elif self._tools._argv[1].lower() == "--help":
|
|
263
|
+
self.help()
|
|
264
|
+
return True
|
|
265
|
+
else:
|
|
266
|
+
return False
|
|
267
|
+
|
|
268
|
+
def help(self, prefix='', long=True):
|
|
269
|
+
self._tools.print_log(f'{prefix}{self.title}')
|
|
270
|
+
usage = f"Usage: {self.title.split(':')[0]}"
|
|
271
|
+
maxlen = -1
|
|
272
|
+
for k,o in self._posargsdef.items():
|
|
273
|
+
if len(usage) > 75:
|
|
274
|
+
self._tools.print_log(f'{prefix}{usage}')
|
|
275
|
+
usage = " "*len(f"Usage: {self.title.split(':')[0]}")
|
|
276
|
+
usage += f' {o["argid"]}'
|
|
277
|
+
maxlen = max(maxlen,len(o["argid"]))
|
|
278
|
+
for k,o in self._namedargsdef.items():
|
|
279
|
+
if len(usage) > 75:
|
|
280
|
+
self._tools.print_log(f'{prefix}{usage}')
|
|
281
|
+
usage = " "*len(f"Usage: {self.title.split(':')[0]}")
|
|
282
|
+
usage += f' {o["argid"]}'
|
|
283
|
+
maxlen = max(maxlen,len(o["argid"].split('=')[0]))
|
|
284
|
+
self._tools.print_log(f'{prefix}{usage}')
|
|
285
|
+
if long:
|
|
286
|
+
for k,o in self._posargsdef.items():
|
|
287
|
+
s = f'{o["argid"]}:'.ljust(maxlen+2)
|
|
288
|
+
self._tools.print_log(f'{prefix} {s} {o["argtext"]}')
|
|
289
|
+
for k,o in self._namedargsdef.items():
|
|
290
|
+
s = f'{o["argid"].split("=")[0]}:'.ljust(maxlen+2)
|
|
291
|
+
t = o["argtext"]
|
|
292
|
+
if "\n" in t:
|
|
293
|
+
pf = " "*len(f'{prefix} {s} ')
|
|
294
|
+
if not o["argdefault"] is None:
|
|
295
|
+
t = t.replace('\n',f' (default {o["argdefault"]})\n',1)
|
|
296
|
+
t = t.replace('\n','\n'+pf)
|
|
297
|
+
else:
|
|
298
|
+
if not o["argdefault"] is None:
|
|
299
|
+
t = t + f' (default {o["argdefault"]})'
|
|
300
|
+
self._tools.print_log(f'{prefix} {s} {t}')
|
|
301
|
+
|
|
302
|
+
def tool_error(self, msg, print_help=True):
|
|
303
|
+
if print_help:
|
|
304
|
+
self.help(long=False)
|
|
305
|
+
raise GamsToolsException(msg, error_code=1, traceback=self._trace>0)
|
|
306
|
+
|
|
307
|
+
def is_upper_matrix(self, a):
|
|
308
|
+
if not np.allclose(a, a.T):
|
|
309
|
+
if not np.allclose(a, np.tril(a)):
|
|
310
|
+
if np.allclose(a, np.triu(a)):
|
|
311
|
+
return True
|
|
312
|
+
else:
|
|
313
|
+
self.tool_error(f'Matrix {A} is not symmetric and does not have a triangular structure.', print_help=False)
|
|
314
|
+
return False
|
|
315
|
+
|
|
316
|
+
@abstractmethod
|
|
317
|
+
def execute(self):
|
|
318
|
+
'''
|
|
319
|
+
Called by Tools. This abstract method needs to be implemented by a subclass.
|
|
320
|
+
'''
|
|
321
|
+
...
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#
|
|
2
|
+
# GAMS - General Algebraic Modeling System Python API
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
|
|
5
|
+
# Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#
|
|
2
|
+
# GAMS - General Algebraic Modeling System Python API
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
|
|
5
|
+
# Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
|
|
26
|
+
from gams.tools.toolcollection.tooltemplate import ToolTemplate
|
|
27
|
+
import os
|
|
28
|
+
|
|
29
|
+
class Excelmerge (ToolTemplate):
|
|
30
|
+
|
|
31
|
+
def __init__(self, system_directory, tool):
|
|
32
|
+
super().__init__(system_directory, tool)
|
|
33
|
+
self.title = 'excelmerge: Merges the sheets of the source Excel workbook into the destination workbook (MS Windows only).'
|
|
34
|
+
self.add_posargdef('sourceExcelFile', 'fnExist', 'Source Excel workbook filename')
|
|
35
|
+
self.add_posargdef('targetExcelFile', 'str', 'Merged Excel workbook filename')
|
|
36
|
+
|
|
37
|
+
def execute(self):
|
|
38
|
+
if self.dohelp():
|
|
39
|
+
return
|
|
40
|
+
if os.name != 'nt':
|
|
41
|
+
self.tool_error('excelmerge only for MS Windows', print_help=False)
|
|
42
|
+
|
|
43
|
+
self.process_args()
|
|
44
|
+
sourceName, targetName = self.posargs
|
|
45
|
+
|
|
46
|
+
try:
|
|
47
|
+
import win32com.client as w3c
|
|
48
|
+
|
|
49
|
+
xl = w3c.gencache.EnsureDispatch("Excel.Application")
|
|
50
|
+
except:
|
|
51
|
+
self.tool_error(f'Could not dispatch Excel', print_help=False)
|
|
52
|
+
|
|
53
|
+
if not os.path.isabs(targetName):
|
|
54
|
+
targetName = os.path.join(os.getcwd(), targetName)
|
|
55
|
+
if not os.path.isabs(sourceName):
|
|
56
|
+
sourceName = os.path.join(os.getcwd(), sourceName)
|
|
57
|
+
|
|
58
|
+
try:
|
|
59
|
+
target = xl.Workbooks.Open(Filename=targetName)
|
|
60
|
+
except:
|
|
61
|
+
self.tool_error(f'Could not open target Excel workbook "{targetName}"', print_help=False)
|
|
62
|
+
|
|
63
|
+
target_sheetnames = {sheet.Name: i for i, sheet in enumerate(target.Sheets)}
|
|
64
|
+
|
|
65
|
+
# required to overide the delete prompt shown by MS-Excel
|
|
66
|
+
xl.DisplayAlerts = False
|
|
67
|
+
|
|
68
|
+
try:
|
|
69
|
+
source_sheets = xl.Workbooks.Open(Filename=sourceName).Sheets
|
|
70
|
+
except:
|
|
71
|
+
self.tool_error(f'Could not extract sheets from Excel workbook "{sourceName}"', print_help=False)
|
|
72
|
+
|
|
73
|
+
for sheet in source_sheets:
|
|
74
|
+
if not sheet.Name in target_sheetnames.keys():
|
|
75
|
+
sheet.Copy(Before=None, After=target.Worksheets(target.Sheets.Count)) # append at the end
|
|
76
|
+
else:
|
|
77
|
+
# if only one sheet exists in dest add a temporary sheet so workbook is never empty
|
|
78
|
+
if target.Sheets.Count == 1:
|
|
79
|
+
add_dummy_sheet = target.Sheets.Add(Before = None , After = target.Sheets(1))
|
|
80
|
+
target.Worksheets(sheet.Name).Delete()
|
|
81
|
+
sheet.Copy(Before=target.Worksheets(1))
|
|
82
|
+
add_dummy_sheet.Delete()
|
|
83
|
+
else:
|
|
84
|
+
target.Worksheets(sheet.Name).Delete()
|
|
85
|
+
if target_sheetnames[sheet.Name] == 0:
|
|
86
|
+
sheet.Copy(Before=target.Worksheets(1))
|
|
87
|
+
else:
|
|
88
|
+
sheet.Copy(Before=None, After=target.Worksheets(target_sheetnames[sheet.Name]))
|
|
89
|
+
try:
|
|
90
|
+
target.Close(SaveChanges=True)
|
|
91
|
+
xl.Quit()
|
|
92
|
+
except:
|
|
93
|
+
self.tool_error(f'Could not save and close Excel workbook "{targetName}"', print_help=False)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#
|
|
2
|
+
# GAMS - General Algebraic Modeling System Python API
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
|
|
5
|
+
# Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
|
|
26
|
+
from gams.tools.toolcollection.tooltemplate import ToolTemplate
|
|
27
|
+
import os
|
|
28
|
+
|
|
29
|
+
class Exceltalk (ToolTemplate):
|
|
30
|
+
|
|
31
|
+
def __init__(self, system_directory, tool):
|
|
32
|
+
super().__init__(system_directory, tool)
|
|
33
|
+
self.title = 'exceltalk: Performs command on an Excel workbook specified by filename (MS Windows only).'
|
|
34
|
+
self.add_posargdef('command', 'str', 'Recognized commands are\n close: Close workbook ignoring changes\n open: Opens workbook\n saveAndClose: Perform save & close of the workbook')
|
|
35
|
+
self.add_posargdef('excelFile', 'fnExist', 'Excel workbook filename')
|
|
36
|
+
self.add_namedargdef('quit=0|1', 'int', 'Determines if Excel program should be terminated or not', argdefault=0)
|
|
37
|
+
|
|
38
|
+
def execute(self):
|
|
39
|
+
if self.dohelp():
|
|
40
|
+
return
|
|
41
|
+
if os.name != 'nt':
|
|
42
|
+
self.tool_error('exceltalk only for MS Windows', print_help=False)
|
|
43
|
+
|
|
44
|
+
self.process_args()
|
|
45
|
+
command, excelFile = self.posargs
|
|
46
|
+
quitExcel = self.namedargs_val("quit")
|
|
47
|
+
|
|
48
|
+
try:
|
|
49
|
+
import win32com.client as w3c
|
|
50
|
+
|
|
51
|
+
xl = w3c.gencache.EnsureDispatch("Excel.Application")
|
|
52
|
+
except:
|
|
53
|
+
self.tool_error(f'Could not dispatch Excel', print_help=False)
|
|
54
|
+
|
|
55
|
+
if command.lower() in ['close', 'saveandclose']:
|
|
56
|
+
excelFile = os.path.basename(excelFile)
|
|
57
|
+
for obj in xl.Workbooks:
|
|
58
|
+
if obj.Name.lower() == excelFile.lower():
|
|
59
|
+
wb = obj
|
|
60
|
+
break
|
|
61
|
+
else:
|
|
62
|
+
self.tool_error(f'No workbook with name "{excelFile}" found', print_help=False)
|
|
63
|
+
try:
|
|
64
|
+
wb.Close(SaveChanges=command.lower() == 'saveandclose')
|
|
65
|
+
except:
|
|
66
|
+
self.tool_error(f'Could not close Excel workbook {excelFile}', print_help=False)
|
|
67
|
+
elif command.lower() == 'open':
|
|
68
|
+
try:
|
|
69
|
+
xl.Visible = True
|
|
70
|
+
xl.Workbooks.Open(os.path.abspath(excelFile))
|
|
71
|
+
except:
|
|
72
|
+
self.tool_error(f'Could not open Excel workbook {os.path.abspath(excelFile)}', print_help=False)
|
|
73
|
+
else:
|
|
74
|
+
self.tool_error(f'Unknown command : "{command}"')
|
|
75
|
+
if quitExcel != 0:
|
|
76
|
+
xl.Quit()
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#
|
|
2
|
+
# GAMS - General Algebraic Modeling System Python API
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
|
|
5
|
+
# Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
|
|
26
|
+
from gams.tools.toolcollection.tooltemplate import ToolTemplate
|
|
27
|
+
import os
|
|
28
|
+
|
|
29
|
+
class Msappavail (ToolTemplate):
|
|
30
|
+
|
|
31
|
+
def __init__(self, system_directory, tool):
|
|
32
|
+
super().__init__(system_directory, tool)
|
|
33
|
+
self.title = 'msappavail: Checks if a MS Office Application is available (MS Windows only).'
|
|
34
|
+
self.add_posargdef('application', 'str', 'MS Office application name')
|
|
35
|
+
|
|
36
|
+
def execute(self):
|
|
37
|
+
if self.dohelp():
|
|
38
|
+
return
|
|
39
|
+
if os.name != 'nt':
|
|
40
|
+
self.tool_error('msappavail only for MS Windows', print_help=False)
|
|
41
|
+
|
|
42
|
+
self.process_args()
|
|
43
|
+
import ctypes
|
|
44
|
+
try:
|
|
45
|
+
rc = ctypes.oledll.ole32.CLSIDFromProgID(f'{self.posargs[0]}.Application',ctypes.byref(ctypes.c_void_p()))
|
|
46
|
+
except:
|
|
47
|
+
rc = 1
|
|
48
|
+
if 0 != rc:
|
|
49
|
+
self.tool_error(f'Application {self.posargs[0]} not available', print_help=False)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#
|
|
2
|
+
# GAMS - General Algebraic Modeling System Python API
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2017-2026 GAMS Development Corp. <support@gams.com>
|
|
5
|
+
# Copyright (c) 2017-2026 GAMS Software GmbH <support@gams.com>
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
# copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
# SOFTWARE.
|
|
24
|
+
#
|
|
25
|
+
|
|
26
|
+
from gams.tools.toolcollection.tooltemplate import ToolTemplate
|
|
27
|
+
import os
|
|
28
|
+
|
|
29
|
+
class Shellexecute (ToolTemplate):
|
|
30
|
+
|
|
31
|
+
def __init__(self, system_directory, tool):
|
|
32
|
+
super().__init__(system_directory, tool)
|
|
33
|
+
self.title = 'shellexecute: This allows to spawn an external program based on the file type of the document to open. (MS Windows only)'
|
|
34
|
+
self.add_posargdef('progargs', 'str.list', 'Program and arguments')
|
|
35
|
+
self.add_namedargdef('dir=workdir', 'str', 'The directory where the file to be opened is located', argdefault='.')
|
|
36
|
+
self.add_namedargdef('verb=open|...', 'str', 'Action to be performed.\nThe allowed actions are application dependent.\nSome commonly available actions include\n-edit: Launches an editor and opens the document for editing\n-find: Initiates a search starting from the specified directory\n-open: Launches an application. If this file is not an executable file, its associated application is launched\nprint: Prints the document file\nproperties: Displays the objects properties', argdefault='open')
|
|
37
|
+
self.add_namedargdef('showCmd=0..11','int', 'Specifies how an application is to be displayed when it is opened\n The map between numerical values 0 to 11 and symbolic names can be found here:\nhttps://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow', argdefault=0)
|
|
38
|
+
|
|
39
|
+
def execute(self):
|
|
40
|
+
if self.dohelp():
|
|
41
|
+
return
|
|
42
|
+
if os.name != 'nt':
|
|
43
|
+
self.tool_error('shellexecute only for MS Windows', print_help=False)
|
|
44
|
+
|
|
45
|
+
self.process_args()
|
|
46
|
+
pargs = self.posargs[0].split()
|
|
47
|
+
|
|
48
|
+
import ctypes
|
|
49
|
+
try:
|
|
50
|
+
rc = ctypes.windll.shell32.ShellExecuteW(None, self.namedargs_val("verb"), pargs[0], ' '.join(pargs[1:]), self.namedargs_val("dir"), self.namedargs_val("showCmd"))
|
|
51
|
+
if rc < 32:
|
|
52
|
+
self.tool_error(ctypes.WinError())
|
|
53
|
+
except Exception as e:
|
|
54
|
+
self.tool_error(str(e), print_help=False)
|