Source code for visual_viper.chart_deployers.miro_chart_deployer

import os
import json
import requests
import inflection

from .abstract_chart_deployer import AbstractChartDeployer


[docs] class MiroChartDeployer (AbstractChartDeployer): DEFAULT_IMAGE_WIDTH=2000 DEFAULT_IMAGE_X_POSITION=0 DEFAULT_IMAGE_Y_POSITION=0 DEFAULT_IMAGE_TITLE="Default Image Title" DEFAULT_LAYOUT_COLUMNS=4 DEFAULT_LAYOUT_COLUMN_SPACING=150 DEFAULT_LAYOUT_ROW_SPACING=150 def __init__( self, board_id, token, layout_columns=None, layout_x_position=None, layout_y_position=None, params=None ): self.board_id = board_id self.oauth_token = token self.parent_id = params.get("parent_id") if params else None self.layout_columns = layout_columns or self.DEFAULT_LAYOUT_COLUMNS self.layout_x_position = layout_x_position or self.DEFAULT_IMAGE_X_POSITION self.layout_y_position = layout_y_position or self.DEFAULT_IMAGE_Y_POSITION self.image_title = params.get("image_title") if params else self.DEFAULT_IMAGE_TITLE self.image_width = params.get("image_width") if params else self.DEFAULT_IMAGE_WIDTH self.image_x_position = self.layout_x_position self.image_y_position = self.layout_y_position self.layout_column_spacing = params.get("layout_column_spacing") if params else self.DEFAULT_LAYOUT_COLUMN_SPACING self.layout_row_spacing = params.get("layout_row_spacing") if params else self.DEFAULT_LAYOUT_ROW_SPACING self.deployment_counter = 0 self.row_elements_height = [] self.last_widget_id = None
[docs] def calc_position(self,last_widget_id=None): if (self.deployment_counter == 0) or (last_widget_id == None): return if self.deployment_counter % self.layout_columns > 0: self.image_x_position = self.image_x_position + self.image_width + self.layout_column_spacing last_widget_height = self.get_widget_attribute( widget_id=self.last_widget_id, attribute_path=['geometry', 'height'] ) self.row_elements_height.append(last_widget_height) else: row_height = max(self.row_elements_height) self.image_y_position = self.image_y_position + row_height + self.layout_row_spacing + self.layout_y_position self.image_x_position = self.layout_x_position self.row_elements_height = []
[docs] def get_widget_attribute(self, widget_id, attribute_path): url = f"https://api.miro.com/v2/boards/{self.board_id}/widgets/{widget_id}" headers = {"Authorization": f"Bearer {self.oauth_token}"} response = requests.get(url, headers=headers) if response.status_code == 200: widget = response.json() attribute_value = widget for attr in attribute_path: attribute_value = attribute_value.get(attr) print("O attribute_value é: ", attribute_value) if attribute_value is None: raise KeyError (f"Attribute path {attribute_path} not found in widget data") return attribute_value else: response.raise_for_status()
[docs] def deploy( self, fp, rotation=0, **kwargs ): if hasattr(fp, 'getvalue'): content = fp.getvalue() elif isinstance(fp, (str, bytes, os.PathLike)): with open(fp, 'rb') as file: content = file.read() else: raise TypeError("fp must be a file-like object or a file path") self.calc_position(self.last_widget_id) files_dict = dict( resource=( f"{inflection.underscore(self.image_title)}.svg", content, "image/svg", ), data=( None, json.dumps( { "title": self.image_title, "position": { "x": self.image_x_position, "y": self.image_y_position, }, "geometry": { "width": self.image_width, "rotation": rotation, }, "parent": { "id": self.parent_id, }, } ), "application/json", ), ) files_list = [(key, value) for key, value in files_dict.items()] headers = {"Authorization": f"Bearer {self.oauth_token}"} url = f"https://api.miro.com/v2/boards/{self.board_id}/images" response = requests.post(url, headers=headers, data={}, files=files_list) if response.status_code == 201: self.deployment_counter += 1 self.last_widget_id = response.json()["id"] else: response.raise_for_status()