def test_update_and_invoke(self):

        gdrive = GDrive()
        file_id = gdrive.find_by_name('GSlides API tests').get('id')
        pdf_bytes = gdrive.file_export(file_id)
        pdf_data = base64.b64encode(pdf_bytes).decode()
        payload = {"pdf_data": pdf_data, 'channel': 'DDKUZTK6X'}

        result = self.pdf_to_slack.update_with_src().invoke(payload)

        Dev.pprint(result)
Beispiel #2
0
 def __init__(self, gsuite_secret_id=None):
     self.presentations = GSuite(
         gsuite_secret_id).slides_v1().presentations()
     self.gdrive = GDrive(gsuite_secret_id)
Beispiel #3
0
class GSlides:
    def __init__(self, gsuite_secret_id=None):
        self.presentations = GSuite(
            gsuite_secret_id).slides_v1().presentations()
        self.gdrive = GDrive(gsuite_secret_id)

    # misc utils

    def batch_update(self, file_id, requests):
        body = {'requests': requests}
        return self.execute(
            self.presentations.batchUpdate(presentationId=file_id, body=body))

    def execute(self, command):
        return self.gdrive.execute(command)

    def execute_requests(self, file_id, requests):
        return self.batch_update(file_id, requests)

    def random_id(self, prefix):
        return Misc.random_string_and_numbers(6, prefix + "_")

    def all_presentations(self):
        mime_type_presentations = 'application/vnd.google-apps.presentation'
        return self.gdrive.find_by_mime_type(mime_type_presentations)

    # Elements
    def element_create_image_request(self,
                                     page_id,
                                     image_url,
                                     x_pos=200,
                                     y_pos=200,
                                     width=100,
                                     height=100):
        return {
            "createImage": {
                "url": image_url,
                "elementProperties": {
                    "pageObjectId": page_id,
                    "size": {
                        "width": {
                            "magnitude": width,
                            "unit": "PT"
                        },
                        "height": {
                            "magnitude": height,
                            "unit": "PT"
                        }
                    },
                    "transform": {
                        "scaleX": 1,
                        "scaleY": 1,
                        "translateX": x_pos,
                        "translateY": y_pos,
                        "unit": "PT"
                    }
                }
            }
        }

    def element_create_image(self,
                             file_id,
                             page_id,
                             image_url,
                             x_pos=200,
                             y_pos=200,
                             width=100,
                             height=100):
        requests = [
            self.element_create_image_request(page_id, image_url, x_pos, y_pos,
                                              width, height)
        ]
        result = self.batch_update(file_id, requests)
        return result.get('replies')[0].get('createImage').get('objectId')

    def element_create_table_request(self,
                                     slide_id,
                                     rows=3,
                                     cols=3,
                                     x_pos=200,
                                     y_pos=200,
                                     width=100,
                                     height=100,
                                     objectId=None):
        return {
            "createTable": {
                "objectId": objectId,
                "elementProperties": {
                    "pageObjectId": slide_id,
                    "size": {
                        "width": {
                            "magnitude": width,
                            "unit": "PT"
                        },
                        "height": {
                            "magnitude": height,
                            "unit": "PT"
                        }
                    },
                    "transform": {
                        "scaleX": 1,
                        "scaleY": 1,
                        "translateX": x_pos,
                        "translateY": y_pos,
                        "unit": "PT"
                    }
                },
                "rows": rows,
                "columns": cols
            }
        }
        #"tableRows"        : [{'rowHeight':{ 'magnitude': 10, 'unit': 'PT'}},{'rowHeight':{ 'magnitude': 100, 'unit': 'PT'}}]}}
    def element_create_table(self,
                             file_id,
                             slide_id,
                             rows=3,
                             cols=3,
                             x_pos=200,
                             y_pos=200,
                             width=100,
                             height=100,
                             objectId=None):
        requests = [
            self.element_create_table_request(slide_id, rows, cols, x_pos,
                                              y_pos, width, height, objectId)
        ]
        result = self.batch_update(file_id, requests)
        if result:
            return result.get('replies')[0].get('createTable').get('objectId')

    def element_create_shape_request(self,
                                     page_id,
                                     x_pos=200,
                                     y_pos=200,
                                     width=100,
                                     height=100,
                                     objectId=None):
        return {
            'createShape': {
                'objectId': objectId,
                'shapeType': 'TEXT_BOX',
                'elementProperties': {
                    'pageObjectId': page_id,
                    'size': {
                        'height': {
                            'magnitude': height,
                            'unit': 'PT'
                        },
                        'width': {
                            'magnitude': width,
                            'unit': 'PT'
                        }
                    },
                    'transform': {
                        'scaleX': 1,
                        'scaleY': 1,
                        'translateX': x_pos,
                        'translateY': y_pos,
                        'unit': 'PT'
                    }
                }
            }
        }

    def element_create_text_requests(self,
                                     page_id,
                                     text="Text...",
                                     x_pos=200,
                                     y_pos=200,
                                     width=100,
                                     height=100,
                                     objectId=None):
        return [
            self.element_create_shape_request(page_id, x_pos, y_pos, width,
                                              height, objectId),
            self.element_insert_text_request(objectId, text)
        ]

    def element_create_text(self,
                            file_id,
                            page_id,
                            text="Text...",
                            x_pos=200,
                            y_pos=200,
                            width=100,
                            height=100,
                            objectId=None):
        requests = self.element_create_text_requests(page_id, text, x_pos,
                                                     y_pos, width, height,
                                                     objectId)
        result = self.batch_update(file_id, requests)
        if result:
            return result.get('replies')[0].get('createShape').get('objectId')

    def element_create_shape(self,
                             file_id,
                             page_id,
                             shape_type,
                             x_pos=200,
                             y_pos=200,
                             width=100,
                             height=100):
        requests = [{
            'createShape': {
                'shapeType': shape_type,
                'elementProperties': {
                    'pageObjectId': page_id,
                    'size': {
                        'height': {
                            'magnitude': height,
                            'unit': 'PT'
                        },
                        'width': {
                            'magnitude': width,
                            'unit': 'PT'
                        }
                    },
                    'transform': {
                        'scaleX': 1,
                        'scaleY': 1,
                        'translateX': x_pos,
                        'translateY': y_pos,
                        'unit': 'PT'
                    }
                }
            }
        }]

        result = self.batch_update(file_id, requests)
        if result:
            return result.get('replies')[0].get('createShape').get('objectId')

    def element_delete(self, file_id, element_id):
        requests = [{'deleteObject': {'objectId': element_id}}]
        return self.batch_update(file_id, requests)

    def element_insert_text_request(self, objectId, text):
        return {
            'insertText': {
                'objectId': objectId,
                'insertionIndex': 0,
                'text': text
            }
        }

    def element_set_table_cell_size_bold_requests(self, table_id, row, col,
                                                  size, bold):
        style = {"bold": bold, "fontSize": {"magnitude": size, "unit": "PT"}}
        fields = "bold,fontSize"
        return self.element_set_table_text_style_request(
            table_id, row, col, style, fields)

    def element_set_table_text_style_request(self, shape_id, row, col, style,
                                             fields):
        return {
            'updateTextStyle': {
                'objectId': shape_id,
                "cellLocation": {
                    "rowIndex": row,
                    "columnIndex": col
                },
                'style': style,
                'fields': fields
            }
        }

    def element_set_table_text_requests(self, table_id, row, col, text):
        return [  #{ "deleteText": {   "objectId"      : table_id,
            #                    "cellLocation"  : {  "rowIndex": row, "columnIndex": col   },
            #                    "textRange"     : {"type": "ALL"                         }}},
            {
                "insertText": {
                    "objectId": table_id,
                    "cellLocation": {
                        "rowIndex": row,
                        "columnIndex": col
                    },
                    "text": text,
                    "insertionIndex": 0
                }
            }
        ]

    def element_set_table_text(self, file_id, table_id, row, col, text):
        requests = self.element_set_table_text_requests(
            table_id, row, col, text)

        self.execute_requests(file_id, requests)

    def element_set_table_column_width_request(self, table_id, column_index,
                                               column_width):

        return {
            'updateTableColumnProperties': {
                'objectId': table_id,
                "columnIndices": [column_index],
                "tableColumnProperties": {
                    'columnWidth': {
                        "magnitude": column_width,
                        "unit": "PT"
                    }
                },
                "fields": "columnWidth"
            }
        }

    def element_set_table_cell_aligment_request(self,
                                                table_id,
                                                row_index,
                                                column_index,
                                                row_span,
                                                column_span,
                                                alignment='MIDDLE'):
        return {
            "updateTableCellProperties": {
                "objectId": table_id,
                "tableRange": {
                    "location": {
                        "rowIndex": row_index,
                        "columnIndex": column_index
                    },
                    "rowSpan": row_span,
                    "columnSpan": column_span
                },
                "tableCellProperties": {
                    "contentAlignment": alignment
                },
                "fields": "contentAlignment"
            }
        }

    def element_set_table_row_height_request(self, table_id, height):
        return {
            "updateTableRowProperties": {
                "objectId": table_id,
                "rowIndices": 0,
                "tableRowProperties": {
                    "minRowHeight": {
                        'magnitude': height,
                        'unit': 'PT'
                    }
                },
                "fields": "minRowHeight"
            }
        }

    def element_set_text_requests(self, file_id, element_id, text):
        return [{
            'deleteText': {
                'objectId': element_id,
                'textRange': {
                    'type': 'ALL'
                }
            }
        }, {
            'insertText': {
                'objectId': element_id,
                'insertionIndex': 0,
                'text': text
            }
        }]

    def element_set_text(self, file_id, element_id, text):

        requests = self.element_set_text_requests(file_id, element_id, text)

        return self.batch_update(file_id, requests)

    def element_set_text_style_requests(self, object_id, style, fields):
        return {
            'updateTextStyle': {
                'objectId': object_id,
                'style': style,
                'fields': fields
            }
        }

    def element_set_text_style(self, file_id, shape_id, style, fields):
        requests = [
            self.element_set_text_style_requests(shape_id, style, fields)
        ]
        return self.batch_update(file_id, requests)

    def element_set_text_style_requests__for_title(self,
                                                   shape_id,
                                                   font_size,
                                                   blue=0.5,
                                                   green=0.5,
                                                   red=0.5):
        style = {
            'bold': True,
            'fontFamily': 'Avenir',
            'fontSize': {
                'magnitude': font_size,
                'unit': 'PT'
            },
            'foregroundColor': {
                'opaqueColor': {
                    'rgbColor': {
                        'blue': blue,
                        'green': green,
                        'red': red
                    }
                }
            }
        }
        fields = 'bold,fontFamily,fontSize,foregroundColor'

        return self.element_set_text_style_requests(shape_id, style, fields)

    def element_set_shape_properties(self, shape_id, properties, fields=None):
        if fields is None:
            fields = ",".join(list(set(properties)))
        requests = [{
            'updateShapeProperties': {
                'objectId': shape_id,
                'shapeProperties': properties,
                'fields': fields
            }
        }]
        return self.batch_update(file_id, requests)

    def presentation_create(self, title):
        body = {'title': title}
        presentation = self.presentations.create(body=body).execute()
        return presentation.get('presentationId')

    def presentation_copy(self, file_id, title, parent_folder):
        body = {'name': title, 'parents': [parent_folder]}
        result = self.execute(self.gdrive.files.copy(fileId=file_id,
                                                     body=body))
        return result.get('id')

    def presentation_metadata(self, presentation_id):
        try:
            return self.presentations.get(
                presentationId=presentation_id).execute()
        except:
            return None

    def slide_delete_request(self, slide_id):
        return {"deleteObject": {"objectId": slide_id}}

    def slide_delete(self, presentation_id, slide_id):
        requests = [self.slide_delete_request(slide_id)]
        return self.execute_requests(presentation_id, requests)

    def slide_copy(self,
                   presentation_id,
                   slide_id,
                   new_slide_id,
                   objects_ids={}):
        requests = [{
            "duplicateObject": {
                "objectId": slide_id,
                "objectIds": objects_ids
            }
        }]
        requests[0]['duplicateObject']['objectIds'][slide_id] = new_slide_id
        return self.execute_requests(presentation_id, requests)

    def slide_create_request(self,
                             new_slide_id=None,
                             layout='BLANK',
                             insert_at=None):
        return {
            "createSlide": {
                "objectId": new_slide_id,
                'insertionIndex': insert_at,
                'slideLayoutReference': {
                    'predefinedLayout': layout
                }
            }
        }

    def slide_create(self,
                     presentation_id,
                     insert_at=1,
                     layout='TITLE',
                     new_slide_id=None):
        requests = [self.slide_create_request(new_slide_id, layout, insert_at)]
        result = self.execute_requests(presentation_id, requests)
        if result:
            return result.get('replies')[0].get('createSlide').get('objectId')

    def slide_move_to_pos_request(self, presentation_id, slide_id, pos):
        return [{
            "updateSlidesPosition": {
                "slideObjectIds": [slide_id],
                "insertionIndex": pos
            }
        }]

    def slide_move_to_pos(self, presentation_id, slide_id, pos):
        requests = self.slide_move_to_pos_request(presentation_id, slide_id,
                                                  pos)
        return self.execute_requests(presentation_id, requests)

    def slide_elements(self, presentation_id, page_number):
        slides = self.slides(presentation_id)
        page = slides[page_number]
        if page:
            return page.get('pageElements')
        return []

    def slide_elements_via_id(self, presentation_id, slide_id):
        slides = self.slides_indexed_by_id(presentation_id)
        slide = slides.get(slide_id)
        if slide:
            return slide.get('pageElements')
        return []

    def slide_elements_via_id_indexed_by_id(self, presentation_id, slide_id):
        elements = {}
        for element in self.slide_elements_via_id(presentation_id, slide_id):
            elements[element.get('objectId')] = element
        return elements

    def slides(self, presentation_id):
        presentation = self.presentation_metadata(presentation_id)
        if presentation:
            return presentation.get('slides')
        return []

    def slides_indexed_by_id(self, presentation_id):
        presentation = self.presentation_metadata(presentation_id)
        slides = {}
        if presentation:
            for slide in presentation.get('slides'):
                slides[slide.get('objectId')] = slide
        return slides

    # Helper methods

    def add_slide_with_table_from_array(self,
                                        file_id,
                                        slide_id,
                                        title,
                                        data,
                                        row_widths=[]):
        title_id = '{0}_title'.format(slide_id)
        table_id = '{0}_table'.format(slide_id)
        headers = data.pop(0)
        cols = len(headers)
        rows = len(data) + 1
        cell_size = 7
        self.slide_delete(file_id, slide_id)
        requests = [
            self.slide_create_request(slide_id),
            self.element_create_shape_request(slide_id, 10, 10, 500, 50,
                                              title_id),
            self.element_insert_text_request(title_id, title),
            self.element_set_text_style_requests__for_title(title_id, 26),
            self.element_create_table_request(slide_id, rows, cols, 12, 80,
                                              700, 270, table_id),
            #self.element_set_table_row_height_request      (table_id, 10)
        ]

        for col_index, header in enumerate(headers):
            requests.extend(
                self.element_set_table_text_requests(table_id, 0, col_index,
                                                     header))
            requests.append(
                self.element_set_table_cell_size_bold_requests(
                    table_id, 0, col_index, 11, True))

        for row_index, row in enumerate(data):
            for col_index, cell in enumerate(row):
                requests.extend(
                    self.element_set_table_text_requests(
                        table_id, row_index + 1, col_index, cell))
                requests.append(
                    self.element_set_table_cell_size_bold_requests(
                        table_id, row_index + 1, col_index, cell_size, False))

        for index, row_width in enumerate(row_widths):
            requests.append(
                self.element_set_table_column_width_request(
                    table_id, index, row_width))

        requests.append(
            self.element_set_table_cell_aligment_request(
                table_id, 0, 0, rows, cols))

        self.execute_requests(file_id, requests)
        return table_id

    def add_slide_with_table_from_object(self, file_id, slide_id, title, data):

        title_id = '{0}_title'.format(slide_id)
        table_id = '{0}_table'.format(slide_id)
        headers = list(set(data))
        rows = len(headers)  # number of fields to show
        cols = 2  # name:value pair
        requests = [
            self.slide_create_request(slide_id),
            self.element_create_shape_request(slide_id, 10, 10, 500, 50,
                                              title_id),
            self.element_insert_text_request(title_id, title),
            self.element_set_text_style_requests__for_title(title_id, 26),
            self.element_create_table_request(slide_id, rows, cols, 12, 80,
                                              700, 270, table_id),
            self.element_set_table_column_width_request(table_id, 0, 110),
            self.element_set_table_column_width_request(table_id, 1, 585)
        ]

        for index, header in enumerate(headers):
            requests.extend(
                self.element_set_table_text_requests(table_id, index, 0,
                                                     header))
            requests.extend(
                self.element_set_table_text_requests(table_id, index, 1,
                                                     str(data[header])))
            requests.append(
                self.element_set_table_cell_size_bold_requests(
                    table_id, index, 0, 10, True))
            requests.append(
                self.element_set_table_cell_size_bold_requests(
                    table_id, index, 1, 9, False))

        #requests.extend(self.element_set_table_text_requests        (table_id, 1, 0, headers.pop()))

        self.execute_requests(file_id, requests)
Beispiel #4
0
 def __init__(self, gsuite_secret_id=None):
     self.gdrive       = GDrive(gsuite_secret_id)
     self.spreadsheets = GSuite(gsuite_secret_id).sheets_v4().spreadsheets()
Beispiel #5
0
class GSheets:

    def __init__(self, gsuite_secret_id=None):
        self.gdrive       = GDrive(gsuite_secret_id)
        self.spreadsheets = GSuite(gsuite_secret_id).sheets_v4().spreadsheets()

    def batch_update(self, file_id, requests):
        body = {'requests': requests}
        return self.execute(self.spreadsheets.batchUpdate(spreadsheetId=file_id, body=body))

    def execute(self,command):
        return self.gdrive.execute(command)

    def execute_request(self, file_id, request):
        return self.batch_update(file_id, [request])

    def execute_requests(self, file_id, requests):
        return self.batch_update(file_id, requests)


    def all_spreadsheets(self):
        mime_type_presentations = 'application/vnd.google-apps.spreadsheet'
        return self.gdrive.find_by_mime_type(mime_type_presentations)

    def sheets_metadata(self, file_id):
        return self.execute(self.spreadsheets.get(spreadsheetId=file_id))

    def sheets_add_sheet(self, file_id, title):
        request = { "addSheet": { "properties": { "title": title } } }

        result  =  self.execute_request(file_id, [request])
        return result.get('replies')[0].get('addSheet').get('properties').get('sheetId')


    def sheets_delete_sheet(self, file_id, sheet_id):
        request = { "deleteSheet": { "sheetId": sheet_id } }

        return self.execute_request(file_id, [request])

    def sheets_rename_sheet(self, file_id, sheet_id, new_name):
        request = {"updateSheetProperties": { "properties": { "sheetId": sheet_id    ,
                                                              "title"  : new_name   },
                                              "fields"    :   "title"               }}
        return self.execute_request(file_id, [request])

    def sheets_properties_by_id(self, file_id):
        values = {}
        metadata = self.sheets_metadata(file_id)
        for sheet in metadata.get('sheets'):
           properties = sheet.get('properties')
           sheet_id   = properties.get('sheetId')
           values[sheet_id] = properties
        return values

    def sheets_properties_by_title(self, file_id):
        values = {}
        metadata = self.sheets_metadata(file_id)
        if metadata:
            for sheet in metadata.get('sheets'):
               properties = sheet.get('properties')
               sheet_id   = properties.get('title')
               values[sheet_id] = properties
            return values

    def request_cell_set_background_color(self, sheet_id, col, row, red, green, blue):
        return {'updateCells': { 'start': {'sheetId': sheet_id, 'rowIndex': row, 'columnIndex': col },
                                 'rows': [{'values': [ {'userEnteredFormat' : {'backgroundColor': {'red': red, 'blue': blue, 'green': green}}}] } ],
                                 'fields': 'userEnteredFormat.backgroundColor'}}

    def request_cell_set_value(self, sheet_id, col, row, value):
        return {'updateCells': { 'start': {'sheetId': sheet_id, 'rowIndex': row, 'columnIndex': col },
                                 'rows': [{'values': [ {'userEnteredValue': {'stringValue': value}}] } ],
                                 'fields': 'userEnteredValue'}}

    def clear_values(self, file_id, sheet_name):
        sheet_range = "{0}!A1:Z".format(sheet_name)
        return self.execute(self.spreadsheets.values().clear(spreadsheetId=file_id, range=sheet_range))

    def get_values(self, file_id, range):
        if file_id and range:
            values = self.spreadsheets.values()
            result = self.execute(values.get(spreadsheetId = file_id , range = range    ))
            return result.get('values')

    def set_values(self, file_id, sheet_range, values):
        value_input_option = 'USER_ENTERED' # vs 'RAW'
        body               = { 'values' : values }
        result = self.execute(self.spreadsheets.values().update( spreadsheetId    = file_id,
                                                                 range            = sheet_range,
                                                                 valueInputOption = value_input_option,
                                                                 body             = body))
        return result

    # this assumes that the the first row contains the fields and the rest is the data items
    def get_values_as_objects(self, file_id, range_selector):
        columns = self.get_values(file_id, range_selector)
        fields = columns.pop(0)
        values = []
        for column in columns:
            item = {}
            for index, cell in enumerate(column):
                item[fields[index]] = cell
            values.append(item)
        return values


    # helper methods
    def covert_raw_data_to_flat_objects(self, raw_data):
        sheet_data = []
        headers = list(raw_data[0].keys())

        sheet_data.append(headers)

        for item in raw_data:
            sheet_data.append(list(item.values()))

        # make sure every cell is a string
        for i, row in enumerate(sheet_data):
            for j, cell in enumerate(row):
                if cell is None:
                    sheet_data[i][j] = ''
                else:
                    sheet_data[i][j] = str(sheet_data[i][j])
        return sheet_data

    def format_headers(self, file_id, sheet_id, end_column):
        requests =  [   { "repeatCell": { "range": {  "sheetId": sheet_id,
                                                      "startRowIndex"  : 0,
                                                      "endRowIndex"    : 1,
                                                      "endColumnIndex" : end_column},
                                          "cell" : {  "userEnteredFormat": { "backgroundColor": { "red": 0.8, "green": 0.8, "blue": 0.8 },
                                                                             "horizontalAlignment" : "CENTER",
                                                                             "textFormat"  : { "foregroundColor": { "red": 0.0, "green": 0.0, "blue": 0.0 },
                                                                                               "fontSize": 12,
                                                                                               "bold": True } }},
                                          "fields": "userEnteredFormat(backgroundColor,textFormat,horizontalAlignment)" } },
                        { "updateSheetProperties": { "properties": { "sheetId": sheet_id,
                                                                     "gridProperties": { "frozenRowCount": 1 }},
                                                     "fields": "gridProperties.frozenRowCount"}} ]
        self.execute_requests(file_id,requests)
class Test_GDrive(TestCase):
    def setUp(self):
        self.gslides = GSlides()
        self.gdrive  = GDrive()

    # helper methods

    def get_target_slide_id(self):
        file_id  = self.gdrive.find_by_name('GSlides API tests').get('id')
        slides   = self.gslides.slides(file_id)
        slide_id = slides.pop().get('objectId')
        return file_id, slide_id

    # tests for GDrive methods

    def test_ctor(self):
        service = self.gslides.service
        assert service._baseUrl == 'https://slides.googleapis.com/'

    def test_all_presentations(self):
        result = self.gslides.all_presentations()
        assert len(result) > 0

    def test_presentation_get(self):
        presentation_id = self.gslides.presentation_create('created via Unit tests')
        result = self.gslides.presentation(presentation_id)

        assert set(result) == { 'layouts'       , 'locale'    , 'masters', 'notesMaster', 'pageSize',
                                'presentationId', 'revisionId', 'slides' , 'title'                  }

        assert result.get('title') == 'created via Unit tests'

        self.gdrive.file_delete(presentation_id)
        assert self.gslides.presentation(presentation_id) is None

    def test_presentation_create(self):
        presentation_id = self.gslides.presentation_create('created via Unit tests')
        Dev.pprint(presentation_id)

    def test_slide_copy(self):
        file_id = self.gdrive.find_by_name('GSlides API tests').get('id')
        slide_id = 'g4b149a1e32_0_0'
        new_slide_id = 'slide_3'
        result = self.gslides.slide_copy(file_id,slide_id,new_slide_id)
        Dev.pprint(result)

    def test_slide_create(self):
        file_id = self.gdrive.find_by_name('GSlides API tests').get('id')
        new_slide_id = 'new_slide_id'
        self.gslides.slide_delete(file_id, new_slide_id)
        result = self.gslides.slide_create(file_id, 2, 'TITLE_AND_BODY', new_slide_id)
        assert result == new_slide_id
        self.gslides.slide_delete(file_id, new_slide_id)
        result = self.gslides.slide_create(file_id)
        self.gslides.slide_delete(file_id, result)

    def test_slide_elements(self):
        test_id = self.gdrive.find_by_name('GSlides API tests').get('id')
        elements = self.gslides.slide_elements(test_id, 1)
        assert len(elements) > 0

    def test_slides(self):
        test_id = self.gdrive.find_by_name('GSlides API tests').get('id')
        slides = self.gslides.slides(test_id)
        assert len(slides) > 0

    def test_element_set_text(self):
        file_id    = self.gdrive.find_by_name('GSlides API tests').get('id')
        slides     = self.gslides.slides(file_id)
        element_id = slides.pop().get('pageElements').pop().get('objectId') # last element of the last slide
        text       = 'new text.....changed....'
        result     = self.gslides.set_element_text(file_id,element_id,text)

        assert result.get('presentationId') == file_id


    def test_delete_element__all_temp_created(self):
        file_id  = self.gdrive.find_by_name('GSlides API tests').get('id')
        elements = self.gslides.slide_elements_indexed_by_id(file_id,1)
        for key,element in elements.items():
            #Dev.pprint(key)
            if 'textbox_' in key.lower():
                Dev.pprint(self.gslides.element_delete(file_id,key))



    def test_add_element_text(self):
        (file_id, slide_id) = self.get_target_slide_id()
        text    = Misc.random_string_and_numbers(6,'New Text Field - ')
        x_pos   = 50
        y_pos   = 250
        width   = 300
        height  = 50
        new_id = self.gslides.element_create_text(file_id, slide_id, text, x_pos, y_pos, width, height)

        self.gslides.element_set_text(file_id,new_id,'changed text')
        sleep(2)
        self.gslides.element_delete(file_id,new_id)

    def test_element_create_image(self):
        (file_id, slide_id) = self.get_target_slide_id()
        image_url = 'https://pbx-group-security.com/img/pbx-gs/pbx-gs-logo.png'
        shape_id  = self.gslides.element_create_image(file_id, slide_id,image_url, 100,100,300,300)
        sleep(3)
        self.gslides.element_delete(file_id, shape_id)

    def test_element_create_shape(self):
        (file_id, slide_id) = self.get_target_slide_id()
        def test_shape_creation(shape_type):
            shape_id  = self.gslides.element_create_shape(file_id, slide_id, shape_type,225,50,300,300)
            #properties = {"shapeBackgroundFill": {"solidFill": {"alpha": 0.6, "color": {"themeColor": "ACCENT5"}}}}
            #self.gslides.element_set_shape_properties(file_id, shape_id, properties)
            if shape_id:
                self.gslides.element_delete(file_id, shape_id)

        # enabling all 140 shapes below will cause an "Quota exceeded for quota group 'WriteGroup' and limit 'USER-100s" error

        shapes = [  #'TEXT_BOX','RECTANGLE','ROUND_RECTANGLE','ELLIPSE','ARC','BENT_ARROW','BENT_UP_ARROW','BEVEL',
                    #'BLOCK_ARC','BRACE_PAIR','BRACKET_PAIR','CAN','CHEVRON','CHORD','CLOUD','CORNER','CUBE',
                    #'CURVED_DOWN_ARROW','CURVED_LEFT_ARROW','CURVED_RIGHT_ARROW','CURVED_UP_ARROW','DECAGON',
                    #'DIAGONAL_STRIPE','DIAMOND','DODECAGON','DONUT','DOUBLE_WAVE','DOWN_ARROW','DOWN_ARROW_CALLOUT',
                    #'FOLDED_CORNER','FRAME','HALF_FRAME','HEART','HEPTAGON','HEXAGON','HOME_PLATE','HORIZONTAL_SCROLL',
                    #'IRREGULAR_SEAL_1','IRREGULAR_SEAL_2','LEFT_ARROW','LEFT_ARROW_CALLOUT','LEFT_BRACE','LEFT_BRACKET',
                    #'LEFT_RIGHT_ARROW','LEFT_RIGHT_ARROW_CALLOUT','LEFT_RIGHT_UP_ARROW','LEFT_UP_ARROW','LIGHTNING_BOLT',
                    #'MATH_DIVIDE','MATH_EQUAL','MATH_MINUS','MATH_MULTIPLY','MATH_NOT_EQUAL','MATH_PLUS','MOON',
                    #'NO_SMOKING','NOTCHED_RIGHT_ARROW','OCTAGON','PARALLELOGRAM','PENTAGON','PIE','PLAQUE','PLUS',
                    #'QUAD_ARROW','QUAD_ARROW_CALLOUT','RIBBON','RIBBON_2','RIGHT_ARROW','RIGHT_ARROW_CALLOUT',
                    #'RIGHT_BRACE','RIGHT_BRACKET','ROUND_1_RECTANGLE','ROUND_2_DIAGONAL_RECTANGLE','ROUND_2_SAME_RECTANGLE',
                    #'RIGHT_TRIANGLE','SMILEY_FACE','SNIP_1_RECTANGLE','SNIP_2_DIAGONAL_RECTANGLE','SNIP_2_SAME_RECTANGLE',
                    #'SNIP_ROUND_RECTANGLE','STAR_10','STAR_12','STAR_16','STAR_24','STAR_32','STAR_4','STAR_5','STAR_6',
                    #'STAR_7','STAR_8','STRIPED_RIGHT_ARROW','SUN','TRAPEZOID','TRIANGLE','UP_ARROW','UP_ARROW_CALLOUT',
                    'UP_DOWN_ARROW','UTURN_ARROW','VERTICAL_SCROLL','WAVE','WEDGE_ELLIPSE_CALLOUT','WEDGE_RECTANGLE_CALLOUT',
                    'WEDGE_ROUND_RECTANGLE_CALLOUT','FLOW_CHART_ALTERNATE_PROCESS','FLOW_CHART_COLLATE','FLOW_CHART_CONNECTOR',
                    'FLOW_CHART_DECISION','FLOW_CHART_DELAY','FLOW_CHART_DISPLAY','FLOW_CHART_DOCUMENT','FLOW_CHART_EXTRACT',
                    'FLOW_CHART_INPUT_OUTPUT','FLOW_CHART_INTERNAL_STORAGE','FLOW_CHART_MAGNETIC_DISK','FLOW_CHART_MAGNETIC_DRUM',
                    'FLOW_CHART_MAGNETIC_TAPE','FLOW_CHART_MANUAL_INPUT','FLOW_CHART_MANUAL_OPERATION','FLOW_CHART_MERGE',
                    'FLOW_CHART_MULTIDOCUMENT','FLOW_CHART_OFFLINE_STORAGE','FLOW_CHART_OFFPAGE_CONNECTOR','FLOW_CHART_ONLINE_STORAGE',
                    'FLOW_CHART_OR','FLOW_CHART_PREDEFINED_PROCESS','FLOW_CHART_PREPARATION','FLOW_CHART_PROCESS','FLOW_CHART_PUNCHED_CARD',
                    'FLOW_CHART_PUNCHED_TAPE','FLOW_CHART_SORT','FLOW_CHART_SUMMING_JUNCTION','FLOW_CHART_TERMINATOR','ARROW_EAST',
                    'ARROW_NORTH_EAST','ARROW_NORTH','SPEECH','STARBURST','TEARDROPELLIPSE_RIBBON','ELLIPSE_RIBBON_2','CLOUD_CALLOUT']
        for shape in shapes:
            test_shape_creation(shape)

    def test_element_create_table(self):
        (file_id, slide_id) = self.get_target_slide_id()
        table_id  = self.gslides.element_create_table(file_id, slide_id)

        # the deleteText command (below) was throwing an error (I think it might be caused by the fact that there is no data in the cell)
        requests = [#{ "deleteText": {   "objectId"      : table_id,
                    #                    "cellLocation"  : {  "rowIndex": 4, "columnIndex": 2   },
                    #                    "textRange"     : {"type": "ALL"                     }}},
                    { "insertText": {   "objectId"      : table_id,
                                        "cellLocation"  : {  "rowIndex": 0, "columnIndex": 0   },
                                        "text"          : "text added",
                                        "insertionIndex": 0                                   }},]
        self.gslides.execute_requests(file_id, requests)
        requests = [ { "updateTableCellProperties"  : {   "objectId": table_id,
                                                          "tableRange": { "location"  : { "rowIndex"   : 0, "columnIndex": 0},
                                                                          "rowSpan"   : 1 ,
                                                                          "columnSpan": 1 },
                                                          "tableCellProperties": { "tableCellBackgroundFill":  { "solidFill": { "color": {"rgbColor": {"red": 0.0,"green": 0.0, "blue": 0.0 }}}}},
                                                          "fields"             : "tableCellBackgroundFill.solidFill.color"}},
                     { "updateTextStyle"            : {    "objectId": table_id,
                                                           "cellLocation": { "rowIndex": 0, "columnIndex": 0},
                                                           "style": { "foregroundColor": {
                                                                      "opaqueColor": { "rgbColor": {"red": 0.5,"green": 1.0,"blue": 0.5}} },
                                                                      "bold": True,
                                                                      "fontFamily": "Cambria",
                                                                      "fontSize": { "magnitude": 38,"unit": "PT" }},
                                                          "textRange": { "type": "ALL"},
                                                          "fields": "foregroundColor,bold,fontFamily,fontSize" }}]
        self.gslides.execute_requests(file_id, requests)
        sleep(3)
        self.gslides.element_delete(file_id, table_id)

    def test_element_set_text_style(self):
        (file_id, slide_id) = self.get_target_slide_id()
        shape_id = self.gslides.element_create_text(file_id, slide_id,width=400)

        style = {  'bold'            : True,
                   'italic'          : True,
                   'fontFamily'      : 'Times New Roman',
                   'fontSize'        : { 'magnitude'  : 74, 'unit': 'PT' },
                   'foregroundColor' : { 'opaqueColor': { 'rgbColor': { 'blue': 0.49803922, 'green': 1.0, 'red': 0.0 }}},
                    'link'           : { 'url': 'https://news.bbc.co.uk'         } }
        fields   = 'bold,italic,fontFamily,fontSize, foregroundColor,link'

        self.gslides.element_set_text_style(file_id,shape_id, style, fields)
        sleep(3)
        self.gslides.element_delete(file_id,shape_id)

    def test_element_set_shape_properties(self):
        (file_id, slide_id) = self.get_target_slide_id()
        shape_id = self.gslides.element_create_text(file_id, slide_id,width=400)

        properties = { "shapeBackgroundFill": { "solidFill"  : { "alpha": 0.6, "color": { "themeColor": "ACCENT5" } } },
                        "outline"           : { "dashStyle"  : "SOLID",
                                                "outlineFill": { "solidFill": { "alpha": 1, "color": { "themeColor": "ACCENT5" }} },
                                                "weight"     : {"magnitude": 3, "unit": "PT"                                    } },
                        "contentAlignment"  : 'MIDDLE'                                                                            }

        fields = "shapeBackgroundFill,outline, contentAlignment"

        self.gslides.element_set_shape_properties(file_id,shape_id,properties,fields)
        sleep(3)
        self.gslides.element_delete(file_id, shape_id)

    def test_element_set_via_requests(self):
        (file_id, slide_id) = self.get_target_slide_id()
        shape_id = self.gslides.element_create_text(file_id, slide_id, width=400)
        requests = []
        requests.append  ({ 'updateTextStyle'       : { 'objectId'       : shape_id  ,
                                                        'style'          : { 'fontSize': {'magnitude': 74, 'unit': 'PT'}},
                                                        'fields'         : 'fontSize'                                  }})
        requests.append  ({ 'updateParagraphStyle'  : { "objectId"       : shape_id,
                                                        "style"          : { "alignment": "CENTER" },
                                                        "fields"         : 'alignment'                                 }})
        requests.append  ({ "updateShapeProperties" : { "objectId"       : shape_id,
                                                        'shapeProperties': { "shapeBackgroundFill" : { "solidFill"  : { "alpha": 0.6, "color": { "themeColor": "ACCENT5" } } }},
                                                        'fields'         : 'shapeBackgroundFill'                       }})

        self.gslides.execute_requests(file_id, requests)
        sleep(2)
        self.gslides.element_delete(file_id, shape_id)
 def setUp(self):
     self.gslides = GSlides()
     self.gdrive  = GDrive()
Beispiel #8
0
 def setUp(self):
     self.gdrive = GDrive()
Beispiel #9
0
class Test_GDrive(TestCase):
    def setUp(self):
        self.gdrive = GDrive()

    def test_ctor(self):
        files = self.gdrive.files
        assert files._baseUrl == 'https://www.googleapis.com/drive/v3/'

    def test_file_find_by_name(self):
        name = 'GSlides API tests'
        assert self.gdrive.find_by_name(name).get('name') == name
        assert self.gdrive.find_by_name('aaaa') is None

    def test_file_export(self):
        #id = '1rWCUAh2y4AY-RrqyK5JywDskGjJe4GydrPSrX1td6Lk'   # test document
        #id = '1CA-uqZj9HVr2_RHiI-esVyHBoHZ1M1sxGzq54EQ2Ek4'   # test slides
        file_id = self.gdrive.find_by_name('GSlides API tests').get('id')
        pdf_data = self.gdrive.file_export(file_id)

        with open('./test.pdf', "wb") as fh:
            fh.write(pdf_data)
            #fh.write(base64.decodebytes(pdf_data.encode()))
        #Dev.pprint(result)

    def test_file_metadata(self):
        file_id = '1rWCUAh2y4AY-RrqyK5JywDskGjJe4GydrPSrX1td6Lk'  # test document
        result = self.gdrive.file_metadata(file_id)
        Dev.pprint(result)

    def test_file_metadata_update(self):
        file_id = '1CA-uqZj9HVr2_RHiI-esVyHBoHZ1M1sxGzq54EQ2Ek4'  # test spreadsheet
        metadata = self.gdrive.file_metadata(file_id)
        Dev.pprint(metadata)
        changes = self.gdrive.set_file_title(file_id, 'GSlides API tests')
        Dev.pprint(changes)

    def test_file_update(self):
        file = '/tmp/puml_graph_W64.png'
        #file   = '/tmp/puml_graph_09Q.png'
        file = '/tmp/puml_graph.png'
        id = '1H72nAFgqu1OSW_xm-gwDWml6tOzy5UZ_'
        result = self.gdrive.file_update(file, 'image/png', id)
        Dev.pprint(result)

    def test_file_upload(self):
        #file   = '/tmp/puml_graph_W64.png'
        file = '/tmp/puml_graph_09Q.png'
        folder = '1ZXXoYc443-HG6Twr7chTvym8JNgssoNJ'
        result = self.gdrive.file_upload(file, 'image/png', folder)
        Dev.pprint(result)

    def test_files(self):
        files = self.gdrive.files_all(4)
        for item in files:
            print('{0:22} - {1}'.format(item['name'], item['id']))

    def test_files_in_folder(self):
        folder_id = '16yOkKyi0TfOy3w4IMW40vo-pr--Wa1Y9'
        try:
            files = self.gdrive.files_in_folder(folder_id, size=2)
            for item in files:
                print('{0:22} - {1}'.format(item['name'], item['id']))
        except Exception as error:
            Dev.pprint(error)

    def testfiles_with_mime_type(self):
        mime_type_presentations = 'application/vnd.google-apps.presentation'
        files = self.gdrive.find_by_mime_type(mime_type_presentations)

        assert len(files) > 0