From e722bd399fde116f0bdcbca395de5e5c5cae9266 Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Sat, 7 Nov 2015 22:13:08 +0100 Subject: [PATCH] API: update method --- README.md | 71 ++++++++++++++++ app/bootstrap.php.d/60-api.php | 3 +- app/config/routing.yml | 4 + app/console | 2 + src/Gist/Api/Client.php | 21 +++++ src/Gist/Command/CreateCommand.php | 10 +++ src/Gist/Command/UpdateCommand.php | 114 ++++++++++++++++++++++++++ src/Gist/Controller/ApiController.php | 52 ++++++++++++ src/Gist/Form/ApiCreateGistForm.php | 2 +- src/Gist/Form/ApiUpdateGistForm.php | 21 +++++ 10 files changed, 298 insertions(+), 2 deletions(-) create mode 100644 src/Gist/Command/UpdateCommand.php create mode 100644 src/Gist/Form/ApiUpdateGistForm.php diff --git a/README.md b/README.md index 7b44e85..816ee2d 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,34 @@ Params: * Code ```405```: Method Not Allowed * Code ```400```: Bad Request +### Update an existing Gist + +**POST** /{locale}/api/update/{id} +Params: + +* ```{id}```: Gist Id (required) +* ```form[content]```: String (required) + +#### Responses: + +* Code ```200```: A json which contains gist's information. Example: + ```javascript +{ + "url": "https:\/\/gist.deblan.org\/en\/view\/55abcfa7771e0\/abcgi72967dd95e3461490dcaa310d728d6adef", + "gist": { + "Id": 66, + "Title": "test prod", + "Cipher": false, + "Type": "javascript", + "File": "55abcfa7771e0", + "CreatedAt": "2015-07-19T16:26:15Z", + "UpdatedAt": "2015-07-19T16:30:15Z" + } +} + ``` +* Code ```405```: Method Not Allowed +* Code ```400```: Bad Request + Console ------- @@ -146,6 +174,7 @@ Arguments: Options: -t, --title=TITLE Title of the gist -u, --show-url Display only the gist url + -i, --show-id Display only the gist Id -h, --help Display this help message -q, --quiet Do not output any message -V, --version Display this application version @@ -168,6 +197,48 @@ Help: Options: --title, -t Defines a title + + --show-id, -i + Display only the Id of the gist + + --show-url, -u + Display only the url of the gist +$ ./app/console --help create +Usage: + update [options] [--] + +Arguments: + input Input + +Options: + --id=ID Gist Id + -u, --show-url Display only the gist url + -i, --show-id Display only the gist Id + -h, --help Display this help message + -q, --quiet Do not output any message + -V, --version Display this application version + --ansi Force ANSI output + --no-ansi Disable ANSI output + -n, --no-interaction Do not ask any interactive question + -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug + +Help: + Provides a client to create a gist using the API. + + Arguments: + input + Identify the source of the content: path of the file (eg: /path/to/file) or standard input (-) + + type + Defines the type of code: html, css, javascript, php, sql, xml, yaml, perl, c, asp, python, bash, actionscript3, text + Default value: text + + Options: + --id + Defines the Gist to update by using its ID + + --show-id, -i + Display only the Id of the gist --show-url, -u Display only the url of the gist diff --git a/app/bootstrap.php.d/60-api.php b/app/bootstrap.php.d/60-api.php index bdde1f9..874cca5 100644 --- a/app/bootstrap.php.d/60-api.php +++ b/app/bootstrap.php.d/60-api.php @@ -3,5 +3,6 @@ use Gist\Api\Client; $app['api_client'] = function ($app) { - return new Client(['base_uri' => 'https://gist.deblan.org/']); + // return new Client(['base_uri' => 'https://gist.deblan.org/']); + return new Client(['base_uri' => 'http://localhost:8080/']); }; diff --git a/app/config/routing.yml b/app/config/routing.yml index 1da5b74..c7a2d5b 100644 --- a/app/config/routing.yml +++ b/app/config/routing.yml @@ -33,3 +33,7 @@ revisions: api_create: path: /api/create defaults: {_controller: Gist\Controller\ApiController::createAction, _locale: en} + +api_update: + path: /api/update/{id} + defaults: {_controller: Gist\Controller\ApiController::updateAction, _locale: en} diff --git a/app/console b/app/console index 7aafa0c..b7ddd2b 100755 --- a/app/console +++ b/app/console @@ -2,9 +2,11 @@ add(new CreateCommand()); +$app['console']->add(new UpdateCommand()); $app['console']->run(); diff --git a/src/Gist/Api/Client.php b/src/Gist/Api/Client.php index 6a1b703..d09bdb3 100644 --- a/src/Gist/Api/Client.php +++ b/src/Gist/Api/Client.php @@ -11,6 +11,7 @@ use GuzzleHttp\Client as BaseClient; class Client extends BaseClient { const CREATE = '/en/api/create'; + const UPDATE = '/en/api/update/{id}'; public function create($title, $type, $content) { @@ -33,4 +34,24 @@ class Client extends BaseClient return []; } + + public function update($id, $content) + { + $response = $this->post( + str_replace('{id}', $id, self::UPDATE), + array( + 'form_params' => array( + 'form' => array( + 'content' => $content, + ), + ), + ) + ); + + if ($response->getStatusCode() === 200) { + return json_decode($response->getBody()->getContents(), true); + } + + return []; + } } diff --git a/src/Gist/Command/CreateCommand.php b/src/Gist/Command/CreateCommand.php index f2ed43c..a3c9551 100644 --- a/src/Gist/Command/CreateCommand.php +++ b/src/Gist/Command/CreateCommand.php @@ -20,6 +20,7 @@ class CreateCommand extends Command ->addArgument('type', InputArgument::OPTIONAL, 'Type', 'text') ->addOption('title', 't', InputOption::VALUE_REQUIRED, 'Title of the gist') ->addOption('show-url', 'u', InputOption::VALUE_NONE, 'Display only the gist url') + ->addOption('show-id', 'i', InputOption::VALUE_NONE, 'Display only the gist Id') ->setHelp(<<--title, -t Defines a title + + --show-id, -i + Display only the Id of the gist --show-url, -u Display only the url of the gist @@ -84,6 +88,12 @@ EOF return true; } + + if ($input->getOption('show-id')) { + $output->writeln($gist['gist']['Id']); + + return true; + } $output->writeln(json_encode($gist)); } diff --git a/src/Gist/Command/UpdateCommand.php b/src/Gist/Command/UpdateCommand.php new file mode 100644 index 0000000..2e4f666 --- /dev/null +++ b/src/Gist/Command/UpdateCommand.php @@ -0,0 +1,114 @@ +getTypes()); + $this + ->setName('update') + ->setDescription('Update a gist using the API') + ->addArgument('input', InputArgument::REQUIRED, 'Input') + ->addOption('id', null, InputOption::VALUE_REQUIRED, 'Gist Id') + ->addOption('show-url', 'u', InputOption::VALUE_NONE, 'Display only the gist url') + ->addOption('show-id', 'i', InputOption::VALUE_NONE, 'Display only the gist Id') + ->setHelp(<<input + Identify the source of the content: path of the file (eg: /path/to/file) or standard input (-) + + type + Defines the type of code: {$types} + Default value: text + +Options: + --id + Defines the Gist to update by using its ID + + --show-id, -i + Display only the Id of the gist + + --show-url, -u + Display only the url of the gist +EOF + ); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + //$output->writeln(sprintf('%s bar.', 'test')); + + $file = $input->getArgument('input'); + $id = $input->getOption('id'); + + if ($file === '-') { + $content = file_get_contents('php://stdin'); + } else { + if (!is_readable($file)) { + $output->writeln(sprintf('%s: No such file.', $file)); + + return false; + } + + if (!is_file($file)) { + $output->writeln(sprintf('"%s" must be a file.', $file)); + + return false; + } + + $content = file_get_contents($file); + } + + if (trim($content) === '') { + $output->writeln(sprintf('You can not create an empty gist.', $type)); + } + + $gist = $this->getSilexApplication()['api_client']->update($id, $content); + + if ($input->getOption('show-url')) { + $output->writeln($gist['url']); + + return true; + } + + if ($input->getOption('show-id')) { + $output->writeln($gist['gist']['Id']); + + return true; + } + + $output->writeln(json_encode($gist)); + } + + protected function getTypes() + { + $types = array( + 'html', + 'css', + 'javascript', + 'php', + 'sql', + 'xml', + 'yaml', + 'perl', + 'c', + 'asp', + 'python', + 'bash', + 'actionscript3', + 'text', + ); + + return $types; + } +} diff --git a/src/Gist/Controller/ApiController.php b/src/Gist/Controller/ApiController.php index 940d42f..6d64039 100644 --- a/src/Gist/Controller/ApiController.php +++ b/src/Gist/Controller/ApiController.php @@ -7,6 +7,8 @@ use Symfony\Component\HttpFoundation\Request; use Gist\Model\Gist; use Symfony\Component\HttpFoundation\JsonResponse; use Gist\Form\ApiCreateGistForm; +use Gist\Model\GistQuery; +use Gist\Form\ApiUpdateGistForm; /** * Class ApiController @@ -51,6 +53,56 @@ class ApiController extends Controller return $this->invalidRequestResponse('Invalid field(s)'); } + + public function updateAction(Request $request, Application $app, $id) + { + if (false === $request->isMethod('post')) { + return $this->invalidMethodResponse('POST method is required.'); + } + + if (!ctype_digit($id)) { + return $this->invalidRequestResponse('Invalid Gist'); + } + + $gist = GistQuery::create() + ->filterByCipher(false) + ->filterById((int) $id) + ->findOne(); + + if (!$gist) { + return $this->invalidRequestResponse('Invalid Gist'); + } + + $form = new ApiUpdateGistForm( + $app['form.factory'], + $app['translator'], + [], + ['csrf_protection' => false] + ); + + $form = $form->build()->getForm(); + + $form->submit($request); + + if ($form->isValid()) { + $gist = $app['gist']->commit($gist, $form->getData()); + + $history = $app['gist']->getHistory($gist); + + return new JsonResponse(array( + 'url' => $request->getSchemeAndHttpHost().$app['url_generator']->generate( + 'view', + array( + 'gist' => $gist->getFile(), + 'commit' => array_pop($history)['commit'], + ) + ), + 'gist' => $gist->toArray(), + )); + } + + return $this->invalidRequestResponse('Invalid field(s)'); + } protected function invalidMethodResponse($message = null) { diff --git a/src/Gist/Form/ApiCreateGistForm.php b/src/Gist/Form/ApiCreateGistForm.php index 27963f5..2f022a2 100644 --- a/src/Gist/Form/ApiCreateGistForm.php +++ b/src/Gist/Form/ApiCreateGistForm.php @@ -3,7 +3,7 @@ namespace Gist\Form; /** - * Class CreateGistForm + * Class ApiCreateGistForm * @author Simon Vieille */ class ApiCreateGistForm extends CreateGistForm diff --git a/src/Gist/Form/ApiUpdateGistForm.php b/src/Gist/Form/ApiUpdateGistForm.php new file mode 100644 index 0000000..a9d21b1 --- /dev/null +++ b/src/Gist/Form/ApiUpdateGistForm.php @@ -0,0 +1,21 @@ + + */ +class ApiUpdateGistForm extends ApiCreateGistForm +{ + public function build(array $options = array()) + { + parent::build($options); + + $this->builder + ->remove('title') + ->remove('type'); + + return $this->builder; + } +}