diff --git a/BeginerGuide/Loop/data/label_temp.docx b/BeginerGuide/Loop/data/label_temp.docx new file mode 100644 index 0000000..9add900 Binary files /dev/null and b/BeginerGuide/Loop/data/label_temp.docx differ diff --git a/BeginerGuide/Loop/data/loop_template.docx b/BeginerGuide/Loop/data/loop_template.docx new file mode 100644 index 0000000..21f0496 Binary files /dev/null and b/BeginerGuide/Loop/data/loop_template.docx differ diff --git a/BeginerGuide/Loop/data/shhet_temp.xlsx b/BeginerGuide/Loop/data/shhet_temp.xlsx new file mode 100644 index 0000000..efe0e56 Binary files /dev/null and b/BeginerGuide/Loop/data/shhet_temp.xlsx differ diff --git a/BeginerGuide/Loop/data/slide_temp.pptx b/BeginerGuide/Loop/data/slide_temp.pptx new file mode 100644 index 0000000..b0ed231 Binary files /dev/null and b/BeginerGuide/Loop/data/slide_temp.pptx differ diff --git a/BeginerGuide/Loop/data/tem.docx b/BeginerGuide/Loop/data/tem.docx new file mode 100644 index 0000000..4feef75 Binary files /dev/null and b/BeginerGuide/Loop/data/tem.docx differ diff --git a/BeginerGuide/Loop/data/un_loop.docx b/BeginerGuide/Loop/data/un_loop.docx new file mode 100644 index 0000000..0a04ee8 Binary files /dev/null and b/BeginerGuide/Loop/data/un_loop.docx differ diff --git a/BeginerGuide/Loop/merge_loop.py b/BeginerGuide/Loop/merge_loop.py new file mode 100644 index 0000000..1b9d6fd --- /dev/null +++ b/BeginerGuide/Loop/merge_loop.py @@ -0,0 +1,63 @@ +import sys +sys.path.insert(0, "PATH_TO_COP_DIR") +import cloudofficeprint as cop + + +data = cop.elements.ElementCollection("data") + +eng_emp1 = cop.elements.ElementCollection.from_mapping({ + "name": "John Smith", + "project": "Website Redesign", + "status": "In Progress" +}) + +eng_emp2 = cop.elements.ElementCollection.from_mapping({ + "name": "Emily Johnson", + "project": "API Development", + "status": "Completed" +}) + +eng_emp3 = cop.elements.ElementCollection.from_mapping({ + "name": "Michael Brown", + "project": "Mobile App", + "status": "Planning" +}) + +mkt_emp1 = cop.elements.ElementCollection.from_mapping({ + "name": "Sarah Wilson", + "project": "Brand Campaign", + "status": "In Progress" +}) + +mkt_emp2 = cop.elements.ElementCollection.from_mapping({ + "name": "David Thompson", + "project": "Market Research", + "status": "Not Started" +}) + +engineering_dept = cop.elements.ElementCollection.from_mapping({ + "department": "Engineering" +}) +engineering_dept.add(cop.elements.ForEachMergeCells("employees", [eng_emp1, eng_emp2, eng_emp3])) + +marketing_dept = cop.elements.ElementCollection.from_mapping({ + "department": "Marketing" +}) +marketing_dept.add(cop.elements.ForEachMergeCells("employees", [mkt_emp1, mkt_emp2])) + +departments = cop.elements.ForEachMergeCells("departments", [engineering_dept, marketing_dept]) + +data.add(departments) + +server = cop.config.Server( + "http://localhost:8010/" +) +# Create print job +# PrintJob combines template, data, server and an optional output configuration +printjob = cop.PrintJob( + data=data, + server=server, + template=cop.Resource.from_local_file("./data/tem.docx"), +) +response = printjob.execute() +response.to_file("./output/output.docx") \ No newline at end of file diff --git a/BeginerGuide/Loop/output/label_output.docx b/BeginerGuide/Loop/output/label_output.docx new file mode 100644 index 0000000..80be25b Binary files /dev/null and b/BeginerGuide/Loop/output/label_output.docx differ diff --git a/BeginerGuide/Loop/output/output.docx b/BeginerGuide/Loop/output/output.docx new file mode 100644 index 0000000..445025e Binary files /dev/null and b/BeginerGuide/Loop/output/output.docx differ diff --git a/BeginerGuide/Loop/output/output.pptx b/BeginerGuide/Loop/output/output.pptx new file mode 100644 index 0000000..d3770dc Binary files /dev/null and b/BeginerGuide/Loop/output/output.pptx differ diff --git a/BeginerGuide/Loop/output/output_loop.docx b/BeginerGuide/Loop/output/output_loop.docx new file mode 100644 index 0000000..7e4bc57 Binary files /dev/null and b/BeginerGuide/Loop/output/output_loop.docx differ diff --git a/BeginerGuide/Loop/output/sheet_output.xlsx b/BeginerGuide/Loop/output/sheet_output.xlsx new file mode 100644 index 0000000..45d2150 Binary files /dev/null and b/BeginerGuide/Loop/output/sheet_output.xlsx differ diff --git a/BeginerGuide/Loop/output/uncertain_loop.docx b/BeginerGuide/Loop/output/uncertain_loop.docx new file mode 100644 index 0000000..7905c8a Binary files /dev/null and b/BeginerGuide/Loop/output/uncertain_loop.docx differ diff --git a/BeginerGuide/Loop/usingLabel.py b/BeginerGuide/Loop/usingLabel.py new file mode 100644 index 0000000..ee01c93 --- /dev/null +++ b/BeginerGuide/Loop/usingLabel.py @@ -0,0 +1,65 @@ +import sys +sys.path.insert(0,"PATH_TO_COP_DIR") +import cloudofficeprint as cop + +# Create main collection +collection = cop.elements.ElementCollection() + +# Create elements for the labels +element1 = cop.elements.ElementCollection.from_mapping( + { + "FirstName": "John", + "LastName": "Smith", + "Company": "Tech Solutions Inc.", + "Address1": "123 Business Ave", + "City": "San Francisco", + "State": "CA", + "PostalCode": "94105" + } +) +element2 = cop.elements.ElementCollection.from_mapping( + { + "FirstName": "Sarah", + "LastName": "Johnson", + "Company": "Marketing Pro LLC", + "Address1": "456 Market Street", + "City": "New York", + "State": "NY", + "PostalCode": "10013" + } +) +element3 = cop.elements.ElementCollection.from_mapping( + { + "FirstName": "Michael", + "LastName": "Brown", + "Company": "Digital Services Co.", + "Address1": "789 Innovation Blvd", + "City": "Chicago", + "State": "IL", + "PostalCode": "60601" + } +) + +loopLabel = cop.elements.loops.Labels( + name="labels", + content=[element1, element2, element3] +) +# Add the loop to the main collection +collection.add(loopLabel) + +# Server +server = cop.config.Server( + "http://localhost:8010/", + cop.config.ServerConfig(api_key="YOUR_API_KEY") +) + +# Create print job +printjob = cop.PrintJob( + data=collection, + server=server, + template=cop.Resource.from_local_file("./data/label_temp.docx") +) + +# Execute and save the output +response = printjob.execute() +response.to_file("./output/label_output.docx") \ No newline at end of file diff --git a/BeginerGuide/Loop/usingLoop.py b/BeginerGuide/Loop/usingLoop.py new file mode 100644 index 0000000..185e1e1 --- /dev/null +++ b/BeginerGuide/Loop/usingLoop.py @@ -0,0 +1,55 @@ +import sys +sys.path.insert(0,"PATH_TO_COP_DIR") +import cloudofficeprint as cop + +# Create main collection +collection = cop.elements.ElementCollection() + +# Create elements for the loop +element1 = cop.elements.ElementCollection.from_mapping( + { + "a": 1, + "b": 2, + "c": 3 + } +) + +element2 = cop.elements.ElementCollection.from_mapping( + { + "a": 4, + "b": 5, + "c": 6 + } +) + +# Create loop +loop = cop.elements.loops.ForEachInline( + name="loop_name", + content=[element1, element2] +) + +# Add loop to collection +collection.add(loop) + +# Server configuration +server = cop.config.Server( + "http://localhost:8010/", + cop.config.ServerConfig(api_key="YOUR_API_KEY") +) + +# Create print job with output type specified +# For running on localhost you do not need api_key else replace below "YOUR_API_KEY" with your api key. +server = cop.config.Server( + "http://localhost:8010/", + cop.config.ServerConfig(api_key = "YOUR_API_KEY") +) +# Create print job +# PrintJob combines template, data, server and an optional output configuration +printjob = cop.PrintJob( + data=collection, + server=server, + template=cop.Resource.from_local_file("./data/loop_template.docx"), +) +# Execute and save +response = printjob.execute() +response.to_file("./output/output_loop.docx") \ No newline at end of file diff --git a/BeginerGuide/Loop/usingSheetLoop.py b/BeginerGuide/Loop/usingSheetLoop.py new file mode 100644 index 0000000..51e5da4 --- /dev/null +++ b/BeginerGuide/Loop/usingSheetLoop.py @@ -0,0 +1,68 @@ +import sys +sys.path.insert(0,"PATH_TO_COP_DIR") +import cloudofficeprint as cop + +# Create main collection +collection = cop.elements.ElementCollection() + +# Create elements for customer invoices +element1 = cop.elements.ElementCollection.from_mapping( + { + "cust_first_name": "John", + "cust_last_name": "Smith", + "orders": [ + {"order_name": "Office Supplies", "order_total": "$525.00"}, + {"order_name": "Electronics", "order_total": "$1,299.99"}, + {"order_name": "Furniture", "order_total": "$2,450.00"} + ] + } +) + +element2 = cop.elements.ElementCollection.from_mapping( + { + "cust_first_name": "Sarah", + "cust_last_name": "Johnson", + "orders": [ + {"order_name": "Software License", "order_total": "$899.00"}, + {"order_name": "IT Support", "order_total": "$750.00"} + ] + } +) + +element3 = cop.elements.ElementCollection.from_mapping( + { + "cust_first_name": "Michael", + "cust_last_name": "Brown", + "orders": [ + {"order_name": "Marketing Services", "order_total": "$3,500.00"}, + {"order_name": "Training Materials", "order_total": "$450.00"}, + {"order_name": "Cloud Storage", "order_total": "$199.99"} + ] + } +) + +# Create sheet loop +loop = cop.elements.loops.ForEachSheet( + name="customers", + content=[element1, element2, element3] +) + +# Add loop to collection +collection.add(loop) + +# Server configuration +server = cop.config.Server( + "http://localhost:8010/", + cop.config.ServerConfig(api_key="YOUR_API_KEY") +) + +# Create print job +printjob = cop.PrintJob( + data=collection, + server=server, + template=cop.Resource.from_local_file("./data/shhet_temp.xlsx") +) + +# Execute and save +response = printjob.execute() +response.to_file("./output/sheet_output.xlsx") \ No newline at end of file diff --git a/BeginerGuide/Loop/usingSlideLoop.py b/BeginerGuide/Loop/usingSlideLoop.py new file mode 100644 index 0000000..8830f22 --- /dev/null +++ b/BeginerGuide/Loop/usingSlideLoop.py @@ -0,0 +1,61 @@ +import sys +sys.path.insert(0,"PATH_TO_COP_DIR") +import cloudofficeprint as cop + +# Create main collection +collection = cop.elements.ElementCollection() + +# Create elements for the loop +element1 = cop.elements.ElementCollection.from_mapping( + { + "a": "Sales Report Q1", + "b": "Total Revenue: $125,000", + "c": "Growth: 15% YoY" + } +) +element2 = cop.elements.ElementCollection.from_mapping( + { + "a": "Marketing Metrics Q1", + "b": "New Customers: 2,500", + "c": "Campaign ROI: 225%" + } +) +element3 = cop.elements.ElementCollection.from_mapping( + { + "a": "Product Performance Q1", + "b": "Units Sold: 45,000", + "c": "Customer Satisfaction: 4.8/5" + } +) +element4 = cop.elements.ElementCollection.from_mapping( + { + "a": "Support Analytics Q1", + "b": "Tickets Resolved: 3,200", + "c": "Average Response Time: 2.5h" + } +) + +#slide loop +loop = cop.elements.loops.ForEachSlide( + name="slideloop", + content=[element1, element2, element3, element4] +) +# Add the loop to the main collection +collection.add(loop) + +# Server +server = cop.config.Server( + "http://localhost:8010/", + cop.config.ServerConfig(api_key="YOUR_API_KEY") +) + +# Create print job +printjob = cop.PrintJob( + data=collection, + server=server, + template=cop.Resource.from_local_file("./Loop/data/slide_temp.pptx") +) + +# Execute and save the output +response = printjob.execute() +response.to_file("./Loop/output/output") \ No newline at end of file diff --git a/BeginerGuide/Loop/usingUncertainLoop.py b/BeginerGuide/Loop/usingUncertainLoop.py new file mode 100644 index 0000000..1572340 --- /dev/null +++ b/BeginerGuide/Loop/usingUncertainLoop.py @@ -0,0 +1,49 @@ +import sys +sys.path.insert(0,"PATH_TO_COP_DIR") +import cloudofficeprint as cop + +# Create main collection +collection = cop.elements.ElementCollection() + +# Create products data +products = [ + {"prod_name": "Business Shirt", "category": "Mens"}, + {"prod_name": "Trousers", "category": "Mens"}, + {"prod_name": "Jacket", "category": "Mens"}, + {"prod_name": "Blouse", "category": "Womens"}, + {"prod_name": "Skirt", "category": "Womens"}, + {"prod_name": "Ladies Shoes", "category": "Womens"}, + {"prod_name": "Belt", "category": "Accessories"}, + {"prod_name": "Bag", "category": "Accessories"}, + {"prod_name": "Mens Shoes", "category": "Mens"}, + {"prod_name": "Wallet", "category": "Accessories"} +] + +#elements for each product item +product_elements = [] +for product in products: + element_collection = cop.elements.ElementCollection() + element_collection.add(cop.elements.Property("prod_name", product["prod_name"])) + element_collection.add(cop.elements.Property("category", product["category"])) + product_elements.append(element_collection) + +#ForEach loop +collection.add(cop.elements.ForEach(name="products", content=product_elements)) + +# Server configuration +server = cop.config.Server( + "http://localhost:8010/", + cop.config.ServerConfig(api_key="YOUR_API_KEY") +) + +# Create print job +template = cop.Resource.from_local_file("./data/un_loop.docx") +printjob = cop.PrintJob( + data=collection, + server=server, + template=template +) + +# Execute and save +response = printjob.execute() +response.to_file("./output/uncertain_loop.docx") \ No newline at end of file diff --git a/BeginerGuide/Transformation/data/template.docx b/BeginerGuide/Transformation/data/template.docx new file mode 100644 index 0000000..010f3ec Binary files /dev/null and b/BeginerGuide/Transformation/data/template.docx differ diff --git a/BeginerGuide/Transformation/output/output.pdf b/BeginerGuide/Transformation/output/output.pdf new file mode 100644 index 0000000..9578fb3 Binary files /dev/null and b/BeginerGuide/Transformation/output/output.pdf differ diff --git a/BeginerGuide/Transformation/usingTransformation.py b/BeginerGuide/Transformation/usingTransformation.py new file mode 100644 index 0000000..325c3f9 --- /dev/null +++ b/BeginerGuide/Transformation/usingTransformation.py @@ -0,0 +1,127 @@ +import sys +sys.path.insert(0,"PATH_TO_COP_DIR") +import cloudofficeprint as cop + +# Create main data structure representing the files array +files = cop.elements.ElementCollection(name="files") + +# Create a file entry +file_entry = cop.elements.ElementCollection() +file_entry.add(cop.elements.Property("filename", "file1")) + +# Add customer data +data_array = cop.elements.ElementCollection() +customer = cop.elements.Property( + name='cust_first_name', + value='John' +) +customer_last_name = cop.elements.Property( + name='cust_last_name', + value='Dullas' +) + +data_array.add(customer) +data_array.add(customer_last_name) + +# Product data +product1 = cop.elements.ElementCollection.from_mapping({ + "product_name": "Buisness Shirt", + "unit_price": 50, + "quantity": 3, + "category": "Mens" +}) + +product2 = cop.elements.ElementCollection.from_mapping({ + "product_name": "Trousers", + "unit_price": 80, + "quantity": 3, + "category": "Mens" +}) + +product3 = cop.elements.ElementCollection.from_mapping({ + "product_name": "Jacket", + "unit_price": 150, + "quantity": 3, + "category": "Mens" +}) +product4 = cop.elements.ElementCollection.from_mapping({ + "product_name": "Blouse", + "unit_price": 60, + "quantity": 3, + "category": "Womens" +}) +product5 = cop.elements.ElementCollection.from_mapping({ + "product_name": "Skirt", + "unit_price": 80, + "quantity": 3, + "category": "Womens" +}) +product6 = cop.elements.ElementCollection.from_mapping({ + "product_name": "Ladies Shoes", + "unit_price": 120, + "quantity": 2, + "category": "Womens" +}) +product7 = cop.elements.ElementCollection.from_mapping({ + "product_name": "Belt", + "unit_price": 50, + "quantity": 2, + "category": "Accessories" +}) +product8 = cop.elements.ElementCollection.from_mapping({ + "product_name": "Bag", + "unit_price": 50, + "quantity": 2, + "category": "Accessories" +}) +product9 = cop.elements.ElementCollection.from_mapping({ + "product_name": "Mens Shoes", + "unit_price": 110, + "quantity": 2, + "category": "Mens" +}) +product10 = cop.elements.ElementCollection.from_mapping({ + "product_name": "Wallet", + "unit_price": 50, + "quantity": 2, + "category": "Accessories" +}) + +product = cop.elements.ForEach("product", [product1, product2, product3, product4, product5, product6, product7, product8, product9, product10]) +data_array.add(product) + +# Create main data object +main_data = cop.elements.ElementCollection() +main_data.add(cop.elements.Property("data", data_array)) +data = main_data.as_dict + +# Transformation function +js_code ="function generateProductRows(products, category) {\r\n return products\r\n .filter(product => product.category === category)\r\n .map(product => {\r\n if (category === \"Mens\") {\r\n product.category_bold = \"true\";\r\n product.product_name_font_color = \"blue\";\r\n } else {\r\n product.category_italic = \"true\";\r\n product.product_name_font_color = \"red\";\r\n }\r\n const totalCost = product.unit_price * product.quantity;\r\n return `\r\n \r\n ${product.product_name}\r\n ${product.unit_price}\r\n ${product.quantity}\r\n ${totalCost}\r\n \r\n `;\r\n })\r\n .join('');\r\n}\r\n\r\nfunction transform() {\r\n files.forEach(file => {\r\n let data = file.data;\r\n // Initialize HTML strings for mens_products and womens_products\r\n let mensProductsHtml = '';\r\n let womensProductsHtml = '
';\r\n\r\n // Add table headers\r\n const tableHeaders = `\r\n \r\n \r\n \r\n \r\n \r\n \r\n `;\r\n mensProductsHtml += tableHeaders;\r\n womensProductsHtml += tableHeaders;\r\n\r\n // Generate HTML rows for mens and womens products\r\n const mensProductsRows = generateProductRows(data.product, \"Mens\");\r\n const womensProductsRows = generateProductRows(data.product, \"Womens\");\r\n\r\n // Calculate totals using reduce\r\n const mensTotals = data.product\r\n .filter(product => product.category === \"Mens\")\r\n .reduce((totals, product) => {\r\n totals.quantity += product.quantity;\r\n totals.cost += product.unit_price * product.quantity;\r\n return totals;\r\n }, { quantity: 0, cost: 0 });\r\n\r\n const womensTotals = data.product\r\n .filter(product => product.category === \"Womens\")\r\n .reduce((totals, product) => {\r\n totals.quantity += product.quantity;\r\n totals.cost += product.unit_price * product.quantity;\r\n return totals;\r\n }, { quantity: 0, cost: 0 });\r\n\r\n // Close the HTML tables\r\n mensProductsHtml += mensProductsRows + '
Product NameUnit PriceQuantityTotal Cost
';\r\n womensProductsHtml += womensProductsRows + '';\r\n\r\n // Add the new entries to the data object\r\n data.mens_products = mensProductsHtml;\r\n data.womens_products = womensProductsHtml;\r\n data.mens_total_quantity = mensTotals.quantity;\r\n data.mens_total_cost = mensTotals.cost;\r\n data.womens_total_quantity = womensTotals.quantity;\r\n data.womens_total_cost = womensTotals.cost;\r\n });\r\n return files;\r\n}\r\n" +# Transformation objeect +transformation_function = cop.TransformationFunction(js_code) + +# transformation_function = cop.TransformationFunction("sample_transform.js") + +# Configure the Server +server = cop.config.Server( + url="http://localhost:8010/", + config=cop.config.ServerConfig(api_key="YOUR_API_KEY") +) + +template = cop.Resource.from_local_file( + "./data/template.docx" +) +output_conf = cop.config.OutputConfig(filetype="pdf") + +# Create print job +printjob = cop.PrintJob( + data=data, + server=server, + template=template, + output_config=output_conf, + transformation_function=transformation_function +) + +response = printjob.execute() +response.to_file( + "./output/output.pdf") \ No newline at end of file diff --git a/BeginerGuide/UsingCharts/data/template.docx b/BeginerGuide/UsingCharts/data/template.docx index 6e86888..6eae444 100644 Binary files a/BeginerGuide/UsingCharts/data/template.docx and b/BeginerGuide/UsingCharts/data/template.docx differ diff --git a/BeginerGuide/UsingCharts/usingChart.py b/BeginerGuide/UsingCharts/usingChart.py index 5753544..124cca0 100644 --- a/BeginerGuide/UsingCharts/usingChart.py +++ b/BeginerGuide/UsingCharts/usingChart.py @@ -5,213 +5,266 @@ # ---------------line_chart line1 = cop.elements.LineSeries( - x=('a', 'b', 'c'), - y=(1, 2, 3), - name='line1', - smooth=True, - symbol='diamond', - symbol_size=10, - color='red', - line_width='0.2cm', - line_style='sysDashDotDot' + ('a', 'b', 'c'), + (1, 2, 3), + 'line1', + True, + 'diamond', + 10, + 'red', + '0.2cm', + 'sysDashDotDot' ) line2 = cop.elements.LineSeries( - x=('a', 'b', 'c'), - y=(4, 5, 6), - name='line2', - smooth=True, - symbol='square', - symbol_size=12, - color='blue', - line_width='2px', - line_style='sysDash' + ('a', 'b', 'c'), + (4, 5, 6), + 'line2', + True, + 'square', + 12, + 'blue', + '2px', + 'sysDash' ) + +# To make line stacked chart you can simply use cop.elements.LineStackedChart line_chart = cop.elements.LineChart( - name='line_chart_name', - lines=(line1, line2) + 'line_chart_name', + (line1, line2) ) collection.add(line_chart) # --------------------bar_chart----------- bars1 = cop.elements.BarSeries( - x=('a', 'b', 'c'), - y=(1, 2, 3), - name='bars1', - color='red' + ('a', 'b', 'c'), + (1, 2, 3), + 'bars1', + 'red' ) bars2 = cop.elements.BarSeries( - x=('a', 'b', 'c'), - y=(4, 5, 6), - name='bars2', - color='blue' + ('a', 'b', 'c'), + (4, 5, 6), + 'bars2', + 'blue' ) bar_chart = cop.elements.BarChart( - name='bar_chart_name', - bars=(bars1, bars2) + 'bar_chart_name', + (bars1, bars2) ) collection.add(bar_chart) # -------------pie_chart---------- pies1 = cop.elements.PieSeries( - x=('a', 'b', 'c'), - y=(1, 2, 3), - name='pies1', - colors=('red', None, 'blue') + ('a', 'b', 'c'), + (1, 2, 3), + 'pies1', + ('red', None, 'blue') ) pies2 = cop.elements.PieSeries( - x=('a', 'b', 'c'), - y=(4, 5, 6), - name='pies2', - colors=('green', 'blue', None) + ('a', 'b', 'c'), + (4, 5, 6), + 'pies2', + ('green', 'blue', None) ) pies_chart = cop.elements.PieChart( - name='pie_chart_name', - pies=(pies1, pies2) + 'pie_chart_name', + (pies1, pies2) ) collection.add(pies_chart) # ---------------area_chart------------ area1 = cop.elements.AreaSeries( - x=('a', 'b', 'c'), - y=(1, 2, 3), - name='area1', - color='red', - opacity=50 + ('a', 'b', 'c'), + (1, 2, 3), + 'area1', + 'red', + 50 ) area2 = cop.elements.AreaSeries( - x=('a', 'b', 'c'), - y=(4, 5, 6), - name='area2', - color='blue', - opacity=80 + ('a', 'b', 'c'), + (4, 5, 6), + 'area2', + 'blue', + 80 ) area_chart = cop.elements.AreaChart( - name='area_chart_name', - areas=(area1, area2) + 'area_chart_name', + (area1, area2) ) collection.add(area_chart) # -----------------bubble_chart---------- bubble1 = cop.elements.BubbleSeries( - x=('a', 'b', 'c'), - y=(1, 2, 3), - sizes=(5, 6, 2), - name='bubble1', - color='red' + ('a', 'b', 'c'), + (1, 2, 3), + (5, 6, 2), + 'bubble1', + 'red' ) bubble2 = cop.elements.BubbleSeries( - x=('a', 'b', 'c'), - y=(4, 5, 6), - sizes=(5, 6, 2), - name='bubble2', - color='blue' + ('a', 'b', 'c'), + (4, 5, 6), + (5, 6, 2), + 'bubble2', + 'blue' ) bubble_chart = cop.elements.BubbleChart( - name='bubble_chart_name', - bubbles=(bubble1, bubble2) + 'bubble_chart_name', + (bubble1, bubble2) ) collection.add(bubble_chart) # ---------------stock_chart stock1 = cop.elements.StockSeries( - x=(1, 2, 3), - high=(4, 5, 6), - low=(7, 8, 9), - close=(10, 11, 12), - open_=(13, 14, 15), - volume=(16, 17, 18), - name='stock1' + (1, 2, 3), + (4, 5, 6), + (7, 8, 9), + (10, 11, 12), + (13, 14, 15), + (16, 17, 18), + 'stock1' ) stock2 = cop.elements.StockSeries( - x=(1, 2, 3), - high=(4, 5, 6), - low=(7, 8, 9), - close=(10, 11, 12), - open_=(13, 14, 15), - volume=(16, 17, 18), - name='stock2' + (1, 2, 3), + (4, 5, 6), + (7, 8, 9), + (10, 11, 12), + (13, 14, 15), + (16, 17, 18), + 'stock2' ) stock_chart = cop.elements.StockChart( - name='stock_chart_name', - stocks=(stock1, stock2) + 'stock_chart_name', + (stock1, stock2) ) # collection.add(stock_chart) # ----------------combined_chart------- axis = cop.elements.ChartAxisOptions() column1 = cop.elements.ColumnSeries( - x=('a', 'b', 'c'), - y=(1, 2, 3), - name='column1' + ('a', 'b', 'c'), + (1, 2, 3), + 'column1' ) column2 = cop.elements.ColumnSeries( - x=('a', 'b', 'c'), - y=(4, 5, 6), - name='column2' + ('a', 'b', 'c'), + (4, 5, 6), + 'column2' ) column_chart = cop.elements.ColumnChart( - name='column_chart', - columns=(column1, column2) + 'column_chart', + (column1, column2) ) line1 = cop.elements.LineSeries( - x=('a', 'b', 'c'), - y=(1, 2, 3), - name='line1', - symbol='square' + ('a', 'b', 'c'), + (1, 2, 3), + 'line1', + 'square' ) line2 = cop.elements.LineSeries( - x=('a', 'b', 'c'), - y=(4, 5, 6), - name='line2', - symbol='square' + ('a', 'b', 'c'), + (4, 5, 6), + 'line2', + 'square' ) line_chart_options = cop.elements.ChartOptions( - x_axis=axis, - y_axis=axis, - width=50, - background_color='gray', - background_opacity=50 + axis, + axis, + 50, + 'gray', + 50 ) line_chart = cop.elements.LineChart( - name='line_chart', - lines=(line1, line2), - options=line_chart_options + 'line_chart', + (line1, line2), + line_chart_options ) bar1 = cop.elements.BarSeries( - x=('a', 'b', 'c'), - y=(1, 2, 3), - name='bar1' + ('a', 'b', 'c'), + (1, 2, 3), + 'bar1' ) bar2 = cop.elements.BarSeries( - x=('a', 'b', 'c'), - y=(4, 5, 6), - name='bar2' + ('a', 'b', 'c'), + (4, 5, 6), + 'bar2' ) bar_chart_options = cop.elements.ChartOptions( - x_axis=axis, - y_axis=axis, - width=100, + axis, + axis, + 100, height=100, rounded_corners=False ) bar_chart = cop.elements.BarChart( - name='bar_chart', - bars=(bar1, bar2), - options=bar_chart_options + 'bar_chart', + (bar1, bar2), + bar_chart_options ) combined_chart = cop.elements.CombinedChart( - name='combined_chart_name', - charts=(column_chart, line_chart), - secondaryCharts=(bar_chart,) + 'combined_chart_name', + (column_chart, line_chart), + (bar_chart,) +) +# collection.add(combined_chart) +# ---------------line_stacked_chart +line_stacked1 = cop.elements.LineStackedSeries( + ('Jan', 'Feb', 'Mar', 'Apr'), + (10, 25, 15, 30), + 'Sales 2023', + True, + 'diamond', + 10, + 'red', + '0.2cm', + 'sysDashDotDot' +) +line_stacked2 = cop.elements.LineStackedSeries( + ('Jan', 'Feb', 'Mar', 'Apr'), + (20, 15, 35, 25), + 'Sales 2024', + True, + 'square', + 12, + 'blue', + '2px', + 'sysDash' +) + +line_stacked_chart = cop.elements.LineStackedChart( + 'line_stacked_chart_name', + (line_stacked1, line_stacked2) +) + +collection.add(line_stacked_chart) + +# ---------------area_stacked_chart------------ +area1 = cop.elements.AreaSeries( + ('Q1', 'Q2', 'Q3', 'Q4'), + (45, 60, 75, 90), + 'Revenue 2023', + 'green', + 50 +) +area2 = cop.elements.AreaSeries( + ('Q1', 'Q2', 'Q3', 'Q4'), + (55, 70, 85, 100), + 'Revenue 2024', + 'purple', + 80 +) +area_stacked_chart = cop.elements.AreaStackedChart( + 'area_stacked_chart_name', + (area1, area2) ) -collection.add(combined_chart) +collection.add(area_stacked_chart) # configure server # For running on localhost you do not need api_key else replace below "YOUR_API_KEY" with your api key. server = cop.config.Server( "http://localhost:8010/", - cop.config.ServerConfig(api_key="YOUR_API_KEY") + cop.config.ServerConfig("YOUR_API_KEY") ) # Create print job # PrintJob combines template, data, server and an optional output configuration diff --git a/BeginerGuide/UsingDistribute/UsingDistribute.py b/BeginerGuide/UsingDistribute/UsingDistribute.py new file mode 100644 index 0000000..fa6a21b --- /dev/null +++ b/BeginerGuide/UsingDistribute/UsingDistribute.py @@ -0,0 +1,92 @@ +import sys +sys.path.insert(0,"PATH_TO_COP_DIR") +import cloudofficeprint as cop + +# Main data collection +collection = cop.elements.ElementCollection() + +#products +product_a = [ + {"product_name": "Business Shirt", "price": 50, "category": "Mens"}, + {"product_name": "Trousers", "price": 80, "category": "Mens"}, + {"product_name": "Jacket", "price": 150, "category": "Mens"}, + {"product_name": "Blouse", "price": 60, "category": "Womens"} +] +product_b = [ + {"product_name": "Ladies Shoes", "price": 120, "category": "Womens"}, + {"product_name": "Belt", "price": 30, "category": "Accessories"}, + {"product_name": "Bag", "price": 125, "category": "Accessories"}, + {"product_name": "Mens Shoes", "price": 110, "category": "Mens"} +] + + +product_a_elems = [cop.elements.ElementCollection.from_mapping(p) for p in product_a] +product_b_elems = [cop.elements.ElementCollection.from_mapping(p) for p in product_b] + +collection.add(cop.elements.loops.ForEachInline("product_a", product_a_elems)) +collection.add(cop.elements.loops.ForEachInline("product_b", product_b_elems, distribute=True)) + +# orderdata +orders = [ + { + "order_name": "Order 1", + "order_total": 2380, + "product": [ + {"product_name": "Business Shirt", "quantity": 3, "unit_price": 50}, + {"product_name": "Trousers", "quantity": 3, "unit_price": 80}, + {"product_name": "Jacket", "quantity": 3, "unit_price": 150}, + {"product_name": "Blouse", "quantity": 3, "unit_price": 60} + ] + }, + { + "order_name": "Order 2", + "order_total": 1640, + "product": [ + {"product_name": "Blouse", "quantity": 4, "unit_price": 60}, + {"product_name": "Skirt", "quantity": 4, "unit_price": 80}, + {"product_name": "Ladies Shoes", "quantity": 4, "unit_price": 120}, + {"product_name": "Bag", "quantity": 4, "unit_price": 125} + ] + }, + { + "order_name": "Order 3", + "order_total": 730, + "product": [ + {"product_name": "Blouse", "quantity": 4, "unit_price": 60}, + {"product_name": "Skirt", "quantity": 3, "unit_price": 80}, + {"product_name": "Bag", "quantity": 2, "unit_price": 125} + ] + } +] +order_elements = [] +for order in orders: + order_col = cop.elements.ElementCollection() + order_col.add(cop.elements.Property("order_name", order["order_name"])) + order_col.add(cop.elements.Property("order_total", order["order_total"])) + + order_product_elements = [ + cop.elements.ElementCollection.from_mapping(p) for p in order["product"] + ] + + order_col.add(cop.elements.loops.ForEachInline("product", order_product_elements)) + order_elements.append(order_col) + +collection.add(cop.elements.loops.ForEachInline("orders", order_elements)) + +server = cop.config.Server( + "http://localhost:8010/", + config=cop.config.ServerConfig(api_key="YOUR_API_KEY") +) + +print_job = cop.PrintJob( + data=collection, + server=server, + template=cop.Resource.from_local_file( + "./data/template.docx" + ) +) + +response = print_job.execute() +response.to_file( + "./output/output.docx" +) \ No newline at end of file diff --git a/BeginerGuide/UsingDistribute/data/template.docx b/BeginerGuide/UsingDistribute/data/template.docx new file mode 100644 index 0000000..31734b2 Binary files /dev/null and b/BeginerGuide/UsingDistribute/data/template.docx differ diff --git a/BeginerGuide/UsingDistribute/output/output.docx b/BeginerGuide/UsingDistribute/output/output.docx new file mode 100644 index 0000000..f21d3e1 Binary files /dev/null and b/BeginerGuide/UsingDistribute/output/output.docx differ diff --git a/BeginerGuide/UsingElements/data/template.docx b/BeginerGuide/UsingElements/data/template.docx index 12db90c..e7d75b8 100644 Binary files a/BeginerGuide/UsingElements/data/template.docx and b/BeginerGuide/UsingElements/data/template.docx differ diff --git a/BeginerGuide/UsingElements/output/output.docx b/BeginerGuide/UsingElements/output/output.docx index dba7ec0..2f9f8a3 100644 Binary files a/BeginerGuide/UsingElements/output/output.docx and b/BeginerGuide/UsingElements/output/output.docx differ diff --git a/BeginerGuide/UsingElements/using_elements.py b/BeginerGuide/UsingElements/using_elements.py index 91dfb6c..74bf918 100644 --- a/BeginerGuide/UsingElements/using_elements.py +++ b/BeginerGuide/UsingElements/using_elements.py @@ -1,6 +1,9 @@ # Install cloudofficeprint using pip install cloudofficeprint #Import the cloudofficeprint libary. -from ... import cloudofficeprint as cop +import sys +sys.path.insert(0, "PATH_TO_COP_DIR") +import cloudofficeprint as cop + # Main object that holds the data collection = cop.elements.ElementCollection() # Create the title element and add it to the element collection @@ -42,6 +45,31 @@ ) collection.add(styled_prop) +docx_column1_cell_style = cop.elements.CellStyleDocx( + cell_background_color='red', + border_color='0d72c7', + border_top='double' + ) +docx_column1_table_style_property = cop.elements.CellStyleProperty( + name='column1', + value='DemoCustomerName', + cell_style=docx_column1_cell_style + ) +collection.add(docx_column1_table_style_property) + +docx_column2_cell_style = cop.elements.CellStyleDocx( + border_diagonal_down='single', + border_diagonal_down_size=10, + border_diagonal_up='single', + border_diagonal_up_color='#0d72c7' + ) +docx_column2_table_style_property = cop.elements.CellStyleProperty( + name='column2', + value='DemoCustomerName', + cell_style=docx_column2_cell_style + ) +collection.add(docx_column2_table_style_property) + # ------------------watermark---------- watermark = cop.elements.Watermark( name='watermark_name', @@ -54,6 +82,32 @@ rotation=45 ) collection.add(watermark) +# Insert tag for Word files +insert1 = cop.elements.Insert( + name="fileToInsert1", + value="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" +) +collection.add(insert1) + +# Another insert example for pptx files... +insert2 = cop.elements.Insert( + name="fileToInsert2", + value="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MTQ5IDIwLjgzOSAwIDE5LjM2IDAgMTQuMjU4IDAgOS4yNTggMi4xMzIgNS43ODkgNS44MDIgMi4yNjkgOS41MjEgMC41MzUgMTQuMzggMC45NDMgMTkuNDg4IDEuNzA4IDI4LjcxMSA5LjgyIDM2IDE5LjM2IDM2TDI3Ljk4MiAzNkMzMi42MjQgMzYgMzcuMTE0IDM0LjMxNCA0MC41MzIgMzEuMjQgNDMuOTUgMjguMTY1IDQ2LjA5MyAyNCA0Ni40NSAxOS40ODggNDYuODU4IDE0LjM4IDQ1LjE3NSA5LjUyMSA0MS42MDMgNS44MDJaTTIzLjY5NiAzLjAyNUMzMC41ODQgNC45MDkgMzUuMzc5IDExLjAwOCAzNS4zNzkgMTggMzUuMzc5IDI0Ljk0MiAzMC41ODQgMzEuMDkxIDIzLjY5NiAzMi45MjYgMTYuODA5IDMxLjA5MSAxMi4wMTMgMjQuOTQyIDEyLjAxMyAxOCAxMi4wMTMgMTEuMDA4IDE2LjgwOSA0LjkwOSAyMy42OTYgMy4wMjVaTTE4LjM0IDIuNjI4QzE4LjE4NyAyLjcyNyAxOC4wMzMgMi43NzcgMTcuODggMi44NzZMMTcuNDIxIDMuMTc0IDE3LjA2NCAzLjQ3MUMxNy4wMTMgMy40NzEgMTYuOTYyIDMuNTIxIDE2Ljk2MiAzLjU3IDE2LjgwOSAzLjY2OSAxNi42NTYgMy44MTggMTYuNTAzIDMuOTE3IDE2LjE5NyA0LjE2NSAxNS44NCA0LjQxMyAxNS40ODMgNC43NkwxNS4xMjUgNS4xMDdDMTQuOTIxIDUuMzA2IDE0LjcxNyA1LjUwNCAxNC41MTMgNS43NTJMMTQuMTU2IDYuMDVDMTQuMDkzMiA2LjEwNTk1IDE0LjA0MTMgNi4xNzMwOSAxNC4wMDMgNi4yNDggMTMuOTUyIDYuMjk4IDEzLjg1IDYuMzk3IDEzLjc5OSA2LjQ5NkwxMy42OTcgNi41OTVDMTMuNDQyIDYuOTQyIDEzLjEzNiA3LjI4OSAxMi44MyA3LjY4NiAxMi41NzUgOC4wMzMgMTIuMzIgOC40MyAxMi4wNjQgOC44MjYgMTEuOTExIDkuMDI1IDExLjgwOSA5LjI3MyAxMS43MDcgOS40NzEgMTEuNjA1IDkuNjY5IDExLjQ1MiA5LjkxNyAxMS4zNSAxMC4xMTYgMTEuMjQ4IDEwLjMxNCAxMS4xNDYgMTAuNTYyIDExLjA0NCAxMC44MSAxMC45NDIgMTEuMDA4IDEwLjg0IDExLjIwNyAxMC43ODkgMTEuNDA1IDEwLjYzNiAxMS44MDIgMTAuNDgzIDEyLjE0OSAxMC4zODEgMTIuNDk2IDEwLjI4OTcgMTIuNzE5OCAxMC4yMjEzIDEyLjk1MjQgMTAuMTc3IDEzLjE5IDEwLjEyNiAxMy4zMzkgMTAuMDc1IDEzLjQ4OCAxMC4wNzUgMTMuNTg3IDEwLjAyNCAxMy44MzUgOS45NzMgMTQuMDgzIDkuOTIyIDE0LjI4MUw5LjkyMiAxNC4zMzFDOS44NzEgMTQuNTI5IDkuODcxIDE0LjY3OCA5LjgyIDE0Ljg3NiA5Ljc2OSAxNS4wMjUgOS43NjkgMTUuMTc0IDkuNzY5IDE1LjMyMkw5Ljc2OSAxNS40NzFDOS43MTggMTUuNjIgOS43MTggMTUuNzY5IDkuNzE4IDE1LjkxNyA5LjcxOCAxNi4wNjYgOS42NjcgMTYuMjY1IDkuNjY3IDE2LjQ2M0w5LjY2NyAxNi41NjJDOS42NjcgMTYuODEgOS42MTYgMTcuMDU4IDkuNjE2IDE3LjMwNkw5LjYxNiAxOC43OTNDOS42MTYgMTkuMDQxIDkuNjY3IDE5LjI4OSA5LjY2NyAxOS40ODhMOS42NjcgMTkuNjg2QzkuNjY3IDE5LjgzNSA5LjcxOCAyMC4wMzMgOS43MTggMjAuMTgyIDkuNzE4IDIwLjM4IDkuNzY5IDIwLjUyOSA5Ljc2OSAyMC42NzggOS43NjkgMjAuODc2IDkuODIgMjEuMDI1IDkuODcxIDIxLjE3NCA5Ljg3MSAyMS4yNzMgOS45MjIgMjEuNDIyIDkuOTIyIDIxLjUyMUw5Ljk3MyAyMS43MTkgMTAuNDgzIDIxLjYyIDEwLjAyNCAyMS43NjlDMTAuMDc1IDIyLjAxNyAxMC4xMjYgMjIuMjE1IDEwLjE3NyAyMi40NjMgMTAuMjI4IDIyLjU2MiAxMC4yMjggMjIuNzExIDEwLjI3OSAyMi44MSAxMC4zODEgMjMuMTA3IDEwLjQ4MyAyMy40NTUgMTAuNTg1IDIzLjc1MiAxMC42ODcgMjQuMDUgMTAuNzg5IDI0LjM0NyAxMC45NDIgMjQuNjQ1IDEwLjk5MyAyNC43OTMgMTEuMDQ0IDI0Ljg5MyAxMS4wOTUgMjUuMDQxTDExLjI0OCAyNS4zMzlDMTEuMjk5IDI1LjQ4OCAxMS40MDEgMjUuNjg2IDExLjUwMyAyNS44MzVMMTEuNTU0IDI1LjkzNEMxMS42NTYgMjYuMTMyIDExLjc1OCAyNi4zOCAxMS45MTEgMjYuNTc4IDEyLjAxMyAyNi43NzcgMTIuMTY2IDI3LjAyNSAxMi4yNjkgMjcuMjIzIDEyLjYyNiAyNy44NjggMTMuMDg1IDI4LjQ2MyAxMy41NDQgMjkuMDA4IDEzLjY0NiAyOS4xNTcgMTMuNzk5IDI5LjMwNiAxMy45MDEgMjkuNDU1IDE0LjAwMyAyOS41NTQgMTQuMTA1IDI5LjY1MyAxNC4yMDcgMjkuODAyIDE0LjI1OCAyOS44NTEgMTQuMzA5IDI5Ljk1IDE0LjM2IDMwIDE0LjQ2MiAzMC4wOTkgMTQuNTY0IDMwLjE5OCAxNC42NjYgMzAuMzQ3TDE1LjAyMyAzMC42OTQgMTUuNDgzIDMxLjE0MUMxNS45OTMgMzEuNjM2IDE2LjU1NCAzMi4wODMgMTcuMTY2IDMyLjUyOSAxNy4zMTkgMzIuNjc4IDE3LjUyMyAzMi43NzcgMTcuNjc2IDMyLjg3NiAxNy44MjkgMzIuOTc1IDE4LjAzMyAzMy4xMjQgMTguMTg3IDMzLjIyM0wxOC4yMzggMzMuMjczQzE4LjM5MSAzMy4zNzIgMTguNDkzIDMzLjQyMiAxOC42NDYgMzMuNTIxTDE4LjY5NyAzMy41N0MxMC43MzggMzMuMTc0IDQuMTU3IDI3LjEyNCAzLjU0NSAxOS4zMzkgMy4wODUgMTQuODc2IDQuNTY1IDEwLjY2MSA3LjYyNiA3LjQzOCAxMC40ODMgNC40NjMgMTQuNDExIDIuNjI4IDE4LjU5NSAyLjQ3OSAxOC41NDQgMi41MjkgMTguNDQyIDIuNTc5IDE4LjM0IDIuNjI4Wk0zNy44NzkgMThDMzcuODc5IDExLjU1NCAzNC4zNTkgNS43MDIgMjguNzQ3IDIuNDc5IDMyLjkzIDIuNjc4IDM2LjkxIDQuNDYzIDM5LjcxNiA3LjQzOCA0Mi43NzcgMTAuNjYxIDQ0LjI1NiAxNC44NzYgNDMuODk5IDE5LjI0IDQzLjIzNiAyNy4wMjUgMzYuNzA2IDMzLjA3NCAyOC43NDcgMzMuNDcxIDM0LjM1OSAzMC4yOTggMzcuODc5IDI0LjM5NyAzNy44NzkgMThaTTEwOC41MzggNi42OTRDMTA3LjM2NSA2LjY5NCAxMDYuNDk3IDUuODUxIDEwNi40OTcgNC43MTEgMTA2LjQ5NyAzLjYyIDEwNy4zNjUgMi43MjcgMTA4LjUzOCAyLjcyNyAxMDkuNzEyIDIuNzI3IDExMC41NzkgMy41NyAxMTAuNTc5IDQuNzExIDExMC41NzkgNS44NTEgMTA5LjY2MSA2LjY5NCAxMDguNTM4IDYuNjk0Wk0xMDYuNzUzIDExLjA1OEMxMDYuNzUzIDEwLjcxMSAxMDYuODA0IDEwLjYxMiAxMDcuMTYxIDEwLjUxMiAxMDcuNTY5IDEwLjQ2MyAxMDguMDI4IDEwLjQxMyAxMDguNDg3IDEwLjQxMyAxMDguOTQ2IDEwLjQxMyAxMDkuMzU0IDEwLjQxMyAxMDkuODE0IDEwLjUxMiAxMTAuMTcxIDEwLjU2MiAxMTAuMjIyIDEwLjcxMSAxMTAuMjIyIDExLjA1OEwxMTAuMjIyIDI3LjQ3MUMxMTAuMjIyIDI3LjgxOCAxMTAuMTcxIDI3LjkxNyAxMDkuODE0IDI4LjAxNyAxMDkuNDA1IDI4LjA2NiAxMDguOTQ2IDI4LjExNiAxMDguNDg3IDI4LjExNiAxMDguMDI4IDI4LjExNiAxMDcuNjIgMjguMTE2IDEwNy4xNjEgMjguMDE3IDEwNi44MDQgMjcuOTY3IDEwNi43NTMgMjcuODE4IDEwNi43NTMgMjcuNDcxTDEwNi43NTMgMTEuMDU4Wk0xMDEuMzQ1IDI3LjQ3MSAxMDEuMzQ1IDE3LjYwM0MxMDEuMzQ1IDEyLjQ5NiA5OC43OTQgMTAuMzE0IDk0LjQ1NyAxMC4zMTQgOTAuOTg4IDEwLjMxNCA4OS41NiAxMS41NTQgODguNzk1IDEyLjI5OCA4OC42NDEgMTIuMzk3IDg4LjU5IDEyLjM5NyA4OC40ODggMTIuMzk3TDg4LjM4NiAxMi4zOTdDODguMTgyIDEyLjM5NyA4OC4wOCAxMi4zOTcgODguMDggMTIuMTk4TDg3LjkyNyAxMC45NTlDODcuODc2IDEwLjYxMiA4Ny43MjMgMTAuNTYyIDg3LjM2NiAxMC41MTIgODYuOTU4IDEwLjQ2MyA4Ni42MDEgMTAuNDYzIDg2LjE5MyAxMC40NjMgODUuNzg0IDEwLjQ2MyA4NS4zNzYgMTAuNDYzIDg1LjAxOSAxMC41MTIgODQuNjExIDEwLjU2MiA4NC41NiAxMC43MTEgODQuNTYgMTEuMDU4TDg0LjU2IDI3LjQyMkM4NC41NiAyNy43NjkgODQuNjExIDI3LjkxNyA4NC45NjggMjcuOTY3IDg1LjQyNyAyOC4wNjYgODUuODM2IDI4LjA2NiA4Ni4yOTUgMjguMDY2IDg2Ljc1NCAyOC4wNjYgODcuMjEzIDI4LjAxNyA4Ny42MjEgMjcuOTY3IDg3Ljk3OCAyNy44NjggODguMDI5IDI3Ljc2OSA4OC4wMjkgMjcuNDIyTDg4LjAyOSAxOS4wNDFDODguMDI5IDE1LjE3NCA4OS43NjQgMTIuOTQyIDkzLjIzMyAxMi45NDIgOTYuODA0IDEyLjk0MiA5Ny44NzYgMTQuNzc3IDk3Ljg3NiAxOC4zNDdMOTcuODc2IDI3LjQ3MUM5Ny44NzYgMjcuODE4IDk3LjkyNyAyNy45NjcgOTguMjg0IDI4LjAxNyA5OC43NDMgMjguMTE2IDk5LjE1MSAyOC4xMTYgOTkuNjEgMjguMTE2IDEwMC4wNjkgMjguMTE2IDEwMC41MjggMjguMDY2IDEwMC45MzcgMjguMDE3IDEwMS4yOTQgMjcuOTE3IDEwMS4zNDUgMjcuODE4IDEwMS4zNDUgMjcuNDcxWk03NS42ODMgMTkuNDg4Qzc1LjY4MyAyMy41MDQgNzQuMzU3IDI1LjU4NyA3MC41MzEgMjUuNTg3IDY3LjExMiAyNS41ODcgNjYuMDQxIDIzLjg1MSA2Ni4wNDEgMjAuNDNMNjYuMDQxIDExLjA1OEM2Ni4wNDEgMTAuNzExIDY1Ljk5IDEwLjU2MiA2NS42MzMgMTAuNTEyIDY1LjE3NCAxMC40MTMgNjQuNzY2IDEwLjQxMyA2NC4zMDYgMTAuNDEzIDYzLjg0NyAxMC40MTMgNjMuMzg4IDEwLjQ2MyA2Mi45OCAxMC41MTIgNjIuNjIzIDEwLjYxMiA2Mi41NzIgMTAuNzExIDYyLjU3MiAxMS4wNThMNjIuNTcyIDIxLjI3M0M2Mi41NzIgMjYuMzggNjUuNDggMjguMjY1IDY5LjYxMiAyOC4yNjUgNzIuOTI4IDI4LjI2NSA3NC40NTkgMjYuODI3IDc0Ljg2NyAyNi40MyA3NS4wMiAyNi4yODEgNzUuMDcxIDI2LjI4MSA3NS4yNzUgMjYuMjgxTDc1LjM3NyAyNi4yODFDNzUuNTgxIDI2LjI4MSA3NS42MzIgMjYuMzMxIDc1LjY4MyAyNi40NzlMNzUuODg3IDI3LjUyMUM3NS45MzggMjcuODY4IDc2LjA0IDI3LjkxNyA3Ni4zOTcgMjcuOTY3IDc2Ljc1NCAyOC4wNjYgNzcuMTEyIDI4LjA2NiA3Ny41NzEgMjguMDY2IDc3Ljk4OCAyOC4wNjYgNzguMjc5IDI4LjAyNSA3OC41OTYgMjcuOTgxTDc4LjY5MyAyNy45NjdDNzkuMTAxIDI3Ljg2OCA3OS4xNTIgMjcuODE4IDc5LjE1MiAyNy40MjJMNzkuMTUyIDExLjA1OEM3OS4xNTIgMTAuNzExIDc5LjEwMSAxMC41NjIgNzguNzQ0IDEwLjUxMiA3OC4yODUgMTAuNDEzIDc3Ljg3NyAxMC40MTMgNzcuNDE4IDEwLjQxMyA3Ni45NTkgMTAuNDEzIDc2LjUgMTAuNDYzIDc2LjA5MSAxMC41MTIgNzUuNzM0IDEwLjYxMiA3NS42ODMgMTAuNzExIDc1LjY4MyAxMS4wNThMNzUuNjgzIDE5LjQ4OFpNMTI1LjMyMyAxMC41MTIgMTE5Ljg2NCAxMC41MTJDMTE5LjYwOSAxMC41MTIgMTE5LjUwNyAxMC40MTMgMTE5LjUwNyAxMC4yMTVMMTE5LjUwNyA2LjA5OUMxMTkuNTA3IDUuNzUyIDExOS40NTYgNS42MDMgMTE5LjA5OSA1LjU1NCAxMTguNjQgNS40NTUgMTE4LjIzMSA1LjQ1NSAxMTcuNzcyIDUuNDU1IDExNy4zMTMgNS40NTUgMTE2Ljg1NCA1LjUwNCAxMTYuNDQ2IDUuNTU0IDExNi4wODkgNS42NTMgMTE2LjAzOCA1Ljc1MiAxMTYuMDM4IDYuMDk5TDExNi4wMzggMjIuMTY1QzExNi4wMzggMjYuMzggMTE4LjQ4NyAyOC4wNjYgMTIyLjQxNSAyOC4wNjYgMTI0LjM1NCAyOC4wNjYgMTI1LjMyMyAyNy44NjggMTI1Ljg4NCAyNy43MTkgMTI2LjE5IDI3LjY2OSAxMjYuMjQxIDI3LjU3IDEyNi4yOTIgMjcuMjczTDEyNi4yOTIgMjYuNzc3QzEyNi4yOTIgMjYuMzMxIDEyNi4yNDEgMjUuODg0IDEyNi4xOSAyNS41MzcgMTI2LjEzOSAyNS4yODkgMTI2LjAzNyAyNS4xNDEgMTI1LjgzMyAyNS4xNDFMMTI1LjY4IDI1LjE0MUMxMjQuODI2IDI1LjMzNjEgMTIzLjk1NCAyNS40MzU3IDEyMy4wNzggMjUuNDM4IDEyMC43MzEgMjUuNDM4IDExOS40NTYgMjQuODkzIDExOS40NTYgMjEuODE4TDExOS40NTYgMTMuNTM3QzExOS40NTYgMTMuMzM5IDExOS42MDkgMTMuMTkgMTE5Ljg2NCAxMy4xOUwxMjUuMzIzIDEzLjE5QzEyNS42MjkgMTMuMTkgMTI1LjczMSAxMy4xNDEgMTI1Ljc4MiAxMi44NDMgMTI1LjgzMyAxMi41OTUgMTI1LjgzMyAxMi4xOTggMTI1LjgzMyAxMS44NTEgMTI1LjgzMyAxMS41MDQgMTI1LjgzMyAxMS4xNTcgMTI1Ljc4MiAxMC44NiAxMjUuNzMxIDEwLjYxMiAxMjUuNjI5IDEwLjUxMiAxMjUuMzIzIDEwLjUxMloiIGZpbGw9IiMyRDJFODIiIGZpbGwtcnVsZT0ibm9uemVybyIvPjxwYXRoIGQ9Ik0xMzIuMDA2IDIwLjc3N0MxMzIuMjYxIDI0LjQ5NiAxMzUuMjcxIDI1LjU4NyAxMzguODk0IDI1LjU4NyAxNDEuNzI2IDI1LjU4NyAxNDQuMjA4IDI0LjcwOSAxNDQuNzk3IDI0LjUwMUwxNDQuODEyIDI0LjQ5NkMxNDQuODU5IDI0LjQ5NTEgMTQ0LjkwNiAyNC40ODQ2IDE0NC45NDkgMjQuNDY1IDE0NC45NzMgMjQuNDU1IDE0NC45OTQgMjQuNDQ2IDE0NS4wMTYgMjQuNDQ2IDE0NS4yMiAyNC40NDYgMTQ1LjMyMiAyNC41NDYgMTQ1LjM3MyAyNC43OTMgMTQ1LjQ3NSAyNS4yNCAxNDUuNTI2IDI1LjgzNSAxNDUuNTI2IDI2LjM4IDE0NS41MjYgMjYuOTI2IDE0NS41MjYgMjcuMDI1IDE0NS4wNjcgMjcuMjIzIDE0NC40NTQgMjcuNTIxIDE0Mi4xNTkgMjguMjY1IDEzOC43OTEgMjguMjY1IDEzMi42NjkgMjguMjY1IDEyOC4zMzMgMjYuMDgzIDEyOC4zMzMgMTkuMjQgMTI4LjMzMyAxMy43MzYgMTMxLjA4OCAxMC4yMTUgMTM3LjU2NyAxMC4yMTUgMTQzLjU4NyAxMC4yMTUgMTQ2Ljc1IDEzLjA0MSAxNDYuNzUgMTguNTQ2IDE0Ni43NSAxOS4xNDEgMTQ2LjY5OSAxOS42MzYgMTQ2LjY0OCAxOS45MzQgMTQ2LjU5NyAyMC4yODEgMTQ2LjQ5NSAyMC4zMzEgMTQ2LjEzOCAyMC4zMzFMMTMyLjQxNCAyMC4zMzFDMTMyLjEwOCAyMC4zOCAxMzIuMDA2IDIwLjQ3OSAxMzIuMDA2IDIwLjc3N1pNMTMxLjk1NSAxNy42NTNDMTMxLjk1NSAxNy44NTEgMTMyLjA1NyAxNy45NSAxMzIuMzYzIDE3Ljk1TDE0Mi44MjIgMTcuOTVDMTQzLjEyOCAxNy45NSAxNDMuMjMgMTcuODUxIDE0My4yMyAxNy41NTQgMTQzLjIzIDE0LjM4IDE0MS4yOTEgMTIuNjk0IDEzNy43MiAxMi42OTQgMTM0LjE0OSAxMi42OTQgMTMyLjIxIDE0LjI4MSAxMzIuMDA2IDE3LjU1NEwxMzIuMDA2IDE3LjY1MyAxMzEuOTU1IDE3LjY1M1pNMTY0LjY1NyAyNi40MyAxNjQuODEgMjYuNDNDMTY0Ljk2MyAyNi40MyAxNjUuMDY1IDI2LjQ3OSAxNjUuMTE2IDI2LjU3OEwxNjUuMzIgMjcuNTIxQzE2NS40MjIgMjcuODY4IDE2NS40NzQgMjcuOTE3IDE2NS44MzEgMjcuOTY3IDE2Ni4xODggMjguMDY2IDE2Ni41OTYgMjguMDY2IDE2Ny4wMDQgMjguMDY2IDE2Ny40MjEgMjguMDY2IDE2Ny43MTIgMjguMDI1IDE2OC4wMjkgMjcuOTgxTDE2OC4xMjYgMjcuOTY3QzE2OC41MzUgMjcuODY4IDE2OC41ODYgMjcuODE4IDE2OC41ODYgMjcuNDIyTDE2OC41ODYgMy40NzFDMTY4LjU4NiAzLjEyNCAxNjguNTM1IDIuOTc1IDE2OC4xNzcgMi45MjYgMTY3LjcxOCAyLjgyNiAxNjcuMzEgMi44MjYgMTY2Ljg1MSAyLjgyNiAxNjYuMzkyIDIuODI2IDE2NS45MzMgMi44NzYgMTY1LjUyNSAyLjkyNiAxNjUuMTY3IDMuMDI1IDE2NS4xMTYgMy4xMjQgMTY1LjExNiAzLjQ3MUwxNjUuMTE2IDExLjY1M0MxNjUuMTE2IDExLjg1MSAxNjUuMDY1IDExLjkwMSAxNjQuODYxIDExLjkwMUwxNjQuNzA4IDExLjkwMUMxNjQuNTU1IDExLjkwMSAxNjQuNTA0IDExLjkwMSAxNjQuMzUxIDExLjgwMiAxNjQuMjg0IDExLjc1NzMgMTY0LjIxNyAxMS43MTE2IDE2NC4xNTEgMTEuNjY1IDE2My40NTkgMTEuMTg0IDE2Mi4wNjUgMTAuMjE1IDE1OC44NDEgMTAuMjE1IDE1NC4xNDggMTAuMjE1IDE1MC4yNyAxMi43OTMgMTUwLjI3IDE5LjM4OSAxNTAuMjcgMjYuMDMzIDE1NC4xOTkgMjguMjY1IDE1OC45OTQgMjguMjY1IDE2Mi4zMzUgMjguMjY1IDE2My43IDI3LjA1OSAxNjQuMjIzIDI2LjU5N0wxNjQuMjY1IDI2LjU1OSAxNjQuMyAyNi41MjlDMTY0LjQwMiAyNi40MyAxNjQuNDUzIDI2LjQzIDE2NC42NTcgMjYuNDNaTTE1OS42MDcgMjUuNzM2QzE1NS4yNyAyNS43MzYgMTUzLjc0IDIzLjI1NiAxNTMuNzQgMTkuMjg5IDE1My43NCAxNS4zMjIgMTU1LjIxOSAxMi43OTMgMTU5LjYwNyAxMi44NDMgMTYzLjk0MyAxMi44NDMgMTY1LjQ3NCAxNS4zMjIgMTY1LjQ3NCAxOS4yODkgMTY1LjQ3NCAyMy4yNTYgMTYzLjk0MyAyNS43MzYgMTU5LjYwNyAyNS43MzZaIiBmaWxsPSIjMkQyRTgyIi8+PHBhdGggZD0iTTE4MS41OTUgMTkuMjg5QzE4MS41OTUgMjMuNjAzIDE4My43ODkgMjUuNjg2IDE4Ny45MjEgMjUuNjg2IDE5MC43NDIgMjUuNjg2IDE5Mi43MTIgMjQuOTg5IDE5My41MzYgMjQuNjk4TDE5My42ODYgMjQuNjQ1QzE5My43NDYgMjQuNjQ1IDE5My43ODggMjQuNjI4IDE5My44MjMgMjQuNjEzIDE5My44NDggMjQuNjA0IDE5My44NjkgMjQuNTk1IDE5My44OSAyNC41OTUgMTk0LjA5NCAyNC41OTUgMTk0LjE5NiAyNC42OTQgMTk0LjI0NyAyNC45NDIgMTk0LjM0OSAyNS4zODkgMTk0LjQgMjUuOTM0IDE5NC40IDI2LjQzIDE5NC40IDI2Ljk3NSAxOTQuNCAyNy4wNzQgMTkzLjk0MSAyNy4yNzMgMTkzLjIyNyAyNy41NyAxOTAuNzc4IDI4LjMxNCAxODcuOTIxIDI4LjMxNCAxODEuODUgMjguMzE0IDE3OC4wNzUgMjUuNTg3IDE3OC4wNzUgMTkuMjg5IDE3OC4wNzUgMTIuOTkyIDE4MS44NSAxMC4yNjUgMTg3LjkyMSAxMC4yNjUgMTkwLjc3OCAxMC4yNjUgMTkzLjIyNyAxMC45NTkgMTkzLjk0MSAxMS4zMDYgMTk0LjQgMTEuNTA0IDE5NC40IDExLjYwMyAxOTQuNCAxMi4xNDkgMTk0LjQgMTIuNjQ1IDE5NC4zNDkgMTMuMTkgMTk0LjI0NyAxMy42MzYgMTk0LjE5NiAxMy44ODQgMTk0LjA5NCAxMy45ODMgMTkzLjg5IDEzLjk4MyAxOTMuODM5IDEzLjk4MyAxOTMuNzM3IDEzLjk4MyAxOTMuNjg2IDEzLjkzNEwxOTMuNjMzIDEzLjkxNyAxOTMuNTcxIDEzLjg5NiAxOTMuNDE3IDEzLjg0NEMxOTIuNTA5IDEzLjUzNCAxOTAuNjI3IDEyLjg5MyAxODcuOTIxIDEyLjg5MyAxODMuNzg5IDEyLjg5MyAxODEuNTk1IDE0LjkyNiAxODEuNTk1IDE5LjI4OVoiIGZpbGw9IiMyRDJFODIiIGZpbGwtcnVsZT0ibm9uemVybyIvPjxwYXRoIGQ9Ik0yMDcuMTA0IDEwLjI2NUMyMDAuNzc3IDEwLjI2NSAxOTcuNjY1IDEzLjUzNyAxOTcuNjY1IDE5LjI4OSAxOTcuNjY1IDI1LjA0MSAyMDAuODI4IDI4LjI2NSAyMDcuMTA0IDI4LjMxNCAyMTMuNDMgMjguMzE0IDIxNi41NDIgMjUuMDQxIDIxNi41NDIgMTkuMjg5IDIxNi41NDIgMTMuNTM3IDIxMy40MyAxMC4yNjUgMjA3LjEwNCAxMC4yNjVaTTIwNy4xMDQgMTIuODQzQzIxMS41NDIgMTIuODQzIDIxMy4wNzMgMTUuMzcyIDIxMy4wNzMgMTkuMjg5IDIxMy4wNzMgMjMuMjA3IDIxMS41NDIgMjUuNzM2IDIwNy4xMDQgMjUuNzM2IDIwMi42NjUgMjUuNzM2IDIwMS4xMzUgMjMuMjA3IDIwMS4xMzUgMTkuMjg5IDIwMS4xMzUgMTUuMzcyIDIwMi42NjUgMTIuODQzIDIwNy4xMDQgMTIuODQzWk0yMzQuMzk4IDI2LjQzIDIzNC4yNDUgMjYuNDNDMjM0LjA0MSAyNi40MyAyMzMuOTkgMjYuNDMgMjMzLjg4NyAyNi41MjlMMjMzLjg1NSAyNi41NTggMjMzLjgxIDI2LjU5N0MyMzMuMjg3IDI3LjA1OSAyMzEuOTIzIDI4LjI2NSAyMjguNTgyIDI4LjI2NSAyMjMuNzg2IDI4LjI2NSAyMTkuODU4IDI2LjAzMyAyMTkuODU4IDE5LjM4OSAyMTkuODU4IDEyLjc5MyAyMjMuNzM1IDEwLjIxNSAyMjguNDI5IDEwLjIxNSAyMzEuNjUyIDEwLjIxNSAyMzMuMDQ3IDExLjE4NCAyMzMuNzM4IDExLjY2NSAyMzMuODEyIDExLjcxNyAyMzMuODc5IDExLjc2MyAyMzMuOTM4IDExLjgwMiAyMzQuMDkyIDExLjkwMSAyMzQuMTQzIDExLjkwMSAyMzQuMjk2IDExLjkwMUwyMzQuNDQ5IDExLjkwMUMyMzQuNjUzIDExLjkwMSAyMzQuNzA0IDExLjg1MSAyMzQuNzA0IDExLjY1M0wyMzQuNzA0IDMuNDcxQzIzNC43MDQgMy4xMjQgMjM0Ljc1NSAzLjAyNSAyMzUuMTEyIDIuOTI2IDIzNS41MiAyLjg3NiAyMzUuOTc5IDIuODI2IDIzNi40MzggMi44MjYgMjM2Ljg5NyAyLjgyNiAyMzcuMzA2IDIuODI2IDIzNy43NjUgMi45MjYgMjM4LjEyMiAyLjk3NSAyMzguMTczIDMuMTI0IDIzOC4xNzMgMy40NzFMMjM4LjE3MyAyNy40MjJDMjM4LjE3MyAyNy44MTggMjM4LjEyMiAyNy44NjggMjM3LjcxNCAyNy45NjdMMjM3LjYxNyAyNy45ODFDMjM3LjI5OSAyOC4wMjUgMjM3LjAwOCAyOC4wNjYgMjM2LjU5MSAyOC4wNjYgMjM2LjE4MyAyOC4wNjYgMjM1Ljc3NSAyOC4wNjYgMjM1LjQxOCAyNy45NjcgMjM1LjA2MSAyNy45MTcgMjM1LjAxIDI3Ljg2OCAyMzQuOTA4IDI3LjUyMUwyMzQuNzA0IDI2LjU3OEMyMzQuNjUzIDI2LjQ3OSAyMzQuNjAyIDI2LjQzIDIzNC4zOTggMjYuNDNaTTIyMy4zMjcgMTkuMjg5QzIyMy4zMjcgMjMuMjU2IDIyNC44NTcgMjUuNzM2IDIyOS4xOTQgMjUuNzM2IDIzMy41MyAyNS43MzYgMjM1LjA2MSAyMy4yNTYgMjM1LjA2MSAxOS4yODkgMjM1LjA2MSAxNS4zMjIgMjMzLjUzIDEyLjg0MyAyMjkuMTk0IDEyLjg0MyAyMjQuODU3IDEyLjc5MyAyMjMuMzI3IDE1LjMyMiAyMjMuMzI3IDE5LjI4OVpNMjUzLjA3IDI1LjU4N0MyNDkuNDQ4IDI1LjU4NyAyNDYuNDM4IDI0LjQ5NiAyNDYuMTgzIDIwLjc3NyAyNDYuMTgzIDIwLjQ3OSAyNDYuMjg1IDIwLjM4IDI0Ni41OTEgMjAuMzMxTDI2MC4zMTQgMjAuMzMxQzI2MC42NzIgMjAuMzMxIDI2MC43NzQgMjAuMjgxIDI2MC44MjUgMTkuOTM0IDI2MC44NzYgMTkuNjM2IDI2MC45MjcgMTkuMTQxIDI2MC45MjcgMTguNTQ2IDI2MC45MjcgMTMuMDQxIDI1Ny43NjQgMTAuMjE1IDI1MS43NDQgMTAuMjE1IDI0NS4yNjQgMTAuMjE1IDI0Mi41MDkgMTMuNzM2IDI0Mi41MDkgMTkuMjQgMjQyLjUwOSAyNi4wODMgMjQ2Ljg0NiAyOC4yNjUgMjUyLjk2OCAyOC4yNjUgMjU2LjMzNSAyOC4yNjUgMjU4LjYzMSAyNy41MjEgMjU5LjI0MyAyNy4yMjMgMjU5LjcwMiAyNy4wMjUgMjU5LjcwMiAyNi45MjYgMjU5LjcwMiAyNi4zOCAyNTkuNzAyIDI1LjgzNSAyNTkuNjUxIDI1LjI0IDI1OS41NDkgMjQuNzkzIDI1OS40OTggMjQuNTQ2IDI1OS4zOTYgMjQuNDQ2IDI1OS4xOTIgMjQuNDQ2IDI1OS4xNzEgMjQuNDQ2IDI1OS4xNSAyNC40NTUgMjU5LjEyNSAyNC40NjUgMjU5LjA5IDI0LjQ3OSAyNTkuMDQ4IDI0LjQ5NiAyNTguOTg4IDI0LjQ5NkwyNTguOTczIDI0LjUwMUMyNTguMzg0IDI0LjcwOSAyNTUuOTAzIDI1LjU4NyAyNTMuMDcgMjUuNTg3Wk0yNDYuNTQgMTcuOTVDMjQ2LjIzNCAxNy45NSAyNDYuMTMyIDE3Ljg1MSAyNDYuMTMyIDE3LjY1M0wyNDYuMTgzIDE3LjY1MyAyNDYuMTgzIDE3LjU1NEMyNDYuMzg3IDE0LjI4MSAyNDguMzI1IDEyLjY5NCAyNTEuODk3IDEyLjY5NCAyNTUuNDY4IDEyLjY5NCAyNTcuNDA2IDE0LjM4IDI1Ny40MDYgMTcuNTU0IDI1Ny40MDYgMTcuODUxIDI1Ny4zMDQgMTcuOTUgMjU2Ljk5OCAxNy45NUwyNDYuNTQgMTcuOTVaIiBmaWxsPSIjMkQyRTgyIi8+PHBhdGggZD0iTTI3Mi45NjcgMTIuNzQ0QzI3MC42NzEgMTIuNzQ0IDI2OC4zNzUgMTMuMTQxIDI2OC4zNzUgMTUuMDI1IDI2OC4zNzUgMTYuNzExIDI3MC4wMDggMTYuOTU5IDI3My4zNzUgMTcuNDU1IDI3OC4xMTkgMTguMTk4IDI4MS4xMjkgMTguOTQyIDI4MS4xMjkgMjIuOTU5IDI4MS4xMjkgMjcuMzcyIDI3Ni41ODkgMjguMjY1IDI3Mi40NTYgMjguMjY1IDI2OS4zOTUgMjguMjY1IDI2Ni4yODMgMjcuNzE5IDI2NS4yNjMgMjcuMzcyIDI2NC45MDYgMjcuMjczIDI2NC44NTUgMjcuMTc0IDI2NC44MDQgMjYuODI3IDI2NC43NTMgMjYuMjgxIDI2NC43NTMgMjUuNDg4IDI2NC45NTcgMjQuODkzIDI2NS4wNTkgMjQuNTQ2IDI2NS4yMTIgMjQuNTQ2IDI2NS41NjkgMjQuNTk1IDI2Ni41ODkgMjQuODkzIDI2OS4zOTUgMjUuNjM2IDI3Mi42MSAyNS42MzYgMjc1LjEwOSAyNS42MzYgMjc3LjY2IDI1LjMzOSAyNzcuNjYgMjMuMTU3IDI3Ny42NiAyMS42MiAyNzYuNzkzIDIxLjEyNCAyNzMuMDE4IDIwLjUyOSAyNjguNDc3IDE5Ljg4NCAyNjQuOTU3IDE5LjE5IDI2NC45NTcgMTUuMjIzIDI2NC45NTcgMTAuOTA5IDI2OS4zOTUgMTAuMTY1IDI3My4zMjQgMTAuMTY1IDI3Ni40MzYgMTAuMTY1IDI3OS4wODkgMTAuODYgMjc5LjY1IDExLjA1OCAyNzkuOTU2IDExLjE1NyAyODAuMDU4IDExLjI1NiAyODAuMDU4IDExLjU1NEwyODAuMDU4IDEyQzI4MC4wNTggMTIuNDQ2IDI4MC4wMDcgMTIuOTkyIDI3OS45MDUgMTMuMzM5IDI3OS44NTQgMTMuNTM3IDI3OS43NTIgMTMuNjM2IDI3OS41OTkgMTMuNjM2IDI3OS41NDggMTMuNjM2IDI3OS40NDYgMTMuNjM2IDI3OS4zNDQgMTMuNTg3IDI3OS4xODggMTMuNTg3IDI3OC43ODEgMTMuNTA5IDI3OC4yMTYgMTMuNCAyNzYuOTI2IDEzLjE1MSAyNzQuODExIDEyLjc0NCAyNzIuOTY3IDEyLjc0NFoiIGZpbGw9IiMyRDJFODIiIGZpbGwtcnVsZT0ibm9uemVybyIvPjxwYXRoIGQ9Ik0yODUuNjE5IDI2LjkyNkMyODUuNjE5IDI2Ljk3NSAyODUuNjE5IDI2Ljk3NSAyODUuNjcgMjYuOTc1IDI4NS43MjEgMjYuOTc1IDI4NS44MjMgMjYuOTc1IDI4NS44MjMgMjcuMDI1TDI4Ni4wMjcgMjcuMDI1QzI4Ni4wNTMgMjcuMDI1IDI4Ni4wNjUgMjcuMDI1IDI4Ni4wNzIgMjcuMDE5IDI4Ni4wNzggMjcuMDEyIDI4Ni4wNzggMjcgMjg2LjA3OCAyNi45NzVMMjg2LjA3OCAyNi4zOEMyODYuMDc4IDI2LjMzMSAyODYuMDc4IDI2LjMzMSAyODYuMTI5IDI2LjMzMUwyODYuNjM5IDI2LjMzMUMyODYuNjkgMjYuMzMxIDI4Ni42OSAyNi4zMzEgMjg2Ljc0MSAyNi4zOEwyODcuMiAyNi45NzVDMjg3LjI1MSAyNy4wMjUgMjg3LjI1MSAyNy4wMjUgMjg3LjMwMiAyNy4wMjVMMjg3Ljc2MiAyNy4wMjVDMjg3Ljg2NCAyNy4wMjUgMjg3Ljg2NCAyNi45NzUgMjg3LjgxMyAyNi45MjZMMjg3LjI1MSAyNi4yMzFDMjg3LjIgMjYuMjMxIDI4Ny4yNTEgMjYuMTgyIDI4Ny4yNTEgMjYuMTgyIDI4Ny40NTYgMjYuMDMzIDI4Ny42NiAyNS44ODQgMjg3LjY2IDI1LjQ4OCAyODcuNjYgMjQuOTQyIDI4Ny4zMDIgMjQuNjk0IDI4Ni42OSAyNC42OTRMMjg1LjcyMSAyNC42OTRDMjg1LjY3IDI0LjY5NCAyODUuNjE5IDI0Ljc0NCAyODUuNjE5IDI0Ljc5M0wyODUuNjE5IDI2LjkyNlpNMjg2LjUzNyAyNS4wNDFDMjg2Ljg5NCAyNS4wNDEgMjg3LjIgMjUuMDkxIDI4Ny4yIDI1LjQ4OCAyODcuMiAyNS44ODQgMjg2Ljg5NCAyNS45MzQgMjg2LjUzNyAyNS45MzRMMjg2LjE4IDI1LjkzNEMyODYuMTI5IDI1LjkzNCAyODYuMTI5IDI1LjkzNCAyODYuMTI5IDI1Ljg4NEwyODYuMTI5IDI1LjA5MUMyODYuMTI5IDI1LjA0MSAyODYuMTI5IDI1LjA0MSAyODYuMTggMjUuMDQxTDI4Ni41MzcgMjUuMDQxWiIgZmlsbD0iIzJEMkU4MiIvPjxwYXRoIGQ9Ik0yODguODg0IDI1LjkzNEMyODguODg0IDI0LjU0NiAyODcuOTY2IDIzLjc1MiAyODYuNTg4IDIzLjc1MiAyODUuMjExIDIzLjc1MiAyODQuMjkyIDI0LjU0NiAyODQuMjkyIDI1LjkzNCAyODQuMjkyIDI3LjMyMiAyODUuMjExIDI4LjExNiAyODYuNTg4IDI4LjExNiAyODcuOTY2IDI4LjExNiAyODguODg0IDI3LjMyMiAyODguODg0IDI1LjkzNFpNMjg4LjQyNSAyNS45MzRDMjg4LjQyNSAyNy4wNzQgMjg3Ljc2MiAyNy43MTkgMjg2LjU4OCAyNy43MTkgMjg1LjQ2NiAyNy43MTkgMjg0Ljc1MiAyNy4wNzQgMjg0Ljc1MiAyNS45MzQgMjg0Ljc1MiAyNC43OTMgMjg1LjQxNSAyNC4xNDkgMjg2LjU4OCAyNC4xNDkg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" +) +collection.add(insert2) + +# Embedtag +embed = cop.elements.Embed( + name="fileToEmbed", + value="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" +) +collection.add(embed) +#Raw Tag +RawTag = cop.elements.Raw( + name="bold", + value='John' +) +collection.add(RawTag) # configure server # For running on localhost you do not need api_key else replace below "YOUR_API_KEY" with your api key. @@ -66,8 +120,8 @@ printjob = cop.PrintJob( data=collection, server=server, - template=cop.Resource.from_local_file("./data/template.docx"), + template=cop.Resource.from_local_file("C:/Users/em8ee/OneDrive/Documents/cloudofficeprint-python/BeginerGuide/UsingElements/data/template.docx"), ) # Execute print job and save response to file response = printjob.execute() -response.to_file("output/output") \ No newline at end of file +response.to_file("C:/Users/em8ee/OneDrive/Documents/cloudofficeprint-python/BeginerGuide/UsingElements/output/output.docx") \ No newline at end of file diff --git a/BeginerGuide/UsingEncyrption/data/template.docx b/BeginerGuide/UsingEncyrption/data/template.docx new file mode 100644 index 0000000..46a40f4 Binary files /dev/null and b/BeginerGuide/UsingEncyrption/data/template.docx differ diff --git a/BeginerGuide/UsingEncyrption/output/output.pdf b/BeginerGuide/UsingEncyrption/output/output.pdf new file mode 100644 index 0000000..663ec45 Binary files /dev/null and b/BeginerGuide/UsingEncyrption/output/output.pdf differ diff --git a/BeginerGuide/UsingEncyrption/usingEncryption.py b/BeginerGuide/UsingEncyrption/usingEncryption.py new file mode 100644 index 0000000..62a19c5 --- /dev/null +++ b/BeginerGuide/UsingEncyrption/usingEncryption.py @@ -0,0 +1,46 @@ +import sys +sys.path.insert(0, "C:/Users/em8ee/OneDrive/Documents/cloudofficeprint-python") +import cloudofficeprint as cop + +# Main object that holds the data +collection = cop.elements.ElementCollection() + +title = cop.elements.Property( + name="title", + value="Hello World!" +) +collection.add(title) + +# Create the text element and add it to the element collection +text = cop.elements.Property( + name="text", + value="This is an example created with the Cloud Office Print Python SDK" +) +collection.add(text) +text2 = cop.elements.Property( + name="text2", + value="This is an example created with the Cloud Office Print Python SDK" +) +collection.add(text2) +# Server +server = cop.config.Server( + url="http://localhost:8010/", + config=cop.config.ServerConfig(api_key="YOUR_API_KEY") +) + +# Template +template = cop.Resource.from_local_file("./data/template.docx") + +output_conf = cop.config.OutputConfig(filetype="pdf", + output_read_password="123" +) + +# PrintJob +printjob = cop.PrintJob( + data=collection, + template=template, + server=server, + output_config=output_conf, +) +response = printjob.execute() +response.to_file("./output/output.pdf") diff --git a/BeginerGuide/UsingForm/FormExample.py b/BeginerGuide/UsingForm/FormExample.py new file mode 100644 index 0000000..18184dc --- /dev/null +++ b/BeginerGuide/UsingForm/FormExample.py @@ -0,0 +1,78 @@ +import sys +sys.path.insert(0, "PATH_TO_COP_DIR") +import cloudofficeprint as cop + +# Create an ElementCollection to hold all form elements +collection = cop.elements.ElementCollection() + +# Textboxes +first_name_collection = cop.elements.ElementCollection("first_name") +first_name_collection.add( + cop.elements.Textbox(name="first_name", value="Prabin") +) +last_name_collection = cop.elements.ElementCollection("last_name") +last_name_collection.add( + cop.elements.Textbox( + name="last_name", + value="Apex R&D", + width=200, + height=20, + multiline=True + ) +) +collection.add(first_name_collection) +collection.add(last_name_collection) + +# Radio buttons +radiolist_collection = cop.elements.ElementCollection("radiolist") +radiolist_collection.add( + cop.elements.RadioButton( + name="radiolist", + value="List A", + text="List Option A", + selected=True + ) +) +radiolist_collection.add( + cop.elements.RadioButton( + name="radiolist", + value="List B", + text="List Option B" + ) +) +collection.add(radiolist_collection) + +# checkbox +checkbox_collection = cop.elements.ElementCollection("checkbox") +checkbox_collection.add( + cop.elements.Checkbox( + name="checkbox", + value=True, + text="IsChecked", + height=20, + width=200 + ) +) +collection.add(checkbox_collection) + +# Configure the Server +server = cop.config.Server( + url="http://localhost:8010/", + config=cop.config.ServerConfig(api_key="YOUR_API_KEY") +) + +# Load the DOCX Template +template = cop.Resource.from_local_file("./data/template.docx") +output_conf = cop.config.OutputConfig(filetype="pdf") + +# Create and Run the PrintJob +printjob = cop.PrintJob( + data=collection, + template=template, + server=server, + output_config=output_conf, +) +response = printjob.execute() +response.to_file( "./output/output.pdf") + + diff --git a/BeginerGuide/UsingForm/data/template.docx b/BeginerGuide/UsingForm/data/template.docx new file mode 100644 index 0000000..8496634 Binary files /dev/null and b/BeginerGuide/UsingForm/data/template.docx differ diff --git a/BeginerGuide/UsingForm/output/output.pdf b/BeginerGuide/UsingForm/output/output.pdf new file mode 100644 index 0000000..f6c9d12 Binary files /dev/null and b/BeginerGuide/UsingForm/output/output.pdf differ diff --git a/BeginerGuide/UsingHideSlide/data/hide_temp.pptx b/BeginerGuide/UsingHideSlide/data/hide_temp.pptx new file mode 100644 index 0000000..fc4a707 Binary files /dev/null and b/BeginerGuide/UsingHideSlide/data/hide_temp.pptx differ diff --git a/BeginerGuide/UsingHideSlide/output/output.pptx b/BeginerGuide/UsingHideSlide/output/output.pptx new file mode 100644 index 0000000..2acb0c4 Binary files /dev/null and b/BeginerGuide/UsingHideSlide/output/output.pptx differ diff --git a/BeginerGuide/UsingHideSlide/usingHideSlide.py b/BeginerGuide/UsingHideSlide/usingHideSlide.py new file mode 100644 index 0000000..1a2f97a --- /dev/null +++ b/BeginerGuide/UsingHideSlide/usingHideSlide.py @@ -0,0 +1,101 @@ +import sys +sys.path.insert(0, "PATH_TO_COP_DIR") +import cloudofficeprint as cop + +# Main object that holds the data +data = cop.elements.ElementCollection() + +# Define customers data +customers_data = [ + { + "sheet_name": "John Dulles", + "cust_first_name": "John", + "cust_last_name": "Dulles", + "cust_city": "Sterling", + "orders": [ + {"order_total": 2380, "order_name": "Order 1"} + ] + }, + { + "sheet_name": "William Hartsfield", + "cust_first_name": "William", + "cust_last_name": "Hartsfield", + "cust_city": "Atlanta", + "orders": [ + {"order_total": 1640, "order_name": "Order 1"}, + {"order_total": 730, "order_name": "Order 2"} + ] + }, + { + "sheet_name": "Edward Logan", + "cust_first_name": "Edward", + "cust_last_name": "Logan", + "cust_city": "East Boston", + "orders": [ + {"order_total": 1515, "order_name": "Order 1"}, + {"order_total": 905, "order_name": "Order 2"} + ] + }, + { + "sheet_name": "Frank OHare", + "cust_first_name": "Frank", + "cust_last_name": "OHare", + "cust_city": "Chicago", + "orders": [] #Note: set this to [] or none to trigger the hide + + }, + { + "sheet_name": "Cris Jr Santos", + "cust_first_name": "Cris Jr", + "cust_last_name": "Santos", + "cust_city": "Texas", + "orders": [] #Note: set this to [] or none to trigger the hide + } +] + +#Build up a Py list of ElementCollection objects for each customer +customers_list = [] +for customer in customers_data: + mapping = { + "sheet_name": customer["sheet_name"], + "cust_first_name": customer["cust_first_name"], + "cust_last_name": customer["cust_last_name"], + "cust_city": customer["cust_city"], + + } + customer_elem = cop.elements.ElementCollection.from_mapping(mapping) + + if customer.get("orders"): + order_elems = [ + cop.elements.ElementCollection.from_mapping({ + "order_total": o["order_total"], + "order_name": o["order_name"] + }) + for o in customer["orders"] + ] + customer_elem.add(cop.elements.ForEach("orders", order_elems)) + else: + # If orders is empty or None, explicitly set "orders" to None so that + # !orders == true in the template: + customer_elem.add( + cop.elements.ElementCollection.from_mapping({"orders": None}) + ) + customers_list.append(customer_elem) + +# wrap all customers +customers_cursor = cop.elements.ForEach("customers", customers_list) +data.add(customers_cursor) + +server = cop.config.Server( + "http://localhost:8010/", + cop.config.ServerConfig(api_key="YOUR_API_KEY") +) +printjob = cop.PrintJob( + data=data, + server=server, + template=cop.Resource.from_local_file("./data/hide_temp.pptx") +) + + +response = printjob.execute() +response.to_file("./output/output") diff --git a/BeginerGuide/UsingHtmlTag/data/html_temp.docx b/BeginerGuide/UsingHtmlTag/data/html_temp.docx new file mode 100644 index 0000000..f1e4eda Binary files /dev/null and b/BeginerGuide/UsingHtmlTag/data/html_temp.docx differ diff --git a/BeginerGuide/UsingHtmlTag/output/output.docx b/BeginerGuide/UsingHtmlTag/output/output.docx new file mode 100644 index 0000000..3f7eae0 Binary files /dev/null and b/BeginerGuide/UsingHtmlTag/output/output.docx differ diff --git a/BeginerGuide/UsingHtmlTag/usingHtml.py b/BeginerGuide/UsingHtmlTag/usingHtml.py new file mode 100644 index 0000000..9442951 --- /dev/null +++ b/BeginerGuide/UsingHtmlTag/usingHtml.py @@ -0,0 +1,107 @@ +import sys +sys.path.insert(0, "PATH_TO_COP_DIR") +import cloudofficeprint as cop + + +# Create data collection +collection = cop.elements.ElementCollection() + +# HTML paragraph and line break +collection.add(cop.elements.Html( + name="overview", + value=( + "

This is a bold statement, followed by a line break.
" + "And here's a new line in the same paragraph.

" + ), + custom_table_style = None, + unordered_list_style = None, + ordered_list_style = None, + use_tag_style = None, + ignore_cell_margin = None, + ignore_empty_p = None +)) + +# empty paragraphs +collection.add(cop.elements.Html( + name="html_with_empty_p", + value="

First paragraph.

Third paragraph.

", + custom_table_style = None, + unordered_list_style = None, + ordered_list_style = None, + use_tag_style = None, + ignore_cell_margin = None, + ignore_empty_p = True +)) + +# Word’s tag style and also set a custom numbering style +collection.add(cop.elements.Html( + name="lists", + value=( + "" + ), + custom_table_style=None, + unordered_list_style="1", + ordered_list_style="2", + use_tag_style=True, + ignore_cell_margin=None, + ignore_empty_p=True +)) + +#HTML table (default style) +collection.add(cop.elements.Html( + name="html_table_1", + value=( + '' + ' ' + ' ' + ' ' + '
NameAgeCountry
Alice30USA
Bob25Canada
' + ), + custom_table_style = None, + unordered_list_style = None, + ordered_list_style = None, + use_tag_style = None, + ignore_cell_margin = None, + ignore_empty_p = None +)) + +# tag +collection.add(cop.elements.Html( + name="html_img", + value=( + '' + ), + custom_table_style = None, + unordered_list_style = None, + ordered_list_style = None, + use_tag_style = None, + ignore_cell_margin = None, + ignore_empty_p = None +)) + +# server +server = cop.config.Server( + "http://localhost:8010/", + cop.config.ServerConfig(api_key="YOUR_API_KEY") +) +template = cop.Resource.from_local_file("./data/html_temp.docx") + +# print job +printjob = cop.PrintJob( + data=collection, + server=server, + template=template +) + +# save output +response = printjob.execute() +response.to_file("./output/output") diff --git a/BeginerGuide/UsingMarkdown/data/template.docx b/BeginerGuide/UsingMarkdown/data/template.docx new file mode 100644 index 0000000..8ce0e7d Binary files /dev/null and b/BeginerGuide/UsingMarkdown/data/template.docx differ diff --git a/BeginerGuide/UsingMarkdown/output/output.docx b/BeginerGuide/UsingMarkdown/output/output.docx new file mode 100644 index 0000000..09488e0 Binary files /dev/null and b/BeginerGuide/UsingMarkdown/output/output.docx differ diff --git a/BeginerGuide/UsingMarkdown/usingMarkdown.py b/BeginerGuide/UsingMarkdown/usingMarkdown.py new file mode 100644 index 0000000..4244090 --- /dev/null +++ b/BeginerGuide/UsingMarkdown/usingMarkdown.py @@ -0,0 +1,90 @@ +import sys +sys.path.insert(0, "C:/Users/em8ee/OneDrive/Documents/cloudofficeprint-python") +import cloudofficeprint as cop + + +# Create main data collection +collection = cop.elements.ElementCollection() + +#markdown content +markdown_text = """ +# Heading level 1 + +## Heading level 2 + +=============== + +I just love **bold text**. + +Italicized text is the *cat's meow*. + +1. First item +2. Second item +3. Third item +4. Fourth item + +--- + +* First item +* Second item +* Third item +* Fourth item + +| Syntax | Description | +| --------- | ----------- | +| Header | Title | +| Paragraph | Text | + +The world is flat. We now know that the world is round. +""" +# Adding markdown content +collection.add(cop.elements.MarkdownContent("markdowncontent", markdown_text)) + +# Create and add customer names +cust_names = cop.elements.ElementCollection("cust_names") +customers = [ + {"first": "Albert", + "cust_name_bold": "**Albert**"}, + {"first": "Edward", + "cust_name_bold": "**Edward**"}, + {"first": "Eugene", + "cust_name_bold": "**Eugene**"}, + {"first": "Fiorello", + "cust_name_bold": "**Fiorello**"}, + {"first": "Frank", + "cust_name_bold": "**Frank**"}, + {"first": "John", + "cust_name_bold": "**John**"}, + {"first": "William", + "cust_name_bold": "**William**"} +] + +customer_collections = [] +for customer in customers: + cust_collection = cop.elements.ElementCollection() + cust_collection.add(cop.elements.Property("first", customer["first"])) + cust_collection.add(cop.elements.Property("cust_name_bold", customer["cust_name_bold"])) + customer_collections.append(cust_collection) + +# create array structure +customers_loop = cop.elements.ForEach("cust_names", customer_collections) +collection.add(customers_loop) + + +# Server configuration +server = cop.config.Server( + "http://localhost:8010/", + cop.config.ServerConfig(api_key="YOUR_API_KEY") +) + +# Load template and create print job +template = cop.Resource.from_local_file("./data/template.docx") +printjob = cop.PrintJob( + data=collection, + server=server, + template=template +) + +# Execute and save +response = printjob.execute() +response.to_file("./output/output") \ No newline at end of file diff --git a/BeginerGuide/UsingOtherPptxTag/UsingOtherPPTX.py b/BeginerGuide/UsingOtherPptxTag/UsingOtherPPTX.py new file mode 100644 index 0000000..d28796f --- /dev/null +++ b/BeginerGuide/UsingOtherPptxTag/UsingOtherPPTX.py @@ -0,0 +1,58 @@ +# Install cloudofficeprint using pip install cloudofficeprint +#Import the cloudofficeprint libary. +import sys +sys.path.insert(0, "PATH_TO_COP_DIR") +import cloudofficeprint as cop + +# Main object that holds the data +collection = cop.elements.ElementCollection() +# Create the title element and add it to the element collection + +# ---------------------using autoLink----------- +autoLink = cop.elements.AutoLink( + name='autoLink', + value='sample text with hyperlinks like https://www.cloudofficeprint.com/docs/python/index.html . COP link is https://www.cloudofficeprint.com/index.html contact us in info@cloudofficeprint.com ', + ) +collection.add(autoLink) + +# ----------------HyperLink--------------- +hyperlink = cop.elements.Hyperlink( + name='hyperlink', + url='https://www.cloudofficeprint.com/index.html', + text='COP_link' + ) +collection.add(hyperlink) +insert1 = cop.elements.Insert( + name="fileToInsert", + value="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" +) +collection.add(insert1) +image = cop.elements.Image.from_url( + name="image1", + url_source="https://picsum.photos/300/200", + width="80px", + height="60px", + alt_text="Random image", + wrap_text="square", + rotation=0, + transparency="10%", + url="https://example.com" +) +collection.add(image) + +# configure server +# For running on localhost you do not need api_key else replace below "YOUR_API_KEY" with your api key. +server = cop.config.Server( + "http://localhost:8010/", + cop.config.ServerConfig(api_key = "YOUR_API_KEY") +) +# Create print job +# PrintJob combines template, data, server and an optional output configuration +printjob = cop.PrintJob( + data=collection, + server=server, + template=cop.Resource.from_local_file("./data/other_temp.pptx") +) +# Execute print job and save response to file +response = printjob.execute() +response.to_file("./output/other_output.pptx") \ No newline at end of file diff --git a/BeginerGuide/UsingOtherPptxTag/data/other_temp.pptx b/BeginerGuide/UsingOtherPptxTag/data/other_temp.pptx new file mode 100644 index 0000000..0fb31b0 Binary files /dev/null and b/BeginerGuide/UsingOtherPptxTag/data/other_temp.pptx differ diff --git a/BeginerGuide/UsingOtherPptxTag/output/other_output.pptx b/BeginerGuide/UsingOtherPptxTag/output/other_output.pptx new file mode 100644 index 0000000..7d8f62a Binary files /dev/null and b/BeginerGuide/UsingOtherPptxTag/output/other_output.pptx differ diff --git a/BeginerGuide/UsingOtherXlsxTags/data/codes_temp.xlsx b/BeginerGuide/UsingOtherXlsxTags/data/codes_temp.xlsx new file mode 100644 index 0000000..0cf677a Binary files /dev/null and b/BeginerGuide/UsingOtherXlsxTags/data/codes_temp.xlsx differ diff --git a/BeginerGuide/UsingOtherXlsxTags/output/output.xlsx b/BeginerGuide/UsingOtherXlsxTags/output/output.xlsx new file mode 100644 index 0000000..a3b3962 Binary files /dev/null and b/BeginerGuide/UsingOtherXlsxTags/output/output.xlsx differ diff --git a/BeginerGuide/UsingOtherXlsxTags/usingCodes.py b/BeginerGuide/UsingOtherXlsxTags/usingCodes.py new file mode 100644 index 0000000..6ef942b --- /dev/null +++ b/BeginerGuide/UsingOtherXlsxTags/usingCodes.py @@ -0,0 +1,130 @@ +# Install cloudofficeprint using pip install cloudofficeprint +import cloudofficeprint as cop #Import the cloudofficeprint libary. +# Main object that holds the data +collection = cop.elements.ElementCollection() + +# -----------------barcode---------- +barcode = cop.elements.BarCode( + name='barcode_name', + data='cloudofficeprint', + type='code128', + extra_options='includetext guardwhitespace' + ) +collection.add(barcode) + +# --------------------------qrcode----------- +qrcode = cop.elements.QRCode( + name='qrcode_name', + data='https://www.cloudofficeprint.com/index.html', + type='qrcode' + ) +# you can add multiple options for qrcode using variable_name.options +# for ex: +# if variable name is qrcode +# qrcode.logo('background Image') + +collection.add(qrcode) + +# ---------------------wifi_qr_code------------ +wifi = cop.elements.WiFiQRCode( + name='wifi_code_name', + ssid='test_wifi_network', + wifi_encryption='WPA', + wifi_password='my_wifi_password', + wifi_hidden=False + ) +collection.add(wifi) + +# ----------------------telephone_qr_code--------- +telephone_number = cop.elements.TelephoneNumberQRCode( + name='telephone_number_name', + number='9823038377' + ) +collection.add(telephone_number) + +# --------------------email_qr_code----------- +email = cop.elements.EmailQRCode( + name='email_name', + receiver='info@cloudofficeprint.com', + cc='cc', + bcc='bcc', + subject='test subject', + body='Hi there,/n I would like to know about cloudofficeprint./nThank you/n' + ) +collection.add(email) + +#---------------sms_qr_code---------------- +sms = cop.elements.SMSQRCode( + name='sms_qr_code', + receiver='9823038377', + sms_body='this is test message body' + ) +collection.add(sms) + +# --------------url_qr_code -------------- +url = cop.elements.URLQRCode( + name='urlQr_code', + url='https://www.cloudofficeprint.com/index.html' + ) +collection.add(url) + +# ---------------v_card_qrcode------------ +v_card = cop.elements.VCardQRCode( + name='vcard_name', + first_name='first_name', + last_name='last_name', + email='email', + website='website' + ) +collection.add(v_card) + +# ---------------me_card------------- +me_card = cop.elements.MeCardQRCode( + name='me_card_name', + first_name='first_name', + last_name='last_name', + nickname='nickname', + email='email', + contact_primary='contact_primary', + contact_secondary='contact_secondary', + contact_tertiary='contact_tertiary', + website='website', + birthday='birthday', + notes='notes' + ) +collection.add(me_card) + +# -----------------geo_location---------- +geolocation = cop.elements.GeolocationQRCode( + name='geolocatin_qr_code_name', + latitude='27.608683', + longitude='85.360287', + altitude='1400' + ) +collection.add(geolocation) + +# ---------------event---------------- +event = cop.elements.EventQRCode( + name='event_qr_code_name', + summary='summary', + startdate='startdate', + enddate='enddate' + ) +collection.add(event) + +# configure server +# For running on localhost you do not need api_key else replace below "YOUR_API_KEY" with your api key. +server = cop.config.Server( + "http://localhost:8010/", + cop.config.ServerConfig(api_key = "YOUR_API_KEY") +) +# Create print job +# PrintJob combines template, data, server and an optional output configuration +printjob = cop.PrintJob( + data=collection, + server=server, + template=cop.Resource.from_local_file("C:/Users/em8ee/OneDrive/Documents/cloudofficeprint-python/BeginerGuide/UsingOtherXlsxTags/data/codes_temp.xlsx"), +) +# Execute print job and save response to file +response = printjob.execute() +response.to_file("C:/Users/em8ee/OneDrive/Documents/cloudofficeprint-python/BeginerGuide/UsingOtherXlsxTags/output/output.xlsx") \ No newline at end of file diff --git a/BeginerGuide/UsingPageBreak/data/pagebreak_temp.docx b/BeginerGuide/UsingPageBreak/data/pagebreak_temp.docx new file mode 100644 index 0000000..f665825 Binary files /dev/null and b/BeginerGuide/UsingPageBreak/data/pagebreak_temp.docx differ diff --git a/BeginerGuide/UsingPageBreak/output/output.docx b/BeginerGuide/UsingPageBreak/output/output.docx new file mode 100644 index 0000000..71f0073 Binary files /dev/null and b/BeginerGuide/UsingPageBreak/output/output.docx differ diff --git a/BeginerGuide/UsingPageBreak/usingPageBreak.py b/BeginerGuide/UsingPageBreak/usingPageBreak.py new file mode 100644 index 0000000..d8d4512 --- /dev/null +++ b/BeginerGuide/UsingPageBreak/usingPageBreak.py @@ -0,0 +1,45 @@ +import sys +sys.path.insert(0, "Path_To_Dir") +import cloudofficeprint as cop + + +# Create main data collection +collection = cop.elements.ElementCollection() + +# Add customer data +customer1 = cop.elements.ElementCollection() +customer1.add(cop.elements.Property("cust_first_name", "John")) +customer1.add(cop.elements.Property("cust_last_name", "Dulles")) +customer1.add(cop.elements.PageBreak("pageBreak", True)) + +customer2 = cop.elements.ElementCollection() +customer2.add(cop.elements.Property("cust_first_name", "William")) +customer2.add(cop.elements.Property("cust_last_name", "Hartsfield")) +customer2.add(cop.elements.PageBreak("pageBreak", True)) + +customer3 = cop.elements.ElementCollection() +customer3.add(cop.elements.Property("cust_first_name", "Edward")) +customer3.add(cop.elements.Property("cust_last_name", "Logan")) +customer3.add(cop.elements.PageBreak("pageBreak", False)) + +# Create customers loop +customers_loop = cop.elements.ForEach("customers", [customer1, customer2, customer3]) +collection.add(customers_loop) + +# Server configuration +server = cop.config.Server( + "http://localhost:8010/", + cop.config.ServerConfig(api_key="YOUR_API_KEY") +) + +# Load template and create print job +template = cop.Resource.from_local_file("./data/pagebreak_temp.docx") +printjob = cop.PrintJob( + data=collection, + server=server, + template=template +) + +# Execute and save +response = printjob.execute() +response.to_file("./output/output.docx") \ No newline at end of file diff --git a/BeginerGuide/UsingPdfInclude/UsingPdfInclude.py b/BeginerGuide/UsingPdfInclude/UsingPdfInclude.py new file mode 100644 index 0000000..8290796 --- /dev/null +++ b/BeginerGuide/UsingPdfInclude/UsingPdfInclude.py @@ -0,0 +1,46 @@ +#Import the cloudofficeprint libary. +import base64 +import sys +sys.path.insert(0, "./cloudofficeprint-python") +import cloudofficeprint as cop + +# Read the image file and encode it to base64 +# Make sure to change the path to the image file as per your system +with open("./data/view.png", "rb") as img: + # Encode the image to base64 + b64_img = base64.b64encode(img.read()).decode("utf-8") + + +# Create element collection +collection = cop.elements.ElementCollection() + +# include element +include1 = cop.elements.PdfInclude( + name="view", + value="", + filename="view.pdf", + mime_type="image/png", + file_content=b64_img, + file_source="base64" + ) +collection.add(include1) + +# Configure the Server +server = cop.config.Server( + url="http://localhost:8010/", + config=cop.config.ServerConfig(api_key="YOUR_API_KEY") +) + +# Load the DOCX Template +template = cop.Resource.from_local_file("./data/include_temp.docx") + +# Create and Run the PrintJob +printjob = cop.PrintJob( + data=collection, + template=template, + server=server, + output_config=cop.config.OutputConfig(filetype="pdf") +) +response = printjob.execute() +response.to_file("./output/output") + diff --git a/BeginerGuide/UsingPdfInclude/data/include_temp.docx b/BeginerGuide/UsingPdfInclude/data/include_temp.docx new file mode 100644 index 0000000..6c9d2fe Binary files /dev/null and b/BeginerGuide/UsingPdfInclude/data/include_temp.docx differ diff --git a/BeginerGuide/UsingPdfInclude/data/view.png b/BeginerGuide/UsingPdfInclude/data/view.png new file mode 100644 index 0000000..877f196 Binary files /dev/null and b/BeginerGuide/UsingPdfInclude/data/view.png differ diff --git a/BeginerGuide/UsingPdfInclude/output/output.pdf b/BeginerGuide/UsingPdfInclude/output/output.pdf new file mode 100644 index 0000000..e932418 Binary files /dev/null and b/BeginerGuide/UsingPdfInclude/output/output.pdf differ diff --git a/BeginerGuide/UsingShapeRemove/UsingShapeRemove.py b/BeginerGuide/UsingShapeRemove/UsingShapeRemove.py new file mode 100644 index 0000000..2e4bd95 --- /dev/null +++ b/BeginerGuide/UsingShapeRemove/UsingShapeRemove.py @@ -0,0 +1,33 @@ +import sys +sys.path.insert(0,"PATH_TO_COP_DIR") +import cloudofficeprint as cop + +# Create main data collection +collection = cop.elements.ElementCollection() +greeting = cop.elements.PptxShapeRemove("greeting", "Hello World, Thank you for using AOP") +collection.add(greeting) + +# The remove property will be false, so any shape with {remove?} tag will be removed in the tenmlate +remove = cop.elements.PptxShapeRemove("remove", False) +collection.add(remove) + +# Add a quote that will be shown +quote = cop.elements.PptxShapeRemove("toShow", "When in doubt, look intelligent. - GARRISON KEILLOR") +collection.add(quote) + +# Configure server +server = cop.config.Server( + "http://localhost:8010/", + cop.config.ServerConfig(api_key="YOUR_API_KEY") +) + +# Create print job +printjob = cop.PrintJob( + data=collection, + server=server, + template=cop.Resource.from_local_file("./data/shapeRemove_temp.pptx") +) + +# Execute print job and save response to file +response = printjob.execute() +response.to_file("./output/output.pptx") \ No newline at end of file diff --git a/BeginerGuide/UsingShapeRemove/data/shapeRemove_temp.pptx b/BeginerGuide/UsingShapeRemove/data/shapeRemove_temp.pptx new file mode 100644 index 0000000..79663d6 Binary files /dev/null and b/BeginerGuide/UsingShapeRemove/data/shapeRemove_temp.pptx differ diff --git a/BeginerGuide/UsingShapeRemove/output/output.pptx b/BeginerGuide/UsingShapeRemove/output/output.pptx new file mode 100644 index 0000000..3985a72 Binary files /dev/null and b/BeginerGuide/UsingShapeRemove/output/output.pptx differ diff --git a/BeginerGuide/UsingSheetProtection/UsingSheetProtection.py b/BeginerGuide/UsingSheetProtection/UsingSheetProtection.py new file mode 100644 index 0000000..1ede8a3 --- /dev/null +++ b/BeginerGuide/UsingSheetProtection/UsingSheetProtection.py @@ -0,0 +1,37 @@ +# Install cloudofficeprint using pip install cloudofficeprint +import cloudofficeprint as cop + +# Main object that holds the data +collection = cop.elements.ElementCollection() + +# Use SheetProtection to protect the sheet with a password +sheet_protection = cop.elements.SheetProtection( + name="protectTag", + password="123", + formatCells=False, + insertRows=False, + deleteRows=False +) +collection.add(sheet_protection) + +fname = cop.elements.Property(name="cust_first_name", value="john") +collection.add(fname) + +lname = cop.elements.Property(name="cust_last_name", value="doe") +collection.add(lname) + +# configure server +# For running on localhost you do not need api_key else replace below "YOUR_API_KEY" with your api key. +server = cop.config.Server( + "http://localhost:8010/", + cop.config.ServerConfig(api_key = "YOUR_API_KEY") +) +# Create print job +printjob = cop.PrintJob( + data=collection, + server=server, + template=cop.Resource.from_local_file("./data/temp.xlsx"), +) +# Execute print job and save response to file +response = printjob.execute() +response.to_file("./output/output.xlsx") \ No newline at end of file diff --git a/BeginerGuide/UsingSheetProtection/data/temp.xlsx b/BeginerGuide/UsingSheetProtection/data/temp.xlsx new file mode 100644 index 0000000..d05bdaf Binary files /dev/null and b/BeginerGuide/UsingSheetProtection/data/temp.xlsx differ diff --git a/BeginerGuide/UsingSheetProtection/output/output.xlsx b/BeginerGuide/UsingSheetProtection/output/output.xlsx new file mode 100644 index 0000000..e20299c Binary files /dev/null and b/BeginerGuide/UsingSheetProtection/output/output.xlsx differ diff --git a/BeginerGuide/UsingSpanTag/UsingSpan.py b/BeginerGuide/UsingSpanTag/UsingSpan.py new file mode 100644 index 0000000..e15c7cd --- /dev/null +++ b/BeginerGuide/UsingSpanTag/UsingSpan.py @@ -0,0 +1,47 @@ +import sys +sys.path.insert(0, "Path_To_Dir") +import cloudofficeprint as cop + +# Create main data collection +collection = cop.elements.ElementCollection() + +collection.add(cop.elements.Property("cust_first_name", "John")) +collection.add(cop.elements.Property("cust_last_name", "Doe")) + +# Create a span element for the first cell that will span 2 rows and 3 columns +span1 = cop.elements.Span( + name="span", + value="This cell will span 2 rows and 3 columns", + columns=3, + rows=2 +) + +# Create a span element for the second cell that will span 3 rows and 4 columns +span2 = cop.elements.Span( + name="testSpan", + value="This cell will span 3 rows and 4 columns", + columns=4, + rows=3 +) + +# Add spans to collection +collection.add(span1) +collection.add(span2) + +# Server configuration +server = cop.config.Server( + "http://localhost:8010/", + cop.config.ServerConfig(api_key="YOUR_API_KEY") +) + +# Load template and create print job +template = cop.Resource.from_local_file("./data/span_temp.xlsx") +printjob = cop.PrintJob( + data=collection, + server=server, + template=template +) + +# Execute and save +response = printjob.execute() +response.to_file("./output/output") \ No newline at end of file diff --git a/BeginerGuide/UsingSpanTag/data/span_temp.xlsx b/BeginerGuide/UsingSpanTag/data/span_temp.xlsx new file mode 100644 index 0000000..5312ba7 Binary files /dev/null and b/BeginerGuide/UsingSpanTag/data/span_temp.xlsx differ diff --git a/BeginerGuide/UsingSpanTag/output/output.xlsx b/BeginerGuide/UsingSpanTag/output/output.xlsx new file mode 100644 index 0000000..dff2a8e Binary files /dev/null and b/BeginerGuide/UsingSpanTag/output/output.xlsx differ diff --git a/BeginerGuide/UsingTOC/data/toc_temp.docx b/BeginerGuide/UsingTOC/data/toc_temp.docx new file mode 100644 index 0000000..382b009 Binary files /dev/null and b/BeginerGuide/UsingTOC/data/toc_temp.docx differ diff --git a/BeginerGuide/UsingTOC/output/output.docx b/BeginerGuide/UsingTOC/output/output.docx new file mode 100644 index 0000000..93347bc Binary files /dev/null and b/BeginerGuide/UsingTOC/output/output.docx differ diff --git a/BeginerGuide/UsingTOC/usingTOC.py b/BeginerGuide/UsingTOC/usingTOC.py new file mode 100644 index 0000000..2b98ef4 --- /dev/null +++ b/BeginerGuide/UsingTOC/usingTOC.py @@ -0,0 +1,100 @@ +import sys +sys.path.insert(0, "C:/Users/em8ee/OneDrive/Documents/cloudofficeprint-python") +import cloudofficeprint as cop + +# Create main data collection +collection = cop.elements.ElementCollection() + +# Add table of contents +toc = cop.elements.TableOfContents( + name="toc_demo", + title="Table of Contents - Generated by AOP", + depth=2, + tab_leader="hyphen" +) +collection.add(toc) + +# Add customer data +customers = [ + { + "cust_f_name": "John", + "cust_l_name": "Dulles", + "city": "Sterling", + "addr_1": "45020 Aviation Drive", + "state": "VA", + "email": "john.dulles@email.com", + "phone_number_1": "703-555-2143", + "phone_number_2": "703-555-8967", + "url": "http://www.johndulles.com" + }, + + { + "cust_f_name": "Fiorello", + "cust_l_name": "LaGuardia", + "city": "Flushing", + "addr_1": "Hangar Center", + "addr_2": "Third Floor", + "state": "NY", + "phone_number_1": "212-555-3923" + }, + { + "cust_f_name": "Albert", + "cust_l_name": "Lambert", + "city": "St. Louis", + "addr_1": "10701 Lambert International Blvd.", + "state": "MO", + "phone_number_1": "314-555-4022" + + } + + +] + +customer_collections = [] +for customer in customers: + cust = cop.elements.ElementCollection() + for key, value in customer.items(): + cust.add(cop.elements.Property(key, value)) + customer_collections.append(cust) + +# customers to main collection +customers_loop = cop.elements.ForEach("cust_list", customer_collections) +collection.add(customers_loop) + +# Add the HTML content +html_content = """ +

Heading 1 from html

+

Heading 2 from html

+

Heading 3 from html

+AOP also handles the headings from html +""" +collection.add(cop.elements.Html( + name="sample_html", + value=html_content, + custom_table_style=None, + unordered_list_style=None, + ordered_list_style=None, + use_tag_style=True, + ignore_cell_margin=None, + ignore_empty_p=None +)) + +# Server configuration +server = cop.config.Server( + "http://localhost:8010/", + cop.config.ServerConfig(api_key="YOUR_API_KEY") +) + +# Load template +template = cop.Resource.from_local_file("./data/toc_temp.docx") + +# Create and execute print job +printjob = cop.PrintJob( + data=collection, + server=server, + template=template +) + +# Save output +response = printjob.execute() +response.to_file("./output/output") \ No newline at end of file diff --git a/BeginerGuide/imageTag/data/img_temp.docx b/BeginerGuide/imageTag/data/img_temp.docx new file mode 100644 index 0000000..a4bdaed Binary files /dev/null and b/BeginerGuide/imageTag/data/img_temp.docx differ diff --git a/BeginerGuide/imageTag/local_img/UC_Logo.svg b/BeginerGuide/imageTag/local_img/UC_Logo.svg new file mode 100644 index 0000000..b0a8931 --- /dev/null +++ b/BeginerGuide/imageTag/local_img/UC_Logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/BeginerGuide/imageTag/output/ouput.docx b/BeginerGuide/imageTag/output/ouput.docx new file mode 100644 index 0000000..7188cb8 Binary files /dev/null and b/BeginerGuide/imageTag/output/ouput.docx differ diff --git a/BeginerGuide/imageTag/usingImage.py b/BeginerGuide/imageTag/usingImage.py new file mode 100644 index 0000000..0cba9c4 --- /dev/null +++ b/BeginerGuide/imageTag/usingImage.py @@ -0,0 +1,65 @@ +import sys +sys.path.insert(0, "PATH_TO_COP_DIR") +import cloudofficeprint as cop + +# Create data collection +collection = cop.elements.ElementCollection() + +# Add sample properties +collection.add(cop.elements.Property(name="title", value="Image Example")) +collection.add(cop.elements.Property(name="description", value="This images are dynamically loaded using Cloud Office Print")) + +# 1) URL based image +image = cop.elements.Image.from_url( + name="image_name", + url_source="https://picsum.photos/300/200", + width="80px", + height="60px", + alt_text="Random image", + wrap_text="square", + rotation=0, + transparency="10%", + url="https://example.com" +) +collection.add(image) + +# 2) SVG with density +image_svg = cop.elements.Image.from_url( + name="img_svg", + url_source="https://upload.wikimedia.org/wikipedia/commons/4/4f/SVG_Logo.svg", + width="200px", + density=300, # 300 dpi + alt_text="SVG logo", +) +collection.add(image_svg) + +# 3) Local file image +collection.add( + cop.elements.Image.from_file( + name="img_file", + path="./local_img/UC_Logo.svg", + width="150px", + wrap_text="square", + alt_text=" Uc logo" + ) +) + +#server +server = cop.config.Server( + "http://localhost:8010/", + cop.config.ServerConfig(api_key="YOUR_API_KEY") +) + +# Load template +template = cop.Resource.from_local_file("./data/img_temp.docx") + +# print job +printjob = cop.PrintJob( + data=collection, + server=server, + template=template +) + +#save output +response = printjob.execute() +response.to_file("./output/ouput") diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..f304438 --- /dev/null +++ b/build.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +set -e + + +# Clean old build folders +echo "[1] Cleaning previous build artifacts (build/, dist/, *.egg-info)..." +rm -rf build/ dist/ *.egg-info + +# Remove any previously generated docs for this package +echo "[2] Removing old auto-generated docs (docs/cloudofficeprint/)..." +rm -rf docs/cloudofficeprint + +# Generate documentation via pdoc +echo "[3] Generating documentation with pdoc into docs/cloudofficeprint/..." +# Make sure pdoc is installed: pip install pdoc3 +pdoc --html --force --output-dir docs/ cloudofficeprint + +# Build source (+sdist) and wheel (+bdist_wheel) +echo "[4] Building source and wheel distributions (python setup.py sdist bdist_wheel)..." +python setup.py sdist bdist_wheel + +# Verify the newly built distributions with twine +echo "[5] Verifying distributions with twine check dist/*..." +twine check dist/* + +echo +echo " wow ,completed all steps." diff --git a/cloudofficeprint/__init__.py b/cloudofficeprint/__init__.py index da838d5..0592011 100644 --- a/cloudofficeprint/__init__.py +++ b/cloudofficeprint/__init__.py @@ -95,7 +95,9 @@ from .printjob import PrintJob from .resource import Resource +from .template import Template from .response import Response +from .transformation import TransformationFunction # specify what is imported on "from cloudofficeprint import *" # but that shouldn't really be used anyway @@ -106,5 +108,7 @@ "own_utils", "PrintJob", "Resource", - "Response" + "Template", + "Response", + "transformation", ] diff --git a/cloudofficeprint/config/__init__.py b/cloudofficeprint/config/__init__.py index 1b43102..f96a40f 100644 --- a/cloudofficeprint/config/__init__.py +++ b/cloudofficeprint/config/__init__.py @@ -10,3 +10,4 @@ from .output import * from .pdf import * from .server import * +from .request_option import * \ No newline at end of file diff --git a/cloudofficeprint/config/output.py b/cloudofficeprint/config/output.py index e4ddd0a..4c109a6 100644 --- a/cloudofficeprint/config/output.py +++ b/cloudofficeprint/config/output.py @@ -2,6 +2,7 @@ from typing import Dict from .cloud import CloudAccessToken from .pdf import PDFOptions +from .request_option import requestOptions class OutputConfig: @@ -17,16 +18,34 @@ def __init__(self, cloud_access_token: CloudAccessToken = None, server_directory: str = None, pdf_options: PDFOptions = None, - append_per_page: bool = None,): - """ + append_per_page: bool = None, + prepend_per_page: bool = None, + output_polling: bool = None, + secret_key: str = None, + request_option: requestOptions = None, + update_toc: bool = None, + output_locale: str = None, + return_output : bool = None, + output_read_password: str = None, + ): + """If the parameters are not provided default value will be used. + Args: - filetype (str, optional): The file type (as extension) to use for the output. Defaults to None (set to template-type in printjob.py). + filetype (str, optional): The file type (as extension) to use for the output. Defaults to None (set to template-type in printjob.py). Defaults to None. encoding (str, optional): Encoding of output file. Either "raw" or "base64". Defaults to "raw". converter (str, optional): The pdf converter to use. Can be "libreoffice", "officetopdf" or any custom defined converter. Custom converters are configurated in the Cloud Office Print server's `aop_config.json` file. Defaults to "libreoffice". cloud_access_token (CloudAccessToken, optional): Access token used to access various cloud services for output storage. Defaults to None. server_directory (str, optional): Base directory to save output files into. Can only be used if the server allows to save on disk. The specific output path for each file is appended to the base path. Defaults to None. pdf_options (PDFOptions, optional): Optional PDF options. Defaults to None. - append_per_page (bool, optional): Ability to prepend/append file after each page of output. + append_per_page (bool, optional): Ability to append file after each page of output. Defaults to None. + prepend_per_page (bool, optional): Ability to prepend file after each page of output. Defaults to None. + output_polling (bool, optional): A unique link for each request is sent back, which can be used later to download the output file. Defaults to None. + secret_key (str, optional): A secret key can be specified to encrypt the file stored on the server (used with output polling). Defaults to None. + request_option (requestOptions, optional): AOP makes a call to the given option with response/output of the current request. Defaults to None. + update_toc (bool, optional): Update table of contents of Word document. + output_locale (str, optional): Locale/language setting for output formatting (e.g. "nep", "en_us"). Defaults to None. + output_read_password (str, optional): Password to encrypt and protect the output document (PDF, DOCX, etc). + return_output (bool, optional): When True, both saves files to server directory and returns the output. Defaults to None. """ self.filetype: str = filetype self.converter: str = converter @@ -35,6 +54,14 @@ def __init__(self, self.pdf_options: PDFOptions = pdf_options self.encoding = encoding self.append_per_page = append_per_page + self.prepend_per_page = prepend_per_page + self.output_polling = output_polling + self.secret_key = secret_key + self.request_option = request_option + self.update_toc = update_toc + self.output_locale: str = output_locale + self.output_read_password: str = output_read_password + self.return_output: bool= return_output @property def json(self) -> str: @@ -69,6 +96,22 @@ def as_dict(self) -> Dict: result.update(self.pdf_options.as_dict) if self.append_per_page is not None: result["output_append_per_page"] = self.append_per_page + if self.prepend_per_page is not None: + result["output_prepend_per_page"] = self.prepend_per_page + if self.output_polling is not None: + result['output_polling'] = self.output_polling + if self.secret_key is not None: + result['secret_key'] = self.secret_key + if self.update_toc is not None: + result['update_toc'] = self.update_toc + if self.output_locale is not None: + result["output_locale"] = self.output_locale + if self.output_read_password is not None: + result["output_read_password"] = self.output_read_password + if self.request_option is not None: + result['request_option'] = self.request_option.as_dict + if self.return_output is not None : + result['return_output'] = self.return_output return result @property diff --git a/cloudofficeprint/config/pdf.py b/cloudofficeprint/config/pdf.py index 0400a04..c4436a7 100644 --- a/cloudofficeprint/config/pdf.py +++ b/cloudofficeprint/config/pdf.py @@ -1,5 +1,7 @@ import json -from typing import Union, Iterable, Dict, Mapping +from typing import Union, Dict, Mapping + +from ..resource import Base64Resource, ServerPathResource, URLResource class PDFOptions: @@ -9,38 +11,50 @@ class PDFOptions: All of them are optional, which is why passing an instance of this class in an OutputConfig is also optional. """ - def __init__(self, - read_password: str = None, - watermark: str = None, - watermark_font_size: int = None, - watermark_opacity: int = None, - watermark_color: str = None, - watermark_font: str = None, - page_width: Union[str, int] = None, - page_height: Union[str, int] = None, - even_page: bool = None, - merge_making_even: bool = None, - modify_password: str = None, - password_protection_flag: int = None, - lock_form: bool = None, - copies: int = None, - page_margin: Union[int, dict] = None, - landscape: bool = None, - page_format: str = None, - merge: bool = None, - sign_certificate: str = None, - sign_certificate_password: str = None, - identify_form_fields: bool = None, - split: bool = None, - remove_last_page: bool = None): + def __init__( + self, + read_password: str = None, + watermark: str = None, + watermark_font_size: int = None, + watermark_opacity: int = None, + watermark_color: str = None, + watermark_font: str = None, + page_width: Union[str, int] = None, + page_height: Union[str, int] = None, + even_page: bool = None, + merge_making_even: bool = None, + modify_password: str = None, + password_protection_flag: int = None, + lock_form: bool = None, + copies: int = None, + page_margin: Union[int, dict] = None, + landscape: bool = None, + page_format: str = None, + merge: bool = None, + sign_certificate: str = None, + sign_certificate_password: str = None, + identify_form_fields: bool = None, + split: bool = None, + remove_last_page: bool = None, + sign_certificate_txt: str = None, + watermark_rotation: int = None, + convert_to_pdfa: str = None, + attachment_name: str = None, + convert_attachment_to_json: bool = None, + insert_barcode: bool = None, + page_number_start_at: str = None, + batch_selector: str = None, + batch_size: int = None, + batch_condition: str = None + ): """ Args: read_password (str, optional): The password needed to open the PDF. Defaults to None. - watermark (str, optional): Setting this generates a diagonal custom watermark on every page in the PDF file. Defaults to None. - watermark_color (str, optional): You can specify to change watermark color. Accepts css colors. Defaults to black. - watermark_font (str, optional): You can specify to change the font of watermark. Defaults to Aerial. - watermark_opacity (int, optional): You can specify to change the opacity of watermark. Should be in percentage - watermark_font_size (int, optional): You can specify to change the font size of watemark. Should be a number(px) ie: 45 . + watermark (str, optional): Requires PDF output, generates a diagonal custom watermark on every page of the PDF file. Defaults to None. + watermark_font_size (int, optional): Requires PDF output, specifies the size of watermark text specified, should be a number in px, i.e. 45. Defaults to None. + watermark_opacity (int, optional): Requires PDF output, specifies the opacity of the watermark text specified, should be as a percentage, i.e. 45. Defaults to None. + watermark_color (str, optional): Requires PDF output, specifies the font of the watermark specified, with a default of "black". Defaults to None. + watermark_font (str, optional): Requires PDF output, specifies the font of the watermark text specified, with a default of "Arial". Defaults to None. page_width (Union[str, int], optional): Only for HTML to PDF. Page width in px, mm, cm, in. No unit means px. Defaults to None. page_height (Union[str, int], optional): Only for HTML to PDF. Page height in px, mm, cm, in. No unit means px. Defaults to None. even_page (bool, optional): If you want your output to have even pages, for example printing on both sides after merging, you can set this to be true. Defaults to None. @@ -54,34 +68,55 @@ def __init__(self, page_format (str, optional): Only for HTML to PDF. The page format: "a4" (default) or "letter". Defaults to None. merge (bool, optional): If True: instead of returning back a zip file for multiple output, merge it. Defaults to None. sign_certificate (str, optional): Signing certificate for the output PDF (pkcs #12 .p12/.pfx) as a base64 string, URL, FTP location or a server path. The function read_file_as_base64() from file_utils.py can be used to read local .p12 or .pfx file as base64. Defaults to None. - sign_certificate_password (str, optional): It is possible to sign certificate with password. + sign_certificate_password (str, optional): If you are signing with a password protected certificate, you can specify the password as a plain string. Defaults to None. identify_form_fields (bool, optional): Identify the form fields in a PDF-form by filling the name of each field into the respective field. Defaults to None. split (bool, optional): You can specify to split a PDF in separate files. You will get one file per page in a zip file. Defaults to None. - remove_last_page (bool, optional): You can specify to remove the last page from output file, this is helpful when the last page of output is blank. + remove_last_page (bool, optional): Remove the last page from the given PDF document. Defaults to None. + sign_certificate_txt (str, optional): Add custom text in any language to the signature field + watermark_rotation (int, optional): Requires PDF output, specifies the angle of watermark text specified, should be a number, i.e. 45. Defaults to None. + convert_to_pdfa (str, optional): For generating PDF/A format. While converting using openoffice converter, specifying it will create PDF/A format, values can be either 1b or 2b which are the variants of PDF/A specification. + attachment_name (str, optional): To retrieve specific attachment. output_type must be get_attachments. + convert_attachment_to_json (bool, optional): To retrieve data of the XML attachment as a JSON. output_type must be get_attachments. + insert_barcode (bool, optional): To insert barcode in pdf. + page_number_start_at (str, optional): Provide start of the page number. Defaults to None. + batch_selector (str, optional): Specifies the hierarchy of keys to split data into batches. Defaults to None. + batch_size (int, optional): Number of batches or files to split into. Defaults to None. + batch_condition (str, optional): Condition to determine batch allocation. Defaults to Non """ self.read_password: str = read_password self.watermark: str = watermark - self.watermark_font: str = watermark_font - self.watermark_font_size: str = watermark_font_size + self.watermark_font_size: int = watermark_font_size + self.watermark_opacity: int = watermark_opacity self.watermark_color: str = watermark_color - self.watermark_opacity: str = watermark_opacity + self.watermark_font: str = watermark_font self.page_width: Union[str, int] = page_width self.page_height: Union[str, int] = page_height self.even_page: bool = even_page - self.merge_making_even: bool = merge_making_even self.modify_password: str = modify_password + self.merge_making_even: bool = merge_making_even self.password_protection_flag: int = password_protection_flag self.lock_form: bool = lock_form self.copies: int = copies + self.page_margin: Union[int, dict] = page_margin + self._landscape: bool = landscape self.page_format: str = page_format self.merge: bool = merge - self.page_margin: Union[int, dict] = page_margin self.sign_certificate: str = sign_certificate self.sign_certificate_password: str = sign_certificate_password - self._landscape: bool = landscape self.identify_form_fields: bool = identify_form_fields self.split: bool = split - self.remove_last_page = remove_last_page + self.remove_last_page: bool = remove_last_page + self.sign_certificate_txt: str = sign_certificate_txt + self.watermark_rotation: int = watermark_rotation + self.convert_to_pdfa: str = convert_to_pdfa + self.attachment_name: str = attachment_name + self.convert_attachment_to_json: bool = convert_attachment_to_json + self.insert_barcode: bool = insert_barcode + self.page_number_start_at = page_number_start_at + self.batch_selector : str = batch_selector + self.batch_size: int = batch_size + self.batch_condition : str = batch_condition + def __str__(self) -> str: """Get the string representation of these PDF options. @@ -116,6 +151,8 @@ def as_dict(self) -> Dict: result["output_even_page"] = self.even_page if self.merge_making_even is not None: result["output_merge_making_even"] = self.merge_making_even + if self.remove_last_page is not None: + result["output_remove_last_page"] = self.remove_last_page if self.modify_password is not None: result["output_modify_password"] = self.modify_password if self.read_password is not None: @@ -132,6 +169,8 @@ def as_dict(self) -> Dict: result["output_watermark_opacity"] = self.watermark_opacity if self.watermark_font_size is not None: result["output_watermark_size"] = self.watermark_font_size + if self.watermark_rotation is not None: + result["output_watermark_rotation"] = self.watermark_rotation if self.lock_form is not None: result["lock_form"] = self.lock_form if self.copies is not None: @@ -139,6 +178,9 @@ def as_dict(self) -> Dict: if self.page_margin is not None: # For Cloud Office Print versions later than 21.1.1, output_page_margin will also be supported result["page_margin"] = self.page_margin + if self._landscape is not None: + # For Cloud Office Print versions later than 21.1.1, output_page_orientation will also be supported + result["page_orientation"] = self.page_orientation if self.page_width is not None: result["output_page_width"] = self.page_width if self.page_height is not None: @@ -147,21 +189,63 @@ def as_dict(self) -> Dict: result["output_page_format"] = self.page_format if self.merge is not None: result["output_merge"] = self.merge - if self._landscape is not None: - # For Cloud Office Print versions later than 21.1.1, output_page_orientation will also be supported - result["page_orientation"] = self.page_orientation + if self.split is not None: + result["output_split"] = self.split + if self.identify_form_fields is not None: + result["identify_form_fields"] = self.identify_form_fields if self.sign_certificate is not None: result["output_sign_certificate"] = self.sign_certificate if self.sign_certificate_password is not None: - result['output_sign_certificate_password'] = self.sign_certificate_password - if self.identify_form_fields is not None: - result["identify_form_fields"] = self.identify_form_fields - if self.split is not None: - result['output_split'] = self.split - if self.remove_last_page is not None: - result['output_remove_last_page'] = self.remove_last_page + result["output_sign_certificate_password"] = self.sign_certificate_password + if self.sign_certificate_txt is not None: + result["output_sign_certificate_txt"] = self.sign_certificate_txt + if self.convert_to_pdfa is not None: + result["output_convert_to_pdfa"] = self.convert_to_pdfa + if self.attachment_name is not None: + result["output_attachment_name"] = self.attachment_name + if self.convert_attachment_to_json is not None: + result["output_convert_attachment_to_json"] = self.convert_attachment_to_json + if self.insert_barcode is not None: + result["output_insert_barcode"] = self.insert_barcode + if self.page_number_start_at is not None: + result['output_page_number_start_at'] = self.page_number_start_at + if self.batch_selector is not None: + result["batch_selector"] = self.batch_selector + if self.batch_size is not None: + result["batch_size"] = self.batch_size + if self.batch_condition is not None: + result["batch_condition"] = self.batch_condition return result + def set_watermark( + self, + text: str = None, + color: str = None, + font: str = None, + opacity: int = None, + size: int = None, + rotation: int = None, + ): + """Set watermark + + Set a diagonal custom watermark on every page in the PDF file with a specific text, color, font, opacity and size. + Setting all to None will remove the watermark. + + Args: + text (str, optional): Requires PDF output, generates a diagonal custom watermark on every page of the PDF file. Defaults to None. + color (str, optional): Requires PDF output, specifies the font of the watermark specified, with a default of "black". Defaults to None. + font (str, optional): Requires PDF output, specifies the font of the watermark text specified, with a default of "Arial". Defaults to None. + opacity (int, optional): Requires PDF output, specifies the opacity of the watermark text specified, should be as a percentage, i.e. 45. Defaults to None. + size (int, optional): Requires PDF output, specifies the size of watermark text specified, should be a number in px, i.e. 45. Defaults to None. + rotation (int, optional): Requires PDF output, specifies the angle of watermark text specified, should be a number in px, i.e. 45. Defaults to None. + """ + self.watermark = text + self.watermark_color = color + self.watermark_font = font + self.watermark_opacity = opacity + self.watermark_font_size = size + self.watermark_rotation = rotation + def set_page_margin_at(self, value: int, position: str = None): """Set page_margin @@ -177,9 +261,7 @@ def set_page_margin_at(self, value: int, position: str = None): self.page_margin[position] = value elif self.page_margin is None: # page margin not yet defined, set it to a dict with this position defined - self.page_margin = { - position: value - } + self.page_margin = {position: value} else: # page margin defined but no dict, convert to dict first current = self.page_margin @@ -187,7 +269,7 @@ def set_page_margin_at(self, value: int, position: str = None): "top": current, "bottom": current, "left": current, - "right": current + "right": current, } self.page_margin[position] = value else: @@ -210,3 +292,17 @@ def page_orientation(self, value: str): value (str): the page orientation """ self._landscape = value == "landscape" + + def sign( + self, + certificate: Union[Base64Resource, ServerPathResource, URLResource], + password: str = None, + ): + """Sign the output PDF with a certificate file. + + Args: + certificate (str): Resource of the certificate file. + password (str): password of the certificate. Defaults to None. + """ + self.sign_certificate = certificate.data + self.sign_certificate_password = password diff --git a/cloudofficeprint/config/request_option.py b/cloudofficeprint/config/request_option.py new file mode 100644 index 0000000..04481aa --- /dev/null +++ b/cloudofficeprint/config/request_option.py @@ -0,0 +1,15 @@ +class requestOptions: + def __init__(self, + url: str, + extraHeaders: object, + ): + super() + self.url = url + self.extraHeaders = extraHeaders + + @property + def as_dict(self): + result = {} + result['url'] = self.url + result['extra_headers'] = self.extraHeaders + return result diff --git a/cloudofficeprint/config/server.py b/cloudofficeprint/config/server.py index 2d6645d..003241a 100644 --- a/cloudofficeprint/config/server.py +++ b/cloudofficeprint/config/server.py @@ -47,9 +47,7 @@ def _dict(self) -> Dict[str, str]: class Command: """Command object with a single command for the Cloud Office Print server.""" - def __init__(self, - command: str, - parameters: Mapping[str, str] = None): + def __init__(self, command: str, parameters: Mapping[str, str] = None): """ Args: command (str): The name of the command to execute. This command should be present in the aop_config.json file. @@ -65,9 +63,7 @@ def _dict(self) -> Dict[str, str]: Returns: Dict[str, str]: dict representation of this command """ - result = { - "command": self.command - } + result = {"command": self.command} if self.parameters: result["command_parameters"] = self.parameters @@ -96,13 +92,15 @@ def _dict_post(self) -> Dict[str, str]: class Commands: """Command hook configuration class.""" - def __init__(self, - post_process: Command = None, - post_process_return: bool = None, - post_process_delete_delay: int = None, - pre_conversion: Command = None, - post_conversion: Command = None, - post_merge: Command = None): + def __init__( + self, + post_process: Command = None, + post_process_return: bool = None, + post_process_delete_delay: int = None, + pre_conversion: Command = None, + post_conversion: Command = None, + post_merge: Command = None, + ): """ Args: post_process (Command, optional): Command to run after the given request has been processed but before returning back the output file. Defaults to None. @@ -152,13 +150,15 @@ def _dict(self) -> Dict: class ServerConfig: """Class for configuring the server options.""" - def __init__(self, - api_key: str = None, - logging: Mapping = None, - printer: Printer = None, - commands: Commands = None, - proxies: Dict[str, str] = None, - cop_remote_debug: bool = False): + def __init__( + self, + api_key: str = None, + logging: Mapping = None, + printer: Printer = None, + commands: Commands = None, + proxies: Dict[str, str] = None, + cop_remote_debug: bool = False, + ): """ Args: api_key (str, optional): API key to use for communicating with a Cloud Office Print server. Defaults to None. @@ -226,10 +226,9 @@ def url(self, value: str): Args: value (str): URL at which to contact the server """ - if (urlparse(value).scheme == ''): + if urlparse(value).scheme == "": self._url = "http://" + value - logging.warning( - f'No scheme found in "{value}", assuming "{self._url}".') + logging.warning(f'No scheme found in "{value}", assuming "{self._url}".') else: self._url = value @@ -240,8 +239,10 @@ def is_reachable(self) -> bool: bool: whether the server at `Server.url` is reachable """ try: - r = requests.get(urljoin( - self.url, "marco"), proxies=self.config.proxies if self.config is not None else None) + r = requests.get( + urljoin(self.url, "marco"), + proxies=self.config.proxies if self.config is not None else None, + ) return r.text == "polo" except requests.exceptions.ConnectionError: return False @@ -268,8 +269,7 @@ def _raise_if_unreachable(self): ConnectionError: raise error if server is unreachable """ if not self.is_reachable(): - raise ConnectionError( - f"Could not reach server at {self.url}") + raise ConnectionError(f"Could not reach server at {self.url}") def get_version_soffice(self) -> str: """Sends a GET request to server-url/soffice. @@ -278,7 +278,10 @@ def get_version_soffice(self) -> str: str: current version of Libreoffice installed on the server. """ self._raise_if_unreachable() - return requests.get(urljoin(self.url, 'soffice'), proxies=self.config.proxies if self.config is not None else None).text + return requests.get( + urljoin(self.url, "soffice"), + proxies=self.config.proxies if self.config is not None else None, + ).text def get_version_officetopdf(self) -> str: """Sends a GET request to server-url/officetopdf. @@ -287,7 +290,10 @@ def get_version_officetopdf(self) -> str: str: current version of OfficeToPdf installed on the server. (Only available if the server runs in Windows environment). """ self._raise_if_unreachable() - return requests.get(urljoin(self.url, 'officetopdf'), proxies=self.config.proxies if self.config is not None else None).text + return requests.get( + urljoin(self.url, "officetopdf"), + proxies=self.config.proxies if self.config is not None else None, + ).text def get_supported_template_mimetypes(self) -> Dict: """Sends a GET request to server-url/supported_template_mimetypes. @@ -296,7 +302,12 @@ def get_supported_template_mimetypes(self) -> Dict: Dict: JSON of the mime types of templates that Cloud Office Print supports. """ self._raise_if_unreachable() - return json.loads(requests.get(urljoin(self.url, 'supported_template_mimetypes'), proxies=self.config.proxies if self.config is not None else None).text) + return json.loads( + requests.get( + urljoin(self.url, "supported_template_mimetypes"), + proxies=self.config.proxies if self.config is not None else None, + ).text + ) def get_supported_output_mimetypes(self, input_type: str) -> Dict: """Sends a GET request to server-url/supported_output_mimetypes?template=input_type. @@ -309,7 +320,14 @@ def get_supported_output_mimetypes(self, input_type: str) -> Dict: Dict: JSON of the supported output types for the given template extension. """ self._raise_if_unreachable() - return json.loads(requests.get(urljoin(self.url, 'supported_output_mimetypes' + f'?template={input_type}'), proxies=self.config.proxies if self.config is not None else None).text) + return json.loads( + requests.get( + urljoin( + self.url, "supported_output_mimetypes" + f"?template={input_type}" + ), + proxies=self.config.proxies if self.config is not None else None, + ).text + ) def get_supported_prepend_mimetypes(self) -> Dict: """Sends a GET request to server-url/supported_prepend_mimetypes. @@ -318,7 +336,12 @@ def get_supported_prepend_mimetypes(self) -> Dict: Dict: JSON of the supported prepend file mime types. """ self._raise_if_unreachable() - return json.loads(requests.get(urljoin(self.url, 'supported_prepend_mimetypes'), proxies=self.config.proxies if self.config is not None else None).text) + return json.loads( + requests.get( + urljoin(self.url, "supported_prepend_mimetypes"), + proxies=self.config.proxies if self.config is not None else None, + ).text + ) def get_supported_append_mimetypes(self) -> Dict: """Sends a GET request to server-url/supported_append_mimetypes. @@ -327,7 +350,29 @@ def get_supported_append_mimetypes(self) -> Dict: Dict: JSON of the supported append file mime types. """ self._raise_if_unreachable() - return json.loads(requests.get(urljoin(self.url, 'supported_append_mimetypes'), proxies=self.config.proxies if self.config is not None else None).text) + return json.loads( + requests.get( + urljoin(self.url, "supported_append_mimetypes"), + proxies=self.config.proxies if self.config is not None else None, + ).text + ) + + def verify_template_hash(self, hashcode: str) -> bool: + """Sends a GET request to server-url/verify_template_hash?hash=hashcode. + + Args: + hashcode (str): md5 hash of file + + Returns: + bool: whether the hash is valid and present in cache. + """ + self._raise_if_unreachable() + return json.loads( + requests.get( + urljoin(self.url, "verify_template_hash" + f"?hash={hashcode}"), + proxies=self.config.proxies if self.config is not None else None, + ).text + )["valid"] def get_version_cop(self) -> str: """Sends a GET request to server-url/version. @@ -336,4 +381,27 @@ def get_version_cop(self) -> str: str: the version of Cloud Office Print that the server runs. """ self._raise_if_unreachable() - return requests.get(urljoin(self.url, 'version'), proxies=self.config.proxies if self.config is not None else None).text + return requests.get( + urljoin(self.url, "version"), + proxies=self.config.proxies if self.config is not None else None, + ).text + + def check_ipp(self, ipp_url: str, version: str) -> Dict: + """Sends a GET request to server-url/ipp_check?ipp_url=ipp_url&version=version. + + Args: + ippURL (str): the URL of the IPP printer. + version (str): the version of the IPP printer. + + Returns: + Dict: the status of the IPP printer. + """ + self._raise_if_unreachable() + return json.loads( + requests.get( + urljoin( + self.url, "ipp_check" + f"?ipp_url={ipp_url}&version={version}" + ), + proxies=self.config.proxies if self.config is not None else None, + ).text + ) diff --git a/cloudofficeprint/elements/__init__.py b/cloudofficeprint/elements/__init__.py index a10fdfc..888ee71 100644 --- a/cloudofficeprint/elements/__init__.py +++ b/cloudofficeprint/elements/__init__.py @@ -9,3 +9,4 @@ from .loops import * from .pdf import * from .rest_source import * +from .form import * diff --git a/cloudofficeprint/elements/charts.py b/cloudofficeprint/elements/charts.py index 9b04e12..0855b92 100644 --- a/cloudofficeprint/elements/charts.py +++ b/cloudofficeprint/elements/charts.py @@ -193,7 +193,11 @@ def __init__(self, background_opacity: int = None, title: str = None, title_style: ChartTextStyle = None, - grid: bool = None): + grid: bool = None, + holeSize: int = None, + firstSliceAngle: int = None, + enableAreaTransparency: bool = None + ): """ Args: x_axis (ChartAxisOptions, optional): The options for the x-axis. Defaults to None. @@ -210,6 +214,9 @@ def __init__(self, title (str, optional): The title of the chart. Defaults to None. title_style (ChartTextStyle, optional): The styling for the title of the chart. Defaults to None. grid (bool, optional): Whether or not the chart should have a grid. Defaults to None. + holeSize (int, optional): Hole size for doughnut chart (0-100). + firstSLiceAngle (int , optional): Angle of first slice for dough chart (0-360). Must be specified for holeSize option to work + enableAreaTransparency (bool, option): Whether to make area chart transparent. """ self._legend_options: dict = None self._data_labels_options: dict = None @@ -226,6 +233,9 @@ def __init__(self, self.title: str = title self.title_style: ChartTextStyle = title_style self.grid: bool = grid + self.holeSize: int = holeSize + self.firstSliceAngle: int = firstSliceAngle + self.enableAreaTransparency: bool = enableAreaTransparency def set_legend(self, position: str = 'r', style: ChartTextStyle = None): """Setter for the legend of the chart. @@ -325,6 +335,12 @@ def as_dict(self) -> Dict: result["titleStyle"] = self.title_style.as_dict if self.grid is not None: result["grid"] = self.grid + if self.firstSliceAngle is not None: + result["firstSliceAngle"] = self.firstSliceAngle + if self.holeSize is not None: + result["holeSize"] = self.holeSize + if self.enableAreaTransparency is not None: + result["enableAreaTransparency"] = self.enableAreaTransparency if self._legend_options is not None: result["legend"] = self._legend_options if self._data_labels_options is not None: @@ -655,7 +671,7 @@ def from_dataframe(cls, data: 'pandas.DataFrame', name: str = None) -> 'StockSer # better to have a series for every possible chart for future-proofing, in case their options diverge later BarSeries = BarStackedSeries = BarStackedPercentSeries = ColumnSeries = ColumnStackedSeries = ColumnStackedPercentSeries = ScatterSeries = XYSeries -RadarSeries = LineSeries +RadarSeries = LineStackedSeries = LineSeries class Chart(Element, ABC): @@ -715,6 +731,26 @@ def as_dict(self) -> Dict: "lines": [line.as_dict for line in self.lines], "type": "line" }) + +class LineStackedChart(Chart): + """Class for a line chart""" + + def __init__(self, name: str, lines: Tuple[Union[LineStackedSeries, XYSeries]], options: ChartOptions = None): + """ + Args: + name (str): The name of the chart. + lines (Tuple[Union[LineStackedSeries, XYSeries]]): Iterable of line series. + options (Union[ChartOptions, dict], optional): The options for the chart. Defaults to None. + """ + super().__init__(name, options) + self.lines: Tuple[Union[LineStackedSeries, XYSeries]] = lines + + @property + def as_dict(self) -> Dict: + return self._get_dict({ + "lines": [line.as_dict for line in self.lines], + "type": "lineStacked" + }) class BarChart(Chart): @@ -947,6 +983,25 @@ def as_dict(self) -> Dict: "areas": [area.as_dict for area in self.areas], "type": "area" }) +class AreaStackedChart(Chart): + """Class for an area stacked chart""" + + def __init__(self, name: str, areas: Tuple[Union[AreaSeries, XYSeries]], options: ChartOptions = None): + """ + Args: + name (str): The name of the chart. + areas (Tuple[Union[AreaSeries, XYSeries]]): Iterable of area series. + options (Union[ChartOptions, dict], optional): The options for the chart. Defaults to None. + """ + super().__init__(name, options) + self.areas: Tuple[Union[AreaSeries, XYSeries]] = areas + + @property + def as_dict(self) -> Dict: + return self._get_dict({ + "areas": [area.as_dict for area in self.areas], + "type": "areaStacked" + }) class ScatterChart(Chart): diff --git a/cloudofficeprint/elements/elements.py b/cloudofficeprint/elements/elements.py index fff9c51..e7482f5 100644 --- a/cloudofficeprint/elements/elements.py +++ b/cloudofficeprint/elements/elements.py @@ -39,25 +39,172 @@ def _dict_suffixes(self) -> Dict: class CellStyleDocx(CellStyle): """Cell styling settings for docx templates""" - def __init__(self, cell_background_color: str = None, width: Union[int, str] = None): + def __init__( + self, + cell_background_color: str = None, + width: Union[int, str] = None, + preserve_total_width_of_table: str = None, + border: str = None, + border_top: str = None, + border_bottom: str = None, + border_left: str = None, + border_right: str = None, + border_diagonal_down: str = None, + border_diagonal_up: str = None, + border_color: str = None, + border_top_color: str = None, + border_bottom_color: str = None, + border_left_color: str = None, + border_right_color: str = None, + border_diagonal_up_color: str = None, + border_diagonal_down_color: str = None, + border_size: Union[int, str] = None, + border_top_size: Union[int, str] = None, + border_bottom_size: Union[int, str] = None, + border_left_size: Union[int, str] = None, + border_right_size: Union[int, str] = None, + border_diagonal_up_size: Union[int, str] = None, + border_diagonal_down_size: Union[int, str] = None, + border_space: Union[int, str] = None, + border_top_space: Union[int, str] = None, + border_bottom_space: Union[int, str] = None, + border_left_space: Union[int, str] = None, + border_right_space: Union[int, str] = None, + border_diagonal_up_space: Union[int, str] = None, + border_diagonal_down_space: Union[int, str] = None, + ): """ Args: cell_background_color (str, optional): The background color of the cell. Defaults to None. width (Union[int, str], optional): The width of the cell. Defaults to None. + preserve_total_width_of_table (str, optional): Keeps table width constant by redistributing removed column's width to others. + border (str, optional): Applies the specified border style to all table edges (top, bottom, left, right). + border_top (str, optional): Applies the specified border style to the top edge of the table. + border_bottom (str, optional): Applies the specified border style to the bottom edge of the table. + border_left (str, optional): Applies the specified border style to the left edge of the table. + border_right (str, optional): Applies the specified border style to the right edge of the table. + border_diagonal_down (str, optional): Applies the specified border style to the diagonal line going from the top-left to the bottom-right corner. + border_diagonal_up (str, optional): Applies the specified border style to the diagonal line going from the bottom-left to the top-right corner. + border_color (str, optional): Sets the color of the borders (top, bottom, left, right). + border_top_color (str, optional): Sets the color of the top border. + border_bottom_color (str, optional): Sets the color of the bottom border. + border_left_color (str, optional): Sets the color of the left border. + border_right_color (str, optional): Sets the color of the right border. + border_diagonal_up_color (str, optional): Sets the color of the diagonal up border. + border_diagonal_down_color (str, optional): Sets the color of the diagonal down border. + border_size (Union[int, str], optional): Sets the width of the borders (top, bottom, left, right) in points. + border_top_size (Union[int, str], optional): Sets the width of the top border in points. + border_bottom_size (Union[int, str], optional): Sets the width of the bottom border in points. + border_left_size (Union[int, str], optional): Sets the width of the left border in points. + border_right_size (Union[int, str], optional): Sets the width of the right border in points. + border_diagonal_up_size (Union[int, str], optional): Sets the width of the diagonal up border in points. + border_diagonal_down_size (Union[int, str], optional): Sets the width of the diagonal down border in points. + border_space (Union[int, str], optional): Sets the spacing between the content and borders (top, bottom, left, right) in points. + border_top_space (Union[int, str], optional): Sets the spacing between the content and the top border in points. + border_bottom_space (Union[int, str], optional): Sets the spacing between the content and the bottom border in points. + border_left_space (Union[int, str], optional): Sets the spacing between the content and the left border in points. + border_right_space (Union[int, str], optional): Sets the spacing between the content and the right border in points. + border_diagonal_up_space (Union[int, str], optional): Sets the spacing between the content and the diagonal up border in points. + border_diagonal_down_space (Union[int, str], optional): Sets the spacing between the content and the diagonal down border in points. """ super().__init__() self.cell_background_color: str = cell_background_color self.width: Union[int, str] = width - + self.preserve_total_width_of_table: str = preserve_total_width_of_table + self.border: str = border + self.border_top: str = border_top + self.border_bottom: str = border_bottom + self.border_left: str = border_left + self.border_right: str = border_right + self.border_diagonal_down: str = border_diagonal_down + self.border_diagonal_up: str = border_diagonal_up + self.border_color: str = border_color + self.border_top_color: str = border_top_color + self.border_bottom_color: str = border_bottom_color + self.border_left_color: str = border_left_color + self.border_right_color: str = border_right_color + self.border_diagonal_up_color: str = border_diagonal_up_color + self.border_diagonal_down_color: str = border_diagonal_down_color + self.border_size: Union[int, str] = border_size + self.border_top_size: Union[int, str] = border_top_size + self.border_bottom_size: Union[int, str] = border_bottom_size + self.border_left_size: Union[int, str] = border_left_size + self.border_right_size: Union[int, str] = border_right_size + self.border_diagonal_up_size: Union[int, str] = border_diagonal_up_size + self.border_diagonal_down_size: Union[int, str] = border_diagonal_down_size + self.border_space: Union[int, str] = border_space + self.border_top_space: Union[int, str] = border_top_space + self.border_bottom_space: Union[int, str] = border_bottom_space + self.border_left_space: Union[int, str] = border_left_space + self.border_right_space: Union[int, str] = border_right_space + self.border_diagonal_up_space: Union[int, str] = border_diagonal_up_space + self.border_diagonal_down_space: Union[int, str] = border_diagonal_down_space + @property def _dict_suffixes(self): result = super()._dict_suffixes - if self.cell_background_color is not None: - result['_cell_background_color'] = self.cell_background_color + result["_cell_background_color"] = self.cell_background_color if self.width is not None: - result['_width'] = self.width - + result["_width"] = self.width + if self.preserve_total_width_of_table is not None: + result["_preserve_total_width_of_table"] = self.preserve_total_width_of_table + if self.border is not None: + result["_border"] = self.border + if self.border_top is not None: + result["_border_top"] = self.border_top + if self.border_bottom is not None: + result["_border_bottom"] = self.border_bottom + if self.border_left is not None: + result["_border_left"] = self.border_left + if self.border_right is not None: + result["_border_right"] = self.border_right + if self.border_diagonal_down is not None: + result["_border_diagonal_down"] = self.border_diagonal_down + if self.border_diagonal_up is not None: + result["_border_diagonal_up"] = self.border_diagonal_up + if self.border_color is not None: + result["_border_color"] = self.border_color + if self.border_top_color is not None: + result["_border_top_color"] = self.border_top_color + if self.border_bottom_color is not None: + result["_border_bottom_color"] = self.border_bottom_color + if self.border_left_color is not None: + result["_border_left_color"] = self.border_left_color + if self.border_right_color is not None: + result["_border_right_color"] = self.border_right_color + if self.border_diagonal_up_color is not None: + result["_border_diagonal_up_color"] = self.border_diagonal_up_color + if self.border_diagonal_down_color is not None: + result["_border_diagonal_down_color"] = self.border_diagonal_down_color + if self.border_size is not None: + result["_border_size"] = self.border_size + if self.border_top_size is not None: + result["_border_top_size"] = self.border_top_size + if self.border_bottom_size is not None: + result["_border_bottom_size"] = self.border_bottom_size + if self.border_left_size is not None: + result["_border_left_size"] = self.border_left_size + if self.border_right_size is not None: + result["_border_right_size"] = self.border_right_size + if self.border_diagonal_up_size is not None: + result["_border_diagonal_up_size"] = self.border_diagonal_up_size + if self.border_diagonal_down_size is not None: + result["_border_diagonal_down_size"] = self.border_diagonal_down_size + if self.border_space is not None: + result["_border_space"] = self.border_space + if self.border_top_space is not None: + result["_border_top_space"] = self.border_top_space + if self.border_bottom_space is not None: + result["_border_bottom_space"] = self.border_bottom_space + if self.border_left_space is not None: + result["_border_left_space"] = self.border_left_space + if self.border_right_space is not None: + result["_border_right_space"] = self.border_right_space + if self.border_diagonal_up_space is not None: + result["_border_diagonal_up_space"] = self.border_diagonal_up_space + if self.border_diagonal_down_space is not None: + result["_border_diagonal_down_space"] = self.border_diagonal_down_space return result @@ -91,7 +238,12 @@ def __init__( border_diagonal_color: str = None, text_h_alignment: str = None, text_v_alignment: str = None, - text_rotation: Union[int, str] = None + text_rotation: Union[int, str] = None, + wrap_text: bool = False, + width: Union[int, str] = None, + height: Union[int, str] = None, + max_characters : Union[int, str] = None, + height_scaling : Union[int, str] = None, ): """ Args: @@ -120,7 +272,12 @@ def __init__( border_diagonal_color (str, optional): hex color e.g: #000000. Defaults to None. text_h_alignment (str, optional): [top|bottom|center|justify]. Defaults to None. text_v_alignment (str, optional): [top|bottom|center|justify]. Defaults to None. - text_rotation (Union[int, str], optional): rotation of text value from 0-90 degrees. Defaults to None. + text_rotation (Union[int, str], optional): Rotation of text value from 0-90 degrees. Defaults to None. + wrap_text (bool, optional): Set to true for wrap text. When false (default )S,the property won't be included in the output. + width (Union[int, str], optional): Provide a custom width to the cell. Supported units: inch, cm, px, pt, em, Excel Units(eu) + height (Union[int, str], optional): Provide custom height to the cell. Supported units: inch, cm, px, pt, em, Excel Units(eu) + max_characters (Union[int, str], optional): Provide width for the cell. + height_scaling (Union[int, str], optional): Adjusts cell height for consistent rendering. """ super().__init__() self.cell_locked: bool = cell_locked @@ -149,69 +306,87 @@ def __init__( self.text_h_alignment: str = text_h_alignment self.text_v_alignment: str = text_v_alignment self.text_rotation: Union[int, str] = text_rotation + self.wrap_text: bool = wrap_text + self.width: Union[int, str] = width + self.height: Union[int, str] = height + self.max_characters: Union[int, str] = max_characters + self.height_scaling: Union[int, str] = height_scaling + + + @property def _dict_suffixes(self): result = super()._dict_suffixes if self.cell_locked is not None: - result['_cell_locked'] = self.cell_locked + result["_cell_locked"] = self.cell_locked if self.cell_hidden is not None: - result['_cell_hidden'] = self.cell_hidden + result["_cell_hidden"] = self.cell_hidden if self.cell_background is not None: - result['_cell_background'] = self.cell_background + result["_cell_background"] = self.cell_background if self.font_name is not None: - result['_font_name'] = self.font_name + result["_font_name"] = self.font_name if self.font_size is not None: - result['_font_size'] = self.font_size + result["_font_size"] = self.font_size if self.font_color is not None: - result['_font_color'] = self.font_color + result["_font_color"] = self.font_color if self.font_italic is not None: - result['_font_italic'] = self.font_italic + result["_font_italic"] = self.font_italic if self.font_bold is not None: - result['_font_bold'] = self.font_bold + result["_font_bold"] = self.font_bold if self.font_strike is not None: - result['_font_strike'] = self.font_strike + result["_font_strike"] = self.font_strike if self.font_underline is not None: - result['_font_underline'] = self.font_underline + result["_font_underline"] = self.font_underline if self.font_superscript is not None: - result['_font_superscript'] = self.font_superscript + result["_font_superscript"] = self.font_superscript if self.font_subscript is not None: - result['_font_subscript'] = self.font_subscript + result["_font_subscript"] = self.font_subscript if self.border_top is not None: - result['_border_top'] = self.border_top + result["_border_top"] = self.border_top if self.border_top_color is not None: - result['_border_top_color'] = self.border_top_color + result["_border_top_color"] = self.border_top_color if self.border_bottom is not None: - result['_border_bottom'] = self.border_bottom + result["_border_bottom"] = self.border_bottom if self.border_bottom_color is not None: - result['_border_bottom_color'] = self.border_bottom_color + result["_border_bottom_color"] = self.border_bottom_color if self.border_left is not None: - result['_border_left'] = self.border_left + result["_border_left"] = self.border_left if self.border_left_color is not None: - result['_border_left_color'] = self.border_left_color + result["_border_left_color"] = self.border_left_color if self.border_right is not None: - result['_border_right'] = self.border_right + result["_border_right"] = self.border_right if self.border_right_color is not None: - result['_border_right_color'] = self.border_right_color + result["_border_right_color"] = self.border_right_color if self.border_diagonal is not None: - result['_border_diagonal'] = self.border_diagonal + result["_border_diagonal"] = self.border_diagonal if self.border_diagonal_direction is not None: - result['_border_diagonal_direction'] = self.border_diagonal_direction + result["_border_diagonal_direction"] = self.border_diagonal_direction if self.border_diagonal_color is not None: - result['_border_diagonal_color'] = self.border_diagonal_color + result["_border_diagonal_color"] = self.border_diagonal_color if self.text_h_alignment is not None: - result['_text_h_alignment'] = self.text_h_alignment + result["_text_h_alignment"] = self.text_h_alignment if self.text_v_alignment is not None: - result['_text_v_alignment'] = self.text_v_alignment + result["_text_v_alignment"] = self.text_v_alignment if self.text_rotation is not None: - result['_text_rotation'] = self.text_rotation + result["_text_rotation"] = self.text_rotation + if self.wrap_text is True: + result["_wrap_text"] = self.wrap_text + if self.width is not None: + result["_width"] = self.width + if self.height is not None: + result["_height"] = self.height + if self.max_characters is not None: + result["_max_characters"] = self.max_characters + if self.height_scaling is not None: + result["_height_scaling"] = self.height_scaling return result class Element(ABC): - """ The abstract base class for elements.""" + """The abstract base class for elements.""" def __init__(self, name: str): """ @@ -292,9 +467,7 @@ def available_tags(self) -> FrozenSet[str]: @property def as_dict(self) -> Dict: - return { - self.name: self.value - } + return {self.name: self.value} class CellStyleProperty(Property): @@ -314,9 +487,7 @@ def available_tags(self) -> FrozenSet[str]: @property def as_dict(self) -> Dict: - result = { - self.name: self.value - } + result = {self.name: self.value} for suffix, value in self.cell_style._dict_suffixes.items(): result[self.name + suffix] = value @@ -325,18 +496,56 @@ def as_dict(self) -> Dict: class Html(Property): - def __init__(self, name: str, value: str): + def __init__( + self, name: str, + value: str, + custom_table_style: str, + unordered_list_style: Union[str, int], + ordered_list_style: Union[str, int], + use_tag_style: bool, + ignore_cell_margin: bool, + ignore_empty_p: bool + ): """ Args: name (str): The name for this property. value (str): The value for this property. + custom_table_style (str): Specify custom table style + unordered_list_style (str): Create and customize ordered list + ordered_list_style (str): Create and customize unordered list + use_tag_style (bool): Use the styling from the template instead of default Word styling + ignore_cell_margin (bool): Ignore empty paragraphs within HTML content + ignore_empty_p (bool): Ignore the cell margins in an HTML table cell when the text content is large """ super().__init__(name, value) - + self.custom_table_style: str = custom_table_style + self.unordered_list_style: Union[str, int] = unordered_list_style + self.ordered_list_style: Union[str, int] = ordered_list_style + self.use_tag_style: bool = use_tag_style + self.ignore_cell_margin: bool = ignore_cell_margin + self.ignore_empty_p: bool = ignore_empty_p + @property def available_tags(self) -> FrozenSet[str]: return frozenset({"{_" + self.name + "}"}) - + + @property + def as_dict(self) -> Dict: + result = {self.name: self.value} + + if self.custom_table_style is not None: + result[self.name + "_custom_table_style"] = self.custom_table_style + if self.unordered_list_style is not None: + result[self.name + "_unordered_list_style"] = self.unordered_list_style + if self.ordered_list_style is not None: + result[self.name + "_ordered_list_style"] = self.ordered_list_style + if self.use_tag_style is not None: + result[self.name + "_use_tag_style"] = self.use_tag_style + if self.ignore_cell_margin is not None: + result[self.name + "_ignore_cell_margin"] = self.ignore_cell_margin + if self.ignore_empty_p is not None: + result[self.name + "_ignore_empty_p"] = self.ignore_empty_p + return result class RightToLeft(Property): def __init__(self, name: str, value: str): @@ -367,20 +576,47 @@ def available_tags(self) -> FrozenSet[str]: class AutoLink(Property): - """ This tag allows you to insert text into the document detecting links. + """ This tag allows you to insert text into the document detecting links. + For PPTX templates, additional styling options are available including: + - Custom font color for hyperlinks + - Custom underline color + - Option to preserve template styling """ - def __init__(self, name: str, value: str): + + def __init__(self, + name: str, + value: str, + font_color: Union[str, None] = None, + underline_color: Union[str, None] = None, + preserve_tag_style: Union[bool, str, None] = None): """ Args: name (str): The name for this element. value (str): The value of the autoLink. + font_color (str, optional): PPTX-only The font color of autolink. + underline_color (str, optional): The underline color of autolink. + preserve_tag_style (str or bool, optional): Take the styling of hyperlink text defined in the template (blue and underlined by default). """ - super().__init__(name,value) + super().__init__(name, value) + self.value: str = value + self.font_color = font_color + self.underline_color = underline_color + self.preserve_tag_style = preserve_tag_style @property def available_tags(self) -> FrozenSet[str]: return frozenset({"{*auto " + self.name + "}"}) - + @property + def as_dict(self) -> Dict : + result ={self.name:self.value} + if self.font_color is not None: + result[f"{self.name}_font_color"] = self.font_color + if self.underline_color is not None: + result[f"{self.name}_underline_color"] = self.underline_color + if self.preserve_tag_style is not None: + result[f"{self.name}_preserve_tag_style"] = self.preserve_tag_style + return result + class Hyperlink(Element): def __init__(self, name: str, url: str, text: str = None): """ @@ -388,10 +624,16 @@ def __init__(self, name: str, url: str, text: str = None): name (str): The name for this element. url (str): The URL for the hyperlink. text (str, optional): The text for the hyperlink. Defaults to None. + font_color (str, optional): PPTX ONLY -The font color of text for hyperlink. ( optional) + underline_color (str, optional): PPTX ONLY -The underline color of text for hyperlink. ( optional) + preserve_tag_style (str or bool, optional): For PPTX & Word- Take the styling of hyperlink text defined in the template (blue and underlined by default). ( optional) """ super().__init__(name) self.url: str = url - self.text: str = text + self.text: Union[str, None] = None + self.font_color: Union[str, None] = None + self.underline_color: Union[str, None] = None + self.preserve_tag_style: Union[str, bool, None] = None @property def available_tags(self) -> FrozenSet[str]: @@ -399,18 +641,22 @@ def available_tags(self) -> FrozenSet[str]: @property def as_dict(self) -> Dict: - result = { - self.name: self.url - } + result = {self.name: self.url} if self.text is not None: result[self.name + "_text"] = self.text + if (self.text is not None) and (self.font_color is not None): + result[self.text + "_font_color"] = self.font_color + if (self.text is not None) and (self.underline_color is not None): + result[self.text + "_underline_color"] = self.underline_color + if (self.preserve_tag_style is not None): + result[self.name + "_preserve_tag_style"] = self.preserve_tag_style return result - - class TableOfContents(Element): - def __init__(self, name: str, title: str = None, depth: int = None, tab_leader: str = None): + def __init__( + self, name: str, title: str = None, depth: int = None, tab_leader: str = None + ): """ Args: name (str): The name for this element. @@ -477,7 +723,7 @@ def as_dict(self) -> Dict: return { self.name: self.value, self.name + "_row_span": self.rows, - self.name + "_col_span": self.columns + self.name + "_col_span": self.columns, } @@ -496,17 +742,19 @@ def available_tags(self) -> FrozenSet[str]: class StyledProperty(Property): - def __init__(self, - name: str, - value: str, - font: str = None, - font_size: Union[str, int] = None, - font_color: str = None, - bold: bool = None, - italic: bool = None, - underline: bool = None, - strikethrough: bool = None, - highlight_color: str = None): + def __init__( + self, + name: str, + value: str, + font: str = None, + font_size: Union[str, int] = None, + font_color: str = None, + bold: bool = None, + italic: bool = None, + underline: bool = None, + strikethrough: bool = None, + highlight_color: str = None, + ): """ Args: name (str): The name for this property. @@ -536,9 +784,7 @@ def available_tags(self) -> FrozenSet[str]: @property def as_dict(self) -> Dict: - result = { - self.name: self.value - } + result = {self.name: self.value} if self.font is not None: result[self.name + "_font_family"] = self.font @@ -561,15 +807,17 @@ def as_dict(self) -> Dict: class Watermark(Property): - def __init__(self, - name: str, - text: str, - color: str = None, - font: str = None, - width: Union[int, str] = None, - height: Union[int, str] = None, - opacity: float = None, - rotation: int = None): + def __init__( + self, + name: str, + text: str, + color: str = None, + font: str = None, + width: Union[int, str] = None, + height: Union[int, str] = None, + opacity: float = None, + rotation: int = None, + ): """ Args: name (str): The name for this property. @@ -595,9 +843,7 @@ def available_tags(self) -> FrozenSet[str]: @property def as_dict(self) -> Dict: - result = { - self.name: self.value - } + result = {self.name: self.value} if self.color is not None: result[self.name + "_color"] = self.color @@ -633,12 +879,10 @@ def available_tags(self) -> FrozenSet[str]: @property def as_dict(self) -> Dict: - result = { - self.name: self.code - } + result = {self.name: self.code} if self.data is not None: - result[self.name + '_data'] = self.data + result[self.name + "_data"] = self.data return result @@ -646,15 +890,14 @@ def as_dict(self) -> Dict: class COPChartDateOptions: """Date options for an COPChart (different from ChartDateOptions in charts.py).""" - def __init__(self, - format: str = None, - unit: str = None, - step: Union[int, str] = None): + def __init__( + self, format: str = None, unit: str = None, step: Union[int, str] = None + ): """ Args: format (str, optional): The format to display the date on the chart's axis. Defaults to None. unit (str, optional): The unit to be used for spacing the axis values. Defaults to None. - step (Union[int, str], optional): How many of the above unit should be used for spacing the axis values (automatic if undefined). + step (Union[int, str], optional): How many of the above unit should be used for spacing the axis values (automatic if undefined). This option is not supported in LibreOffice. Defaults to None. """ self.format: str = format @@ -678,16 +921,21 @@ def as_dict(self) -> Dict: class COPChart(Element): """The class for an COPChart. This is used for chart templating.""" - def __init__(self, - name: str, - x_data: Iterable[Union[str, int, float, Mapping]], - y_datas: Union[Iterable[Iterable[Union[str, int, float, Mapping]]], Mapping[str, Iterable[Union[str, int, float, Mapping]]]], - date: COPChartDateOptions = None, - title: str = None, - x_title: str = None, - y_title: str = None, - y2_title: str = None, - x2_title: str = None): + def __init__( + self, + name: str, + x_data: Iterable[Union[str, int, float, Mapping]], + y_datas: Union[ + Iterable[Iterable[Union[str, int, float, Mapping]]], + Mapping[str, Iterable[Union[str, int, float, Mapping]]], + ], + date: COPChartDateOptions = None, + title: str = None, + x_title: str = None, + y_title: str = None, + y2_title: str = None, + x2_title: str = None, + ): """ Args: name (str): The name for this element. @@ -711,16 +959,15 @@ def __init__(self, self.y_datas: Dict[str, Iterable[Union[str, int, float]]] = None """If the argument 'y_datas' is of type Iterable[Iterable], then default names (e.g. series 1, series 2, ...) will be used.""" if isinstance(y_datas, Mapping): - self.y_datas = { - name: list(data) for name, data in y_datas.items() - } + self.y_datas = {name: list(data) for name, data in y_datas.items()} elif isinstance(y_datas, Iterable): self.y_datas = { f"series {i+1}": list(data) for i, data in enumerate(y_datas) } else: raise TypeError( - f'Expected Mapping or Iterable for y_data, got "{type(y_datas)}"') + f'Expected Mapping or Iterable for y_data, got "{type(y_datas)}"' + ) self.date: COPChartDateOptions = date self.title: str = title @@ -730,15 +977,17 @@ def __init__(self, self.y2_title: str = y2_title @classmethod - def from_dataframe(cls, - name: str, - data: 'pandas.DataFrame', - date: COPChartDateOptions = None, - title: str = None, - x_title: str = None, - y_title: str = None, - y2_title: str = None, - x2_title: str = None) -> 'COPChart': + def from_dataframe( + cls, + name: str, + data: "pandas.DataFrame", + date: COPChartDateOptions = None, + title: str = None, + x_title: str = None, + y_title: str = None, + y2_title: str = None, + x2_title: str = None, + ) -> "COPChart": """Construct an COPChart object from a [Pandas dataframe](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html). Args: @@ -761,7 +1010,9 @@ def from_dataframe(cls, for col_name, col_data in y_frame.iteritems(): y_datas[col_name] = col_data - return cls(name, x_data, y_datas, date, title, x_title, y_title, y2_title, x2_title) + return cls( + name, x_data, y_datas, date, title, x_title, y_title, y2_title, x2_title + ) @property def as_dict(self) -> Dict: @@ -770,26 +1021,25 @@ def as_dict(self) -> Dict: "data": self.x_data, }, "yAxis": { - "series": [{ - "name": name, - "data": data - } for name, data in self.y_datas.items()] - } + "series": [ + {"name": name, "data": data} for name, data in self.y_datas.items() + ] + }, } if self.title is not None: result["title"] = self.title if self.date is not None: - result['xAxis']['date'] = self.date.as_dict + result["xAxis"]["date"] = self.date.as_dict if self.x_title is not None: result["xAxis"]["title"] = self.x_title if self.y_title is not None: result["yAxis"]["title"] = self.y_title if self.x2_title is not None: - result['x2Axis'] = {} + result["x2Axis"] = {} result["x2Axis"]["title"] = self.x2_title if self.y2_title is not None: - result['y2Axis'] = {} + result["y2Axis"] = {} result["y2Axis"]["title"] = self.y2_title return {self.name: result} @@ -835,15 +1085,17 @@ def available_tags(self) -> FrozenSet[str]: class TextBox(Element): """This tag will allow you to insert a text box starting in the cell containing the tag in Excel.""" - def __init__(self, - name: str, - value: str, - font: str = None, - font_color: str = None, - font_size: Union[int, str] = None, - transparency: Union[int, str] = None, - width: Union[int, str] = None, - height: Union[int, str] = None): + def __init__( + self, + name: str, + value: str, + font: str = None, + font_color: str = None, + font_size: Union[int, str] = None, + transparency: Union[int, str] = None, + width: Union[int, str] = None, + height: Union[int, str] = None, + ): """ Args: name (str): The name for this element. @@ -870,22 +1122,20 @@ def available_tags(self) -> FrozenSet[str]: @property def as_dict(self) -> Dict: - result = { - self.name: self.value - } + result = {self.name: self.value} if self.font is not None: - result[self.name + '_font'] = self.font + result[self.name + "_font"] = self.font if self.font_color is not None: - result[self.name + '_font_color'] = self.font_color + result[self.name + "_font_color"] = self.font_color if self.font_size is not None: - result[self.name + '_font_size'] = self.font_size + result[self.name + "_font_size"] = self.font_size if self.transparency is not None: - result[self.name + '_transparency'] = self.transparency + result[self.name + "_transparency"] = self.transparency if self.width is not None: - result[self.name + '_width'] = self.width + result[self.name + "_width"] = self.width if self.height is not None: - result[self.name + '_height'] = self.height + result[self.name + "_height"] = self.height return result @@ -910,21 +1160,473 @@ def available_tags(self) -> FrozenSet[str]: class Insert(Property): - """Inside Word and PowerPoint documents, the tag {?insert fileToInsert} can be used to insert files like Word, Excel, Powerpoint and PDF documents.""" + """Inside Word and PowerPoint and Excel documents, the tag {?insert fileToInsert} can be used to insert files like Word, Excel, Powerpoint and PDF documents. + Please use `ExcelInsert` element to insert in excel with more flexibility. + """ + + def __init__(self, name: str, value: str): + """ + Args: + name (str): The name for the insert tag. + value (str): Base64 encoded document that needs to be inserted in output docx or pptx. + The document can be docx, pptx, xlsx, or pdf documents. + """ + super().__init__(name, value) + + @property + def available_tags(self) -> FrozenSet[str]: + return frozenset({"{?insert " + self.name + "}"}) + +class PdfInclude(Element): + """Inside Word and PowerPoint and Excel documents, the tag {?include pdf } can be used to include files like Word, Excel, Powerpoint and PDF documents. + Please use `ExcelInsert` element to insert in excel with more flexibility. + """ + def __init__(self, name: str , value: str, filename: str, mime_type: str, file_content: str, file_source: str): + """ + Args: + name (str): The tag name referenced in templates + filename (str): Name of the file to include + mime_type (str): MIME type of the content (e.g., 'image/png') + file_content (str): Base64 encoded content of the file + file_source (str): Source type ('base64', 'local', etc.) + """ + super().__init__(name) + self.value = value + self.filename = filename + self.mime_type = mime_type + self.file_content = file_content + self.file_source = file_source + + @property + def available_tags(self) -> FrozenSet[str]: + return frozenset({"{?pdfinclude " + self.name + "}"}) + + + @property + def as_dict(self) -> Dict: + result = {} + result [self.name] = {} + + if self.filename is not None: + result [self.name]["name"] = self.filename + if self.mime_type is not None: + result [self.name]["mime_type"] = self.mime_type + if self.file_content is not None: + result [self.name]["file_content"] = self.file_content + if self.file_source is not None: + result [self.name]["file_source"] = self.file_source + + return result + + +class PptxShapeRemove(Property): + """Allows the removal of an entire shape / text-box if the associated tag evaluates to false. For example, if a template slide includes a text box with the tag {toShow?} and + the value of toShow is false or undefined, the entire shape will be removed from the slide. + """ + def __init__(self, name: str, value: Union[bool, str]): + """ + Args: + name (str): The name for the remove tag. + value (bool or string): False (to remove the shape / text-box) or string/True + The document should be, pptx. + """ + super().__init__(name, value) + + @property + def available_tags(self) -> FrozenSet[str]: + return frozenset({"{ " + self.name + "?" + "}"}) + + +class HideSlide(Property): + """Allows hiding a slide. + LIMITATION: using _hide for slide hide is that it can only be used for hiding slides during generation(!slideGeneration) + """ + def __init__(self, name: str, condition : str ): + """ + Args: + name (str): Name/identifier for this hide condition + condition (str): The condition to determine when to hide the slide + The document should be, pptx. + """ + super().__init__(name, condition) + + @property + def available_tags(self) -> FrozenSet[str]: + return frozenset({"{hide " + self.name + "}"}) + +class HideSheets(Property): + """Allows hiding a sheet in Excel documents. + Can be used to hide sheets based on conditions during generation. + The hide tag {hide condition} is replaced by nothing but will hide the sheet if the condition evaluates to true. + The condition can use any Angular expressions that are supported. + + """ + def __init__(self, name: str, condition: str): + """ + Args: + name (str): Name/identifier for this hide condition + condition (str): Angular expression that determines when to hide the sheet. + The document must be an Excel workbook (.xlsx) + """ + super().__init__(name, condition) + + @property + def available_tags(self) -> FrozenSet[str]: + return frozenset({"{hide " + self.name + "}"}) + + +class ExcelInsert(Element): + """Inside Excel it is posiible to insert word, powerpoint, excel and pdf file using AOP tag {?insert fileToInsert}. + Options available are: you can provide dynamic icon and icon position. """ - Args: - name (str): The name for the insert tag. - value (str): Base64 encoded document that needs to be inserted in output docx or pptx. - The documnet can be docx, pptx, xlsx, or pdf documents. + + def __init__(self, + name: str, + value: str, + # isPreview: bool = None, + icon: str = None, + fromRow: int = None, + fromCol: Union[str, int] = None, + fromRowOff: str = None, + fromColOff: str = None, + toRow: int = None, + toCol: Union[str, int] = None, + toRowOff: str = None, + toColOff: str = None + ): + """It is possible to provide dynamic icon and position of icon. + + Args: + name (str): Name of insert tag. Ex(fileToInsert) + value (str): File to insert of path to file. (Source can be FTP, SFTP, URL or base64encoded file.) + icon (str, optional): Icon that links the file to insert. Once clicked on it, opens the file inserted. If it is not provide default icon is used. + fromRow (int, optional): position for top of icon. Defaults to row of the tag. + fromCol (Union[str,int], optional): positon for left of icon. Defaults to column of the tag. + fromRowOff (str, optional): space after the value of from Row. Defaults to 0. + fromColOff (str, optional): space after the value of fromCol. Defaults to 0. + toRow (int, optional): position for bottom of icon. Defaults to row of the tag + 3. + toCol (Union[str,int], optional): position for right side of icon. Defaults to column of the tag. + toRowOff (str, optional): space after toRow value. Defaults to 20px. + toColOff (str, optional): space after toCol value. Defaults to 50px. + """ + super().__init__(name) + self.value: str = value + # self.isPreview: bool = isPreview + self.icon: str = icon + self.fromRow: int = fromRow + self.fromCol: Union[str, int] = fromCol + self.fromRowOff: str = fromRowOff + self.fromColOff: str = fromColOff + self.toRow: int = toRow + self.toCol: Union[str, int] = toCol + self.toRowOff: str = toRowOff + self.toColOff: str = toColOff + + @property + def as_dict(self) -> Dict: + result = { + self.name: self.value + } + # if self.isPreview is not None: + # result[self.name+'_isPreview'] = self.isPreview + if self.icon is not None: + result[self.name+'_icon'] = self.icon + if self.fromRow is not None: + result[self.name+'_fromRow'] = self.fromRow + if self.fromCol is not None: + result[self.name+'_fromCol'] = self.fromCol + if self.fromRowOff is not None: + result[self.name+'_fromRowOff'] = self.fromRowOff + if self.fromColOff is not None: + result[self.name+'_fromColOff'] = self.fromColOff + if self.toRow is not None: + result[self.name+'_toRow'] = self.toRow + if self.toCol is not None: + result[self.name+'_toCol'] = self.toCol + if self.toRowOff is not None: + result[self.name+'_toRowOff'] = self.toRowOff + if self.toColOff is not None: + result[self.name+'_toColOff'] = self.toColOff + + return result + + @property + def available_tags(self) -> FrozenSet[str]: + return frozenset({"{?insert fileToInsert}"}) + + +class Embed(Property): + """Inside Word, it is possible to copy the content of one docx file to the template without rendering. + + To do so, you can use AOP embed tag as {?embed fileToEmbed} where fileToEmbed contains the path of file or file itself. + + The content of fileToEmbed replaces the tag + + Only supported in Word and only supports docx file to embed. """ def __init__(self, name: str, value: str): + """It takes the tagName and its value as parameter. + + Args: + name (str): Name of the tag (ex. fileToEmbed) + value (str): File to embed. Source can be FTP, SFTP, URL or base64 encoded file. (ex. base64encoded string) + """ super().__init__(name, value) @property def available_tags(self) -> FrozenSet[str]: - return frozenset({"{?insert " + self.name + "}"}) + return frozenset({"{?embed fileToEmbed}"}) + + +class SheetProtection(Element): + """Inside Excel documents, this tag can be used to make password protected sheets. This tag has the feature of password along with different other features. + + Note: value is considered password, so try to use only one (either value or passowrd). + """ + + def __init__(self, + name: str, + value: str = None, + autoFilter: str = None, + deleteColumns: bool = None, + deleteRows: bool = None, + formatCells: bool = None, + formatColumns: bool = None, + formatRows: bool = None, + insertColumns: bool = None, + insertHyperlinks: bool = None, + insertRows: bool = None, + password: str = None, + pivotTables: bool = None, + selectLockedCells: bool = None, + selectUnlockedCells: bool = None, + sort: bool = None, + ): + """ + Args: + name (str): The name for the sheet protection tag. + value (str): Value for the tag; this is used as password + autoFilter (str): lock auto filter in sheet. + deleteColumns (bool): lock delete columns in sheet. + deleteRows (bool): lock delete rows in sheet. + formatCells (bool): lock format cells. + formatColumns (bool): lock format columns. + formatRows (bool): lock format rows. + insertColumns (bool): lock insert columns. + insertHyperlinks (bool): lock insert hyperlinks. + insertRows (bool): lock insert rows. + password (str): password to lock with. + pivotTables (bool): lock pivot tables. + selectLockedCells (bool): lock select locked cells. + selectUnlockedCells (bool): lock select unlocked cells. + sort (bool): lock sort. + """ + super().__init__(name) + self.value = value + self.autoFilter = autoFilter + self.deleteColumns = deleteColumns + self.deleteRows = deleteRows + self.formatCells = formatCells + self.formatColumns = formatColumns + self.formatRows = formatRows + self.insertColumns = insertColumns + self.insertHyperlinks = insertHyperlinks + self.insertRows = insertRows + self.password = password + self.pivotTables = pivotTables + self.selectLockedCells = selectLockedCells + self.selectUnlockedCells = selectUnlockedCells + self.sort = sort + + @property + def available_tags(self) -> FrozenSet[str]: + return frozenset({"{protect " + self.name + "}"}) + + @property + def as_dict(self) -> Dict: + result = {} + if self.value is not None: + result[self.name] = self.value + if self.autoFilter is not None: + result[self.name+'_allow_auto_filter'] = self.autoFilter + if self.deleteColumns is not None: + result[self.name+'_allow_delete_columns'] = self.deleteColumns + if self.deleteRows is not None: + result[self.name+'_allow_delete_rows'] = self.deleteRows + if self.formatCells is not None: + result[self.name+'_allow_format_cells'] = self.formatCells + if self.formatColumns is not None: + result[self.name+'_allow_format_columns'] = self.formatColumns + if self.formatRows is not None: + result[self.name+'_allow_format_rows'] = self.formatRows + if self.insertColumns is not None: + result[self.name+'_allow_insert_columns'] = self.insertColumns + if self.insertHyperlinks is not None: + result[self.name+'_allow_insert_hyperlinks'] = self.insertHyperlinks + if self.insertRows is not None: + result[self.name+'_allow_insert_rows'] = self.insertRows + if self.password is not None: + result[self.name+'_password'] = self.password + if self.pivotTables is not None: + result[self.name+'_allow_pivot_tables'] = self.pivotTables + if self.selectLockedCells is not None: + result[self.name+'_allow_select_locked_cells'] = self.selectLockedCells + if self.selectUnlockedCells is not None: + result[self.name+'_allow_select_unlocked_cells'] = self.selectUnlockedCells + if self.sort is not None: + result[self.name+'_allow_sort'] = self.sort + return result + + +class ValidateCell(Element): + """ + It is possible to insert cell validation in excel using validate tag as {validate validateTag} (validate keyword followed by tagName) + """ + + def __init__(self, + name: str, + ignoreBlank: bool = None, + allow: str = None, + value1: str = None, + value2: str = None, + inCellDropdown: bool = None, + data: str = None, + showInputMessage: bool = None, + inputTitle: str = None, + inputMessage: str = None, + showErrorAlert: bool = None, + errorStyle: str = None, + errorTitle: str = None, + errorMessage: str = None, + ): + """Available option while using validate cell are ( ignoreBlank, allow, value1, value2, inCellDropdown, data, showInputMessage, inputTitle, inputMessage, showErrorAlert, errorStyle, errorTitle,errorMessage ) + + Args: + name (string, optional): Name of the validate tag. For {validate tagName}, tagName is name for this element. + ignoreBlank (bool, optional): Set it to false for not allowing empty values in cell. The value is true by default. + allow (string, optional): Type of data used for validation. Available options are (anyValue, whole, decimal, list, date, time, textLength, custom). Please use camelCase to insert value for allow attribute. + value1 (string, optional): Value to compare with. + value2 (string, optional): Value to compare with.
+ Note: + These two options (_value1, _value2) can be used for any allow/type of validation that require values for comparison, in such case use "_value1" attribute as the first value to be passed and "_value2" attribute as the 2nd value.

+ Some allow type of validation require only one value to compare; in such case use "_value1" attribute.

+ For ex :
+ If allow type of validation is date and you have to check in between two dates.
+ Then you could use "_value1" attribute as start date and "_value2" attribute as end date.

+ If allow type of validation is whole and you have to check for value less than 100.
+ Then you could use "_value1" for that value and do not use "_value2".

+ While using time and date as allow type validation, please provide date/time with correct formatting.
+ for time: hours:minutes:seconds i.e hours , minutes, seconds separated by colon (:)
+ ex : 14:30:00 for 2:30 pm

+ for date: month/day/year i.e day, month , year separated by forward slash(/)
+ ex : 02/07/2023 for Feb 7 2023.

+ for list: you could use normal string with elements separated by comma(,).
+ ex : "first, second, third" for list of three elements.
+ inCellDropdown (bool, optional): Set it to false for not showing dropdown button while validation allow type is list. It is true by default for list allow type. + data (string, optional): Type of comparison to be done for the cell value. Available values are (lessThanOrEqual, notBetween, equal, notEqual, greaterThan, greaterThan, lessThan, greaterThanOrEqual, lessThanOrEqual). Default value is "between". Please use camelCase for the value as shown in examples. + showInputMessage (bool, optional): Set it to false to hide message shown when the cell to validate is being selected. The value for it is true by default. + inputTitle (string, optional): Title of message to be shown when cell to validate is selected. + inputMessage (string, optional): Message to be shown when cell to validate is selected. + showErrorAlert (bool, optional): Set it to false, if you want to hide error alert once cell validation fails. The value is true by default. + errorStyle (string, optional): Type of error style when cell validation fails. The value is stop by default. Available options are(stop,waring, Information). + errorTitle (string, optional): Title of error to be shown when cell validation fails. + errorMessage (string, optional): Message of error to be shown when cell validation fails. + """ + super().__init__(name) + self.ignoreBlank = ignoreBlank + self.allow = allow + self.value1 = value1 + self.value2 = value2 + self.inCellDropdown = inCellDropdown + self.data = data + self.showInputMessage = showInputMessage + self.inputTitle = inputTitle + self.inputMessage = inputMessage + self.showErrorAlert = showErrorAlert + self.errorStyle = errorStyle + self.errorTitle = errorTitle + self.errorMessage = errorMessage + + @property + def available_tags(self) -> FrozenSet[str]: + return frozenset({"{validate " + self.name + "}"}) + + @property + def as_dict(self) -> Dict: + result = {} + if self.ignoreBlank is not None: + result[self.name + '_ignore_blank'] = self.ignoreBlank + if self.allow is not None: + result[self.name + '_allow'] = self.allow + if self.value1 is not None: + result[self.name + '_value1'] = self.value1 + if self.value2 is not None: + result[self.name + '_value2'] = self.value2 + if self.inCellDropdown is not None: + result[self.name + '_in_cell_dropdown'] = self.inCellDropdown + if self.data is not None: + result[self.name + '_data'] = self.data + if self.showInputMessage is not None: + result[self.name + '_show_input_message'] = self.showInputMessage + if self.inputTitle is not None: + result[self.name + '_input_title'] = self.inputTitle + if self.inputMessage is not None: + result[self.name + '_input_message'] = self.inputMessage + if self.showErrorAlert is not None: + result[self.name + '_show_error_alert'] = self.showErrorAlert + if self.errorStyle is not None: + result[self.name + '_error_style'] = self.errorStyle + if self.errorTitle is not None: + result[self.name + '_error_title'] = self.errorTitle + if self.errorMessage is not None: + result[self.name + '_error_message'] = self.errorMessage + return result + + +class Link(Property): + """The class for the link/target tags. + This tags allows you to place a link to a target in the same document. + If the uid is not provided, a new uid will be generated uniquely for every link and target pair. + """ + + def __init__( + self, + name: str, + value: str, + uid_name: str = None, + uid_value: str = None, + ): + """Create a new link/target tag pair. + If the uid is not provided, a new uid will be generated uniquely for each link/target pair. + + Args: + name (str): the name of the link/target tags. + value (str): the value of the link/target tags. + uid_name (str): the name of the uid of the link/target pair. + uid_value (str): the value of the uid of the link/target pair. + """ + super().__init__(name, value) + self.uid_name = uid_name + self.uid_value = uid_value + + @property + def available_tags(self) -> FrozenSet[str]: + if self.uid_name and self.uid_value: + return frozenset( + { + "{link" + self.name + ":" + self.uid_name + "}", + "{target" + self.name + ":" + self.uid_name + "}", + } + ) + return frozenset({"{link" + self.name + "}", "{target" + self.name + "}"}) + + @property + def as_dict(self) -> Dict: + if self.uid_name and self.uid_value: + return {self.name: self.value, self.uid_name: self.uid_value} + return {self.name: self.value} class ElementCollection(list, Element): @@ -956,14 +1658,14 @@ def __repr__(self) -> str: """ return self.json - def copy(self) -> 'ElementCollection': + def copy(self) -> "ElementCollection": """ Returns: ElementCollection: A copy of this element collection. """ return self.__class__(self) - def deepcopy(self) -> 'ElementCollection': + def deepcopy(self) -> "ElementCollection": """ Returns: ElementCollection: A deep copy of this element collection. @@ -982,7 +1684,7 @@ def add(self, element: Element): """ self.append(element) - def add_all(self, obj: 'ElementCollection'): + def add_all(self, obj: "ElementCollection"): """Add all the elements in the given collection to this collection. Args: @@ -998,8 +1700,7 @@ def remove_element_by_name(self, element_name: str): element_name (str): the name of the element that needs to be removed """ self.remove( - next(element for element in self if element.name == element_name) - ) + next(element for element in self if element.name == element_name)) @property def as_dict(self) -> Dict: @@ -1024,7 +1725,9 @@ def available_tags(self) -> FrozenSet[str]: return frozenset(result) @classmethod - def element_to_element_collection(cls, element: Element, name: str = "") -> 'ElementCollection': + def element_to_element_collection( + cls, element: Element, name: str = "" + ) -> "ElementCollection": """Generate an element collection from an element and a name. Args: @@ -1037,7 +1740,7 @@ def element_to_element_collection(cls, element: Element, name: str = "") -> 'Ele return cls.from_mapping(element.as_dict, name) @classmethod - def from_mapping(cls, mapping: Mapping, name: str = "") -> 'ElementCollection': + def from_mapping(cls, mapping: Mapping, name: str = "") -> "ElementCollection": """Generate an element collection from a mapping and a name. Args: @@ -1053,7 +1756,7 @@ def from_mapping(cls, mapping: Mapping, name: str = "") -> 'ElementCollection': return cls(name, result_set) @classmethod - def from_json(cls, json_str: str, name: str = "") -> 'ElementCollection': + def from_json(cls, json_str: str, name: str = "") -> "ElementCollection": """Generate an element collection from a JSON string. Args: diff --git a/cloudofficeprint/elements/form.py b/cloudofficeprint/elements/form.py new file mode 100644 index 0000000..7578482 --- /dev/null +++ b/cloudofficeprint/elements/form.py @@ -0,0 +1,125 @@ +from typing import Dict, Union,Any, FrozenSet +from .elements import Element + +class Textbox(Element): + """PDF form textbox element + + Args: + name (str): the PDF field name + value (str, optional): text to put into the box + height (int|str, optional): box height + width (int|str, optional): box width + multiline (bool, optional): True for multiline input (serialized as 1/0) + """ + def __init__(self, + name: str, + value: str = None, + height: Union[int, str] = None, + width: Union[int, str] = None, + multiline: bool = None): + super().__init__(name) + self.type = "text" + self.value = value + self.height = height + self.width = width + self.multiline = multiline + @property + def as_dict(self) -> Dict[str, Any]: + result = {"type": self.type, "name": self.name} + if self.value is not None: + result["value"] = self.value + if self.height is not None: + result["height"] = self.height + if self.width is not None: + result["width"] = self.width + if self.multiline is not None: + result["multiline"] = self.multiline + return result + @property + def available_tags(self) -> FrozenSet[str]: + return frozenset([f"{{?form {self.name}}}"]) + + +class RadioButton(Element): + """PDF form radio button element + + Args: + name (str): the PDF field name + value (str, optional): the field’s export values + text (str, optional): visible caption next to the button + selected (bool, optional): True if this button is chosen (serialized as 1/0) + height (int|str, optional): control height + width (int|str, optional): control width + """ + def __init__(self, + name: str, + value: str = None, + text: str = None, + selected: bool = None, + height: Union[int, str] = None, + width: Union[int, str] = None): + super().__init__(name) + self.type = "radio" + self.value = value + self.text = text + self.selected = selected + self.height = height + self.width = width + + @property + def as_dict(self) -> Dict[str, Any]: + result = {"type": self.type, "name": self.name} + if self.value is not None: + result["value"] = self.value + if self.text is not None: + result["text"] = self.text + if self.selected is not None: + result["selected"] = 1 if self.selected else 0 + if self.height is not None: + result["height"] = self.height + if self.width is not None: + result["width"] = self.width + return result + + @property + def available_tags(self) -> FrozenSet[str]: + return frozenset([f"{{?form {self.name}}}"]) + +class Checkbox(Element): + """PDF form checkbox element + + Args: + name (str): the PDF field name + value (bool, optional): True if checked (serialized as 1/0) + text (str, optional): visible caption next to the box + height (int|str, optional): control height + width (int|str, optional): control width + """ + + def __init__(self, name: str, value: bool = None, + text: str = None, + height: Union[int, str] = None, + width: Union[int, str] = None): + super().__init__(name) + self.type = "checkbox" + self.value = value + self.text = text + self.height = height + self.width = width + + @property + def as_dict(self) -> Dict[str, Any]: + result = {"type": self.type, "name": self.name} + if self.value is not None: + result["value"] = 1 if self.value else 0 + if self.text is not None: + result["text"] = self.text + if self.height is not None: + result["height"] = self.height + if self.width is not None: + result["width"] = self.width + return result + + @property + def available_tags(self) -> FrozenSet[str]: + return frozenset([f"{{?form {self.name}}}"]) \ No newline at end of file diff --git a/cloudofficeprint/elements/images.py b/cloudofficeprint/elements/images.py index 83ebebb..b56585a 100644 --- a/cloudofficeprint/elements/images.py +++ b/cloudofficeprint/elements/images.py @@ -16,7 +16,9 @@ def __init__(self, transparency: Union[int, str]=None, url: str=None, width: Union[int, str]=None, - height: Union[int, str]=None): + height: Union[int, str] = None, + density: int = None + ): """ Args: name (str): The name of the image element. @@ -35,6 +37,7 @@ def __init__(self, url (str): The URL to load when the image is clicked. width (Union[int, str]): The width of the image (for non-proportional scaling). height (Union[int, str]): The height of the image (for non-proportional scaling). + density (int):The density to use for svg to png conversion. """ super().__init__(name) self.source: str = source @@ -47,6 +50,10 @@ def __init__(self, self.url: str = url self.width: Union[int, str] = width self.height: Union[int, str] = height + if density is not None and density > 1200: + self.density = 1200 + else: + self.density = density @property def alt_text(self) -> str: @@ -133,6 +140,8 @@ def _dict_suffixes(self) -> Dict: result["_width"] = self.width if self.height is not None: result["_height"] = self.height + if self.density is not None: + result["_density"] = self.density return result @@ -158,7 +167,8 @@ def from_file( transparency: Union[int, str]=None, url: str=None, width: Union[int, str]=None, - height: Union[int, str]=None + height: Union[int, str]=None, + density: int = None ) -> 'Image': """Generate an Image object from a local file. @@ -179,6 +189,7 @@ def from_file( url (str): The URL to load when the image is clicked. width (Union[int, str]): The width of the image (for non-proportional scaling). height (Union[int, str]): The height of the image (for non-proportional scaling). + density (int): The density to use for svg to png conversion. Returns: Image: the generated Image object from a local file @@ -195,6 +206,7 @@ def from_file( url, width, height, + min(density, 1200) if density is not None else None ) @staticmethod @@ -209,7 +221,8 @@ def from_raw( transparency: Union[int, str]=None, url: str=None, width: Union[int, str]=None, - height: Union[int, str]=None + height: Union[int, str]=None, + density: int = None ) -> 'Image': """Generate an Image object from raw data. @@ -230,7 +243,7 @@ def from_raw( url (str): The URL to load when the image is clicked. width (Union[int, str]): The width of the image (for non-proportional scaling). height (Union[int, str]): The height of the image (for non-proportional scaling). - + density (int): The density to use for svg to png conversion. Returns: Image: the generated Image object from raw data """ @@ -246,6 +259,7 @@ def from_raw( url, width, height, + density, ) @staticmethod @@ -260,7 +274,8 @@ def from_base64( transparency: Union[int, str]=None, url: str=None, width: Union[int, str]=None, - height: Union[int, str]=None + height: Union[int, str]=None, + density: int = None ) -> 'Image': """Generate an Image object from a base64 string. @@ -281,6 +296,8 @@ def from_base64( url (str): The URL to load when the image is clicked. width (Union[int, str]): The width of the image (for non-proportional scaling). height (Union[int, str]): The height of the image (for non-proportional scaling). + density (int):The density to use for svg to png conversion. + Returns: Image: the generated Image object from a base64 string @@ -297,6 +314,7 @@ def from_base64( url, width, height, + min(density, 1200) if density is not None else None ) @staticmethod @@ -311,7 +329,8 @@ def from_url( transparency: Union[int, str]=None, url: str=None, width: Union[int, str]=None, - height: Union[int, str]=None + height: Union[int, str]=None, + density: int = None ) -> 'Image': """Generate an Image object from a URL. @@ -332,6 +351,7 @@ def from_url( url (str): The URL to load when the image is clicked. width (Union[int, str]): The width of the image (for non-proportional scaling). height (Union[int, str]): The height of the image (for non-proportional scaling). + density (int):The density to use for svg to png conversion. Returns: Image: the generated Image object from a URL @@ -348,4 +368,5 @@ def from_url( url, width, height, + min(density, 1200) if density is not None else None ) diff --git a/cloudofficeprint/elements/loops.py b/cloudofficeprint/elements/loops.py index 7002ef4..2ccfe11 100644 --- a/cloudofficeprint/elements/loops.py +++ b/cloudofficeprint/elements/loops.py @@ -124,7 +124,7 @@ class ForEachInline(ForEach): Note: this tag can be used to repeat only one row in Word. In Excel this works like a normal loop tag and repeats the cells defined by the rectangular boundary of the starting and closing tag.""" - def __init__(self, name: str, content: Iterable[Element]): + def __init__(self, name: str, content: Iterable[Element], distribute: bool = False): """ Args: name (str): The name for this element (Cloud Office Print tag). @@ -135,7 +135,13 @@ def __init__(self, name: str, content: Iterable[Element]): "{:" + name + "}", "{/" + name + "}" } - + self._distribute = distribute + @property + def as_dict(self) -> Dict: + data = super().as_dict + if self._distribute: + data[f"{self.name}_distribute"] = True + return data # These are the same, but they may not be forever # and combining them into one class breaks consistency @@ -157,3 +163,21 @@ def __init__(self, name: str, content: Iterable[Element]): "{=" + name + "}", "{/" + name + "}" } + +class ForEachMergeCells(ForEach): + """Loop where table cells are vertically merged across rows during looping. + Only supported in Word templates with {##...} {/...} syntax.""" + + def __init__(self, name: str, content: Iterable[Element]): + """ + Args: + name (str): The name for this element (Cloud Office Print tag with merge cells). + content (Iterable[Element]): An iterable containing the elements for this loop element. + """ + super().__init__(name, content) + self._tags = { + "{##" + name + "}", + "{/" + name + "}" + } + + diff --git a/cloudofficeprint/elements/pdf.py b/cloudofficeprint/elements/pdf.py index 53673d5..e946c79 100644 --- a/cloudofficeprint/elements/pdf.py +++ b/cloudofficeprint/elements/pdf.py @@ -153,6 +153,68 @@ def _inner_dict(self) -> Dict: result["image_max_width"] = self.max_width return result + +class PDFComment(PDFInsertObject): + """A free‑text comment (annotation) on a PDF page.""" + def __init__(self, + text: str, + x: int, + y: int, + page: Union[int, str] = "all", + # rotation: int = None, + bold: bool = None, + italic: bool = None, + font: str = None, + font_color: str = None, + font_size: int = None): + """ + Args: + text (str): Text to insert. + x (int): X component of this object's position. + y (int): Y component of this object's position. + page (Union[int, str], optional): Page to include this object on. Either "all" or an integer. Defaults to "all". + rotation (int, optional): Text rotation in degrees. Defaults to None. + bold (bool, optional): Whether or not the text should be in bold. Defaults to None. + italic (bool, optional): Whether or not the text should be in italic. Defaults to None. + font (str, optional): The text font name. Defaults to None. + font_color (str, optional): The text font color, CSS notation. Defaults to None. + font_size (int, optional): The text font size. Defaults to None. + """ + super().__init__(x, y, page) + self.text: str = text + # self.rotation: int = rotation + self.bold: bool = bold + self.italic: bool = italic + self.font: str = font + self.font_color: str = font_color + self.font_size: int = font_size + + @staticmethod + def _identifier() -> str: + return "AOP_PDF_COMMENTS" + + @property + def _inner_dict(self) -> Dict: + result = { + "text": self.text, + "x": self.x, + "y": self.y + } + + # if self.rotation is not None: + # result["rotation"] = self.rotation + if self.bold is not None: + result["bold"] = self.bold + if self.italic is not None: + result["italic"] = self.italic + if self.font is not None: + result["font"] = self.font + if self.font_color is not None: + result["font_color"] = self.font_color + if self.font_size is not None: + result["font_size"] = self.font_size + + return result class PDFTexts(Element): """Group of PDF texts as an `Element`. @@ -242,3 +304,30 @@ def as_dict(self) -> Dict: @property def available_tags(self) -> FrozenSet[str]: return frozenset() + +class PDFComments(Element): + """Group multiple PDFComment instances into one Element.""" + def __init__(self, comments: Iterable[PDFComment]): + """ + Args: + comments (Iterable[PDFComment]): An iterable consisting of `PDFComment`-objects. + """ + super().__init__(PDFComment._identifier()) + # self.comments = comments + self.comments: Iterable[PDFComment] = comments + + + @property + def as_dict(self) -> Dict: + result = {} + for txt in self.comments: + + if str(txt.page) in result: + result[str(txt.page)].append(txt._inner_dict) + else: + result[str(txt.page)] = [txt._inner_dict] + return {self.name: [result]} + @property + def available_tags(self) -> FrozenSet[str]: + return frozenset() + diff --git a/cloudofficeprint/printjob.py b/cloudofficeprint/printjob.py index c5be0a4..1892845 100644 --- a/cloudofficeprint/printjob.py +++ b/cloudofficeprint/printjob.py @@ -2,19 +2,21 @@ Module containing the PrintJob class, which is also exposed at package level. """ -from cloudofficeprint.elements.rest_source import RESTSource import requests import asyncio import json + +from typing import Union, List, Dict, Mapping, Optional +from functools import partial +from pprint import pprint + from .config import OutputConfig, Server +from .elements import Element, RESTSource from .exceptions import COPError -from .response import Response from .resource import Resource -from .elements import Element, ElementCollection -from typing import Union, List, Dict, Mapping -from functools import partial -import sys -from pprint import pprint +from .template import Template +from .response import Response +from .transformation import TransformationFunction STATIC_OPTS = { "tool": "python", @@ -30,35 +32,44 @@ class PrintJob: and the `PrintJob.execute` method to combine all these and send a request to the Cloud Office Print server. """ - def __init__(self, - data: Union[Element, Mapping[str, Element], RESTSource], - server: Server, - template: Resource = None, - output_config: OutputConfig = OutputConfig(), - subtemplates: Dict[str, Resource] = {}, - prepend_files: List[Resource] = [], - append_files: List[Resource] = [], - cop_verbose: bool = False): + def __init__( + self, + data: Union[Element, Mapping[str, Element], RESTSource], + server: Server, + template: Union[Template, Resource] = None, + output_config: OutputConfig = OutputConfig(), + subtemplates: Dict[str, Resource] = {}, + prepend_files: List[Resource] = [], + append_files: List[Resource] = [], + cop_verbose: bool = False, + compare_files: List[Resource] = [], + attachments : List[Resource] = [], + transformation_function: Optional[TransformationFunction] = None, + ): """ Args: data (Union[Element, Mapping[str, Element], RESTSource]): This is either: An `Element` (e.g. an `ElementCollection`); A mapping, containing file names as keys and an `Element` as data. Multiple files will be produced from the different datas, the result is a zip file containing them. In the first case, no output file name is specified and the server will name it "file0". server (Server): Server to be used for this print job. - template (Resource): Template to use for this print job. + template (Union[Template, Resource]): Template to use for this print job. output_config (OutputConfig, optional): Output configuration to be used for this print job. Defaults to `OutputConfig`(). subtemplates (Dict[str, Resource], optional): Subtemplates for this print job, accessible (in docx) through `{?include subtemplate_dict_key}`. Defaults to {}. prepend_files (List[Resource], optional): Files to prepend to the output file. Defaults to []. append_files (List[Resource], optional): Files to append to the output file. Defaults to []. cop_verbose (bool, optional): Whether or not verbose mode should be activated. Defaults to False. + compare_files (List[Resource], optional): Files to compare with the output file. Defaults to []. + attachments (List[Resource], optional): Files to attach to the pdf file. Defaults to []. The file must be PDF. """ - self.data: Union[Element, Mapping[str, Element], RESTSource] = data self.server: Server = server self.output_config: OutputConfig = output_config - self.template: Resource = template + self.template: Union[Template, Resource] = template self.subtemplates: Dict[str, Resource] = subtemplates self.prepend_files: List[Resource] = prepend_files self.append_files: List[Resource] = append_files self.cop_verbose: bool = cop_verbose + self.attachments: List[Resource] = attachments + self.compare_files: List[Resource] = compare_files + self.transformation_function = transformation_function def execute(self) -> Response: """Execute this print job. @@ -67,7 +78,18 @@ def execute(self) -> Response: Response: `Response`-object """ self.server._raise_if_unreachable() - return self._handle_response(requests.post(self.server.url, proxies=self.server.config.proxies if self.server.config is not None else None, json=self.as_dict, headers={"Content-type": "application/json"})) + proxy = self.server.config.proxies if self.server.config else None + response = requests.post( + self.server.url, + json=self.as_dict, + proxies=proxy, + headers={"Content-type": "application/json"}, + ) + if type(self.template) is Template and self.template.should_hash: + template_hash = response.headers["Template-Hash"] + if template_hash: + self.template.update_hash(template_hash) + return self._handle_response(response) async def execute_async(self) -> Response: """Async version of `PrintJob.execute` @@ -76,16 +98,22 @@ async def execute_async(self) -> Response: Response: `Response`-object """ self.server._raise_if_unreachable() - return PrintJob._handle_response( - await asyncio.get_event_loop().run_in_executor( - None, partial( - requests.post, - self.server.url, - proxies=self.server.config.proxies if self.server.config is not None else None, - json=self.as_dict - ) - ) + proxy = self.server.config.proxies if self.server.config else None + response = await asyncio.get_event_loop().run_in_executor( + None, + partial( + requests.post, + self.server.url, + json=self.as_dict, + proxies=proxy, + headers={"Content-type": "application/json"}, + ), ) + if type(self.template) is Template and self.template.should_hash: + template_hash = response.headers["Template-Hash"] + if template_hash: + self.template.update_hash(template_hash) + return PrintJob._handle_response(response) @staticmethod def execute_full_json(json_data: str, server: Server) -> Response: @@ -99,7 +127,14 @@ def execute_full_json(json_data: str, server: Server) -> Response: Response: `Response`-object """ server._raise_if_unreachable() - return PrintJob._handle_response(requests.post(server.url, proxies=server.config.proxies if server.config is not None else None, data=json_data, headers={"Content-type": "application/json"})) + proxy = server.config.proxies if server.config else None + response = requests.post( + server.url, + data=json_data, + proxies=proxy, + headers={"Content-type": "application/json"}, + ) + return PrintJob._handle_response(response) @staticmethod async def execute_full_json_async(json_data: str, server: Server) -> Response: @@ -113,17 +148,18 @@ async def execute_full_json_async(json_data: str, server: Server) -> Response: Response: `Response`-object """ server._raise_if_unreachable() - return PrintJob._handle_response( - await asyncio.get_event_loop().run_in_executor( - None, partial( - requests.post, - server.url, - proxies=server.config.proxies if server.config is not None else None, - data=json_data, - headers={"Content-type": "application/json"} - ) - ) + proxy = server.config.proxies if server.config else None + response = await asyncio.get_event_loop().run_in_executor( + None, + partial( + requests.post, + server.url, + data=json_data, + proxies=proxy, + headers={"Content-type": "application/json"}, + ), ) + return PrintJob._handle_response(response) @staticmethod def _handle_response(res: requests.Response) -> Response: @@ -160,8 +196,8 @@ def as_dict(self) -> Dict: Returns: Dict: dict representation of this print job """ - result = dict( - STATIC_OPTS) # Copy of STATIC_OPTS! Otherwise everything we add to 'result' will also be added to 'STATIC_OPTS' + # Copy of STATIC_OPTS! Otherwise everything we add to 'result' will also be added to 'STATIC_OPTS' + result = dict(STATIC_OPTS) # server config goes in the upper level if self.server.config: result.update(self.server.config.as_dict) @@ -176,43 +212,54 @@ def as_dict(self) -> Dict: # If output_type is not specified, set this to the template filetype # If no template found: default docx - if 'output_type' not in self.output_config.as_dict.keys(): + if "output_type" not in self.output_config.as_dict.keys(): if self.template: - result['output']['output_type'] = result['template']['template_type'] + result["output"]["output_type"] = result["template"]["template_type"] else: - result['output']['output_type'] = 'docx' + result["output"]["output_type"] = "docx" if isinstance(self.data, Mapping): - result["files"] = [{ - "filename": name, - "data": data.as_dict - } for name, data in self.data.items()] + result["files"] = [ + {"filename": name, "data": data.as_dict} + for name, data in self.data.items() + ] elif isinstance(self.data, RESTSource): - result['files'] = [self.data.as_dict] + result["files"] = [self.data.as_dict] else: result["files"] = [{"data": self.data.as_dict}] if len(self.prepend_files) > 0: result["prepend_files"] = [ - res.secondary_file_dict for res in self.prepend_files + file.secondary_file_dict for file in self.prepend_files ] if len(self.append_files) > 0: result["append_files"] = [ - res.secondary_file_dict for res in self.append_files + file.secondary_file_dict for file in self.append_files + ] + + if len(self.compare_files) > 0: + result["compare_files"] = [ + file.secondary_file_dict for file in self.compare_files + ] + + if len(self.attachments) > 0: + result["attachments"] = [ + file.secondary_file_dict for file in self.attachments ] if len(self.subtemplates) > 0: - templates_list = [] - for name, res in self.subtemplates.items(): - to_add = res.secondary_file_dict - to_add["name"] = name - templates_list.append(to_add) - result["templates"] = templates_list - - # If verbose mode is activated, print the result to the terminal + result["templates"] = [ + {**file.secondary_file_dict, "name": name} + for name, file in self.subtemplates.items() + ] + + if self.transformation_function is not None: + result["transformation_function"] = self.transformation_function.as_dict() + + if self.cop_verbose: - print('The JSON data that is sent to the Cloud Office Print server:\n') + print("The JSON data that is sent to the Cloud Office Print server:\n") pprint(result) return result diff --git a/cloudofficeprint/resource.py b/cloudofficeprint/resource.py index e39f60f..e57f86c 100644 --- a/cloudofficeprint/resource.py +++ b/cloudofficeprint/resource.py @@ -12,77 +12,67 @@ import json from typing import Dict, Union -from .own_utils import type_utils, file_utils from abc import abstractmethod, ABC +from .own_utils import type_utils, file_utils + class Resource(ABC): """The abstract base class for the resources.""" - def __init__(self, data: Union[str, bytes] = None, filetype: str = None): - """ + def __init__( + self, + data: Union[str, bytes] = None, + filetype: str = None, + ): + """Create a new Resource. + Args: - data (Union[str, bytes], optional): the data for this resource. Defaults to None. - filetype (str, optional): the file type of this resource. Defaults to None. + data (Union[str, bytes], optional): the data for this Resource. Defaults to None. + filetype (str, optional): the file type of this Resource. Defaults to None. """ - self._data: Union[str, bytes] = data + self.data: Union[str, bytes] = data self.filetype: str = filetype @property def mimetype(self) -> str: - """Resource type as a mime type. - - Returns: - str: resource type as a mime type """ - return type_utils.extension_to_mimetype(self.filetype) - - @property - def data(self) -> Union[str, bytes]: - """The data contained in this Resource. - Returns: - Union[str, bytes]: the data contained in this Resource + str: the mime type of the Resource """ - return self._data + return type_utils.extension_to_mimetype(self.filetype) @property def template_json(self) -> str: - """Get the JSON representation when used as a template. - + """ Returns: - str: JSON representation of this resource as a template + str: the JSON representation of this Resource. """ return json.dumps(self.template_dict) @property @abstractmethod def template_dict(self) -> Dict: - """This Resource object as a dict object for use as a template. - This dict and the template JSON representation (`Resource.template_json`) are isomorphic. - + """ Returns: - Dict: dict representation of this resource as a template + Dict: the dictionary representation of this Resource. """ pass @property def secondary_file_json(self) -> str: - """The JSON representation for use as secondary file. - + """ Returns: - str: JSON representation of this resource as a secondary file + str: the JSON representation of this Resource. """ return json.dumps(self.secondary_file_dict) @property @abstractmethod def secondary_file_dict(self) -> Dict: - """This Resource object as a dict object for use as a secondary file (prepend, append, insert, as subtemplate). - This dict and the "concat file" JSON representation (`Resource.secondary_file_json`) are isomorphic. - + """ Returns: - Dict: dict representation of this resource as a secondary file + Dict: the dictionarty representation of this resource as a secondary file (prepend, append, insert, as subtemplate). """ pass @@ -90,91 +80,91 @@ def __str__(self) -> str: """Override the string representation of this class to return the template-style json. Returns: - str: JSON representation of this resource as a template + str: the JSON representation of this resource as a template. """ return self.template_json @staticmethod - def from_base64(base64string: str, filetype: str) -> 'Base64Resource': - """Create a Base64Resource from a base64 string and a file type (extension). + def from_raw(raw_data: bytes, filetype: str) -> "RawResource": + """Create a RawResource from raw file data. Args: - base64string (str): base64 encoded string - filetype (str): file type (extension) + raw_data (bytes): the raw data as a [bytes-like object](https://docs.python.org/3/glossary.html#term-bytes-like-object). + filetype (str): the file type (extension). Returns: - Base64Resource: the created Resource + RawResource: the created RawResource. """ - return Base64Resource(base64string, filetype) + return RawResource(raw_data, filetype) @staticmethod - def from_raw(raw_data: bytes, filetype: str) -> 'RawResource': - """Create a RawResource from raw file data and a file type (extension). + def from_base64(base64string: str, filetype: str) -> "Base64Resource": + """Create a Base64Resource from a base64 string. Args: - raw_data (bytes): raw data as a [bytes-like object](https://docs.python.org/3/glossary.html#term-bytes-like-object) - filetype (str): file type (extension) + base64string (str): the base64 encoded representation of a file. + filetype (str): the file type (extension). Returns: - RawResource: the created Resource + Base64Resource: the created Base64Resource. """ - return RawResource(raw_data, filetype) + return Base64Resource(base64string, filetype) @staticmethod - def from_local_file(local_path: str) -> 'Base64Resource': + def from_local_file(local_path: str) -> "Base64Resource": """Create a Base64Resource with the contents of a local file. + The filetype is determined by the extension of the file. Throws IOError if it can't read the file. - The filetype is determined by the extension of the file. Args: - local_path (str): path to local file + local_path (str): the path to local file. Returns: - Base64Resource: the created Resource + Base64Resource: the created Base64Resource. """ - base64string: str = file_utils.read_file_as_base64(local_path) - return Base64Resource(base64string, type_utils.path_to_extension(local_path)) + return Base64Resource( + file_utils.read_file_as_base64(local_path), + type_utils.path_to_extension(local_path), + ) @staticmethod - def from_server_path(path: str) -> 'ServerPathResource': + def from_server_path(path: str) -> "ServerPathResource": """Create a ServerPathResource targeting a file on the server. - The filetype is determined by the extension of the file. Args: - path (str): location of target file on the server + path (str): the location of target file on the server. Returns: - ServerPathResource: the created Resource + ServerPathResource: the created ServerPathResource. """ return ServerPathResource(path) @staticmethod - def from_url(url: str, filetype: str) -> 'URLResource': - """Create an Resource targeting the file at url with given filetype (extension). + def from_url(url: str, filetype: str) -> "URLResource": + """Create an URLResource targeting the file at a given URL. Args: - url (str): file url - filetype (str): file type (extension) + url (str): the file URL. + filetype (str): the file type (extension). Returns: - URLResource: the created Resource + URLResource: the created URLResource. """ return URLResource(url, filetype) @staticmethod - def from_html(htmlstring: str, landscape: bool = False) -> 'HTMLResource': + def from_html(htmlstring: str, landscape: bool = False) -> "HTMLResource": """Create an HTMLResource with html data in plain text. - Landscape is not supported for prepend/append sources, only for template resources. Args: - htmlstring (str): html content - landscape (bool, optional): whether to use the landscape option. Defaults to False. + htmlstring (str): the html content. + landscape (bool, optional): whether or not to use the landscape option. Defaults to False. Returns: - HTMLResource: the created Resource + HTMLResource: the created HTMLResource. """ return HTMLResource(htmlstring, landscape) @@ -183,62 +173,83 @@ class RawResource(Resource): """A `Resource` containing raw binary data.""" def __init__(self, raw_data: bytes, filetype: str): - """ + """Create a new RawResource. + Args: - raw_data (bytes): raw data as a [bytes-like object](https://docs.python.org/3/glossary.html#term-bytes-like-object) - filetype (str): file type (extension) + raw_data (bytes): the raw data as a [bytes-like object](https://docs.python.org/3/glossary.html#term-bytes-like-object). + filetype (str): the file type (extension). """ super().__init__(raw_data, filetype) @property def base64(self) -> str: - """Base64 representation of the raw data in `RawResource.data`. - + """ Returns: - str: base64 representation of the raw data in `RawResource.data` + str: the base64 representation of the raw data in `RawResource.data`. """ return file_utils.raw_to_base64(self.data) @property def template_dict(self) -> Dict: + """ + Returns: + str: the JSON representation of this resource. + """ return { "template_type": self.filetype, - "file": self.base64 + "file": self.base64, } @property def secondary_file_dict(self) -> Dict: + """ + Returns: + str: the JSON representation of this resource. + """ return { "mime_type": self.mimetype, "file_source": "base64", - "file_content": self.base64 + "file_content": self.base64, } class Base64Resource(Resource): """A `Resource` containing base64 data.""" - def __init__(self, base64string: str, filetype: str): - """ + def __init__( + self, + base64string: str, + filetype: str, + ): + """Create a new Base64Resource. + Args: - base64string (str): base64 encoded file - filetype (str): file type (extension) + base64string (str): the base64 encoded data. + filetype (str): the file type (extension). """ super().__init__(base64string, filetype) @property def template_dict(self) -> Dict: + """ + Returns: + str: the JSON representation of this resource. + """ return { "template_type": self.filetype, - "file": self.data + "file": self.data, } @property def secondary_file_dict(self) -> Dict: + """ + Returns: + str: the JSON representation of this resource. + """ return { "mime_type": self.mimetype, "file_source": "base64", - "file_content": self.data + "file_content": self.data, } @@ -246,25 +257,34 @@ class ServerPathResource(Resource): """A `Resource` targeting a file on the server.""" def __init__(self, server_path: str): - """ + """Create a new ServerPathResource. + Args: - server_path (str): path on the server to target + server_path (str): the path on the server to target. """ super().__init__(server_path, type_utils.path_to_extension(server_path)) @property def template_dict(self) -> Dict: + """ + Returns: + str: the JSON representation of this resource. + """ return { "template_type": self.filetype, - "filename": self.data + "filename": self.data, } @property def secondary_file_dict(self) -> Dict: + """ + Returns: + str: the JSON representation of this resource. + """ return { "mime_type": self.mimetype, "file_source": "file", - "filename": self.data + "filename": self.data, } @@ -272,37 +292,51 @@ class URLResource(Resource): """A `Resource` targeting a file at a URL.""" def __init__(self, url: str, filetype: str): - """ + """Create a new URLResource. + Args: - url (str): URL location of the file - filetype (str): file type (extension) + url (str): the URL location of the file. + filetype (str): the file type (extension). """ super().__init__(url, filetype) @property def template_dict(self) -> Dict: + """ + Returns: + str: the JSON representation of this resource. + """ return { "template_type": self.filetype, - "url": self.data + "url": self.data, } @property def secondary_file_dict(self) -> Dict: + """ + Returns: + str: the JSON representation of this resource. + """ return { "mime_type": self.mimetype, "file_source": "file", - "file_url": self.data + "file_url": self.data, } class HTMLResource(Resource): """A Resource containing HTML data in plain text.""" - def __init__(self, htmlstring: str, landscape: bool = False): - """ + def __init__( + self, + htmlstring: str, + landscape: bool = False, + ): + """Create a new HTMLResource. + Args: - htmlstring (str): HTML input in plain text - landscape (bool, optional): Whether the HTML should be rendered as landscape-oriented page. Defaults to False. + htmlstring (str): the HTML input in plain text. + landscape (bool, optional): whether the HTML should be rendered as landscape-oriented page. Defaults to False. """ super().__init__(htmlstring, "html") self.landscape: bool = landscape @@ -315,26 +349,30 @@ def orientation(self) -> str: Orientation is not supported for prepend/append sources, only for template resources. Returns: - str: orientation + str: the orientation. """ return None if not self.landscape else "landscape" @property def template_dict(self) -> Dict: - result = { + """ + Returns: + str: the JSON representation of this resource. + """ + return { "template_type": self.filetype, - "html_template_content": self.data + "html_template_content": self.data, + "orientation": self.orientation, } - if self.orientation is not None: - result["orientation"] = self.orientation - - return result - @property def secondary_file_dict(self) -> Dict: + """ + Returns: + str: the JSON representation of this resource. + """ return { "mime_type": self.mimetype, "file_source": "file", - "file_content": self.data + "file_content": self.data, } diff --git a/cloudofficeprint/template.py b/cloudofficeprint/template.py new file mode 100644 index 0000000..c7c3aaa --- /dev/null +++ b/cloudofficeprint/template.py @@ -0,0 +1,281 @@ +import json +from typing import Dict + +from .resource import Resource + + +class Template: + """The Template class""" + + def __init__( + self, + resource: Resource, + start_delimiter: str = None, + end_delimiter: str = None, + should_hash: bool = None, + template_hash: str = None, + ): + """Create a new Template. + + Args: + resource (Resource): the resource of this template. + start_delimiter (str, optional): the starting delimiter used in the template. + end_delimiter (str, optional): the starting delimiter used in the template. + should_hash (bool, optional): whether the template should be hashed on the server. + template_hash (str, optional): the hash of the template. + """ + self.resource = resource + self.start_delimiter = start_delimiter + self.end_delimiter = end_delimiter + self.should_hash = should_hash + self.template_hash = template_hash + + def update_hash(self, template_hash: str): + """Update the Template to store a hash. + On the next request to the server, the file data will not be sent, only the hash of the template. + + Args: + template_hash (str): the hash of the template. + """ + self.template_hash = template_hash + self.should_hash = False + + def reset_hash(self, should_hash: bool = True): + """Reset the stored hash of the template. + + Args: + should_hash (bool, optional): whether the template should be hashed on the server. Defaults to True. + """ + self.template_hash = None + self.should_hash = should_hash + + @property + def mimetype(self) -> str: + """ + Returns: + str: the mime type of the Resource + """ + return self.resource.mimetype + + @property + def template_json(self) -> str: + """ + Returns: + str: the JSON representation of this Resource. + """ + return json.dumps(self.template_dict) + + @property + def template_dict(self) -> Dict: + """ + Returns: + Dict: the dictionary representation of this Resource. + """ + if self.template_hash and not self.should_hash: + dict = { + "template_type": self.resource.filetype, + "template_hash": self.template_hash, + } + if self.start_delimiter: + dict["start_delimiter"] = self.start_delimiter + if self.end_delimiter: + dict["end_delimiter"] = self.end_delimiter + return dict + dict = self.resource.template_dict + if self.start_delimiter: + dict["start_delimiter"] = self.start_delimiter + if self.end_delimiter: + dict["end_delimiter"] = self.end_delimiter + if self.should_hash: + dict["should_hash"] = self.should_hash + if self.template_hash: + dict["template_hash"] = self.template_hash + return dict + + def __str__(self) -> str: + """Override the string representation of this class to return the template-style json. + + Returns: + str: the JSON representation of this resource as a template. + """ + return self.template_json + + @staticmethod + def from_raw( + raw_data: bytes, + filetype: str, + start_delimiter: str = None, + end_delimiter: str = None, + should_hash: bool = None, + template_hash: str = None, + ) -> "Template": + """Create a Template with a RawResource from raw file data. + + Args: + raw_data (bytes): the raw data as a [bytes-like object](https://docs.python.org/3/glossary.html#term-bytes-like-object). + filetype (str): the file type (extension). + start_delimiter (str, optional): the starting delimiter used in the template. + end_delimiter (str, optional): the starting delimiter used in the template. + should_hash (bool, optional): whether the template should be hashed on the server. + template_hash (str, optional): the hash of the template. + + Returns: + Template: the created Template. + """ + return Template( + Resource.from_raw(raw_data, filetype), + start_delimiter, + end_delimiter, + should_hash, + template_hash, + ) + + @staticmethod + def from_base64( + base64string: str, + filetype: str, + start_delimiter: str = None, + end_delimiter: str = None, + should_hash: bool = None, + template_hash: str = None, + ) -> "Template": + """Create a Template with a Base64Resource from a base64 string. + + Args: + base64string (str): the base64 encoded representation of a file. + filetype (str): the file type (extension). + start_delimiter (str, optional): the starting delimiter used in the template. + end_delimiter (str, optional): the starting delimiter used in the template. + should_hash (bool, optional): whether the template should be hashed on the server. + template_hash (str, optional): the hash of the template. + + Returns: + Template: the created Template. + """ + return Template( + Resource.from_base64(base64string, filetype), + start_delimiter, + end_delimiter, + should_hash, + template_hash, + ) + + @staticmethod + def from_local_file( + local_path: str, + start_delimiter: str = None, + end_delimiter: str = None, + should_hash: bool = None, + template_hash: str = None, + ) -> "Template": + """Create a Template with a Base64Resource with the contents of a local file. + The filetype is determined by the extension of the file. + + Throws IOError if it can't read the file. + + Args: + local_path (str): the path to local file. + start_delimiter (str, optional): the starting delimiter used in the template. + end_delimiter (str, optional): the starting delimiter used in the template. + should_hash (bool, optional): whether the template should be hashed on the server. + template_hash (str, optional): the hash of the template. + + Returns: + Template: the created Template. + """ + return Template( + Resource.from_local_file(local_path), + start_delimiter, + end_delimiter, + should_hash, + template_hash, + ) + + @staticmethod + def from_server_path( + path: str, + start_delimiter: str = None, + end_delimiter: str = None, + should_hash: bool = None, + template_hash: str = None, + ) -> "Template": + """Create a Template with a ServerPathResource targeting a file on the server. + The filetype is determined by the extension of the file. + + Args: + path (str): the location of target file on the server. + start_delimiter (str, optional): the starting delimiter used in the template. + end_delimiter (str, optional): the starting delimiter used in the template. + should_hash (bool, optional): whether the template should be hashed on the server. + template_hash (str, optional): the hash of the template. + + Returns: + Template: the created Template. + """ + return Template( + Resource.from_server_path(path), + start_delimiter, + end_delimiter, + should_hash, + template_hash, + ) + + @staticmethod + def from_url( + url: str, + filetype: str, + start_delimiter: str = None, + end_delimiter: str = None, + should_hash: bool = None, + template_hash: str = None, + ) -> "Template": + """Create a Template with a URLResource targeting the file at a given url. + + Args: + url (str): the file URL. + filetype (str): the file type (extension). + start_delimiter (str, optional): the starting delimiter used in the template. + end_delimiter (str, optional): the starting delimiter used in the template. + should_hash (bool, optional): whether the template should be hashed on the server. + template_hash (str, optional): the hash of the template. + + Returns: + Template: the created Template. + """ + return Template( + Resource.from_url(url, filetype), + start_delimiter, + end_delimiter, + should_hash, + template_hash, + ) + + @staticmethod + def from_html( + htmlstring: str, + landscape: bool = False, + start_delimiter: str = None, + end_delimiter: str = None, + should_hash: bool = None, + template_hash: str = None, + ) -> "Template": + """Create a Template with a HTMLResource with html data in plain text. + + Args: + htmlstring (str): the html content. + landscape (bool, optional): whether or not to use the landscape option. Defaults to False. + start_delimiter (str, optional): the starting delimiter used in the template. + end_delimiter (str, optional): the starting delimiter used in the template. + should_hash (bool, optional): whether the template should be hashed on the server. + template_hash (str, optional): the hash of the template. + + Returns: + Template: the created Template. + """ + return Template( + Resource.from_html(htmlstring, landscape), + start_delimiter, + end_delimiter, + should_hash, + template_hash, + ) diff --git a/cloudofficeprint/transformation.py b/cloudofficeprint/transformation.py new file mode 100644 index 0000000..8c22542 --- /dev/null +++ b/cloudofficeprint/transformation.py @@ -0,0 +1,54 @@ +from typing import Optional + +class TransformationFunction: + """ + Represents a transformation function for Cloud Office Print (AOP). + Args: + js_code (str, optional): Inline JavaScript code for transformation. + filename (str, optional): Filename from AOP's `assets/transformation_function/` directory. + """ + + def __init__( + self, + js_code: Optional[str] = None, + filename: Optional[str] = None + ): + self._js_code: Optional[str] = None + self._filename: Optional[str] = None + + if js_code is not None: + self.js_code = js_code + if filename is not None: + self.filename = filename + + @property + def js_code(self) -> Optional[str]: + return self._js_code + + @js_code.setter + def js_code(self, code: str): + if self._filename is not None: + raise ValueError("Cannot set js_code when filename is already set") + if not isinstance(code, str) or not code.strip(): + raise ValueError("js_code must be a non‑empty string") + self._js_code = code + + @property + def filename(self) -> Optional[str]: + return self._filename + + @filename.setter + def filename(self, name: str): + if self._js_code is not None: + raise ValueError("Cannot set filename when js_code is already set") + if not isinstance(name, str) or not name.lower().endswith(".js"): + raise ValueError("Filename must be a string ending with '.js'") + if "/" in name or "\\" in name: + raise ValueError("Filename must not include any path separators") + self._filename = name + + def as_dict(self) -> Optional[str]: + """ + Return the transformation_function + """ + return self._js_code or self._filename diff --git a/docs/cloudofficeprint.html b/docs/cloudofficeprint.html index 9aacb90..61775ac 100644 --- a/docs/cloudofficeprint.html +++ b/docs/cloudofficeprint.html @@ -3,68 +3,40 @@ - + cloudofficeprint API documentation - - - - - - - -
-
+

cloudofficeprint

@@ -183,15 +155,19 @@

Usage

The examples below call this package cop.

-
import cloudofficeprint as cop
-
+
+
import cloudofficeprint as cop
+
+

Templates

Templates are represented by Resource. The simplest way to obtain a Resource is to load from a local path.

-
template = cop.Resource.from_local_file("./path/to/template.docx")
-
+
+
template = cop.Resource.from_local_file("./path/to/template.docx")
+
+

Render elements

@@ -199,7 +175,8 @@

Render elements

Combining a simple line chart and some text tags:

-
line = cop.elements.LineChart(
+
+
line = cop.elements.LineChart(
     "linechart",
     cop.elements.LineSeries([1, 2, 3, 4], [1, 2, 3, 4], color="green"),
     cop.elements.XYSeries([1, 2, 3, 4], ["a", "b", "c", "d"])
@@ -217,554 +194,398 @@ 

Render elements

combined_data.add(line) combined_data.add(text_tag) combined_data.add_all(text_tags) -
+
+

The server

A Cloud Office Print server is configured as a config.Server. It takes a url and an optional config.ServerConfig which allows for various server configuration options. If you're using Cloud Office Print Cloud edition, you will need to use this to declare your API key.

-
server = cop.config.Server(
+
+
server = cop.config.Server(
     "http://server.url.com/",
     cop.config.ServerConfig(api_key = "YOUR_API_KEY")
 )
-
+
+

PrintJob combines template, data, server and an optional output configuration (config.OutputConfig) and can execute itself on the Cloud Office Print server. An example using the variables declared above:

-
printjob = cop.PrintJob(combined_data, server, template)
+
+
printjob = cop.PrintJob(combined_data, server, template)
 printjob.execute()
-
+
+

A print job can be executed asynchronously as well.

-
import asyncio
+
+
import asyncio
 coroutine = printjob.execute_async()
 # simply await your result when you need it
 result = await coroutine
-
+
+

Full JSON available

If you already have the JSON to be sent to the server (not just the data, but the entire JSON body including your API key and template), this package will wrap the request to the server for you (requests are made using requests).

-
json_data = open("./path/to/data.json", "r").read()
+
+
json_data = open("./path/to/data.json", "r").read()
 cop.PrintJob.execute_full_json(
         json_data, server
     ).to_file("./test/from_full_json_output")
-
+
+

Server errors

In case the Cloud Office Print server returns an error, PrintJob will throw one as well. You can catch it and get either its user-readable message or an encoded stack trace that can be passed to Cloud Office Print support.

-
try:
+
+
try:
     # execute some previously constructed printjob
     printjob.execute()
 except cop.exceptions.COPError as err:
     print("Cloud Office Print error! " + err.user_message)
     print(err.encoded_message)
     ...
-
+
+

Further information

For further information, such as where to find our examples, we refer to our README.md file on our Github page.

-
- View Source -
"""
-This Python package provides a programmatic interface with a [Cloud Office Print](https://www.cloudofficeprint.com) server.
-
-## Usage
-The examples below call this package cop.
-```python
-import cloudofficeprint as cop
-```
-
-### Templates
-Templates are represented by `Resource`. The simplest way to obtain a `Resource` is to load from a local path.
-```python
-template = cop.Resource.from_local_file("./path/to/template.docx")
-```
-
-### Render elements
-Most render elements encapsulate the data for a single tag. An `elements.ElementCollection` is an element which represents a collection of elements.
-
-Combining a simple line chart and some text tags:
-```python
-line = cop.elements.LineChart(
-    "linechart",
-    cop.elements.LineSeries([1, 2, 3, 4], [1, 2, 3, 4], color="green"),
-    cop.elements.XYSeries([1, 2, 3, 4], ["a", "b", "c", "d"])
-)
-
-text_tag = cop.elements.Property("tag-name", "Hello, world!")
-# or multiple at once using ElementCollection.from_mapping
-# and supplying the dictionary representation directly
-text_tags = cop.elements.ElementCollection.from_mapping({
-    "another-tag": "Foo",
-    "one-more-tag": "Bar"
-})
-
-combined_data = cop.elements.ElementCollection()
-combined_data.add(line)
-combined_data.add(text_tag)
-combined_data.add_all(text_tags)
-```
-
-### The server
-A Cloud Office Print server is configured as a `config.Server`. It takes a url and an optional `config.ServerConfig` which allows for various server configuration options. If you're using Cloud Office Print Cloud edition, you will need to use this to declare your API key.
-
-```python
-server = cop.config.Server(
-    "http://server.url.com/",
-    cop.config.ServerConfig(api_key = "YOUR_API_KEY")
-)
-```
-
-### Print job
-`PrintJob` combines template, data, server and an optional output configuration (`config.OutputConfig`) and can execute itself on the Cloud Office Print server. An example using the variables declared above:
-
-```python
-printjob = cop.PrintJob(combined_data, server, template)
-printjob.execute()
-```
-
-A print job can be executed asynchronously as well.
-
-```python
-import asyncio
-coroutine = printjob.execute_async()
-# simply await your result when you need it
-result = await coroutine
-```
-
-### Full JSON available
-If you already have the JSON to be sent to the server (not just the data, but the entire JSON body including your API key and template), this package will wrap the request to the server for you (requests are made using [requests](https://requests.readthedocs.io/en/master/)).
-```python
-json_data = open("./path/to/data.json", "r").read()
-cop.PrintJob.execute_full_json(
-        json_data, server
-    ).to_file("./test/from_full_json_output")
-```
-
-### Server errors
-In case the Cloud Office Print server returns an error, `PrintJob` will throw one as well.
-You can catch it and get either its user-readable message or an encoded stack trace that can be passed to Cloud Office Print support.
-```python
-try:
-    # execute some previously constructed printjob
-    printjob.execute()
-except cop.exceptions.COPError as err:
-    print("Cloud Office Print error! " + err.user_message)
-    print(err.encoded_message)
-    ...
-```
-
-### Further information
-For further information, such as where to find our examples, we refer to our README.md file on our [Github page](https://github.com/United-Codes/cloudofficeprint-python/).
-"""
-
-from . import exceptions, config, elements, own_utils
-
-from .printjob import PrintJob
-from .resource import Resource
-from .response import Response
-
-# specify what is imported on "from cloudofficeprint import *"
-# but that shouldn't really be used anyway
-__all__ = [
-    "exceptions",
-    "config",
-    "elements",
-    "own_utils",
-    "PrintJob",
-    "Resource",
-    "Response"
-]
-
- -
- -
-
- - -
- View Source -
"""Custom exceptions for cloudofficeprint."""
-
-from typing import List
-
-
-class COPError(Exception):
-    """The error that is thrown when the Cloud Office Print server itself returns an error instead of a result.
-
-    It contains a user message and an encoded message to be handed to Cloud Office Print support if they are contacted.
-    """
-
-    def __init__(self, full_message: str):
-        """
-        Args:
-            full_message (str): the full error message received from the Cloud Office Print server
-        """
-        (self._user_message,
-         self._contact_support_message,
-         self._encoded_message) = self._split_message(full_message)
-        super().__init__(self._user_message)
-
-    @staticmethod
-    def _split_message(message: str) -> List[str]:
-        """Split the Cloud Office Print server error message into different parts: user message, contact support message and encoded message.
-
-        Args:
-            message (str): Cloud Office Print server error message
-
-        Returns:
-            List[str]: a list with the split messages
-        """
-        separated = message.split("\n")
-        # everything before the last 2 lines are considered user message
-        user_message = "\n".join(separated[:-2])
-        # second to last line contains the support message
-        contact_support_message = separated[-2]
-        # last line contains the encoded message
-        encoded_message = separated[-1]
-        return [user_message, contact_support_message, encoded_message]
-
-    @property
-    def encoded_message(self) -> str:
-        """The encrypted and encoded part of the message, for Cloud Office Print support.
-
-        Returns:
-            str: the encrypted and encoded part of the message, for Cloud Office Print support
-        """
-        return self._encoded_message
-
-    @property
-    def user_message(self) -> str:
-        """The user-friendly part of the message.
-
-        Returns:
-            str: the user-friendly part of the message
-        """
-        return self._user_message
-
-    @property
-    def contact_support_message(self) -> str:
-        """The contact support message.
-
-        Returns:
-            str: the contact support message
-        """
-        return self._contact_support_message
-
-    @property
-    def full_message(self) -> str:
-        """The full error message as sent by the server.
-
-        Returns:
-            str: the full error message as sent by the server
-        """
-        return self.user_message + "\n" + self.contact_support_message + "\n" + self.encoded_message
-
- -
- -

Custom exceptions for cloudofficeprint.

-
- - -
-
- - -
- View Source -
"""
-Module for output configurations.
-
-The classes under this module encapsulate various configuration options for a print job.
-They are to be used with `cloudofficeprint.printjob.PrintJob`.
-"""
-
-from .cloud import *
-from .csv import *
-from .output import *
-from .pdf import *
-from .server import *
-
- -
- -

Module for output configurations.

- -

The classes under this module encapsulate various configuration options for a print job. -They are to be used with cloudofficeprint.printjob.PrintJob.

-
- - -
-
- - -
- View Source -
"""
-Elements are used to replace the various tags in a template with actual data.
-"""
-
-from .charts import *
-from .codes import *
-from .elements import *
-from .images import *
-from .loops import *
-from .pdf import *
-from .rest_source import *
-
- -
- -

Elements are used to replace the various tags in a template with actual data.

-
- - -
-
- - -
- View Source -
"""
-Helper functions.
-"""
-
-from .file_utils import *
-from .type_utils import *
-
- -
- -

Helper functions.

-
+ + + + +
  1"""
+  2This Python package provides a programmatic interface with a [Cloud Office Print](https://www.cloudofficeprint.com) server.
+  3
+  4## Usage
+  5The examples below call this package cop.
+  6```python
+  7import cloudofficeprint as cop
+  8```
+  9
+ 10### Templates
+ 11Templates are represented by `Resource`. The simplest way to obtain a `Resource` is to load from a local path.
+ 12```python
+ 13template = cop.Resource.from_local_file("./path/to/template.docx")
+ 14```
+ 15
+ 16### Render elements
+ 17Most render elements encapsulate the data for a single tag. An `elements.ElementCollection` is an element which represents a collection of elements.
+ 18
+ 19Combining a simple line chart and some text tags:
+ 20```python
+ 21line = cop.elements.LineChart(
+ 22    "linechart",
+ 23    cop.elements.LineSeries([1, 2, 3, 4], [1, 2, 3, 4], color="green"),
+ 24    cop.elements.XYSeries([1, 2, 3, 4], ["a", "b", "c", "d"])
+ 25)
+ 26
+ 27text_tag = cop.elements.Property("tag-name", "Hello, world!")
+ 28# or multiple at once using ElementCollection.from_mapping
+ 29# and supplying the dictionary representation directly
+ 30text_tags = cop.elements.ElementCollection.from_mapping({
+ 31    "another-tag": "Foo",
+ 32    "one-more-tag": "Bar"
+ 33})
+ 34
+ 35combined_data = cop.elements.ElementCollection()
+ 36combined_data.add(line)
+ 37combined_data.add(text_tag)
+ 38combined_data.add_all(text_tags)
+ 39```
+ 40
+ 41### The server
+ 42A Cloud Office Print server is configured as a `config.Server`. It takes a url and an optional `config.ServerConfig` which allows for various server configuration options. If you're using Cloud Office Print Cloud edition, you will need to use this to declare your API key.
+ 43
+ 44```python
+ 45server = cop.config.Server(
+ 46    "http://server.url.com/",
+ 47    cop.config.ServerConfig(api_key = "YOUR_API_KEY")
+ 48)
+ 49```
+ 50
+ 51### Print job
+ 52`PrintJob` combines template, data, server and an optional output configuration (`config.OutputConfig`) and can execute itself on the Cloud Office Print server. An example using the variables declared above:
+ 53
+ 54```python
+ 55printjob = cop.PrintJob(combined_data, server, template)
+ 56printjob.execute()
+ 57```
+ 58
+ 59A print job can be executed asynchronously as well.
+ 60
+ 61```python
+ 62import asyncio
+ 63coroutine = printjob.execute_async()
+ 64# simply await your result when you need it
+ 65result = await coroutine
+ 66```
+ 67
+ 68### Full JSON available
+ 69If you already have the JSON to be sent to the server (not just the data, but the entire JSON body including your API key and template), this package will wrap the request to the server for you (requests are made using [requests](https://requests.readthedocs.io/en/master/)).
+ 70```python
+ 71json_data = open("./path/to/data.json", "r").read()
+ 72cop.PrintJob.execute_full_json(
+ 73        json_data, server
+ 74    ).to_file("./test/from_full_json_output")
+ 75```
+ 76
+ 77### Server errors
+ 78In case the Cloud Office Print server returns an error, `PrintJob` will throw one as well.
+ 79You can catch it and get either its user-readable message or an encoded stack trace that can be passed to Cloud Office Print support.
+ 80```python
+ 81try:
+ 82    # execute some previously constructed printjob
+ 83    printjob.execute()
+ 84except cop.exceptions.COPError as err:
+ 85    print("Cloud Office Print error! " + err.user_message)
+ 86    print(err.encoded_message)
+ 87    ...
+ 88```
+ 89
+ 90### Further information
+ 91For further information, such as where to find our examples, we refer to our README.md file on our [Github page](https://github.com/United-Codes/cloudofficeprint-python/).
+ 92"""
+ 93
+ 94from . import exceptions, config, elements, own_utils
+ 95
+ 96from .printjob import PrintJob
+ 97from .resource import Resource
+ 98from .response import Response
+ 99
+100# specify what is imported on "from cloudofficeprint import *"
+101# but that shouldn't really be used anyway
+102__all__ = [
+103    "exceptions",
+104    "config",
+105    "elements",
+106    "own_utils",
+107    "PrintJob",
+108    "Resource",
+109    "Response"
+110]
+
-
+
-
- #   + +
+ + class + PrintJob: + + - - class - PrintJob:
+ +
 27class PrintJob:
+ 28    """A print job for a Cloud Office Print server.
+ 29
+ 30    This class contains all configuration options, resources, render elements ...
+ 31    and the `PrintJob.execute` method to combine all these and send a request to the Cloud Office Print server.
+ 32    """
+ 33
+ 34    def __init__(self,
+ 35                 data: Union[Element, Mapping[str, Element], RESTSource],
+ 36                 server: Server,
+ 37                 template: Resource = None,
+ 38                 output_config: OutputConfig = OutputConfig(),
+ 39                 subtemplates: Dict[str, Resource] = {},
+ 40                 prepend_files: List[Resource] = [],
+ 41                 append_files: List[Resource] = [],
+ 42                 cop_verbose: bool = False):
+ 43        """
+ 44        Args:
+ 45            data (Union[Element, Mapping[str, Element], RESTSource]): This is either: An `Element` (e.g. an `ElementCollection`); A mapping, containing file names as keys and an `Element` as data. Multiple files will be produced from the different datas, the result is a zip file containing them. In the first case, no output file name is specified and the server will name it "file0".
+ 46            server (Server): Server to be used for this print job.
+ 47            template (Resource): Template to use for this print job.
+ 48            output_config (OutputConfig, optional): Output configuration to be used for this print job. Defaults to `OutputConfig`().
+ 49            subtemplates (Dict[str, Resource], optional): Subtemplates for this print job, accessible (in docx) through `{?include subtemplate_dict_key}`. Defaults to {}.
+ 50            prepend_files (List[Resource], optional): Files to prepend to the output file. Defaults to [].
+ 51            append_files (List[Resource], optional): Files to append to the output file. Defaults to [].
+ 52            cop_verbose (bool, optional): Whether or not verbose mode should be activated. Defaults to False.
+ 53        """
+ 54
+ 55        self.data: Union[Element, Mapping[str, Element], RESTSource] = data
+ 56        self.server: Server = server
+ 57        self.output_config: OutputConfig = output_config
+ 58        self.template: Resource = template
+ 59        self.subtemplates: Dict[str, Resource] = subtemplates
+ 60        self.prepend_files: List[Resource] = prepend_files
+ 61        self.append_files: List[Resource] = append_files
+ 62        self.cop_verbose: bool = cop_verbose
+ 63
+ 64    def execute(self) -> Response:
+ 65        """Execute this print job.
+ 66
+ 67        Returns:
+ 68            Response: `Response`-object
+ 69        """
+ 70        self.server._raise_if_unreachable()
+ 71        return self._handle_response(requests.post(self.server.url, proxies=self.server.config.proxies if self.server.config is not None else None, json=self.as_dict, headers={"Content-type": "application/json"}))
+ 72
+ 73    async def execute_async(self) -> Response:
+ 74        """Async version of `PrintJob.execute`
+ 75
+ 76        Returns:
+ 77            Response: `Response`-object
+ 78        """
+ 79        self.server._raise_if_unreachable()
+ 80        return PrintJob._handle_response(
+ 81            await asyncio.get_event_loop().run_in_executor(
+ 82                None, partial(
+ 83                    requests.post,
+ 84                    self.server.url,
+ 85                    proxies=self.server.config.proxies if self.server.config is not None else None,
+ 86                    json=self.as_dict
+ 87                )
+ 88            )
+ 89        )
+ 90
+ 91    @staticmethod
+ 92    def execute_full_json(json_data: str, server: Server) -> Response:
+ 93        """If you already have the JSON to be sent to the server (not just the data, but the entire JSON body including your API key and template), this package will wrap the request to the server.
+ 94
+ 95        Args:
+ 96            json_data (str): full JSON data that needs to be sent to a Cloud Office Print server
+ 97            server (Server): `Server`-object
+ 98
+ 99        Returns:
+100            Response: `Response`-object
+101        """
+102        server._raise_if_unreachable()
+103        return PrintJob._handle_response(requests.post(server.url, proxies=server.config.proxies if server.config is not None else None, data=json_data, headers={"Content-type": "application/json"}))
+104
+105    @staticmethod
+106    async def execute_full_json_async(json_data: str, server: Server) -> Response:
+107        """Async version of `Printjob.execute_full_json`
+108
+109        Args:
+110            json_data (str): full JSON data that needs to be sent to a Cloud Office Print server
+111            server (Server): `Server`-object
+112
+113        Returns:
+114            Response: `Response`-object
+115        """
+116        server._raise_if_unreachable()
+117        return PrintJob._handle_response(
+118            await asyncio.get_event_loop().run_in_executor(
+119                None, partial(
+120                    requests.post,
+121                    server.url,
+122                    proxies=server.config.proxies if server.config is not None else None,
+123                    data=json_data,
+124                    headers={"Content-type": "application/json"}
+125                )
+126            )
+127        )
+128
+129    @staticmethod
+130    def _handle_response(res: requests.Response) -> Response:
+131        """Converts the HTML response to a `Response`-object
+132
+133        Args:
+134            res (requests.Response): HTML response from the Cloud Office Print server
+135
+136        Raises:
+137            COPError: Error when the HTML status code is not 200
+138
+139        Returns:
+140            Response: `Response`-object of HTML response
+141        """
+142        if res.status_code != 200:
+143            raise COPError(res.text)
+144        else:
+145            return Response(res)
+146
+147    @property
+148    def json(self) -> str:
+149        """JSON equivalent of the dict representation of this print job.
+150        This representation is isomorphic to the dict representation `Printjob.as_dict`.
+151
+152        Returns:
+153            str: JSON equivalent of the dict representation of this print job
+154        """
+155        return json.dumps(self.as_dict)
+156
+157    @property
+158    def as_dict(self) -> Dict:
+159        """Return the dict representation of this print job.
+160
+161        Returns:
+162            Dict: dict representation of this print job
+163        """
+164        result = dict(
+165            STATIC_OPTS)  # Copy of STATIC_OPTS! Otherwise everything we add to 'result' will also be added to 'STATIC_OPTS'
+166        # server config goes in the upper level
+167        if self.server.config:
+168            result.update(self.server.config.as_dict)
+169
+170        # output config goes in "output"
+171        # and decides where its sub-configs go through its as_dict property
+172        # (e.g. PDFConfigs are just appended at this "output" level)
+173        result["output"] = self.output_config.as_dict
+174
+175        if self.template:
+176            result["template"] = self.template.template_dict
+177
+178        # If output_type is not specified, set this to the template filetype
+179        # If no template found: default docx
+180        if 'output_type' not in self.output_config.as_dict.keys():
+181            if self.template:
+182                result['output']['output_type'] = result['template']['template_type']
+183            else:
+184                result['output']['output_type'] = 'docx'
+185
+186        if isinstance(self.data, Mapping):
+187            result["files"] = [{
+188                "filename": name,
+189                "data": data.as_dict
+190            } for name, data in self.data.items()]
+191        elif isinstance(self.data, RESTSource):
+192            result['files'] = [self.data.as_dict]
+193        else:
+194            result["files"] = [{"data": self.data.as_dict}]
+195
+196        if len(self.prepend_files) > 0:
+197            result["prepend_files"] = [
+198                res.secondary_file_dict for res in self.prepend_files
+199            ]
+200
+201        if len(self.append_files) > 0:
+202            result["append_files"] = [
+203                res.secondary_file_dict for res in self.append_files
+204            ]
+205
+206        if len(self.subtemplates) > 0:
+207            templates_list = []
+208            for name, res in self.subtemplates.items():
+209                to_add = res.secondary_file_dict
+210                to_add["name"] = name
+211                templates_list.append(to_add)
+212            result["templates"] = templates_list
+213
+214        # If verbose mode is activated, print the result to the terminal
+215        if self.cop_verbose:
+216            print('The JSON data that is sent to the Cloud Office Print server:\n')
+217            pprint(result)
+218
+219        return result
+
-
- View Source -
class PrintJob:
-    """A print job for a Cloud Office Print server.
-
-    This class contains all configuration options, resources, render elements ...
-    and the `PrintJob.execute` method to combine all these and send a request to the Cloud Office Print server.
-    """
-
-    def __init__(self,
-                 data: Union[Element, Mapping[str, Element], RESTSource],
-                 server: Server,
-                 template: Resource = None,
-                 output_config: OutputConfig = OutputConfig(),
-                 subtemplates: Dict[str, Resource] = {},
-                 prepend_files: List[Resource] = [],
-                 append_files: List[Resource] = [],
-                 cop_verbose: bool = False):
-        """
-        Args:
-            data (Union[Element, Mapping[str, Element], RESTSource]): This is either: An `Element` (e.g. an `ElementCollection`); A mapping, containing file names as keys and an `Element` as data. Multiple files will be produced from the different datas, the result is a zip file containing them. In the first case, no output file name is specified and the server will name it "file0".
-            server (Server): Server to be used for this print job.
-            template (Resource): Template to use for this print job.
-            output_config (OutputConfig, optional): Output configuration to be used for this print job. Defaults to `OutputConfig`().
-            subtemplates (Dict[str, Resource], optional): Subtemplates for this print job, accessible (in docx) through `{?include subtemplate_dict_key}`. Defaults to {}.
-            prepend_files (List[Resource], optional): Files to prepend to the output file. Defaults to [].
-            append_files (List[Resource], optional): Files to append to the output file. Defaults to [].
-            cop_verbose (bool, optional): Whether or not verbose mode should be activated. Defaults to False.
-        """
-
-        self.data: Union[Element, Mapping[str, Element], RESTSource] = data
-        self.server: Server = server
-        self.output_config: OutputConfig = output_config
-        self.template: Resource = template
-        self.subtemplates: Dict[str, Resource] = subtemplates
-        self.prepend_files: List[Resource] = prepend_files
-        self.append_files: List[Resource] = append_files
-        self.cop_verbose: bool = cop_verbose
-
-    def execute(self) -> Response:
-        """Execute this print job.
-
-        Returns:
-            Response: `Response`-object
-        """
-        self.server._raise_if_unreachable()
-        return self._handle_response(requests.post(self.server.url, proxies=self.server.config.proxies if self.server.config is not None else None, json=self.as_dict, headers={"Content-type": "application/json"}))
-
-    async def execute_async(self) -> Response:
-        """Async version of `PrintJob.execute`
-
-        Returns:
-            Response: `Response`-object
-        """
-        self.server._raise_if_unreachable()
-        return PrintJob._handle_response(
-            await asyncio.get_event_loop().run_in_executor(
-                None, partial(
-                    requests.post,
-                    self.server.url,
-                    proxies=self.server.config.proxies if self.server.config is not None else None,
-                    json=self.as_dict
-                )
-            )
-        )
-
-    @staticmethod
-    def execute_full_json(json_data: str, server: Server) -> Response:
-        """If you already have the JSON to be sent to the server (not just the data, but the entire JSON body including your API key and template), this package will wrap the request to the server.
-
-        Args:
-            json_data (str): full JSON data that needs to be sent to a Cloud Office Print server
-            server (Server): `Server`-object
-
-        Returns:
-            Response: `Response`-object
-        """
-        server._raise_if_unreachable()
-        return PrintJob._handle_response(requests.post(server.url, proxies=server.config.proxies if server.config is not None else None, data=json_data, headers={"Content-type": "application/json"}))
-
-    @staticmethod
-    async def execute_full_json_async(json_data: str, server: Server) -> Response:
-        """Async version of `Printjob.execute_full_json`
-
-        Args:
-            json_data (str): full JSON data that needs to be sent to a Cloud Office Print server
-            server (Server): `Server`-object
-
-        Returns:
-            Response: `Response`-object
-        """
-        server._raise_if_unreachable()
-        return PrintJob._handle_response(
-            await asyncio.get_event_loop().run_in_executor(
-                None, partial(
-                    requests.post,
-                    server.url,
-                    proxies=server.config.proxies if server.config is not None else None,
-                    data=json_data,
-                    headers={"Content-type": "application/json"}
-                )
-            )
-        )
-
-    @staticmethod
-    def _handle_response(res: requests.Response) -> Response:
-        """Converts the HTML response to a `Response`-object
-
-        Args:
-            res (requests.Response): HTML response from the Cloud Office Print server
-
-        Raises:
-            COPError: Error when the HTML status code is not 200
-
-        Returns:
-            Response: `Response`-object of HTML response
-        """
-        if res.status_code != 200:
-            raise COPError(res.text)
-        else:
-            return Response(res)
-
-    @property
-    def json(self) -> str:
-        """JSON equivalent of the dict representation of this print job.
-        This representation is isomorphic to the dict representation `Printjob.as_dict`.
-
-        Returns:
-            str: JSON equivalent of the dict representation of this print job
-        """
-        return json.dumps(self.as_dict)
-
-    @property
-    def as_dict(self) -> Dict:
-        """Return the dict representation of this print job.
-
-        Returns:
-            Dict: dict representation of this print job
-        """
-        result = dict(
-            STATIC_OPTS)  # Copy of STATIC_OPTS! Otherwise everything we add to 'result' will also be added to 'STATIC_OPTS'
-        # server config goes in the upper level
-        if self.server.config:
-            result.update(self.server.config.as_dict)
-
-        # output config goes in "output"
-        # and decides where its sub-configs go through its as_dict property
-        # (e.g. PDFConfigs are just appended at this "output" level)
-        result["output"] = self.output_config.as_dict
-
-        if self.template:
-            result["template"] = self.template.template_dict
-
-        # If output_type is not specified, set this to the template filetype
-        # If no template found: default docx
-        if 'output_type' not in self.output_config.as_dict.keys():
-            if self.template:
-                result['output']['output_type'] = result['template']['template_type']
-            else:
-                result['output']['output_type'] = 'docx'
-
-        if isinstance(self.data, Mapping):
-            result["files"] = [{
-                "filename": name,
-                "data": data.as_dict
-            } for name, data in self.data.items()]
-        elif isinstance(self.data, RESTSource):
-            result['files'] = [self.data.as_dict]
-        else:
-            result["files"] = [{"data": self.data.as_dict}]
-
-        if len(self.prepend_files) > 0:
-            result["prepend_files"] = [
-                res.secondary_file_dict for res in self.prepend_files
-            ]
-
-        if len(self.append_files) > 0:
-            result["append_files"] = [
-                res.secondary_file_dict for res in self.append_files
-            ]
-
-        if len(self.subtemplates) > 0:
-            templates_list = []
-            for name, res in self.subtemplates.items():
-                to_add = res.secondary_file_dict
-                to_add["name"] = name
-                templates_list.append(to_add)
-            result["templates"] = templates_list
-
-        # If verbose mode is activated, print the result to the terminal
-        if self.cop_verbose:
-            print('The JSON data that is sent to the Cloud Office Print server:\n')
-            pprint(result)
-
-        return result
-
- -

A print job for a Cloud Office Print server.

@@ -774,55 +595,46 @@

Further information

-
#   + + + +
34    def __init__(self,
+35                 data: Union[Element, Mapping[str, Element], RESTSource],
+36                 server: Server,
+37                 template: Resource = None,
+38                 output_config: OutputConfig = OutputConfig(),
+39                 subtemplates: Dict[str, Resource] = {},
+40                 prepend_files: List[Resource] = [],
+41                 append_files: List[Resource] = [],
+42                 cop_verbose: bool = False):
+43        """
+44        Args:
+45            data (Union[Element, Mapping[str, Element], RESTSource]): This is either: An `Element` (e.g. an `ElementCollection`); A mapping, containing file names as keys and an `Element` as data. Multiple files will be produced from the different datas, the result is a zip file containing them. In the first case, no output file name is specified and the server will name it "file0".
+46            server (Server): Server to be used for this print job.
+47            template (Resource): Template to use for this print job.
+48            output_config (OutputConfig, optional): Output configuration to be used for this print job. Defaults to `OutputConfig`().
+49            subtemplates (Dict[str, Resource], optional): Subtemplates for this print job, accessible (in docx) through `{?include subtemplate_dict_key}`. Defaults to {}.
+50            prepend_files (List[Resource], optional): Files to prepend to the output file. Defaults to [].
+51            append_files (List[Resource], optional): Files to append to the output file. Defaults to [].
+52            cop_verbose (bool, optional): Whether or not verbose mode should be activated. Defaults to False.
+53        """
+54
+55        self.data: Union[Element, Mapping[str, Element], RESTSource] = data
+56        self.server: Server = server
+57        self.output_config: OutputConfig = output_config
+58        self.template: Resource = template
+59        self.subtemplates: Dict[str, Resource] = subtemplates
+60        self.prepend_files: List[Resource] = prepend_files
+61        self.append_files: List[Resource] = append_files
+62        self.cop_verbose: bool = cop_verbose
+
-
- View Source -
    def __init__(self,
-                 data: Union[Element, Mapping[str, Element], RESTSource],
-                 server: Server,
-                 template: Resource = None,
-                 output_config: OutputConfig = OutputConfig(),
-                 subtemplates: Dict[str, Resource] = {},
-                 prepend_files: List[Resource] = [],
-                 append_files: List[Resource] = [],
-                 cop_verbose: bool = False):
-        """
-        Args:
-            data (Union[Element, Mapping[str, Element], RESTSource]): This is either: An `Element` (e.g. an `ElementCollection`); A mapping, containing file names as keys and an `Element` as data. Multiple files will be produced from the different datas, the result is a zip file containing them. In the first case, no output file name is specified and the server will name it "file0".
-            server (Server): Server to be used for this print job.
-            template (Resource): Template to use for this print job.
-            output_config (OutputConfig, optional): Output configuration to be used for this print job. Defaults to `OutputConfig`().
-            subtemplates (Dict[str, Resource], optional): Subtemplates for this print job, accessible (in docx) through `{?include subtemplate_dict_key}`. Defaults to {}.
-            prepend_files (List[Resource], optional): Files to prepend to the output file. Defaults to [].
-            append_files (List[Resource], optional): Files to append to the output file. Defaults to [].
-            cop_verbose (bool, optional): Whether or not verbose mode should be activated. Defaults to False.
-        """
-
-        self.data: Union[Element, Mapping[str, Element], RESTSource] = data
-        self.server: Server = server
-        self.output_config: OutputConfig = output_config
-        self.template: Resource = template
-        self.subtemplates: Dict[str, Resource] = subtemplates
-        self.prepend_files: List[Resource] = prepend_files
-        self.append_files: List[Resource] = append_files
-        self.cop_verbose: bool = cop_verbose
-
- -

Args: data (Union[Element, Mapping[str, Element], RESTSource]): This is either: An Element (e.g. an ElementCollection); A mapping, containing file names as keys and an Element as data. Multiple files will be produced from the different datas, the result is a zip file containing them. In the first case, no output file name is specified and the server will name it "file0". @@ -838,26 +650,26 @@

Further information

-
#   - - - def - execute(self) -> cloudofficeprint.response.Response: -
+ +
+ + def + execute(self) -> cloudofficeprint.Response: -
- View Source -
    def execute(self) -> Response:
-        """Execute this print job.
+                
 
-        Returns:
-            Response: `Response`-object
-        """
-        self.server._raise_if_unreachable()
-        return self._handle_response(requests.post(self.server.url, proxies=self.server.config.proxies if self.server.config is not None else None, json=self.as_dict, headers={"Content-type": "application/json"}))
-
+
+ +
64    def execute(self) -> Response:
+65        """Execute this print job.
+66
+67        Returns:
+68            Response: `Response`-object
+69        """
+70        self.server._raise_if_unreachable()
+71        return self._handle_response(requests.post(self.server.url, proxies=self.server.config.proxies if self.server.config is not None else None, json=self.as_dict, headers={"Content-type": "application/json"}))
+
-

Execute this print job.

@@ -868,35 +680,35 @@

Further information

-
#   + +
+ + async def + execute_async(self) -> cloudofficeprint.Response: + + - - async def - execute_async(self) -> cloudofficeprint.response.Response:
+ +
73    async def execute_async(self) -> Response:
+74        """Async version of `PrintJob.execute`
+75
+76        Returns:
+77            Response: `Response`-object
+78        """
+79        self.server._raise_if_unreachable()
+80        return PrintJob._handle_response(
+81            await asyncio.get_event_loop().run_in_executor(
+82                None, partial(
+83                    requests.post,
+84                    self.server.url,
+85                    proxies=self.server.config.proxies if self.server.config is not None else None,
+86                    json=self.as_dict
+87                )
+88            )
+89        )
+
-
- View Source -
    async def execute_async(self) -> Response:
-        """Async version of `PrintJob.execute`
-
-        Returns:
-            Response: `Response`-object
-        """
-        self.server._raise_if_unreachable()
-        return PrintJob._handle_response(
-            await asyncio.get_event_loop().run_in_executor(
-                None, partial(
-                    requests.post,
-                    self.server.url,
-                    proxies=self.server.config.proxies if self.server.config is not None else None,
-                    json=self.as_dict
-                )
-            )
-        )
-
- -

Async version of PrintJob.execute

@@ -907,35 +719,32 @@

Further information

-
#   + +
+
@staticmethod
-
@staticmethod
+ def + execute_full_json( json_data: str, server: cloudofficeprint.config.server.Server) -> cloudofficeprint.Response: - def - execute_full_json( - json_data: str, - server: cloudofficeprint.config.server.Server -) -> cloudofficeprint.response.Response: -
+ -
- View Source -
    @staticmethod
-    def execute_full_json(json_data: str, server: Server) -> Response:
-        """If you already have the JSON to be sent to the server (not just the data, but the entire JSON body including your API key and template), this package will wrap the request to the server.
-
-        Args:
-            json_data (str): full JSON data that needs to be sent to a Cloud Office Print server
-            server (Server): `Server`-object
-
-        Returns:
-            Response: `Response`-object
-        """
-        server._raise_if_unreachable()
-        return PrintJob._handle_response(requests.post(server.url, proxies=server.config.proxies if server.config is not None else None, data=json_data, headers={"Content-type": "application/json"}))
-
+
+ +
 91    @staticmethod
+ 92    def execute_full_json(json_data: str, server: Server) -> Response:
+ 93        """If you already have the JSON to be sent to the server (not just the data, but the entire JSON body including your API key and template), this package will wrap the request to the server.
+ 94
+ 95        Args:
+ 96            json_data (str): full JSON data that needs to be sent to a Cloud Office Print server
+ 97            server (Server): `Server`-object
+ 98
+ 99        Returns:
+100            Response: `Response`-object
+101        """
+102        server._raise_if_unreachable()
+103        return PrintJob._handle_response(requests.post(server.url, proxies=server.config.proxies if server.config is not None else None, data=json_data, headers={"Content-type": "application/json"}))
+
-

If you already have the JSON to be sent to the server (not just the data, but the entire JSON body including your API key and template), this package will wrap the request to the server.

@@ -950,45 +759,42 @@

Further information

-
#   + +
+
@staticmethod
+ + async def + execute_full_json_async( json_data: str, server: cloudofficeprint.config.server.Server) -> cloudofficeprint.Response: -
@staticmethod
+ - async def - execute_full_json_async( - json_data: str, - server: cloudofficeprint.config.server.Server -) -> cloudofficeprint.response.Response:
+ +
105    @staticmethod
+106    async def execute_full_json_async(json_data: str, server: Server) -> Response:
+107        """Async version of `Printjob.execute_full_json`
+108
+109        Args:
+110            json_data (str): full JSON data that needs to be sent to a Cloud Office Print server
+111            server (Server): `Server`-object
+112
+113        Returns:
+114            Response: `Response`-object
+115        """
+116        server._raise_if_unreachable()
+117        return PrintJob._handle_response(
+118            await asyncio.get_event_loop().run_in_executor(
+119                None, partial(
+120                    requests.post,
+121                    server.url,
+122                    proxies=server.config.proxies if server.config is not None else None,
+123                    data=json_data,
+124                    headers={"Content-type": "application/json"}
+125                )
+126            )
+127        )
+
-
- View Source -
    @staticmethod
-    async def execute_full_json_async(json_data: str, server: Server) -> Response:
-        """Async version of `Printjob.execute_full_json`
-
-        Args:
-            json_data (str): full JSON data that needs to be sent to a Cloud Office Print server
-            server (Server): `Server`-object
-
-        Returns:
-            Response: `Response`-object
-        """
-        server._raise_if_unreachable()
-        return PrintJob._handle_response(
-            await asyncio.get_event_loop().run_in_executor(
-                None, partial(
-                    requests.post,
-                    server.url,
-                    proxies=server.config.proxies if server.config is not None else None,
-                    data=json_data,
-                    headers={"Content-type": "application/json"}
-                )
-            )
-        )
-
- -

Async version of Printjob.execute_full_json

@@ -1003,11 +809,13 @@

Further information

-
#   +
+ json: str - json: str +
- + +

JSON equivalent of the dict representation of this print job. This representation is isomorphic to the dict representation Printjob.as_dict.

@@ -1018,11 +826,13 @@

Further information

-
#   +
+ as_dict: Dict - as_dict: Dict +
- + +

Return the dict representation of this print job.

Returns: @@ -1033,205 +843,204 @@

Further information

-
- #   - - - class - Resource(abc.ABC): -
- -
- View Source -
class Resource(ABC):
-    """The abstract base class for the resources."""
-
-    def __init__(self, data: Union[str, bytes] = None, filetype: str = None):
-        """
-        Args:
-            data (Union[str, bytes], optional): the data for this resource. Defaults to None.
-            filetype (str, optional): the file type of this resource. Defaults to None.
-        """
-        self._data: Union[str, bytes] = data
-        self.filetype: str = filetype
-
-    @property
-    def mimetype(self) -> str:
-        """Resource type as a mime type.
-
-        Returns:
-            str: resource type as a mime type
-        """
-        return type_utils.extension_to_mimetype(self.filetype)
-
-    @property
-    def data(self) -> Union[str, bytes]:
-        """The data contained in this Resource.
-
-        Returns:
-            Union[str, bytes]: the data contained in this Resource
-        """
-        return self._data
-
-    @property
-    def template_json(self) -> str:
-        """Get the JSON representation when used as a template.
-
-        Returns:
-            str: JSON representation of this resource as a template
-        """
-        return json.dumps(self.template_dict)
-
-    @property
-    @abstractmethod
-    def template_dict(self) -> Dict:
-        """This Resource object as a dict object for use as a template.
-        This dict and the template JSON representation (`Resource.template_json`) are isomorphic.
-
-        Returns:
-            Dict: dict representation of this resource as a template
-        """
-        pass
-
-    @property
-    def secondary_file_json(self) -> str:
-        """The JSON representation for use as secondary file.
-
-        Returns:
-            str: JSON representation of this resource as a secondary file
-        """
-        return json.dumps(self.secondary_file_dict)
-
-    @property
-    @abstractmethod
-    def secondary_file_dict(self) -> Dict:
-        """This Resource object as a dict object for use as a secondary file (prepend, append, insert, as subtemplate).
-        This dict and the "concat file" JSON representation (`Resource.secondary_file_json`) are isomorphic.
-
-        Returns:
-            Dict: dict representation of this resource as a secondary file
-        """
-        pass
-
-    def __str__(self) -> str:
-        """Override the string representation of this class to return the template-style json.
-
-        Returns:
-            str: JSON representation of this resource as a template
-        """
-        return self.template_json
-
-    @staticmethod
-    def from_base64(base64string: str, filetype: str) -> 'Base64Resource':
-        """Create a Base64Resource from a base64 string and a file type (extension).
-
-        Args:
-            base64string (str): base64 encoded string
-            filetype (str): file type (extension)
-
-        Returns:
-            Base64Resource: the created Resource
-        """
-        return Base64Resource(base64string, filetype)
-
-    @staticmethod
-    def from_raw(raw_data: bytes, filetype: str) -> 'RawResource':
-        """Create a RawResource from raw file data and a file type (extension).
-
-        Args:
-            raw_data (bytes): raw data as a [bytes-like object](https://docs.python.org/3/glossary.html#term-bytes-like-object)
-            filetype (str): file type (extension)
-
-        Returns:
-            RawResource: the created Resource
-        """
-        return RawResource(raw_data, filetype)
-
-    @staticmethod
-    def from_local_file(local_path: str) -> 'Base64Resource':
-        """Create a Base64Resource with the contents of a local file.
-
-        Throws IOError if it can't read the file.
-        The filetype is determined by the extension of the file.
-
-        Args:
-            local_path (str): path to local file
-
-        Returns:
-            Base64Resource: the created Resource
-        """
-        base64string: str = file_utils.read_file_as_base64(local_path)
-        return Base64Resource(base64string, type_utils.path_to_extension(local_path))
-
-    @staticmethod
-    def from_server_path(path: str) -> 'ServerPathResource':
-        """Create a ServerPathResource targeting a file on the server.
-
-        The filetype is determined by the extension of the file.
-
-        Args:
-            path (str): location of target file on the server
-
-        Returns:
-            ServerPathResource: the created Resource
-        """
-        return ServerPathResource(path)
-
-    @staticmethod
-    def from_url(url: str, filetype: str) -> 'URLResource':
-        """Create an Resource targeting the file at url with given filetype (extension).
-
-        Args:
-            url (str): file url
-            filetype (str): file type (extension)
-
-        Returns:
-            URLResource: the created Resource
-        """
-        return URLResource(url, filetype)
+                            
+
+ + class + Resource(abc.ABC): - @staticmethod - def from_html(htmlstring: str, landscape: bool = False) -> 'HTMLResource': - """Create an HTMLResource with html data in plain text. + - Landscape is not supported for prepend/append sources, only for template resources. - - Args: - htmlstring (str): html content - landscape (bool, optional): whether to use the landscape option. Defaults to False. - - Returns: - HTMLResource: the created Resource - """ - return HTMLResource(htmlstring, landscape) -
+ + +
 20class Resource(ABC):
+ 21    """The abstract base class for the resources."""
+ 22
+ 23    def __init__(self, data: Union[str, bytes] = None, filetype: str = None):
+ 24        """
+ 25        Args:
+ 26            data (Union[str, bytes], optional): the data for this resource. Defaults to None.
+ 27            filetype (str, optional): the file type of this resource. Defaults to None.
+ 28        """
+ 29        self._data: Union[str, bytes] = data
+ 30        self.filetype: str = filetype
+ 31
+ 32    @property
+ 33    def mimetype(self) -> str:
+ 34        """Resource type as a mime type.
+ 35
+ 36        Returns:
+ 37            str: resource type as a mime type
+ 38        """
+ 39        return type_utils.extension_to_mimetype(self.filetype)
+ 40
+ 41    @property
+ 42    def data(self) -> Union[str, bytes]:
+ 43        """The data contained in this Resource.
+ 44
+ 45        Returns:
+ 46            Union[str, bytes]: the data contained in this Resource
+ 47        """
+ 48        return self._data
+ 49
+ 50    @property
+ 51    def template_json(self) -> str:
+ 52        """Get the JSON representation when used as a template.
+ 53
+ 54        Returns:
+ 55            str: JSON representation of this resource as a template
+ 56        """
+ 57        return json.dumps(self.template_dict)
+ 58
+ 59    @property
+ 60    @abstractmethod
+ 61    def template_dict(self) -> Dict:
+ 62        """This Resource object as a dict object for use as a template.
+ 63        This dict and the template JSON representation (`Resource.template_json`) are isomorphic.
+ 64
+ 65        Returns:
+ 66            Dict: dict representation of this resource as a template
+ 67        """
+ 68        pass
+ 69
+ 70    @property
+ 71    def secondary_file_json(self) -> str:
+ 72        """The JSON representation for use as secondary file.
+ 73
+ 74        Returns:
+ 75            str: JSON representation of this resource as a secondary file
+ 76        """
+ 77        return json.dumps(self.secondary_file_dict)
+ 78
+ 79    @property
+ 80    @abstractmethod
+ 81    def secondary_file_dict(self) -> Dict:
+ 82        """This Resource object as a dict object for use as a secondary file (prepend, append, insert, as subtemplate).
+ 83        This dict and the "concat file" JSON representation (`Resource.secondary_file_json`) are isomorphic.
+ 84
+ 85        Returns:
+ 86            Dict: dict representation of this resource as a secondary file
+ 87        """
+ 88        pass
+ 89
+ 90    def __str__(self) -> str:
+ 91        """Override the string representation of this class to return the template-style json.
+ 92
+ 93        Returns:
+ 94            str: JSON representation of this resource as a template
+ 95        """
+ 96        return self.template_json
+ 97
+ 98    @staticmethod
+ 99    def from_base64(base64string: str, filetype: str) -> 'Base64Resource':
+100        """Create a Base64Resource from a base64 string and a file type (extension).
+101
+102        Args:
+103            base64string (str): base64 encoded string
+104            filetype (str): file type (extension)
+105
+106        Returns:
+107            Base64Resource: the created Resource
+108        """
+109        return Base64Resource(base64string, filetype)
+110
+111    @staticmethod
+112    def from_raw(raw_data: bytes, filetype: str) -> 'RawResource':
+113        """Create a RawResource from raw file data and a file type (extension).
+114
+115        Args:
+116            raw_data (bytes): raw data as a [bytes-like object](https://docs.python.org/3/glossary.html#term-bytes-like-object)
+117            filetype (str): file type (extension)
+118
+119        Returns:
+120            RawResource: the created Resource
+121        """
+122        return RawResource(raw_data, filetype)
+123
+124    @staticmethod
+125    def from_local_file(local_path: str) -> 'Base64Resource':
+126        """Create a Base64Resource with the contents of a local file.
+127
+128        Throws IOError if it can't read the file.
+129        The filetype is determined by the extension of the file.
+130
+131        Args:
+132            local_path (str): path to local file
+133
+134        Returns:
+135            Base64Resource: the created Resource
+136        """
+137        base64string: str = file_utils.read_file_as_base64(local_path)
+138        return Base64Resource(base64string, type_utils.path_to_extension(local_path))
+139
+140    @staticmethod
+141    def from_server_path(path: str) -> 'ServerPathResource':
+142        """Create a ServerPathResource targeting a file on the server.
+143
+144        The filetype is determined by the extension of the file.
+145
+146        Args:
+147            path (str): location of target file on the server
+148
+149        Returns:
+150            ServerPathResource: the created Resource
+151        """
+152        return ServerPathResource(path)
+153
+154    @staticmethod
+155    def from_url(url: str, filetype: str) -> 'URLResource':
+156        """Create an Resource targeting the file at url with given filetype (extension).
+157
+158        Args:
+159            url (str): file url
+160            filetype (str): file type (extension)
+161
+162        Returns:
+163            URLResource: the created Resource
+164        """
+165        return URLResource(url, filetype)
+166
+167    @staticmethod
+168    def from_html(htmlstring: str, landscape: bool = False) -> 'HTMLResource':
+169        """Create an HTMLResource with html data in plain text.
+170
+171        Landscape is not supported for prepend/append sources, only for template resources.
+172
+173        Args:
+174            htmlstring (str): html content
+175            landscape (bool, optional): whether to use the landscape option. Defaults to False.
+176
+177        Returns:
+178            HTMLResource: the created Resource
+179        """
+180        return HTMLResource(htmlstring, landscape)
+
-

The abstract base class for the resources.

-
#   + +
+ + Resource(data: Union[str, bytes] = None, filetype: str = None) - - Resource(data: Union[str, bytes] = None, filetype: str = None) -
+ -
- View Source -
    def __init__(self, data: Union[str, bytes] = None, filetype: str = None):
-        """
-        Args:
-            data (Union[str, bytes], optional): the data for this resource. Defaults to None.
-            filetype (str, optional): the file type of this resource. Defaults to None.
-        """
-        self._data: Union[str, bytes] = data
-        self.filetype: str = filetype
-
+
+ +
23    def __init__(self, data: Union[str, bytes] = None, filetype: str = None):
+24        """
+25        Args:
+26            data (Union[str, bytes], optional): the data for this resource. Defaults to None.
+27            filetype (str, optional): the file type of this resource. Defaults to None.
+28        """
+29        self._data: Union[str, bytes] = data
+30        self.filetype: str = filetype
+
-

Args: data (Union[str, bytes], optional): the data for this resource. Defaults to None. @@ -1241,11 +1050,13 @@

Further information

-
#   +
+ mimetype: str - mimetype: str +
- + +

Resource type as a mime type.

Returns: @@ -1255,11 +1066,13 @@

Further information

-
#   +
+ data: Union[str, bytes] - data: Union[str, bytes] +
- + +

The data contained in this Resource.

Returns: @@ -1269,11 +1082,13 @@

Further information

-
#   +
+ template_json: str - template_json: str +
- + +

Get the JSON representation when used as a template.

Returns: @@ -1283,11 +1098,13 @@

Further information

-
#   +
+ template_dict: Dict - template_dict: Dict +
- + +

This Resource object as a dict object for use as a template. This dict and the template JSON representation (Resource.template_json) are isomorphic.

@@ -1298,11 +1115,13 @@

Further information

-
#   +
+ secondary_file_json: str - secondary_file_json: str +
- + +

The JSON representation for use as secondary file.

Returns: @@ -1312,11 +1131,13 @@

Further information

-
#   +
+ secondary_file_dict: Dict - secondary_file_dict: Dict +
- + +

This Resource object as a dict object for use as a secondary file (prepend, append, insert, as subtemplate). This dict and the "concat file" JSON representation (Resource.secondary_file_json) are isomorphic.

@@ -1327,34 +1148,31 @@

Further information

-
#   - -
@staticmethod
+ +
+
@staticmethod
- def - from_base64( - base64string: str, - filetype: str -) -> cloudofficeprint.resource.Base64Resource: -
+ def + from_base64( base64string: str, filetype: str) -> cloudofficeprint.resource.Base64Resource: -
- View Source -
    @staticmethod
-    def from_base64(base64string: str, filetype: str) -> 'Base64Resource':
-        """Create a Base64Resource from a base64 string and a file type (extension).
+                
 
-        Args:
-            base64string (str): base64 encoded string
-            filetype (str): file type (extension)
-
-        Returns:
-            Base64Resource: the created Resource
-        """
-        return Base64Resource(base64string, filetype)
-
+
+ +
 98    @staticmethod
+ 99    def from_base64(base64string: str, filetype: str) -> 'Base64Resource':
+100        """Create a Base64Resource from a base64 string and a file type (extension).
+101
+102        Args:
+103            base64string (str): base64 encoded string
+104            filetype (str): file type (extension)
+105
+106        Returns:
+107            Base64Resource: the created Resource
+108        """
+109        return Base64Resource(base64string, filetype)
+
-

Create a Base64Resource from a base64 string and a file type (extension).

@@ -1369,34 +1187,31 @@

Further information

-
#   + +
+
@staticmethod
-
@staticmethod
+ def + from_raw(raw_data: bytes, filetype: str) -> cloudofficeprint.resource.RawResource: - def - from_raw( - raw_data: bytes, - filetype: str -) -> cloudofficeprint.resource.RawResource: -
- -
- View Source -
    @staticmethod
-    def from_raw(raw_data: bytes, filetype: str) -> 'RawResource':
-        """Create a RawResource from raw file data and a file type (extension).
+                
 
-        Args:
-            raw_data (bytes): raw data as a [bytes-like object](https://docs.python.org/3/glossary.html#term-bytes-like-object)
-            filetype (str): file type (extension)
-
-        Returns:
-            RawResource: the created Resource
-        """
-        return RawResource(raw_data, filetype)
-
+
+ +
111    @staticmethod
+112    def from_raw(raw_data: bytes, filetype: str) -> 'RawResource':
+113        """Create a RawResource from raw file data and a file type (extension).
+114
+115        Args:
+116            raw_data (bytes): raw data as a [bytes-like object](https://docs.python.org/3/glossary.html#term-bytes-like-object)
+117            filetype (str): file type (extension)
+118
+119        Returns:
+120            RawResource: the created Resource
+121        """
+122        return RawResource(raw_data, filetype)
+
-

Create a RawResource from raw file data and a file type (extension).

@@ -1411,34 +1226,34 @@

Further information

-
#   + +
+
@staticmethod
-
@staticmethod
+ def + from_local_file(local_path: str) -> cloudofficeprint.resource.Base64Resource: - def - from_local_file(local_path: str) -> cloudofficeprint.resource.Base64Resource: -
- -
- View Source -
    @staticmethod
-    def from_local_file(local_path: str) -> 'Base64Resource':
-        """Create a Base64Resource with the contents of a local file.
-
-        Throws IOError if it can't read the file.
-        The filetype is determined by the extension of the file.
-
-        Args:
-            local_path (str): path to local file
+                
 
-        Returns:
-            Base64Resource: the created Resource
-        """
-        base64string: str = file_utils.read_file_as_base64(local_path)
-        return Base64Resource(base64string, type_utils.path_to_extension(local_path))
-
+
+ +
124    @staticmethod
+125    def from_local_file(local_path: str) -> 'Base64Resource':
+126        """Create a Base64Resource with the contents of a local file.
+127
+128        Throws IOError if it can't read the file.
+129        The filetype is determined by the extension of the file.
+130
+131        Args:
+132            local_path (str): path to local file
+133
+134        Returns:
+135            Base64Resource: the created Resource
+136        """
+137        base64string: str = file_utils.read_file_as_base64(local_path)
+138        return Base64Resource(base64string, type_utils.path_to_extension(local_path))
+
-

Create a Base64Resource with the contents of a local file.

@@ -1455,32 +1270,32 @@

Further information

-
#   - -
@staticmethod
- - def - from_server_path(path: str) -> cloudofficeprint.resource.ServerPathResource: -
+ +
+
@staticmethod
-
- View Source -
    @staticmethod
-    def from_server_path(path: str) -> 'ServerPathResource':
-        """Create a ServerPathResource targeting a file on the server.
+        def
+        from_server_path(path: str) -> cloudofficeprint.resource.ServerPathResource:
 
-        The filetype is determined by the extension of the file.
+                
 
-        Args:
-            path (str): location of target file on the server
-
-        Returns:
-            ServerPathResource: the created Resource
-        """
-        return ServerPathResource(path)
-
+
+ +
140    @staticmethod
+141    def from_server_path(path: str) -> 'ServerPathResource':
+142        """Create a ServerPathResource targeting a file on the server.
+143
+144        The filetype is determined by the extension of the file.
+145
+146        Args:
+147            path (str): location of target file on the server
+148
+149        Returns:
+150            ServerPathResource: the created Resource
+151        """
+152        return ServerPathResource(path)
+
-

Create a ServerPathResource targeting a file on the server.

@@ -1496,31 +1311,31 @@

Further information

-
#   - -
@staticmethod
- - def - from_url(url: str, filetype: str) -> cloudofficeprint.resource.URLResource: -
+ +
+
@staticmethod
-
- View Source -
    @staticmethod
-    def from_url(url: str, filetype: str) -> 'URLResource':
-        """Create an Resource targeting the file at url with given filetype (extension).
+        def
+        from_url(url: str, filetype: str) -> cloudofficeprint.resource.URLResource:
 
-        Args:
-            url (str): file url
-            filetype (str): file type (extension)
+                
 
-        Returns:
-            URLResource: the created Resource
-        """
-        return URLResource(url, filetype)
-
+
+ +
154    @staticmethod
+155    def from_url(url: str, filetype: str) -> 'URLResource':
+156        """Create an Resource targeting the file at url with given filetype (extension).
+157
+158        Args:
+159            url (str): file url
+160            filetype (str): file type (extension)
+161
+162        Returns:
+163            URLResource: the created Resource
+164        """
+165        return URLResource(url, filetype)
+
-

Create an Resource targeting the file at url with given filetype (extension).

@@ -1535,36 +1350,33 @@

Further information

-
#   - -
@staticmethod
- - def - from_html( - htmlstring: str, - landscape: bool = False -) -> cloudofficeprint.resource.HTMLResource: -
+ +
+
@staticmethod
-
- View Source -
    @staticmethod
-    def from_html(htmlstring: str, landscape: bool = False) -> 'HTMLResource':
-        """Create an HTMLResource with html data in plain text.
+        def
+        from_html(	htmlstring: str,	landscape: bool = False) -> cloudofficeprint.resource.HTMLResource:
 
-        Landscape is not supported for prepend/append sources, only for template resources.
+                
 
-        Args:
-            htmlstring (str): html content
-            landscape (bool, optional): whether to use the landscape option. Defaults to False.
-
-        Returns:
-            HTMLResource: the created Resource
-        """
-        return HTMLResource(htmlstring, landscape)
-
+
+ +
167    @staticmethod
+168    def from_html(htmlstring: str, landscape: bool = False) -> 'HTMLResource':
+169        """Create an HTMLResource with html data in plain text.
+170
+171        Landscape is not supported for prepend/append sources, only for template resources.
+172
+173        Args:
+174            htmlstring (str): html content
+175            landscape (bool, optional): whether to use the landscape option. Defaults to False.
+176
+177        Returns:
+178            HTMLResource: the created Resource
+179        """
+180        return HTMLResource(htmlstring, landscape)
+
-

Create an HTMLResource with html data in plain text.

@@ -1582,101 +1394,100 @@

Further information

-
- #   + +
+ + class + Response: + + - - class - Response:
+ +
11class Response():
+12    """The Response class serves as a container for and interface with the Cloud Office Print server's response to a printjob request.
+13
+14    The Cloud Office Print server can also throw an error, in which case you will be dealing with a cloudofficeprint.exceptions.COPError instead of this class.
+15    """
+16
+17    def __init__(self, response: requests.Response):
+18        """You should never need to construct a Response manually.
+19
+20        Args:
+21            response (requests.Response): Response object from the requests package
+22        """
+23        self._mimetype = response.headers["Content-Type"]
+24        self._bytes = response.content
+25
+26    @property
+27    def mimetype(self) -> str:
+28        """Mime type of this response.
+29
+30        Returns:
+31            str: mime type of this response
+32        """
+33        return self._mimetype
+34
+35    @property
+36    def filetype(self) -> str:
+37        """File type (extension) of this response. E.g. "docx".
+38
+39        Returns:
+40            str: file type of this response
+41        """
+42        return type_utils.mimetype_to_extension(self.mimetype)
+43
+44    @property
+45    def binary(self) -> bytes:
+46        """Binary representation of the output file.
+47
+48        Response.to_file can be used to output to a file,
+49        alternatively, use this property to do something else with the binary data.
+50
+51        Returns:
+52            bytes: response file as binary
+53        """
+54        return self._bytes
+55
+56    def to_string(self) -> str:
+57        """Return the string representation of this buffer.
+58        Useful if the server returns a JSON (e.g. for output_type 'count_tags').
+59
+60        Raises:
+61            err: raise error is bytes cannot be decoded in utf-8
+62
+63        Returns:
+64            str: string representation of this buffer
+65        """
+66        try:
+67            return self._bytes.decode('utf-8')
+68        except UnicodeDecodeError as err:
+69            print("""The method 'to_string()' cannot be called on this object.
+70            The server response is probably not a string (e.g. JSON).
+71            To get the bytes of the response, use the property 'binary' instead.""")
+72            raise err
+73
+74    def to_file(self, path: str):
+75        """Write the response to a file at the given path without extension.
+76
+77        If the given file path does not contain an extension,
+78        the correct path is automatically added from the response data.
+79        That is how this method is intended to be used.
+80        You should only specify the extension in the path if you have some reason to specify the extension manually.
+81
+82        Args:
+83            path (str): path without extension
+84        """
+85
+86        if not splitext(path)[1]:
+87            path += "." + self.filetype
+88
+89        # open the file in binary ("b") and write ("w") mode
+90        outfile = open(path, "wb")
+91        outfile.write(self.binary)
+92        outfile.close()
+
-
- View Source -
class Response():
-    """The Response class serves as a container for and interface with the Cloud Office Print server's response to a printjob request.
-
-    The Cloud Office Print server can also throw an error, in which case you will be dealing with a cloudofficeprint.exceptions.COPError instead of this class.
-    """
-
-    def __init__(self, response: requests.Response):
-        """You should never need to construct a Response manually.
-
-        Args:
-            response (requests.Response): Response object from the requests package
-        """
-        self._mimetype = response.headers["Content-Type"]
-        self._bytes = response.content
-
-    @property
-    def mimetype(self) -> str:
-        """Mime type of this response.
-
-        Returns:
-            str: mime type of this response
-        """
-        return self._mimetype
-
-    @property
-    def filetype(self) -> str:
-        """File type (extension) of this response. E.g. "docx".
-
-        Returns:
-            str: file type of this response
-        """
-        return type_utils.mimetype_to_extension(self.mimetype)
-
-    @property
-    def binary(self) -> bytes:
-        """Binary representation of the output file.
-
-        Response.to_file can be used to output to a file,
-        alternatively, use this property to do something else with the binary data.
-
-        Returns:
-            bytes: response file as binary
-        """
-        return self._bytes
-
-    def to_string(self) -> str:
-        """Return the string representation of this buffer.
-        Useful if the server returns a JSON (e.g. for output_type 'count_tags').
-
-        Raises:
-            err: raise error is bytes cannot be decoded in utf-8
-
-        Returns:
-            str: string representation of this buffer
-        """
-        try:
-            return self._bytes.decode('utf-8')
-        except UnicodeDecodeError as err:
-            print("""The method 'to_string()' cannot be called on this object.
-            The server response is probably not a string (e.g. JSON).
-            To get the bytes of the response, use the property 'binary' instead.""")
-            raise err
-
-    def to_file(self, path: str):
-        """Write the response to a file at the given path without extension.
-
-        If the given file path does not contain an extension,
-        the correct path is automatically added from the response data.
-        That is how this method is intended to be used.
-        You should only specify the extension in the path if you have some reason to specify the extension manually.
-
-        Args:
-            path (str): path without extension
-        """
-
-        if not splitext(path)[1]:
-            path += "." + self.filetype
-
-        # open the file in binary ("b") and write ("w") mode
-        outfile = open(path, "wb")
-        outfile.write(self.binary)
-        outfile.close()
-
- -

The Response class serves as a container for and interface with the Cloud Office Print server's response to a printjob request.

@@ -1685,25 +1496,25 @@

Further information

-
#   + +
+ + Response(response: requests.models.Response) - - Response(response: requests.models.Response) -
+ -
- View Source -
    def __init__(self, response: requests.Response):
-        """You should never need to construct a Response manually.
-
-        Args:
-            response (requests.Response): Response object from the requests package
-        """
-        self._mimetype = response.headers["Content-Type"]
-        self._bytes = response.content
-
+
+ +
17    def __init__(self, response: requests.Response):
+18        """You should never need to construct a Response manually.
+19
+20        Args:
+21            response (requests.Response): Response object from the requests package
+22        """
+23        self._mimetype = response.headers["Content-Type"]
+24        self._bytes = response.content
+
-

You should never need to construct a Response manually.

@@ -1714,11 +1525,13 @@

Further information

-
#   +
+ mimetype: str - mimetype: str +
- + +

Mime type of this response.

Returns: @@ -1728,11 +1541,13 @@

Further information

-
#   +
+ filetype: str - filetype: str +
- + +

File type (extension) of this response. E.g. "docx".

Returns: @@ -1742,11 +1557,13 @@

Further information

-
#   +
+ binary: bytes - binary: bytes +
- + +

Binary representation of the output file.

Response.to_file can be used to output to a file, @@ -1759,35 +1576,35 @@

Further information

-
#   + +
+ + def + to_string(self) -> str: + + - - def - to_string(self) -> str:
+ +
56    def to_string(self) -> str:
+57        """Return the string representation of this buffer.
+58        Useful if the server returns a JSON (e.g. for output_type 'count_tags').
+59
+60        Raises:
+61            err: raise error is bytes cannot be decoded in utf-8
+62
+63        Returns:
+64            str: string representation of this buffer
+65        """
+66        try:
+67            return self._bytes.decode('utf-8')
+68        except UnicodeDecodeError as err:
+69            print("""The method 'to_string()' cannot be called on this object.
+70            The server response is probably not a string (e.g. JSON).
+71            To get the bytes of the response, use the property 'binary' instead.""")
+72            raise err
+
-
- View Source -
    def to_string(self) -> str:
-        """Return the string representation of this buffer.
-        Useful if the server returns a JSON (e.g. for output_type 'count_tags').
-
-        Raises:
-            err: raise error is bytes cannot be decoded in utf-8
-
-        Returns:
-            str: string representation of this buffer
-        """
-        try:
-            return self._bytes.decode('utf-8')
-        except UnicodeDecodeError as err:
-            print("""The method 'to_string()' cannot be called on this object.
-            The server response is probably not a string (e.g. JSON).
-            To get the bytes of the response, use the property 'binary' instead.""")
-            raise err
-
- -

Return the string representation of this buffer. Useful if the server returns a JSON (e.g. for output_type 'count_tags').

@@ -1802,37 +1619,37 @@

Further information

-
#   + +
+ + def + to_file(self, path: str): - - def - to_file(self, path: str): -
- -
- View Source -
    def to_file(self, path: str):
-        """Write the response to a file at the given path without extension.
-
-        If the given file path does not contain an extension,
-        the correct path is automatically added from the response data.
-        That is how this method is intended to be used.
-        You should only specify the extension in the path if you have some reason to specify the extension manually.
-
-        Args:
-            path (str): path without extension
-        """
+                
 
-        if not splitext(path)[1]:
-            path += "." + self.filetype
-
-        # open the file in binary ("b") and write ("w") mode
-        outfile = open(path, "wb")
-        outfile.write(self.binary)
-        outfile.close()
-
+
+ +
74    def to_file(self, path: str):
+75        """Write the response to a file at the given path without extension.
+76
+77        If the given file path does not contain an extension,
+78        the correct path is automatically added from the response data.
+79        That is how this method is intended to be used.
+80        You should only specify the extension in the path if you have some reason to specify the extension manually.
+81
+82        Args:
+83            path (str): path without extension
+84        """
+85
+86        if not splitext(path)[1]:
+87            path += "." + self.filetype
+88
+89        # open the file in binary ("b") and write ("w") mode
+90        outfile = open(path, "wb")
+91        outfile.write(self.binary)
+92        outfile.close()
+
-

Write the response to a file at the given path without extension.

@@ -1949,12 +1766,26 @@

Further information

} let heading; - switch (result.doc.type) { + switch (result.doc.kind) { case "function": - heading = `${doc.funcdef} ${doc.fullname}(${doc.parameters.join(", ")})`; + if (doc.fullname.endsWith(".__init__")) { + heading = `${doc.fullname.replace(/\.__init__$/, "")}${doc.signature}`; + } else { + heading = `${doc.funcdef} ${doc.fullname}${doc.signature}`; + } break; case "class": heading = `class ${doc.fullname}`; + if (doc.bases) + heading += `(${doc.bases})`; + heading += `:`; + break; + case "variable": + heading = `${doc.fullname}`; + if (doc.annotation) + heading += `${doc.annotation}`; + if (doc.default_value) + heading += `${doc.default_value}`; break; default: heading = `${doc.fullname}`; @@ -1962,7 +1793,7 @@

Further information

} html += `
- ${heading} + ${heading}
${doc.doc}
`; diff --git a/docs/cloudofficeprint/config.html b/docs/cloudofficeprint/config.html index 2d7edbb..563f4ff 100644 --- a/docs/cloudofficeprint/config.html +++ b/docs/cloudofficeprint/config.html @@ -3,76 +3,79 @@ - + cloudofficeprint.config API documentation - - - - - - - -
-
+

cloudofficeprint.config

Module for output configurations.

The classes under this module encapsulate various configuration options for a print job. -They are to be used with cloudofficeprint.printjob.PrintJob.

+They are to be used with cloudofficeprint.printjob.PrintJob.

-
- View Source -
"""
-Module for output configurations.
+                        
 
-The classes under this module encapsulate various configuration options for a print job.
-They are to be used with `cloudofficeprint.printjob.PrintJob`.
-"""
+                        
 
-from .cloud import *
-from .csv import *
-from .output import *
-from .pdf import *
-from .server import *
-
+
 1"""
+ 2Module for output configurations.
+ 3
+ 4The classes under this module encapsulate various configuration options for a print job.
+ 5They are to be used with `cloudofficeprint.printjob.PrintJob`.
+ 6"""
+ 7
+ 8from .cloud import *
+ 9from .csv import *
+10from .output import *
+11from .pdf import *
+12from .server import *
+13from .request_option import *
+
-
@@ -176,12 +179,26 @@

} let heading; - switch (result.doc.type) { + switch (result.doc.kind) { case "function": - heading = `${doc.funcdef} ${doc.fullname}(${doc.parameters.join(", ")})`; + if (doc.fullname.endsWith(".__init__")) { + heading = `${doc.fullname.replace(/\.__init__$/, "")}${doc.signature}`; + } else { + heading = `${doc.funcdef} ${doc.fullname}${doc.signature}`; + } break; case "class": heading = `class ${doc.fullname}`; + if (doc.bases) + heading += `(${doc.bases})`; + heading += `:`; + break; + case "variable": + heading = `${doc.fullname}`; + if (doc.annotation) + heading += `${doc.annotation}`; + if (doc.default_value) + heading += `${doc.default_value}`; break; default: heading = `${doc.fullname}`; @@ -189,7 +206,7 @@

} html += `
- ${heading} + ${heading}
${doc.doc}
`; diff --git a/docs/cloudofficeprint/config/cloud.html b/docs/cloudofficeprint/config/cloud.html index de57404..f498228 100644 --- a/docs/cloudofficeprint/config/cloud.html +++ b/docs/cloudofficeprint/config/cloud.html @@ -2,18 +2,32 @@ - - + + cloudofficeprint.config.cloud API documentation - - - - - - + + + + + + - - + +
@@ -22,259 +36,6 @@

Module cloudofficeprint.config.cloud

-
- -Expand source code - -
import json
-from typing import Dict, List
-from abc import ABC, abstractmethod
-
-__all__ = [
-    "CloudAccessToken",
-    "OAuthToken",
-    "AWSToken",
-    "FTPToken"
-]
-
-SERVICES = [
-    "dropbox",
-    "gdrive",
-    "onedrive",
-    "aws_s3",
-    "sftp",
-    "ftp"
-]
-
-
-class CloudAccessToken(ABC):
-    """Abstract base class for classes used to specify cloud access information for outputting to a cloud service."""
-
-    def __init__(self, service: str):
-        """
-        Args:
-            service (str): name of the cloud service
-
-        Raises:
-            ValueError: raise error if the given name for the cloud service is not known
-        """
-        if not self.is_valid_service(service):
-            raise ValueError(f'Unsupported cloud service "{service}".')
-        self._service = service
-
-    @property
-    def service(self) -> str:
-        """Returns which cloud service is being used.
-
-        Returns:
-            str: which cloud service is being used
-        """
-        return self._service
-
-    @service.setter
-    def service(self, value: str):
-        """Setter for self._service
-
-        Args:
-            value (str): new value for self._service
-
-        Raises:
-            ValueError: raise error if the given name for the cloud service is not known
-        """
-        if not self.is_valid_service(value):
-            raise ValueError(f'Unsupported cloud service "{value}".')
-        self._service = value
-
-    @property
-    @abstractmethod
-    def as_dict(self) -> Dict:
-        """The cloud access token as a dict, for building the JSON.
-
-        Returns:
-            Dict: dict representation for this cloud access token
-        """
-        return {
-            "output_location": self.service
-        }
-
-    @property
-    def json(self) -> str:
-        """The cloud access token as JSON.
-
-        Returns:
-            str: JSON representation for this cloud access token
-        """
-        return json.dumps(self.as_dict)
-
-    @staticmethod
-    def is_valid_service(value: str) -> bool:
-        """Check if the given value is a valid service string.
-
-        Args:
-            value (str): the service to check
-
-        Returns:
-            bool: whether value is valid
-        """
-        return value in SERVICES
-
-    @staticmethod
-    def list_available_services() -> List[str]:
-        """List all available services.
-
-        Returns:
-            List[str]: list of available service strings
-        """
-        return SERVICES
-
-    @staticmethod
-    def from_OAuth(service: str, token: str) -> 'OAuthToken':
-        """Create a token from an OAuth string and service name.
-
-        Args:
-            service (str): cloud service
-            token (str): OAuth access token
-
-        Returns:
-            OAuthToken: created token
-        """
-        return OAuthToken(service, token)
-
-    @staticmethod
-    def from_AWS(key_id: str, secret_key: str):
-        """Create a token from Amazon S3 access key id and secret access key.
-
-        Args:
-            key_id (str): AWS access key ID
-            secret_key (str): AWS secret access key
-
-        Returns:
-            AWSToken: created token
-        """
-        return AWSToken(key_id, secret_key)
-
-    @staticmethod
-    def from_FTP(host: str, port: int = None, user: str = None, password: str = None) -> 'FTPToken':
-        """Create a token from FTP info
-
-        When an argument is / defaults to None, no data about it is sent to the Cloud Office Print server.
-        The Cloud Office Print server will then fill in default values.
-
-        Args:
-            host (str): host name or IP address
-            port (int, optional): port to use. Defaults to None.
-            user (str, optional): user name. Defaults to None.
-            password (str, optional): password for user. Defaults to None.
-
-        Returns:
-            FTPToken: created token
-        """
-        return FTPToken(host, False, port, user, password)
-
-    @staticmethod
-    def from_SFTP(host: str, port: int = None, user: str = None, password: str = None) -> 'FTPToken':
-        """Create a token from SFTP info
-
-        When an argument is / defaults to None, no data about it is sent to the Cloud Office Print server.
-        The Cloud Office Print server will then fill in default values.
-
-        Args:
-            host (str): host name or IP address
-            port (int, optional): port to use. Defaults to None.
-            user (str, optional): user name. Defaults to None.
-            password (str, optional): password for user. Defaults to None.
-
-        Returns:
-            FTPToken: created token
-                      This is an FTPToken object, with sftp=True passed into the constructor.
-                      The only difference with FTP is CloudAccessToken.servicename.
-        """
-        return FTPToken(host, True, port, user, password)
-
-
-class OAuthToken(CloudAccessToken):
-    """`CloudAccessToken` to be used for OAuth tokens"""
-
-    def __init__(self, service: str, token: str):
-        """
-        Args:
-            service (str): `CloudAccessToken.service`
-            token (str): OAuth token
-        """
-        super().__init__(service)
-        self.token: str = token
-
-    @property
-    def as_dict(self) -> Dict:
-        result = super().as_dict
-        result.update({
-            "cloud_access_token": self.token
-        })
-        return result
-
-
-class AWSToken(CloudAccessToken):
-    """`CloudAccessToken` to be used for AWS tokens"""
-
-    def __init__(self, key_id: str, secret_key: str):
-        """
-        Args:
-            key_id (str): AWS access key ID
-            secret_key (str): AWS secret key
-        """
-        super().__init__("aws_s3")
-        self.key_id: str = key_id
-        self.secret_key: str = secret_key
-
-    @property
-    def as_dict(self) -> Dict:
-        result = super().as_dict
-        result.update({
-            "cloud_access_token": {
-                "access_key": self.key_id,
-                "secret_access_key": self.secret_key
-            }
-        })
-        return result
-
-
-class FTPToken(CloudAccessToken):
-    """`CloudAccessToken` to be used for FTP/SFTP tokens"""
-
-    def __init__(self, host: str, sftp: bool = False, port: int = None, user: str = None, password: str = None):
-        """
-        Args:
-            host (str): Host name or IP address of the FTP/SFTP server.
-            sftp (bool, optional): whether to use SFTP (else FTP). Defaults to False.
-            port (int, optional): Port number of the FTP/SFTP server. Defaults to None.
-            user (str, optional): User name for the FTP/SFTP server. Defaults to None.
-            password (str, optional): Password for the user. Defaults to None.
-        """
-        super().__init__("sftp" if sftp else "ftp")
-        self.host: str = host
-        self.port: int = port
-        self.user: str = user
-        self.password: str = password
-
-    @property
-    def as_dict(self) -> Dict:
-        cloud_access_token = {
-            "host": self.host
-        }
-        if self.port is not None:
-            cloud_access_token["port"] = self.port
-        if self.user is not None:
-            cloud_access_token["user"] = self.user
-        if self.password is not None:
-            cloud_access_token["password"] = self.password
-
-        result = super().as_dict
-        result.update({
-            "cloud_access_token": cloud_access_token
-        })
-
-        return result
-
@@ -290,14 +51,6 @@

Classes

(key_id: str, secret_key: str)
-

CloudAccessToken to be used for AWS tokens

-

Args

-
-
key_id : str
-
AWS access key ID
-
secret_key : str
-
AWS secret key
-
Expand source code @@ -326,6 +79,14 @@

Args

}) return result
+

CloudAccessToken to be used for AWS tokens

+

Args

+
+
key_id : str
+
AWS access key ID
+
secret_key : str
+
AWS secret key
+

Ancestors

  • CloudAccessToken
  • @@ -353,17 +114,6 @@

    Inherited members

    (service: str)
    -

    Abstract base class for classes used to specify cloud access information for outputting to a cloud service.

    -

    Args

    -
    -
    service : str
    -
    name of the cloud service
    -
    -

    Raises

    -
    -
    ValueError
    -
    raise error if the given name for the cloud service is not known
    -
    Expand source code @@ -512,6 +262,17 @@

    Raises

    """ return FTPToken(host, True, port, user, password)
    +

    Abstract base class for classes used to specify cloud access information for outputting to a cloud service.

    +

    Args

    +
    +
    service : str
    +
    name of the cloud service
    +
    +

    Raises

    +
    +
    ValueError
    +
    raise error if the given name for the cloud service is not known
    +

    Ancestors

    • abc.ABC
    • @@ -528,19 +289,6 @@

      Static methods

      def from_AWS(key_id: str, secret_key: str)
      -

      Create a token from Amazon S3 access key id and secret access key.

      -

      Args

      -
      -
      key_id : str
      -
      AWS access key ID
      -
      secret_key : str
      -
      AWS secret access key
      -
      -

      Returns

      -
      -
      AWSToken
      -
      created token
      -
      Expand source code @@ -558,30 +306,24 @@

      Returns

      """ return AWSToken(key_id, secret_key)
      -
      -
      -def from_FTP(host: str, port: int = None, user: str = None, password: str = None) ‑> FTPToken -
      -
      -

      Create a token from FTP info

      -

      When an argument is / defaults to None, no data about it is sent to the Cloud Office Print server. -The Cloud Office Print server will then fill in default values.

      +

      Create a token from Amazon S3 access key id and secret access key.

      Args

      -
      host : str
      -
      host name or IP address
      -
      port : int, optional
      -
      port to use. Defaults to None.
      -
      user : str, optional
      -
      user name. Defaults to None.
      -
      password : str, optional
      -
      password for user. Defaults to None.
      +
      key_id : str
      +
      AWS access key ID
      +
      secret_key : str
      +
      AWS secret access key

      Returns

      -
      FTPToken
      +
      AWSToken
      created token
      +
      +
      +def from_FTP(host: str, port: int = None, user: str = None, password: str = None) ‑> FTPToken +
      +
      Expand source code @@ -604,24 +346,30 @@

      Returns

      """ return FTPToken(host, False, port, user, password)
      -
      -
      -def from_OAuth(service: str, token: str) ‑> OAuthToken -
      -
      -

      Create a token from an OAuth string and service name.

      +

      Create a token from FTP info

      +

      When an argument is / defaults to None, no data about it is sent to the Cloud Office Print server. +The Cloud Office Print server will then fill in default values.

      Args

      -
      service : str
      -
      cloud service
      -
      token : str
      -
      OAuth access token
      +
      host : str
      +
      host name or IP address
      +
      port : int, optional
      +
      port to use. Defaults to None.
      +
      user : str, optional
      +
      user name. Defaults to None.
      +
      password : str, optional
      +
      password for user. Defaults to None.

      Returns

      -
      OAuthToken
      +
      FTPToken
      created token
      +
      +
      +def from_OAuth(service: str, token: str) ‑> OAuthToken +
      +
      Expand source code @@ -639,32 +387,24 @@

      Returns

      """ return OAuthToken(service, token)
      -
      -
      -def from_SFTP(host: str, port: int = None, user: str = None, password: str = None) ‑> FTPToken -
      -
      -

      Create a token from SFTP info

      -

      When an argument is / defaults to None, no data about it is sent to the Cloud Office Print server. -The Cloud Office Print server will then fill in default values.

      +

      Create a token from an OAuth string and service name.

      Args

      -
      host : str
      -
      host name or IP address
      -
      port : int, optional
      -
      port to use. Defaults to None.
      -
      user : str, optional
      -
      user name. Defaults to None.
      -
      password : str, optional
      -
      password for user. Defaults to None.
      +
      service : str
      +
      cloud service
      +
      token : str
      +
      OAuth access token

      Returns

      -
      FTPToken
      -
      created token -This is an FTPToken object, with sftp=True passed into the constructor. -The only difference with FTP is CloudAccessToken.servicename.
      +
      OAuthToken
      +
      created token
      +
      +
      +def from_SFTP(host: str, port: int = None, user: str = None, password: str = None) ‑> FTPToken +
      +
      Expand source code @@ -689,22 +429,32 @@

      Returns

      """ return FTPToken(host, True, port, user, password)
      -
      -
      -def is_valid_service(value: str) ‑> bool -
      -
      -

      Check if the given value is a valid service string.

      +

      Create a token from SFTP info

      +

      When an argument is / defaults to None, no data about it is sent to the Cloud Office Print server. +The Cloud Office Print server will then fill in default values.

      Args

      -
      value : str
      -
      the service to check
      +
      host : str
      +
      host name or IP address
      +
      port : int, optional
      +
      port to use. Defaults to None.
      +
      user : str, optional
      +
      user name. Defaults to None.
      +
      password : str, optional
      +
      password for user. Defaults to None.

      Returns

      -
      bool
      -
      whether value is valid
      +
      FTPToken
      +
      created token +This is an FTPToken object, with sftp=True passed into the constructor. +The only difference with FTP is CloudAccessToken.servicename.
      +
      +
      +def is_valid_service(value: str) ‑> bool +
      +
      Expand source code @@ -721,17 +471,22 @@

      Returns

      """ return value in SERVICES
      +

      Check if the given value is a valid service string.

      +

      Args

      +
      +
      value : str
      +
      the service to check
      +
      +

      Returns

      +
      +
      bool
      +
      whether value is valid
      +
      def list_available_services() ‑> List[str]
      -

      List all available services.

      -

      Returns

      -
      -
      List[str]
      -
      list of available service strings
      -
      Expand source code @@ -745,18 +500,18 @@

      Returns

      """ return SERVICES
      +

      List all available services.

      +

      Returns

      +
      +
      List[str]
      +
      list of available service strings
      +

      Instance variables

      -
      var as_dict : Dict
      +
      prop as_dict : Dict
      -

      The cloud access token as a dict, for building the JSON.

      -

      Returns

      -
      -
      Dict
      -
      dict representation for this cloud access token
      -
      Expand source code @@ -773,15 +528,15 @@

      Returns

      "output_location": self.service }
      -
      -
      var json : str
      -
      -

      The cloud access token as JSON.

      +

      The cloud access token as a dict, for building the JSON.

      Returns

      -
      str
      -
      JSON representation for this cloud access token
      +
      Dict
      +
      dict representation for this cloud access token
      +
      +
      prop json : str
      +
      Expand source code @@ -795,15 +550,15 @@

      Returns

      """ return json.dumps(self.as_dict)
      -
      -
      var service : str
      -
      -

      Returns which cloud service is being used.

      +

      The cloud access token as JSON.

      Returns

      str
      -
      which cloud service is being used
      +
      JSON representation for this cloud access token
      +
      +
      prop service : str
      +
      Expand source code @@ -817,28 +572,20 @@

      Returns

      """ return self._service
      +

      Returns which cloud service is being used.

      +

      Returns

      +
      +
      str
      +
      which cloud service is being used
      +
    class FTPToken -(host: str, sftp: bool = False, port: int = None, user: str = None, password: str = None) +(host: str,
    sftp: bool = False,
    port: int = None,
    user: str = None,
    password: str = None)
    -

    CloudAccessToken to be used for FTP/SFTP tokens

    -

    Args

    -
    -
    host : str
    -
    Host name or IP address of the FTP/SFTP server.
    -
    sftp : bool, optional
    -
    whether to use SFTP (else FTP). Defaults to False.
    -
    port : int, optional
    -
    Port number of the FTP/SFTP server. Defaults to None.
    -
    user : str, optional
    -
    User name for the FTP/SFTP server. Defaults to None.
    -
    password : str, optional
    -
    Password for the user. Defaults to None.
    -
    Expand source code @@ -880,6 +627,20 @@

    Args

    return result
    +

    CloudAccessToken to be used for FTP/SFTP tokens

    +

    Args

    +
    +
    host : str
    +
    Host name or IP address of the FTP/SFTP server.
    +
    sftp : bool, optional
    +
    whether to use SFTP (else FTP). Defaults to False.
    +
    port : int, optional
    +
    Port number of the FTP/SFTP server. Defaults to None.
    +
    user : str, optional
    +
    User name for the FTP/SFTP server. Defaults to None.
    +
    password : str, optional
    +
    Password for the user. Defaults to None.
    +

    Ancestors