Explorar o código

:construction: merge texlive & pandoc task examples

Jeremy Zheng hai 1 ano
pai
achega
4d09561221

+ 7 - 2
rpc/tutorials/php/.gitignore

@@ -1,4 +1,9 @@
+/tmp/
+/morus-client.json
+/queue.json
+
+/GPBMetadata/
+/Palm/
+
 /composer.lock
 /vendor/
-/lib/
-/config.yml

+ 6 - 6
rpc/tutorials/php/README.md

@@ -1,9 +1,9 @@
-# USAGE
-
-- install [php-pear](https://aur.archlinux.org/packages/php-pear)
+# Usage
 
 ```bash
-# add "extension=yaml" to php.ini
-sudo pecl install yaml
-composer update
+composer install
+
+php -d extension=grpc.so -d max_execution_time=300 morus-client.php morus.json
+php queue-producer.php queue.json texlive QUEUE
+php queue-producer.php queue.json pandoc QUEUE
 ```

+ 15 - 3
rpc/tutorials/php/composer.json

@@ -1,7 +1,19 @@
 {
+  "name": "grpc/grpc-demo",
+  "description": "gRPC example for PHP",
   "require": {
-    "php-amqplib/php-amqplib": "^3.2",
-    "apache/thrift": "0.20.0",
-    "monolog/monolog": "3.6.0"
+    "grpc/grpc": "^v1.39.0",
+    "google/protobuf": "^v3.12.2",
+    "monolog/monolog": "^3.7",
+    "ramsey/uuid": "^4.7",
+    "php-amqplib/php-amqplib": "^3.7"
+  },
+  "autoload": {
+    "psr-4": {
+      "GPBMetadata\\": [
+        "GPBMetadata/"
+      ],
+      "Palm\\": "Palm/"
+    }
   }
 }

+ 0 - 11
rpc/tutorials/php/config-orig.yml

@@ -1,11 +0,0 @@
-rabbitmq:
-  host: "127.0.0.1"
-  port: 5672
-  user: "guest"
-  password: "guest"
-  virtual-host: "testing"
-
-lily:
-  tex-to-pdf:
-    queue-name: "tex2pdf"
-    callback-url: "http://localhost:8080/md2pdf/callback"

+ 0 - 88
rpc/tutorials/php/lily.php

@@ -1,88 +0,0 @@
-<?php
-
-require_once __DIR__ . '/vendor/autoload.php';
-require_once __DIR__ . '/lib/lily/Tex.php';
-require_once __DIR__ . '/lib/lily/TexToPdfTask.php';
-
-
-use Monolog\Level;
-use Monolog\Logger;
-use Monolog\Handler\StreamHandler;
-use Thrift\Serializer\TBinarySerializer;
-use PhpAmqpLib\Connection\AMQPStreamConnection;
-use PhpAmqpLib\Message\AMQPMessage;
-
-
-use lily\Tex;
-use lily\TexToPdfTask;
-
-function publish_tex_to_pdf($logger, $channel, $queue, $callback)
-{
-    $task = new TexToPdfTask();
-    $task->bucket = "testing";
-    $task->object = date("Y-m-d") . '.pdf';
-    $task->callback = $callback;
-    $task->tex = new Tex();
-    $task->tex->homepage = <<<TEX
-\\documentclass{article}
-
-\\begin{document}
-
-\\title{The title \\thanks{With footnote}}
-\\auhtor{me}
-\\date{\\today}
-\\maketitle
-
-\\include{vocabulary/session-1.tex}
-\\include{vocabulary/session-2.tex}
-\\include{vocabulary/session-3.tex}
-
-\\end {document}
-TEX;
-    $task->tex->files = array(
-        "section-1.tex" => <<<TEX
-\\section{Session 1}
-TEX,
-        "section-2.tex" => <<<TEX
-\\section{Session 2}        
-
-\\First\\footnote{First note}
-\\Second\\footnote{Second note}
-\\Third\\footnote{Third note}
-TEX,
-        "section-3.tex" => <<<TEX
-\\section{Session 3}
-TEX,
-    );
-
-    $body = TBinarySerializer::serialize($task);
-    $message_id = uniqid();
-    $logger->debug("publish a tex-to-pdf task(" . strlen($body)  . "bytes) " . $message_id);
-    // https://github.com/php-amqplib/php-amqplib/blob/master/doc/AMQPMessage.md
-    $message = new AMQPMessage($body, ['message_id' => $message_id]);
-    $channel->basic_publish($message, '', $queue);
-}
-
-$logger = new Logger('lily');
-$logger->pushHandler(new StreamHandler('php://stdout', Level::Debug));
-$logger->debug("run on debug mode");
-
-if ($argc !== 2) {
-    $logger->error("usage: php $argv[0] config.yml");
-    exit(1);
-}
-$logger->debug("$argc");
-$logger->info("load config from" . $argv[1]);
-$config = yaml_parse_file($argv[1]);
-$logger->debug("connect to rabbitmq://" . $config['rabbitmq']['host'] . "@" . $config['rabbitmq']['host'] . ":" . $config['rabbitmq']['port'] . "/" . $config['rabbitmq']['virtual-host']);
-
-$queue_connection = new AMQPStreamConnection($config['rabbitmq']['host'], $config['rabbitmq']['port'], $config['rabbitmq']['user'], $config['rabbitmq']['password'], $config['rabbitmq']['virtual-host']);
-$queue_channel = $queue_connection->channel();
-
-
-publish_tex_to_pdf($logger, $queue_channel, $config['lily']['tex-to-pdf']['queue-name'], $config['lily']['tex-to-pdf']['callback-url']);
-
-
-$queue_channel->close();
-$queue_connection->close();
-$logger->warning("quit.");

+ 12 - 0
rpc/tutorials/php/morus-client.orig.json

@@ -0,0 +1,12 @@
+{
+  "server": {
+    "host": "127.0.0.1",
+    "port": 9999
+  },
+  "ssl": {
+    "ca-file": "tmp/ca.crt",
+    "key-file": "tmp/client.key",
+    "cert-file": "tmp/client.crt",
+    "authority": "www.change-me.org"
+  }
+}

+ 48 - 0
rpc/tutorials/php/morus-client.php

@@ -0,0 +1,48 @@
+<?php
+
+require dirname(__FILE__) . '/vendor/autoload.php';
+
+function markdown2html($server_uri, $options, $payload, $sanitize)
+{
+    global $logger;
+
+    $client = new Palm\Morus\V1\MarkdownClient($server_uri, $options);
+    $request = new Palm\Morus\V1\MarkdownToHtmlRequest();
+    $request->setPayload($payload);
+    $request->setSanitize($sanitize);
+    list($response, $status) = $client->ToHtml($request)->wait();
+    if ($status->code !== Grpc\STATUS_OK) {
+        $logger->error("markdown to html", ['code' => $status->code, 'details' => $status->details]);
+        exit(1);
+    }
+    $logger->info("markdown to html", ['body' => $response->getPayload()]);
+}
+
+$logger = new Monolog\Logger('palm');
+$logger->pushHandler(new Monolog\Handler\StreamHandler('php://stdout', Monolog\Level::Debug));
+
+
+if (empty($argv[1])) {
+    $logger->error("USAGE: " . $argv[0] . " CONFIG_FILE");
+    exit(1);
+}
+
+$logger->debug("load config from", ['file' => $argv[1]]);
+$config = json_decode(file_get_contents($argv[1]));
+
+$server_uri = $config->{'server'}->{'host'} . ":" . $config->{'server'}->{'port'};
+// $server_options = [
+//     'credentials' => Grpc\ChannelCredentials::createInsecure(),
+// ];
+$server_options = [
+    'credentials' => \Grpc\ChannelCredentials::createSsl(
+        file_get_contents($config->{'ssl'}->{'ca-file'}),
+        file_get_contents($config->{'ssl'}->{'key-file'}),
+        file_get_contents($config->{'ssl'}->{'cert-file'})
+    ),
+    // 'grpc.ssl_target_name_override' => $config->{'server'}->{'host'},
+    'grpc.default_authority' => $config->{'ssl'}->{'authority'}
+];
+
+$logger->info("connect to", ['server' => $server]);
+markdown2html($server_uri, $server_options, "# Hi, Palm!", true);

+ 96 - 0
rpc/tutorials/php/queue-producer.php

@@ -0,0 +1,96 @@
+<?php
+
+require dirname(__FILE__) . '/vendor/autoload.php';
+
+function texlive_task_message($s3_bucket_name)
+{
+    $output =  new Palm\Lily\V1\TeXLiveTask\Output();
+    $output->setFormat(Palm\Lily\V1\TeXLiveTask\Output\Format::Pdf);
+    $output->setBucket($s3_bucket_name);
+    $output->setObject(Ramsey\Uuid\Uuid::uuid4()->toString() . '.pdf');
+
+    $request = new Palm\Lily\V1\TeXLiveTask();
+    $request->setEntry(file_get_contents('tex/main.tex'));
+
+    foreach (array("coding.png", "foreword.tex", "section-1.tex", "section-2.tex", "postscript.tex") as $f) {
+        $request->getAttachments()[$f] = file_get_contents('tex/' . $f);
+    }
+
+    $request->setOutput($output);
+    return $request->serializeToString();
+}
+function pandoc_task_message($s3_bucket_name)
+{
+    $input =  new Palm\Lily\V1\PandocTask\Input();
+    $input->setFormat(Palm\Lily\V1\PandocTask\Format::Markdown);
+    $input->setPayload("# Hello, Lily!");
+
+    $output =  new Palm\Lily\V1\PandocTask\Output();
+    $output->setFormat(Palm\Lily\V1\PandocTask\Format::Docx);
+    $output->setBucket($s3_bucket_name);
+    $output->setObject(Ramsey\Uuid\Uuid::uuid4()->toString() . '.docx');
+
+    $request = new Palm\Lily\V1\PandocTask();
+    $request->setInput($input);
+    $request->setOutput($output);
+    return $request->serializeToString();
+}
+
+function send_message($channel, $queue_name, $message_id, $message_body)
+{
+    global $logger;
+    $logger->info("send message", ['id' => $message_id]);
+    $message = new PhpAmqpLib\Message\AMQPMessage(
+        $message_body,
+        properties: ['message_id' => $message_id, 'content_type' => 'application/grpc+proto']
+    );
+    $channel->basic_publish($message, '', $queue_name);
+}
+
+$logger = new Monolog\Logger('palm');
+$logger->pushHandler(new Monolog\Handler\StreamHandler('php://stdout', Monolog\Level::Debug));
+
+
+if (empty($argv[1]) or empty($argv[2]) or empty($argv[3])) {
+    $logger->error("USAGE: " . $argv[0] . " CONFIG_FILE JOB QUEUE");
+    exit(1);
+}
+
+$logger->debug("load config from", ['file' => $argv[1]]);
+$config = json_decode(file_get_contents($argv[1]));
+
+$logger->info("connect to", ['host' => $config->{'host'}, 'port' => $config->{'port'}, 'user' => $config->{'user'}]);
+$queue_connection = new PhpAmqpLib\Connection\AMQPStreamConnection(
+    $config->{'host'},
+    $config->{'port'},
+    $config->{'user'},
+    $config->{'password'},
+    vhost: $config->{'virtual-host'}
+);
+$queue_channel = $queue_connection->channel();
+$queue_name = $argv[3];
+$logger->info("create queue", ['name' => $queue_name]);
+$queue_channel->queue_declare($queue_name, false, false, false, false);
+
+$s3_bucket_name = "testing";
+
+foreach (range(1, 10) as $i) {
+    $message_id = Ramsey\Uuid\Uuid::uuid4()->toString();
+
+    $message_properties = [];
+    switch ($argv[2]) {
+        case "pandoc":
+            send_message($queue_channel, $queue_name, $message_id, pandoc_task_message($s3_bucket_name));
+            break;
+        case "texlive":
+            send_message($queue_channel, $queue_name, $message_id, texlive_task_message($s3_bucket_name));
+            break;
+        default:
+            $logger->error("unknown job", ['name' => $argv[2]]);
+            exit(1);
+    }
+    sleep(1);
+}
+
+$queue_channel->close();
+$queue_connection->close();

+ 7 - 0
rpc/tutorials/php/queue.orig.json

@@ -0,0 +1,7 @@
+{
+  "host": "127.0.0.1",
+  "port": 5672,
+  "user": "guest",
+  "password": "guest",
+  "virtual-host": "palm-dev"
+}

BIN=BIN
rpc/tutorials/php/tex/coding.png


+ 5 - 0
rpc/tutorials/php/tex/foreword.tex

@@ -0,0 +1,5 @@
+\frontmatter
+\chapter{Dedication}
+\chapter{Copyright}
+\chapter{Acknowledgements}
+\chapter{Preface}

+ 28 - 0
rpc/tutorials/php/tex/main.tex

@@ -0,0 +1,28 @@
+\setmainfont{DejaVu Sans}
+\setsansfont{DejaVu Sans}
+\setmonofont{DejaVu Sans Mono}
+
+\newcommand\ytl[2]{\parbox[b]{8em}{\hfill{\color{cyan}\bfseries\sffamily #1}~$\cdots\cdots$~}\makebox[0pt][c]{$\bullet$}\vrule\quad \parbox[c]{10cm}{\vspace{7pt}\color{red!40!black!80}\raggedright\sffamily #2.\\[7pt]}\\[-3pt]}
+
+\title{Tex2Pdf Testing \footnote{Not everybody could sail the ocean, but still we could share this dream.}}
+\author{通吃島主}
+\date{\today}
+
+\begin{document}
+    \maketitle
+
+    \include{foreword.tex}
+
+    \tableofcontents
+    \listoffigures
+    \listoftables
+
+    \mainmatter
+    \part{P1}
+        \chapter{C1}
+        \include{section-1.tex}
+        \include{section-2.tex}
+        
+    \include{postscript.tex}
+
+\end{document}

+ 7 - 0
rpc/tutorials/php/tex/postscript.tex

@@ -0,0 +1,7 @@
+\appendix
+\chapter{感谢}
+
+\chapter{时间线}
+
+\backmatter
+\chapter{后记}

+ 7 - 0
rpc/tutorials/php/tex/section-1.tex

@@ -0,0 +1,7 @@
+\section{Session 1}
+
+S1:
+\begin{itemize}
+    \item line 1.1
+    \item line 1.2
+\end{itemize}

+ 9 - 0
rpc/tutorials/php/tex/section-2.tex

@@ -0,0 +1,9 @@
+\section{Session 2}
+
+S2:
+
+\begin{frame}
+    \frametitle{Coding}
+    \centering
+    \includegraphics[scale=0.6]{coding.png}
+\end{frame}