# Copyright 2012 Google Inc. All Rights Reserved.


"""A sample app that uses GCS client to operate on bucket and file."""

import os
import cloudstorage as gcs
import webapp2

"""
Retry can help overcome transient urlfetch or GCS issues, such as timeouts.
"""
my_default_retry_params = gcs.RetryParams(initial_delay=0.2,
                                          max_delay=5.0,
                                          backoff_factor=2,
                                          max_retry_period=15)
"""
All requests to GCS using the GCS client within current GAE request and
current thread will use this retry params as default. A specific GCS
client call can override the default.
"""
gcs.set_default_retry_params(my_default_retry_params)


class MainPage(webapp2.RequestHandler):

  def get(self):
    bucket = '/yey-cloud-storage-trial'
    filename = bucket + '/demo-testfile'

    self.response.headers['Content-Type'] = 'text/plain'

    self.create_file(filename)
    self.response.write('\n\n')

    self.read_file(filename)
    self.response.write('\n\n')

    self.stat_file(filename)
    self.response.write('\n\n')

    self.list_bucket(bucket)
    self.response.write('\n\n')

    self.delete_file(filename)

  def create_file(self, filename):
    """Create a file.

    The retry_params specified in the open call will override the default
    retry params for this particular file handle.

    Args:
      filename: filename.
    """
    self.response.write('Creating file...\n')

    write_retry_params = gcs.RetryParams(backoff_factor=1.1)
    gcs_file = gcs.open(filename,
                        'w',
                        content_type='text/plain',
                        options={'x-goog-meta-foo': 'foo',
                                 'x-goog-meta-bar': 'bar'},
                        retry_params=write_retry_params)
    gcs_file.write('abcde\n')
    gcs_file.write('f'*1024*1024 + '\n')
    gcs_file.close()

  def read_file(self, filename):
    self.response.write('Truncated file content:\n')

    gcs_file = gcs.open(filename)
    self.response.write(gcs_file.readline())
    gcs_file.seek(-1024, os.SEEK_END)
    self.response.write(gcs_file.read())
    gcs_file.close()

  def stat_file(self, filename):
    self.response.write('File stat:\n')

    stat = gcs.stat(filename)
    self.response.write(repr(stat))

  def list_bucket(self, bucket):
    self.response.write('Listbucket result:\n')

    stats = gcs.listbucket(bucket)
    for stat in stats:
      self.response.write(repr(stat))
      self.response.write('\n')

  def delete_file(self, filename):
    self.response.write('Deleting file...\n')
    gcs.delete(filename)

    try:
      gcs.delete(filename)
    except gcs.NotFoundError:
      pass


app = webapp2.WSGIApplication([('/', MainPage)],
                              debug=True)

@@ -629,38 +629,172 @@
 lt. 
-A specific
+If a default is not%0Aset via this mechanism, the library's built-in default will be used.%0AAny
  GCS
-%0A
+ 
 client 
-call can
+function can also be given a more specific retry params%0Athat
  ove
@@ -790,32 +790,33 @@
 ms%0Athat override
+s
  the default.%0A%22%22
@@ -1069,16 +1069,56 @@
 t/plain'
+%0A    self.tmp_filenames_to_clean_up = %5B%5D
 %0A%0A    se
@@ -1381,25 +1381,18 @@
 ete_file
+s
 (
-filename
 )%0A%0A  def
@@ -1651,22 +1651,33 @@
 ing file
-...%5Cn'
+ %25s%5Cn' %25 filename
 )%0A%0A    w
@@ -2105,32 +2105,84 @@
 gcs_file.close()
+%0A    self.tmp_filenames_to_clean_up.append(filename)
 %0A%0A  def read_fil
@@ -2612,37 +2612,344 @@
 t):%0A    
-self.response.write('
+%22%22%22Create several files and paginate through them.%0A%0A    Production apps should set page_size to a practical value.%0A%0A    Args:%0A      bucket: bucket.%0A    %22%22%22%0A    self.response.write('Creating more files for listbucket...%5Cn')%0A    self.create_file(bucket + '/foo1')%0A    self.create_file(bucket + '/foo2')%0A    self.response.write('%5Cn
 Listbuck
@@ -2956,32 +2956,50 @@
 et result:%5Cn')%0A%0A
+    page_size = 1%0A
     stats = gcs.
@@ -3011,26 +3011,80 @@
 ucket(bucket
-)%0A
+, max_keys=page_size)%0A    while True:%0A      count = 0%0A  
     for stat
@@ -3094,16 +3094,37 @@
  stats:%0A
+        count += 1%0A  
       se
@@ -3155,24 +3155,26 @@
 tat))%0A      
+  
 self.respons
@@ -3194,38 +3194,218 @@
 %0A%0A  
-def delete_file(self, filename
+    if count != page_size or count == 0:%0A        break%0A      last_filename = stat.filename%5Blen(bucket)+1:%5D%0A      stats = gcs.listbucket(bucket, max_keys=page_size, marker=last_filename)%0A%0A  def delete_files(self
 ):%0A 
@@ -3441,16 +3441,17 @@
 ing file
+s
 ...%5Cn')%0A
@@ -3458,30 +3458,58 @@
     
-gcs.delete(filename)%0A%0A
+for filename in self.tmp_filenames_to_clean_up:%0A  
     
@@ -3519,16 +3519,18 @@
 :%0A      
+ 
+ 
 gcs.dele
@@ -3538,24 +3538,26 @@
 e(filename)%0A
+  
     except g
@@ -3574,16 +3574,18 @@
 dError:%0A
+  
       pa

Update listbucket example with pagination