From 49dcc0eda3ae8cfcbfbc0ec64820f36a3ef7349b Mon Sep 17 00:00:00 2001 From: Cheryl Moser Date: Tue, 4 Mar 2025 12:51:21 -0800 Subject: [PATCH 1/5] generate pdf folder, re-add --- dart/generate_pdf/.gitignore | 30 ++++++++++++ dart/generate_pdf/README.md | 31 +++++++++++++ dart/generate_pdf/analysis_options.yaml | 1 + dart/generate_pdf/lib/faker.dart | 23 +++++++++ dart/generate_pdf/lib/main.dart | 23 +++++++++ dart/generate_pdf/lib/pdf.dart | 62 +++++++++++++++++++++++++ dart/generate_pdf/pubspec.yaml | 15 ++++++ 7 files changed, 185 insertions(+) create mode 100644 dart/generate_pdf/.gitignore create mode 100644 dart/generate_pdf/README.md create mode 100644 dart/generate_pdf/analysis_options.yaml create mode 100644 dart/generate_pdf/lib/faker.dart create mode 100644 dart/generate_pdf/lib/main.dart create mode 100644 dart/generate_pdf/lib/pdf.dart create mode 100644 dart/generate_pdf/pubspec.yaml diff --git a/dart/generate_pdf/.gitignore b/dart/generate_pdf/.gitignore new file mode 100644 index 00000000..a8852f54 --- /dev/null +++ b/dart/generate_pdf/.gitignore @@ -0,0 +1,30 @@ +# See https://www.dartlang.org/guides/libraries/private-files + +# Files and directories created by pub +.dart_tool/ +.packages +build/ +# If you're building an application, you may want to check-in your pubspec.lock +pubspec.lock + +# Directory created by dartdoc +# If you don't generate documentation locally you can remove this line. +doc/api/ + +# dotenv environment variables file +.env* + +# Avoid committing generated Javascript files: +*.dart.js +*.info.json # Produced by the --dump-info flag. +*.js # When generated by dart2js. Don't specify *.js if your + # project includes source files written in JavaScript. +*.js_ +*.js.deps +*.js.map + +.flutter-plugins +.flutter-plugins-dependencies + +# Directory used by Appwrite CLI for local development +.appwrite \ No newline at end of file diff --git a/dart/generate_pdf/README.md b/dart/generate_pdf/README.md new file mode 100644 index 00000000..a7c6adad --- /dev/null +++ b/dart/generate_pdf/README.md @@ -0,0 +1,31 @@ +# 📄 Dart Generate PDF Function + +Generates a sample invoice in PDF. + +## 🧰 Usage + +### GET / + +Returns a PDF invoice. + +No parameters required. + +**Response** + +Sample `200` Response: + +Returns a binary stream of the generated PDF document. The `Content-Type` of the response will be set as `application/pdf`. + +## ⚙️ Configuration + +| Setting | Value | +| ----------------- | --------------- | +| Runtime | Dart (3.7.0) | +| Entrypoint | `lib/main.dart` | +| Build Commands | `dart pub get` | +| Permissions | `any` | +| Timeout (Seconds) | 15 | + +## 🔒 Environment Variables + +No environment variables required. diff --git a/dart/generate_pdf/analysis_options.yaml b/dart/generate_pdf/analysis_options.yaml new file mode 100644 index 00000000..ea2c9e94 --- /dev/null +++ b/dart/generate_pdf/analysis_options.yaml @@ -0,0 +1 @@ +include: package:lints/recommended.yaml \ No newline at end of file diff --git a/dart/generate_pdf/lib/faker.dart b/dart/generate_pdf/lib/faker.dart new file mode 100644 index 00000000..c037fd25 --- /dev/null +++ b/dart/generate_pdf/lib/faker.dart @@ -0,0 +1,23 @@ +import 'package:faker_dart/faker_dart.dart'; + +Map generateFakeOrder() { + final faker = Faker.instance; + List> items = List.generate( + faker.datatype.number(min: 1, max: 5), + (_) => { + 'description': faker.commerce.productName(), + 'quantity': faker.datatype.number(min: 1, max: 10), + 'cost': double.parse(faker.commerce.price(symbol: '')) + .toStringAsFixed(2) + }); + + return { + 'id': faker.datatype.uuid(), + 'date': faker.date.past(DateTime.now(), rangeInYears: 25).toIso8601String(), + 'name': faker.name.fullName(), + 'items': items, + 'total': items.fold(0, (sum, item) { + return sum + double.parse(item['cost']); + }) + }; +} diff --git a/dart/generate_pdf/lib/main.dart b/dart/generate_pdf/lib/main.dart new file mode 100644 index 00000000..4286f7b9 --- /dev/null +++ b/dart/generate_pdf/lib/main.dart @@ -0,0 +1,23 @@ +import 'dart:convert'; +import 'package:shelf/shelf.dart'; +import 'package:shelf/shelf_io.dart' as shelf_io; //for testing locally +import './pdf.dart'; +import './faker.dart'; + +Future pdfHandler(Request request) async { + final fakeOrder = generateFakeOrder(); + print( + 'Generated fake order: ${JsonEncoder.withIndent(' ').convert(fakeOrder)}'); + + final pdfBuffer = await createPDF(fakeOrder); + print('PDF created'); + + return Response.ok(pdfBuffer, headers: {'Content-Type': 'application/pdf'}); +} + +//For testing locally +void main() async { + final handler = const Pipeline().addHandler(pdfHandler); + final server = await shelf_io.serve(handler, 'localhost', 8080); + print('Serving at http://${server.address.host}:${server.port}'); +} diff --git a/dart/generate_pdf/lib/pdf.dart b/dart/generate_pdf/lib/pdf.dart new file mode 100644 index 00000000..85bb5ad2 --- /dev/null +++ b/dart/generate_pdf/lib/pdf.dart @@ -0,0 +1,62 @@ +import 'dart:typed_data'; +import 'package:pdf/pdf.dart'; +import 'package:pdf/widgets.dart' as pw; + +Future createPDF(order) async { + final pdf = pw.Document(); + final date = DateTime.parse(order['date']); + + final String orderList = (order['items'] as List) + .map((item) => + '${item['description']} x ${item['quantity']} = \$${item['cost']}') + .join('\n'); + + pdf.addPage(pw.Page( + pageFormat: PdfPageFormat.a4, + margin: pw.EdgeInsets.only(left: 50), + build: (pw.Context context) { + return pw.Stack(children: [ + //Manually positioned to match the output from the Node.js template + // Invoice title + pw.Positioned( + bottom: 750, + child: + pw.Text('Sample Invoice', style: pw.TextStyle(fontSize: 20))), + + // Order date + pw.Positioned( + left: 350, + bottom: 750, + child: pw.Text('${date.month}/${date.day}/${date.year}', + style: pw.TextStyle(fontSize: 15))), + + // Name + pw.Positioned( + bottom: 700, + child: pw.Text('Hello, ${order['name']}!', + style: pw.TextStyle(fontSize: 30))), + + // Order ID + pw.Positioned( + bottom: 650, + child: pw.Text('Order ID: ${order['id']}', + style: pw.TextStyle(fontSize: 10))), + + // Order total + pw.Positioned( + bottom: 600, + child: pw.Text('Total: \$${order['total'].toStringAsFixed(2)}', + style: pw.TextStyle(fontSize: 15))), + + // Order item list + pw.Positioned( + top: 841.89 - 565, + child: pw.Text(orderList, + style: pw.TextStyle(fontSize: 15, lineSpacing: 8))), + ]); + })); + + final Uint8List pdfBytes = await pdf.save(); + + return Uint8List.fromList(pdfBytes); +} diff --git a/dart/generate_pdf/pubspec.yaml b/dart/generate_pdf/pubspec.yaml new file mode 100644 index 00000000..99b26eda --- /dev/null +++ b/dart/generate_pdf/pubspec.yaml @@ -0,0 +1,15 @@ +name: generate_pdf +version: 1.0.0 + +environment: + sdk: ^3.6.1 + +dependencies: + dart_appwrite: 8.0.0 + faker_dart: ^0.2.2 + pdf: ^3.11.3 + shelf: ^1.4.2 + +dev_dependencies: + lints: ^5.0.0 + test: ^1.24.0 From 266c13c791e158ffe63245fdab5715fa84491a0d Mon Sep 17 00:00:00 2001 From: Cheryl Moser Date: Tue, 4 Mar 2025 13:15:45 -0800 Subject: [PATCH 2/5] updated readme file --- dart/generate_pdf/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dart/generate_pdf/README.md b/dart/generate_pdf/README.md index a7c6adad..26cf9aea 100644 --- a/dart/generate_pdf/README.md +++ b/dart/generate_pdf/README.md @@ -20,7 +20,7 @@ Returns a binary stream of the generated PDF document. The `Content-Type` of the | Setting | Value | | ----------------- | --------------- | -| Runtime | Dart (3.7.0) | +| Runtime | Dart (3.7.1) | | Entrypoint | `lib/main.dart` | | Build Commands | `dart pub get` | | Permissions | `any` | From 0d49129b0045f4dc99631c4634c648ed7ff7e946 Mon Sep 17 00:00:00 2001 From: Cheryl Moser Date: Wed, 5 Mar 2025 21:49:37 -0800 Subject: [PATCH 3/5] cleaning up --- dart/generate_pdf/lib/main.dart | 8 -------- dart/generate_pdf/lib/pdf.dart | 1 - 2 files changed, 9 deletions(-) diff --git a/dart/generate_pdf/lib/main.dart b/dart/generate_pdf/lib/main.dart index 4286f7b9..0b3b292e 100644 --- a/dart/generate_pdf/lib/main.dart +++ b/dart/generate_pdf/lib/main.dart @@ -1,6 +1,5 @@ import 'dart:convert'; import 'package:shelf/shelf.dart'; -import 'package:shelf/shelf_io.dart' as shelf_io; //for testing locally import './pdf.dart'; import './faker.dart'; @@ -14,10 +13,3 @@ Future pdfHandler(Request request) async { return Response.ok(pdfBuffer, headers: {'Content-Type': 'application/pdf'}); } - -//For testing locally -void main() async { - final handler = const Pipeline().addHandler(pdfHandler); - final server = await shelf_io.serve(handler, 'localhost', 8080); - print('Serving at http://${server.address.host}:${server.port}'); -} diff --git a/dart/generate_pdf/lib/pdf.dart b/dart/generate_pdf/lib/pdf.dart index 85bb5ad2..dfc771cd 100644 --- a/dart/generate_pdf/lib/pdf.dart +++ b/dart/generate_pdf/lib/pdf.dart @@ -16,7 +16,6 @@ Future createPDF(order) async { margin: pw.EdgeInsets.only(left: 50), build: (pw.Context context) { return pw.Stack(children: [ - //Manually positioned to match the output from the Node.js template // Invoice title pw.Positioned( bottom: 750, From d6c6f4db6c90cfa28bfc54576fa629750a0e1898 Mon Sep 17 00:00:00 2001 From: Cheryl Moser Date: Thu, 6 Mar 2025 12:33:10 -0800 Subject: [PATCH 4/5] adjusted dependencies, corrected response handling in main --- dart/generate_pdf/README.md | 2 +- dart/generate_pdf/lib/main.dart | 18 +++++++++++++++--- dart/generate_pdf/pubspec.yaml | 4 ++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/dart/generate_pdf/README.md b/dart/generate_pdf/README.md index 26cf9aea..a8dc8b84 100644 --- a/dart/generate_pdf/README.md +++ b/dart/generate_pdf/README.md @@ -20,7 +20,7 @@ Returns a binary stream of the generated PDF document. The `Content-Type` of the | Setting | Value | | ----------------- | --------------- | -| Runtime | Dart (3.7.1) | +| Runtime | Dart (3.5.0) | | Entrypoint | `lib/main.dart` | | Build Commands | `dart pub get` | | Permissions | `any` | diff --git a/dart/generate_pdf/lib/main.dart b/dart/generate_pdf/lib/main.dart index 0b3b292e..82f66870 100644 --- a/dart/generate_pdf/lib/main.dart +++ b/dart/generate_pdf/lib/main.dart @@ -1,9 +1,10 @@ import 'dart:convert'; -import 'package:shelf/shelf.dart'; +//import 'package:dart_appwrite/dart_appwrite.dart'; +//import 'package:shelf/shelf.dart'; import './pdf.dart'; import './faker.dart'; -Future pdfHandler(Request request) async { +Future> pdfHandler() async { final fakeOrder = generateFakeOrder(); print( 'Generated fake order: ${JsonEncoder.withIndent(' ').convert(fakeOrder)}'); @@ -11,5 +12,16 @@ Future pdfHandler(Request request) async { final pdfBuffer = await createPDF(fakeOrder); print('PDF created'); - return Response.ok(pdfBuffer, headers: {'Content-Type': 'application/pdf'}); + return pdfBuffer; +} + +Future main(final context) async { + try { + final pdfBuffer = await pdfHandler(); + return context.res + .binary(pdfBuffer, 200, {'Content-Type': 'application/pdf'}); + } catch (e) { + context.error('Error occurred while generating PDF: $e'); + return context.res.text('Error occurred while generating PDF: $e', 500); + } } diff --git a/dart/generate_pdf/pubspec.yaml b/dart/generate_pdf/pubspec.yaml index 99b26eda..465fd773 100644 --- a/dart/generate_pdf/pubspec.yaml +++ b/dart/generate_pdf/pubspec.yaml @@ -2,10 +2,10 @@ name: generate_pdf version: 1.0.0 environment: - sdk: ^3.6.1 + sdk: ^3.5.0 dependencies: - dart_appwrite: 8.0.0 + dart_appwrite: ^13.0.0 faker_dart: ^0.2.2 pdf: ^3.11.3 shelf: ^1.4.2 From 1eeb0976dbd9e619dccdb64b88c045436d2aca59 Mon Sep 17 00:00:00 2001 From: Cheryl Moser Date: Thu, 6 Mar 2025 12:40:32 -0800 Subject: [PATCH 5/5] removed unused imports --- dart/generate_pdf/lib/main.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/dart/generate_pdf/lib/main.dart b/dart/generate_pdf/lib/main.dart index 82f66870..59778797 100644 --- a/dart/generate_pdf/lib/main.dart +++ b/dart/generate_pdf/lib/main.dart @@ -1,6 +1,4 @@ import 'dart:convert'; -//import 'package:dart_appwrite/dart_appwrite.dart'; -//import 'package:shelf/shelf.dart'; import './pdf.dart'; import './faker.dart';