Add Activepieces integration for workflow automation
- Add Activepieces fork with SmoothSchedule custom piece - Create integrations app with Activepieces service layer - Add embed token endpoint for iframe integration - Create Automations page with embedded workflow builder - Add sidebar visibility fix for embed mode - Add list inactive customers endpoint to Public API - Include SmoothSchedule triggers: event created/updated/cancelled - Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"PDF": "PDF",
|
||||
"Extract Text": "Extract Text",
|
||||
"Convert to Image": "Convert to Image",
|
||||
"Text to PDF": "Text to PDF",
|
||||
"Image to PDF": "Image to PDF",
|
||||
"Extract text from PDF file or url": "Extract text from PDF file or url",
|
||||
"Convert a PDF file or URL to an image": "Convert a PDF file or URL to an image",
|
||||
"Convert text to PDF": "Convert text to PDF",
|
||||
"Convert image to PDF": "Convert image to PDF",
|
||||
"PDF File or URL": "PDF File or URL",
|
||||
"Output Image Type": "Output Image Type",
|
||||
"text": "text",
|
||||
"image": "image",
|
||||
"Enter text to convert": "Enter text to convert",
|
||||
"Image has to be png, jpeg or jpg and it will be scaled down to fit the page when image is larger than an A4 page": "Image has to be png, jpeg or jpg and it will be scaled down to fit the page when image is larger than an A4 page",
|
||||
"Single Combined Image": "Single Combined Image",
|
||||
"Separate Image for Each Page": "Separate Image for Each Page"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"Extract Text": "Text extrahieren",
|
||||
"Convert to Image": "In Bild konvertieren",
|
||||
"Text to PDF": "Text in PDF",
|
||||
"Image to PDF": "Bild als PDF",
|
||||
"PDF Page Count": "PDF-Seitenanzahl",
|
||||
"Extract PDF Pages": "PDF-Seiten extrahieren",
|
||||
"Merge PDFs": "PDFs zusammenführen",
|
||||
"Extract text from PDF file or url": "Text aus PDF-Datei oder URL extrahieren",
|
||||
"Convert a PDF file or URL to an image": "PDF-Datei oder URL in ein Bild konvertieren",
|
||||
"Convert text to PDF": "Text in PDF konvertieren",
|
||||
"Convert image to PDF": "Bild in PDF konvertieren",
|
||||
"Get page count of PDF file.": "Seitenanzahl der PDF-Datei abrufen.",
|
||||
"Extract or rearrange page(s)from PDF File.": "Entpacken oder ordnen Sie Seite(n) aus PDF Datei neu an.",
|
||||
"Merges multiple PDF files into a single PDF document.": "Fügt mehrere PDF-Dateien zu einem einzigen PDF-Dokument zusammen.",
|
||||
"PDF File or URL": "PDF-Datei oder URL",
|
||||
"Output Image Type": "Ausgabebild Typ",
|
||||
"text": "text",
|
||||
"image": "bild",
|
||||
"Markdown": "Markdown",
|
||||
"Page Ranges": "Seitenbereiche",
|
||||
"PDF Files": "PDF-Dateien",
|
||||
"Output File Name": "Dateiname ausgeben",
|
||||
"Enter text to convert": "Text zum Konvertieren eingeben",
|
||||
"Image has to be png, jpeg or jpg and it will be scaled down to fit the page when image is larger than an A4 page": "Bild muss png sein, jpeg oder jpg und es wird auf die Seite reduziert, wenn das Bild größer ist als eine A4-Seite",
|
||||
"\nThis action can extract or rearrange the pages in a PDF.\n\n- The order of array determines the sequence of pages.\n- Each array element is one inclusive continuous range with a start page and end page.\n- Pages start from 1, and 0 is not valid.\n- Start page has to be less than end page.\n- You can select one page by setting the same start and end page.\n- To select pages from the start, specify negative pages eg. -1 is the last page, -5 is the 5th last page. start: -5, end: -1 are the last 5 pages.\n- Range cann": "\nDiese Aktion kann die Seiten in einer PDF Datei extrahieren oder neu anordnen.\n\n- Die Reihenfolge des Arrays bestimmt die Reihenfolge der Seiten.\n- Jedes Array-Element ist ein durchgängiger Bereich mit einer Start- und Endseite.\n- Seiten beginnen von 1 und 0 ist nicht gültig.\n- Startseite muss kleiner als Endseite sein.\n- Sie können eine Seite auswählen, indem Sie die gleiche Start- und Endseite setzen.\n- Um Seiten von Anfang an auszuwählen, geben Sie z.B. negative Seiten an. -1 ist die letzte Seite, -5 ist die 5. letzte Seite. Start: -5, Ende: -1 sind die letzten 5 Seiten.\n- Bereich kann sich nicht auf 0 erstrecken (z.B. Start: -3, End: 5.\n",
|
||||
"Array of PDF files to merge": "Anordnung der zusammenzuführenden PDF-Dateien",
|
||||
"Name for the merged PDF file (without extension)": "Name für die zusammengeführte PDF-Datei (ohne Erweiterung)",
|
||||
"Single Combined Image": "Einzelnes kombiniertes Bild",
|
||||
"Separate Image for Each Page": "Bild für jede Seite trennen"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"Extract Text": "Extraer texto",
|
||||
"Convert to Image": "Convertir a imagen",
|
||||
"Text to PDF": "Texto a PDF",
|
||||
"Image to PDF": "Imagen a PDF",
|
||||
"PDF Page Count": "Número de páginas PDF",
|
||||
"Extract PDF Pages": "Extraer páginas PDF",
|
||||
"Merge PDFs": "Combinar PDFs",
|
||||
"Extract text from PDF file or url": "Extraer texto del archivo PDF o url",
|
||||
"Convert a PDF file or URL to an image": "Convierte un archivo PDF o URL a una imagen",
|
||||
"Convert text to PDF": "Convertir texto a PDF",
|
||||
"Convert image to PDF": "Convertir imagen a PDF",
|
||||
"Get page count of PDF file.": "Obtener el conteo de páginas del archivo PDF.",
|
||||
"Extract or rearrange page(s)from PDF File.": "Extraer o reorganizar página(s) del archivo PDF.",
|
||||
"Merges multiple PDF files into a single PDF document.": "Combina múltiples archivos PDF en un solo documento PDF.",
|
||||
"PDF File or URL": "Archivo PDF o URL",
|
||||
"Output Image Type": "Tipo de imagen de salida",
|
||||
"text": "texto",
|
||||
"image": "imagen",
|
||||
"Markdown": "Markdown",
|
||||
"Page Ranges": "Rangos de página",
|
||||
"PDF Files": "Archivos PDF",
|
||||
"Output File Name": "Nombre del archivo de salida",
|
||||
"Enter text to convert": "Introduzca texto a convertir",
|
||||
"Image has to be png, jpeg or jpg and it will be scaled down to fit the page when image is larger than an A4 page": "La imagen tiene que ser png, jpeg o jpg y se reducirá para ajustarse a la página cuando la imagen sea mayor que una página A4",
|
||||
"\nThis action can extract or rearrange the pages in a PDF.\n\n- The order of array determines the sequence of pages.\n- Each array element is one inclusive continuous range with a start page and end page.\n- Pages start from 1, and 0 is not valid.\n- Start page has to be less than end page.\n- You can select one page by setting the same start and end page.\n- To select pages from the start, specify negative pages eg. -1 is the last page, -5 is the 5th last page. start: -5, end: -1 are the last 5 pages.\n- Range cann": "\nThis action can extract or rearrange the pages in a PDF.\n\n- The order of array determines the sequence of pages.\n- Each array element is one inclusive continuous range with a start page and end page.\n- Pages start from 1, and 0 is not valid.\n- Start page has to be less than end page.\n- You can select one page by setting the same start and end page.\n- To select pages from the start, specify negative pages eg. -1 is the last page, -5 is the 5th last page. start: -5, end: -1 are the last 5 pages.\n- Range cannot span across 0 eg. start: -3, end: 5.\n",
|
||||
"Array of PDF files to merge": "Arreglo de archivos PDF a combinar",
|
||||
"Name for the merged PDF file (without extension)": "Nombre para el archivo PDF combinado (sin extensión)",
|
||||
"Single Combined Image": "Imagen única combinada",
|
||||
"Separate Image for Each Page": "Separar imagen para cada página"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"Extract Text": "Extraire le texte",
|
||||
"Convert to Image": "Convertir en Image",
|
||||
"Text to PDF": "Texte au format PDF",
|
||||
"Image to PDF": "Image au format PDF",
|
||||
"PDF Page Count": "Nombre de pages PDF",
|
||||
"Extract PDF Pages": "Extraire les pages PDF",
|
||||
"Merge PDFs": "Fusionner les PDF",
|
||||
"Extract text from PDF file or url": "Extraire du texte du fichier PDF ou de l'URL",
|
||||
"Convert a PDF file or URL to an image": "Convertir un fichier PDF ou une URL en image",
|
||||
"Convert text to PDF": "Convertir le texte en PDF",
|
||||
"Convert image to PDF": "Convertir l'image en PDF",
|
||||
"Get page count of PDF file.": "Obtenir le nombre de pages du fichier PDF.",
|
||||
"Extract or rearrange page(s)from PDF File.": "Extraire ou réorganiser la(les) page(s) depuis le fichier PDF.",
|
||||
"Merges multiple PDF files into a single PDF document.": "Fusionne plusieurs fichiers PDF en un seul document PDF.",
|
||||
"PDF File or URL": "Fichier PDF ou URL",
|
||||
"Output Image Type": "Type d'image de sortie",
|
||||
"text": "texte du texte",
|
||||
"image": "image",
|
||||
"Markdown": "Markdown",
|
||||
"Page Ranges": "Intervalle de pages",
|
||||
"PDF Files": "Fichiers PDF",
|
||||
"Output File Name": "Nom du fichier de sortie",
|
||||
"Enter text to convert": "Entrez le texte à convertir",
|
||||
"Image has to be png, jpeg or jpg and it will be scaled down to fit the page when image is larger than an A4 page": "L'image doit être en png, jpeg ou jpg et il sera redimensionné pour s'adapter à la page lorsque l'image est plus grande qu'une page A4",
|
||||
"\nThis action can extract or rearrange the pages in a PDF.\n\n- The order of array determines the sequence of pages.\n- Each array element is one inclusive continuous range with a start page and end page.\n- Pages start from 1, and 0 is not valid.\n- Start page has to be less than end page.\n- You can select one page by setting the same start and end page.\n- To select pages from the start, specify negative pages eg. -1 is the last page, -5 is the 5th last page. start: -5, end: -1 are the last 5 pages.\n- Range cann": "\nThis action can extract or rearrange the pages in a PDF.\n\n- The order of array determines the sequence of pages.\n- Each array element is one inclusive continuous range with a start page and end page.\n- Pages start from 1, and 0 is not valid.\n- Start page has to be less than end page.\n- You can select one page by setting the same start and end page.\n- To select pages from the start, specify negative pages eg. -1 is the last page, -5 is the 5th last page. start: -5, end: -1 are the last 5 pages.\n- Range cannot span across 0 eg. start: -3, end: 5.\n",
|
||||
"Array of PDF files to merge": "Tableau de fichiers PDF à fusionner",
|
||||
"Name for the merged PDF file (without extension)": "Nom du fichier PDF fusionné (sans extension)",
|
||||
"Single Combined Image": "Image unique combinée",
|
||||
"Separate Image for Each Page": "Image séparée pour chaque page"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"PDF": "PDF",
|
||||
"Extract Text": "Extract Text",
|
||||
"Convert to Image": "Convert to Image",
|
||||
"Text to PDF": "Text to PDF",
|
||||
"Image to PDF": "Image to PDF",
|
||||
"Extract text from PDF file or url": "Extract text from PDF file or url",
|
||||
"Convert a PDF file or URL to an image": "Convert a PDF file or URL to an image",
|
||||
"Convert text to PDF": "Convert text to PDF",
|
||||
"Convert image to PDF": "Convert image to PDF",
|
||||
"PDF File or URL": "PDF File or URL",
|
||||
"Output Image Type": "Output Image Type",
|
||||
"text": "text",
|
||||
"image": "image",
|
||||
"Enter text to convert": "Enter text to convert",
|
||||
"Image has to be png, jpeg or jpg and it will be scaled down to fit the page when image is larger than an A4 page": "Image has to be png, jpeg or jpg and it will be scaled down to fit the page when image is larger than an A4 page",
|
||||
"Single Combined Image": "Single Combined Image",
|
||||
"Separate Image for Each Page": "Separate Image for Each Page"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"PDF": "PDF",
|
||||
"Extract Text": "Extract Text",
|
||||
"Convert to Image": "Convert to Image",
|
||||
"Text to PDF": "Text to PDF",
|
||||
"Image to PDF": "Image to PDF",
|
||||
"Extract text from PDF file or url": "Extract text from PDF file or url",
|
||||
"Convert a PDF file or URL to an image": "Convert a PDF file or URL to an image",
|
||||
"Convert text to PDF": "Convert text to PDF",
|
||||
"Convert image to PDF": "Convert image to PDF",
|
||||
"PDF File or URL": "PDF File or URL",
|
||||
"Output Image Type": "Output Image Type",
|
||||
"text": "text",
|
||||
"image": "image",
|
||||
"Enter text to convert": "Enter text to convert",
|
||||
"Image has to be png, jpeg or jpg and it will be scaled down to fit the page when image is larger than an A4 page": "Image has to be png, jpeg or jpg and it will be scaled down to fit the page when image is larger than an A4 page",
|
||||
"Single Combined Image": "Single Combined Image",
|
||||
"Separate Image for Each Page": "Separate Image for Each Page"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"Extract Text": "テキストを抽出",
|
||||
"Convert to Image": "画像に変換",
|
||||
"Text to PDF": "PDF にテキスト",
|
||||
"Image to PDF": "PDFへの画像",
|
||||
"PDF Page Count": "PDF ページ数",
|
||||
"Extract PDF Pages": "PDFページを抽出",
|
||||
"Merge PDFs": "PDF の結合",
|
||||
"Extract text from PDF file or url": "PDFファイルまたはURLからテキストを抽出",
|
||||
"Convert a PDF file or URL to an image": "PDFファイルまたはURLを画像に変換",
|
||||
"Convert text to PDF": "テキストをPDFに変換する",
|
||||
"Convert image to PDF": "画像をPDFに変換",
|
||||
"Get page count of PDF file.": "PDF ファイルのページ数を取得します。",
|
||||
"Extract or rearrange page(s)from PDF File.": "PDFファイルからページを抽出または並べ替えます。",
|
||||
"Merges multiple PDF files into a single PDF document.": "複数の PDF ファイルを 1 つの PDF ドキュメントにマージします。",
|
||||
"PDF File or URL": "PDFファイルまたはURL",
|
||||
"Output Image Type": "出力イメージタイプ",
|
||||
"text": "テキスト",
|
||||
"image": "画像",
|
||||
"Markdown": "Markdown",
|
||||
"Page Ranges": "ページ範囲",
|
||||
"PDF Files": "PDF ファイル",
|
||||
"Output File Name": "出力ファイル名",
|
||||
"Enter text to convert": "変換するテキストを入力してください",
|
||||
"Image has to be png, jpeg or jpg and it will be scaled down to fit the page when image is larger than an A4 page": "画像はpngでなければなりません jpegまたはjpgと画像がA4ページより大きいときにページに合わせて縮小します",
|
||||
"\nThis action can extract or rearrange the pages in a PDF.\n\n- The order of array determines the sequence of pages.\n- Each array element is one inclusive continuous range with a start page and end page.\n- Pages start from 1, and 0 is not valid.\n- Start page has to be less than end page.\n- You can select one page by setting the same start and end page.\n- To select pages from the start, specify negative pages eg. -1 is the last page, -5 is the 5th last page. start: -5, end: -1 are the last 5 pages.\n- Range cann": "\nThis action can extract or rearrange the pages in a PDF.\n\n- The order of array determines the sequence of pages.\n- Each array element is one inclusive continuous range with a start page and end page.\n- Pages start from 1, and 0 is not valid.\n- Start page has to be less than end page.\n- You can select one page by setting the same start and end page.\n- To select pages from the start, specify negative pages eg. -1 is the last page, -5 is the 5th last page. start: -5, end: -1 are the last 5 pages.\n- Range cannot span across 0 eg. start: -3, end: 5.\n",
|
||||
"Array of PDF files to merge": "マージするPDFファイルの配列",
|
||||
"Name for the merged PDF file (without extension)": "統合された PDF ファイルの名前 (拡張子なし)",
|
||||
"Single Combined Image": "単一の複合画像",
|
||||
"Separate Image for Each Page": "各ページごとに画像を分離する"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"Extract Text": "Tekst uitpakken",
|
||||
"Convert to Image": "Converteren naar afbeelding",
|
||||
"Text to PDF": "Tekst naar PDF",
|
||||
"Image to PDF": "Afbeelding naar PDF",
|
||||
"PDF Page Count": "PDF pagina aantal",
|
||||
"Extract PDF Pages": "PDF-pagina's uitpakken",
|
||||
"Merge PDFs": "PDF's samenvoegen",
|
||||
"Extract text from PDF file or url": "Tekst uit PDF-bestand of url halen",
|
||||
"Convert a PDF file or URL to an image": "Converteer een PDF-bestand of URL naar een afbeelding",
|
||||
"Convert text to PDF": "Tekst converteren naar PDF",
|
||||
"Convert image to PDF": "Afbeelding converteren naar PDF",
|
||||
"Get page count of PDF file.": "Haal het aantal pagina's op van het PDF-bestand.",
|
||||
"Extract or rearrange page(s)from PDF File.": "Pagina('s) uitpakken of herschikken van PDF-bestand.",
|
||||
"Merges multiple PDF files into a single PDF document.": "Voegt meerdere PDF-bestanden samen in een enkel PDF-document.",
|
||||
"PDF File or URL": "PDF bestand of URL",
|
||||
"Output Image Type": "Uitvoer afbeeldingstype",
|
||||
"text": "tekstveld",
|
||||
"image": "afbeelding",
|
||||
"Markdown": "Markdown",
|
||||
"Page Ranges": "Pagina Bereiken",
|
||||
"PDF Files": "PDF bestanden",
|
||||
"Output File Name": "Uitvoer bestandsnaam",
|
||||
"Enter text to convert": "Voer tekst in om te converteren",
|
||||
"Image has to be png, jpeg or jpg and it will be scaled down to fit the page when image is larger than an A4 page": "Afbeelding moet png, Jpeg of jpg en het zal naar beneden geschaald worden om te passen op de pagina wanneer de afbeelding groter is dan een A4 pagina",
|
||||
"\nThis action can extract or rearrange the pages in a PDF.\n\n- The order of array determines the sequence of pages.\n- Each array element is one inclusive continuous range with a start page and end page.\n- Pages start from 1, and 0 is not valid.\n- Start page has to be less than end page.\n- You can select one page by setting the same start and end page.\n- To select pages from the start, specify negative pages eg. -1 is the last page, -5 is the 5th last page. start: -5, end: -1 are the last 5 pages.\n- Range cann": "\nDeze actie kan de pagina's in een PDF uitpakken of herschikken.\n\n- De volgorde van de pagina's wordt bepaald door de volgorde van de pagina's.\n- Elk array element is een inclusief continu bereik met een startpagina en eindpagina.\n- Pagina's starten vanaf 1 en 0 is niet geldig.\n- Startpagina moet kleiner zijn dan de eindpagina.\n- U kunt één pagina selecteren door dezelfde start- en eindpagina in te stellen.\n- Om pagina's vanaf de start te selecteren, geef negatieve pagina's op. -1 is de laatste pagina, -5 is de 5e laatste pagina. Start: -5, einde: -1 zijn de laatste 5 pagina's.\n- Het bereik kan niet span tussen 0 bijv. start: -3, end: 5.\n",
|
||||
"Array of PDF files to merge": "Array van PDF-bestanden samen te voegen",
|
||||
"Name for the merged PDF file (without extension)": "Naam voor het samengevoegde PDF-bestand (zonder extensie)",
|
||||
"Single Combined Image": "Enkele gecombineerde afbeelding",
|
||||
"Separate Image for Each Page": "Aparte afbeelding voor elke pagina"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"Extract Text": "Extrair Texto",
|
||||
"Convert to Image": "Converter para imagem",
|
||||
"Text to PDF": "Texto para PDF",
|
||||
"Image to PDF": "Imagem para PDF",
|
||||
"PDF Page Count": "Contagem de Páginas PDF",
|
||||
"Extract PDF Pages": "Extrair páginas em PDF",
|
||||
"Merge PDFs": "Mesclar PDFs",
|
||||
"Extract text from PDF file or url": "Extrair texto do arquivo PDF ou URL",
|
||||
"Convert a PDF file or URL to an image": "Converta um arquivo PDF ou URL para uma imagem",
|
||||
"Convert text to PDF": "Converter texto para PDF",
|
||||
"Convert image to PDF": "Converter imagem para PDF",
|
||||
"Get page count of PDF file.": "Obter a contagem de páginas do arquivo PDF.",
|
||||
"Extract or rearrange page(s)from PDF File.": "Extrair ou reorganizar a(s) página(s) de arquivo PDF.",
|
||||
"Merges multiple PDF files into a single PDF document.": "Mescla vários arquivos PDF em um único documento PDF.",
|
||||
"PDF File or URL": "Arquivo PDF ou URL",
|
||||
"Output Image Type": "Tipo de Imagem de Saída",
|
||||
"text": "texto",
|
||||
"image": "Imagem",
|
||||
"Markdown": "Markdown",
|
||||
"Page Ranges": "Intervalos de Página",
|
||||
"PDF Files": "Arquivos PDF",
|
||||
"Output File Name": "Nome do arquivo de saída",
|
||||
"Enter text to convert": "Digite o texto a ser convertido",
|
||||
"Image has to be png, jpeg or jpg and it will be scaled down to fit the page when image is larger than an A4 page": "A imagem tem que ser png, jpeg ou jpg e ele será redimensionado para se encaixar na página quando a imagem é maior que uma página A4",
|
||||
"\nThis action can extract or rearrange the pages in a PDF.\n\n- The order of array determines the sequence of pages.\n- Each array element is one inclusive continuous range with a start page and end page.\n- Pages start from 1, and 0 is not valid.\n- Start page has to be less than end page.\n- You can select one page by setting the same start and end page.\n- To select pages from the start, specify negative pages eg. -1 is the last page, -5 is the 5th last page. start: -5, end: -1 are the last 5 pages.\n- Range cann": "\nThis action can extract or rearrange the pages in a PDF.\n\n- The order of array determines the sequence of pages.\n- Each array element is one inclusive continuous range with a start page and end page.\n- Pages start from 1, and 0 is not valid.\n- Start page has to be less than end page.\n- You can select one page by setting the same start and end page.\n- To select pages from the start, specify negative pages eg. -1 is the last page, -5 is the 5th last page. start: -5, end: -1 are the last 5 pages.\n- Range cannot span across 0 eg. start: -3, end: 5.\n",
|
||||
"Array of PDF files to merge": "Array de arquivos PDF para mesclar",
|
||||
"Name for the merged PDF file (without extension)": "Nome para o arquivo PDF mesclado (sem extensão)",
|
||||
"Single Combined Image": "Imagem Combinada Simples",
|
||||
"Separate Image for Each Page": "Imagem separada para cada página"
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"PDF": "PDF",
|
||||
"Extract Text": "Извлечь текст",
|
||||
"Convert to Image": "Преобразовать в изображение",
|
||||
"Text to PDF": "Текст в PDF",
|
||||
"Image to PDF": "Изображение в PDF",
|
||||
"PDF Page Count": "Счетчик PDF-страниц",
|
||||
"Extract PDF Pages": "Извлечь PDF страницы",
|
||||
"Extract text from PDF file or url": "Извлечь текст из PDF файла или url",
|
||||
"Convert a PDF file or URL to an image": "Преобразовать PDF файл или URL в изображение",
|
||||
"Convert text to PDF": "Преобразовать текст в PDF",
|
||||
"Convert image to PDF": "Преобразовать изображение в PDF",
|
||||
"Get page count of PDF file.": "Получить количество страниц в PDF файле.",
|
||||
"Extract or rearrange page(s)from PDF File.": "Извлечь или изменить порядок страниц из PDF-файла.",
|
||||
"PDF File or URL": "PDF файл или URL",
|
||||
"Output Image Type": "Тип изображения вывода",
|
||||
"text": "текст",
|
||||
"image": "изображение",
|
||||
"Markdown": "Markdown",
|
||||
"Page Ranges": "Диапазоны страниц",
|
||||
"Enter text to convert": "Введите текст для преобразования",
|
||||
"Image has to be png, jpeg or jpg and it will be scaled down to fit the page when image is larger than an A4 page": "Изображение должно быть png, jpeg или jpg и он будет масштабирован вниз по размеру страницы, когда изображение больше страницы A4",
|
||||
"\nThis action can extract or rearrange the pages in a PDF.\n\n- The order of array determines the sequence of pages.\n- Each array element is one inclusive continuous range with a start page and end page.\n- Pages start from 1, and 0 is not valid.\n- Start page has to be less than end page.\n- You can select one page by setting the same start and end page.\n- To select pages from the start, specify negative pages eg. -1 is the last page, -5 is the 5th last page. start: -5, end: -1 are the last 5 pages.\n- Range cann": "\nThis action can extract or rearrange the pages in a PDF.\n\n- The order of array determines the sequence of pages.\n- Each array element is one inclusive continuous range with a start page and end page.\n- Pages start from 1, and 0 is not valid.\n- Start page has to be less than end page.\n- You can select one page by setting the same start and end page.\n- To select pages from the start, specify negative pages eg. -1 is the last page, -5 is the 5th last page. start: -5, end: -1 are the last 5 pages.\n- Range cannot span across 0 eg. start: -3, end: 5.\n",
|
||||
"Single Combined Image": "Одно комбинированное изображение",
|
||||
"Separate Image for Each Page": "Отдельное изображение для каждой страницы"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"Extract Text": "Extract Text",
|
||||
"Convert to Image": "Convert to Image",
|
||||
"Text to PDF": "Text to PDF",
|
||||
"Image to PDF": "Image to PDF",
|
||||
"PDF Page Count": "PDF Page Count",
|
||||
"Extract PDF Pages": "Extract PDF Pages",
|
||||
"Merge PDFs": "Merge PDFs",
|
||||
"Extract text from PDF file or url": "Extract text from PDF file or url",
|
||||
"Convert a PDF file or URL to an image": "Convert a PDF file or URL to an image",
|
||||
"Convert text to PDF": "Convert text to PDF",
|
||||
"Convert image to PDF": "Convert image to PDF",
|
||||
"Get page count of PDF file.": "Get page count of PDF file.",
|
||||
"Extract or rearrange page(s)from PDF File.": "Extract or rearrange page(s)from PDF File.",
|
||||
"Merges multiple PDF files into a single PDF document.": "Merges multiple PDF files into a single PDF document.",
|
||||
"PDF File or URL": "PDF File or URL",
|
||||
"Output Image Type": "Output Image Type",
|
||||
"text": "text",
|
||||
"image": "image",
|
||||
"Markdown": "Markdown",
|
||||
"Page Ranges": "Page Ranges",
|
||||
"PDF Files": "PDF Files",
|
||||
"Output File Name": "Output File Name",
|
||||
"Enter text to convert": "Enter text to convert",
|
||||
"Image has to be png, jpeg or jpg and it will be scaled down to fit the page when image is larger than an A4 page": "Image has to be png, jpeg or jpg and it will be scaled down to fit the page when image is larger than an A4 page",
|
||||
"\nThis action can extract or rearrange the pages in a PDF.\n\n- The order of array determines the sequence of pages.\n- Each array element is one inclusive continuous range with a start page and end page.\n- Pages start from 1, and 0 is not valid.\n- Start page has to be less than end page.\n- You can select one page by setting the same start and end page.\n- To select pages from the start, specify negative pages eg. -1 is the last page, -5 is the 5th last page. start: -5, end: -1 are the last 5 pages.\n- Range cann": "\nThis action can extract or rearrange the pages in a PDF.\n\n- The order of array determines the sequence of pages.\n- Each array element is one inclusive continuous range with a start page and end page.\n- Pages start from 1, and 0 is not valid.\n- Start page has to be less than end page.\n- You can select one page by setting the same start and end page.\n- To select pages from the start, specify negative pages eg. -1 is the last page, -5 is the 5th last page. start: -5, end: -1 are the last 5 pages.\n- Range cannot span across 0 eg. start: -3, end: 5.\n",
|
||||
"Array of PDF files to merge": "Array of PDF files to merge",
|
||||
"Name for the merged PDF file (without extension)": "Name for the merged PDF file (without extension)",
|
||||
"Single Combined Image": "Single Combined Image",
|
||||
"Separate Image for Each Page": "Separate Image for Each Page"
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"PDF": "PDF",
|
||||
"Extract Text": "Extract Text",
|
||||
"Convert to Image": "Convert to Image",
|
||||
"Text to PDF": "Text to PDF",
|
||||
"Image to PDF": "Image to PDF",
|
||||
"PDF Page Count": "PDF Page Count",
|
||||
"Extract PDF Pages": "Extract PDF Pages",
|
||||
"Extract text from PDF file or url": "Extract text from PDF file or url",
|
||||
"Convert a PDF file or URL to an image": "Convert a PDF file or URL to an image",
|
||||
"Convert text to PDF": "Convert text to PDF",
|
||||
"Convert image to PDF": "Convert image to PDF",
|
||||
"Get page count of PDF file.": "Get page count of PDF file.",
|
||||
"Extract or rearrange page(s)from PDF File.": "Extract or rearrange page(s)from PDF File.",
|
||||
"PDF File or URL": "PDF File or URL",
|
||||
"Output Image Type": "Output Image Type",
|
||||
"text": "text",
|
||||
"image": "image",
|
||||
"Markdown": "Markdown",
|
||||
"Page Ranges": "Page Ranges",
|
||||
"Enter text to convert": "Enter text to convert",
|
||||
"Image has to be png, jpeg or jpg and it will be scaled down to fit the page when image is larger than an A4 page": "Image has to be png, jpeg or jpg and it will be scaled down to fit the page when image is larger than an A4 page",
|
||||
"\nThis action can extract or rearrange the pages in a PDF.\n\n- The order of array determines the sequence of pages.\n- Each array element is one inclusive continuous range with a start page and end page.\n- Pages start from 1, and 0 is not valid.\n- Start page has to be less than end page.\n- You can select one page by setting the same start and end page.\n- To select pages from the start, specify negative pages eg. -1 is the last page, -5 is the 5th last page. start: -5, end: -1 are the last 5 pages.\n- Range cann": "\nThis action can extract or rearrange the pages in a PDF.\n\n- The order of array determines the sequence of pages.\n- Each array element is one inclusive continuous range with a start page and end page.\n- Pages start from 1, and 0 is not valid.\n- Start page has to be less than end page.\n- You can select one page by setting the same start and end page.\n- To select pages from the start, specify negative pages eg. -1 is the last page, -5 is the 5th last page. start: -5, end: -1 are the last 5 pages.\n- Range cannot span across 0 eg. start: -3, end: 5.\n",
|
||||
"Single Combined Image": "Single Combined Image",
|
||||
"Separate Image for Each Page": "Separate Image for Each Page"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"Extract Text": "Extract Text",
|
||||
"Convert to Image": "Convert to Image",
|
||||
"Text to PDF": "Text to PDF",
|
||||
"Image to PDF": "Image to PDF",
|
||||
"PDF Page Count": "PDF Page Count",
|
||||
"Extract PDF Pages": "Extract PDF Pages",
|
||||
"Merge PDFs": "Merge PDFs",
|
||||
"Extract text from PDF file or url": "Extract text from PDF file or url",
|
||||
"Convert a PDF file or URL to an image": "Convert a PDF file or URL to an image",
|
||||
"Convert text to PDF": "Convert text to PDF",
|
||||
"Convert image to PDF": "Convert image to PDF",
|
||||
"Get page count of PDF file.": "Get page count of PDF file.",
|
||||
"Extract or rearrange page(s)from PDF File.": "Extract or rearrange page(s)from PDF File.",
|
||||
"Merges multiple PDF files into a single PDF document.": "Merges multiple PDF files into a single PDF document.",
|
||||
"PDF File or URL": "PDF File or URL",
|
||||
"Output Image Type": "Output Image Type",
|
||||
"text": "text",
|
||||
"image": "image",
|
||||
"Markdown": "Markdown",
|
||||
"Page Ranges": "Page Ranges",
|
||||
"PDF Files": "PDF Files",
|
||||
"Output File Name": "Output File Name",
|
||||
"Enter text to convert": "Enter text to convert",
|
||||
"Image has to be png, jpeg or jpg and it will be scaled down to fit the page when image is larger than an A4 page": "Image has to be png, jpeg or jpg and it will be scaled down to fit the page when image is larger than an A4 page",
|
||||
"\nThis action can extract or rearrange the pages in a PDF.\n\n- The order of array determines the sequence of pages.\n- Each array element is one inclusive continuous range with a start page and end page.\n- Pages start from 1, and 0 is not valid.\n- Start page has to be less than end page.\n- You can select one page by setting the same start and end page.\n- To select pages from the start, specify negative pages eg. -1 is the last page, -5 is the 5th last page. start: -5, end: -1 are the last 5 pages.\n- Range cann": "\nThis action can extract or rearrange the pages in a PDF.\n\n- The order of array determines the sequence of pages.\n- Each array element is one inclusive continuous range with a start page and end page.\n- Pages start from 1, and 0 is not valid.\n- Start page has to be less than end page.\n- You can select one page by setting the same start and end page.\n- To select pages from the start, specify negative pages eg. -1 is the last page, -5 is the 5th last page. start: -5, end: -1 are the last 5 pages.\n- Range cannot span across 0 eg. start: -3, end: 5.\n",
|
||||
"Array of PDF files to merge": "Array of PDF files to merge",
|
||||
"Name for the merged PDF file (without extension)": "Name for the merged PDF file (without extension)",
|
||||
"Single Combined Image": "Single Combined Image",
|
||||
"Separate Image for Each Page": "Separate Image for Each Page"
|
||||
}
|
||||
32
activepieces-fork/packages/pieces/community/pdf/src/index.ts
Normal file
32
activepieces-fork/packages/pieces/community/pdf/src/index.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { createPiece, PieceAuth } from '@activepieces/pieces-framework';
|
||||
import { extractText } from './lib/actions/extract-text';
|
||||
import { convertToImage } from './lib/actions/convert-to-image';
|
||||
import { textToPdf } from './lib/actions/text-to-pdf';
|
||||
import { imageToPdf } from './lib/actions/image-to-pdf';
|
||||
import { pdfPageCount } from './lib/actions/pdf-page-count';
|
||||
import { extractPdfPages } from './lib/actions/extract-pdf-pages';
|
||||
import { mergePdfs } from './lib/actions/merge-pdfs';
|
||||
|
||||
export const PDF = createPiece({
|
||||
displayName: 'PDF',
|
||||
auth: PieceAuth.None(),
|
||||
minimumSupportedRelease: '0.34.2',
|
||||
logoUrl: 'https://cdn.activepieces.com/pieces/pdf.svg',
|
||||
authors: [
|
||||
'nyamkamunhjin',
|
||||
'abuaboud',
|
||||
'AbdulTheActivepiecer',
|
||||
'jmgb27',
|
||||
'danielpoonwj',
|
||||
],
|
||||
actions: [
|
||||
extractText,
|
||||
convertToImage,
|
||||
textToPdf,
|
||||
imageToPdf,
|
||||
pdfPageCount,
|
||||
extractPdfPages,
|
||||
mergePdfs,
|
||||
],
|
||||
triggers: [],
|
||||
});
|
||||
@@ -0,0 +1,133 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { promises as fs } from 'fs';
|
||||
import { tmpdir } from 'os';
|
||||
import { join } from 'path';
|
||||
import { exec } from 'child_process';
|
||||
import { promisify } from 'util';
|
||||
import { nanoid } from 'nanoid';
|
||||
import Jimp from 'jimp';
|
||||
|
||||
const execPromise = promisify(exec);
|
||||
const pdftoppmPath = '/usr/bin/pdftoppm';
|
||||
|
||||
const MAX_FILE_SIZE = 16 * 1024 * 1024;
|
||||
|
||||
async function isPdftoppmInstalled(): Promise<boolean> {
|
||||
const { stdout, stderr } = await execPromise(`command -v ${pdftoppmPath}`);
|
||||
return !stderr && stdout.trim() === pdftoppmPath;
|
||||
}
|
||||
async function convertPdfToImages(dataBuffer: Buffer): Promise<Buffer[]> {
|
||||
const tempDir = tmpdir();
|
||||
const uniqueId = nanoid();
|
||||
const inputFilePath = join(tempDir, `input-${uniqueId}.pdf`);
|
||||
const outputDir = join(tempDir, `output-${uniqueId}`);
|
||||
try {
|
||||
await fs.mkdir(outputDir);
|
||||
await fs.writeFile(inputFilePath, dataBuffer as any);
|
||||
|
||||
const { stderr } = await execPromise(`${pdftoppmPath} -png ${inputFilePath} ${join(outputDir, 'output')}`);
|
||||
if (stderr) {
|
||||
throw new Error(stderr);
|
||||
}
|
||||
|
||||
const files = await fs.readdir(outputDir);
|
||||
const imageBuffers = [];
|
||||
for (const file of files) {
|
||||
const filePath = join(outputDir, file);
|
||||
const imageBuffer = await fs.readFile(filePath);
|
||||
await fs.unlink(filePath);
|
||||
imageBuffers.push(imageBuffer);
|
||||
}
|
||||
|
||||
return imageBuffers;
|
||||
} finally {
|
||||
await fs.unlink(inputFilePath).catch(() => void 0);
|
||||
await fs.rm(outputDir, { recursive: true, force: true }).catch(() => void 0);
|
||||
}
|
||||
}
|
||||
|
||||
async function concatImagesVertically(imageBuffers: Buffer[]): Promise<Buffer> {
|
||||
const images = await Promise.all(imageBuffers.map(buffer => Jimp.read(buffer)));
|
||||
const totalHeight = images.reduce((sum, image) => sum + image.getHeight(), 0);
|
||||
const maxWidth = Math.max(...images.map(image => image.getWidth()));
|
||||
|
||||
const finalImage = new Jimp(maxWidth, totalHeight);
|
||||
let yOffset = 0;
|
||||
|
||||
for (const image of images) {
|
||||
finalImage.composite(image, 0, yOffset);
|
||||
yOffset += image.getHeight();
|
||||
}
|
||||
|
||||
return finalImage.getBufferAsync(Jimp.MIME_PNG);
|
||||
}
|
||||
|
||||
export const convertToImage = createAction({
|
||||
name: 'convertToImage',
|
||||
displayName: 'Convert to Image',
|
||||
description: 'Convert a PDF file or URL to an image',
|
||||
props: {
|
||||
file: Property.File({
|
||||
displayName: 'PDF File or URL',
|
||||
required: true,
|
||||
}),
|
||||
imageOutputType: Property.StaticDropdown({
|
||||
displayName: 'Output Image Type',
|
||||
required: true,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Single Combined Image', value: 'single' },
|
||||
{ label: 'Separate Image for Each Page', value: 'multiple' },
|
||||
],
|
||||
},
|
||||
defaultValue: 'multiple',
|
||||
}),
|
||||
},
|
||||
errorHandlingOptions: {
|
||||
continueOnFailure: {
|
||||
defaultValue: false,
|
||||
},
|
||||
retryOnFailure: {
|
||||
hide: true
|
||||
},
|
||||
},
|
||||
async run(context) {
|
||||
if (!await isPdftoppmInstalled()) {
|
||||
throw new Error(`${pdftoppmPath} is not installed`);
|
||||
}
|
||||
|
||||
const file = context.propsValue.file;
|
||||
const returnConcatenatedImage = context.propsValue.imageOutputType === 'single';
|
||||
// To prevent a DOS attack, we limit the file size to 16MB
|
||||
if (file.data.buffer.byteLength > MAX_FILE_SIZE) {
|
||||
throw new Error(`File size exceeds the limit of ${MAX_FILE_SIZE / (1024 * 1024)} MB.`);
|
||||
}
|
||||
|
||||
const dataBuffer = Buffer.from(file.data.buffer);
|
||||
|
||||
const imageBuffers = await convertPdfToImages(dataBuffer);
|
||||
|
||||
if (returnConcatenatedImage) {
|
||||
const finalImageBuffer = await concatImagesVertically(imageBuffers);
|
||||
const imageLink = await context.files.write({
|
||||
data: finalImageBuffer,
|
||||
fileName: `converted_image.png`,
|
||||
});
|
||||
|
||||
return {
|
||||
image: imageLink,
|
||||
};
|
||||
} else {
|
||||
const imageLinks = await Promise.all(imageBuffers.map((imageBuffer, index) =>
|
||||
context.files.write({
|
||||
data: imageBuffer,
|
||||
fileName: `converted_image_page_${index + 1}.png`,
|
||||
})
|
||||
));
|
||||
|
||||
return {
|
||||
images: imageLinks,
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,123 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { PDFDocument } from 'pdf-lib';
|
||||
import { MarkdownVariant } from '@activepieces/shared';
|
||||
|
||||
export function pageRangeToIndexes(
|
||||
startPage: number,
|
||||
endPage: number,
|
||||
totalPages: number
|
||||
) {
|
||||
if (startPage > endPage) {
|
||||
throw Error(
|
||||
`Range start (${startPage}) has to be less than range end (${endPage})`
|
||||
);
|
||||
}
|
||||
|
||||
if (startPage === 0 || endPage === 0) {
|
||||
throw Error('Range start/end has to be a non-zero number');
|
||||
}
|
||||
|
||||
if (startPage > totalPages || endPage > totalPages) {
|
||||
throw Error(
|
||||
'Range start/end has to be less or equal to the total number of pages'
|
||||
);
|
||||
}
|
||||
|
||||
if (startPage < 0 && endPage > 0) {
|
||||
throw Error('Range start cannot be negative when end is positive');
|
||||
}
|
||||
|
||||
// page is 1 indexed, handle positive case
|
||||
let startIndex = startPage - 1;
|
||||
// handle negative case
|
||||
if (startPage < 0) {
|
||||
startIndex = totalPages + startPage;
|
||||
}
|
||||
|
||||
// page is 1 indexed, handle positive case
|
||||
let endIndex = endPage - 1;
|
||||
// handle negative case
|
||||
if (endPage < 0) {
|
||||
endIndex = totalPages + endPage;
|
||||
}
|
||||
|
||||
return Array.from(
|
||||
{ length: endIndex - startIndex + 1 },
|
||||
(_, idx) => startIndex + idx
|
||||
);
|
||||
}
|
||||
|
||||
const markdownValue = `
|
||||
This action can extract or rearrange the pages in a PDF.
|
||||
|
||||
- The order of array determines the sequence of pages.
|
||||
- Each array element is one inclusive continuous range with a start page and end page.
|
||||
- Pages start from 1, and 0 is not valid.
|
||||
- Start page has to be less than end page.
|
||||
- You can select one page by setting the same start and end page.
|
||||
- To select pages from the start, specify negative pages eg. -1 is the last page, -5 is the 5th last page. start: -5, end: -1 are the last 5 pages.
|
||||
- Range cannot span across 0 eg. start: -3, end: 5.
|
||||
`;
|
||||
|
||||
export const extractPdfPages = createAction({
|
||||
name: 'extractPdfPages',
|
||||
displayName: 'Extract PDF Pages',
|
||||
description: 'Extract or rearrange page(s)from PDF File.',
|
||||
props: {
|
||||
markdown: Property.MarkDown({
|
||||
variant: MarkdownVariant.INFO,
|
||||
value: markdownValue,
|
||||
}),
|
||||
file: Property.File({
|
||||
displayName: 'PDF File or URL',
|
||||
required: true,
|
||||
}),
|
||||
pageRanges: Property.Array({
|
||||
displayName: 'Page Ranges',
|
||||
properties: {
|
||||
startPage: Property.Number({
|
||||
displayName: 'Start Page',
|
||||
required: true,
|
||||
}),
|
||||
endPage: Property.Number({
|
||||
displayName: 'End Page',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
errorHandlingOptions: {
|
||||
continueOnFailure: {
|
||||
defaultValue: false,
|
||||
},
|
||||
retryOnFailure: {
|
||||
hide: true,
|
||||
},
|
||||
},
|
||||
async run(context) {
|
||||
try {
|
||||
const srcDoc = await PDFDocument.load(context.propsValue.file.data as any);
|
||||
|
||||
const totalPages = srcDoc.getPageCount();
|
||||
const pageIndexes = context.propsValue.pageRanges.flatMap(
|
||||
(pageRange: any) =>
|
||||
pageRangeToIndexes(pageRange.startPage, pageRange.endPage, totalPages)
|
||||
);
|
||||
|
||||
const newDoc = await PDFDocument.create();
|
||||
const newPages = await newDoc.copyPages(srcDoc, pageIndexes);
|
||||
newPages.forEach((newPage) => newDoc.addPage(newPage));
|
||||
|
||||
const pdfBytes = await newDoc.save();
|
||||
const base64Pdf = Buffer.from(pdfBytes).toString('base64');
|
||||
|
||||
return context.files.write({
|
||||
data: Buffer.from(base64Pdf, 'base64'),
|
||||
fileName: context.propsValue.file.filename,
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to extract pages: ${(error as Error).message}`);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import pdfParse from 'pdf-parse';
|
||||
|
||||
export const extractText = createAction({
|
||||
name: 'extractText',
|
||||
displayName: 'Extract Text',
|
||||
description: 'Extract text from PDF file or url',
|
||||
props: {
|
||||
file: Property.File({
|
||||
displayName: 'PDF File or URL',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
errorHandlingOptions: {
|
||||
continueOnFailure: {
|
||||
defaultValue: false,
|
||||
},
|
||||
retryOnFailure: {
|
||||
hide: true
|
||||
},
|
||||
},
|
||||
async run(context) {
|
||||
const file = context.propsValue.file;
|
||||
const dataBuffer = Buffer.from(file.data.buffer);
|
||||
const pdfData = await pdfParse(dataBuffer);
|
||||
return pdfData.text;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,210 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { PDFDocument, PDFImage, RotationTypes, PageSizes } from 'pdf-lib';
|
||||
|
||||
export const imageToPdf = createAction({
|
||||
name: 'imageToPdf',
|
||||
displayName: 'Image to PDF',
|
||||
description: 'Convert image to PDF',
|
||||
props: {
|
||||
image: Property.File({
|
||||
displayName: 'image',
|
||||
description:
|
||||
'Image has to be png, jpeg or jpg and it will be scaled down to fit the page when image is larger than an A4 page',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
errorHandlingOptions: {
|
||||
continueOnFailure: {
|
||||
defaultValue: false,
|
||||
},
|
||||
retryOnFailure: {
|
||||
hide: true,
|
||||
},
|
||||
},
|
||||
async run(context) {
|
||||
try {
|
||||
const image = context.propsValue.image;
|
||||
const imageExtension = image.extension?.toLowerCase();
|
||||
|
||||
const pdfDoc = await PDFDocument.create();
|
||||
const page = pdfDoc.addPage();
|
||||
const [pageWidth, pageHeight] = PageSizes.A4;
|
||||
page.setSize(pageWidth, pageHeight);
|
||||
|
||||
const xMargin = 30;
|
||||
const yMargin = 30;
|
||||
const [maxCardWidth, maxCardHeight] = [pageWidth - xMargin * 2, pageHeight - yMargin * 2];
|
||||
|
||||
let result: PDFImage | null = null;
|
||||
|
||||
if (imageExtension === 'png') {
|
||||
result = await pdfDoc.embedPng(image.data as any);
|
||||
} else if (imageExtension === 'jpg' || imageExtension === 'jpeg') {
|
||||
result = await pdfDoc.embedJpg(image.data as any);
|
||||
} else {
|
||||
throw new Error(`Unsupported image format: ${imageExtension}`);
|
||||
}
|
||||
|
||||
if (result === null) {
|
||||
throw new Error('Failed to embed image');
|
||||
}
|
||||
|
||||
const exifOrientation = getImageOrientation(image.data.buffer as any);
|
||||
const orientationCorrection = getOrientationCorrection(exifOrientation);
|
||||
|
||||
let scaledImage, correctedWidth, correctedHeight;
|
||||
switch (exifOrientation) {
|
||||
case ImageOrientation.FlipHorizontalRotate90:
|
||||
case ImageOrientation.Rotate90:
|
||||
case ImageOrientation.FlipVerticalRotate90:
|
||||
case ImageOrientation.Rotate270:
|
||||
// The uploaded image is rotated +/- 90 degrees
|
||||
scaledImage = result.scaleToFit(maxCardHeight, maxCardWidth);
|
||||
correctedWidth = scaledImage.height;
|
||||
correctedHeight = scaledImage.width;
|
||||
break;
|
||||
default:
|
||||
scaledImage = result.scaleToFit(maxCardWidth, maxCardHeight);
|
||||
correctedWidth = scaledImage.width;
|
||||
correctedHeight = scaledImage.height;
|
||||
}
|
||||
|
||||
let xShift, yShift;
|
||||
const yOffset = pageHeight - yMargin;
|
||||
switch (exifOrientation) {
|
||||
case ImageOrientation.FlipHorizontal:
|
||||
xShift = pageWidth - xMargin - correctedWidth;
|
||||
yShift = yOffset - correctedHeight;
|
||||
break;
|
||||
case ImageOrientation.Rotate180:
|
||||
xShift = xMargin + correctedWidth;
|
||||
yShift = yOffset;
|
||||
break;
|
||||
case ImageOrientation.FlipVertical:
|
||||
xShift = pageWidth - xMargin;
|
||||
yShift = yOffset;
|
||||
break;
|
||||
case ImageOrientation.FlipHorizontalRotate90:
|
||||
xShift = xMargin + correctedWidth;
|
||||
yShift = pageHeight - yOffset;
|
||||
break;
|
||||
case ImageOrientation.Rotate90:
|
||||
xShift = xMargin;
|
||||
yShift = yOffset;
|
||||
break;
|
||||
case ImageOrientation.FlipVerticalRotate90:
|
||||
xShift = xMargin;
|
||||
yShift = pageHeight - yOffset + correctedHeight;
|
||||
break;
|
||||
case ImageOrientation.Rotate270:
|
||||
xShift = xMargin + correctedWidth;
|
||||
yShift = yOffset - correctedHeight;
|
||||
break;
|
||||
default:
|
||||
xShift = xMargin;
|
||||
yShift = yOffset - correctedHeight;
|
||||
}
|
||||
|
||||
page.drawImage(result, {
|
||||
x: xShift,
|
||||
y: yShift,
|
||||
height: scaledImage.height,
|
||||
width: scaledImage.width,
|
||||
rotate: { angle: orientationCorrection.degrees, type: RotationTypes.Degrees },
|
||||
});
|
||||
|
||||
const pdfBytes = await pdfDoc.save();
|
||||
const base64Pdf = Buffer.from(pdfBytes).toString('base64');
|
||||
|
||||
return context.files.write({
|
||||
data: Buffer.from(base64Pdf, 'base64'),
|
||||
fileName: `${image.filename}.pdf`,
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to convert text to PDF: ${(error as Error).message}`);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// https://sirv.com/help/articles/rotate-photos-to-be-upright/#exif-orientation-values
|
||||
enum ImageOrientation {
|
||||
Normal = 1, // "Image is in normal orientation, no rotation or flipping"
|
||||
Rotate90 = 6, // "Image is rotated 90 degrees"
|
||||
Rotate180 = 3, // "Image is rotated 180 degrees"
|
||||
Rotate270 = 8, // "Image is rotated 270 degrees"
|
||||
FlipHorizontal = 2, // "Image is flipped horizontally"
|
||||
FlipVertical = 4, // "Image is flipped horizontally and rotated 180 degrees"
|
||||
FlipHorizontalRotate90 = 5, // "Image is rotated 90 degrees and flipped horizontally"
|
||||
FlipVerticalRotate90 = 7, // "Image is rotated 270 degrees and flipped horizontally"
|
||||
Unknown= -1
|
||||
|
||||
}
|
||||
|
||||
// https://github.com/Hopding/pdf-lib/issues/1284
|
||||
// https://stackoverflow.com/questions/7584794/accessing-jpeg-exif-rotation-data-in-javascript-on-the-client-side/32490603#32490603
|
||||
function getImageOrientation(file: ArrayBuffer): ImageOrientation {
|
||||
const view = new DataView(file);
|
||||
|
||||
const length = view.byteLength;
|
||||
let offset = 2;
|
||||
|
||||
while (offset < length) {
|
||||
if (view.getUint16(offset + 2, false) <= 8) return ImageOrientation.Unknown;
|
||||
const marker = view.getUint16(offset, false);
|
||||
offset += 2;
|
||||
|
||||
// If EXIF buffer segment exists find the orientation
|
||||
if (marker == 0xffe1) {
|
||||
if (view.getUint32((offset += 2), false) != 0x45786966) {
|
||||
return ImageOrientation.Unknown;
|
||||
}
|
||||
|
||||
const little = view.getUint16((offset += 6), false) == 0x4949;
|
||||
offset += view.getUint32(offset + 4, little);
|
||||
const tags = view.getUint16(offset, little);
|
||||
offset += 2;
|
||||
for (let i = 0; i < tags; i++) {
|
||||
if (view.getUint16(offset + i * 12, little) == 0x0112) {
|
||||
const orientation = view.getUint16(offset + i * 12 + 8, little);
|
||||
switch (orientation) {
|
||||
case 1: return ImageOrientation.Normal;
|
||||
case 3: return ImageOrientation.Rotate180;
|
||||
case 6: return ImageOrientation.Rotate90;
|
||||
case 8: return ImageOrientation.Rotate270;
|
||||
case 2: return ImageOrientation.FlipHorizontal;
|
||||
case 4: return ImageOrientation.FlipVertical;
|
||||
case 5: return ImageOrientation.FlipHorizontalRotate90;
|
||||
case 7: return ImageOrientation.FlipVerticalRotate90;
|
||||
default: return ImageOrientation.Unknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ((marker & 0xff00) != 0xff00) {
|
||||
break;
|
||||
} else {
|
||||
offset += view.getUint16(offset, false);
|
||||
}
|
||||
}
|
||||
return ImageOrientation.Unknown;
|
||||
}
|
||||
|
||||
function getOrientationCorrection(orientation: number): { degrees: number; mirrored?: 'x' | 'y' } {
|
||||
switch (orientation) {
|
||||
case ImageOrientation.FlipHorizontal:
|
||||
return { degrees: 0, mirrored: 'x' };
|
||||
case ImageOrientation.Rotate180:
|
||||
return { degrees: -180 };
|
||||
case ImageOrientation.FlipVertical:
|
||||
return { degrees: 180, mirrored: 'x' };
|
||||
case ImageOrientation.FlipHorizontalRotate90:
|
||||
return { degrees: 90, mirrored: 'y' };
|
||||
case ImageOrientation.Rotate90:
|
||||
return { degrees: -90 };
|
||||
case ImageOrientation.FlipVerticalRotate90:
|
||||
return { degrees: -90, mirrored: 'y' };
|
||||
case ImageOrientation.Rotate270:
|
||||
return { degrees: 90 };
|
||||
default:
|
||||
return { degrees: 0 };
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { PDFDocument } from 'pdf-lib';
|
||||
|
||||
export const mergePdfs = createAction({
|
||||
name: 'mergePdfs',
|
||||
displayName: 'Merge PDFs',
|
||||
description: 'Merges multiple PDF files into a single PDF document.',
|
||||
props: {
|
||||
pdfFiles: Property.Array({
|
||||
displayName: 'PDF Files',
|
||||
description: 'Array of PDF files to merge',
|
||||
required: true,
|
||||
properties: {
|
||||
file: Property.File({
|
||||
displayName: 'PDF File',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
}),
|
||||
outputFileName: Property.ShortText({
|
||||
displayName: 'Output File Name',
|
||||
description: 'Name for the merged PDF file (without extension)',
|
||||
required: false,
|
||||
defaultValue: 'merged-document',
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
try {
|
||||
const { pdfFiles, outputFileName } = context.propsValue;
|
||||
|
||||
// pdfFiles is already an array from Property.Array
|
||||
|
||||
if (!pdfFiles || !Array.isArray(pdfFiles) || pdfFiles.length < 2) {
|
||||
throw new Error('At least 2 PDF files are required for merging');
|
||||
}
|
||||
|
||||
const mergedPdf = await PDFDocument.create();
|
||||
|
||||
for (let i = 0; i < pdfFiles.length; i++) {
|
||||
const fileItem = pdfFiles[i] as any;
|
||||
const file = fileItem.file;
|
||||
|
||||
if (!file) {
|
||||
throw new Error(`File at index ${i} is null or undefined`);
|
||||
}
|
||||
|
||||
// Handle PDF files only
|
||||
let fileData: Buffer;
|
||||
const fileName = file.filename || file.name || `file-${i}.pdf`;
|
||||
|
||||
// Validate it's a PDF file
|
||||
if (fileName && !fileName.toLowerCase().endsWith('.pdf')) {
|
||||
throw new Error(`File at index ${i} (${fileName}) is not a PDF file`);
|
||||
}
|
||||
|
||||
if (file.data) {
|
||||
// Handle base64 strings
|
||||
if (typeof file.data === 'string') {
|
||||
fileData = Buffer.from(file.data, 'base64');
|
||||
}
|
||||
// Handle Buffer objects serialized as JSON
|
||||
else if (file.data.type === 'Buffer' && Array.isArray(file.data.data)) {
|
||||
fileData = Buffer.from(file.data.data);
|
||||
}
|
||||
// Handle direct Buffer
|
||||
else if (Buffer.isBuffer(file.data)) {
|
||||
fileData = file.data;
|
||||
}
|
||||
else {
|
||||
throw new Error(`Unsupported data format for PDF file ${i}: ${typeof file.data}`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new Error(`PDF file at index ${i} has no data property`);
|
||||
}
|
||||
|
||||
try {
|
||||
const pdfDoc = await PDFDocument.load(new Uint8Array(fileData));
|
||||
const pageCount = pdfDoc.getPageCount();
|
||||
const pageIndices = Array.from({ length: pageCount }, (_, idx) => idx);
|
||||
|
||||
const copiedPages = await mergedPdf.copyPages(pdfDoc, pageIndices);
|
||||
copiedPages.forEach((page) => mergedPdf.addPage(page));
|
||||
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to process PDF file at index ${i} (${fileName}): ${(error as Error).message}`);
|
||||
}
|
||||
}
|
||||
|
||||
const pdfBytes = await mergedPdf.save();
|
||||
|
||||
return context.files.write({
|
||||
data: Buffer.from(pdfBytes),
|
||||
fileName: `${outputFileName || 'merged-document'}.pdf`,
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to merge PDFs: ${(error as Error).message}`);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,30 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { PDFDocument } from 'pdf-lib';
|
||||
|
||||
export const pdfPageCount = createAction({
|
||||
name: 'pdfPageCount',
|
||||
displayName: 'PDF Page Count',
|
||||
description: 'Get page count of PDF file.',
|
||||
props: {
|
||||
file: Property.File({
|
||||
displayName: 'PDF File or URL',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
errorHandlingOptions: {
|
||||
continueOnFailure: {
|
||||
defaultValue: false,
|
||||
},
|
||||
retryOnFailure: {
|
||||
hide: true,
|
||||
},
|
||||
},
|
||||
async run({ propsValue }) {
|
||||
try {
|
||||
const pdfDoc = await PDFDocument.load(propsValue.file.data as any);
|
||||
return pdfDoc.getPageCount();
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to get page count: ${(error as Error).message}`);
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,103 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { PDFDocument, StandardFonts } from 'pdf-lib';
|
||||
|
||||
export const textToPdf = createAction({
|
||||
name: 'textToPdf',
|
||||
displayName: 'Text to PDF',
|
||||
description: 'Convert text to PDF',
|
||||
props: {
|
||||
text: Property.LongText({
|
||||
displayName: 'text',
|
||||
description: 'Enter text to convert',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
errorHandlingOptions: {
|
||||
continueOnFailure: {
|
||||
defaultValue: false,
|
||||
},
|
||||
retryOnFailure: {
|
||||
hide: true,
|
||||
},
|
||||
},
|
||||
async run(context) {
|
||||
const text = context.propsValue.text;
|
||||
|
||||
const pageSize: [number, number] = [595, 842]; // Standard A4 size
|
||||
const margin = 50;
|
||||
const topMargin = 70;
|
||||
const fontSize = 12;
|
||||
const lineSpacing = 5;
|
||||
const paragraphSpacing = 8;
|
||||
const fontType: StandardFonts = StandardFonts.Helvetica;
|
||||
|
||||
try {
|
||||
const pdfDoc = await PDFDocument.create();
|
||||
let page = pdfDoc.addPage(pageSize);
|
||||
const { width, height } = page.getSize();
|
||||
|
||||
const font = await pdfDoc.embedFont(fontType);
|
||||
|
||||
const lineHeight = font.heightAtSize(fontSize) + lineSpacing;
|
||||
const maxWidth = width - margin * 2;
|
||||
|
||||
const paragraphs = text.split('\n');
|
||||
let yPosition = height - topMargin;
|
||||
|
||||
paragraphs.forEach((paragraph) => {
|
||||
const words = paragraph.split(' ');
|
||||
let line = '';
|
||||
|
||||
words.forEach((word) => {
|
||||
const testLine = line + word + ' ';
|
||||
const testLineWidth = font.widthOfTextAtSize(testLine, fontSize);
|
||||
|
||||
if (testLineWidth > maxWidth) {
|
||||
page.drawText(line.trim(), {
|
||||
x: margin,
|
||||
y: yPosition,
|
||||
size: fontSize,
|
||||
font,
|
||||
});
|
||||
line = word + ' ';
|
||||
yPosition -= lineHeight;
|
||||
|
||||
if (yPosition < margin + lineHeight) {
|
||||
page = pdfDoc.addPage(pageSize);
|
||||
yPosition = height - topMargin;
|
||||
}
|
||||
} else {
|
||||
line = testLine;
|
||||
}
|
||||
});
|
||||
|
||||
if (line.trim()) {
|
||||
page.drawText(line.trim(), {
|
||||
x: margin,
|
||||
y: yPosition,
|
||||
size: fontSize,
|
||||
font,
|
||||
});
|
||||
yPosition -= lineHeight;
|
||||
}
|
||||
|
||||
yPosition -= paragraphSpacing;
|
||||
|
||||
if (yPosition < margin + lineHeight) {
|
||||
page = pdfDoc.addPage(pageSize);
|
||||
yPosition = height - topMargin;
|
||||
}
|
||||
});
|
||||
|
||||
const pdfBytes = await pdfDoc.save();
|
||||
const base64Pdf = Buffer.from(pdfBytes).toString('base64');
|
||||
|
||||
return context.files.write({
|
||||
data: Buffer.from(base64Pdf, 'base64'),
|
||||
fileName: 'text.pdf',
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to convert text to PDF: ${(error as Error).message}`);
|
||||
}
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user