<s> """<STR_LIT>""" <EOL> import re <EOL> from collections import defaultdict <EOL> from itertools import chain <EOL> from xml . etree import ElementTree <EOL> from xml . etree . ElementTree import Element , SubElement <EOL> from . import urlencode <EOL> from . ns import _ns , _ns1 , ATOM_NS , BATCH_NS , SPREADSHEET_NS <EOL> from . urls import construct_url <EOL> from . utils import finditem , numericise_all <EOL> from . exceptions import IncorrectCellLabel , WorksheetNotFound , CellNotFound <EOL> try : <EOL> unicode <EOL> except NameError : <EOL> basestring = unicode = str <EOL> _elementtree_escape_attrib = ElementTree . _escape_attrib <EOL> def _escape_attrib ( text , encoding = None , replace = None ) : <EOL> try : <EOL> text = _elementtree_escape_attrib ( text ) <EOL> except TypeError as e : <EOL> if str ( e ) == '<STR_LIT>' : <EOL> text = _elementtree_escape_attrib ( text , encoding ) <EOL> entities = { '<STR_LIT:\n>' : '<STR_LIT>' , '<STR_LIT:\r>' : '<STR_LIT>' , '<STR_LIT:\t>' : '<STR_LIT>' } <EOL> for key , value in entities . items ( ) : <EOL> text = text . replace ( key , value ) <EOL> return text <EOL> ElementTree . _escape_attrib = _escape_attrib <EOL> class Spreadsheet ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , client , feed_entry ) : <EOL> self . client = client <EOL> self . _sheet_list = [ ] <EOL> self . _feed_entry = feed_entry <EOL> @ property <EOL> def id ( self ) : <EOL> return self . _feed_entry . find ( _ns ( '<STR_LIT:id>' ) ) . text . split ( '<STR_LIT:/>' ) [ - <NUM_LIT:1> ] <EOL> def get_id_fields ( self ) : <EOL> return { '<STR_LIT>' : self . id } <EOL> def _fetch_sheets ( self ) : <EOL> feed = self . client . get_worksheets_feed ( self ) <EOL> for elem in feed . findall ( _ns ( '<STR_LIT>' ) ) : <EOL> self . _sheet_list . append ( Worksheet ( self , elem ) ) <EOL> def add_worksheet ( self , title , rows , cols ) : <EOL> """<STR_LIT>""" <EOL> feed = Element ( '<STR_LIT>' , { '<STR_LIT>' : ATOM_NS , <EOL> '<STR_LIT>' : SPREADSHEET_NS } ) <EOL> SubElement ( feed , '<STR_LIT:title>' ) . text = title <EOL> SubElement ( feed , '<STR_LIT>' ) . text = str ( rows ) <EOL> SubElement ( feed , '<STR_LIT>' ) . text = str ( cols ) <EOL> url = construct_url ( '<STR_LIT>' , self ) <EOL> elem = self . client . post_feed ( url , ElementTree . tostring ( feed ) ) <EOL> worksheet = Worksheet ( self , elem ) <EOL> self . _sheet_list . append ( worksheet ) <EOL> return worksheet <EOL> def del_worksheet ( self , worksheet ) : <EOL> """<STR_LIT>""" <EOL> self . client . del_worksheet ( worksheet ) <EOL> self . _sheet_list . remove ( worksheet ) <EOL> def worksheets ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . _sheet_list : <EOL> self . _fetch_sheets ( ) <EOL> return self . _sheet_list [ : ] <EOL> def worksheet ( self , title ) : <EOL> """<STR_LIT>""" <EOL> if not self . _sheet_list : <EOL> self . _fetch_sheets ( ) <EOL> try : <EOL> return finditem ( lambda x : x . title == title , self . _sheet_list ) <EOL> except StopIteration : <EOL> raise WorksheetNotFound ( title ) <EOL> def get_worksheet ( self , index ) : <EOL> """<STR_LIT>""" <EOL> if not self . _sheet_list : <EOL> self . _fetch_sheets ( ) <EOL> try : <EOL> return self . _sheet_list [ index ] <EOL> except IndexError : <EOL> return None <EOL> @ property <EOL> def sheet1 ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . get_worksheet ( <NUM_LIT:0> ) <EOL> @ property <EOL> def title ( self ) : <EOL> return self . _feed_entry . find ( _ns ( '<STR_LIT:title>' ) ) . text <EOL> def __iter__ ( self ) : <EOL> for sheet in self . worksheets ( ) : <EOL> yield ( sheet ) <EOL> class Worksheet ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , spreadsheet , element ) : <EOL> self . spreadsheet = spreadsheet <EOL> self . client = spreadsheet . client <EOL> self . _id = element . find ( _ns ( '<STR_LIT:id>' ) ) . text . split ( '<STR_LIT:/>' ) [ - <NUM_LIT:1> ] <EOL> self . _title = element . find ( _ns ( '<STR_LIT:title>' ) ) . text <EOL> self . _element = element <EOL> try : <EOL> self . version = self . _get_link ( <EOL> '<STR_LIT>' , element ) . get ( '<STR_LIT>' ) . split ( '<STR_LIT:/>' ) [ - <NUM_LIT:1> ] <EOL> except : <EOL> self . version = None <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % ( self . __class__ . __name__ , <EOL> repr ( self . title ) , <EOL> self . id ) <EOL> @ property <EOL> def id ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _id <EOL> @ property <EOL> def title ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _title <EOL> @ property <EOL> def row_count ( self ) : <EOL> """<STR_LIT>""" <EOL> return int ( self . _element . find ( _ns1 ( '<STR_LIT>' ) ) . text ) <EOL> @ property <EOL> def col_count ( self ) : <EOL> """<STR_LIT>""" <EOL> return int ( self . _element . find ( _ns1 ( '<STR_LIT>' ) ) . text ) <EOL> @ property <EOL> def updated ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _element . find ( _ns ( '<STR_LIT>' ) ) . text <EOL> def get_id_fields ( self ) : <EOL> return { '<STR_LIT>' : self . spreadsheet . id , <EOL> '<STR_LIT>' : self . id } <EOL> def _cell_addr ( self , row , col ) : <EOL> return '<STR_LIT>' % ( row , col ) <EOL> def _get_link ( self , link_type , feed ) : <EOL> return finditem ( lambda x : x . get ( '<STR_LIT>' ) == link_type , <EOL> feed . findall ( _ns ( '<STR_LIT>' ) ) ) <EOL> def _fetch_cells ( self ) : <EOL> feed = self . client . get_cells_feed ( self ) <EOL> return [ Cell ( self , elem ) for elem in feed . findall ( _ns ( '<STR_LIT>' ) ) ] <EOL> _MAGIC_NUMBER = <NUM_LIT:64> <EOL> _cell_addr_re = re . compile ( r'<STR_LIT>' ) <EOL> def get_int_addr ( self , label ) : <EOL> """<STR_LIT>""" <EOL> m = self . _cell_addr_re . match ( label ) <EOL> if m : <EOL> column_label = m . group ( <NUM_LIT:1> ) . upper ( ) <EOL> row = int ( m . group ( <NUM_LIT:2> ) ) <EOL> col = <NUM_LIT:0> <EOL> for i , c in enumerate ( reversed ( column_label ) ) : <EOL> col += ( ord ( c ) - self . _MAGIC_NUMBER ) * ( <NUM_LIT> ** i ) <EOL> else : <EOL> raise IncorrectCellLabel ( label ) <EOL> return ( row , col ) <EOL> def get_addr_int ( self , row , col ) : <EOL> """<STR_LIT>""" <EOL> row = int ( row ) <EOL> col = int ( col ) <EOL> if row < <NUM_LIT:1> or col < <NUM_LIT:1> : <EOL> raise IncorrectCellLabel ( '<STR_LIT>' % ( row , col ) ) <EOL> div = col <EOL> column_label = '<STR_LIT>' <EOL> while div : <EOL> ( div , mod ) = divmod ( div , <NUM_LIT> ) <EOL> if mod == <NUM_LIT:0> : <EOL> mod = <NUM_LIT> <EOL> div -= <NUM_LIT:1> <EOL> column_label = chr ( mod + self . _MAGIC_NUMBER ) + column_label <EOL> label = '<STR_LIT>' % ( column_label , row ) <EOL> return label <EOL> def acell ( self , label ) : <EOL> """<STR_LIT>""" <EOL> return self . cell ( * ( self . get_int_addr ( label ) ) ) <EOL> def cell ( self , row , col ) : <EOL> """<STR_LIT>""" <EOL> feed = self . client . get_cells_cell_id_feed ( self , <EOL> self . _cell_addr ( row , col ) ) <EOL> return Cell ( self , feed ) <EOL> def range ( self , alphanum ) : <EOL> """<STR_LIT>""" <EOL> feed = self . client . get_cells_feed ( self , params = { '<STR_LIT>' : alphanum , <EOL> '<STR_LIT>' : '<STR_LIT:true>' } ) <EOL> return [ Cell ( self , elem ) for elem in feed . findall ( _ns ( '<STR_LIT>' ) ) ] <EOL> def get_all_values ( self ) : <EOL> """<STR_LIT>""" <EOL> cells = self . _fetch_cells ( ) <EOL> rows = defaultdict ( lambda : defaultdict ( str ) ) <EOL> for cell in cells : <EOL> row = rows . setdefault ( int ( cell . row ) , defaultdict ( str ) ) <EOL> row [ cell . col ] = cell . value <EOL> if not rows : <EOL> return [ ] <EOL> all_row_keys = chain . from_iterable ( row . keys ( ) for row in rows . values ( ) ) <EOL> rect_cols = range ( <NUM_LIT:1> , max ( all_row_keys ) + <NUM_LIT:1> ) <EOL> rect_rows = range ( <NUM_LIT:1> , max ( rows . keys ( ) ) + <NUM_LIT:1> ) <EOL> return [ [ rows [ i ] [ j ] for j in rect_cols ] for i in rect_rows ] <EOL> def get_all_records ( self , empty2zero = False , head = <NUM_LIT:1> ) : <EOL> """<STR_LIT>""" <EOL> idx = head - <NUM_LIT:1> <EOL> data = self . get_all_values ( ) <EOL> keys = data [ idx ] <EOL> values = [ numericise_all ( row , empty2zero ) for row in data [ idx + <NUM_LIT:1> : ] ] <EOL> return [ dict ( zip ( keys , row ) ) for row in values ] <EOL> def row_values ( self , row ) : <EOL> """<STR_LIT>""" <EOL> start_cell = self . get_addr_int ( row , <NUM_LIT:1> ) <EOL> end_cell = self . get_addr_int ( row , self . col_count ) <EOL> row_cells = self . range ( '<STR_LIT>' % ( start_cell , end_cell ) ) <EOL> return [ cell . value for cell in row_cells ] <EOL> def col_values ( self , col ) : <EOL> """<STR_LIT>""" <EOL> start_cell = self . get_addr_int ( <NUM_LIT:1> , col ) <EOL> end_cell = self . get_addr_int ( self . row_count , col ) <EOL> row_cells = self . range ( '<STR_LIT>' % ( start_cell , end_cell ) ) <EOL> return [ cell . value for cell in row_cells ] <EOL> def update_acell ( self , label , val ) : <EOL> """<STR_LIT>""" <EOL> return self . update_cell ( * ( self . get_int_addr ( label ) ) , val = val ) <EOL> def update_cell ( self , row , col , val ) : <EOL> """<STR_LIT>""" <EOL> feed = self . client . get_cells_cell_id_feed ( self , <EOL> self . _cell_addr ( row , col ) ) <EOL> cell_elem = feed . find ( _ns1 ( '<STR_LIT>' ) ) <EOL> cell_elem . set ( '<STR_LIT>' , unicode ( val ) ) <EOL> uri = self . _get_link ( '<STR_LIT>' , feed ) . get ( '<STR_LIT>' ) <EOL> self . client . put_feed ( uri , ElementTree . tostring ( feed ) ) <EOL> def _create_update_feed ( self , cell_list ) : <EOL> feed = Element ( '<STR_LIT>' , { '<STR_LIT>' : ATOM_NS , <EOL> '<STR_LIT>' : BATCH_NS , <EOL> '<STR_LIT>' : SPREADSHEET_NS } ) <EOL> id_elem = SubElement ( feed , '<STR_LIT:id>' ) <EOL> id_elem . text = construct_url ( '<STR_LIT>' , self ) <EOL> for cell in cell_list : <EOL> entry = SubElement ( feed , '<STR_LIT>' ) <EOL> SubElement ( entry , '<STR_LIT>' ) . text = cell . element . find ( <EOL> _ns ( '<STR_LIT:title>' ) ) . text <EOL> SubElement ( entry , '<STR_LIT>' , { '<STR_LIT:type>' : '<STR_LIT>' } ) <EOL> SubElement ( entry , '<STR_LIT:id>' ) . text = cell . element . find ( _ns ( '<STR_LIT:id>' ) ) . text <EOL> edit_link = finditem ( lambda x : x . get ( '<STR_LIT>' ) == '<STR_LIT>' , <EOL> cell . element . findall ( _ns ( '<STR_LIT>' ) ) ) <EOL> SubElement ( entry , '<STR_LIT>' , { '<STR_LIT>' : '<STR_LIT>' , <EOL> '<STR_LIT:type>' : edit_link . get ( '<STR_LIT:type>' ) , <EOL> '<STR_LIT>' : edit_link . get ( '<STR_LIT>' ) } ) <EOL> SubElement ( entry , '<STR_LIT>' , { '<STR_LIT>' : str ( cell . row ) , <EOL> '<STR_LIT>' : str ( cell . col ) , <EOL> '<STR_LIT>' : unicode ( cell . value ) } ) <EOL> return feed <EOL> def update_cells ( self , cell_list ) : <EOL> """<STR_LIT>""" <EOL> feed = self . _create_update_feed ( cell_list ) <EOL> self . client . post_cells ( self , ElementTree . tostring ( feed ) ) <EOL> def resize ( self , rows = None , cols = None ) : <EOL> """<STR_LIT>""" <EOL> if rows is None and cols is None : <EOL> raise TypeError ( "<STR_LIT>" ) <EOL> self_uri = self . _get_link ( '<STR_LIT>' , self . _element ) . get ( '<STR_LIT>' ) <EOL> feed = self . client . get_feed ( self_uri ) <EOL> uri = self . _get_link ( '<STR_LIT>' , feed ) . get ( '<STR_LIT>' ) <EOL> if rows : <EOL> elem = feed . find ( _ns1 ( '<STR_LIT>' ) ) <EOL> elem . text = str ( rows ) <EOL> if cols : <EOL> elem = feed . find ( _ns1 ( '<STR_LIT>' ) ) <EOL> elem . text = str ( cols ) <EOL> self . _element = self . client . put_feed ( uri , ElementTree . tostring ( feed ) ) <EOL> def add_rows ( self , rows ) : <EOL> """<STR_LIT>""" <EOL> self . resize ( rows = self . row_count + rows ) <EOL> def add_cols ( self , cols ) : <EOL> """<STR_LIT>""" <EOL> self . resize ( cols = self . col_count + cols ) <EOL> def append_row ( self , values ) : <EOL> """<STR_LIT>""" <EOL> self . add_rows ( <NUM_LIT:1> ) <EOL> new_row = self . row_count <EOL> data_width = len ( values ) <EOL> if self . col_count < data_width : <EOL> self . resize ( cols = data_width ) <EOL> cell_list = [ ] <EOL> for i , value in enumerate ( values , start = <NUM_LIT:1> ) : <EOL> cell = self . cell ( new_row , i ) <EOL> cell . value = value <EOL> cell_list . append ( cell ) <EOL> self . update_cells ( cell_list ) <EOL> def insert_row ( self , values , index = <NUM_LIT:1> ) : <EOL> """<STR_LIT>""" <EOL> if index == self . row_count + <NUM_LIT:1> : <EOL> return self . append_row ( values ) <EOL> elif index > self . row_count + <NUM_LIT:1> : <EOL> raise IndexError ( '<STR_LIT>' ) <EOL> self . add_rows ( <NUM_LIT:1> ) <EOL> data_width = len ( values ) <EOL> if self . col_count < data_width : <EOL> self . resize ( cols = data_width ) <EOL> top_left = self . get_addr_int ( index , <NUM_LIT:1> ) <EOL> bottom_right = self . get_addr_int ( self . row_count , self . col_count ) <EOL> range_str = '<STR_LIT>' % ( top_left , bottom_right ) <EOL> cells_after_insert = self . range ( range_str ) <EOL> for ind , cell in reversed ( list ( enumerate ( cells_after_insert ) ) ) : <EOL> if ind < self . col_count : <EOL> new_val = values [ ind ] if ind < len ( values ) else '<STR_LIT>' <EOL> else : <EOL> new_val = cells_after_insert [ ind - self . col_count ] . value <EOL> cell . value = new_val <EOL> self . update_cells ( cells_after_insert ) <EOL> def _finder ( self , func , query ) : <EOL> cells = self . _fetch_cells ( ) <EOL> if isinstance ( query , basestring ) : <EOL> match = lambda x : x . value == query <EOL> else : <EOL> match = lambda x : query . search ( x . value ) <EOL> return func ( match , cells ) <EOL> def find ( self , query ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> return self . _finder ( finditem , query ) <EOL> except StopIteration : <EOL> raise CellNotFound ( query ) <EOL> def findall ( self , query ) : <EOL> """<STR_LIT>""" <EOL> return list ( self . _finder ( filter , query ) ) <EOL> def export ( self , format = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> export_link = self . _get_link ( <EOL> '<STR_LIT>' , <EOL> self . _element ) . get ( '<STR_LIT>' ) <EOL> url , qs = export_link . split ( '<STR_LIT:?>' ) <EOL> params = dict ( param . split ( '<STR_LIT:=>' ) for param in qs . split ( '<STR_LIT:&>' ) ) <EOL> params [ '<STR_LIT>' ] = format <EOL> params = urlencode ( params ) <EOL> export_link = '<STR_LIT>' % ( url , params ) <EOL> return self . client . session . get ( export_link ) . content <EOL> class Cell ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , worksheet , element ) : <EOL> self . element = element <EOL> cell_elem = element . find ( _ns1 ( '<STR_LIT>' ) ) <EOL> self . _row = int ( cell_elem . get ( '<STR_LIT>' ) ) <EOL> self . _col = int ( cell_elem . get ( '<STR_LIT>' ) ) <EOL> self . input_value = cell_elem . get ( '<STR_LIT>' ) <EOL> numeric_value = cell_elem . get ( '<STR_LIT>' ) <EOL> self . numeric_value = float ( numeric_value ) if numeric_value else None <EOL> self . value = cell_elem . text or '<STR_LIT>' <EOL> @ property <EOL> def row ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _row <EOL> @ property <EOL> def col ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _col <EOL> def __repr__ ( self ) : <EOL> return '<STR_LIT>' % ( self . __class__ . __name__ , <EOL> self . row , <EOL> self . col , <EOL> repr ( self . value ) ) </s>
