1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-18 21:02:41 +01:00
Summary:
This is Paste. It needs some work, but epriestley recommended that I just commit something that works, and expand on that later.

Specifically, it lacks the ability to view a raw paste right now, and to turn off line numbers, making it hard to copy/paste from for now. It works for showing other people code, however.

Test Plan:
Pasted stuff, and was able to view it, and see it in the list on /paste/. Put a file extension in the title, and saw that syntax highlighting worked as expected.

Reviewers:
epriestley

CC:

Differential Revision: 424
This commit is contained in:
Ricky Elrod 2011-06-10 02:53:53 -04:00
parent 8bddade834
commit b9c9f90164
15 changed files with 469 additions and 12 deletions

View file

@ -0,0 +1,17 @@
CREATE DATABASE phabricator_pastebin;
CREATE TABLE phabricator_pastebin.pastebin_paste (
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
phid VARCHAR(64) BINARY NOT NULL,
authorPHID VARCHAR(64) BINARY NOT NULL,
filePHID VARCHAR(64) BINARY NOT NULL,
dateCreated INT UNSIGNED NOT NULL,
dateModified INT UNSIGNED NOT NULL
);
INSERT INTO phabricator_directory.directory_item
(name, description, href, categoryID, sequence, dateCreated, dateModified)
VALUES
("Paste", "Mmm... tasty, delicious paste.", "/paste/", 5, 150,
UNIX_TIMESTAMP(), UNIX_TIMESTAMP());

View file

@ -398,6 +398,12 @@ phutil_register_library_map(array(
'PhabricatorPHIDDAO' => 'applications/phid/storage/base', 'PhabricatorPHIDDAO' => 'applications/phid/storage/base',
'PhabricatorPHIDListController' => 'applications/phid/controller/list', 'PhabricatorPHIDListController' => 'applications/phid/controller/list',
'PhabricatorPHIDLookupController' => 'applications/phid/controller/lookup', 'PhabricatorPHIDLookupController' => 'applications/phid/controller/lookup',
'PhabricatorPaste' => 'applications/paste/storage/paste',
'PhabricatorPasteController' => 'applications/paste/controller/base',
'PhabricatorPasteCreateController' => 'applications/paste/controller/create',
'PhabricatorPasteDAO' => 'applications/paste/storage/base',
'PhabricatorPasteHomeController' => 'applications/paste/controller/home',
'PhabricatorPasteViewController' => 'applications/paste/controller/view',
'PhabricatorPeopleController' => 'applications/people/controller/base', 'PhabricatorPeopleController' => 'applications/people/controller/base',
'PhabricatorPeopleEditController' => 'applications/people/controller/edit', 'PhabricatorPeopleEditController' => 'applications/people/controller/edit',
'PhabricatorPeopleListController' => 'applications/people/controller/list', 'PhabricatorPeopleListController' => 'applications/people/controller/list',
@ -840,6 +846,12 @@ phutil_register_library_map(array(
'PhabricatorPHIDDAO' => 'PhabricatorLiskDAO', 'PhabricatorPHIDDAO' => 'PhabricatorLiskDAO',
'PhabricatorPHIDListController' => 'PhabricatorPHIDController', 'PhabricatorPHIDListController' => 'PhabricatorPHIDController',
'PhabricatorPHIDLookupController' => 'PhabricatorPHIDController', 'PhabricatorPHIDLookupController' => 'PhabricatorPHIDController',
'PhabricatorPaste' => 'PhabricatorPasteDAO',
'PhabricatorPasteController' => 'PhabricatorController',
'PhabricatorPasteCreateController' => 'PhabricatorPasteController',
'PhabricatorPasteDAO' => 'PhabricatorLiskDAO',
'PhabricatorPasteHomeController' => 'PhabricatorPasteController',
'PhabricatorPasteViewController' => 'PhabricatorPasteController',
'PhabricatorPeopleController' => 'PhabricatorController', 'PhabricatorPeopleController' => 'PhabricatorController',
'PhabricatorPeopleEditController' => 'PhabricatorPeopleController', 'PhabricatorPeopleEditController' => 'PhabricatorPeopleController',
'PhabricatorPeopleListController' => 'PhabricatorPeopleController', 'PhabricatorPeopleListController' => 'PhabricatorPeopleController',

View file

@ -305,6 +305,13 @@ class AphrontDefaultApplicationConfiguration
'/status/$' => 'PhabricatorStatusController', '/status/$' => 'PhabricatorStatusController',
'/paste/' => array(
'$' => 'PhabricatorPasteHomeController',
'create/' => 'PhabricatorPasteCreateController',
),
'/P(?P<id>\d+)$' => 'PhabricatorPasteViewController',
'/help/' => array( '/help/' => array(
'keyboardshortcut/$' => 'PhabricatorHelpKeyboardShortcutController', 'keyboardshortcut/$' => 'PhabricatorHelpKeyboardShortcutController',
), ),

View file

@ -0,0 +1,44 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
abstract class PhabricatorPasteController extends PhabricatorController {
public function buildStandardPageResponse($view, array $data) {
$page = $this->buildStandardPageView();
$page->setApplicationName('Paste');
$page->setBaseURI('/paste/');
$page->setTitle(idx($data, 'title'));
$page->setGlyph("\xE2\x9C\x8E");
$page->setTabs(
array(
'create' => array(
'href' => '/paste/create',
'name' => 'Create a Paste',
),
),
idx($data, 'tab'));
$page->appendChild($view);
$response = new AphrontWebpageResponse();
return $response->setContent($page->render());
}
}

View file

@ -22,6 +22,43 @@ class PhabricatorPasteCreateController extends PhabricatorPasteController {
$request = $this->getRequest(); $request = $this->getRequest();
$user = $request->getUser(); $user = $request->getUser();
$paste = new PhabricatorPaste();
$error_view = null;
$e_text = true;
if ($request->isFormPost()) {
$errors = array();
$title = $request->getStr('title');
$text = $request->getStr('text');
if (!strlen($text)) {
$e_text = 'Required';
$errors[] = 'The paste may not be blank.';
} else {
$e_text = null;
}
$paste->setTitle($title);
if (!$errors) {
$paste_file = PhabricatorFile::newFromFileData(
$text,
array(
'name' => $title,
));
$paste->setFilePHID($paste_file->getPHID());
$paste->setAuthorPHID($user->getPHID());
$paste->save();
return id(new AphrontRedirectResponse())
->setURI('/P'.$paste->getID());
} else {
$error_view = new AphrontErrorView();
$error_view->setErrors($errors);
$error_view->setTitle('A problem has occurred!');
}
}
$form = new AphrontFormView(); $form = new AphrontFormView();
$form $form
@ -30,26 +67,31 @@ class PhabricatorPasteCreateController extends PhabricatorPasteController {
->appendChild( ->appendChild(
id(new AphrontFormTextControl()) id(new AphrontFormTextControl())
->setLabel('Title') ->setLabel('Title')
->setValue($paste->getTitle())
->setName('title')) ->setName('title'))
->appendChild( ->appendChild(
id(new AphrontFormTextAreaControl()) id(new AphrontFormTextAreaControl())
->setLabel('Text') ->setLabel('Text')
->setError($e_text)
->setName('text')) ->setName('text'))
->appendChild( ->appendChild(
id(new AphrontFormSubmitControl()) id(new AphrontFormSubmitControl())
->addCancelButton('/paste/') ->addCancelButton('/paste/')
->setValue('Create Paste')); ->setValue('Create Paste'));
$panel = new AphrontPanelView(); $panel = new AphrontPanelView();
$panel->setWidth(AphrontPanelView::WIDTH_FULL); $panel->setWidth(AphrontPanelView::WIDTH_FORM);
$panel->setHeader("Create a Paste"); $panel->setHeader('Create a Paste');
$panel->appendChild($form); $panel->appendChild($form);
return $this->buildStandardPageResponse( return $this->buildStandardPageResponse(
$panel, array(
$error_view,
$panel,
),
array( array(
'title' => 'Paste Creation', 'title' => 'Paste Creation',
'tab' => 'create', 'tab' => 'create',
)); ));
} }
} }

View file

@ -6,7 +6,18 @@
phutil_require_module('phabricator', 'aphront/response/redirect');
phutil_require_module('phabricator', 'applications/files/storage/file');
phutil_require_module('phabricator', 'applications/paste/controller/base'); phutil_require_module('phabricator', 'applications/paste/controller/base');
phutil_require_module('phabricator', 'applications/paste/storage/paste');
phutil_require_module('phabricator', 'view/form/base');
phutil_require_module('phabricator', 'view/form/control/submit');
phutil_require_module('phabricator', 'view/form/control/text');
phutil_require_module('phabricator', 'view/form/control/textarea');
phutil_require_module('phabricator', 'view/form/error');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorPasteCreateController.php'); phutil_require_source('PhabricatorPasteCreateController.php');

View file

@ -19,11 +19,83 @@
class PhabricatorPasteHomeController extends PhabricatorPasteController { class PhabricatorPasteHomeController extends PhabricatorPasteController {
public function processRequest() { public function processRequest() {
$request = $this->getRequest();
$pager = new AphrontPagerView();
$pager->setOffset($request->getInt('page'));
$pastes = id(new PhabricatorPaste())->loadAllWhere(
'1 = 1 ORDER BY id DESC LIMIT %d, %d',
$pager->getOffset(),
$pager->getPageSize() + 1);
$pastes = $pager->sliceResults($pastes);
$pager->setURI($request->getRequestURI(), 'page');
$phids = mpull($pastes, 'getAuthorPHID');
$handles = array();
if ($phids) {
$handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
}
$rows = array();
foreach ($pastes as $paste) {
$handle = $handles[$paste->getAuthorPHID()];
$rows[] = array(
phutil_escape_html($paste->getPHID()),
phutil_escape_html($paste->getTitle()),
// TODO: Make this filter by user instead of going to their profile.
phutil_render_tag(
'a',
array(
'href' => '/p/'.$handle->getName().'/',
),
phutil_escape_html($handle->getName())),
phutil_render_tag(
'a',
array(
'href' => PhabricatorFileURI::getViewURIForPHID(
$paste->getFilePHID()),
),
phutil_escape_html($paste->getFilePHID())),
phutil_render_tag(
'a',
array(
'class' => 'small button grey',
'href' => '/P'.$paste->getID(),
),
'View'),
);
}
$table = new AphrontTableView($rows);
$table->setHeaders(
array(
'PHID',
'Title',
'Author',
'File PHID',
'View'
));
$panel = new AphrontPanelView();
$panel->setWidth(AphrontPanelView::WIDTH_FULL);
$panel->setHeader("Paste");
$panel->setCreateButton('Paste Something', '/paste/create/');
$panel->appendChild($table);
$panel->appendChild($pager);
return $this->buildStandardPageResponse( return $this->buildStandardPageResponse(
null, $panel,
array( array(
'title' => 'Paste', 'title' => 'Paste',
'tab' => 'home', )
)); );
} }
} }

View file

@ -6,7 +6,16 @@
phutil_require_module('phabricator', 'applications/files/uri');
phutil_require_module('phabricator', 'applications/paste/controller/base'); phutil_require_module('phabricator', 'applications/paste/controller/base');
phutil_require_module('phabricator', 'applications/paste/storage/paste');
phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phabricator', 'view/control/pager');
phutil_require_module('phabricator', 'view/control/table');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorPasteHomeController.php'); phutil_require_source('PhabricatorPasteHomeController.php');

View file

@ -0,0 +1,130 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class PhabricatorPasteViewController extends PhabricatorPasteController {
private $id;
public function willProcessRequest(array $data) {
$this->id = $data['id'];
}
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$paste = id(new PhabricatorPaste())->load($this->id);
if (!$paste) {
return new Aphront404Response();
}
$file = id(new PhabricatorFile())->loadOneWhere(
'phid = %s',
$paste->getFilePHID());
if (!$file) {
return new Aphront400Response();
}
$corpus = $this->buildCorpus($paste, $file);
/* TODO
$raw_button = phutil_render_tag(
'a',
array(
'class' => 'small button grey',
'href' => '/P'.$paste->getId().'/raw/',
),
'Raw Paste');
*/
$panel = new AphrontPanelView();
if (strlen($paste->getTitle())) {
$panel->setHeader(
'Viewing Paste '.$paste->getID().' - '.
phutil_escape_html($paste->getTitle()));
} else {
$panel->setHeader('Viewing Paste '.$paste->getID());
}
$panel->setWidth(AphrontPanelView::WIDTH_FULL);
$panel->setCreateButton('Paste Something', '/paste/create/');
$panel->appendChild($corpus);
// $panel->appendChild($raw_button);
return $this->buildStandardPageResponse(
$panel,
array(
'title' => 'Viewing Paste '.$this->id,
'tab' => 'view',
));
}
private function buildCorpus($paste, $file) {
// Blantently copied from DiffusionBrowseFileController
require_celerity_resource('diffusion-source-css');
require_celerity_resource('syntax-highlighting-css');
$highlightEngine = new PhutilDefaultSyntaxHighlighterEngine();
$highlightEngine->setConfig(
'pygments.enabled',
PhabricatorEnv::getEnvConfig('pygments.enabled'));
$text_list = explode(
"\n", $highlightEngine->highlightSource(
$paste->getTitle(),
$file->loadFileData()));
$rows = $this->buildDisplayRows($text_list);
$corpus_table = phutil_render_tag(
'table',
array(
'class' => "diffusion-source remarkup-code PhabricatorMonospaced",
),
implode("\n", $rows));
$corpus = phutil_render_tag(
'div',
array(
'style' => 'padding: 0pt 2em;',
),
$corpus_table);
return $corpus;
}
private function buildDisplayRows($text_list) {
$rows = array();
$n = 1;
foreach ($text_list as $k => $line) {
// Pardon the ugly for the time being.
// And eventually this will highlight a line that you click
// like diffusion does. Or maybe allow for line comments
// like differential. Either way it will be better than it is now.
$rows[] = '<tr><th>'.$n.'</th><td>'.$line.'</td></tr>';
++$n;
}
return $rows;
}
}

View file

@ -0,0 +1,23 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'aphront/response/400');
phutil_require_module('phabricator', 'aphront/response/404');
phutil_require_module('phabricator', 'applications/files/storage/file');
phutil_require_module('phabricator', 'applications/paste/controller/base');
phutil_require_module('phabricator', 'applications/paste/storage/paste');
phutil_require_module('phabricator', 'infrastructure/celerity/api');
phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'markup/syntax/engine/default');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorPasteViewController.php');

View file

@ -0,0 +1,25 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
abstract class PhabricatorPasteDAO extends PhabricatorLiskDAO {
public function getApplicationName() {
return 'pastebin';
}
}

View file

@ -0,0 +1,12 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/base/storage/lisk');
phutil_require_source('PhabricatorPasteDAO.php');

View file

@ -0,0 +1,37 @@
<?php
/*
* Copyright 2011 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class PhabricatorPaste extends PhabricatorPasteDAO {
protected $phid;
protected $title;
protected $authorPHID;
protected $filePHID;
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorPHIDConstants::PHID_TYPE_PSTE);
}
}

View file

@ -0,0 +1,14 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/paste/storage/base');
phutil_require_module('phabricator', 'applications/phid/constants');
phutil_require_module('phabricator', 'applications/phid/storage/phid');
phutil_require_source('PhabricatorPaste.php');

View file

@ -29,6 +29,7 @@ final class PhabricatorPHIDConstants {
const PHID_TYPE_REPO = 'REPO'; const PHID_TYPE_REPO = 'REPO';
const PHID_TYPE_CMIT = 'CMIT'; const PHID_TYPE_CMIT = 'CMIT';
const PHID_TYPE_OPKG = 'OPKG'; const PHID_TYPE_OPKG = 'OPKG';
const PHID_TYPE_PSTE = 'PSTE';
public static function getTypes() { public static function getTypes() {
return array( return array(
@ -42,6 +43,7 @@ final class PhabricatorPHIDConstants {
self::PHID_TYPE_MAGIC, self::PHID_TYPE_MAGIC,
self::PHID_TYPE_REPO, self::PHID_TYPE_REPO,
self::PHID_TYPE_CMIT, self::PHID_TYPE_CMIT,
self::PHID_TYPE_PSTE,
); );
} }
} }