zenysis-py77 0.2.1__tar.gz

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.
Files changed (155) hide show
  1. zenysis_py77-0.2.1/LICENSE +21 -0
  2. zenysis_py77-0.2.1/PKG-INFO +63 -0
  3. zenysis_py77-0.2.1/README.md +43 -0
  4. zenysis_py77-0.2.1/pylib/__init__.py +0 -0
  5. zenysis_py77-0.2.1/pylib/base/__init__.py +0 -0
  6. zenysis_py77-0.2.1/pylib/base/environment.py +17 -0
  7. zenysis_py77-0.2.1/pylib/base/exec_utils.py +263 -0
  8. zenysis_py77-0.2.1/pylib/base/flags.py +35 -0
  9. zenysis_py77-0.2.1/pylib/base/term_color.py +129 -0
  10. zenysis_py77-0.2.1/pylib/config/__init__.py +0 -0
  11. zenysis_py77-0.2.1/pylib/config/r77_init.py +54 -0
  12. zenysis_py77-0.2.1/pylib/file/__init__.py +0 -0
  13. zenysis_py77-0.2.1/pylib/file/file_utils.py +446 -0
  14. zenysis_py77-0.2.1/pylib/file/parse_include_list.py +44 -0
  15. zenysis_py77-0.2.1/pylib/flash/__init__.py +0 -0
  16. zenysis_py77-0.2.1/pylib/flash/build.py +129 -0
  17. zenysis_py77-0.2.1/pylib/flash/cc_rules.py +174 -0
  18. zenysis_py77-0.2.1/pylib/flash/clean.py +73 -0
  19. zenysis_py77-0.2.1/pylib/flash/cmd_handler.py +140 -0
  20. zenysis_py77-0.2.1/pylib/flash/dep_graph.py +157 -0
  21. zenysis_py77-0.2.1/pylib/flash/flash.py +152 -0
  22. zenysis_py77-0.2.1/pylib/flash/gen_makefile.py +228 -0
  23. zenysis_py77-0.2.1/pylib/flash/js_rules.py +36 -0
  24. zenysis_py77-0.2.1/pylib/flash/make_rules.py +156 -0
  25. zenysis_py77-0.2.1/pylib/flash/ng_rules.py +35 -0
  26. zenysis_py77-0.2.1/pylib/flash/nge2e_rules.py +113 -0
  27. zenysis_py77-0.2.1/pylib/flash/pkg_rules.py +74 -0
  28. zenysis_py77-0.2.1/pylib/flash/proto_rules.py +91 -0
  29. zenysis_py77-0.2.1/pylib/flash/py_rules.py +91 -0
  30. zenysis_py77-0.2.1/pylib/flash/rules.py +576 -0
  31. zenysis_py77-0.2.1/pylib/flash/run.py +108 -0
  32. zenysis_py77-0.2.1/pylib/flash/swig_rules.py +132 -0
  33. zenysis_py77-0.2.1/pylib/flash/test.py +37 -0
  34. zenysis_py77-0.2.1/pylib/flash/url_rules_base.py +127 -0
  35. zenysis_py77-0.2.1/pylib/flash/utils.py +135 -0
  36. zenysis_py77-0.2.1/pylib/monitor/__init__.py +0 -0
  37. zenysis_py77-0.2.1/pylib/monitor/haproxy/__init__.py +0 -0
  38. zenysis_py77-0.2.1/pylib/monitor/haproxy/conditions.py +48 -0
  39. zenysis_py77-0.2.1/pylib/monitor/haproxy/haproxy_cluster_monitor_group.py +133 -0
  40. zenysis_py77-0.2.1/pylib/monitor/haproxy/haproxy_cluster_monitor_group_test.py +59 -0
  41. zenysis_py77-0.2.1/pylib/monitor/haproxy/haproxy_monitor.py +186 -0
  42. zenysis_py77-0.2.1/pylib/monitor/haproxy/haproxy_monitor_test.py +48 -0
  43. zenysis_py77-0.2.1/pylib/monitor/monitor_server.py +91 -0
  44. zenysis_py77-0.2.1/pylib/mps/__init__.py +0 -0
  45. zenysis_py77-0.2.1/pylib/mps/cluster/__init__.py +0 -0
  46. zenysis_py77-0.2.1/pylib/mps/cluster/cluster.py +591 -0
  47. zenysis_py77-0.2.1/pylib/mps/cluster/lazy.py +127 -0
  48. zenysis_py77-0.2.1/pylib/mps/cluster/multiplecmd.py +88 -0
  49. zenysis_py77-0.2.1/pylib/mps/cluster/packages.py +328 -0
  50. zenysis_py77-0.2.1/pylib/mps/packager/__init__.py +0 -0
  51. zenysis_py77-0.2.1/pylib/mps/packager/packager.py +95 -0
  52. zenysis_py77-0.2.1/pylib/mps/packager/packager_util.py +58 -0
  53. zenysis_py77-0.2.1/pylib/mps/packager/pkg_bin_rules.py +80 -0
  54. zenysis_py77-0.2.1/pylib/mps/packager/pkg_ctrl.py +33 -0
  55. zenysis_py77-0.2.1/pylib/mps/packager/pkg_rules.py +96 -0
  56. zenysis_py77-0.2.1/pylib/mps/packager/pkg_rules_interface.py +19 -0
  57. zenysis_py77-0.2.1/pylib/mps/packager/pkg_sys_rules.py +105 -0
  58. zenysis_py77-0.2.1/pylib/mps/packager/pkg_utils.py +27 -0
  59. zenysis_py77-0.2.1/pylib/mps/packager/shared/__init__.py +0 -0
  60. zenysis_py77-0.2.1/pylib/mps/packager/shared/control_base.py +188 -0
  61. zenysis_py77-0.2.1/pylib/mps/packager/shared/copy_shared.py +23 -0
  62. zenysis_py77-0.2.1/pylib/mps/update_packages.py +101 -0
  63. zenysis_py77-0.2.1/pylib/mps/util/__init__.py +0 -0
  64. zenysis_py77-0.2.1/pylib/mps/util/push_util.py +23 -0
  65. zenysis_py77-0.2.1/pylib/mps/util/queue_cluster_config_updates.py +83 -0
  66. zenysis_py77-0.2.1/pylib/net/__init__.py +0 -0
  67. zenysis_py77-0.2.1/pylib/net/mailer.py +48 -0
  68. zenysis_py77-0.2.1/pylib/net/server.py +262 -0
  69. zenysis_py77-0.2.1/pylib/net/util.py +153 -0
  70. zenysis_py77-0.2.1/pylib/net/util_test.py +23 -0
  71. zenysis_py77-0.2.1/pylib/pager/__init__.py +0 -0
  72. zenysis_py77-0.2.1/pylib/pager/pager.py +254 -0
  73. zenysis_py77-0.2.1/pylib/playback/__init__.py +0 -0
  74. zenysis_py77-0.2.1/pylib/playback/play.py +69 -0
  75. zenysis_py77-0.2.1/pylib/playback/record.py +62 -0
  76. zenysis_py77-0.2.1/pylib/prod/__init__.py +0 -0
  77. zenysis_py77-0.2.1/pylib/prod/cluster/__init__.py +0 -0
  78. zenysis_py77-0.2.1/pylib/prod/cluster/cluster.py +591 -0
  79. zenysis_py77-0.2.1/pylib/prod/cluster/lazy.py +127 -0
  80. zenysis_py77-0.2.1/pylib/prod/cluster/multiplecmd.py +88 -0
  81. zenysis_py77-0.2.1/pylib/prod/cluster/packages.py +328 -0
  82. zenysis_py77-0.2.1/pylib/prod/packager/__init__.py +0 -0
  83. zenysis_py77-0.2.1/pylib/prod/packager/packager.py +95 -0
  84. zenysis_py77-0.2.1/pylib/prod/packager/packager_util.py +58 -0
  85. zenysis_py77-0.2.1/pylib/prod/packager/pkg_bin_rules.py +80 -0
  86. zenysis_py77-0.2.1/pylib/prod/packager/pkg_ctrl.py +33 -0
  87. zenysis_py77-0.2.1/pylib/prod/packager/pkg_rules.py +96 -0
  88. zenysis_py77-0.2.1/pylib/prod/packager/pkg_rules_interface.py +19 -0
  89. zenysis_py77-0.2.1/pylib/prod/packager/pkg_sys_rules.py +105 -0
  90. zenysis_py77-0.2.1/pylib/prod/packager/pkg_utils.py +27 -0
  91. zenysis_py77-0.2.1/pylib/prod/packager/shared/__init__.py +0 -0
  92. zenysis_py77-0.2.1/pylib/prod/packager/shared/control_base.py +188 -0
  93. zenysis_py77-0.2.1/pylib/prod/packager/shared/copy_shared.py +23 -0
  94. zenysis_py77-0.2.1/pylib/prod/update_packages.py +101 -0
  95. zenysis_py77-0.2.1/pylib/prod/util/__init__.py +0 -0
  96. zenysis_py77-0.2.1/pylib/prod/util/push_util.py +23 -0
  97. zenysis_py77-0.2.1/pylib/prod/util/queue_cluster_config_updates.py +83 -0
  98. zenysis_py77-0.2.1/pylib/pyinstaller/__init__.py +0 -0
  99. zenysis_py77-0.2.1/pylib/pyinstaller/hooks/__init__.py +0 -0
  100. zenysis_py77-0.2.1/pylib/pyinstaller/hooks/hook-flask.py +1 -0
  101. zenysis_py77-0.2.1/pylib/pyinstaller/hooks/hook-gunicorn.py +3 -0
  102. zenysis_py77-0.2.1/pylib/pyinstaller/hooks/hook-pylib.mail.template.py +1 -0
  103. zenysis_py77-0.2.1/pylib/pyinstaller/hooks/hook-pylib.mail.template.templates.py +9 -0
  104. zenysis_py77-0.2.1/pylib/pyinstaller/hooks/hook_utils.py +3 -0
  105. zenysis_py77-0.2.1/pylib/template/__init__.py +0 -0
  106. zenysis_py77-0.2.1/pylib/template/template_manager.py +58 -0
  107. zenysis_py77-0.2.1/pylib/template/template_manager_test.py +48 -0
  108. zenysis_py77-0.2.1/pylib/util/__init__.py +1 -0
  109. zenysis_py77-0.2.1/pylib/util/algorithm.py +78 -0
  110. zenysis_py77-0.2.1/pylib/util/credentials.py +45 -0
  111. zenysis_py77-0.2.1/pylib/util/date_time.py +131 -0
  112. zenysis_py77-0.2.1/pylib/util/date_time_test.py +75 -0
  113. zenysis_py77-0.2.1/pylib/util/decorators/__init__.py +1 -0
  114. zenysis_py77-0.2.1/pylib/util/decorators/decorations.py +12 -0
  115. zenysis_py77-0.2.1/pylib/util/decorators/decorations_test.py +30 -0
  116. zenysis_py77-0.2.1/pylib/util/decorators/thread.py +36 -0
  117. zenysis_py77-0.2.1/pylib/util/descriptor.py +25 -0
  118. zenysis_py77-0.2.1/pylib/util/descriptor_test.py +76 -0
  119. zenysis_py77-0.2.1/pylib/util/dev.py +16 -0
  120. zenysis_py77-0.2.1/pylib/util/dictionary.py +83 -0
  121. zenysis_py77-0.2.1/pylib/util/dictionary_test.py +32 -0
  122. zenysis_py77-0.2.1/pylib/util/generator.py +15 -0
  123. zenysis_py77-0.2.1/pylib/util/git_util.py +195 -0
  124. zenysis_py77-0.2.1/pylib/util/iter_util.py +25 -0
  125. zenysis_py77-0.2.1/pylib/util/mail/__init__.py +1 -0
  126. zenysis_py77-0.2.1/pylib/util/mail/mailer.py +129 -0
  127. zenysis_py77-0.2.1/pylib/util/math/__init__.py +0 -0
  128. zenysis_py77-0.2.1/pylib/util/math/errors.py +25 -0
  129. zenysis_py77-0.2.1/pylib/util/math/list_ops.py +70 -0
  130. zenysis_py77-0.2.1/pylib/util/math/list_ops_test.py +50 -0
  131. zenysis_py77-0.2.1/pylib/util/singleton.py +80 -0
  132. zenysis_py77-0.2.1/pylib/util/singleton_test.py +104 -0
  133. zenysis_py77-0.2.1/pylib/util/stop_words.py +673 -0
  134. zenysis_py77-0.2.1/pylib/util/string_util.py +85 -0
  135. zenysis_py77-0.2.1/pylib/util/time_decay.py +55 -0
  136. zenysis_py77-0.2.1/pylib/util/time_decay_test.py +40 -0
  137. zenysis_py77-0.2.1/pylib/zeus/__init__.py +0 -0
  138. zenysis_py77-0.2.1/pylib/zeus/cleaner.py +87 -0
  139. zenysis_py77-0.2.1/pylib/zeus/continuer.py +71 -0
  140. zenysis_py77-0.2.1/pylib/zeus/exporter.py +146 -0
  141. zenysis_py77-0.2.1/pylib/zeus/importer.py +132 -0
  142. zenysis_py77-0.2.1/pylib/zeus/pipeline_cmd_base.py +177 -0
  143. zenysis_py77-0.2.1/pylib/zeus/pipeline_config.py +213 -0
  144. zenysis_py77-0.2.1/pylib/zeus/pipeline_utils.py +232 -0
  145. zenysis_py77-0.2.1/pylib/zeus/publisher.py +115 -0
  146. zenysis_py77-0.2.1/pylib/zeus/runner.py +516 -0
  147. zenysis_py77-0.2.1/pylib/zeus/utils/bash/common.sh +69 -0
  148. zenysis_py77-0.2.1/pylib/zeus/zeus.py +208 -0
  149. zenysis_py77-0.2.1/setup.cfg +4 -0
  150. zenysis_py77-0.2.1/setup.py +30 -0
  151. zenysis_py77-0.2.1/zenysis_py77.egg-info/PKG-INFO +63 -0
  152. zenysis_py77-0.2.1/zenysis_py77.egg-info/SOURCES.txt +153 -0
  153. zenysis_py77-0.2.1/zenysis_py77.egg-info/dependency_links.txt +1 -0
  154. zenysis_py77-0.2.1/zenysis_py77.egg-info/entry_points.txt +2 -0
  155. zenysis_py77-0.2.1/zenysis_py77.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Room 77, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,63 @@
1
+ Metadata-Version: 2.4
2
+ Name: zenysis-py77
3
+ Version: 0.2.1
4
+ Summary: Zenysis-maintained fork of the Room 77 Python Libraries
5
+ Home-page: https://github.com/Zenysis/py77
6
+ License: MIT
7
+ Project-URL: Source, https://github.com/Zenysis/py77
8
+ Project-URL: Upstream, https://github.com/room77/py77
9
+ Provides: pylib
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Dynamic: description
13
+ Dynamic: description-content-type
14
+ Dynamic: home-page
15
+ Dynamic: license
16
+ Dynamic: license-file
17
+ Dynamic: project-url
18
+ Dynamic: provides
19
+ Dynamic: summary
20
+
21
+ # Room 77 Python Libraries
22
+ This is a collection of Python libraries used at Room 77, Inc.
23
+
24
+ This is a fork maintained by Zenysis, since the original
25
+ [room77/py77](https://github.com/room77/py77) is no longer maintained.
26
+
27
+ ## Installation
28
+ Install from PyPI:
29
+
30
+ pip install zenysis-py77
31
+
32
+ The package is still imported as `pylib` and installs the `zeus` command.
33
+
34
+ Alternatively, clone the repo and include its path in your PYTHONPATH
35
+
36
+ For example:
37
+
38
+ export PYTHONPATH=${PYTHONPATH}:/home/user/src/pylib
39
+
40
+
41
+ Many of the pylib libraries can be used immediately without installing dependencies. The stable-requirements has not been cleaned and contains more dependencies than are necessary. The recommended approach is to not install the stable-requirements and attempt to use the library as is. Only install the requirements when they are needed.
42
+
43
+ There is one additional dependency not in PyPi: GraphViz. To install the necessary Python bindings run
44
+
45
+ sudo apt-get install libgv-python
46
+
47
+ Or the equivalent command for your operating system. Depending on your environment, it may be necessary to add the installed module to your Python path either by setting the PYTHONPATH environment variable or by creating symlinks to the installed module and shared library. On Debian, by default, `gv.py` and `_gv.so` are installed to `/usr/share/pyshared`.
48
+
49
+ A `setup.py` file has been provided but is in experimental state. It is not recommended to install this way if you want to use `flash`
50
+
51
+ ## Components
52
+
53
+ ### Flash
54
+ A declarative build system.
55
+
56
+ ### Zeus
57
+ A task runner.
58
+
59
+ ### Master Packaging System
60
+ A production deployment system.
61
+
62
+ ## License
63
+ All code is distributed under the MIT license, unless otherwise noted. See LICENSE for details.
@@ -0,0 +1,43 @@
1
+ # Room 77 Python Libraries
2
+ This is a collection of Python libraries used at Room 77, Inc.
3
+
4
+ This is a fork maintained by Zenysis, since the original
5
+ [room77/py77](https://github.com/room77/py77) is no longer maintained.
6
+
7
+ ## Installation
8
+ Install from PyPI:
9
+
10
+ pip install zenysis-py77
11
+
12
+ The package is still imported as `pylib` and installs the `zeus` command.
13
+
14
+ Alternatively, clone the repo and include its path in your PYTHONPATH
15
+
16
+ For example:
17
+
18
+ export PYTHONPATH=${PYTHONPATH}:/home/user/src/pylib
19
+
20
+
21
+ Many of the pylib libraries can be used immediately without installing dependencies. The stable-requirements has not been cleaned and contains more dependencies than are necessary. The recommended approach is to not install the stable-requirements and attempt to use the library as is. Only install the requirements when they are needed.
22
+
23
+ There is one additional dependency not in PyPi: GraphViz. To install the necessary Python bindings run
24
+
25
+ sudo apt-get install libgv-python
26
+
27
+ Or the equivalent command for your operating system. Depending on your environment, it may be necessary to add the installed module to your Python path either by setting the PYTHONPATH environment variable or by creating symlinks to the installed module and shared library. On Debian, by default, `gv.py` and `_gv.so` are installed to `/usr/share/pyshared`.
28
+
29
+ A `setup.py` file has been provided but is in experimental state. It is not recommended to install this way if you want to use `flash`
30
+
31
+ ## Components
32
+
33
+ ### Flash
34
+ A declarative build system.
35
+
36
+ ### Zeus
37
+ A task runner.
38
+
39
+ ### Master Packaging System
40
+ A production deployment system.
41
+
42
+ ## License
43
+ All code is distributed under the MIT license, unless otherwise noted. See LICENSE for details.
File without changes
File without changes
@@ -0,0 +1,17 @@
1
+ """
2
+ module for managing machine environments
3
+ """
4
+
5
+ __copyright__ = '2013, Room 77, Inc.'
6
+ __author__ = 'Kyle Konrad'
7
+
8
+ import os
9
+ import subprocess
10
+
11
+ __PRODUCTION_FILE = '/home/config/prod_machine'
12
+ __STAGING_FILE = '/home/config/staging_machine'
13
+ __TEST_FILE = '/localdisk/home/is_r77_test'
14
+
15
+ IN_PRODUCTION = os.path.exists(__PRODUCTION_FILE)
16
+ IN_STAGING = os.path.exists(__STAGING_FILE)
17
+ IN_TEST = os.path.exists(__TEST_FILE)
@@ -0,0 +1,263 @@
1
+ """Utils file for the different build operations."""
2
+
3
+ __author__ = 'pramodg@room77.com (Pramod Gupta)'
4
+ __copyright__ = 'Copyright 2012 Room77, Inc.'
5
+
6
+ from collections import deque
7
+ from queue import Queue
8
+ import multiprocessing
9
+ import os
10
+ import signal
11
+ import subprocess
12
+ import sys
13
+ import shlex
14
+ from threading import Thread, Timer
15
+
16
+ from pylib.base.term_color import TermColor
17
+
18
+
19
+ class KeyboardInterruptError(Exception):
20
+ """Exception to translate keyboard interrupt in child processes."""
21
+ def __init__(self, value="Keyboard Interrupt."):
22
+ self.value = value
23
+
24
+ def __str__(self):
25
+ return repr(self.value)
26
+
27
+
28
+ class PicklableCallback():
29
+ """Class to use as a picklable callback(e.g. for pools)."""
30
+
31
+ def __call__(self, args):
32
+ """The default call method for the class. We want to explicitly handle
33
+ KeyboardInterrupt as otherwise this may lead to invalid child task.
34
+
35
+ Args:
36
+ args: tuple: List of args. We expect args to be as follows:
37
+ arg[0]: The class object.
38
+ arg[1]: Method to be called for the class object.
39
+ arg[2:]: All the arguments to be passed to the method.
40
+
41
+ Return:
42
+ Passes on the value from the called method.
43
+ """
44
+ try:
45
+ handler = getattr(args[0], args[1], None)
46
+ method_args = args[2:]
47
+ res = handler(*method_args)
48
+ sys.stdout.flush()
49
+ return res
50
+ except KeyboardInterrupt:
51
+ raise KeyboardInterruptError()
52
+
53
+
54
+ class ExecUtils:
55
+ """Utility class."""
56
+
57
+ @staticmethod
58
+ def ExecuteParallel(args, pool_size=0, callback=PicklableCallback()):
59
+ """Executes a list of methods in parallel. Uses the PicklableCallback
60
+ as default callback to run individual handlers with the given set of args.
61
+
62
+ Args:
63
+ callback: callable method: A method that can be pickled and called.
64
+ args: list: List of args to pass to PicklableCallback which in turn calls
65
+ the callback handler.
66
+ pool_size: int: The size of the task pool.
67
+ Return:
68
+ list: Returns a list of results passed on by the callback handler.
69
+ """
70
+ if not args:
71
+ TermColor.Warning('Nothing to execute.')
72
+ return []
73
+
74
+ if not pool_size:
75
+ pool_size = max(multiprocessing.cpu_count(), 1)
76
+
77
+ # NOTE(stephen): Require use of `fork` for multiprocessing instead of `spawn` since
78
+ # there are issues with the reuse of some libraries (like Flags) when `spawn` is
79
+ # used.
80
+ pool = multiprocessing.get_context('fork').Pool(processes=pool_size)
81
+ try:
82
+ res = pool.map(callback, args)
83
+ pool.terminate()
84
+ sys.stdout.flush()
85
+ return res
86
+ except (KeyboardInterrupt, Exception) as e:
87
+ TermColor.Error('%s: %s' % (type(e), e))
88
+ # pool.close()
89
+ pool.terminate()
90
+ # Pass on the keyboard interrupt.
91
+ if type(e) == KeyboardInterrupt: raise e
92
+
93
+ sys.stdout.flush()
94
+ return []
95
+
96
+
97
+ @staticmethod
98
+ def ExecuteParallelGenerator(args, pool_size=0, callback=PicklableCallback()):
99
+ """Executes a list of methods in parallel. Uses the PicklableCallback
100
+ as default callback to run individual handlers with the given set of args.
101
+
102
+ Args:
103
+ callback: callable method: A method that can be pickled and called.
104
+ args: list: List of args to pass to PicklableCallback which in turn calls
105
+ the callback handler.
106
+ pool_size: int: The size of the task pool.
107
+ Return:
108
+ list: Returns a list of results passed on by the callback handler.
109
+ """
110
+ if not args:
111
+ TermColor.Warning('Nothing to execute.')
112
+ return []
113
+
114
+ if not pool_size:
115
+ pool_size = max(multiprocessing.cpu_count(), 1)
116
+
117
+ in_queue = Queue()
118
+ for job in args:
119
+ in_queue.put(job)
120
+ out_queue = Queue()
121
+ def worker(in_queue, out_queue):
122
+ while (job := in_queue.get()):
123
+ out_queue.put(callback(job))
124
+
125
+ for _ in range(pool_size):
126
+ Thread(target=worker, args=(in_queue, out_queue)).start()
127
+
128
+ try:
129
+ while True:
130
+ res = out_queue.get()
131
+ new_work = yield res
132
+ if new_work is None:
133
+ break
134
+ for job in new_work:
135
+ in_queue.put(job)
136
+ sys.stdout.flush()
137
+ except (KeyboardInterrupt, Exception) as e:
138
+ TermColor.Error('%s: %s' % (type(e), e))
139
+ # Pass on the keyboard interrupt.
140
+ if type(e) == KeyboardInterrupt: raise e
141
+ finally:
142
+ for _ in range(pool_size):
143
+ in_queue.put(None)
144
+ sys.stdout.flush()
145
+ yield None
146
+
147
+ @staticmethod
148
+ def ExecuteSequentiallyGenerator(args, pool_size=0, callback=PicklableCallback()):
149
+ """Executes a list of methods sequentially. Uses the PicklableCallback
150
+ as default callback to run individual handlers with the given set of args.
151
+
152
+ Args:
153
+ callback: callable method: A method that can be pickled and called.
154
+ args: list: List of args to pass to PicklableCallback which in turn calls
155
+ the callback handler.
156
+ pool_size: int: The size of the task pool.
157
+ Return:
158
+ list: Returns a list of results passed on by the callback handler.
159
+ """
160
+ if not args:
161
+ TermColor.Warning('Nothing to execute.')
162
+ return []
163
+
164
+ queue = deque(args)
165
+ try:
166
+ while queue:
167
+ job = queue.popleft()
168
+ new_jobs = yield callback(job)
169
+ queue.extend(new_jobs or ())
170
+ yield # wait for the final sentinel
171
+ except (KeyboardInterrupt, Exception) as e:
172
+ TermColor.Error('%s: %s' % (type(e), e))
173
+ # Pass on the keyboard interrupt.
174
+ if type(e) == KeyboardInterrupt: raise e
175
+ finally:
176
+ sys.stdout.flush()
177
+
178
+ @staticmethod
179
+ def RunCmd(cmd, timeout_sec=sys.maxsize, piped_output=True, extra_env=None):
180
+ """Executes a command.
181
+ Args:
182
+ cmd: string: A string specifying the command to execute.
183
+ timeout: float: Timeout for the command in seconds.
184
+ piped_output: bool: Set to true if the output is to be dumped directly
185
+ to termimal.
186
+ extra_env: dict{string, string}: The extra environment variables to pass to the cmd.
187
+ """
188
+ TermColor.VInfo(2, 'Executing: %s' % cmd)
189
+
190
+ try:
191
+ if extra_env:
192
+ cmd_env = os.environ.copy()
193
+ cmd_env.update(extra_env)
194
+ else:
195
+ cmd_env = os.environ
196
+
197
+ timer = None
198
+ proc = None
199
+
200
+ if piped_output:
201
+ proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
202
+ stderr=subprocess.STDOUT, env=cmd_env)
203
+ else:
204
+ proc = subprocess.Popen(cmd, shell=True, env=cmd_env)
205
+
206
+ # Start timeout.
207
+ timer = Timer(timeout_sec, ExecUtils.__ProcessTimedOut,
208
+ [proc, cmd, timeout_sec])
209
+ timer.start()
210
+ (merged_out, unused) = proc.communicate()
211
+ timer.cancel()
212
+ retcode = proc.poll()
213
+ if not merged_out:
214
+ merged_out = ''
215
+
216
+ if retcode:
217
+ TermColor.Error('%s failed.\nErrorcode: %d' % (cmd, retcode))
218
+ TermColor.Info('%s Output: \n%s' % (cmd, merged_out))
219
+ else:
220
+ TermColor.VInfo(4, '%s Output: \n%s' % (cmd, merged_out))
221
+ return (retcode, merged_out)
222
+ except (KeyboardInterrupt, OSError) as e:
223
+ TermColor.Error('Command: %s failed. Error: %s' % (cmd, e))
224
+ if timer: timer.cancel()
225
+ if proc:
226
+ ExecUtils.__KillSubchildren(proc.pid)
227
+ proc.communicate()
228
+ # Pass on the keyboard interrupt.
229
+ if type(e) == KeyboardInterrupt: raise e
230
+ return (301, '')
231
+
232
+ @staticmethod
233
+ def __ProcessTimedOut(proc, cmd, timeout_sec):
234
+ """Handles timed out process. Kills the process and all its children.
235
+ Args:
236
+ cmd: string: The cmd that launched the proc.
237
+ proc: subprocess.Popen: The proc created for the command.
238
+ timeout_sec: int: The timeout for the process.
239
+ """
240
+ TermColor.Error('Command: %s Timed Out (%dsec)!' % (cmd, timeout_sec))
241
+ ExecUtils.__KillSubchildren(proc.pid)
242
+
243
+ @staticmethod
244
+ def __KillSubchildren(root_pid):
245
+ """Kills the process and all its subchildren specified by the pid.
246
+ Args:
247
+ root_pid: int: The pid of the process to be killed.
248
+ """
249
+ # Get all child processes.
250
+ p = subprocess.Popen('ps --no-headers -o pid --ppid %d' % root_pid,
251
+ shell=True, stdout=subprocess.PIPE,
252
+ stderr=subprocess.PIPE)
253
+ (stdout, stderr) = p.communicate()
254
+ pids = [int(p) for p in stdout.split()]
255
+
256
+ try:
257
+ os.kill(root_pid, signal.SIGKILL)
258
+ except OSError as e:
259
+ TermColor.Warning('Could not kill %d. Error %s' % (root_pid, e))
260
+
261
+ # Kill all subchildren recursively.
262
+ for pid in pids:
263
+ ExecUtils.__KillSubchildren(pid)
@@ -0,0 +1,35 @@
1
+ """Flags."""
2
+
3
+ __author__ = 'pramodg@room77.com (Pramod Gupta)'
4
+ __copyright__ = 'Copyright 2012 Room77, Inc.'
5
+
6
+ import argparse
7
+
8
+ # HACK(stephen): Force add_subparsers to be backwards compatible since this
9
+ # broke in Python 3.
10
+ def build_parser():
11
+ parser = argparse.ArgumentParser(conflict_handler='resolve',
12
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter)
13
+
14
+ # Workaround based on: https://stackoverflow.com/a/22994500
15
+ _add_subparsers = parser.add_subparsers
16
+ def add_subparsers(*args, **kwargs):
17
+ subparser = _add_subparsers(dest='', *args, **kwargs)
18
+ subparser.required = True
19
+ return subparser
20
+ parser.add_subparsers = add_subparsers
21
+ return parser
22
+
23
+ class Flags:
24
+ """Class to manage command line flags."""
25
+ ARGS = argparse.Namespace()
26
+ PARSER = build_parser()
27
+ TESTING = False
28
+
29
+ @classmethod
30
+ def InitArgs(cls):
31
+ cls.ARGS = cls.PARSER.parse_args()
32
+
33
+ # TODO(pramodg): See if we can replace testing above with an argument.
34
+ # Flags.PARSER.add_argument('-t', '--testing', action='store_true', default=False,
35
+ # help='Testing mode.')
@@ -0,0 +1,129 @@
1
+ """Terminal Logging implementation."""
2
+
3
+ __author__ = 'pramodg@room77.com (Pramod Gupta)'
4
+ __copyright__ = 'Copyright 2012 Room77, Inc.'
5
+
6
+ import re
7
+ import sys
8
+ import traceback
9
+
10
+ from pylib.base.flags import Flags
11
+
12
+ Flags.PARSER.add_argument('-v', '--verbose', type=int, default=0,
13
+ help='Verbosity level.')
14
+
15
+ class TermColor:
16
+ """Class for manipulating terminal colors."""
17
+
18
+ CODE = {
19
+ 'ENDC': 0, # RESET COLOR
20
+ 'BOLD': 1,
21
+ 'UNDERLINE': 4,
22
+ 'BLINK': 5,
23
+ 'INVERT': 7,
24
+ 'CONCEALD': 8,
25
+ 'STRIKE': 9,
26
+ 'GREY30': 90,
27
+ 'GREY40': 2,
28
+ 'GREY65': 37,
29
+ 'GREY70': 97,
30
+ 'GREY20_BG': 40,
31
+ 'GREY33_BG': 100,
32
+ 'GREY80_BG': 47,
33
+ 'GREY93_BG': 107,
34
+ 'DARK_RED': 31,
35
+ 'RED': 91,
36
+ 'RED_BG': 41,
37
+ 'LIGHT_RED_BG': 101,
38
+ 'DARK_YELLOW': 33,
39
+ 'YELLOW': 93,
40
+ 'YELLOW_BG': 43,
41
+ 'LIGHT_YELLOW_BG': 103,
42
+ 'DARK_BLUE': 34,
43
+ 'BLUE': 94,
44
+ 'BLUE_BG': 44,
45
+ 'LIGHT_BLUE_BG': 104,
46
+ 'DARK_MAGENTA': 35,
47
+ 'PURPLE': 95,
48
+ 'MAGENTA_BG': 45,
49
+ 'LIGHT_PURPLE_BG': 105,
50
+ 'DARK_CYAN': 36,
51
+ 'AUQA': 96,
52
+ 'CYAN_BG': 46,
53
+ 'LIGHT_AUQA_BG': 106,
54
+ 'DARK_GREEN': 32,
55
+ 'GREEN': 92,
56
+ 'GREEN_BG': 42,
57
+ 'LIGHT_GREEN_BG': 102,
58
+ 'BLACK': 30,
59
+ }
60
+
61
+ @staticmethod
62
+ def TermCode(num):
63
+ return '\033[%sm' % num
64
+
65
+ @staticmethod
66
+ def ColorStr(s, color):
67
+ return (TermColor.TermCode(TermColor.CODE[color]) + s +
68
+ TermColor.TermCode(TermColor.CODE['ENDC']))
69
+
70
+ @staticmethod
71
+ def PrintStr(s, color, print_trace=True):
72
+ if print_trace:
73
+ caller = traceback.extract_stack()[-3]
74
+ s = (caller[0] + ':' + str(caller[1]) + ': ' + s)
75
+
76
+ if sys.stdout.isatty():
77
+ s = TermColor.ColorStr(s, color)
78
+
79
+ print(s)
80
+
81
+ @staticmethod
82
+ def Fatal(s):
83
+ TermColor.PrintStr('FATAL: ' + s, 'RED_BG')
84
+ traceback.print_stack()
85
+ exit(1)
86
+
87
+ @staticmethod
88
+ def PrintException(s):
89
+ TermColor.PrintStr('Exception: ' + s, 'DARK_RED')
90
+ traceback.print_exc()
91
+
92
+ @staticmethod
93
+ def Error(s, print_stack=False):
94
+ TermColor.PrintStr('ERROR: ' + s, 'DARK_RED')
95
+ if print_stack: traceback.print_stack()
96
+
97
+ @staticmethod
98
+ def Warning(s):
99
+ TermColor.PrintStr('WARNING: ' + s, 'PURPLE')
100
+
101
+ @staticmethod
102
+ def Notice(s):
103
+ TermColor.PrintStr(s, 'ENDC')
104
+
105
+ @staticmethod
106
+ def Info(s):
107
+ TermColor.PrintStr(s, 'ENDC', False)
108
+
109
+ @staticmethod
110
+ def VInfo(level, s):
111
+ if level > Flags.ARGS.verbose: return
112
+ TermColor.Info(s)
113
+
114
+ @staticmethod
115
+ def VNotice(level, s):
116
+ if level > Flags.ARGS.verbose: return
117
+ TermColor.Notice(s)
118
+
119
+ @staticmethod
120
+ def Debug(s):
121
+ TermColor.PrintStr('DEBUG: ' + s, 'BLUE')
122
+
123
+ @staticmethod
124
+ def Success(s):
125
+ TermColor.PrintStr('SUCCESS: ' + s, 'GREEN', False)
126
+
127
+ @staticmethod
128
+ def Failure(s):
129
+ TermColor.PrintStr('FAILURE: ' + s, 'RED', False)
File without changes
@@ -0,0 +1,54 @@
1
+ """Common init to get the source root for files."""
2
+
3
+ __author__ = 'pramodg@room77.com (Pramod Gupta)'
4
+ __copyright__ = 'Copyright 2012 Room77, Inc.'
5
+
6
+ import inspect
7
+ import os
8
+ import sys
9
+ import traceback
10
+
11
+ # This is needed to build binaries due to a bug in pyinstaller.
12
+ # May be removed in future if the bug is fixed.
13
+ import encodings
14
+
15
+ # directory of the file this module is imported from
16
+ _dir = os.path.dirname(os.path.realpath(os.path.abspath(
17
+ traceback.extract_stack()[-2][0])))
18
+
19
+ ##
20
+ ## NO NOT PRINT ANYTHING IN THIS FILE. Many files
21
+ ## include this file, and printing may mess up
22
+ ## file generation and other tasks that reply on output
23
+ ##
24
+
25
+ def src_root():
26
+ """Returns the repository root."""
27
+ d = _dir
28
+ while (d and d != '/' and os.path.isdir(d) and not
29
+ os.path.exists(os.path.join(d, '.git'))):
30
+ d = os.path.dirname(d)
31
+ return d
32
+
33
+ def pylib_parent_dir():
34
+ """Returns the directory containing pylib."""
35
+ d = _dir
36
+ while (d and d != '/' and os.path.isdir(d) and not
37
+ os.path.exists(os.path.join(d, 'pylib'))):
38
+ d = os.path.dirname(d)
39
+ if d is None or d == '/':
40
+ raise ValueError('r77_init must be imported from a file under pylib')
41
+ return d
42
+
43
+ def e_dir():
44
+ """Returns the dir with generated code corresponding to this dir"""
45
+ return os.path.join(src_root(), 'e')
46
+
47
+ PY_SRC = pylib_parent_dir()
48
+ E = e_dir()
49
+ # print 'SRC: %s' % SRC
50
+ if PY_SRC not in sys.path:
51
+ sys.path.append(PY_SRC)
52
+ if E not in sys.path:
53
+ sys.path.append(E)
54
+
File without changes