codekingpro/portable-devtools
115k
1""" a clumsy attempt at a macro language to let the programmer execute code on the server (ex: determine 64bit)"""
2from . import is64bit as is64bit
3
4
5def macro_call(macro_name, args, kwargs):
6 """allow the programmer to perform limited processing on the server by passing macro names and args
7
8 :new_key - the key name the macro will create
9 :args[0] - macro name
10 :args[1:] - any arguments
11 :code - the value of the keyword item
12 :kwargs - the connection keyword dictionary. ??key has been removed
13 --> the value to put in for kwargs['name'] = value
14 """
15 if isinstance(args, (str, str)):
16 args = [
17 args
18 ] # the user forgot to pass a sequence, so make a string into args[0]
19 new_key = args[0]
20 try:
21 if macro_name == "is64bit":
22 if is64bit.Python(): # if on 64 bit Python
23 return new_key, args[1] # return first argument
24 else:
25 try:
26 return new_key, args[2] # else return second argument (if defined)
27 except IndexError:
28 return new_key, "" # else return blank
29
30 elif (
31 macro_name == "getuser"
32 ): # get the name of the user the server is logged in under
33 if not new_key in kwargs:
34 import getpass
35
36 return new_key, getpass.getuser()
37
38 elif macro_name == "getnode": # get the name of the computer running the server
39 import platform
40
41 try:
42 return new_key, args[1] % platform.node()
43 except IndexError:
44 return new_key, platform.node()
45
46 elif macro_name == "getenv": # expand the server's environment variable args[1]
47 try:
48 dflt = args[2] # if not found, default from args[2]
49 except IndexError: # or blank
50 dflt = ""
51 return new_key, os.environ.get(args[1], dflt)
52
53 elif macro_name == "auto_security":
54 if (
55 not "user" in kwargs or not kwargs["user"]
56 ): # missing, blank, or Null username
57 return new_key, "Integrated Security=SSPI"
58 return new_key, "User ID=%(user)s; Password=%(password)s" % kwargs
59
60 elif (
61 macro_name == "find_temp_test_path"
62 ): # helper function for testing ado operation -- undocumented
63 import os
64 import tempfile
65
66 return new_key, os.path.join(
67 tempfile.gettempdir(), "adodbapi_test", args[1]
68 )
69
70 raise ValueError("Unknown connect string macro=%s" % macro_name)
71 except:
72 raise ValueError("Error in macro processing %s %s" % (macro_name, repr(args)))
73
74
75def process(
76 args, kwargs, expand_macros=False
77): # --> connection string with keyword arguments processed.
78 """attempts to inject arguments into a connection string using Python "%" operator for strings
79
80 co: adodbapi connection object
81 args: positional parameters from the .connect() call
82 kvargs: keyword arguments from the .connect() call
83 """
84 try:
85 dsn = args[0]
86 except IndexError:
87 dsn = None
88 if isinstance(
89 dsn, dict
90 ): # as a convenience the first argument may be django settings
91 kwargs.update(dsn)
92 elif (
93 dsn
94 ): # the connection string is passed to the connection as part of the keyword dictionary
95 kwargs["connection_string"] = dsn
96 try:
97 a1 = args[1]
98 except IndexError:
99 a1 = None
100 # historically, the second positional argument might be a timeout value
101 if isinstance(a1, int):
102 kwargs["timeout"] = a1
103 # if the second positional argument is a string, then it is user
104 elif isinstance(a1, str):
105 kwargs["user"] = a1
106 # if the second positional argument is a dictionary, use it as keyword arguments, too
107 elif isinstance(a1, dict):
108 kwargs.update(a1)
109 try:
110 kwargs["password"] = args[2] # the third positional argument is password
111 kwargs["host"] = args[3] # the fourth positional argument is host name
112 kwargs["database"] = args[4] # the fifth positional argument is database name
113 except IndexError:
114 pass
115
116 # make sure connection string is defined somehow
117 if not "connection_string" in kwargs:
118 try: # perhaps 'dsn' was defined
119 kwargs["connection_string"] = kwargs["dsn"]
120 except KeyError:
121 try: # as a last effort, use the "host" keyword
122 kwargs["connection_string"] = kwargs["host"]
123 except KeyError:
124 raise TypeError("Must define 'connection_string' for ado connections")
125 if expand_macros:
126 for kwarg in list(kwargs.keys()):
127 if kwarg.startswith("macro_"): # If a key defines a macro
128 macro_name = kwarg[6:] # name without the "macro_"
129 macro_code = kwargs.pop(
130 kwarg
131 ) # we remove the macro_key and get the code to execute
132 new_key, rslt = macro_call(
133 macro_name, macro_code, kwargs
134 ) # run the code in the local context
135 kwargs[new_key] = rslt # put the result back in the keywords dict
136 # special processing for PyRO IPv6 host address
137 try:
138 s = kwargs["proxy_host"]
139 if ":" in s: # it is an IPv6 address
140 if s[0] != "[": # is not surrounded by brackets
141 kwargs["proxy_host"] = s.join(("[", "]")) # put it in brackets
142 except KeyError:
143 pass
144 return kwargs
145 