aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/lib
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:34 -0500
committerJacek Antonelli2008-08-15 23:45:34 -0500
commitcd17687f01420952712a500107e0f93e7ab8d5f8 (patch)
treece48c2b706f2c1176290e39fb555fbdf6648ce01 /linden/indra/lib
parentSecond Life viewer sources 1.19.0.5 (diff)
downloadmeta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.zip
meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.gz
meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.bz2
meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.xz
Second Life viewer sources 1.19.1.0
Diffstat (limited to 'linden/indra/lib')
-rw-r--r--linden/indra/lib/python/indra/base/config.py25
-rw-r--r--linden/indra/lib/python/indra/base/lllog.py72
-rw-r--r--linden/indra/lib/python/indra/base/lluuid.py21
-rw-r--r--linden/indra/lib/python/indra/base/metrics.py23
-rw-r--r--linden/indra/lib/python/indra/ipc/mysql_pool.py5
-rw-r--r--linden/indra/lib/python/indra/ipc/russ.py10
-rw-r--r--linden/indra/lib/python/indra/util/llsubprocess.py106
-rw-r--r--linden/indra/lib/python/indra/util/named_query.py48
-rw-r--r--linden/indra/lib/python/indra/util/shutil2.py84
9 files changed, 379 insertions, 15 deletions
diff --git a/linden/indra/lib/python/indra/base/config.py b/linden/indra/lib/python/indra/base/config.py
index eea733a..3865f5e 100644
--- a/linden/indra/lib/python/indra/base/config.py
+++ b/linden/indra/lib/python/indra/base/config.py
@@ -47,6 +47,25 @@ def load(indra_xml_file=None):
47 config_file.close() 47 config_file.close()
48 #print "loaded config from",indra_xml_file,"into",_g_config_dict 48 #print "loaded config from",indra_xml_file,"into",_g_config_dict
49 49
50def dump(indra_xml_file, indra_cfg={}, update_in_mem=False):
51 '''
52 Dump config contents into a file
53 Kindof reverse of load.
54 Optionally takes a new config to dump.
55 Does NOT update global config unless requested.
56 '''
57 global _g_config_dict
58 if not indra_cfg:
59 indra_cfg = _g_config_dict
60 if not indra_cfg:
61 return
62 config_file = open(indra_xml_file, 'w')
63 _config_xml = llsd.format_xml(indra_cfg)
64 config_file.write(_config_xml)
65 config_file.close()
66 if update_in_mem:
67 update(indra_cfg)
68
50def update(new_conf): 69def update(new_conf):
51 """Load an XML file and apply its map as overrides or additions 70 """Load an XML file and apply its map as overrides or additions
52 to the existing config. The dataserver does this with indra.xml 71 to the existing config. The dataserver does this with indra.xml
@@ -69,6 +88,12 @@ def get(key, default = None):
69 load() 88 load()
70 return _g_config_dict.get(key, default) 89 return _g_config_dict.get(key, default)
71 90
91def set(key, newval):
92 global _g_config_dict
93 if _g_config_dict == None:
94 load()
95 _g_config_dict[key] = newval
96
72def as_dict(): 97def as_dict():
73 global _g_config_dict 98 global _g_config_dict
74 return _g_config_dict 99 return _g_config_dict
diff --git a/linden/indra/lib/python/indra/base/lllog.py b/linden/indra/lib/python/indra/base/lllog.py
new file mode 100644
index 0000000..99c50ef
--- /dev/null
+++ b/linden/indra/lib/python/indra/base/lllog.py
@@ -0,0 +1,72 @@
1"""\
2@file lllog.py
3@brief Logging for event processing
4
5$LicenseInfo:firstyear=2008&license=mit$
6
7Copyright (c) 2008, Linden Research, Inc.
8
9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal
11in the Software without restriction, including without limitation the rights
12to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13copies of the Software, and to permit persons to whom the Software is
14furnished to do so, subject to the following conditions:
15
16The above copyright notice and this permission notice shall be included in
17all copies or substantial portions of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25THE SOFTWARE.
26$/LicenseInfo$
27"""
28
29from indra.base.llsd import format_notation
30
31try:
32 import syslog
33except ImportError:
34 # Windows
35 import sys
36
37 class syslog(object):
38 _logfp = sys.stderr
39
40 def syslog(msg):
41 _logfp.write(msg)
42 if not msg.endswith('\n'):
43 _logfp.write('\n')
44
45 syslog = staticmethod(syslog)
46
47class Logger(object):
48 def __init__(self, name='indra'):
49 self._sequence = 0
50 try:
51 syslog.openlog(name, syslog.LOG_CONS | syslog.LOG_PID,
52 syslog.LOG_LOCAL0)
53 except AttributeError:
54 # No syslog module on Windows
55 pass
56
57 def next(self):
58 self._sequence += 1
59 return self._sequence
60
61 def log(self, msg, llsd):
62 payload = 'LLLOGMESSAGE (%d) %s %s' % (self.next(), msg,
63 format_notation(llsd))
64 syslog.syslog(payload)
65
66_logger = None
67
68def log(msg, llsd):
69 global _logger
70 if _logger is None:
71 _logger = Logger()
72 _logger.log(msg, llsd)
diff --git a/linden/indra/lib/python/indra/base/lluuid.py b/linden/indra/lib/python/indra/base/lluuid.py
index f173310..dd336f0 100644
--- a/linden/indra/lib/python/indra/base/lluuid.py
+++ b/linden/indra/lib/python/indra/base/lluuid.py
@@ -227,16 +227,31 @@ def printTranslatedMemory(four_hex_uints):
227 uuid.setFromMemoryDump(four_hex_uints) 227 uuid.setFromMemoryDump(four_hex_uints)
228 print uuid.toString() 228 print uuid.toString()
229 229
230def isPossiblyID(id_str): 230def isUUID(id_str):
231 """ 231 """
232 This function returns 1 if the string passed has some uuid-like 232 This function returns:
233 characteristics. Otherwise returns 0. 233 - 1 if the string passed is a UUID
234 - 0 is the string passed is not a UUID
235 - None if it neither of the if's below is satisfied
234 """ 236 """
235 if not id_str or len(id_str) < 5 or len(id_str) > 36: 237 if not id_str or len(id_str) < 5 or len(id_str) > 36:
236 return 0 238 return 0
237 239
238 if isinstance(id_str, UUID) or UUID.uuid_regex.match(id_str): 240 if isinstance(id_str, UUID) or UUID.uuid_regex.match(id_str):
239 return 1 241 return 1
242
243 return None
244
245def isPossiblyID(id_str):
246 """
247 This function returns 1 if the string passed has some uuid-like
248 characteristics. Otherwise returns 0.
249 """
250
251 is_uuid = isUUID(id_str)
252 if is_uuid is not None:
253 return is_uuid
254
240 # build a string which matches every character. 255 # build a string which matches every character.
241 hex_wildcard = r"[0-9a-fA-F]" 256 hex_wildcard = r"[0-9a-fA-F]"
242 chars = len(id_str) 257 chars = len(id_str)
diff --git a/linden/indra/lib/python/indra/base/metrics.py b/linden/indra/lib/python/indra/base/metrics.py
index e640c45..04e6286 100644
--- a/linden/indra/lib/python/indra/base/metrics.py
+++ b/linden/indra/lib/python/indra/base/metrics.py
@@ -31,12 +31,23 @@ $/LicenseInfo$
31import sys 31import sys
32from indra.base import llsd 32from indra.base import llsd
33 33
34def log(location, stats, file=None): 34_sequence_id = 0
35 "Write a standard llmetrics log" 35
36 metrics = {'location':location, 'stats':stats} 36def record_metrics(table, stats, dest=None):
37 if file is None: 37 "Write a standard metrics log"
38 _log("LLMETRICS", table, stats, dest)
39
40def record_event(table, data, dest=None):
41 "Write a standard logmessage log"
42 _log("LLLOGMESSAGE", table, data, dest)
43
44def _log(header, table, data, dest):
45 if dest is None:
38 # do this check here in case sys.stdout changes at some 46 # do this check here in case sys.stdout changes at some
39 # point. as a default parameter, it will never be 47 # point. as a default parameter, it will never be
40 # re-evaluated. 48 # re-evaluated.
41 file = sys.stdout 49 dest = sys.stdout
42 print >>file, "LLMETRICS:", llsd.format_notation(metrics) 50 global _sequence_id
51 print >>dest, header, "(" + str(_sequence_id) + ")",
52 print >>dest, table, llsd.format_notation(data)
53 _sequence_id += 1
diff --git a/linden/indra/lib/python/indra/ipc/mysql_pool.py b/linden/indra/lib/python/indra/ipc/mysql_pool.py
index 0a06cdd..01e31bb 100644
--- a/linden/indra/lib/python/indra/ipc/mysql_pool.py
+++ b/linden/indra/lib/python/indra/ipc/mysql_pool.py
@@ -64,12 +64,13 @@ connection pools keyed on host,databasename"""
64 else: 64 else:
65 return self._credentials.get('default', None) 65 return self._credentials.get('default', None)
66 66
67 def get(self, host, dbname): 67 def get(self, host, dbname, port=3306):
68 key = (host, dbname) 68 key = (host, dbname, port)
69 if key not in self._databases: 69 if key not in self._databases:
70 new_kwargs = self._kwargs.copy() 70 new_kwargs = self._kwargs.copy()
71 new_kwargs['db'] = dbname 71 new_kwargs['db'] = dbname
72 new_kwargs['host'] = host 72 new_kwargs['host'] = host
73 new_kwargs['port'] = port
73 new_kwargs.update(self.credentials_for(host)) 74 new_kwargs.update(self.credentials_for(host))
74 dbpool = ConnectionPool(self._min_size, self._max_size, *self._args, **new_kwargs) 75 dbpool = ConnectionPool(self._min_size, self._max_size, *self._args, **new_kwargs)
75 self._databases[key] = dbpool 76 self._databases[key] = dbpool
diff --git a/linden/indra/lib/python/indra/ipc/russ.py b/linden/indra/lib/python/indra/ipc/russ.py
index a198acf..fbb1777 100644
--- a/linden/indra/lib/python/indra/ipc/russ.py
+++ b/linden/indra/lib/python/indra/ipc/russ.py
@@ -136,7 +136,15 @@ def _build_query_string(query_dict):
136 @returns Returns an urlencoded query string including leading '?'. 136 @returns Returns an urlencoded query string including leading '?'.
137 """ 137 """
138 if query_dict: 138 if query_dict:
139 return '?' + urllib.urlencode(query_dict) 139 keys = query_dict.keys()
140 keys.sort()
141 def stringize(value):
142 if type(value) in (str,unicode):
143 return value
144 else:
145 return str(value)
146 query_list = [urllib.quote(str(key)) + '=' + urllib.quote(stringize(query_dict[key])) for key in keys]
147 return '?' + '&'.join(query_list)
140 else: 148 else:
141 return '' 149 return ''
142 150
diff --git a/linden/indra/lib/python/indra/util/llsubprocess.py b/linden/indra/lib/python/indra/util/llsubprocess.py
new file mode 100644
index 0000000..1c107d9
--- /dev/null
+++ b/linden/indra/lib/python/indra/util/llsubprocess.py
@@ -0,0 +1,106 @@
1"""\
2@file llsubprocess.py
3@author Phoenix
4@date 2008-01-18
5@brief The simplest possible wrapper for a common sub-process paradigm.
6
7$LicenseInfo:firstyear=2007&license=mit$
8
9Copyright (c) 2007-2008, Linden Research, Inc.
10
11Permission is hereby granted, free of charge, to any person obtaining a copy
12of this software and associated documentation files (the "Software"), to deal
13in the Software without restriction, including without limitation the rights
14to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15copies of the Software, and to permit persons to whom the Software is
16furnished to do so, subject to the following conditions:
17
18The above copyright notice and this permission notice shall be included in
19all copies or substantial portions of the Software.
20
21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27THE SOFTWARE.
28$/LicenseInfo$
29"""
30
31import os
32import popen2
33import time
34import select
35
36class Timeout(RuntimeError):
37 "Exception raised when a subprocess times out."
38 pass
39
40def run(command, args=None, data=None, timeout=None):
41 """\
42@brief Run command with arguments
43
44This is it. This is the function I want to run all the time when doing
45subprocces, but end up copying the code everywhere. none of the
46standard commands are secure and provide a way to specify input, get
47all the output, and get the result.
48@param command A string specifying a process to launch.
49@param args Arguments to be passed to command. Must be list, tuple or None.
50@param data input to feed to the command.
51@param timeout Maximum number of many seconds to run.
52@return Returns (result, stdout, stderr) from process.
53"""
54 cmd = [command]
55 if args:
56 cmd.extend([str(arg) for arg in args])
57 #print "cmd: ","' '".join(cmd)
58 child = popen2.Popen3(cmd, True)
59 #print child.pid
60 out = []
61 err = []
62 result = -1
63 time_left = timeout
64 tochild = [child.tochild.fileno()]
65 while True:
66 time_start = time.time()
67 #print "time:",time_left
68 p_in, p_out, p_err = select.select(
69 [child.fromchild.fileno(), child.childerr.fileno()],
70 tochild,
71 [],
72 time_left)
73 if p_in:
74 new_line = os.read(child.fromchild.fileno(), 32 * 1024)
75 if new_line:
76 #print "line:",new_line
77 out.append(new_line)
78 new_line = os.read(child.childerr.fileno(), 32 * 1024)
79 if new_line:
80 #print "error:", new_line
81 err.append(new_line)
82 if p_out:
83 if data:
84 #print "p_out"
85 bytes = os.write(child.tochild.fileno(), data)
86 data = data[bytes:]
87 if len(data) == 0:
88 data = None
89 tochild = []
90 child.tochild.close()
91 result = child.poll()
92 if result != -1:
93 child.tochild.close()
94 child.fromchild.close()
95 child.childerr.close()
96 break
97 if time_left is not None:
98 time_left -= (time.time() - time_start)
99 if time_left < 0:
100 raise Timeout
101 #print "result:",result
102 out = ''.join(out)
103 #print "stdout:", out
104 err = ''.join(err)
105 #print "stderr:", err
106 return result, out, err
diff --git a/linden/indra/lib/python/indra/util/named_query.py b/linden/indra/lib/python/indra/util/named_query.py
index c462d9f..c52bfde 100644
--- a/linden/indra/lib/python/indra/util/named_query.py
+++ b/linden/indra/lib/python/indra/util/named_query.py
@@ -495,9 +495,51 @@ class _RewriteQueryForArray(object):
495 if type(value) in (list,tuple): 495 if type(value) in (list,tuple):
496 rv = [] 496 rv = []
497 for idx in range(len(value)): 497 for idx in range(len(value)):
498 new_key = "_" + key + "_" + str(idx) 498 # if the value@idx is array-like, we are
499 self.new_params[new_key] = value[idx] 499 # probably dealing with a VALUES
500 rv.append("%(" + new_key + ")s") 500 new_key = "_%s_%s"%(key, str(idx))
501 val_item = value[idx]
502 if type(val_item) in (list, tuple, dict):
503 if type(val_item) is dict:
504 # this is because in Python, the order of
505 # key, value retrieval from the dict is not
506 # guaranteed to match what the input intended
507 # and for VALUES, order is important.
508 # TODO: Implemented ordered dict in LLSD parser?
509 raise ExpectationFailed('Only lists/tuples allowed,\
510 received dict')
511 values_keys = []
512 for value_idx, item in enumerate(val_item):
513 # we want a key of the format :
514 # key_#replacement_#value_row_#value_col
515 # ugh... so if we are replacing 10 rows in user_note,
516 # the first values clause would read (for @:user_notes) :-
517 # ( :_user_notes_0_1_1, :_user_notes_0_1_2, :_user_notes_0_1_3 )
518 # the input LLSD for VALUES will look like:
519 # <llsd>...
520 # <map>
521 # <key>user_notes</key>
522 # <array>
523 # <array> <!-- row 1 for VALUES -->
524 # <string>...</string>
525 # <string>...</string>
526 # <string>...</string>
527 # </array>
528 # ...
529 # </array>
530 # </map>
531 # ... </llsd>
532 values_key = "%s_%s"%(new_key, value_idx)
533 self.new_params[values_key] = item
534 values_keys.append("%%(%s)s"%values_key)
535 # now collapse all these new place holders enclosed in ()
536 # from [':_key_0_1_1', ':_key_0_1_2', ':_key_0_1_3,...]
537 # rv will have [ '(:_key_0_1_1, :_key_0_1_2, :_key_0_1_3)', ]
538 # which is flattened a few lines below join(rv)
539 rv.append('(%s)' % ','.join(values_keys))
540 else:
541 self.new_params[new_key] = val_item
542 rv.append("%%(%s)s"%new_key)
501 return ','.join(rv) 543 return ','.join(rv)
502 else: 544 else:
503 # not something that can be expanded, so just drop the 545 # not something that can be expanded, so just drop the
diff --git a/linden/indra/lib/python/indra/util/shutil2.py b/linden/indra/lib/python/indra/util/shutil2.py
new file mode 100644
index 0000000..2c504c2
--- /dev/null
+++ b/linden/indra/lib/python/indra/util/shutil2.py
@@ -0,0 +1,84 @@
1'''
2@file shutil2.py
3@brief a better shutil.copytree replacement
4
5$LicenseInfo:firstyear=2007&license=mit$
6
7Copyright (c) 2007-2008, Linden Research, Inc.
8
9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal
11in the Software without restriction, including without limitation the rights
12to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13copies of the Software, and to permit persons to whom the Software is
14furnished to do so, subject to the following conditions:
15
16The above copyright notice and this permission notice shall be included in
17all copies or substantial portions of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25THE SOFTWARE.
26$/LicenseInfo$
27'''
28
29#
30# shutil2.py
31# Taken from http://www.scons.org/wiki/AccumulateBuilder
32# the stock copytree sucks because it insists that the
33# target dir not exist
34#
35
36import os.path
37import shutil
38
39def copytree(src, dest, symlinks=False):
40 """My own copyTree which does not fail if the directory exists.
41
42 Recursively copy a directory tree using copy2().
43
44 If the optional symlinks flag is true, symbolic links in the
45 source tree result in symbolic links in the destination tree; if
46 it is false, the contents of the files pointed to by symbolic
47 links are copied.
48
49 Behavior is meant to be identical to GNU 'cp -R'.
50 """
51 def copyItems(src, dest, symlinks=False):
52 """Function that does all the work.
53
54 It is necessary to handle the two 'cp' cases:
55 - destination does exist
56 - destination does not exist
57
58 See 'cp -R' documentation for more details
59 """
60 for item in os.listdir(src):
61 srcPath = os.path.join(src, item)
62 if os.path.isdir(srcPath):
63 srcBasename = os.path.basename(srcPath)
64 destDirPath = os.path.join(dest, srcBasename)
65 if not os.path.exists(destDirPath):
66 os.makedirs(destDirPath)
67 copyItems(srcPath, destDirPath)
68 elif os.path.islink(item) and symlinks:
69 linkto = os.readlink(item)
70 os.symlink(linkto, dest)
71 else:
72 shutil.copy2(srcPath, dest)
73
74 # case 'cp -R src/ dest/' where dest/ already exists
75 if os.path.exists(dest):
76 destPath = os.path.join(dest, os.path.basename(src))
77 if not os.path.exists(destPath):
78 os.makedirs(destPath)
79 # case 'cp -R src/ dest/' where dest/ does not exist
80 else:
81 os.makedirs(dest)
82 destPath = dest
83 # actually copy the files
84 copyItems(src, destPath)