googlecloud 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/googlecloud.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,20 @@
1
+ # Copyright (c) 2006,2007,2008 Mitch Garnaat http://garnaat.org/
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.
@@ -0,0 +1,75 @@
1
+ # Copyright (c) 2006,2007,2008 Mitch Garnaat http://garnaat.org/
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
+
23
+ class Blob(object):
24
+ """Blob object"""
25
+ def __init__(self, value=None, file=None, id=None):
26
+ self._file = file
27
+ self.id = id
28
+ self.value = value
29
+
30
+ @property
31
+ def file(self):
32
+ from StringIO import StringIO
33
+ if self._file:
34
+ f = self._file
35
+ else:
36
+ f = StringIO(self.value)
37
+ return f
38
+
39
+ def __str__(self):
40
+ return unicode(self).encode('utf-8')
41
+
42
+ def __unicode__(self):
43
+ if hasattr(self.file, "get_contents_as_string"):
44
+ value = self.file.get_contents_as_string()
45
+ else:
46
+ value = self.file.getvalue()
47
+ if isinstance(value, unicode):
48
+ return value
49
+ else:
50
+ return value.decode('utf-8')
51
+
52
+
53
+ def read(self):
54
+ if hasattr(self.file, "get_contents_as_string"):
55
+ return self.file.get_contents_as_string()
56
+ else:
57
+ return self.file.read()
58
+
59
+ def readline(self):
60
+ return self.file.readline()
61
+
62
+ def next(self):
63
+ return self.file.next()
64
+
65
+ def __iter__(self):
66
+ return iter(self.file)
67
+
68
+ @property
69
+ def size(self):
70
+ if self._file:
71
+ return self._file.size
72
+ elif self.value:
73
+ return len(self.value)
74
+ else:
75
+ return 0
@@ -0,0 +1,59 @@
1
+ # Copyright (c) 2006,2007,2008 Mitch Garnaat http://garnaat.org/
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
+ class Key(object):
23
+
24
+ @classmethod
25
+ def from_path(cls, *args, **kwds):
26
+ raise NotImplementedError("Paths are not currently supported")
27
+
28
+ def __init__(self, encoded=None, obj=None):
29
+ self.name = None
30
+ if obj:
31
+ self.id = obj.id
32
+ self.kind = obj.kind()
33
+ else:
34
+ self.id = None
35
+ self.kind = None
36
+
37
+ def app(self):
38
+ raise NotImplementedError("Applications are not currently supported")
39
+
40
+ def kind(self):
41
+ return self.kind
42
+
43
+ def id(self):
44
+ return self.id
45
+
46
+ def name(self):
47
+ raise NotImplementedError("Key Names are not currently supported")
48
+
49
+ def id_or_name(self):
50
+ return self.id
51
+
52
+ def has_id_or_name(self):
53
+ return self.id != None
54
+
55
+ def parent(self):
56
+ raise NotImplementedError("Key parents are not currently supported")
57
+
58
+ def __str__(self):
59
+ return self.id_or_name()
@@ -0,0 +1,85 @@
1
+ # Copyright (c) 2006,2007,2008 Mitch Garnaat http://garnaat.org/
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
+ import boto
22
+
23
+
24
+ def get_manager(cls):
25
+ """
26
+ Returns the appropriate Manager class for a given Model class. It
27
+ does this by looking in the boto config for a section like this::
28
+
29
+ [DB]
30
+ db_type = SimpleDB
31
+ db_user = <aws access key id>
32
+ db_passwd = <aws secret access key>
33
+ db_name = my_domain
34
+ [DB_TestBasic]
35
+ db_type = SimpleDB
36
+ db_user = <another aws access key id>
37
+ db_passwd = <another aws secret access key>
38
+ db_name = basic_domain
39
+ db_port = 1111
40
+
41
+ The values in the DB section are "generic values" that will be used
42
+ if nothing more specific is found. You can also create a section for
43
+ a specific Model class that gives the db info for that class.
44
+ In the example above, TestBasic is a Model subclass.
45
+ """
46
+ db_user = boto.config.get('DB', 'db_user', None)
47
+ db_passwd = boto.config.get('DB', 'db_passwd', None)
48
+ db_type = boto.config.get('DB', 'db_type', 'SimpleDB')
49
+ db_name = boto.config.get('DB', 'db_name', None)
50
+ db_table = boto.config.get('DB', 'db_table', None)
51
+ db_host = boto.config.get('DB', 'db_host', "sdb.amazonaws.com")
52
+ db_port = boto.config.getint('DB', 'db_port', 443)
53
+ enable_ssl = boto.config.getbool('DB', 'enable_ssl', True)
54
+ sql_dir = boto.config.get('DB', 'sql_dir', None)
55
+ debug = boto.config.getint('DB', 'debug', 0)
56
+ # first see if there is a fully qualified section name in the Boto config
57
+ module_name = cls.__module__.replace('.', '_')
58
+ db_section = 'DB_' + module_name + '_' + cls.__name__
59
+ if not boto.config.has_section(db_section):
60
+ db_section = 'DB_' + cls.__name__
61
+ if boto.config.has_section(db_section):
62
+ db_user = boto.config.get(db_section, 'db_user', db_user)
63
+ db_passwd = boto.config.get(db_section, 'db_passwd', db_passwd)
64
+ db_type = boto.config.get(db_section, 'db_type', db_type)
65
+ db_name = boto.config.get(db_section, 'db_name', db_name)
66
+ db_table = boto.config.get(db_section, 'db_table', db_table)
67
+ db_host = boto.config.get(db_section, 'db_host', db_host)
68
+ db_port = boto.config.getint(db_section, 'db_port', db_port)
69
+ enable_ssl = boto.config.getint(db_section, 'enable_ssl', enable_ssl)
70
+ debug = boto.config.getint(db_section, 'debug', debug)
71
+ elif hasattr(cls, "_db_name") and cls._db_name is not None:
72
+ # More specific then the generic DB config is any _db_name class property
73
+ db_name = cls._db_name
74
+ elif hasattr(cls.__bases__[0], "_manager"):
75
+ return cls.__bases__[0]._manager
76
+ if db_type == 'SimpleDB':
77
+ from sdbmanager import SDBManager
78
+ return SDBManager(cls, db_name, db_user, db_passwd,
79
+ db_host, db_port, db_table, sql_dir, enable_ssl)
80
+ elif db_type == 'XML':
81
+ from xmlmanager import XMLManager
82
+ return XMLManager(cls, db_name, db_user, db_passwd,
83
+ db_host, db_port, db_table, sql_dir, enable_ssl)
84
+ else:
85
+ raise ValueError('Unknown db_type: %s' % db_type)
@@ -0,0 +1,732 @@
1
+ # Copyright (c) 2006,2007,2008 Mitch Garnaat http://garnaat.org/
2
+ # Copyright (c) 2010 Chris Moyer http://coredumped.org/
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a
5
+ # copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish, dis-
8
+ # tribute, sublicense, and/or sell copies of the Software, and to permit
9
+ # persons to whom the Software is furnished to do so, subject to the fol-
10
+ # lowing conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included
13
+ # in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16
+ # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
17
+ # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
18
+ # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
+ # IN THE SOFTWARE.
22
+ import boto
23
+ import re
24
+ from boto.utils import find_class
25
+ import uuid
26
+ from boto.sdb.db.key import Key
27
+ from boto.sdb.db.model import Model
28
+ from boto.sdb.db.blob import Blob
29
+ from boto.sdb.db.property import ListProperty, MapProperty
30
+ from datetime import datetime, date, time
31
+ from boto.exception import SDBPersistenceError, S3ResponseError
32
+
33
+ ISO8601 = '%Y-%m-%dT%H:%M:%SZ'
34
+
35
+
36
+ class TimeDecodeError(Exception):
37
+ pass
38
+
39
+
40
+ class SDBConverter(object):
41
+ """
42
+ Responsible for converting base Python types to format compatible
43
+ with underlying database. For SimpleDB, that means everything
44
+ needs to be converted to a string when stored in SimpleDB and from
45
+ a string when retrieved.
46
+
47
+ To convert a value, pass it to the encode or decode method. The
48
+ encode method will take a Python native value and convert to DB
49
+ format. The decode method will take a DB format value and convert
50
+ it to Python native format. To find the appropriate method to
51
+ call, the generic encode/decode methods will look for the
52
+ type-specific method by searching for a method
53
+ called"encode_<type name>" or "decode_<type name>".
54
+ """
55
+ def __init__(self, manager):
56
+ self.manager = manager
57
+ self.type_map = {bool: (self.encode_bool, self.decode_bool),
58
+ int: (self.encode_int, self.decode_int),
59
+ long: (self.encode_long, self.decode_long),
60
+ float: (self.encode_float, self.decode_float),
61
+ Model: (self.encode_reference, self.decode_reference),
62
+ Key: (self.encode_reference, self.decode_reference),
63
+ datetime: (self.encode_datetime, self.decode_datetime),
64
+ date: (self.encode_date, self.decode_date),
65
+ time: (self.encode_time, self.decode_time),
66
+ Blob: (self.encode_blob, self.decode_blob),
67
+ str: (self.encode_string, self.decode_string),
68
+ }
69
+
70
+ def encode(self, item_type, value):
71
+ try:
72
+ if Model in item_type.mro():
73
+ item_type = Model
74
+ except:
75
+ pass
76
+ if item_type in self.type_map:
77
+ encode = self.type_map[item_type][0]
78
+ return encode(value)
79
+ return value
80
+
81
+ def decode(self, item_type, value):
82
+ if item_type in self.type_map:
83
+ decode = self.type_map[item_type][1]
84
+ return decode(value)
85
+ return value
86
+
87
+ def encode_list(self, prop, value):
88
+ if value in (None, []):
89
+ return []
90
+ if not isinstance(value, list):
91
+ # This is a little trick to avoid encoding when it's just a single value,
92
+ # since that most likely means it's from a query
93
+ item_type = getattr(prop, "item_type")
94
+ return self.encode(item_type, value)
95
+ # Just enumerate(value) won't work here because
96
+ # we need to add in some zero padding
97
+ # We support lists up to 1,000 attributes, since
98
+ # SDB technically only supports 1024 attributes anyway
99
+ values = {}
100
+ for k, v in enumerate(value):
101
+ values["%03d" % k] = v
102
+ return self.encode_map(prop, values)
103
+
104
+ def encode_map(self, prop, value):
105
+ import urllib
106
+ if value == None:
107
+ return None
108
+ if not isinstance(value, dict):
109
+ raise ValueError('Expected a dict value, got %s' % type(value))
110
+ new_value = []
111
+ for key in value:
112
+ item_type = getattr(prop, "item_type")
113
+ if Model in item_type.mro():
114
+ item_type = Model
115
+ encoded_value = self.encode(item_type, value[key])
116
+ if encoded_value != None:
117
+ new_value.append('%s:%s' % (urllib.quote(key), encoded_value))
118
+ return new_value
119
+
120
+ def encode_prop(self, prop, value):
121
+ if isinstance(prop, ListProperty):
122
+ return self.encode_list(prop, value)
123
+ elif isinstance(prop, MapProperty):
124
+ return self.encode_map(prop, value)
125
+ else:
126
+ return self.encode(prop.data_type, value)
127
+
128
+ def decode_list(self, prop, value):
129
+ if not isinstance(value, list):
130
+ value = [value]
131
+ if hasattr(prop, 'item_type'):
132
+ item_type = getattr(prop, "item_type")
133
+ dec_val = {}
134
+ for val in value:
135
+ if val != None:
136
+ k, v = self.decode_map_element(item_type, val)
137
+ try:
138
+ k = int(k)
139
+ except:
140
+ k = v
141
+ dec_val[k] = v
142
+ value = dec_val.values()
143
+ return value
144
+
145
+ def decode_map(self, prop, value):
146
+ if not isinstance(value, list):
147
+ value = [value]
148
+ ret_value = {}
149
+ item_type = getattr(prop, "item_type")
150
+ for val in value:
151
+ k, v = self.decode_map_element(item_type, val)
152
+ ret_value[k] = v
153
+ return ret_value
154
+
155
+ def decode_map_element(self, item_type, value):
156
+ """Decode a single element for a map"""
157
+ import urllib
158
+ key = value
159
+ if ":" in value:
160
+ key, value = value.split(':', 1)
161
+ key = urllib.unquote(key)
162
+ if Model in item_type.mro():
163
+ value = item_type(id=value)
164
+ else:
165
+ value = self.decode(item_type, value)
166
+ return (key, value)
167
+
168
+ def decode_prop(self, prop, value):
169
+ if isinstance(prop, ListProperty):
170
+ return self.decode_list(prop, value)
171
+ elif isinstance(prop, MapProperty):
172
+ return self.decode_map(prop, value)
173
+ else:
174
+ return self.decode(prop.data_type, value)
175
+
176
+ def encode_int(self, value):
177
+ value = int(value)
178
+ value += 2147483648
179
+ return '%010d' % value
180
+
181
+ def decode_int(self, value):
182
+ try:
183
+ value = int(value)
184
+ except:
185
+ boto.log.error("Error, %s is not an integer" % value)
186
+ value = 0
187
+ value = int(value)
188
+ value -= 2147483648
189
+ return int(value)
190
+
191
+ def encode_long(self, value):
192
+ value = long(value)
193
+ value += 9223372036854775808
194
+ return '%020d' % value
195
+
196
+ def decode_long(self, value):
197
+ value = long(value)
198
+ value -= 9223372036854775808
199
+ return value
200
+
201
+ def encode_bool(self, value):
202
+ if value == True or str(value).lower() in ("true", "yes"):
203
+ return 'true'
204
+ else:
205
+ return 'false'
206
+
207
+ def decode_bool(self, value):
208
+ if value.lower() == 'true':
209
+ return True
210
+ else:
211
+ return False
212
+
213
+ def encode_float(self, value):
214
+ """
215
+ See http://tools.ietf.org/html/draft-wood-ldapext-float-00.
216
+ """
217
+ s = '%e' % value
218
+ l = s.split('e')
219
+ mantissa = l[0].ljust(18, '0')
220
+ exponent = l[1]
221
+ if value == 0.0:
222
+ case = '3'
223
+ exponent = '000'
224
+ elif mantissa[0] != '-' and exponent[0] == '+':
225
+ case = '5'
226
+ exponent = exponent[1:].rjust(3, '0')
227
+ elif mantissa[0] != '-' and exponent[0] == '-':
228
+ case = '4'
229
+ exponent = 999 + int(exponent)
230
+ exponent = '%03d' % exponent
231
+ elif mantissa[0] == '-' and exponent[0] == '-':
232
+ case = '2'
233
+ mantissa = '%f' % (10 + float(mantissa))
234
+ mantissa = mantissa.ljust(18, '0')
235
+ exponent = exponent[1:].rjust(3, '0')
236
+ else:
237
+ case = '1'
238
+ mantissa = '%f' % (10 + float(mantissa))
239
+ mantissa = mantissa.ljust(18, '0')
240
+ exponent = 999 - int(exponent)
241
+ exponent = '%03d' % exponent
242
+ return '%s %s %s' % (case, exponent, mantissa)
243
+
244
+ def decode_float(self, value):
245
+ case = value[0]
246
+ exponent = value[2:5]
247
+ mantissa = value[6:]
248
+ if case == '3':
249
+ return 0.0
250
+ elif case == '5':
251
+ pass
252
+ elif case == '4':
253
+ exponent = '%03d' % (int(exponent) - 999)
254
+ elif case == '2':
255
+ mantissa = '%f' % (float(mantissa) - 10)
256
+ exponent = '-' + exponent
257
+ else:
258
+ mantissa = '%f' % (float(mantissa) - 10)
259
+ exponent = '%03d' % abs((int(exponent) - 999))
260
+ return float(mantissa + 'e' + exponent)
261
+
262
+ def encode_datetime(self, value):
263
+ if isinstance(value, str) or isinstance(value, unicode):
264
+ return value
265
+ if isinstance(value, datetime):
266
+ return value.strftime(ISO8601)
267
+ else:
268
+ return value.isoformat()
269
+
270
+ def decode_datetime(self, value):
271
+ """Handles both Dates and DateTime objects"""
272
+ if value is None:
273
+ return value
274
+ try:
275
+ if "T" in value:
276
+ if "." in value:
277
+ # Handle true "isoformat()" dates, which may have a microsecond on at the end of them
278
+ return datetime.strptime(value.split(".")[0], "%Y-%m-%dT%H:%M:%S")
279
+ else:
280
+ return datetime.strptime(value, ISO8601)
281
+ else:
282
+ value = value.split("-")
283
+ return date(int(value[0]), int(value[1]), int(value[2]))
284
+ except Exception, e:
285
+ return None
286
+
287
+ def encode_date(self, value):
288
+ if isinstance(value, str) or isinstance(value, unicode):
289
+ return value
290
+ return value.isoformat()
291
+
292
+ def decode_date(self, value):
293
+ try:
294
+ value = value.split("-")
295
+ return date(int(value[0]), int(value[1]), int(value[2]))
296
+ except:
297
+ return None
298
+
299
+ encode_time = encode_date
300
+
301
+ def decode_time(self, value):
302
+ """ converts strings in the form of HH:MM:SS.mmmmmm
303
+ (created by datetime.time.isoformat()) to
304
+ datetime.time objects.
305
+
306
+ Timzone-aware strings ("HH:MM:SS.mmmmmm+HH:MM") won't
307
+ be handled right now and will raise TimeDecodeError.
308
+ """
309
+ if '-' in value or '+' in value:
310
+ # TODO: Handle tzinfo
311
+ raise TimeDecodeError("Can't handle timezone aware objects: %r" % value)
312
+ tmp = value.split('.')
313
+ arg = map(int, tmp[0].split(':'))
314
+ if len(tmp) == 2:
315
+ arg.append(int(tmp[1]))
316
+ return time(*arg)
317
+
318
+ def encode_reference(self, value):
319
+ if value in (None, 'None', '', ' '):
320
+ return None
321
+ if isinstance(value, str) or isinstance(value, unicode):
322
+ return value
323
+ else:
324
+ return value.id
325
+
326
+ def decode_reference(self, value):
327
+ if not value or value == "None":
328
+ return None
329
+ return value
330
+
331
+ def encode_blob(self, value):
332
+ if not value:
333
+ return None
334
+ if isinstance(value, str):
335
+ return value
336
+
337
+ if not value.id:
338
+ bucket = self.manager.get_blob_bucket()
339
+ key = bucket.new_key(str(uuid.uuid4()))
340
+ value.id = "s3://%s/%s" % (key.bucket.name, key.name)
341
+ else:
342
+ match = re.match("^s3:\/\/([^\/]*)\/(.*)$", value.id)
343
+ if match:
344
+ s3 = self.manager.get_s3_connection()
345
+ bucket = s3.get_bucket(match.group(1), validate=False)
346
+ key = bucket.get_key(match.group(2))
347
+ else:
348
+ raise SDBPersistenceError("Invalid Blob ID: %s" % value.id)
349
+
350
+ if value.value != None:
351
+ key.set_contents_from_string(value.value)
352
+ return value.id
353
+
354
+ def decode_blob(self, value):
355
+ if not value:
356
+ return None
357
+ match = re.match("^s3:\/\/([^\/]*)\/(.*)$", value)
358
+ if match:
359
+ s3 = self.manager.get_s3_connection()
360
+ bucket = s3.get_bucket(match.group(1), validate=False)
361
+ try:
362
+ key = bucket.get_key(match.group(2))
363
+ except S3ResponseError, e:
364
+ if e.reason != "Forbidden":
365
+ raise
366
+ return None
367
+ else:
368
+ return None
369
+ if key:
370
+ return Blob(file=key, id="s3://%s/%s" % (key.bucket.name, key.name))
371
+ else:
372
+ return None
373
+
374
+ def encode_string(self, value):
375
+ """Convert ASCII, Latin-1 or UTF-8 to pure Unicode"""
376
+ if not isinstance(value, str):
377
+ return value
378
+ try:
379
+ return unicode(value, 'utf-8')
380
+ except:
381
+ # really, this should throw an exception.
382
+ # in the interest of not breaking current
383
+ # systems, however:
384
+ arr = []
385
+ for ch in value:
386
+ arr.append(unichr(ord(ch)))
387
+ return u"".join(arr)
388
+
389
+ def decode_string(self, value):
390
+ """Decoding a string is really nothing, just
391
+ return the value as-is"""
392
+ return value
393
+
394
+
395
+ class SDBManager(object):
396
+
397
+ def __init__(self, cls, db_name, db_user, db_passwd,
398
+ db_host, db_port, db_table, ddl_dir, enable_ssl,
399
+ consistent=None):
400
+ self.cls = cls
401
+ self.db_name = db_name
402
+ self.db_user = db_user
403
+ self.db_passwd = db_passwd
404
+ self.db_host = db_host
405
+ self.db_port = db_port
406
+ self.db_table = db_table
407
+ self.ddl_dir = ddl_dir
408
+ self.enable_ssl = enable_ssl
409
+ self.s3 = None
410
+ self.bucket = None
411
+ self.converter = SDBConverter(self)
412
+ self._sdb = None
413
+ self._domain = None
414
+ if consistent == None and hasattr(cls, "__consistent__"):
415
+ consistent = cls.__consistent__
416
+ self.consistent = consistent
417
+
418
+ @property
419
+ def sdb(self):
420
+ if self._sdb is None:
421
+ self._connect()
422
+ return self._sdb
423
+
424
+ @property
425
+ def domain(self):
426
+ if self._domain is None:
427
+ self._connect()
428
+ return self._domain
429
+
430
+ def _connect(self):
431
+ args = dict(aws_access_key_id=self.db_user,
432
+ aws_secret_access_key=self.db_passwd,
433
+ is_secure=self.enable_ssl)
434
+ try:
435
+ region = [x for x in boto.sdb.regions() if x.endpoint == self.db_host][0]
436
+ args['region'] = region
437
+ except IndexError:
438
+ pass
439
+ self._sdb = boto.connect_sdb(**args)
440
+ # This assumes that the domain has already been created
441
+ # It's much more efficient to do it this way rather than
442
+ # having this make a roundtrip each time to validate.
443
+ # The downside is that if the domain doesn't exist, it breaks
444
+ self._domain = self._sdb.lookup(self.db_name, validate=False)
445
+ if not self._domain:
446
+ self._domain = self._sdb.create_domain(self.db_name)
447
+
448
+ def _object_lister(self, cls, query_lister):
449
+ for item in query_lister:
450
+ obj = self.get_object(cls, item.name, item)
451
+ if obj:
452
+ yield obj
453
+
454
+ def encode_value(self, prop, value):
455
+ if value == None:
456
+ return None
457
+ if not prop:
458
+ return str(value)
459
+ return self.converter.encode_prop(prop, value)
460
+
461
+ def decode_value(self, prop, value):
462
+ return self.converter.decode_prop(prop, value)
463
+
464
+ def get_s3_connection(self):
465
+ if not self.s3:
466
+ self.s3 = boto.connect_s3(self.db_user, self.db_passwd)
467
+ return self.s3
468
+
469
+ def get_blob_bucket(self, bucket_name=None):
470
+ s3 = self.get_s3_connection()
471
+ bucket_name = "%s-%s" % (s3.aws_access_key_id, self.domain.name)
472
+ bucket_name = bucket_name.lower()
473
+ try:
474
+ self.bucket = s3.get_bucket(bucket_name)
475
+ except:
476
+ self.bucket = s3.create_bucket(bucket_name)
477
+ return self.bucket
478
+
479
+ def load_object(self, obj):
480
+ if not obj._loaded:
481
+ a = self.domain.get_attributes(obj.id, consistent_read=self.consistent)
482
+ if '__type__' in a:
483
+ for prop in obj.properties(hidden=False):
484
+ if prop.name in a:
485
+ value = self.decode_value(prop, a[prop.name])
486
+ value = prop.make_value_from_datastore(value)
487
+ try:
488
+ setattr(obj, prop.name, value)
489
+ except Exception, e:
490
+ boto.log.exception(e)
491
+ obj._loaded = True
492
+
493
+ def get_object(self, cls, id, a=None):
494
+ obj = None
495
+ if not a:
496
+ a = self.domain.get_attributes(id, consistent_read=self.consistent)
497
+ if '__type__' in a:
498
+ if not cls or a['__type__'] != cls.__name__:
499
+ cls = find_class(a['__module__'], a['__type__'])
500
+ if cls:
501
+ params = {}
502
+ for prop in cls.properties(hidden=False):
503
+ if prop.name in a:
504
+ value = self.decode_value(prop, a[prop.name])
505
+ value = prop.make_value_from_datastore(value)
506
+ params[prop.name] = value
507
+ obj = cls(id, **params)
508
+ obj._loaded = True
509
+ else:
510
+ s = '(%s) class %s.%s not found' % (id, a['__module__'], a['__type__'])
511
+ boto.log.info('sdbmanager: %s' % s)
512
+ return obj
513
+
514
+ def get_object_from_id(self, id):
515
+ return self.get_object(None, id)
516
+
517
+ def query(self, query):
518
+ query_str = "select * from `%s` %s" % (self.domain.name, self._build_filter_part(query.model_class, query.filters, query.sort_by, query.select))
519
+ if query.limit:
520
+ query_str += " limit %s" % query.limit
521
+ rs = self.domain.select(query_str, max_items=query.limit, next_token = query.next_token)
522
+ query.rs = rs
523
+ return self._object_lister(query.model_class, rs)
524
+
525
+ def count(self, cls, filters, quick=True, sort_by=None, select=None):
526
+ """
527
+ Get the number of results that would
528
+ be returned in this query
529
+ """
530
+ query = "select count(*) from `%s` %s" % (self.domain.name, self._build_filter_part(cls, filters, sort_by, select))
531
+ count = 0
532
+ for row in self.domain.select(query):
533
+ count += int(row['Count'])
534
+ if quick:
535
+ return count
536
+ return count
537
+
538
+ def _build_filter(self, property, name, op, val):
539
+ if name == "__id__":
540
+ name = 'itemName()'
541
+ if name != "itemName()":
542
+ name = '`%s`' % name
543
+ if val == None:
544
+ if op in ('is', '='):
545
+ return "%(name)s is null" % {"name": name}
546
+ elif op in ('is not', '!='):
547
+ return "%s is not null" % name
548
+ else:
549
+ val = ""
550
+ if property.__class__ == ListProperty:
551
+ if op in ("is", "="):
552
+ op = "like"
553
+ elif op in ("!=", "not"):
554
+ op = "not like"
555
+ if not(op in ["like", "not like"] and val.startswith("%")):
556
+ val = "%%:%s" % val
557
+ return "%s %s '%s'" % (name, op, val.replace("'", "''"))
558
+
559
+ def _build_filter_part(self, cls, filters, order_by=None, select=None):
560
+ """
561
+ Build the filter part
562
+ """
563
+ import types
564
+ query_parts = []
565
+
566
+ order_by_filtered = False
567
+
568
+ if order_by:
569
+ if order_by[0] == "-":
570
+ order_by_method = "DESC"
571
+ order_by = order_by[1:]
572
+ else:
573
+ order_by_method = "ASC"
574
+
575
+ if select:
576
+ if order_by and order_by in select:
577
+ order_by_filtered = True
578
+ query_parts.append("(%s)" % select)
579
+
580
+ if isinstance(filters, str) or isinstance(filters, unicode):
581
+ query = "WHERE %s AND `__type__` = '%s'" % (filters, cls.__name__)
582
+ if order_by in ["__id__", "itemName()"]:
583
+ query += " ORDER BY itemName() %s" % order_by_method
584
+ elif order_by != None:
585
+ query += " ORDER BY `%s` %s" % (order_by, order_by_method)
586
+ return query
587
+
588
+ for filter in filters:
589
+ filter_parts = []
590
+ filter_props = filter[0]
591
+ if not isinstance(filter_props, list):
592
+ filter_props = [filter_props]
593
+ for filter_prop in filter_props:
594
+ (name, op) = filter_prop.strip().split(" ", 1)
595
+ value = filter[1]
596
+ property = cls.find_property(name)
597
+ if name == order_by:
598
+ order_by_filtered = True
599
+ if types.TypeType(value) == types.ListType:
600
+ filter_parts_sub = []
601
+ for val in value:
602
+ val = self.encode_value(property, val)
603
+ if isinstance(val, list):
604
+ for v in val:
605
+ filter_parts_sub.append(self._build_filter(property, name, op, v))
606
+ else:
607
+ filter_parts_sub.append(self._build_filter(property, name, op, val))
608
+ filter_parts.append("(%s)" % (" OR ".join(filter_parts_sub)))
609
+ else:
610
+ val = self.encode_value(property, value)
611
+ if isinstance(val, list):
612
+ for v in val:
613
+ filter_parts.append(self._build_filter(property, name, op, v))
614
+ else:
615
+ filter_parts.append(self._build_filter(property, name, op, val))
616
+ query_parts.append("(%s)" % (" or ".join(filter_parts)))
617
+
618
+
619
+ type_query = "(`__type__` = '%s'" % cls.__name__
620
+ for subclass in self._get_all_decendents(cls).keys():
621
+ type_query += " or `__type__` = '%s'" % subclass
622
+ type_query += ")"
623
+ query_parts.append(type_query)
624
+
625
+ order_by_query = ""
626
+
627
+ if order_by:
628
+ if not order_by_filtered:
629
+ query_parts.append("`%s` LIKE '%%'" % order_by)
630
+ if order_by in ["__id__", "itemName()"]:
631
+ order_by_query = " ORDER BY itemName() %s" % order_by_method
632
+ else:
633
+ order_by_query = " ORDER BY `%s` %s" % (order_by, order_by_method)
634
+
635
+ if len(query_parts) > 0:
636
+ return "WHERE %s %s" % (" AND ".join(query_parts), order_by_query)
637
+ else:
638
+ return ""
639
+
640
+
641
+ def _get_all_decendents(self, cls):
642
+ """Get all decendents for a given class"""
643
+ decendents = {}
644
+ for sc in cls.__sub_classes__:
645
+ decendents[sc.__name__] = sc
646
+ decendents.update(self._get_all_decendents(sc))
647
+ return decendents
648
+
649
+ def query_gql(self, query_string, *args, **kwds):
650
+ raise NotImplementedError("GQL queries not supported in SimpleDB")
651
+
652
+ def save_object(self, obj, expected_value=None):
653
+ if not obj.id:
654
+ obj.id = str(uuid.uuid4())
655
+
656
+ attrs = {'__type__': obj.__class__.__name__,
657
+ '__module__': obj.__class__.__module__,
658
+ '__lineage__': obj.get_lineage()}
659
+ del_attrs = []
660
+ for property in obj.properties(hidden=False):
661
+ value = property.get_value_for_datastore(obj)
662
+ if value is not None:
663
+ value = self.encode_value(property, value)
664
+ if value == []:
665
+ value = None
666
+ if value == None:
667
+ del_attrs.append(property.name)
668
+ continue
669
+ attrs[property.name] = value
670
+ if property.unique:
671
+ try:
672
+ args = {property.name: value}
673
+ obj2 = obj.find(**args).next()
674
+ if obj2.id != obj.id:
675
+ raise SDBPersistenceError("Error: %s must be unique!" % property.name)
676
+ except(StopIteration):
677
+ pass
678
+ # Convert the Expected value to SDB format
679
+ if expected_value:
680
+ prop = obj.find_property(expected_value[0])
681
+ v = expected_value[1]
682
+ if v is not None and not isinstance(v, bool):
683
+ v = self.encode_value(prop, v)
684
+ expected_value[1] = v
685
+ self.domain.put_attributes(obj.id, attrs, replace=True, expected_value=expected_value)
686
+ if len(del_attrs) > 0:
687
+ self.domain.delete_attributes(obj.id, del_attrs)
688
+ return obj
689
+
690
+ def delete_object(self, obj):
691
+ self.domain.delete_attributes(obj.id)
692
+
693
+ def set_property(self, prop, obj, name, value):
694
+ setattr(obj, name, value)
695
+ value = prop.get_value_for_datastore(obj)
696
+ value = self.encode_value(prop, value)
697
+ if prop.unique:
698
+ try:
699
+ args = {prop.name: value}
700
+ obj2 = obj.find(**args).next()
701
+ if obj2.id != obj.id:
702
+ raise SDBPersistenceError("Error: %s must be unique!" % prop.name)
703
+ except(StopIteration):
704
+ pass
705
+ self.domain.put_attributes(obj.id, {name: value}, replace=True)
706
+
707
+ def get_property(self, prop, obj, name):
708
+ a = self.domain.get_attributes(obj.id, consistent_read=self.consistent)
709
+
710
+ # try to get the attribute value from SDB
711
+ if name in a:
712
+ value = self.decode_value(prop, a[name])
713
+ value = prop.make_value_from_datastore(value)
714
+ setattr(obj, prop.name, value)
715
+ return value
716
+ raise AttributeError('%s not found' % name)
717
+
718
+ def set_key_value(self, obj, name, value):
719
+ self.domain.put_attributes(obj.id, {name: value}, replace=True)
720
+
721
+ def delete_key_value(self, obj, name):
722
+ self.domain.delete_attributes(obj.id, name)
723
+
724
+ def get_key_value(self, obj, name):
725
+ a = self.domain.get_attributes(obj.id, name, consistent_read=self.consistent)
726
+ if name in a:
727
+ return a[name]
728
+ else:
729
+ return None
730
+
731
+ def get_raw_item(self, obj):
732
+ return self.domain.get_item(obj.id)