Skip to content

Commit 8cd4c5e

Browse files
committed
Merge pull request #349 from tseaver/313-key_properties
Fix #313: Add Key properties
2 parents 8536991 + a915447 commit 8cd4c5e

3 files changed

Lines changed: 562 additions & 9 deletions

File tree

‎gcloud/storage/bucket.py‎

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,6 @@ def etag(self):
400400
https://cloud.google.com/storage/docs/json_api/v1/buckets
401401
402402
:rtype: string
403-
:returns: a unique identifier for the bucket and current metadata.
404403
"""
405404
return self.properties['etag']
406405

@@ -411,7 +410,6 @@ def id(self):
411410
See: https://cloud.google.com/storage/docs/json_api/v1/buckets
412411
413412
:rtype: string
414-
:returns: a unique identifier for the bucket.
415413
"""
416414
return self.properties['id']
417415

@@ -501,8 +499,6 @@ def metageneration(self):
501499
See: https://cloud.google.com/storage/docs/json_api/v1/buckets
502500
503501
:rtype: integer
504-
:returns: count of times since creation the bucket's metadata has
505-
been updated.
506502
"""
507503
return self.properties['metageneration']
508504

@@ -524,7 +520,6 @@ def project_number(self):
524520
See: https://cloud.google.com/storage/docs/json_api/v1/buckets
525521
526522
:rtype: integer
527-
:returns: a unique identifier for the bucket.
528523
"""
529524
return self.properties['projectNumber']
530525

@@ -535,7 +530,6 @@ def self_link(self):
535530
See: https://cloud.google.com/storage/docs/json_api/v1/buckets
536531
537532
:rtype: string
538-
:returns: URI of the bucket.
539533
"""
540534
return self.properties['selfLink']
541535

@@ -547,8 +541,7 @@ def storage_class(self):
547541
https://cloud.google.com/storage/docs/durable-reduced-availability
548542
549543
:rtype: string
550-
:returns: the storage class for the bucket (currently one of
551-
``STANDARD``, ``DURABLE_REDUCED_AVAILABILITY``)
544+
:returns: Currently one of "STANDARD", "DURABLE_REDUCED_AVAILABILITY"
552545
"""
553546
return self.properties['storageClass']
554547

@@ -559,7 +552,7 @@ def time_created(self):
559552
See: https://cloud.google.com/storage/docs/json_api/v1/buckets
560553
561554
:rtype: string
562-
:returns: timestamp for the bucket's creation, in RFC 3339 format.
555+
:returns: timestamp in RFC 3339 format.
563556
"""
564557
return self.properties['timeCreated']
565558

‎gcloud/storage/key.py‎

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Create / interact with gcloud storage keys."""
22

3+
import copy
34
import mimetypes
45
import os
56
from StringIO import StringIO
@@ -10,11 +11,43 @@
1011
from gcloud.storage.iterator import Iterator
1112

1213

14+
def _scalar_property(fieldname):
15+
"""Create a property descriptor around the :class:`_PropertyMixin` helpers.
16+
"""
17+
def _getter(self):
18+
"""Scalar property getter."""
19+
return self.properties[fieldname]
20+
21+
def _setter(self, value):
22+
"""Scalar property setter."""
23+
self._patch_properties({fieldname: value})
24+
25+
return property(_getter, _setter)
26+
27+
1328
class Key(_PropertyMixin):
1429
"""A wrapper around Cloud Storage's concept of an ``Object``."""
1530

1631
CUSTOM_PROPERTY_ACCESSORS = {
1732
'acl': 'get_acl()',
33+
'cacheControl': 'cache_control',
34+
'contentDisposition': 'content_disposition',
35+
'contentEncoding': 'content_encoding',
36+
'contentLanguage': 'content_language',
37+
'contentType': 'content_type',
38+
'componentCount': 'component_count',
39+
'etag': 'etag',
40+
'generation': 'generation',
41+
'id': 'id',
42+
'mediaLink': 'media_link',
43+
'metageneration': 'metageneration',
44+
'name': 'name',
45+
'owner': 'owner',
46+
'selfLink': 'self_link',
47+
'size': 'size',
48+
'storageClass': 'storage_class',
49+
'timeDeleted': 'time_deleted',
50+
'updated': 'updated',
1851
}
1952
"""Map field name -> accessor for fields w/ custom accessors."""
2053

@@ -359,6 +392,216 @@ def make_public(self):
359392
self.acl.save()
360393
return self
361394

395+
cache_control = _scalar_property('cacheControl')
396+
"""HTTP 'Cache-Control' header for this object.
397+
398+
See: https://tools.ietf.org/html/rfc7234#section-5.2 and
399+
https://cloud.google.com/storage/docs/json_api/v1/objects
400+
401+
:rtype: string
402+
"""
403+
404+
content_disposition = _scalar_property('contentDisposition')
405+
"""HTTP 'Content-Disposition' header for this object.
406+
407+
See: https://tools.ietf.org/html/rfc6266 and
408+
https://cloud.google.com/storage/docs/json_api/v1/objects
409+
410+
:rtype: string
411+
"""
412+
413+
content_encoding = _scalar_property('contentEncoding')
414+
"""HTTP 'Content-Encoding' header for this object.
415+
416+
See: https://tools.ietf.org/html/rfc7231#section-3.1.2.2 and
417+
https://cloud.google.com/storage/docs/json_api/v1/objects
418+
419+
:rtype: string
420+
"""
421+
422+
content_language = _scalar_property('contentLanguage')
423+
"""HTTP 'Content-Language' header for this object.
424+
425+
See: http://tools.ietf.org/html/bcp47 and
426+
https://cloud.google.com/storage/docs/json_api/v1/objects
427+
428+
:rtype: string
429+
"""
430+
431+
content_type = _scalar_property('contentType')
432+
"""HTTP 'Content-Type' header for this object.
433+
434+
See: https://tools.ietf.org/html/rfc2616#section-14.17 and
435+
https://cloud.google.com/storage/docs/json_api/v1/objects
436+
437+
:rtype: string
438+
"""
439+
440+
crc32c = _scalar_property('crc32c')
441+
"""CRC32C checksum for this object.
442+
443+
See: http://tools.ietf.org/html/rfc4960#appendix-B and
444+
https://cloud.google.com/storage/docs/json_api/v1/objects
445+
446+
:rtype: string
447+
"""
448+
449+
@property
450+
def component_count(self):
451+
"""Number of underlying components that make up this object.
452+
453+
See: https://cloud.google.com/storage/docs/json_api/v1/objects
454+
455+
:rtype: integer
456+
"""
457+
return self.properties['componentCount']
458+
459+
@property
460+
def etag(self):
461+
"""Retrieve the ETag for the object.
462+
463+
See: http://tools.ietf.org/html/rfc2616#section-3.11 and
464+
https://cloud.google.com/storage/docs/json_api/v1/objects
465+
466+
:rtype: string
467+
"""
468+
return self.properties['etag']
469+
470+
@property
471+
def generation(self):
472+
"""Retrieve the generation for the object.
473+
474+
See: https://cloud.google.com/storage/docs/json_api/v1/objects
475+
476+
:rtype: integer
477+
"""
478+
return self.properties['generation']
479+
480+
@property
481+
def id(self):
482+
"""Retrieve the ID for the object.
483+
484+
See: https://cloud.google.com/storage/docs/json_api/v1/objects
485+
486+
:rtype: string
487+
"""
488+
return self.properties['id']
489+
490+
md5_hash = _scalar_property('md5Hash')
491+
"""MD5 hash for this object.
492+
493+
See: http://tools.ietf.org/html/rfc4960#appendix-B and
494+
https://cloud.google.com/storage/docs/json_api/v1/objects
495+
496+
:rtype: string
497+
"""
498+
499+
@property
500+
def media_link(self):
501+
"""Retrieve the media download URI for the object.
502+
503+
See: https://cloud.google.com/storage/docs/json_api/v1/objects
504+
505+
:rtype: string
506+
"""
507+
return self.properties['mediaLink']
508+
509+
@property
510+
def metadata(self):
511+
"""Retrieve arbitrary/application specific metadata for the object.
512+
513+
See: https://cloud.google.com/storage/docs/json_api/v1/objects
514+
515+
:rtype: dict
516+
"""
517+
return copy.deepcopy(self.properties['metadata'])
518+
519+
@metadata.setter
520+
def metadata(self, value):
521+
"""Update arbitrary/application specific metadata for the object.
522+
523+
See: https://cloud.google.com/storage/docs/json_api/v1/objects
524+
525+
:type value: dict
526+
"""
527+
self._patch_properties({'metadata': value})
528+
529+
@property
530+
def metageneration(self):
531+
"""Retrieve the metageneration for the object.
532+
533+
See: https://cloud.google.com/storage/docs/json_api/v1/objects
534+
535+
:rtype: integer
536+
"""
537+
return self.properties['metageneration']
538+
539+
@property
540+
def owner(self):
541+
"""Retrieve info about the owner of the object.
542+
543+
See: https://cloud.google.com/storage/docs/json_api/v1/objects
544+
545+
:rtype: dict
546+
:returns: mapping of owner's role/ID.
547+
"""
548+
return self.properties['owner'].copy()
549+
550+
@property
551+
def self_link(self):
552+
"""Retrieve the URI for the object.
553+
554+
See: https://cloud.google.com/storage/docs/json_api/v1/objects
555+
556+
:rtype: string
557+
"""
558+
return self.properties['selfLink']
559+
560+
@property
561+
def size(self):
562+
"""Size of the object, in bytes.
563+
564+
See: https://cloud.google.com/storage/docs/json_api/v1/objects
565+
566+
:rtype: integer
567+
"""
568+
return self.properties['size']
569+
570+
@property
571+
def storage_class(self):
572+
"""Retrieve the storage class for the object.
573+
574+
See: https://cloud.google.com/storage/docs/json_api/v1/objects and
575+
https://cloud.google.com/storage/docs/durable-reduced-availability#_DRA_Bucket
576+
577+
:rtype: string
578+
:returns: Currently one of "STANDARD", "DURABLE_REDUCED_AVAILABILITY"
579+
"""
580+
return self.properties['storageClass']
581+
582+
@property
583+
def time_deleted(self):
584+
"""Retrieve the timestamp at which the object was deleted.
585+
586+
See: https://cloud.google.com/storage/docs/json_api/v1/objects
587+
588+
:rtype: string or None
589+
:returns: timestamp in RFC 3339 format, or None if the object
590+
has a "live" version.
591+
"""
592+
return self.properties.get('timeDeleted')
593+
594+
@property
595+
def updated(self):
596+
"""Retrieve the timestamp at which the object was updated.
597+
598+
See: https://cloud.google.com/storage/docs/json_api/v1/objects
599+
600+
:rtype: string
601+
:returns: timestamp in RFC 3339 format.
602+
"""
603+
return self.properties['updated']
604+
362605

363606
class _KeyIterator(Iterator):
364607
"""An iterator listing keys.

0 commit comments

Comments
 (0)