gcloud 0.0.4 → 0.0.6

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 (768) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +4 -0
  3. data/Makefile +4 -0
  4. data/Manifest +760 -1
  5. data/bin/gcloud +7 -0
  6. data/bin/{gcutil → gcutil.symlink} +0 -0
  7. data/bin/gsutil-symlink +377 -0
  8. data/gcloud.gemspec +5 -5
  9. data/packages/gsutil/CHECKSUM +1 -0
  10. data/packages/gsutil/COPYING +202 -0
  11. data/packages/gsutil/LICENSE.third_party +295 -0
  12. data/packages/gsutil/MANIFEST.in +5 -0
  13. data/packages/gsutil/README +38 -0
  14. data/packages/gsutil/README.pkg +49 -0
  15. data/packages/gsutil/ReleaseNotes.txt +780 -0
  16. data/packages/gsutil/VERSION +1 -0
  17. data/packages/gsutil/boto/Changelog.rst +35 -0
  18. data/packages/gsutil/boto/LICENSE +18 -0
  19. data/packages/gsutil/boto/MANIFEST.in +12 -0
  20. data/packages/gsutil/boto/README.rst +163 -0
  21. data/packages/gsutil/boto/bin/asadmin +290 -0
  22. data/packages/gsutil/boto/bin/bundle_image +27 -0
  23. data/packages/gsutil/boto/bin/cfadmin +108 -0
  24. data/packages/gsutil/boto/bin/cq +89 -0
  25. data/packages/gsutil/boto/bin/cwutil +140 -0
  26. data/packages/gsutil/boto/bin/elbadmin +284 -0
  27. data/packages/gsutil/boto/bin/fetch_file +43 -0
  28. data/packages/gsutil/boto/bin/glacier +154 -0
  29. data/packages/gsutil/boto/bin/instance_events +145 -0
  30. data/packages/gsutil/boto/bin/kill_instance +35 -0
  31. data/packages/gsutil/boto/bin/launch_instance +252 -0
  32. data/packages/gsutil/boto/bin/list_instances +90 -0
  33. data/packages/gsutil/boto/bin/lss3 +77 -0
  34. data/packages/gsutil/boto/bin/mturk +465 -0
  35. data/packages/gsutil/boto/bin/pyami_sendmail +52 -0
  36. data/packages/gsutil/boto/bin/route53 +205 -0
  37. data/packages/gsutil/boto/bin/s3put +374 -0
  38. data/packages/gsutil/boto/bin/sdbadmin +194 -0
  39. data/packages/gsutil/boto/bin/taskadmin +116 -0
  40. data/packages/gsutil/boto/boto/__init__.py +793 -0
  41. data/packages/gsutil/boto/boto/__init__.pyc +0 -0
  42. data/packages/gsutil/boto/boto/auth.py +682 -0
  43. data/packages/gsutil/boto/boto/auth.pyc +0 -0
  44. data/packages/gsutil/boto/boto/auth_handler.py +58 -0
  45. data/packages/gsutil/boto/boto/auth_handler.pyc +0 -0
  46. data/packages/gsutil/boto/boto/beanstalk/__init__.py +65 -0
  47. data/packages/gsutil/boto/boto/beanstalk/exception.py +64 -0
  48. data/packages/gsutil/boto/boto/beanstalk/layer1.py +1153 -0
  49. data/packages/gsutil/boto/boto/beanstalk/response.py +703 -0
  50. data/packages/gsutil/boto/boto/beanstalk/wrapper.py +29 -0
  51. data/packages/gsutil/boto/boto/cacerts/__init__.py +22 -0
  52. data/packages/gsutil/boto/boto/cacerts/__init__.pyc +0 -0
  53. data/packages/gsutil/boto/boto/cacerts/cacerts.txt +633 -0
  54. data/packages/gsutil/boto/boto/cloudformation/__init__.py +68 -0
  55. data/packages/gsutil/boto/boto/cloudformation/connection.py +364 -0
  56. data/packages/gsutil/boto/boto/cloudformation/stack.py +360 -0
  57. data/packages/gsutil/boto/boto/cloudformation/template.py +43 -0
  58. data/packages/gsutil/boto/boto/cloudfront/__init__.py +324 -0
  59. data/packages/gsutil/boto/boto/cloudfront/distribution.py +745 -0
  60. data/packages/gsutil/boto/boto/cloudfront/exception.py +26 -0
  61. data/packages/gsutil/boto/boto/cloudfront/identity.py +122 -0
  62. data/packages/gsutil/boto/boto/cloudfront/invalidation.py +216 -0
  63. data/packages/gsutil/boto/boto/cloudfront/logging.py +38 -0
  64. data/packages/gsutil/boto/boto/cloudfront/object.py +48 -0
  65. data/packages/gsutil/boto/boto/cloudfront/origin.py +150 -0
  66. data/packages/gsutil/boto/boto/cloudfront/signers.py +60 -0
  67. data/packages/gsutil/boto/boto/cloudsearch/__init__.py +45 -0
  68. data/packages/gsutil/boto/boto/cloudsearch/document.py +265 -0
  69. data/packages/gsutil/boto/boto/cloudsearch/domain.py +394 -0
  70. data/packages/gsutil/boto/boto/cloudsearch/layer1.py +738 -0
  71. data/packages/gsutil/boto/boto/cloudsearch/layer2.py +67 -0
  72. data/packages/gsutil/boto/boto/cloudsearch/optionstatus.py +248 -0
  73. data/packages/gsutil/boto/boto/cloudsearch/search.py +365 -0
  74. data/packages/gsutil/boto/boto/cloudsearch/sourceattribute.py +75 -0
  75. data/packages/gsutil/boto/boto/compat.py +28 -0
  76. data/packages/gsutil/boto/boto/compat.pyc +0 -0
  77. data/packages/gsutil/boto/boto/connection.py +1081 -0
  78. data/packages/gsutil/boto/boto/connection.pyc +0 -0
  79. data/packages/gsutil/boto/boto/contrib/__init__.py +22 -0
  80. data/packages/gsutil/boto/boto/contrib/ymlmessage.py +52 -0
  81. data/packages/gsutil/boto/boto/core/README +58 -0
  82. data/packages/gsutil/boto/boto/core/__init__.py +23 -0
  83. data/packages/gsutil/boto/boto/core/auth.py +78 -0
  84. data/packages/gsutil/boto/boto/core/credentials.py +154 -0
  85. data/packages/gsutil/boto/boto/core/dictresponse.py +178 -0
  86. data/packages/gsutil/boto/boto/core/service.py +67 -0
  87. data/packages/gsutil/boto/boto/datapipeline/__init__.py +0 -0
  88. data/packages/gsutil/boto/boto/datapipeline/exceptions.py +42 -0
  89. data/packages/gsutil/boto/boto/datapipeline/layer1.py +546 -0
  90. data/packages/gsutil/boto/boto/dynamodb/__init__.py +66 -0
  91. data/packages/gsutil/boto/boto/dynamodb/batch.py +262 -0
  92. data/packages/gsutil/boto/boto/dynamodb/condition.py +170 -0
  93. data/packages/gsutil/boto/boto/dynamodb/exceptions.py +64 -0
  94. data/packages/gsutil/boto/boto/dynamodb/item.py +196 -0
  95. data/packages/gsutil/boto/boto/dynamodb/layer1.py +575 -0
  96. data/packages/gsutil/boto/boto/dynamodb/layer2.py +798 -0
  97. data/packages/gsutil/boto/boto/dynamodb/schema.py +112 -0
  98. data/packages/gsutil/boto/boto/dynamodb/table.py +540 -0
  99. data/packages/gsutil/boto/boto/dynamodb/types.py +326 -0
  100. data/packages/gsutil/boto/boto/ec2/__init__.py +96 -0
  101. data/packages/gsutil/boto/boto/ec2/address.py +103 -0
  102. data/packages/gsutil/boto/boto/ec2/autoscale/__init__.py +781 -0
  103. data/packages/gsutil/boto/boto/ec2/autoscale/activity.py +74 -0
  104. data/packages/gsutil/boto/boto/ec2/autoscale/group.py +337 -0
  105. data/packages/gsutil/boto/boto/ec2/autoscale/instance.py +60 -0
  106. data/packages/gsutil/boto/boto/ec2/autoscale/launchconfig.py +209 -0
  107. data/packages/gsutil/boto/boto/ec2/autoscale/policy.py +166 -0
  108. data/packages/gsutil/boto/boto/ec2/autoscale/request.py +38 -0
  109. data/packages/gsutil/boto/boto/ec2/autoscale/scheduled.py +60 -0
  110. data/packages/gsutil/boto/boto/ec2/autoscale/tag.py +84 -0
  111. data/packages/gsutil/boto/boto/ec2/blockdevicemapping.py +141 -0
  112. data/packages/gsutil/boto/boto/ec2/bundleinstance.py +78 -0
  113. data/packages/gsutil/boto/boto/ec2/buyreservation.py +84 -0
  114. data/packages/gsutil/boto/boto/ec2/cloudwatch/__init__.py +603 -0
  115. data/packages/gsutil/boto/boto/ec2/cloudwatch/alarm.py +316 -0
  116. data/packages/gsutil/boto/boto/ec2/cloudwatch/datapoint.py +40 -0
  117. data/packages/gsutil/boto/boto/ec2/cloudwatch/dimension.py +38 -0
  118. data/packages/gsutil/boto/boto/ec2/cloudwatch/listelement.py +31 -0
  119. data/packages/gsutil/boto/boto/ec2/cloudwatch/metric.py +175 -0
  120. data/packages/gsutil/boto/boto/ec2/connection.py +3409 -0
  121. data/packages/gsutil/boto/boto/ec2/ec2object.py +107 -0
  122. data/packages/gsutil/boto/boto/ec2/elb/__init__.py +553 -0
  123. data/packages/gsutil/boto/boto/ec2/elb/healthcheck.py +89 -0
  124. data/packages/gsutil/boto/boto/ec2/elb/instancestate.py +62 -0
  125. data/packages/gsutil/boto/boto/ec2/elb/listelement.py +36 -0
  126. data/packages/gsutil/boto/boto/ec2/elb/listener.py +75 -0
  127. data/packages/gsutil/boto/boto/ec2/elb/loadbalancer.py +324 -0
  128. data/packages/gsutil/boto/boto/ec2/elb/policies.py +89 -0
  129. data/packages/gsutil/boto/boto/ec2/elb/securitygroup.py +38 -0
  130. data/packages/gsutil/boto/boto/ec2/group.py +39 -0
  131. data/packages/gsutil/boto/boto/ec2/image.py +350 -0
  132. data/packages/gsutil/boto/boto/ec2/instance.py +661 -0
  133. data/packages/gsutil/boto/boto/ec2/instanceinfo.py +51 -0
  134. data/packages/gsutil/boto/boto/ec2/instancestatus.py +207 -0
  135. data/packages/gsutil/boto/boto/ec2/keypair.py +113 -0
  136. data/packages/gsutil/boto/boto/ec2/launchspecification.py +105 -0
  137. data/packages/gsutil/boto/boto/ec2/networkinterface.py +247 -0
  138. data/packages/gsutil/boto/boto/ec2/placementgroup.py +51 -0
  139. data/packages/gsutil/boto/boto/ec2/regioninfo.py +34 -0
  140. data/packages/gsutil/boto/boto/ec2/reservedinstance.py +227 -0
  141. data/packages/gsutil/boto/boto/ec2/securitygroup.py +357 -0
  142. data/packages/gsutil/boto/boto/ec2/snapshot.py +170 -0
  143. data/packages/gsutil/boto/boto/ec2/spotdatafeedsubscription.py +63 -0
  144. data/packages/gsutil/boto/boto/ec2/spotinstancerequest.py +188 -0
  145. data/packages/gsutil/boto/boto/ec2/spotpricehistory.py +55 -0
  146. data/packages/gsutil/boto/boto/ec2/tag.py +87 -0
  147. data/packages/gsutil/boto/boto/ec2/vmtype.py +58 -0
  148. data/packages/gsutil/boto/boto/ec2/volume.py +293 -0
  149. data/packages/gsutil/boto/boto/ec2/volumestatus.py +200 -0
  150. data/packages/gsutil/boto/boto/ec2/zone.py +80 -0
  151. data/packages/gsutil/boto/boto/ecs/__init__.py +90 -0
  152. data/packages/gsutil/boto/boto/ecs/item.py +153 -0
  153. data/packages/gsutil/boto/boto/elasticache/__init__.py +62 -0
  154. data/packages/gsutil/boto/boto/elasticache/layer1.py +1252 -0
  155. data/packages/gsutil/boto/boto/elastictranscoder/__init__.py +62 -0
  156. data/packages/gsutil/boto/boto/elastictranscoder/exceptions.py +46 -0
  157. data/packages/gsutil/boto/boto/elastictranscoder/layer1.py +509 -0
  158. data/packages/gsutil/boto/boto/emr/__init__.py +73 -0
  159. data/packages/gsutil/boto/boto/emr/bootstrap_action.py +44 -0
  160. data/packages/gsutil/boto/boto/emr/connection.py +531 -0
  161. data/packages/gsutil/boto/boto/emr/emrobject.py +176 -0
  162. data/packages/gsutil/boto/boto/emr/instance_group.py +43 -0
  163. data/packages/gsutil/boto/boto/emr/step.py +281 -0
  164. data/packages/gsutil/boto/boto/exception.py +476 -0
  165. data/packages/gsutil/boto/boto/exception.pyc +0 -0
  166. data/packages/gsutil/boto/boto/file/README +49 -0
  167. data/packages/gsutil/boto/boto/file/__init__.py +28 -0
  168. data/packages/gsutil/boto/boto/file/bucket.py +112 -0
  169. data/packages/gsutil/boto/boto/file/connection.py +33 -0
  170. data/packages/gsutil/boto/boto/file/key.py +199 -0
  171. data/packages/gsutil/boto/boto/file/simpleresultset.py +30 -0
  172. data/packages/gsutil/boto/boto/fps/__init__.py +21 -0
  173. data/packages/gsutil/boto/boto/fps/connection.py +369 -0
  174. data/packages/gsutil/boto/boto/fps/exception.py +344 -0
  175. data/packages/gsutil/boto/boto/fps/response.py +175 -0
  176. data/packages/gsutil/boto/boto/glacier/__init__.py +57 -0
  177. data/packages/gsutil/boto/boto/glacier/concurrent.py +409 -0
  178. data/packages/gsutil/boto/boto/glacier/exceptions.py +58 -0
  179. data/packages/gsutil/boto/boto/glacier/job.py +152 -0
  180. data/packages/gsutil/boto/boto/glacier/layer1.py +637 -0
  181. data/packages/gsutil/boto/boto/glacier/layer2.py +93 -0
  182. data/packages/gsutil/boto/boto/glacier/response.py +48 -0
  183. data/packages/gsutil/boto/boto/glacier/utils.py +163 -0
  184. data/packages/gsutil/boto/boto/glacier/vault.py +387 -0
  185. data/packages/gsutil/boto/boto/glacier/writer.py +242 -0
  186. data/packages/gsutil/boto/boto/gs/__init__.py +22 -0
  187. data/packages/gsutil/boto/boto/gs/__init__.pyc +0 -0
  188. data/packages/gsutil/boto/boto/gs/acl.py +304 -0
  189. data/packages/gsutil/boto/boto/gs/acl.pyc +0 -0
  190. data/packages/gsutil/boto/boto/gs/bucket.py +870 -0
  191. data/packages/gsutil/boto/boto/gs/bucket.pyc +0 -0
  192. data/packages/gsutil/boto/boto/gs/bucketlistresultset.py +64 -0
  193. data/packages/gsutil/boto/boto/gs/bucketlistresultset.pyc +0 -0
  194. data/packages/gsutil/boto/boto/gs/connection.py +103 -0
  195. data/packages/gsutil/boto/boto/gs/connection.pyc +0 -0
  196. data/packages/gsutil/boto/boto/gs/cors.py +169 -0
  197. data/packages/gsutil/boto/boto/gs/cors.pyc +0 -0
  198. data/packages/gsutil/boto/boto/gs/key.py +704 -0
  199. data/packages/gsutil/boto/boto/gs/key.pyc +0 -0
  200. data/packages/gsutil/boto/boto/gs/resumable_upload_handler.py +659 -0
  201. data/packages/gsutil/boto/boto/gs/resumable_upload_handler.pyc +0 -0
  202. data/packages/gsutil/boto/boto/gs/user.py +54 -0
  203. data/packages/gsutil/boto/boto/gs/user.pyc +0 -0
  204. data/packages/gsutil/boto/boto/handler.py +44 -0
  205. data/packages/gsutil/boto/boto/handler.pyc +0 -0
  206. data/packages/gsutil/boto/boto/https_connection.py +124 -0
  207. data/packages/gsutil/boto/boto/https_connection.pyc +0 -0
  208. data/packages/gsutil/boto/boto/iam/__init__.py +74 -0
  209. data/packages/gsutil/boto/boto/iam/connection.py +1317 -0
  210. data/packages/gsutil/boto/boto/iam/summarymap.py +42 -0
  211. data/packages/gsutil/boto/boto/jsonresponse.py +163 -0
  212. data/packages/gsutil/boto/boto/jsonresponse.pyc +0 -0
  213. data/packages/gsutil/boto/boto/manage/__init__.py +23 -0
  214. data/packages/gsutil/boto/boto/manage/cmdshell.py +241 -0
  215. data/packages/gsutil/boto/boto/manage/propget.py +64 -0
  216. data/packages/gsutil/boto/boto/manage/server.py +556 -0
  217. data/packages/gsutil/boto/boto/manage/task.py +175 -0
  218. data/packages/gsutil/boto/boto/manage/test_manage.py +34 -0
  219. data/packages/gsutil/boto/boto/manage/volume.py +420 -0
  220. data/packages/gsutil/boto/boto/mashups/__init__.py +23 -0
  221. data/packages/gsutil/boto/boto/mashups/interactive.py +97 -0
  222. data/packages/gsutil/boto/boto/mashups/iobject.py +115 -0
  223. data/packages/gsutil/boto/boto/mashups/order.py +211 -0
  224. data/packages/gsutil/boto/boto/mashups/server.py +395 -0
  225. data/packages/gsutil/boto/boto/mturk/__init__.py +23 -0
  226. data/packages/gsutil/boto/boto/mturk/connection.py +1027 -0
  227. data/packages/gsutil/boto/boto/mturk/layoutparam.py +55 -0
  228. data/packages/gsutil/boto/boto/mturk/notification.py +103 -0
  229. data/packages/gsutil/boto/boto/mturk/price.py +48 -0
  230. data/packages/gsutil/boto/boto/mturk/qualification.py +137 -0
  231. data/packages/gsutil/boto/boto/mturk/question.py +455 -0
  232. data/packages/gsutil/boto/boto/mws/__init__.py +21 -0
  233. data/packages/gsutil/boto/boto/mws/connection.py +813 -0
  234. data/packages/gsutil/boto/boto/mws/exception.py +75 -0
  235. data/packages/gsutil/boto/boto/mws/response.py +655 -0
  236. data/packages/gsutil/boto/boto/plugin.py +90 -0
  237. data/packages/gsutil/boto/boto/plugin.pyc +0 -0
  238. data/packages/gsutil/boto/boto/provider.py +337 -0
  239. data/packages/gsutil/boto/boto/provider.pyc +0 -0
  240. data/packages/gsutil/boto/boto/pyami/__init__.py +22 -0
  241. data/packages/gsutil/boto/boto/pyami/__init__.pyc +0 -0
  242. data/packages/gsutil/boto/boto/pyami/bootstrap.py +134 -0
  243. data/packages/gsutil/boto/boto/pyami/config.py +229 -0
  244. data/packages/gsutil/boto/boto/pyami/config.pyc +0 -0
  245. data/packages/gsutil/boto/boto/pyami/copybot.cfg +60 -0
  246. data/packages/gsutil/boto/boto/pyami/copybot.py +97 -0
  247. data/packages/gsutil/boto/boto/pyami/helloworld.py +28 -0
  248. data/packages/gsutil/boto/boto/pyami/installers/__init__.py +64 -0
  249. data/packages/gsutil/boto/boto/pyami/installers/ubuntu/__init__.py +22 -0
  250. data/packages/gsutil/boto/boto/pyami/installers/ubuntu/apache.py +43 -0
  251. data/packages/gsutil/boto/boto/pyami/installers/ubuntu/ebs.py +238 -0
  252. data/packages/gsutil/boto/boto/pyami/installers/ubuntu/installer.py +96 -0
  253. data/packages/gsutil/boto/boto/pyami/installers/ubuntu/mysql.py +109 -0
  254. data/packages/gsutil/boto/boto/pyami/installers/ubuntu/trac.py +139 -0
  255. data/packages/gsutil/boto/boto/pyami/launch_ami.py +178 -0
  256. data/packages/gsutil/boto/boto/pyami/scriptbase.py +44 -0
  257. data/packages/gsutil/boto/boto/pyami/startup.py +60 -0
  258. data/packages/gsutil/boto/boto/rds/__init__.py +1194 -0
  259. data/packages/gsutil/boto/boto/rds/dbinstance.py +357 -0
  260. data/packages/gsutil/boto/boto/rds/dbsecuritygroup.py +177 -0
  261. data/packages/gsutil/boto/boto/rds/dbsnapshot.py +108 -0
  262. data/packages/gsutil/boto/boto/rds/event.py +49 -0
  263. data/packages/gsutil/boto/boto/rds/parametergroup.py +201 -0
  264. data/packages/gsutil/boto/boto/rds/regioninfo.py +32 -0
  265. data/packages/gsutil/boto/boto/regioninfo.py +63 -0
  266. data/packages/gsutil/boto/boto/regioninfo.pyc +0 -0
  267. data/packages/gsutil/boto/boto/resultset.py +169 -0
  268. data/packages/gsutil/boto/boto/resultset.pyc +0 -0
  269. data/packages/gsutil/boto/boto/roboto/__init__.py +1 -0
  270. data/packages/gsutil/boto/boto/roboto/awsqueryrequest.py +504 -0
  271. data/packages/gsutil/boto/boto/roboto/awsqueryservice.py +121 -0
  272. data/packages/gsutil/boto/boto/roboto/param.py +147 -0
  273. data/packages/gsutil/boto/boto/route53/__init__.py +75 -0
  274. data/packages/gsutil/boto/boto/route53/connection.py +403 -0
  275. data/packages/gsutil/boto/boto/route53/exception.py +27 -0
  276. data/packages/gsutil/boto/boto/route53/hostedzone.py +56 -0
  277. data/packages/gsutil/boto/boto/route53/record.py +306 -0
  278. data/packages/gsutil/boto/boto/route53/status.py +42 -0
  279. data/packages/gsutil/boto/boto/route53/zone.py +412 -0
  280. data/packages/gsutil/boto/boto/s3/__init__.py +84 -0
  281. data/packages/gsutil/boto/boto/s3/__init__.pyc +0 -0
  282. data/packages/gsutil/boto/boto/s3/acl.py +164 -0
  283. data/packages/gsutil/boto/boto/s3/acl.pyc +0 -0
  284. data/packages/gsutil/boto/boto/s3/bucket.py +1634 -0
  285. data/packages/gsutil/boto/boto/s3/bucket.pyc +0 -0
  286. data/packages/gsutil/boto/boto/s3/bucketlistresultset.py +139 -0
  287. data/packages/gsutil/boto/boto/s3/bucketlistresultset.pyc +0 -0
  288. data/packages/gsutil/boto/boto/s3/bucketlogging.py +83 -0
  289. data/packages/gsutil/boto/boto/s3/bucketlogging.pyc +0 -0
  290. data/packages/gsutil/boto/boto/s3/connection.py +540 -0
  291. data/packages/gsutil/boto/boto/s3/connection.pyc +0 -0
  292. data/packages/gsutil/boto/boto/s3/cors.py +210 -0
  293. data/packages/gsutil/boto/boto/s3/cors.pyc +0 -0
  294. data/packages/gsutil/boto/boto/s3/deletemarker.py +55 -0
  295. data/packages/gsutil/boto/boto/s3/deletemarker.pyc +0 -0
  296. data/packages/gsutil/boto/boto/s3/key.py +1712 -0
  297. data/packages/gsutil/boto/boto/s3/key.pyc +0 -0
  298. data/packages/gsutil/boto/boto/s3/keyfile.py +134 -0
  299. data/packages/gsutil/boto/boto/s3/keyfile.pyc +0 -0
  300. data/packages/gsutil/boto/boto/s3/lifecycle.py +231 -0
  301. data/packages/gsutil/boto/boto/s3/lifecycle.pyc +0 -0
  302. data/packages/gsutil/boto/boto/s3/multidelete.py +138 -0
  303. data/packages/gsutil/boto/boto/s3/multidelete.pyc +0 -0
  304. data/packages/gsutil/boto/boto/s3/multipart.py +315 -0
  305. data/packages/gsutil/boto/boto/s3/multipart.pyc +0 -0
  306. data/packages/gsutil/boto/boto/s3/prefix.py +42 -0
  307. data/packages/gsutil/boto/boto/s3/prefix.pyc +0 -0
  308. data/packages/gsutil/boto/boto/s3/resumable_download_handler.py +339 -0
  309. data/packages/gsutil/boto/boto/s3/resumable_download_handler.pyc +0 -0
  310. data/packages/gsutil/boto/boto/s3/tagging.py +71 -0
  311. data/packages/gsutil/boto/boto/s3/tagging.pyc +0 -0
  312. data/packages/gsutil/boto/boto/s3/user.py +49 -0
  313. data/packages/gsutil/boto/boto/s3/user.pyc +0 -0
  314. data/packages/gsutil/boto/boto/s3/website.py +237 -0
  315. data/packages/gsutil/boto/boto/s3/website.pyc +0 -0
  316. data/packages/gsutil/boto/boto/sdb/__init__.py +67 -0
  317. data/packages/gsutil/boto/boto/sdb/connection.py +617 -0
  318. data/packages/gsutil/boto/boto/sdb/db/__init__.py +20 -0
  319. data/packages/gsutil/boto/boto/sdb/db/blob.py +75 -0
  320. data/packages/gsutil/boto/boto/sdb/db/key.py +59 -0
  321. data/packages/gsutil/boto/boto/sdb/db/manager/__init__.py +85 -0
  322. data/packages/gsutil/boto/boto/sdb/db/manager/sdbmanager.py +732 -0
  323. data/packages/gsutil/boto/boto/sdb/db/manager/xmlmanager.py +517 -0
  324. data/packages/gsutil/boto/boto/sdb/db/model.py +294 -0
  325. data/packages/gsutil/boto/boto/sdb/db/property.py +703 -0
  326. data/packages/gsutil/boto/boto/sdb/db/query.py +85 -0
  327. data/packages/gsutil/boto/boto/sdb/db/sequence.py +226 -0
  328. data/packages/gsutil/boto/boto/sdb/db/test_db.py +231 -0
  329. data/packages/gsutil/boto/boto/sdb/domain.py +377 -0
  330. data/packages/gsutil/boto/boto/sdb/item.py +181 -0
  331. data/packages/gsutil/boto/boto/sdb/queryresultset.py +92 -0
  332. data/packages/gsutil/boto/boto/sdb/regioninfo.py +32 -0
  333. data/packages/gsutil/boto/boto/services/__init__.py +23 -0
  334. data/packages/gsutil/boto/boto/services/bs.py +179 -0
  335. data/packages/gsutil/boto/boto/services/message.py +58 -0
  336. data/packages/gsutil/boto/boto/services/result.py +136 -0
  337. data/packages/gsutil/boto/boto/services/service.py +161 -0
  338. data/packages/gsutil/boto/boto/services/servicedef.py +91 -0
  339. data/packages/gsutil/boto/boto/services/sonofmmm.cfg +43 -0
  340. data/packages/gsutil/boto/boto/services/sonofmmm.py +81 -0
  341. data/packages/gsutil/boto/boto/services/submit.py +88 -0
  342. data/packages/gsutil/boto/boto/ses/__init__.py +54 -0
  343. data/packages/gsutil/boto/boto/ses/connection.py +521 -0
  344. data/packages/gsutil/boto/boto/ses/exceptions.py +77 -0
  345. data/packages/gsutil/boto/boto/sns/__init__.py +78 -0
  346. data/packages/gsutil/boto/boto/sns/connection.py +431 -0
  347. data/packages/gsutil/boto/boto/sqs/__init__.py +56 -0
  348. data/packages/gsutil/boto/boto/sqs/attributes.py +46 -0
  349. data/packages/gsutil/boto/boto/sqs/batchresults.py +95 -0
  350. data/packages/gsutil/boto/boto/sqs/connection.py +417 -0
  351. data/packages/gsutil/boto/boto/sqs/jsonmessage.py +43 -0
  352. data/packages/gsutil/boto/boto/sqs/message.py +253 -0
  353. data/packages/gsutil/boto/boto/sqs/queue.py +478 -0
  354. data/packages/gsutil/boto/boto/sqs/regioninfo.py +32 -0
  355. data/packages/gsutil/boto/boto/storage_uri.py +835 -0
  356. data/packages/gsutil/boto/boto/storage_uri.pyc +0 -0
  357. data/packages/gsutil/boto/boto/sts/__init__.py +55 -0
  358. data/packages/gsutil/boto/boto/sts/connection.py +207 -0
  359. data/packages/gsutil/boto/boto/sts/credentials.py +215 -0
  360. data/packages/gsutil/boto/boto/swf/__init__.py +60 -0
  361. data/packages/gsutil/boto/boto/swf/exceptions.py +44 -0
  362. data/packages/gsutil/boto/boto/swf/layer1.py +1512 -0
  363. data/packages/gsutil/boto/boto/swf/layer1_decisions.py +287 -0
  364. data/packages/gsutil/boto/boto/swf/layer2.py +342 -0
  365. data/packages/gsutil/boto/boto/utils.py +927 -0
  366. data/packages/gsutil/boto/boto/utils.pyc +0 -0
  367. data/packages/gsutil/boto/boto/vpc/__init__.py +910 -0
  368. data/packages/gsutil/boto/boto/vpc/customergateway.py +54 -0
  369. data/packages/gsutil/boto/boto/vpc/dhcpoptions.py +72 -0
  370. data/packages/gsutil/boto/boto/vpc/internetgateway.py +72 -0
  371. data/packages/gsutil/boto/boto/vpc/routetable.py +109 -0
  372. data/packages/gsutil/boto/boto/vpc/subnet.py +57 -0
  373. data/packages/gsutil/boto/boto/vpc/vpc.py +54 -0
  374. data/packages/gsutil/boto/boto/vpc/vpnconnection.py +60 -0
  375. data/packages/gsutil/boto/boto/vpc/vpngateway.py +83 -0
  376. data/packages/gsutil/boto/docs/BotoCheatSheet.pdf +0 -0
  377. data/packages/gsutil/boto/docs/Makefile +89 -0
  378. data/packages/gsutil/boto/docs/make.bat +113 -0
  379. data/packages/gsutil/boto/docs/source/_templates/layout.html +3 -0
  380. data/packages/gsutil/boto/docs/source/autoscale_tut.rst +220 -0
  381. data/packages/gsutil/boto/docs/source/boto_config_tut.rst +125 -0
  382. data/packages/gsutil/boto/docs/source/boto_theme/static/boto.css_t +239 -0
  383. data/packages/gsutil/boto/docs/source/boto_theme/static/pygments.css +61 -0
  384. data/packages/gsutil/boto/docs/source/boto_theme/theme.conf +3 -0
  385. data/packages/gsutil/boto/docs/source/cloudfront_tut.rst +196 -0
  386. data/packages/gsutil/boto/docs/source/cloudsearch_tut.rst +411 -0
  387. data/packages/gsutil/boto/docs/source/cloudwatch_tut.rst +116 -0
  388. data/packages/gsutil/boto/docs/source/conf.py +32 -0
  389. data/packages/gsutil/boto/docs/source/contributing.rst +204 -0
  390. data/packages/gsutil/boto/docs/source/documentation.rst +59 -0
  391. data/packages/gsutil/boto/docs/source/dynamodb_tut.rst +339 -0
  392. data/packages/gsutil/boto/docs/source/ec2_tut.rst +86 -0
  393. data/packages/gsutil/boto/docs/source/elb_tut.rst +257 -0
  394. data/packages/gsutil/boto/docs/source/emr_tut.rst +108 -0
  395. data/packages/gsutil/boto/docs/source/index.rst +146 -0
  396. data/packages/gsutil/boto/docs/source/rds_tut.rst +108 -0
  397. data/packages/gsutil/boto/docs/source/ref/autoscale.rst +62 -0
  398. data/packages/gsutil/boto/docs/source/ref/beanstalk.rst +26 -0
  399. data/packages/gsutil/boto/docs/source/ref/boto.rst +47 -0
  400. data/packages/gsutil/boto/docs/source/ref/cloudformation.rst +34 -0
  401. data/packages/gsutil/boto/docs/source/ref/cloudfront.rst +68 -0
  402. data/packages/gsutil/boto/docs/source/ref/cloudsearch.rst +59 -0
  403. data/packages/gsutil/boto/docs/source/ref/cloudwatch.rst +27 -0
  404. data/packages/gsutil/boto/docs/source/ref/contrib.rst +32 -0
  405. data/packages/gsutil/boto/docs/source/ref/datapipeline.rst +26 -0
  406. data/packages/gsutil/boto/docs/source/ref/dynamodb.rst +61 -0
  407. data/packages/gsutil/boto/docs/source/ref/ec2.rst +140 -0
  408. data/packages/gsutil/boto/docs/source/ref/ecs.rst +19 -0
  409. data/packages/gsutil/boto/docs/source/ref/elasticache.rst +19 -0
  410. data/packages/gsutil/boto/docs/source/ref/elastictranscoder.rst +26 -0
  411. data/packages/gsutil/boto/docs/source/ref/elb.rst +47 -0
  412. data/packages/gsutil/boto/docs/source/ref/emr.rst +34 -0
  413. data/packages/gsutil/boto/docs/source/ref/file.rst +34 -0
  414. data/packages/gsutil/boto/docs/source/ref/fps.rst +19 -0
  415. data/packages/gsutil/boto/docs/source/ref/glacier.rst +63 -0
  416. data/packages/gsutil/boto/docs/source/ref/gs.rst +72 -0
  417. data/packages/gsutil/boto/docs/source/ref/iam.rst +27 -0
  418. data/packages/gsutil/boto/docs/source/ref/index.rst +40 -0
  419. data/packages/gsutil/boto/docs/source/ref/manage.rst +47 -0
  420. data/packages/gsutil/boto/docs/source/ref/mturk.rst +54 -0
  421. data/packages/gsutil/boto/docs/source/ref/mws.rst +33 -0
  422. data/packages/gsutil/boto/docs/source/ref/pyami.rst +103 -0
  423. data/packages/gsutil/boto/docs/source/ref/rds.rst +47 -0
  424. data/packages/gsutil/boto/docs/source/ref/route53.rst +34 -0
  425. data/packages/gsutil/boto/docs/source/ref/s3.rst +111 -0
  426. data/packages/gsutil/boto/docs/source/ref/sdb.rst +45 -0
  427. data/packages/gsutil/boto/docs/source/ref/sdb_db.rst +83 -0
  428. data/packages/gsutil/boto/docs/source/ref/services.rst +61 -0
  429. data/packages/gsutil/boto/docs/source/ref/ses.rst +21 -0
  430. data/packages/gsutil/boto/docs/source/ref/sns.rst +17 -0
  431. data/packages/gsutil/boto/docs/source/ref/sqs.rst +61 -0
  432. data/packages/gsutil/boto/docs/source/ref/sts.rst +25 -0
  433. data/packages/gsutil/boto/docs/source/ref/swf.rst +22 -0
  434. data/packages/gsutil/boto/docs/source/ref/vpc.rst +54 -0
  435. data/packages/gsutil/boto/docs/source/s3_tut.rst +450 -0
  436. data/packages/gsutil/boto/docs/source/security_groups.rst +82 -0
  437. data/packages/gsutil/boto/docs/source/ses_tut.rst +171 -0
  438. data/packages/gsutil/boto/docs/source/simpledb_tut.rst +188 -0
  439. data/packages/gsutil/boto/docs/source/sqs_tut.rst +246 -0
  440. data/packages/gsutil/boto/docs/source/vpc_tut.rst +100 -0
  441. data/packages/gsutil/boto/pylintrc +305 -0
  442. data/packages/gsutil/boto/requirements.txt +10 -0
  443. data/packages/gsutil/boto/setup.py +89 -0
  444. data/packages/gsutil/boto/tests/__init__.py +20 -0
  445. data/packages/gsutil/boto/tests/db/test_lists.py +96 -0
  446. data/packages/gsutil/boto/tests/db/test_password.py +128 -0
  447. data/packages/gsutil/boto/tests/db/test_query.py +152 -0
  448. data/packages/gsutil/boto/tests/db/test_sequence.py +109 -0
  449. data/packages/gsutil/boto/tests/devpay/__init__.py +0 -0
  450. data/packages/gsutil/boto/tests/devpay/test_s3.py +181 -0
  451. data/packages/gsutil/boto/tests/fps/__init__.py +0 -0
  452. data/packages/gsutil/boto/tests/fps/test.py +100 -0
  453. data/packages/gsutil/boto/tests/fps/test_verify_signature.py +12 -0
  454. data/packages/gsutil/boto/tests/integration/__init__.py +0 -0
  455. data/packages/gsutil/boto/tests/integration/beanstalk/test_wrapper.py +209 -0
  456. data/packages/gsutil/boto/tests/integration/cloudformation/__init__.py +21 -0
  457. data/packages/gsutil/boto/tests/integration/cloudformation/test_cert_verification.py +40 -0
  458. data/packages/gsutil/boto/tests/integration/cloudformation/test_connection.py +110 -0
  459. data/packages/gsutil/boto/tests/integration/cloudsearch/__init__.py +21 -0
  460. data/packages/gsutil/boto/tests/integration/cloudsearch/test_cert_verification.py +40 -0
  461. data/packages/gsutil/boto/tests/integration/datapipeline/test_layer1.py +122 -0
  462. data/packages/gsutil/boto/tests/integration/dynamodb/__init__.py +20 -0
  463. data/packages/gsutil/boto/tests/integration/dynamodb/test_cert_verification.py +40 -0
  464. data/packages/gsutil/boto/tests/integration/dynamodb/test_layer1.py +266 -0
  465. data/packages/gsutil/boto/tests/integration/dynamodb/test_layer2.py +484 -0
  466. data/packages/gsutil/boto/tests/integration/dynamodb/test_table.py +84 -0
  467. data/packages/gsutil/boto/tests/integration/ec2/__init__.py +20 -0
  468. data/packages/gsutil/boto/tests/integration/ec2/autoscale/__init__.py +21 -0
  469. data/packages/gsutil/boto/tests/integration/ec2/autoscale/test_cert_verification.py +40 -0
  470. data/packages/gsutil/boto/tests/integration/ec2/autoscale/test_connection.py +167 -0
  471. data/packages/gsutil/boto/tests/integration/ec2/cloudwatch/__init__.py +20 -0
  472. data/packages/gsutil/boto/tests/integration/ec2/cloudwatch/test_cert_verification.py +40 -0
  473. data/packages/gsutil/boto/tests/integration/ec2/cloudwatch/test_connection.py +277 -0
  474. data/packages/gsutil/boto/tests/integration/ec2/elb/__init__.py +20 -0
  475. data/packages/gsutil/boto/tests/integration/ec2/elb/test_cert_verification.py +40 -0
  476. data/packages/gsutil/boto/tests/integration/ec2/elb/test_connection.py +130 -0
  477. data/packages/gsutil/boto/tests/integration/ec2/test_cert_verification.py +40 -0
  478. data/packages/gsutil/boto/tests/integration/ec2/test_connection.py +192 -0
  479. data/packages/gsutil/boto/tests/integration/ec2/vpc/__init__.py +0 -0
  480. data/packages/gsutil/boto/tests/integration/ec2/vpc/test_connection.py +95 -0
  481. data/packages/gsutil/boto/tests/integration/elasticache/__init__.py +0 -0
  482. data/packages/gsutil/boto/tests/integration/elasticache/test_layer1.py +67 -0
  483. data/packages/gsutil/boto/tests/integration/elastictranscoder/__init__.py +0 -0
  484. data/packages/gsutil/boto/tests/integration/elastictranscoder/test_cert_verification.py +35 -0
  485. data/packages/gsutil/boto/tests/integration/elastictranscoder/test_layer1.py +115 -0
  486. data/packages/gsutil/boto/tests/integration/emr/__init__.py +20 -0
  487. data/packages/gsutil/boto/tests/integration/emr/test_cert_verification.py +40 -0
  488. data/packages/gsutil/boto/tests/integration/glacier/__init__.py +22 -0
  489. data/packages/gsutil/boto/tests/integration/glacier/test_cert_verification.py +40 -0
  490. data/packages/gsutil/boto/tests/integration/glacier/test_layer1.py +44 -0
  491. data/packages/gsutil/boto/tests/integration/glacier/test_layer2.py +45 -0
  492. data/packages/gsutil/boto/tests/integration/gs/__init__.py +0 -0
  493. data/packages/gsutil/boto/tests/integration/gs/cb_test_harness.py +71 -0
  494. data/packages/gsutil/boto/tests/integration/gs/test_basic.py +379 -0
  495. data/packages/gsutil/boto/tests/integration/gs/test_generation_conditionals.py +399 -0
  496. data/packages/gsutil/boto/tests/integration/gs/test_resumable_downloads.py +358 -0
  497. data/packages/gsutil/boto/tests/integration/gs/test_resumable_uploads.py +525 -0
  498. data/packages/gsutil/boto/tests/integration/gs/test_storage_uri.py +125 -0
  499. data/packages/gsutil/boto/tests/integration/gs/test_versioning.py +268 -0
  500. data/packages/gsutil/boto/tests/integration/gs/testcase.py +116 -0
  501. data/packages/gsutil/boto/tests/integration/gs/util.py +63 -0
  502. data/packages/gsutil/boto/tests/integration/iam/__init__.py +20 -0
  503. data/packages/gsutil/boto/tests/integration/iam/test_cert_verification.py +40 -0
  504. data/packages/gsutil/boto/tests/integration/mws/__init__.py +0 -0
  505. data/packages/gsutil/boto/tests/integration/mws/test.py +100 -0
  506. data/packages/gsutil/boto/tests/integration/rds/__init__.py +21 -0
  507. data/packages/gsutil/boto/tests/integration/rds/test_cert_verification.py +40 -0
  508. data/packages/gsutil/boto/tests/integration/route53/__init__.py +20 -0
  509. data/packages/gsutil/boto/tests/integration/route53/test_cert_verification.py +40 -0
  510. data/packages/gsutil/boto/tests/integration/route53/test_zone.py +132 -0
  511. data/packages/gsutil/boto/tests/integration/s3/__init__.py +20 -0
  512. data/packages/gsutil/boto/tests/integration/s3/mock_storage_service.py +589 -0
  513. data/packages/gsutil/boto/tests/integration/s3/other_cacerts.txt +70 -0
  514. data/packages/gsutil/boto/tests/integration/s3/test_bucket.py +263 -0
  515. data/packages/gsutil/boto/tests/integration/s3/test_cert_verification.py +40 -0
  516. data/packages/gsutil/boto/tests/integration/s3/test_connection.py +245 -0
  517. data/packages/gsutil/boto/tests/integration/s3/test_cors.py +78 -0
  518. data/packages/gsutil/boto/tests/integration/s3/test_encryption.py +115 -0
  519. data/packages/gsutil/boto/tests/integration/s3/test_https_cert_validation.py +141 -0
  520. data/packages/gsutil/boto/tests/integration/s3/test_key.py +375 -0
  521. data/packages/gsutil/boto/tests/integration/s3/test_mfa.py +95 -0
  522. data/packages/gsutil/boto/tests/integration/s3/test_multidelete.py +181 -0
  523. data/packages/gsutil/boto/tests/integration/s3/test_multipart.py +139 -0
  524. data/packages/gsutil/boto/tests/integration/s3/test_pool.py +246 -0
  525. data/packages/gsutil/boto/tests/integration/s3/test_versioning.py +158 -0
  526. data/packages/gsutil/boto/tests/integration/sdb/__init__.py +20 -0
  527. data/packages/gsutil/boto/tests/integration/sdb/test_cert_verification.py +40 -0
  528. data/packages/gsutil/boto/tests/integration/sdb/test_connection.py +119 -0
  529. data/packages/gsutil/boto/tests/integration/ses/__init__.py +0 -0
  530. data/packages/gsutil/boto/tests/integration/ses/test_cert_verification.py +40 -0
  531. data/packages/gsutil/boto/tests/integration/ses/test_connection.py +38 -0
  532. data/packages/gsutil/boto/tests/integration/sns/__init__.py +20 -0
  533. data/packages/gsutil/boto/tests/integration/sns/test_cert_verification.py +40 -0
  534. data/packages/gsutil/boto/tests/integration/sqs/__init__.py +20 -0
  535. data/packages/gsutil/boto/tests/integration/sqs/test_cert_verification.py +40 -0
  536. data/packages/gsutil/boto/tests/integration/sqs/test_connection.py +217 -0
  537. data/packages/gsutil/boto/tests/integration/sts/__init__.py +20 -0
  538. data/packages/gsutil/boto/tests/integration/sts/test_cert_verification.py +40 -0
  539. data/packages/gsutil/boto/tests/integration/sts/test_session_token.py +65 -0
  540. data/packages/gsutil/boto/tests/integration/swf/__init__.py +0 -0
  541. data/packages/gsutil/boto/tests/integration/swf/test_cert_verification.py +40 -0
  542. data/packages/gsutil/boto/tests/integration/swf/test_layer1.py +246 -0
  543. data/packages/gsutil/boto/tests/integration/swf/test_layer1_workflow_execution.py +173 -0
  544. data/packages/gsutil/boto/tests/mturk/__init__.py +0 -0
  545. data/packages/gsutil/boto/tests/mturk/_init_environment.py +28 -0
  546. data/packages/gsutil/boto/tests/mturk/all_tests.py +24 -0
  547. data/packages/gsutil/boto/tests/mturk/cleanup_tests.py +47 -0
  548. data/packages/gsutil/boto/tests/mturk/common.py +45 -0
  549. data/packages/gsutil/boto/tests/mturk/create_free_text_question_regex.doctest +100 -0
  550. data/packages/gsutil/boto/tests/mturk/create_hit.doctest +92 -0
  551. data/packages/gsutil/boto/tests/mturk/create_hit_binary.doctest +94 -0
  552. data/packages/gsutil/boto/tests/mturk/create_hit_external.py +21 -0
  553. data/packages/gsutil/boto/tests/mturk/create_hit_from_hit_type.doctest +103 -0
  554. data/packages/gsutil/boto/tests/mturk/create_hit_test.py +21 -0
  555. data/packages/gsutil/boto/tests/mturk/create_hit_with_qualifications.py +16 -0
  556. data/packages/gsutil/boto/tests/mturk/hit_persistence.py +27 -0
  557. data/packages/gsutil/boto/tests/mturk/mocks.py +11 -0
  558. data/packages/gsutil/boto/tests/mturk/reviewable_hits.doctest +129 -0
  559. data/packages/gsutil/boto/tests/mturk/run-doctest.py +13 -0
  560. data/packages/gsutil/boto/tests/mturk/search_hits.doctest +16 -0
  561. data/packages/gsutil/boto/tests/mturk/selenium_support.py +61 -0
  562. data/packages/gsutil/boto/tests/mturk/support.py +7 -0
  563. data/packages/gsutil/boto/tests/mturk/test_disable_hit.py +11 -0
  564. data/packages/gsutil/boto/tests/test.py +59 -0
  565. data/packages/gsutil/boto/tests/unit/__init__.py +79 -0
  566. data/packages/gsutil/boto/tests/unit/auth/__init__.py +0 -0
  567. data/packages/gsutil/boto/tests/unit/auth/test_sigv4.py +73 -0
  568. data/packages/gsutil/boto/tests/unit/beanstalk/__init__.py +0 -0
  569. data/packages/gsutil/boto/tests/unit/beanstalk/test_layer1.py +128 -0
  570. data/packages/gsutil/boto/tests/unit/cloudformation/__init__.py +0 -0
  571. data/packages/gsutil/boto/tests/unit/cloudformation/test_connection.py +605 -0
  572. data/packages/gsutil/boto/tests/unit/cloudformation/test_stack.py +63 -0
  573. data/packages/gsutil/boto/tests/unit/cloudfront/__init__.py +0 -0
  574. data/packages/gsutil/boto/tests/unit/cloudfront/test_invalidation_list.py +113 -0
  575. data/packages/gsutil/boto/tests/unit/cloudfront/test_signed_urls.py +354 -0
  576. data/packages/gsutil/boto/tests/unit/cloudsearch/__init__.py +1 -0
  577. data/packages/gsutil/boto/tests/unit/cloudsearch/test_connection.py +241 -0
  578. data/packages/gsutil/boto/tests/unit/cloudsearch/test_document.py +324 -0
  579. data/packages/gsutil/boto/tests/unit/cloudsearch/test_search.py +325 -0
  580. data/packages/gsutil/boto/tests/unit/dynamodb/__init__.py +0 -0
  581. data/packages/gsutil/boto/tests/unit/dynamodb/test_batch.py +103 -0
  582. data/packages/gsutil/boto/tests/unit/dynamodb/test_layer2.py +119 -0
  583. data/packages/gsutil/boto/tests/unit/dynamodb/test_types.py +82 -0
  584. data/packages/gsutil/boto/tests/unit/ec2/__init__.py +0 -0
  585. data/packages/gsutil/boto/tests/unit/ec2/autoscale/__init__.py +0 -0
  586. data/packages/gsutil/boto/tests/unit/ec2/autoscale/test_group.py +162 -0
  587. data/packages/gsutil/boto/tests/unit/ec2/test_address.py +39 -0
  588. data/packages/gsutil/boto/tests/unit/ec2/test_blockdevicemapping.py +79 -0
  589. data/packages/gsutil/boto/tests/unit/ec2/test_connection.py +480 -0
  590. data/packages/gsutil/boto/tests/unit/ec2/test_instance.py +243 -0
  591. data/packages/gsutil/boto/tests/unit/ec2/test_networkinterface.py +140 -0
  592. data/packages/gsutil/boto/tests/unit/ec2/test_volume.py +248 -0
  593. data/packages/gsutil/boto/tests/unit/emr/test_emr_responses.py +373 -0
  594. data/packages/gsutil/boto/tests/unit/glacier/__init__.py +0 -0
  595. data/packages/gsutil/boto/tests/unit/glacier/test_concurrent.py +120 -0
  596. data/packages/gsutil/boto/tests/unit/glacier/test_job.py +60 -0
  597. data/packages/gsutil/boto/tests/unit/glacier/test_layer1.py +98 -0
  598. data/packages/gsutil/boto/tests/unit/glacier/test_layer2.py +266 -0
  599. data/packages/gsutil/boto/tests/unit/glacier/test_utils.py +116 -0
  600. data/packages/gsutil/boto/tests/unit/glacier/test_vault.py +100 -0
  601. data/packages/gsutil/boto/tests/unit/glacier/test_writer.py +185 -0
  602. data/packages/gsutil/boto/tests/unit/provider/__init__.py +0 -0
  603. data/packages/gsutil/boto/tests/unit/provider/test_provider.py +176 -0
  604. data/packages/gsutil/boto/tests/unit/rds/__init__.py +0 -0
  605. data/packages/gsutil/boto/tests/unit/rds/test_connection.py +131 -0
  606. data/packages/gsutil/boto/tests/unit/s3/__init__.py +0 -0
  607. data/packages/gsutil/boto/tests/unit/s3/test_cors_configuration.py +77 -0
  608. data/packages/gsutil/boto/tests/unit/s3/test_key.py +75 -0
  609. data/packages/gsutil/boto/tests/unit/s3/test_keyfile.py +101 -0
  610. data/packages/gsutil/boto/tests/unit/s3/test_lifecycle.py +97 -0
  611. data/packages/gsutil/boto/tests/unit/s3/test_tagging.py +47 -0
  612. data/packages/gsutil/boto/tests/unit/s3/test_uri.py +257 -0
  613. data/packages/gsutil/boto/tests/unit/s3/test_website.py +188 -0
  614. data/packages/gsutil/boto/tests/unit/sns/__init__.py +0 -0
  615. data/packages/gsutil/boto/tests/unit/sns/test_connection.py +99 -0
  616. data/packages/gsutil/boto/tests/unit/sqs/__init__.py +0 -0
  617. data/packages/gsutil/boto/tests/unit/sqs/test_connection.py +98 -0
  618. data/packages/gsutil/boto/tests/unit/sqs/test_queue.py +40 -0
  619. data/packages/gsutil/boto/tests/unit/sts/test_connection.py +74 -0
  620. data/packages/gsutil/boto/tests/unit/test_connection.py +60 -0
  621. data/packages/gsutil/boto/tests/unit/utils/test_utils.py +109 -0
  622. data/packages/gsutil/boto/tox.ini +8 -0
  623. data/packages/gsutil/gslib/README +5 -0
  624. data/packages/gsutil/gslib/__init__.py +22 -0
  625. data/packages/gsutil/gslib/__init__.pyc +0 -0
  626. data/packages/gsutil/gslib/addlhelp/__init__.py +15 -0
  627. data/packages/gsutil/gslib/addlhelp/acls.py +234 -0
  628. data/packages/gsutil/gslib/addlhelp/anon.py +57 -0
  629. data/packages/gsutil/gslib/addlhelp/command_opts.py +116 -0
  630. data/packages/gsutil/gslib/addlhelp/dev.py +139 -0
  631. data/packages/gsutil/gslib/addlhelp/metadata.py +186 -0
  632. data/packages/gsutil/gslib/addlhelp/naming.py +173 -0
  633. data/packages/gsutil/gslib/addlhelp/prod.py +160 -0
  634. data/packages/gsutil/gslib/addlhelp/projects.py +130 -0
  635. data/packages/gsutil/gslib/addlhelp/subdirs.py +110 -0
  636. data/packages/gsutil/gslib/addlhelp/support.py +86 -0
  637. data/packages/gsutil/gslib/addlhelp/versioning.py +242 -0
  638. data/packages/gsutil/gslib/addlhelp/wildcards.py +170 -0
  639. data/packages/gsutil/gslib/bucket_listing_ref.py +175 -0
  640. data/packages/gsutil/gslib/bucket_listing_ref.pyc +0 -0
  641. data/packages/gsutil/gslib/command.py +722 -0
  642. data/packages/gsutil/gslib/command.pyc +0 -0
  643. data/packages/gsutil/gslib/command_runner.py +101 -0
  644. data/packages/gsutil/gslib/command_runner.pyc +0 -0
  645. data/packages/gsutil/gslib/commands/__init__.py +15 -0
  646. data/packages/gsutil/gslib/commands/__init__.pyc +0 -0
  647. data/packages/gsutil/gslib/commands/cat.py +131 -0
  648. data/packages/gsutil/gslib/commands/cat.pyc +0 -0
  649. data/packages/gsutil/gslib/commands/chacl.py +532 -0
  650. data/packages/gsutil/gslib/commands/chacl.pyc +0 -0
  651. data/packages/gsutil/gslib/commands/config.py +694 -0
  652. data/packages/gsutil/gslib/commands/config.pyc +0 -0
  653. data/packages/gsutil/gslib/commands/cp.py +1818 -0
  654. data/packages/gsutil/gslib/commands/cp.pyc +0 -0
  655. data/packages/gsutil/gslib/commands/disablelogging.py +101 -0
  656. data/packages/gsutil/gslib/commands/disablelogging.pyc +0 -0
  657. data/packages/gsutil/gslib/commands/enablelogging.py +149 -0
  658. data/packages/gsutil/gslib/commands/enablelogging.pyc +0 -0
  659. data/packages/gsutil/gslib/commands/getacl.py +82 -0
  660. data/packages/gsutil/gslib/commands/getacl.pyc +0 -0
  661. data/packages/gsutil/gslib/commands/getcors.py +121 -0
  662. data/packages/gsutil/gslib/commands/getcors.pyc +0 -0
  663. data/packages/gsutil/gslib/commands/getdefacl.py +86 -0
  664. data/packages/gsutil/gslib/commands/getdefacl.pyc +0 -0
  665. data/packages/gsutil/gslib/commands/getlogging.py +137 -0
  666. data/packages/gsutil/gslib/commands/getlogging.pyc +0 -0
  667. data/packages/gsutil/gslib/commands/getversioning.py +116 -0
  668. data/packages/gsutil/gslib/commands/getversioning.pyc +0 -0
  669. data/packages/gsutil/gslib/commands/getwebcfg.py +122 -0
  670. data/packages/gsutil/gslib/commands/getwebcfg.pyc +0 -0
  671. data/packages/gsutil/gslib/commands/help.py +218 -0
  672. data/packages/gsutil/gslib/commands/help.pyc +0 -0
  673. data/packages/gsutil/gslib/commands/ls.py +578 -0
  674. data/packages/gsutil/gslib/commands/ls.pyc +0 -0
  675. data/packages/gsutil/gslib/commands/mb.py +172 -0
  676. data/packages/gsutil/gslib/commands/mb.pyc +0 -0
  677. data/packages/gsutil/gslib/commands/mv.py +159 -0
  678. data/packages/gsutil/gslib/commands/mv.pyc +0 -0
  679. data/packages/gsutil/gslib/commands/perfdiag.py +903 -0
  680. data/packages/gsutil/gslib/commands/perfdiag.pyc +0 -0
  681. data/packages/gsutil/gslib/commands/rb.py +113 -0
  682. data/packages/gsutil/gslib/commands/rb.pyc +0 -0
  683. data/packages/gsutil/gslib/commands/rm.py +239 -0
  684. data/packages/gsutil/gslib/commands/rm.pyc +0 -0
  685. data/packages/gsutil/gslib/commands/setacl.py +138 -0
  686. data/packages/gsutil/gslib/commands/setacl.pyc +0 -0
  687. data/packages/gsutil/gslib/commands/setcors.py +145 -0
  688. data/packages/gsutil/gslib/commands/setcors.pyc +0 -0
  689. data/packages/gsutil/gslib/commands/setdefacl.py +105 -0
  690. data/packages/gsutil/gslib/commands/setdefacl.pyc +0 -0
  691. data/packages/gsutil/gslib/commands/setmeta.py +428 -0
  692. data/packages/gsutil/gslib/commands/setmeta.pyc +0 -0
  693. data/packages/gsutil/gslib/commands/setversioning.py +114 -0
  694. data/packages/gsutil/gslib/commands/setversioning.pyc +0 -0
  695. data/packages/gsutil/gslib/commands/setwebcfg.py +190 -0
  696. data/packages/gsutil/gslib/commands/setwebcfg.pyc +0 -0
  697. data/packages/gsutil/gslib/commands/test.py +228 -0
  698. data/packages/gsutil/gslib/commands/test.pyc +0 -0
  699. data/packages/gsutil/gslib/commands/update.py +305 -0
  700. data/packages/gsutil/gslib/commands/update.pyc +0 -0
  701. data/packages/gsutil/gslib/commands/version.py +150 -0
  702. data/packages/gsutil/gslib/commands/version.pyc +0 -0
  703. data/packages/gsutil/gslib/exception.py +76 -0
  704. data/packages/gsutil/gslib/exception.pyc +0 -0
  705. data/packages/gsutil/gslib/help_provider.py +81 -0
  706. data/packages/gsutil/gslib/help_provider.pyc +0 -0
  707. data/packages/gsutil/gslib/name_expansion.py +550 -0
  708. data/packages/gsutil/gslib/name_expansion.pyc +0 -0
  709. data/packages/gsutil/gslib/no_op_auth_plugin.py +30 -0
  710. data/packages/gsutil/gslib/plurality_checkable_iterator.py +56 -0
  711. data/packages/gsutil/gslib/plurality_checkable_iterator.pyc +0 -0
  712. data/packages/gsutil/gslib/project_id.py +67 -0
  713. data/packages/gsutil/gslib/project_id.pyc +0 -0
  714. data/packages/gsutil/gslib/storage_uri_builder.py +56 -0
  715. data/packages/gsutil/gslib/storage_uri_builder.pyc +0 -0
  716. data/packages/gsutil/gslib/tests/__init__.py +15 -0
  717. data/packages/gsutil/gslib/tests/__init__.pyc +0 -0
  718. data/packages/gsutil/gslib/tests/test_chacl.py +236 -0
  719. data/packages/gsutil/gslib/tests/test_cp.py +267 -0
  720. data/packages/gsutil/gslib/tests/test_data/test.gif +0 -0
  721. data/packages/gsutil/gslib/tests/test_data/test.mp3 +0 -0
  722. data/packages/gsutil/gslib/tests/test_ls.py +66 -0
  723. data/packages/gsutil/gslib/tests/test_mv.py +69 -0
  724. data/packages/gsutil/gslib/tests/test_naming.py +989 -0
  725. data/packages/gsutil/gslib/tests/test_perfdiag.py +41 -0
  726. data/packages/gsutil/gslib/tests/test_plurality_checkable_iterator.py +67 -0
  727. data/packages/gsutil/gslib/tests/test_rm.py +143 -0
  728. data/packages/gsutil/gslib/tests/test_setacl.py +152 -0
  729. data/packages/gsutil/gslib/tests/test_setcors.py +168 -0
  730. data/packages/gsutil/gslib/tests/test_setmeta.py +91 -0
  731. data/packages/gsutil/gslib/tests/test_setversioning.py +44 -0
  732. data/packages/gsutil/gslib/tests/test_setwebcfg.py +63 -0
  733. data/packages/gsutil/gslib/tests/test_thread_pool.py +92 -0
  734. data/packages/gsutil/gslib/tests/test_wildcard_iterator.py +364 -0
  735. data/packages/gsutil/gslib/tests/testcase/__init__.py +18 -0
  736. data/packages/gsutil/gslib/tests/testcase/base.py +89 -0
  737. data/packages/gsutil/gslib/tests/testcase/integration_testcase.py +197 -0
  738. data/packages/gsutil/gslib/tests/testcase/unit_testcase.py +230 -0
  739. data/packages/gsutil/gslib/tests/util.py +125 -0
  740. data/packages/gsutil/gslib/tests/util.pyc +0 -0
  741. data/packages/gsutil/gslib/thread_pool.py +79 -0
  742. data/packages/gsutil/gslib/thread_pool.pyc +0 -0
  743. data/packages/gsutil/gslib/util.py +151 -0
  744. data/packages/gsutil/gslib/util.pyc +0 -0
  745. data/packages/gsutil/gslib/wildcard_iterator.py +492 -0
  746. data/packages/gsutil/gslib/wildcard_iterator.pyc +0 -0
  747. data/packages/gsutil/gsutil +377 -0
  748. data/packages/gsutil/gsutil.spec.in +75 -0
  749. data/packages/gsutil/oauth2_plugin/__init__.py +22 -0
  750. data/packages/gsutil/oauth2_plugin/__init__.pyc +0 -0
  751. data/packages/gsutil/oauth2_plugin/oauth2_client.py +642 -0
  752. data/packages/gsutil/oauth2_plugin/oauth2_client.pyc +0 -0
  753. data/packages/gsutil/oauth2_plugin/oauth2_client_test.py +374 -0
  754. data/packages/gsutil/oauth2_plugin/oauth2_helper.py +110 -0
  755. data/packages/gsutil/oauth2_plugin/oauth2_helper.pyc +0 -0
  756. data/packages/gsutil/oauth2_plugin/oauth2_plugin.py +24 -0
  757. data/packages/gsutil/oauth2_plugin/oauth2_plugin.pyc +0 -0
  758. data/packages/gsutil/pkg_gen.sh +54 -0
  759. data/packages/gsutil/pkg_util.py +60 -0
  760. data/packages/gsutil/setup.py +141 -0
  761. data/packages/gsutil/third_party/__init__.py +0 -0
  762. data/packages/gsutil/third_party/__init__.pyc +0 -0
  763. data/packages/gsutil/third_party/fancy_urllib/README +21 -0
  764. data/packages/gsutil/third_party/fancy_urllib/__init__.py +398 -0
  765. data/packages/gsutil/third_party/fancy_urllib/__init__.pyc +0 -0
  766. data/tasks/rubygem.rake +3 -1
  767. metadata +770 -7
  768. metadata.gz.sig +0 -0
@@ -0,0 +1,125 @@
1
+ # Copyright 2013 Google Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import posixpath
16
+ import os.path
17
+ import time
18
+ import urllib
19
+ import urlparse
20
+
21
+ import unittest
22
+ if not hasattr(unittest.TestCase, 'assertIsNone'):
23
+ # external dependency unittest2 required for Python <= 2.6
24
+ import unittest2 as unittest
25
+
26
+ # Flags for running different types of tests.
27
+ RUN_INTEGRATION_TESTS = True
28
+ RUN_UNIT_TESTS = True
29
+
30
+ # Whether the tests are running verbose or not.
31
+ VERBOSE_OUTPUT = False
32
+
33
+
34
+ def _NormalizeURI(uri):
35
+ """Normalizes the path component of a URI.
36
+
37
+ Examples:
38
+ gs://foo//bar -> gs://foo/bar
39
+ gs://foo/./bar -> gs://foo/bar
40
+ """
41
+ # Note: we have to do this dance of changing gs:// to file:// because on
42
+ # Windows, the urlparse function won't work with URL schemes that are not
43
+ # known. urlparse('gs://foo/bar') on Windows turns into:
44
+ # scheme='gs', netloc='', path='//foo/bar'
45
+ # while on non-Windows platforms, it turns into:
46
+ # scheme='gs', netloc='foo', path='/bar'
47
+ uri = uri.replace('gs://', 'file://')
48
+ parsed = list(urlparse.urlparse(uri))
49
+ parsed[2] = posixpath.normpath(parsed[2])
50
+ if parsed[2].startswith('//'):
51
+ # The normpath function doesn't change '//foo' -> '/foo' by design.
52
+ parsed[2] = parsed[2][1:]
53
+ unparsed = urlparse.urlunparse(parsed)
54
+ unparsed = unparsed.replace('file://', 'gs://')
55
+ return unparsed
56
+
57
+
58
+ def ObjectToURI(obj, *suffixes):
59
+ """Returns the storage URI string for a given StorageUri or file object.
60
+
61
+ Args:
62
+ obj: The object to get the URI from. Can be a file object, a subclass of
63
+ boto.storage_uri.StorageURI, or a string. If a string, it is assumed to
64
+ be a local on-disk path.
65
+ suffixes: Suffixes to append. For example, ObjectToUri(bucketuri, 'foo')
66
+ would return the URI for a key name 'foo' inside the given bucket.
67
+ """
68
+ if isinstance(obj, file):
69
+ return 'file://%s' % os.path.abspath(os.path.join(obj.name, *suffixes))
70
+ if isinstance(obj, basestring):
71
+ return 'file://%s' % os.path.join(obj, *suffixes)
72
+ uri = obj.uri
73
+ if suffixes:
74
+ uri = _NormalizeURI('/'.join([uri] + list(suffixes)))
75
+
76
+ # Storage URIs shouldn't contain a trailing slash.
77
+ if uri.endswith('/'):
78
+ uri = uri[:-1]
79
+ return uri
80
+
81
+
82
+ def Retry(ExceptionToCheck, tries=4, delay=3, backoff=2, logger=None):
83
+ """Retry calling the decorated function using an exponential backoff.
84
+
85
+ Taken from:
86
+ https://github.com/saltycrane/retry-decorator
87
+ Licensed under BSD:
88
+ https://github.com/saltycrane/retry-decorator/blob/master/LICENSE
89
+
90
+ :param ExceptionToCheck: the exception to check. may be a tuple of
91
+ exceptions to check
92
+ :type ExceptionToCheck: Exception or tuple
93
+ :param tries: number of times to try (not retry) before giving up
94
+ :type tries: int
95
+ :param delay: initial delay between retries in seconds
96
+ :type delay: int
97
+ :param backoff: backoff multiplier e.g. value of 2 will double the delay
98
+ each retry
99
+ :type backoff: int
100
+ :param logger: logger to use. If None, print
101
+ :type logger: logging.Logger instance
102
+ """
103
+ def deco_retry(f):
104
+ def f_retry(*args, **kwargs):
105
+ mtries, mdelay = tries, delay
106
+ try_one_last_time = True
107
+ while mtries > 1:
108
+ try:
109
+ return f(*args, **kwargs)
110
+ try_one_last_time = False
111
+ break
112
+ except ExceptionToCheck, e:
113
+ msg = "%s, Retrying in %d seconds..." % (str(e), mdelay)
114
+ if logger:
115
+ logger.warning(msg)
116
+ else:
117
+ print msg
118
+ time.sleep(mdelay)
119
+ mtries -= 1
120
+ mdelay *= backoff
121
+ if try_one_last_time:
122
+ return f(*args, **kwargs)
123
+ return
124
+ return f_retry # true decorator
125
+ return deco_retry
@@ -0,0 +1,79 @@
1
+ # Copyright 2011 Google Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Basic thread pool with exception handler."""
16
+
17
+ import logging
18
+ import Queue
19
+ import threading
20
+
21
+
22
+ # Magic values used to cleanly bring down threads.
23
+ _THREAD_EXIT_MAGIC = ('Clean', 'Thread', 'Exit')
24
+
25
+
26
+ def _DefaultExceptionHandler(e):
27
+ logging.exception(e)
28
+
29
+
30
+ class Worker(threading.Thread):
31
+ """Thread executing tasks from a given task's queue."""
32
+
33
+ def __init__(self, tasks, exception_handler):
34
+ threading.Thread.__init__(self)
35
+ self.tasks = tasks
36
+ self.daemon = True
37
+ self.exception_handler = exception_handler
38
+ self.start()
39
+
40
+ def run(self):
41
+ while True:
42
+ func, args, kargs = self.tasks.get()
43
+
44
+ # Listen for magic value indicating thread exit.
45
+ if (func, args, kargs) == _THREAD_EXIT_MAGIC:
46
+ break
47
+
48
+ try:
49
+ func(*args, **kargs)
50
+ except Exception, e:
51
+ self.exception_handler(e)
52
+ finally:
53
+ self.tasks.task_done()
54
+
55
+
56
+ class ThreadPool(object):
57
+ """Pool of threads consuming tasks from a queue."""
58
+
59
+ def __init__(self, num_threads, exception_handler=_DefaultExceptionHandler):
60
+ self.tasks = Queue.Queue(num_threads)
61
+ self.threads = []
62
+ for _ in range(num_threads):
63
+ self.threads.append(Worker(self.tasks, exception_handler))
64
+
65
+ def AddTask(self, func, *args, **kargs):
66
+ """Add a task to the queue."""
67
+ self.tasks.put((func, args, kargs))
68
+
69
+ def WaitCompletion(self):
70
+ """Wait for completion of all the tasks in the queue."""
71
+ self.tasks.join()
72
+
73
+ def Shutdown(self):
74
+ """Shutdown the thread pool."""
75
+ for thread in self.threads:
76
+ self.tasks.put(_THREAD_EXIT_MAGIC)
77
+
78
+ for thread in self.threads:
79
+ thread.join()
@@ -0,0 +1,151 @@
1
+ # Copyright 2010 Google Inc. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Static data and helper functions."""
16
+
17
+ import math
18
+ import re
19
+ import sys
20
+
21
+ import boto
22
+
23
+ # We don't use the oauth2 authentication plugin directly; importing it here
24
+ # ensures that it's loaded and available by default. Note: we made this static
25
+ # state instead of Command instance state because the top-level gsutil code
26
+ # needs to check it.
27
+ HAVE_OAUTH2 = False
28
+ try:
29
+ from oauth2_plugin import oauth2_helper
30
+ HAVE_OAUTH2 = True
31
+ except ImportError:
32
+ pass
33
+
34
+ TWO_MB = 2 * 1024 * 1024
35
+
36
+ NO_MAX = sys.maxint
37
+
38
+ # Binary exponentiation strings.
39
+ _EXP_STRINGS = [
40
+ (0, 'B', 'bit'),
41
+ (10, 'KB', 'kbit'),
42
+ (20, 'MB', 'Mbit'),
43
+ (30, 'GB', 'Gbit'),
44
+ (40, 'TB', 'Tbit'),
45
+ (50, 'PB', 'Pbit'),
46
+ ]
47
+
48
+ # Detect platform types.
49
+ IS_WINDOWS = 'win32' in str(sys.platform).lower()
50
+ IS_LINUX = 'linux' in str(sys.platform).lower()
51
+ IS_OSX = 'darwin' in str(sys.platform).lower()
52
+
53
+ # Enum class for specifying listing style.
54
+ class ListingStyle(object):
55
+ SHORT = 'SHORT'
56
+ LONG = 'LONG'
57
+ LONG_LONG = 'LONG_LONG'
58
+
59
+
60
+ def HasConfiguredCredentials():
61
+ """Determines if boto credential/config file exists."""
62
+ config = boto.config
63
+ has_goog_creds = (config.has_option('Credentials', 'gs_access_key_id') and
64
+ config.has_option('Credentials', 'gs_secret_access_key'))
65
+ has_amzn_creds = (config.has_option('Credentials', 'aws_access_key_id') and
66
+ config.has_option('Credentials', 'aws_secret_access_key'))
67
+ has_oauth_creds = (HAVE_OAUTH2 and
68
+ config.has_option('Credentials', 'gs_oauth2_refresh_token'))
69
+ has_auth_plugins = config.has_option('Plugin', 'plugin_directory')
70
+ return (has_goog_creds or has_amzn_creds or has_oauth_creds
71
+ or has_auth_plugins)
72
+
73
+
74
+ def _RoundToNearestExponent(num):
75
+ i = 0
76
+ while i+1 < len(_EXP_STRINGS) and num >= (2 ** _EXP_STRINGS[i+1][0]):
77
+ i += 1
78
+ return i, round(float(num) / 2 ** _EXP_STRINGS[i][0], 2)
79
+
80
+ def MakeHumanReadable(num):
81
+ """Generates human readable string for a number of bytes.
82
+
83
+ Args:
84
+ num: The number, in bytes.
85
+
86
+ Returns:
87
+ A string form of the number using size abbreviations (KB, MB, etc.).
88
+ """
89
+ i, rounded_val = _RoundToNearestExponent(num)
90
+ return '%s %s' % (rounded_val, _EXP_STRINGS[i][1])
91
+
92
+ def MakeBitsHumanReadable(num):
93
+ """Generates human readable string for a number of bits.
94
+
95
+ Args:
96
+ num: The number, in bits.
97
+
98
+ Returns:
99
+ A string form of the number using bit size abbreviations (kbit, Mbit, etc.)
100
+ """
101
+ i, rounded_val = _RoundToNearestExponent(num)
102
+ return '%s %s' % (rounded_val, _EXP_STRINGS[i][2])
103
+
104
+ def Percentile(values, percent, key=lambda x:x):
105
+ """Find the percentile of a list of values.
106
+
107
+ Taken from: http://code.activestate.com/recipes/511478/
108
+
109
+ Args:
110
+ values: a list of numeric values. Note that the values MUST BE already
111
+ sorted.
112
+ percent: a float value from 0.0 to 1.0.
113
+ key: optional key function to compute value from each element of the list
114
+ of values.
115
+
116
+ Returns:
117
+ The percentile of the values.
118
+ """
119
+ if not values:
120
+ return None
121
+ k = (len(values) - 1) * percent
122
+ f = math.floor(k)
123
+ c = math.ceil(k)
124
+ if f == c:
125
+ return key(values[int(k)])
126
+ d0 = key(values[int(f)]) * (c-k)
127
+ d1 = key(values[int(c)]) * (k-f)
128
+ return d0 + d1
129
+
130
+ def ExtractErrorDetail(e):
131
+ """Extract <Details> text from XML content.
132
+
133
+ Args:
134
+ e: The GSResponseError that includes XML to be parsed.
135
+
136
+ Returns:
137
+ (exception_name, d), where d is <Details> text or None if not found.
138
+ """
139
+ exc_name_parts = re.split("[\.']", str(type(e)))
140
+ if len(exc_name_parts) < 2:
141
+ # Shouldn't happen, but have fallback in case.
142
+ exc_name = str(type(e))
143
+ else:
144
+ exc_name = exc_name_parts[-2]
145
+ if not hasattr(e, 'body'):
146
+ return (exc_name, None)
147
+ detail_start = e.body.find('<Details>')
148
+ detail_end = e.body.find('</Details>')
149
+ if detail_start != -1 and detail_end != -1:
150
+ return (exc_name, e.body[detail_start+9:detail_end])
151
+ return (exc_name, None)
@@ -0,0 +1,492 @@
1
+ # Copyright 2010 Google Inc. All Rights Reserved.
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a
4
+ # copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish, dis-
7
+ # tribute, sublicense, and/or sell copies of the Software, and to permit
8
+ # persons to whom the Software is furnished to do so, subject to the fol-
9
+ # lowing conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included
12
+ # in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15
+ # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16
+ # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17
+ # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20
+ # IN THE SOFTWARE.
21
+
22
+ """Implementation of wildcarding over StorageUris.
23
+
24
+ StorageUri is an abstraction that Google introduced in the boto library,
25
+ for representing storage provider-independent bucket and object names with
26
+ a shorthand URI-like syntax (see boto/boto/storage_uri.py) The current
27
+ class provides wildcarding support for StorageUri objects (including both
28
+ bucket and file system objects), allowing one to express collections of
29
+ objects with syntax like the following:
30
+ gs://mybucket/images/*.png
31
+ file:///tmp/???abc???
32
+
33
+ We provide wildcarding support as part of gsutil rather than as part
34
+ of boto because wildcarding is really part of shell command-like
35
+ functionality.
36
+
37
+ A comment about wildcard semantics: We support both single path component
38
+ wildcards (e.g., using '*') and recursive wildcards (using '**'), for both
39
+ file and cloud URIs. For example,
40
+ gs://bucket/doc/*/*.html
41
+ would enumerate HTML files one directory down from gs://bucket/doc, while
42
+ gs://bucket/**/*.html
43
+ would enumerate HTML files in all objects contained in the bucket.
44
+
45
+ Note also that if you use file system wildcards it's likely your shell
46
+ interprets the wildcarding before passing the command to gsutil. For example:
47
+ % gsutil cp /opt/eclipse/*/*.html gs://bucket/eclipse
48
+ would likely be expanded by the shell into the following before running gsutil:
49
+ % gsutil cp /opt/eclipse/RUNNING.html gs://bucket/eclipse
50
+
51
+ Note also that most shells don't support '**' wildcarding (I think only
52
+ zsh does). If you want to use '**' wildcarding with such a shell you can
53
+ single quote each wildcarded string, so it gets passed uninterpreted by the
54
+ shell to gsutil (at which point gsutil will perform the wildcarding expansion):
55
+ % gsutil cp '/opt/eclipse/**/*.html' gs://bucket/eclipse
56
+ """
57
+
58
+ import boto
59
+ import fnmatch
60
+ import glob
61
+ import os
62
+ import re
63
+ import sys
64
+ import urllib
65
+
66
+ from boto.s3.prefix import Prefix
67
+ from boto.storage_uri import BucketStorageUri
68
+ from bucket_listing_ref import BucketListingRef
69
+
70
+ # Regex to determine if a string contains any wildcards.
71
+ WILDCARD_REGEX = re.compile('[*?\[\]]')
72
+
73
+ WILDCARD_OBJECT_ITERATOR = 'wildcard_object_iterator'
74
+ WILDCARD_BUCKET_ITERATOR = 'wildcard_bucket_iterator'
75
+
76
+
77
+ class WildcardIterator(object):
78
+ """Base class for wildcarding over StorageUris.
79
+
80
+ This class implements support for iterating over StorageUris that
81
+ contain wildcards.
82
+
83
+ The base class is abstract; you should instantiate using the
84
+ wildcard_iterator() static factory method, which chooses the right
85
+ implementation depending on the StorageUri.
86
+ """
87
+
88
+ def __repr__(self):
89
+ """Returns string representation of WildcardIterator."""
90
+ return 'WildcardIterator(%s)' % self.wildcard_uri
91
+
92
+
93
+ class CloudWildcardIterator(WildcardIterator):
94
+ """WildcardIterator subclass for buckets and objects.
95
+
96
+ Iterates over BucketListingRef matching the StorageUri wildcard. It's
97
+ much more efficient to request the Key from the BucketListingRef (via
98
+ GetKey()) than to request the StorageUri and then call uri.get_key()
99
+ to retrieve the key, for cases where you want to get metadata that's
100
+ available in the Bucket (for example to get the name and size of
101
+ each object), because that information is available in the bucket GET
102
+ results. If you were to iterate over URIs for such cases and then get
103
+ the name and size info from each resulting StorageUri, it would cause
104
+ an additional object GET request for each of the result URIs.
105
+ """
106
+
107
+ def __init__(self, wildcard_uri, proj_id_handler,
108
+ bucket_storage_uri_class=BucketStorageUri, all_versions=False,
109
+ headers=None, debug=0):
110
+ """
111
+ Instantiates an iterator over BucketListingRef matching given wildcard URI.
112
+
113
+ Args:
114
+ wildcard_uri: StorageUri that contains the wildcard to iterate.
115
+ proj_id_handler: ProjectIdHandler to use for current command.
116
+ bucket_storage_uri_class: BucketStorageUri interface.
117
+ Settable for testing/mocking.
118
+ headers: Dictionary containing optional HTTP headers to pass to boto.
119
+ debug: Debug level to pass in to boto connection (range 0..3).
120
+ """
121
+ self.wildcard_uri = wildcard_uri
122
+ # Make a copy of the headers so any updates we make during wildcard
123
+ # expansion aren't left in the input params (specifically, so we don't
124
+ # include the x-goog-project-id header needed by a subset of cases, in
125
+ # the data returned to caller, which could then be used in other cases
126
+ # where that header must not be passed).
127
+ if headers is None:
128
+ self.headers = {}
129
+ else:
130
+ self.headers = headers.copy()
131
+ self.proj_id_handler = proj_id_handler
132
+ self.bucket_storage_uri_class = bucket_storage_uri_class
133
+ self.all_versions = all_versions
134
+ self.debug = debug
135
+
136
+ def __iter__(self):
137
+ """Python iterator that gets called when iterating over cloud wildcard.
138
+
139
+ Yields:
140
+ BucketListingRef, or empty iterator if no matches.
141
+ """
142
+ # First handle bucket wildcarding, if any.
143
+ if ContainsWildcard(self.wildcard_uri.bucket_name):
144
+ regex = fnmatch.translate(self.wildcard_uri.bucket_name)
145
+ bucket_uris = []
146
+ prog = re.compile(regex)
147
+ self.proj_id_handler.FillInProjectHeaderIfNeeded(WILDCARD_BUCKET_ITERATOR,
148
+ self.wildcard_uri,
149
+ self.headers)
150
+ for b in self.wildcard_uri.get_all_buckets(headers=self.headers):
151
+ if prog.match(b.name):
152
+ # Use str(b.name) because get_all_buckets() returns Unicode
153
+ # string, which when used to construct x-goog-copy-src metadata
154
+ # requests for object-to-object copies causes pathname '/' chars
155
+ # to be entity-encoded (bucket%2Fdir instead of bucket/dir),
156
+ # which causes the request to fail.
157
+ uri_str = '%s://%s' % (self.wildcard_uri.scheme,
158
+ urllib.quote_plus(str(b.name)))
159
+ bucket_uris.append(
160
+ boto.storage_uri(
161
+ uri_str, debug=self.debug,
162
+ bucket_storage_uri_class=self.bucket_storage_uri_class,
163
+ suppress_consec_slashes=False))
164
+ else:
165
+ bucket_uris = [self.wildcard_uri.clone_replace_name('')]
166
+
167
+ # Now iterate over bucket(s), and handle object wildcarding, if any.
168
+ self.proj_id_handler.FillInProjectHeaderIfNeeded(WILDCARD_OBJECT_ITERATOR,
169
+ self.wildcard_uri,
170
+ self.headers)
171
+ for bucket_uri in bucket_uris:
172
+ if self.wildcard_uri.names_bucket():
173
+ # Bucket-only URI.
174
+ yield BucketListingRef(bucket_uri, key=None, prefix=None,
175
+ headers=self.headers)
176
+ else:
177
+ # URI contains an object name. If there's no wildcard just yield
178
+ # the needed URI.
179
+ if not ContainsWildcard(self.wildcard_uri.object_name):
180
+ uri_to_yield = bucket_uri.clone_replace_name(
181
+ self.wildcard_uri.object_name)
182
+ yield BucketListingRef(uri_to_yield, key=None, prefix=None,
183
+ headers=self.headers)
184
+ else:
185
+ # URI contains a wildcard. Expand iteratively by building
186
+ # prefix/delimiter bucket listing request, filtering the results per
187
+ # the current level's wildcard, and continuing with the next component
188
+ # of the wildcard. See _BuildBucketFilterStrings() documentation
189
+ # for details.
190
+ #
191
+ # Initialize the iteration with bucket name from bucket_uri but
192
+ # object name from self.wildcard_uri. This is needed to handle cases
193
+ # where both the bucket and object names contain wildcards.
194
+ uris_needing_expansion = [
195
+ bucket_uri.clone_replace_name(self.wildcard_uri.object_name)]
196
+ while len(uris_needing_expansion) > 0:
197
+ uri = uris_needing_expansion.pop(0)
198
+ (prefix, delimiter, prefix_wildcard, suffix_wildcard) = (
199
+ self._BuildBucketFilterStrings(uri.object_name))
200
+ prog = re.compile(fnmatch.translate(prefix_wildcard))
201
+ # List bucket for objects matching prefix up to delimiter.
202
+ for key in bucket_uri.list_bucket(prefix=prefix,
203
+ delimiter=delimiter,
204
+ headers=self.headers,
205
+ all_versions=self.all_versions):
206
+ # Check that the prefix regex matches rstripped key.name (to
207
+ # correspond with the rstripped prefix_wildcard from
208
+ # _BuildBucketFilterStrings()).
209
+ if prog.match(key.name.rstrip('/')):
210
+ if suffix_wildcard and key.name.rstrip('/') != suffix_wildcard:
211
+ if isinstance(key, Prefix):
212
+ # There's more wildcard left to expand.
213
+ uris_needing_expansion.append(
214
+ uri.clone_replace_name(key.name.rstrip('/') + '/'
215
+ + suffix_wildcard))
216
+ else:
217
+ # Done expanding.
218
+ expanded_uri = uri.clone_replace_key(key)
219
+
220
+ if isinstance(key, Prefix):
221
+ yield BucketListingRef(expanded_uri, key=None, prefix=key,
222
+ headers=self.headers)
223
+ else:
224
+ yield BucketListingRef(expanded_uri, key=key, prefix=None,
225
+ headers=self.headers)
226
+
227
+ def _BuildBucketFilterStrings(self, wildcard):
228
+ """
229
+ Builds strings needed for querying a bucket and filtering results to
230
+ implement wildcard object name matching.
231
+
232
+ Args:
233
+ wildcard: The wildcard string to match to objects.
234
+
235
+ Returns:
236
+ (prefix, delimiter, prefix_wildcard, suffix_wildcard)
237
+ where:
238
+ prefix is the prefix to be sent in bucket GET request.
239
+ delimiter is the delimiter to be sent in bucket GET request.
240
+ prefix_wildcard is the wildcard to be used to filter bucket GET results.
241
+ suffix_wildcard is wildcard to be appended to filtered bucket GET
242
+ results for next wildcard expansion iteration.
243
+ For example, given the wildcard gs://bucket/abc/d*e/f*.txt we
244
+ would build prefix= abc/d, delimiter=/, prefix_wildcard=d*e, and
245
+ suffix_wildcard=f*.txt. Using this prefix and delimiter for a bucket
246
+ listing request will then produce a listing result set that can be
247
+ filtered using this prefix_wildcard; and we'd use this suffix_wildcard
248
+ to feed into the next call(s) to _BuildBucketFilterStrings(), for the
249
+ next iteration of listing/filtering.
250
+
251
+ Raises:
252
+ AssertionError if wildcard doesn't contain any wildcard chars.
253
+ """
254
+ # Generate a request prefix if the object name part of the wildcard starts
255
+ # with a non-wildcard string (e.g., that's true for 'gs://bucket/abc*xyz').
256
+ match = WILDCARD_REGEX.search(wildcard)
257
+ if not match:
258
+ # Input "wildcard" has no wildcard chars, so just return tuple that will
259
+ # cause a bucket listing to match the given input wildcard. Example: if
260
+ # previous iteration yielded gs://bucket/dir/ with suffix_wildcard abc,
261
+ # the next iteration will call _BuildBucketFilterStrings() with
262
+ # gs://bucket/dir/abc, and we will return prefix ='dir/abc',
263
+ # delimiter='/', prefix_wildcard='dir/abc', and suffix_wildcard=''.
264
+ prefix = wildcard
265
+ delimiter = '/'
266
+ prefix_wildcard = wildcard
267
+ suffix_wildcard = ''
268
+ else:
269
+ if match.start() > 0:
270
+ # Wildcard does not occur at beginning of object name, so construct a
271
+ # prefix string to send to server.
272
+ prefix = wildcard[:match.start()]
273
+ wildcard_part = wildcard[match.start():]
274
+ else:
275
+ prefix = None
276
+ wildcard_part = wildcard
277
+ end = wildcard_part.find('/')
278
+ if end != -1:
279
+ wildcard_part = wildcard_part[:end+1]
280
+ # Remove trailing '/' so we will match gs://bucket/abc* as well as
281
+ # gs://bucket/abc*/ with the same wildcard regex.
282
+ prefix_wildcard = ((prefix or '') + wildcard_part).rstrip('/')
283
+ suffix_wildcard = wildcard[match.end():]
284
+ end = suffix_wildcard.find('/')
285
+ if end == -1:
286
+ suffix_wildcard = ''
287
+ else:
288
+ suffix_wildcard = suffix_wildcard[end+1:]
289
+ # To implement recursive (**) wildcarding, if prefix_wildcard
290
+ # suffix_wildcard starts with '**' don't send a delimiter, and combine
291
+ # suffix_wildcard at end of prefix_wildcard.
292
+ if prefix_wildcard.find('**') != -1:
293
+ delimiter = None
294
+ prefix_wildcard = prefix_wildcard + suffix_wildcard
295
+ suffix_wildcard = ''
296
+ else:
297
+ delimiter = '/'
298
+ delim_pos = suffix_wildcard.find(delimiter)
299
+ # The following debug output is useful for tracing how the algorithm
300
+ # walks through a multi-part wildcard like gs://bucket/abc/d*e/f*.txt
301
+ if self.debug > 1:
302
+ sys.stderr.write(
303
+ 'DEBUG: wildcard=%s, prefix=%s, delimiter=%s, '
304
+ 'prefix_wildcard=%s, suffix_wildcard=%s\n' %
305
+ (wildcard, prefix, delimiter, prefix_wildcard, suffix_wildcard))
306
+ return (prefix, delimiter, prefix_wildcard, suffix_wildcard)
307
+
308
+ def IterKeys(self):
309
+ """
310
+ Convenience iterator that runs underlying iterator and returns Key for each
311
+ iteration.
312
+
313
+ Yields:
314
+ Subclass of boto.s3.key.Key, or empty iterator if no matches.
315
+
316
+ Raises:
317
+ WildcardException: for bucket-only uri.
318
+ """
319
+ for bucket_listing_ref in self. __iter__():
320
+ if bucket_listing_ref.HasKey():
321
+ yield bucket_listing_ref.GetKey()
322
+
323
+ def IterUris(self):
324
+ """
325
+ Convenience iterator that runs underlying iterator and returns StorageUri
326
+ for each iteration.
327
+
328
+ Yields:
329
+ StorageUri, or empty iterator if no matches.
330
+ """
331
+ for bucket_listing_ref in self. __iter__():
332
+ yield bucket_listing_ref.GetUri()
333
+
334
+ def IterUrisForKeys(self):
335
+ """
336
+ Convenience iterator that runs underlying iterator and returns the
337
+ StorageUri for each iterated BucketListingRef that has a Key.
338
+
339
+ Yields:
340
+ StorageUri, or empty iterator if no matches.
341
+ """
342
+ for bucket_listing_ref in self. __iter__():
343
+ if bucket_listing_ref.HasKey():
344
+ yield bucket_listing_ref.GetUri()
345
+
346
+
347
+ class FileWildcardIterator(WildcardIterator):
348
+ """WildcardIterator subclass for files and directories.
349
+
350
+ If you use recursive wildcards ('**') only a single such wildcard is
351
+ supported. For example you could use the wildcard '**/*.txt' to list all .txt
352
+ files in any subdirectory of the current directory, but you couldn't use a
353
+ wildcard like '**/abc/**/*.txt' (which would, if supported, let you find .txt
354
+ files in any subdirectory named 'abc').
355
+ """
356
+
357
+ def __init__(self, wildcard_uri, headers=None, debug=0):
358
+ """
359
+ Instantiate an iterator over BucketListingRefs matching given wildcard URI.
360
+
361
+ Args:
362
+ wildcard_uri: StorageUri that contains the wildcard to iterate.
363
+ headers: Dictionary containing optional HTTP headers to pass to boto.
364
+ debug: Debug level to pass in to boto connection (range 0..3).
365
+ """
366
+ self.wildcard_uri = wildcard_uri
367
+ self.headers = headers
368
+ self.debug = debug
369
+
370
+ def __iter__(self):
371
+ wildcard = self.wildcard_uri.object_name
372
+ match = re.search('\*\*', wildcard)
373
+ if match:
374
+ # Recursive wildcarding request ('.../**/...').
375
+ # Example input: wildcard = '/tmp/tmp2pQJAX/**/*'
376
+ base_dir = wildcard[:match.start()-1]
377
+ remaining_wildcard = wildcard[match.start()+2:]
378
+ # At this point for the above example base_dir = '/tmp/tmp2pQJAX' and
379
+ # remaining_wildcard = '/*'
380
+ if remaining_wildcard.startswith('*'):
381
+ raise WildcardException('Invalid wildcard with more than 2 consecutive '
382
+ '*s (%s)' % wildcard)
383
+ # If there was no remaining wildcard past the recursive wildcard,
384
+ # treat it as if it were a '*'. For example, file://tmp/** is equivalent
385
+ # to file://tmp/**/*
386
+ if not remaining_wildcard:
387
+ remaining_wildcard = '*'
388
+ # Skip slash(es).
389
+ remaining_wildcard = remaining_wildcard.lstrip(os.sep)
390
+ filepaths = []
391
+ for dirpath, unused_dirnames, filenames in os.walk(base_dir):
392
+ filepaths.extend(
393
+ os.path.join(dirpath, f) for f in fnmatch.filter(filenames,
394
+ remaining_wildcard)
395
+ )
396
+ else:
397
+ # Not a recursive wildcarding request.
398
+ filepaths = glob.glob(wildcard)
399
+ for filepath in filepaths:
400
+ expanded_uri = self.wildcard_uri.clone_replace_name(filepath)
401
+ yield BucketListingRef(expanded_uri)
402
+
403
+ def IterKeys(self):
404
+ """
405
+ Placeholder to allow polymorphic use of WildcardIterator.
406
+
407
+ Raises:
408
+ WildcardException: in all cases.
409
+ """
410
+ raise WildcardException(
411
+ 'Iterating over Keys not possible for file wildcards')
412
+
413
+ def IterUris(self):
414
+ """
415
+ Convenience iterator that runs underlying iterator and returns StorageUri
416
+ for each iteration.
417
+
418
+ Yields:
419
+ StorageUri, or empty iterator if no matches.
420
+ """
421
+ for bucket_listing_ref in self. __iter__():
422
+ yield bucket_listing_ref.GetUri()
423
+
424
+
425
+ class WildcardException(StandardError):
426
+ """Exception thrown for invalid wildcard URIs."""
427
+
428
+ def __init__(self, reason):
429
+ StandardError.__init__(self)
430
+ self.reason = reason
431
+
432
+ def __repr__(self):
433
+ return 'WildcardException: %s' % self.reason
434
+
435
+ def __str__(self):
436
+ return 'WildcardException: %s' % self.reason
437
+
438
+
439
+ def wildcard_iterator(uri_or_str, proj_id_handler,
440
+ bucket_storage_uri_class=BucketStorageUri,
441
+ all_versions=False,
442
+ headers=None, debug=0):
443
+ """Instantiate a WildCardIterator for the given StorageUri.
444
+
445
+ Args:
446
+ uri_or_str: StorageUri or URI string naming wildcard objects to iterate.
447
+ proj_id_handler: ProjectIdHandler to use for current command.
448
+ bucket_storage_uri_class: BucketStorageUri interface.
449
+ Settable for testing/mocking.
450
+ headers: Dictionary containing optional HTTP headers to pass to boto.
451
+ debug: Debug level to pass in to boto connection (range 0..3).
452
+
453
+ Returns:
454
+ A WildcardIterator that handles the requested iteration.
455
+ """
456
+
457
+ if isinstance(uri_or_str, basestring):
458
+ # Disable enforce_bucket_naming, to allow bucket names containing wildcard
459
+ # chars.
460
+ uri = boto.storage_uri(
461
+ uri_or_str, debug=debug, validate=False,
462
+ bucket_storage_uri_class=bucket_storage_uri_class,
463
+ suppress_consec_slashes=False)
464
+ else:
465
+ uri = uri_or_str
466
+
467
+ if uri.is_cloud_uri():
468
+ return CloudWildcardIterator(
469
+ uri, proj_id_handler,
470
+ bucket_storage_uri_class=bucket_storage_uri_class,
471
+ all_versions=all_versions,
472
+ headers=headers,
473
+ debug=debug)
474
+ elif uri.is_file_uri():
475
+ return FileWildcardIterator(uri, headers=headers, debug=debug)
476
+ else:
477
+ raise WildcardException('Unexpected type of StorageUri (%s)' % uri)
478
+
479
+
480
+ def ContainsWildcard(uri_or_str):
481
+ """Checks whether uri_or_str contains a wildcard.
482
+
483
+ Args:
484
+ uri_or_str: StorageUri or URI string to check.
485
+
486
+ Returns:
487
+ bool indicator.
488
+ """
489
+ if isinstance(uri_or_str, basestring):
490
+ return bool(WILDCARD_REGEX.search(uri_or_str))
491
+ else:
492
+ return bool(WILDCARD_REGEX.search(uri_or_str.uri))