wmglobalqueue 2.4.5.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (347) hide show
  1. Utils/CPMetrics.py +270 -0
  2. Utils/CertTools.py +100 -0
  3. Utils/EmailAlert.py +50 -0
  4. Utils/ExtendedUnitTestCase.py +62 -0
  5. Utils/FileTools.py +182 -0
  6. Utils/IteratorTools.py +80 -0
  7. Utils/MathUtils.py +31 -0
  8. Utils/MemoryCache.py +119 -0
  9. Utils/Patterns.py +24 -0
  10. Utils/Pipeline.py +137 -0
  11. Utils/PortForward.py +97 -0
  12. Utils/ProcFS.py +112 -0
  13. Utils/ProcessStats.py +194 -0
  14. Utils/PythonVersion.py +17 -0
  15. Utils/Signals.py +36 -0
  16. Utils/TemporaryEnvironment.py +27 -0
  17. Utils/Throttled.py +227 -0
  18. Utils/Timers.py +130 -0
  19. Utils/Timestamps.py +86 -0
  20. Utils/TokenManager.py +143 -0
  21. Utils/Tracing.py +60 -0
  22. Utils/TwPrint.py +98 -0
  23. Utils/Utilities.py +318 -0
  24. Utils/__init__.py +11 -0
  25. Utils/wmcoreDTools.py +707 -0
  26. WMCore/ACDC/Collection.py +57 -0
  27. WMCore/ACDC/CollectionTypes.py +12 -0
  28. WMCore/ACDC/CouchCollection.py +67 -0
  29. WMCore/ACDC/CouchFileset.py +238 -0
  30. WMCore/ACDC/CouchService.py +73 -0
  31. WMCore/ACDC/DataCollectionService.py +485 -0
  32. WMCore/ACDC/Fileset.py +94 -0
  33. WMCore/ACDC/__init__.py +11 -0
  34. WMCore/Algorithms/Alarm.py +39 -0
  35. WMCore/Algorithms/MathAlgos.py +274 -0
  36. WMCore/Algorithms/MiscAlgos.py +67 -0
  37. WMCore/Algorithms/ParseXMLFile.py +115 -0
  38. WMCore/Algorithms/Permissions.py +27 -0
  39. WMCore/Algorithms/Singleton.py +58 -0
  40. WMCore/Algorithms/SubprocessAlgos.py +129 -0
  41. WMCore/Algorithms/__init__.py +7 -0
  42. WMCore/Cache/GenericDataCache.py +98 -0
  43. WMCore/Cache/WMConfigCache.py +572 -0
  44. WMCore/Cache/__init__.py +0 -0
  45. WMCore/Configuration.py +659 -0
  46. WMCore/DAOFactory.py +47 -0
  47. WMCore/DataStructs/File.py +177 -0
  48. WMCore/DataStructs/Fileset.py +140 -0
  49. WMCore/DataStructs/Job.py +182 -0
  50. WMCore/DataStructs/JobGroup.py +142 -0
  51. WMCore/DataStructs/JobPackage.py +49 -0
  52. WMCore/DataStructs/LumiList.py +734 -0
  53. WMCore/DataStructs/Mask.py +219 -0
  54. WMCore/DataStructs/MathStructs/ContinuousSummaryHistogram.py +197 -0
  55. WMCore/DataStructs/MathStructs/DiscreteSummaryHistogram.py +92 -0
  56. WMCore/DataStructs/MathStructs/SummaryHistogram.py +117 -0
  57. WMCore/DataStructs/MathStructs/__init__.py +0 -0
  58. WMCore/DataStructs/Pickleable.py +24 -0
  59. WMCore/DataStructs/Run.py +256 -0
  60. WMCore/DataStructs/Subscription.py +175 -0
  61. WMCore/DataStructs/WMObject.py +47 -0
  62. WMCore/DataStructs/WorkUnit.py +112 -0
  63. WMCore/DataStructs/Workflow.py +60 -0
  64. WMCore/DataStructs/__init__.py +8 -0
  65. WMCore/Database/CMSCouch.py +1430 -0
  66. WMCore/Database/ConfigDBMap.py +29 -0
  67. WMCore/Database/CouchMonitoring.py +450 -0
  68. WMCore/Database/CouchUtils.py +118 -0
  69. WMCore/Database/DBCore.py +198 -0
  70. WMCore/Database/DBCreator.py +113 -0
  71. WMCore/Database/DBExceptionHandler.py +59 -0
  72. WMCore/Database/DBFactory.py +117 -0
  73. WMCore/Database/DBFormatter.py +177 -0
  74. WMCore/Database/Dialects.py +13 -0
  75. WMCore/Database/ExecuteDAO.py +327 -0
  76. WMCore/Database/MongoDB.py +241 -0
  77. WMCore/Database/MySQL/Destroy.py +42 -0
  78. WMCore/Database/MySQL/ListUserContent.py +20 -0
  79. WMCore/Database/MySQL/__init__.py +9 -0
  80. WMCore/Database/MySQLCore.py +132 -0
  81. WMCore/Database/Oracle/Destroy.py +56 -0
  82. WMCore/Database/Oracle/ListUserContent.py +19 -0
  83. WMCore/Database/Oracle/__init__.py +9 -0
  84. WMCore/Database/ResultSet.py +44 -0
  85. WMCore/Database/Transaction.py +91 -0
  86. WMCore/Database/__init__.py +9 -0
  87. WMCore/Database/ipy_profile_couch.py +438 -0
  88. WMCore/GlobalWorkQueue/CherryPyThreads/CleanUpTask.py +29 -0
  89. WMCore/GlobalWorkQueue/CherryPyThreads/HeartbeatMonitor.py +105 -0
  90. WMCore/GlobalWorkQueue/CherryPyThreads/LocationUpdateTask.py +28 -0
  91. WMCore/GlobalWorkQueue/CherryPyThreads/ReqMgrInteractionTask.py +35 -0
  92. WMCore/GlobalWorkQueue/CherryPyThreads/__init__.py +0 -0
  93. WMCore/GlobalWorkQueue/__init__.py +0 -0
  94. WMCore/GroupUser/CouchObject.py +127 -0
  95. WMCore/GroupUser/Decorators.py +51 -0
  96. WMCore/GroupUser/Group.py +33 -0
  97. WMCore/GroupUser/Interface.py +73 -0
  98. WMCore/GroupUser/User.py +96 -0
  99. WMCore/GroupUser/__init__.py +11 -0
  100. WMCore/Lexicon.py +836 -0
  101. WMCore/REST/Auth.py +202 -0
  102. WMCore/REST/CherryPyPeriodicTask.py +166 -0
  103. WMCore/REST/Error.py +333 -0
  104. WMCore/REST/Format.py +642 -0
  105. WMCore/REST/HeartbeatMonitorBase.py +90 -0
  106. WMCore/REST/Main.py +636 -0
  107. WMCore/REST/Server.py +2435 -0
  108. WMCore/REST/Services.py +24 -0
  109. WMCore/REST/Test.py +120 -0
  110. WMCore/REST/Tools.py +38 -0
  111. WMCore/REST/Validation.py +250 -0
  112. WMCore/REST/__init__.py +1 -0
  113. WMCore/ReqMgr/DataStructs/RequestStatus.py +209 -0
  114. WMCore/ReqMgr/DataStructs/RequestType.py +13 -0
  115. WMCore/ReqMgr/DataStructs/__init__.py +0 -0
  116. WMCore/ReqMgr/__init__.py +1 -0
  117. WMCore/Services/AlertManager/AlertManagerAPI.py +111 -0
  118. WMCore/Services/AlertManager/__init__.py +0 -0
  119. WMCore/Services/CRIC/CRIC.py +238 -0
  120. WMCore/Services/CRIC/__init__.py +0 -0
  121. WMCore/Services/DBS/DBS3Reader.py +1044 -0
  122. WMCore/Services/DBS/DBSConcurrency.py +44 -0
  123. WMCore/Services/DBS/DBSErrors.py +112 -0
  124. WMCore/Services/DBS/DBSReader.py +23 -0
  125. WMCore/Services/DBS/DBSUtils.py +166 -0
  126. WMCore/Services/DBS/DBSWriterObjects.py +381 -0
  127. WMCore/Services/DBS/ProdException.py +133 -0
  128. WMCore/Services/DBS/__init__.py +8 -0
  129. WMCore/Services/FWJRDB/FWJRDBAPI.py +118 -0
  130. WMCore/Services/FWJRDB/__init__.py +0 -0
  131. WMCore/Services/HTTPS/HTTPSAuthHandler.py +66 -0
  132. WMCore/Services/HTTPS/__init__.py +0 -0
  133. WMCore/Services/LogDB/LogDB.py +201 -0
  134. WMCore/Services/LogDB/LogDBBackend.py +191 -0
  135. WMCore/Services/LogDB/LogDBExceptions.py +11 -0
  136. WMCore/Services/LogDB/LogDBReport.py +85 -0
  137. WMCore/Services/LogDB/__init__.py +0 -0
  138. WMCore/Services/MSPileup/__init__.py +0 -0
  139. WMCore/Services/MSUtils/MSUtils.py +54 -0
  140. WMCore/Services/MSUtils/__init__.py +0 -0
  141. WMCore/Services/McM/McM.py +173 -0
  142. WMCore/Services/McM/__init__.py +8 -0
  143. WMCore/Services/MonIT/Grafana.py +133 -0
  144. WMCore/Services/MonIT/__init__.py +0 -0
  145. WMCore/Services/PyCondor/PyCondorAPI.py +154 -0
  146. WMCore/Services/PyCondor/__init__.py +0 -0
  147. WMCore/Services/ReqMgr/ReqMgr.py +261 -0
  148. WMCore/Services/ReqMgr/__init__.py +0 -0
  149. WMCore/Services/ReqMgrAux/ReqMgrAux.py +419 -0
  150. WMCore/Services/ReqMgrAux/__init__.py +0 -0
  151. WMCore/Services/RequestDB/RequestDBReader.py +267 -0
  152. WMCore/Services/RequestDB/RequestDBWriter.py +39 -0
  153. WMCore/Services/RequestDB/__init__.py +0 -0
  154. WMCore/Services/Requests.py +624 -0
  155. WMCore/Services/Rucio/Rucio.py +1290 -0
  156. WMCore/Services/Rucio/RucioUtils.py +74 -0
  157. WMCore/Services/Rucio/__init__.py +0 -0
  158. WMCore/Services/RucioConMon/RucioConMon.py +121 -0
  159. WMCore/Services/RucioConMon/__init__.py +0 -0
  160. WMCore/Services/Service.py +400 -0
  161. WMCore/Services/StompAMQ/__init__.py +0 -0
  162. WMCore/Services/TagCollector/TagCollector.py +155 -0
  163. WMCore/Services/TagCollector/XMLUtils.py +98 -0
  164. WMCore/Services/TagCollector/__init__.py +0 -0
  165. WMCore/Services/UUIDLib.py +13 -0
  166. WMCore/Services/UserFileCache/UserFileCache.py +160 -0
  167. WMCore/Services/UserFileCache/__init__.py +8 -0
  168. WMCore/Services/WMAgent/WMAgent.py +63 -0
  169. WMCore/Services/WMAgent/__init__.py +0 -0
  170. WMCore/Services/WMArchive/CMSSWMetrics.py +526 -0
  171. WMCore/Services/WMArchive/DataMap.py +463 -0
  172. WMCore/Services/WMArchive/WMArchive.py +33 -0
  173. WMCore/Services/WMArchive/__init__.py +0 -0
  174. WMCore/Services/WMBS/WMBS.py +97 -0
  175. WMCore/Services/WMBS/__init__.py +0 -0
  176. WMCore/Services/WMStats/DataStruct/RequestInfoCollection.py +300 -0
  177. WMCore/Services/WMStats/DataStruct/__init__.py +0 -0
  178. WMCore/Services/WMStats/WMStatsPycurl.py +145 -0
  179. WMCore/Services/WMStats/WMStatsReader.py +445 -0
  180. WMCore/Services/WMStats/WMStatsWriter.py +273 -0
  181. WMCore/Services/WMStats/__init__.py +0 -0
  182. WMCore/Services/WMStatsServer/WMStatsServer.py +134 -0
  183. WMCore/Services/WMStatsServer/__init__.py +0 -0
  184. WMCore/Services/WorkQueue/WorkQueue.py +492 -0
  185. WMCore/Services/WorkQueue/__init__.py +0 -0
  186. WMCore/Services/__init__.py +8 -0
  187. WMCore/Services/pycurl_manager.py +574 -0
  188. WMCore/WMBase.py +50 -0
  189. WMCore/WMConnectionBase.py +164 -0
  190. WMCore/WMException.py +183 -0
  191. WMCore/WMExceptions.py +269 -0
  192. WMCore/WMFactory.py +76 -0
  193. WMCore/WMInit.py +377 -0
  194. WMCore/WMLogging.py +104 -0
  195. WMCore/WMSpec/ConfigSectionTree.py +442 -0
  196. WMCore/WMSpec/Persistency.py +135 -0
  197. WMCore/WMSpec/Steps/BuildMaster.py +87 -0
  198. WMCore/WMSpec/Steps/BuildTools.py +201 -0
  199. WMCore/WMSpec/Steps/Builder.py +97 -0
  200. WMCore/WMSpec/Steps/Diagnostic.py +89 -0
  201. WMCore/WMSpec/Steps/Emulator.py +62 -0
  202. WMCore/WMSpec/Steps/ExecuteMaster.py +208 -0
  203. WMCore/WMSpec/Steps/Executor.py +210 -0
  204. WMCore/WMSpec/Steps/StepFactory.py +213 -0
  205. WMCore/WMSpec/Steps/TaskEmulator.py +75 -0
  206. WMCore/WMSpec/Steps/Template.py +204 -0
  207. WMCore/WMSpec/Steps/Templates/AlcaHarvest.py +76 -0
  208. WMCore/WMSpec/Steps/Templates/CMSSW.py +613 -0
  209. WMCore/WMSpec/Steps/Templates/DQMUpload.py +59 -0
  210. WMCore/WMSpec/Steps/Templates/DeleteFiles.py +70 -0
  211. WMCore/WMSpec/Steps/Templates/LogArchive.py +84 -0
  212. WMCore/WMSpec/Steps/Templates/LogCollect.py +105 -0
  213. WMCore/WMSpec/Steps/Templates/StageOut.py +105 -0
  214. WMCore/WMSpec/Steps/Templates/__init__.py +10 -0
  215. WMCore/WMSpec/Steps/WMExecutionFailure.py +21 -0
  216. WMCore/WMSpec/Steps/__init__.py +8 -0
  217. WMCore/WMSpec/Utilities.py +63 -0
  218. WMCore/WMSpec/WMSpecErrors.py +12 -0
  219. WMCore/WMSpec/WMStep.py +347 -0
  220. WMCore/WMSpec/WMTask.py +1997 -0
  221. WMCore/WMSpec/WMWorkload.py +2288 -0
  222. WMCore/WMSpec/WMWorkloadTools.py +382 -0
  223. WMCore/WMSpec/__init__.py +9 -0
  224. WMCore/WorkQueue/DataLocationMapper.py +273 -0
  225. WMCore/WorkQueue/DataStructs/ACDCBlock.py +47 -0
  226. WMCore/WorkQueue/DataStructs/Block.py +48 -0
  227. WMCore/WorkQueue/DataStructs/CouchWorkQueueElement.py +148 -0
  228. WMCore/WorkQueue/DataStructs/WorkQueueElement.py +274 -0
  229. WMCore/WorkQueue/DataStructs/WorkQueueElementResult.py +152 -0
  230. WMCore/WorkQueue/DataStructs/WorkQueueElementsSummary.py +185 -0
  231. WMCore/WorkQueue/DataStructs/__init__.py +0 -0
  232. WMCore/WorkQueue/Policy/End/EndPolicyInterface.py +44 -0
  233. WMCore/WorkQueue/Policy/End/SingleShot.py +22 -0
  234. WMCore/WorkQueue/Policy/End/__init__.py +32 -0
  235. WMCore/WorkQueue/Policy/PolicyInterface.py +17 -0
  236. WMCore/WorkQueue/Policy/Start/Block.py +258 -0
  237. WMCore/WorkQueue/Policy/Start/Dataset.py +180 -0
  238. WMCore/WorkQueue/Policy/Start/MonteCarlo.py +131 -0
  239. WMCore/WorkQueue/Policy/Start/ResubmitBlock.py +171 -0
  240. WMCore/WorkQueue/Policy/Start/StartPolicyInterface.py +316 -0
  241. WMCore/WorkQueue/Policy/Start/__init__.py +34 -0
  242. WMCore/WorkQueue/Policy/__init__.py +57 -0
  243. WMCore/WorkQueue/WMBSHelper.py +772 -0
  244. WMCore/WorkQueue/WorkQueue.py +1237 -0
  245. WMCore/WorkQueue/WorkQueueBackend.py +750 -0
  246. WMCore/WorkQueue/WorkQueueBase.py +39 -0
  247. WMCore/WorkQueue/WorkQueueExceptions.py +44 -0
  248. WMCore/WorkQueue/WorkQueueReqMgrInterface.py +278 -0
  249. WMCore/WorkQueue/WorkQueueUtils.py +130 -0
  250. WMCore/WorkQueue/__init__.py +13 -0
  251. WMCore/Wrappers/JsonWrapper/JSONThunker.py +342 -0
  252. WMCore/Wrappers/JsonWrapper/__init__.py +7 -0
  253. WMCore/Wrappers/__init__.py +6 -0
  254. WMCore/__init__.py +10 -0
  255. wmglobalqueue-2.4.5.1.data/data/bin/wmc-dist-patch +15 -0
  256. wmglobalqueue-2.4.5.1.data/data/bin/wmc-dist-unpatch +8 -0
  257. wmglobalqueue-2.4.5.1.data/data/bin/wmc-httpd +3 -0
  258. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/.couchapprc +1 -0
  259. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/README.md +40 -0
  260. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/index.html +264 -0
  261. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/ElementInfoByWorkflow.js +96 -0
  262. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/StuckElementInfo.js +57 -0
  263. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/WorkloadInfoTable.js +80 -0
  264. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/dataTable.js +70 -0
  265. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/js/namespace.js +23 -0
  266. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/_attachments/style/main.css +75 -0
  267. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/couchapp.json +4 -0
  268. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/filters/childQueueFilter.js +13 -0
  269. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/filters/filterDeletedDocs.js +3 -0
  270. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/filters/queueFilter.js +11 -0
  271. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/language +1 -0
  272. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lib/mustache.js +333 -0
  273. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lib/validate.js +27 -0
  274. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lib/workqueue_utils.js +61 -0
  275. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/elementsDetail.js +28 -0
  276. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/filter.js +86 -0
  277. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/stuckElements.js +38 -0
  278. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/workRestrictions.js +153 -0
  279. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/lists/workflowSummary.js +28 -0
  280. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/rewrites.json +73 -0
  281. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/shows/redirect.js +23 -0
  282. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/shows/status.js +40 -0
  283. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/ElementSummaryByWorkflow.html +27 -0
  284. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/StuckElementSummary.html +26 -0
  285. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/TaskStatus.html +23 -0
  286. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/WorkflowSummary.html +27 -0
  287. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/partials/workqueue-common-lib.html +2 -0
  288. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/partials/yui-lib-remote.html +16 -0
  289. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/templates/partials/yui-lib.html +18 -0
  290. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/updates/in-place.js +50 -0
  291. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/validate_doc_update.js +8 -0
  292. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/vendor/couchapp/_attachments/jquery.couch.app.js +235 -0
  293. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/vendor/couchapp/_attachments/jquery.pathbinder.js +173 -0
  294. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeData/map.js +8 -0
  295. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeData/reduce.js +2 -0
  296. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeParentData/map.js +8 -0
  297. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activeParentData/reduce.js +2 -0
  298. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activePileupData/map.js +8 -0
  299. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/activePileupData/reduce.js +2 -0
  300. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/analyticsData/map.js +11 -0
  301. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/analyticsData/reduce.js +1 -0
  302. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/availableByPriority/map.js +6 -0
  303. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/conflicts/map.js +5 -0
  304. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elements/map.js +5 -0
  305. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByData/map.js +8 -0
  306. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByParent/map.js +8 -0
  307. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByParentData/map.js +8 -0
  308. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByPileupData/map.js +8 -0
  309. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByStatus/map.js +8 -0
  310. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsBySubscription/map.js +6 -0
  311. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByWorkflow/map.js +8 -0
  312. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsByWorkflow/reduce.js +3 -0
  313. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/elementsDetailByWorkflowAndStatus/map.js +26 -0
  314. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobInjectStatusByRequest/map.js +10 -0
  315. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobInjectStatusByRequest/reduce.js +1 -0
  316. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobStatusByRequest/map.js +6 -0
  317. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobStatusByRequest/reduce.js +1 -0
  318. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndPriority/map.js +6 -0
  319. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndPriority/reduce.js +1 -0
  320. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndStatus/map.js +6 -0
  321. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByChildQueueAndStatus/reduce.js +1 -0
  322. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByRequest/map.js +6 -0
  323. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByRequest/reduce.js +1 -0
  324. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatus/map.js +6 -0
  325. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatus/reduce.js +1 -0
  326. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatusAndPriority/map.js +6 -0
  327. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/jobsByStatusAndPriority/reduce.js +1 -0
  328. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/openRequests/map.js +6 -0
  329. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/recent-items/map.js +5 -0
  330. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/siteWhitelistByRequest/map.js +6 -0
  331. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/siteWhitelistByRequest/reduce.js +1 -0
  332. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/specsByWorkflow/map.js +5 -0
  333. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/stuckElements/map.js +38 -0
  334. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsInjectStatusByRequest/map.js +12 -0
  335. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsInjectStatusByRequest/reduce.js +3 -0
  336. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrl/map.js +6 -0
  337. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrl/reduce.js +2 -0
  338. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrlByRequest/map.js +6 -0
  339. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/wmbsUrlByRequest/reduce.js +2 -0
  340. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/workflowSummary/map.js +9 -0
  341. wmglobalqueue-2.4.5.1.data/data/data/couchapps/WorkQueue/views/workflowSummary/reduce.js +10 -0
  342. wmglobalqueue-2.4.5.1.dist-info/METADATA +26 -0
  343. wmglobalqueue-2.4.5.1.dist-info/RECORD +347 -0
  344. wmglobalqueue-2.4.5.1.dist-info/WHEEL +5 -0
  345. wmglobalqueue-2.4.5.1.dist-info/licenses/LICENSE +202 -0
  346. wmglobalqueue-2.4.5.1.dist-info/licenses/NOTICE +16 -0
  347. wmglobalqueue-2.4.5.1.dist-info/top_level.txt +2 -0
Utils/Timestamps.py ADDED
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ _Timestamps_ module designed to insert proper WM timing into WMCore FJR.
4
+ Usage: python3 Timestamps.py --reportFile=$outputFile --wmJobStart=<sec> --wmJobEnd=<sec>
5
+ where outputFile represents output FJR file, and wmJobStart/wmJobEnd represent
6
+ start and end time of WM job, respectively.
7
+
8
+ NOTE: this script should reside in Utils area of WMCore repository since it is required
9
+ at run time on condor node where there is no WMCore installation and we only provide WMCore.zip
10
+ archive, and worker node may not have unzip tool to extract this script.
11
+
12
+ """
13
+
14
+ import getopt
15
+ import logging
16
+ import os
17
+ import pickle
18
+ import sys
19
+
20
+
21
+ # script options
22
+ options = {"reportFile=": "", "wmJobStart=": '', "wmJobEnd=": ''}
23
+
24
+
25
+ def addTimestampMetrics(config, wmJobStart, wmJobEnd):
26
+ """
27
+ Adjust timestamp metrics of provied FJR data.
28
+
29
+ :param config: input FJR data
30
+ :param wmJobStart: start time of WM job in seconds
31
+ :param wmJobEnd: end time of WM job in seconds
32
+ """
33
+ wmTiming = config.section_('WMTiming')
34
+ wmTiming.WMJobStart = wmJobStart
35
+ wmTiming.WMJobEnd = wmJobEnd
36
+ wmTiming.WMTotalWallClockTime = wmJobEnd - wmJobStart
37
+ return config
38
+
39
+
40
+ def main():
41
+ """
42
+ Main function of the script performs business logic:
43
+ - parse input arguments
44
+ - read provided input FJR
45
+ - adjust timestamp metrics of FJR data
46
+ - write out FJR
47
+ """
48
+ try:
49
+ opts, _ = getopt.getopt(sys.argv[1:], "", list(options.keys()))
50
+ except getopt.GetoptError as ex:
51
+ msg = "Error processing commandline args:\n"
52
+ msg += str(ex)
53
+ logging.error(msg)
54
+ sys.exit(1)
55
+
56
+ for opt, arg in opts:
57
+ if opt == "--reportFile":
58
+ reportFile = arg
59
+ if opt == "--wmJobStart":
60
+ wmJobStart = float(arg)
61
+ if opt == "--wmJobEnd":
62
+ wmJobEnd = float(arg)
63
+
64
+ # read content of given FJR report file
65
+ data = {}
66
+ with open(reportFile, 'rb') as istream:
67
+ data = pickle.load(istream)
68
+
69
+ # adjust FJR data with provided metrics
70
+ data = addTimestampMetrics(data, wmJobStart, wmJobEnd)
71
+
72
+ # write content of FJR back to report file
73
+ reportOutFile = reportFile + ".new"
74
+ msg = f"Adding wmJobTime metric to {reportFile}"
75
+ with open(reportOutFile, 'wb') as ostream:
76
+ logging.info(msg)
77
+ pickle.dump(data, ostream)
78
+
79
+ # if we successfully wrote reportOutFile we can swap it with input one
80
+ sizeStatus = os.path.getsize(reportOutFile) >= os.path.getsize(reportFile)
81
+ if os.path.isfile(reportOutFile) and sizeStatus:
82
+ os.rename(reportOutFile, reportFile)
83
+
84
+
85
+ if __name__ == '__main__':
86
+ main()
Utils/TokenManager.py ADDED
@@ -0,0 +1,143 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ #pylint: disable=W0212
4
+ """
5
+ File : TokenManager.py
6
+ Author : Valentin Kuznetsov <vkuznet AT gmail dot com>
7
+ Description: IAM token manager
8
+ by default it relies on the following environment/parameters:
9
+ - IAM_TOKEN is either file name or actual token value
10
+ - https://cms-auth.web.cern.ch/jwk is default CMS IAM provider
11
+ - https://wlcg.cern.ch/jwt/v1/any is default for audience parameter
12
+ """
13
+
14
+ # system modules
15
+ import os
16
+ import ssl
17
+ import time
18
+ import logging
19
+ import traceback
20
+
21
+ # third part library
22
+ try:
23
+ import jwt
24
+ except ImportError:
25
+ traceback.print_exc()
26
+ jwt = None
27
+
28
+ from Utils.Utilities import encodeUnicodeToBytes
29
+
30
+ # prevent "SSL: CERTIFICATE_VERIFY_FAILED" error
31
+ # this will cause pylint warning W0212, therefore we ignore it above
32
+ ssl._create_default_https_context = ssl._create_unverified_context
33
+
34
+
35
+ def readToken(name=None):
36
+ """
37
+ Read IAM token either from environment or file name
38
+ :param name: ether file name containing token or environment name which hold the token value.
39
+ If not provided it will be assumed to read token from IAM_TOKEN environment.
40
+ :return: token or None
41
+ """
42
+ if name and os.path.exists(name):
43
+ token = None
44
+ with open(name, 'r', encoding='utf-8') as istream:
45
+ token = istream.read()
46
+ return token
47
+ if name:
48
+ return os.environ.get(name)
49
+ return os.environ.get("IAM_TOKEN")
50
+
51
+
52
+ def tokenData(token, url="https://cms-auth.web.cern.ch/jwk", audUrl="https://wlcg.cern.ch/jwt/v1/any"):
53
+ """
54
+ inspect and extract token data
55
+ :param token: token string
56
+ :param url: IAM provider URL
57
+ :param audUrl: audience string
58
+ """
59
+ if not token or not jwt:
60
+ return {}
61
+ if isinstance(token, str):
62
+ token = encodeUnicodeToBytes(token)
63
+ jwksClient = jwt.PyJWKClient(url)
64
+ signingKey = jwksClient.get_signing_key_from_jwt(token)
65
+ key = signingKey.key
66
+ headers = jwt.get_unverified_header(token)
67
+ alg = headers.get('alg', 'RS256')
68
+ data = jwt.decode(
69
+ token,
70
+ key,
71
+ algorithms=[alg],
72
+ audience=audUrl,
73
+ options={"verify_exp": True},
74
+ )
75
+ return data
76
+
77
+
78
+ def isValidToken(token):
79
+ """
80
+ check if given token is valid or not
81
+
82
+ :param token: token string
83
+ :return: true or false
84
+ """
85
+ tokenDict = {}
86
+ tokenDict = tokenData(token)
87
+ exp = tokenDict.get('exp', 0) # expire, seconds since epoch
88
+ if not exp or exp < time.time():
89
+ return False
90
+ return True
91
+
92
+
93
+ class TokenManager():
94
+ """
95
+ TokenManager class handles IAM tokens
96
+ """
97
+
98
+ def __init__(self,
99
+ name=None,
100
+ url="https://cms-auth.web.cern.ch/jwk",
101
+ audUrl="https://wlcg.cern.ch/jwt/v1/any",
102
+ logger=None):
103
+ """
104
+ Token manager reads IAM tokens either from file or env.
105
+ It caches token along with expiration timestamp.
106
+ By default the env variable to use is IAM_TOKEN.
107
+ :param name: string representing either file or env where we should read token from
108
+ :param url: IAM provider URL
109
+ :param audUrl: audience string
110
+ :param logger: logger object or none to use default one
111
+ """
112
+ self.name = name
113
+ self.url = url
114
+ self.audUrl = audUrl
115
+ self.expire = 0
116
+ self.token = None
117
+ self.logger = logger if logger else logging.getLogger()
118
+ try:
119
+ self.token = self.getToken()
120
+ except Exception as exc:
121
+ self.logger.exception("Failed to get token. Details: %s", str(exc))
122
+
123
+ def getToken(self):
124
+ """
125
+ Return valid token and sets its expire timestamp
126
+ """
127
+ if not self.token or not isValidToken(self.token):
128
+ self.token = readToken(self.name)
129
+ tokenDict = {}
130
+ try:
131
+ tokenDict = tokenData(self.token, url=self.url, audUrl=self.audUrl)
132
+ self.logger.debug(tokenDict)
133
+ except Exception as exc:
134
+ self.logger.exception(str(exc))
135
+ raise
136
+ self.expire = tokenDict.get('exp', 0)
137
+ return self.token
138
+
139
+ def getLifetime(self):
140
+ """
141
+ Return reamaining lifetime of existing token
142
+ """
143
+ return self.expire - int(time.time())
Utils/Tracing.py ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env python
2
+
3
+ """
4
+ Stuff to help with debugging from https://pymotw.com/3/sys/tracing.html
5
+
6
+ Use like this:
7
+
8
+ import sys
9
+ from Utils.Tracing import trace_calls_and_returns, dont_trace
10
+
11
+ sys.settrace(trace_calls_and_returns)
12
+ # Do the things you want to trace
13
+ sys.settrace(dont_trace)
14
+
15
+ """
16
+
17
+
18
+ def trace_calls(frame, event, arg, to_be_traced=None):
19
+ if event != 'call':
20
+ return
21
+ co = frame.f_code
22
+ func_name = co.co_name
23
+ if func_name == 'write':
24
+ return # Ignore write() calls from printing
25
+ line_no = frame.f_lineno
26
+ filename = co.co_filename
27
+ print('* Call to {} on line {} of {}'.format(
28
+ func_name, line_no, filename))
29
+ if func_name in to_be_traced:
30
+ # Trace into this function
31
+ return trace_lines
32
+ return
33
+
34
+
35
+ def trace_calls_and_returns(frame, event, arg):
36
+ co = frame.f_code
37
+ func_name = co.co_name
38
+ if func_name == 'write':
39
+ return # Ignore write() calls from printing
40
+ line_no = frame.f_lineno
41
+ filename = co.co_filename
42
+ if event == 'call':
43
+ print('Call to {} on line {} of {}'.format(func_name, line_no, filename))
44
+ return trace_calls_and_returns
45
+ elif event == 'return':
46
+ print(' {} => {} ({})'.format(func_name, arg, filename))
47
+ return
48
+
49
+
50
+ def trace_lines(frame, event, arg):
51
+ if event != 'line':
52
+ return
53
+ co = frame.f_code
54
+ func_name = co.co_name
55
+ line_no = frame.f_lineno
56
+ print('* {} line {}'.format(func_name, line_no))
57
+
58
+
59
+ def dont_trace(frame, event, arg):
60
+ return
Utils/TwPrint.py ADDED
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env python
2
+ """
3
+ File : TwPrint.py
4
+
5
+ Description:
6
+
7
+ A simple textwrap based printer for nested dictionaries.
8
+
9
+ """
10
+ from textwrap import TextWrapper
11
+ from collections import OrderedDict
12
+
13
+
14
+ def twClosure(replace_whitespace=False,
15
+ break_long_words=False,
16
+ maxWidth=120,
17
+ maxLength=-1,
18
+ maxDepth=-1,
19
+ initial_indent=''):
20
+ """
21
+ Deals with indentation of dictionaries with very long key, value pairs.
22
+ replace_whitespace: Replace each whitespace character with a single space.
23
+ break_long_words: If True words longer than width will be broken.
24
+ width: The maximum length of wrapped lines.
25
+ initial_indent: String that will be prepended to the first line of the output
26
+
27
+ Wraps all strings for both keys and values to 120 chars.
28
+ Uses 4 spaces indentation for both keys and values.
29
+ Nested dictionaries and lists go to next line.
30
+ """
31
+ twr = TextWrapper(replace_whitespace=replace_whitespace,
32
+ break_long_words=break_long_words,
33
+ width=maxWidth,
34
+ initial_indent=initial_indent)
35
+
36
+ def twEnclosed(obj, ind='', depthReached=0, reCall=False):
37
+ """
38
+ The inner function of the closure
39
+ ind: Initial indentation for the single output string
40
+ reCall: Flag to indicate a recursive call (should not be used outside)
41
+ """
42
+ output = ''
43
+ if isinstance(obj, dict):
44
+ obj = OrderedDict(sorted(list(obj.items()),
45
+ key=lambda t: t[0],
46
+ reverse=False))
47
+ if reCall:
48
+ output += '\n'
49
+ ind += ' '
50
+ depthReached += 1
51
+ lengthReached = 0
52
+ for key, value in list(obj.items()):
53
+ lengthReached += 1
54
+ if lengthReached > maxLength and maxLength >= 0:
55
+ output += "%s...\n" % ind
56
+ break
57
+ if depthReached <= maxDepth or maxDepth < 0:
58
+ output += "%s%s: %s" % (ind,
59
+ ''.join(twr.wrap(key)),
60
+ twEnclosed(value, ind, depthReached=depthReached, reCall=True))
61
+
62
+ elif isinstance(obj, (list, set)):
63
+ if reCall:
64
+ output += '\n'
65
+ ind += ' '
66
+ lengthReached = 0
67
+ for value in obj:
68
+ lengthReached += 1
69
+ if lengthReached > maxLength and maxLength >= 0:
70
+ output += "%s...\n" % ind
71
+ break
72
+ if depthReached <= maxDepth or maxDepth < 0:
73
+ output += "%s%s" % (ind, twEnclosed(value, ind, depthReached=depthReached, reCall=True))
74
+ else:
75
+ output += "%s\n" % str(obj) # join(twr.wrap(str(obj)))
76
+ return output
77
+
78
+ return twEnclosed
79
+
80
+
81
+ def twPrint(obj, maxWidth=120, maxLength=-1, maxDepth=-1):
82
+ """
83
+ A simple caller of twClosure (see docstring for twClosure)
84
+ """
85
+ twPrinter = twClosure(maxWidth=maxWidth,
86
+ maxLength=maxLength,
87
+ maxDepth=maxDepth)
88
+ print(twPrinter(obj))
89
+
90
+
91
+ def twFormat(obj, maxWidth=120, maxLength=-1, maxDepth=-1):
92
+ """
93
+ A simple caller of twClosure (see docstring for twClosure)
94
+ """
95
+ twFormatter = twClosure(maxWidth=maxWidth,
96
+ maxLength=maxLength,
97
+ maxDepth=maxDepth)
98
+ return twFormatter(obj)
Utils/Utilities.py ADDED
@@ -0,0 +1,318 @@
1
+ #! /usr/bin/env python
2
+
3
+ from builtins import str, bytes
4
+
5
+ import subprocess
6
+ import os
7
+ import re
8
+ import zlib
9
+ import base64
10
+ import sys
11
+ from types import ModuleType, FunctionType
12
+ from gc import get_referents
13
+
14
+ import xml.etree.ElementTree as ET
15
+
16
+ def extractFromXML(xmlFile, xmlElement):
17
+ tree = ET.parse(xmlFile)
18
+ root = tree.getroot()
19
+ element = root.find(f".//{xmlElement}")
20
+ if element is not None:
21
+ return element.get("Value")
22
+ return None
23
+
24
+ def lowerCmsHeaders(headers):
25
+ """
26
+ Lower CMS headers in provided header's dict. The WMCore Authentication
27
+ code check only cms headers in lower case, e.g. cms-xxx-yyy.
28
+ """
29
+ lheaders = {}
30
+ for hkey, hval in list(headers.items()): # perform lower-case
31
+ # lower header keys since we check lower-case in headers
32
+ if hkey.startswith('Cms-') or hkey.startswith('CMS-'):
33
+ lheaders[hkey.lower()] = hval
34
+ else:
35
+ lheaders[hkey] = hval
36
+ return lheaders
37
+
38
+ def makeList(stringList):
39
+ """
40
+ _makeList_
41
+
42
+ Make a python list out of a comma separated list of strings,
43
+ throws a ValueError if the input is not well formed.
44
+ If the stringList is already of type list, then return it untouched.
45
+ """
46
+ if isinstance(stringList, list):
47
+ return stringList
48
+ if isinstance(stringList, str):
49
+ toks = stringList.lstrip(' [').rstrip(' ]').split(',')
50
+ if toks == ['']:
51
+ return []
52
+ return [str(tok.strip(' \'"')) for tok in toks]
53
+ raise ValueError("Can't convert to list %s" % stringList)
54
+
55
+
56
+ def makeNonEmptyList(stringList):
57
+ """
58
+ _makeNonEmptyList_
59
+
60
+ Given a string or a list of strings, return a non empty list of strings.
61
+ Throws an exception in case the final list is empty or input data is not
62
+ a string or a python list
63
+ """
64
+ finalList = makeList(stringList)
65
+ if not finalList:
66
+ raise ValueError("Input data cannot be an empty list %s" % stringList)
67
+ return finalList
68
+
69
+
70
+ def strToBool(string):
71
+ """
72
+ Try to convert different variations of True or False (including a string
73
+ type object) to a boolean value.
74
+ In short:
75
+ * True gets mapped from: True, "True", "true", "TRUE".
76
+ * False gets mapped from: False, "False", "false", "FALSE"
77
+ * anything else will fail
78
+ :param string: expects a boolean or a string, but it could be anything else
79
+ :return: a boolean value, or raise an exception if value passed in is not supported
80
+ """
81
+ if string is False or string is True:
82
+ return string
83
+ elif string in ["True", "true", "TRUE"]:
84
+ return True
85
+ elif string in ["False", "false", "FALSE"]:
86
+ return False
87
+ raise ValueError("Can't convert to bool: %s" % string)
88
+
89
+
90
+ def safeStr(string):
91
+ """
92
+ _safeStr_
93
+
94
+ Cast simple data (int, float, basestring) to string.
95
+ """
96
+ if not isinstance(string, (tuple, list, set, dict)):
97
+ return str(string)
98
+ raise ValueError("We're not supposed to convert %s to string." % string)
99
+
100
+
101
+ def diskUse():
102
+ """
103
+ This returns the % use of each disk partition
104
+ """
105
+ diskPercent = []
106
+ df = subprocess.Popen(["df", "-klP"], stdout=subprocess.PIPE)
107
+ output = df.communicate()[0]
108
+ output = decodeBytesToUnicode(output).split("\n")
109
+ for x in output:
110
+ split = x.split()
111
+ if split != [] and split[0] != 'Filesystem':
112
+ diskPercent.append({'filesystem': split[0],
113
+ 'mounted': split[5],
114
+ 'percent': split[4]})
115
+
116
+ return diskPercent
117
+
118
+
119
+ def numberCouchProcess():
120
+ """
121
+ This returns the number of couch process
122
+ """
123
+ ps = subprocess.Popen(["ps", "-ef"], stdout=subprocess.PIPE)
124
+ process = ps.communicate()[0]
125
+ process = decodeBytesToUnicode(process).count('couchjs')
126
+
127
+ return process
128
+
129
+
130
+ def rootUrlJoin(base, extend):
131
+ """
132
+ Adds a path element to the path within a ROOT url
133
+ """
134
+ if base:
135
+ match = re.match("^root://([^/]+)/(.+)", base)
136
+ if match:
137
+ host = match.group(1)
138
+ path = match.group(2)
139
+ newpath = os.path.join(path, extend)
140
+ newurl = "root://%s/%s" % (host, newpath)
141
+ return newurl
142
+ return None
143
+
144
+
145
+ def zipEncodeStr(message, maxLen=5120, compressLevel=9, steps=100, truncateIndicator=" (...)"):
146
+ """
147
+ _zipEncodeStr_
148
+ Utility to zip a string and encode it.
149
+ If zipped encoded length is greater than maxLen,
150
+ truncate message until zip/encoded version
151
+ is within the limits allowed.
152
+ """
153
+ message = encodeUnicodeToBytes(message)
154
+ encodedStr = zlib.compress(message, compressLevel)
155
+ encodedStr = base64.b64encode(encodedStr)
156
+ if len(encodedStr) < maxLen or maxLen == -1:
157
+ return encodedStr
158
+
159
+ compressRate = 1. * len(encodedStr) / len(base64.b64encode(message))
160
+
161
+ # Estimate new length for message zip/encoded version
162
+ # to be less than maxLen.
163
+ # Also, append truncate indicator to message.
164
+ truncateIndicator = encodeUnicodeToBytes(truncateIndicator)
165
+ strLen = int((maxLen - len(truncateIndicator)) / compressRate)
166
+ message = message[:strLen] + truncateIndicator
167
+
168
+ encodedStr = zipEncodeStr(message, maxLen=-1)
169
+
170
+ # If new length is not short enough, truncate
171
+ # recursively by steps
172
+ while len(encodedStr) > maxLen:
173
+ message = message[:-steps - len(truncateIndicator)] + truncateIndicator
174
+ encodedStr = zipEncodeStr(message, maxLen=-1)
175
+
176
+ return encodedStr
177
+
178
+
179
+ def getSize(obj):
180
+ """
181
+ _getSize_
182
+
183
+ Function to traverse an object and calculate its total size in bytes
184
+ :param obj: a python object
185
+ :return: an integer representing the total size of the object
186
+
187
+ Code extracted from Stack Overflow:
188
+ https://stackoverflow.com/questions/449560/how-do-i-determine-the-size-of-an-object-in-python
189
+ """
190
+ # Custom objects know their class.
191
+ # Function objects seem to know way too much, including modules.
192
+ # Exclude modules as well.
193
+ BLACKLIST = type, ModuleType, FunctionType
194
+
195
+ if isinstance(obj, BLACKLIST):
196
+ raise TypeError('getSize() does not take argument of type: '+ str(type(obj)))
197
+ seen_ids = set()
198
+ size = 0
199
+ objects = [obj]
200
+ while objects:
201
+ need_referents = []
202
+ for obj in objects:
203
+ if not isinstance(obj, BLACKLIST) and id(obj) not in seen_ids:
204
+ seen_ids.add(id(obj))
205
+ size += sys.getsizeof(obj)
206
+ need_referents.append(obj)
207
+ objects = get_referents(*need_referents)
208
+ return size
209
+
210
+
211
+ def decodeBytesToUnicode(value, errors="strict"):
212
+ """
213
+ Accepts an input "value" of generic type.
214
+
215
+ If "value" is a string of type sequence of bytes (i.e. in py2 `str` or
216
+ `future.types.newbytes.newbytes`, in py3 `bytes`), then it is converted to
217
+ a sequence of unicode codepoints.
218
+
219
+ This function is useful for cleaning input data when using the
220
+ "unicode sandwich" approach, which involves converting bytes (i.e. strings
221
+ of type sequence of bytes) to unicode (i.e. strings of type sequence of
222
+ unicode codepoints, in py2 `unicode` or `future.types.newstr.newstr`,
223
+ in py3 `str` ) as soon as possible when recieving input data, and
224
+ converting unicode back to bytes as late as possible.
225
+ achtung!:
226
+ - converting unicode back to bytes is not covered by this function
227
+ - converting unicode back to bytes is not always necessary. when in doubt,
228
+ do not do it.
229
+ Reference: https://nedbatchelder.com/text/unipain.html
230
+
231
+ py2:
232
+ - "errors" can be: "strict", "ignore", "replace",
233
+ - ref: https://docs.python.org/2/howto/unicode.html#the-unicode-type
234
+ py3:
235
+ - "errors" can be: "strict", "ignore", "replace", "backslashreplace"
236
+ - ref: https://docs.python.org/3/howto/unicode.html#the-string-type
237
+ """
238
+ if isinstance(value, bytes):
239
+ return value.decode("utf-8", errors)
240
+ return value
241
+
242
+ def decodeBytesToUnicodeConditional(value, errors="ignore", condition=True):
243
+ """
244
+ if *condition*, then call decodeBytesToUnicode(*value*, *errors*),
245
+ else return *value*
246
+
247
+ This may be useful when we want to conditionally apply decodeBytesToUnicode,
248
+ maintaining brevity.
249
+
250
+ Parameters
251
+ ----------
252
+ value : any
253
+ passed to decodeBytesToUnicode
254
+ errors: str
255
+ passed to decodeBytesToUnicode
256
+ condition: boolean of object with attribute __bool__()
257
+ if True, then we run decodeBytesToUnicode. Usually PY2/PY3
258
+ """
259
+ if condition:
260
+ return decodeBytesToUnicode(value, errors)
261
+ return value
262
+
263
+ def encodeUnicodeToBytes(value, errors="strict"):
264
+ """
265
+ Accepts an input "value" of generic type.
266
+
267
+ If "value" is a string of type sequence of unicode (i.e. in py2 `unicode` or
268
+ `future.types.newstr.newstr`, in py3 `str`), then it is converted to
269
+ a sequence of bytes.
270
+
271
+ This function is useful for encoding output data when using the
272
+ "unicode sandwich" approach, which involves converting unicode (i.e. strings
273
+ of type sequence of unicode codepoints) to bytes (i.e. strings of type
274
+ sequence of bytes, in py2 `str` or `future.types.newbytes.newbytes`,
275
+ in py3 `bytes`) as late as possible when passing a string to a third-party
276
+ function that only accepts bytes as input (pycurl's curl.setop is an
277
+ example).
278
+ py2:
279
+ - "errors" can be: "strict", "ignore", "replace", "xmlcharrefreplace"
280
+ - ref: https://docs.python.org/2/howto/unicode.html#the-unicode-type
281
+ py3:
282
+ - "errors" can be: "strict", "ignore", "replace", "backslashreplace",
283
+ "xmlcharrefreplace", "namereplace"
284
+ - ref: https://docs.python.org/3/howto/unicode.html#the-string-type
285
+ """
286
+ if isinstance(value, str):
287
+ return value.encode("utf-8", errors)
288
+ return value
289
+
290
+ def encodeUnicodeToBytesConditional(value, errors="ignore", condition=True):
291
+ """
292
+ if *condition*, then call encodeUnicodeToBytes(*value*, *errors*),
293
+ else return *value*
294
+
295
+ This may be useful when we want to conditionally apply encodeUnicodeToBytes,
296
+ maintaining brevity.
297
+
298
+ Parameters
299
+ ----------
300
+ value : any
301
+ passed to encodeUnicodeToBytes
302
+ errors: str
303
+ passed to encodeUnicodeToBytes
304
+ condition: boolean of object with attribute __bool__()
305
+ if True, then we run encodeUnicodeToBytes. Usually PY2/PY3
306
+ """
307
+ if condition:
308
+ return encodeUnicodeToBytes(value, errors)
309
+ return value
310
+
311
+ def normalize_spaces(text):
312
+ """
313
+ Helper function to remove any number of empty spaces within given text and replace
314
+ then with single space.
315
+ :param text: string
316
+ :return: normalized string
317
+ """
318
+ return re.sub(r'\s+', ' ', text).strip()