Initial commit

pull/1/head
Joe Biellik 10 years ago
commit 89f3a86e04

@ -0,0 +1,13 @@
root = true
[*]
charset = utf-8
indent_style = tab
indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[{.eslintrc,*.json,*.yml,*.jade}]
indent_style = space
indent_size = 2

@ -0,0 +1 @@
public/vendor/**/*.js

@ -0,0 +1,11 @@
{
"env": {
"node": true,
"es6": true
},
"parser": "babel-eslint",
"rules": {
"indent": [2, "tab"],
"quotes": [2, "single", "avoid-escape"]
}
}

2
.gitattributes vendored

@ -0,0 +1,2 @@
* text=auto
* text eol=lf

2
.gitignore vendored

@ -0,0 +1,2 @@
.vagrant
node_modules

@ -0,0 +1,2 @@
# paste
Simple Node.js pastebin

38
Vagrantfile vendored

@ -0,0 +1,38 @@
$provision = <<-'EOF'
#!/bin/bash -eu
echo 'Provisioning environment...'
if [ -f /vagrant/package.json ]; then
echo -e "\tRunning 'npm install'..."
rm -rf /vagrant/node_modules
su vagrant -c 'mkdir -p /home/vagrant/node_modules'
su vagrant -c 'ln -s /home/vagrant/node_modules /vagrant/node_modules'
su vagrant -c "cd /vagrant && npm install --silent > /dev/null 2>&1"
fi
echo -e '\nFinished provisioning:\n'
printf '\tNode v%s' $(node -v | cut -d'v' -f2)
printf '\tNPM v%s' $(npm -v)
EOF
Vagrant.configure("2") do |config|
config.vm.define "paste"
config.vm.hostname = "paste"
config.vm.box = "jcbiellikltd/centos-6-node"
config.vm.provision :shell, inline: $provision
config.vm.network :forwarded_port, guest: 3000, host: 3000, auto_correct: true
config.vm.network :forwarded_port, guest: 27017, host: 27017, auto_correct: true
config.ssh.insert_key = false
config.vm.provider "virtualbox" do |v|
v.name = "paste"
v.cpus = 4
v.memory = 2048
v.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/v-root", "1"]
end
end

@ -0,0 +1,27 @@
require('babel/register');
var config = require('config');
var app = require('koa')();
var router = require('./router');
var db = require('./db')();
app.keys = config.keys;
app.proxy = true;
app.use(require('koa-logger')());
app.use(require('koa-compress')());
app.use(require('koa-static-cache')('./public', {
maxAge: config.cacheAge
}));
app.use(require('koa-body')({
multipart: true,
jsonLimit: config.sizeLimit,
formLimit: config.sizeLimit,
textLimit: config.sizeLimit
}));
app.use(require('koa-views')('./views', {
default: 'jade'
}));
app.use(router.routes(), router.allowedMethods());
module.exports = app;

@ -0,0 +1,121 @@
{
"port": 3000,
"db": "localhost/paste",
"cacheAge": 86400,
"sizeLimit": "2mb",
"prettyHtml": true,
"highlights": {
"abap": "ABAP",
"actionscript": "ActionScript",
"apacheconf": "Apache Configuration",
"apl": "APL",
"applescript": "AppleScript",
"asciidoc": "AsciiDoc",
"aspnet": "ASP.NET (C#)",
"autoit": "AutoIt",
"autohotkey": "AutoHotkey",
"bash": "Bash",
"basic": "BASIC",
"batch": "Batch",
"bison": "Bison",
"brainfuck": "Brainfuck",
"c": "C",
"clike": "C-like",
"csharp": "C#",
"cpp": "C++",
"coffeescript": "CoffeeScript",
"crystal": "Crystal",
"css": "CSS",
"css-extras": "CSS Extras",
"d": "D",
"dart": "Dart",
"diff": "Diff",
"docker": "Docker",
"eiffel": "Eiffel",
"elixir": "Elixir",
"erlang": "Erlang",
"fsharp": "F#",
"fortran": "Fortran",
"gherkin": "Gherkin",
"git": "Git",
"glsl": "GLSL",
"go": "Go",
"groovy": "Groovy",
"haml": "Haml",
"handlebars": "Handlebars",
"haskell": "Haskell",
"haxe": "Haxe",
"http": "HTTP",
"icon": "Icon",
"inform7": "Inform 7",
"ini": "Ini",
"j": "J",
"jade": "Jade",
"java": "Java",
"javascript": "JavaScript",
"julia": "Julia",
"keyman": "Keyman",
"kotlin": "Kotlin",
"latex": "LaTeX",
"less": "Less",
"lolcode": "LOLCODE",
"lua": "Lua",
"makefile": "Makefile",
"markdown": "Markdown",
"markup": "Markup",
"matlab": "MATLAB",
"mel": "MEL",
"mizar": "Mizar",
"monkey": "Monkey",
"nasm": "NASM",
"nginx": "nginx",
"nim": "Nim",
"nix": "Nix",
"nsis": "NSIS",
"objectivec": "Objective-C",
"ocaml": "OCaml",
"oz": "Oz",
"parigp": "PARI/GP",
"parser": "Parser",
"pascal": "Pascal",
"perl": "Perl",
"php": "PHP",
"php-extras": "PHP Extras",
"plain": "Plain text",
"powershell": "PowerShell",
"processing": "Processing",
"prolog": "Prolog",
"puppet": "Puppet",
"pure": "Pure",
"python": "Python",
"q": "Q",
"qore": "Qore",
"r": "R",
"jsx": "React JSX",
"rest": "reST (reStructuredText)",
"rip": "Rip",
"roboconf": "Roboconf",
"ruby": "Ruby",
"rust": "Rust",
"sas": "SAS",
"sass": "Sass (Sass)",
"scss": "Sass (Scss)",
"scala": "Scala",
"scheme": "Scheme",
"bash": "Shell",
"smalltalk": "Smalltalk",
"smarty": "Smarty",
"sql": "SQL",
"stylus": "Stylus",
"swift": "Swift",
"tcl": "Tcl",
"textile": "Textile",
"twig": "Twig",
"typescript": "TypeScript",
"verilog": "Verilog",
"vhdl": "VHDL",
"vim": "vim",
"wiki": "Wiki markup",
"yaml": "YAML"
}
}

@ -0,0 +1,52 @@
var config = require('config');
var Paste = require('../models/paste');
module.exports = {
*view(next) {
try {
let paste = yield Paste.findOne({ link: this.params.id }).exec();
let lang = Object.keys(this.query)[0];
if (lang) {
yield this.render('highlight', {
pretty: config.prettyHtml,
title: 'Paste ' + paste.link,
paste: paste.paste,
lang: lang
});
} else {
this.type = 'text/plain';
this.body = paste.paste;
}
} catch (ex) {
this.throw('Paste Not Found', 404);
}
},
*create(next) {
if (this.request.body.fields && this.request.body.fields.paste) {
this.request.body.paste = this.request.body.fields.paste;
}
if (this.request.body.fields && this.request.body.fields.highlight) {
this.request.body.highlight = this.request.body.fields.highlight;
}
let paste = new Paste({
paste: this.request.body.paste
});
yield paste.save();
let link = paste.link;
if (this.request.body.highlight) {
link += '?' + this.request.body.highlight;
}
if (Object.keys(this.query).includes('redirect')) {
this.redirect(link);
} else {
this.body = this.request.origin + '/' + link + '\n';
}
}
};

15
db.js

@ -0,0 +1,15 @@
var config = require('config');
var util = require('util');
var mongoose = require('mongoose');
module.exports = function () {
mongoose.connect(config.db);
mongoose.connection.once('open', function () {
util.log('MongoDB connection open');
});
mongoose.connection.on('error', console.error.bind(console, 'MongoDB connection error:'));
return mongoose.connection;
}

@ -0,0 +1,9 @@
db:
image: mongo:latest
command: "--smallfiles"
hostname: "db"
container_name: "db"
ports:
- "27017:27017"
volumes:
- ~/mongo:/data/db

@ -0,0 +1,19 @@
var mongoose = require('mongoose');
var shortId = require('short-mongo-id');
var paste = new mongoose.Schema({
paste: { type: String },
link: { type: String }
}, {
timestamps: true
});
paste.pre('save', function(next) {
if (this.isNew) {
this.link = shortId(this._id);
next();
}
});
module.exports = mongoose.model('Paste', paste);

@ -0,0 +1,45 @@
{
"name": "paste",
"version": "1.0.0",
"description": "Simple Node.js pastebin",
"license": "MIT",
"repository": "JoeBiellik/paste",
"homepage": "https://github.com/JoeBiellik/paste",
"author": "Joe Biellik <contact@joebiellik.com> (http://joebiellik.com/)",
"bugs": {
"email": "contact@joebiellik.com",
"url": "https://github.com/JoeBiellik/paste/issues"
},
"keywords": [
"pastebin",
"paste",
"node",
"koa",
"mongodb"
],
"main": "server.js",
"scripts": {
"start": "node .",
"watch": "./node_modules/.bin/nodemon -L -e js,json",
"lint": "./node_modules/.bin/eslint ."
},
"dependencies": {
"babel": "^5.8.23",
"config": "^1.16.0",
"jade": "^1.11.0",
"koa": "^1.1.0",
"koa-body": "^1.3.0",
"koa-compress": "^1.0.8",
"koa-logger": "^1.3.0",
"koa-router": "^5.2.3",
"koa-static-cache": "^3.1.2",
"koa-views": "^3.1.0",
"mongoose": "^4.1.12",
"short-mongo-id": "^0.1.1"
},
"devDependencies": {
"babel-eslint": "^4.1.3",
"eslint": "^1.7.2",
"nodemon": "^1.7.2"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

@ -0,0 +1,57 @@
/* http://prismjs.com/plugins/line-numbers/prism-line-numbers.js */
(function() {
if (typeof self === 'undefined' || !self.Prism || !self.document) {
return;
}
Prism.hooks.add('complete', function (env) {
if (!env.code) {
return;
}
// works only for <code> wrapped inside <pre> (not inline)
var pre = env.element.parentNode;
var clsReg = /\s*\bline-numbers\b\s*/;
if (
!pre || !/pre/i.test(pre.nodeName) ||
// Abort only if nor the <pre> nor the <code> have the class
(!clsReg.test(pre.className) && !clsReg.test(env.element.className))
) {
return;
}
if (env.element.querySelector(".line-numbers-rows")) {
// Abort if line numbers already exists
return;
}
if (clsReg.test(env.element.className)) {
// Remove the class "line-numbers" from the <code>
env.element.className = env.element.className.replace(clsReg, '');
}
if (!clsReg.test(pre.className)) {
// Add the class "line-numbers" to the <pre>
pre.className += ' line-numbers';
}
var match = env.code.match(/\n(?!$)/g);
var linesNum = match ? match.length + 1 : 1;
var lineNumbersWrapper;
var lines = new Array(linesNum + 1);
lines = lines.join('<span></span>');
lineNumbersWrapper = document.createElement('span');
lineNumbersWrapper.className = 'line-numbers-rows';
lineNumbersWrapper.innerHTML = lines;
if (pre.hasAttribute('data-start')) {
pre.style.counterReset = 'linenumber ' + (parseInt(pre.getAttribute('data-start'), 10) - 1);
}
env.element.appendChild(lineNumbersWrapper);
});
}());

@ -0,0 +1,288 @@
/* http://prismjs.com/download.html?themes=prism-coy&languages=markup+css+clike+javascript+abap+actionscript+apacheconf+apl+applescript+asciidoc+aspnet+autoit+autohotkey+bash+basic+batch+c+brainfuck+bison+csharp+cpp+coffeescript+ruby+css-extras+d+dart+diff+docker+eiffel+elixir+erlang+fsharp+fortran+gherkin+git+glsl+go+groovy+haml+handlebars+haskell+haxe+http+icon+inform7+ini+j+jade+java+julia+keyman+kotlin+latex+less+lolcode+lua+makefile+markdown+matlab+mel+mizar+monkey+nasm+nginx+nim+nix+nsis+objectivec+ocaml+oz+parigp+parser+pascal+perl+php+php-extras+powershell+processing+prolog+puppet+pure+python+q+qore+r+jsx+rest+rip+roboconf+crystal+rust+sas+sass+scss+scala+scheme+smalltalk+smarty+sql+stylus+swift+tcl+textile+twig+typescript+verilog+vhdl+vim+wiki+yaml&plugins=line-numbers */
/**
* prism.js Coy theme for JavaScript, CoffeeScript, CSS and HTML
* Based on https://github.com/tshedor/workshop-wp-theme (Example: http://workshop.kansan.com/category/sessions/basics or http://workshop.timshedor.com/category/sessions/basics);
* @author Tim Shedor
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
direction: ltr;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
/* Code blocks */
pre[class*="language-"] {
position: relative;
margin: .5em 0;
-webkit-box-shadow: -1px 0px 0px 0px #358ccb, 0px 0px 0px 1px #dfdfdf;
-moz-box-shadow: -1px 0px 0px 0px #358ccb, 0px 0px 0px 1px #dfdfdf;
box-shadow: -1px 0px 0px 0px #358ccb, 0px 0px 0px 1px #dfdfdf;
border-left: 10px solid #358ccb;
background-color: #fdfdfd;
background-image: -webkit-linear-gradient(transparent 50%, rgba(69, 142, 209, 0.04) 50%);
background-image: -moz-linear-gradient(transparent 50%, rgba(69, 142, 209, 0.04) 50%);
background-image: -ms-linear-gradient(transparent 50%, rgba(69, 142, 209, 0.04) 50%);
background-image: -o-linear-gradient(transparent 50%, rgba(69, 142, 209, 0.04) 50%);
background-image: linear-gradient(transparent 50%, rgba(69, 142, 209, 0.04) 50%);
background-size: 3em 3em;
background-origin: content-box;
overflow: visible;
max-height: 30em;
padding: 0;
}
code[class*="language"] {
max-height: inherit;
height: 100%;
padding: 0 1em;
display: block;
overflow: auto;
}
/* Margin bottom to accomodate shadow */
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background-color: #fdfdfd;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
margin-bottom: 1em;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
position: relative;
padding: .2em;
-webkit-border-radius: 0.3em;
-moz-border-radius: 0.3em;
-ms-border-radius: 0.3em;
-o-border-radius: 0.3em;
border-radius: 0.3em;
color: #c92c2c;
border: 1px solid rgba(0, 0, 0, 0.1);
display: inline;
white-space: normal;
}
pre[class*="language-"]:before,
pre[class*="language-"]:after {
content: '';
z-index: -2;
display: block;
position: absolute;
bottom: 0.75em;
left: 0.18em;
width: 40%;
height: 20%;
-webkit-box-shadow: 0px 13px 8px #979797;
-moz-box-shadow: 0px 13px 8px #979797;
box-shadow: 0px 13px 8px #979797;
-webkit-transform: rotate(-2deg);
-moz-transform: rotate(-2deg);
-ms-transform: rotate(-2deg);
-o-transform: rotate(-2deg);
transform: rotate(-2deg);
}
:not(pre) > code[class*="language-"]:after,
pre[class*="language-"]:after {
right: 0.75em;
left: auto;
-webkit-transform: rotate(2deg);
-moz-transform: rotate(2deg);
-ms-transform: rotate(2deg);
-o-transform: rotate(2deg);
transform: rotate(2deg);
}
.token.comment,
.token.block-comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: #7D8B99;
}
.token.punctuation {
color: #5F6364;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.function-name,
.token.constant,
.token.symbol,
.token.deleted {
color: #c92c2c;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.function,
.token.builtin,
.token.inserted {
color: #2f9c0a;
}
.token.operator,
.token.entity,
.token.url,
.token.variable {
color: #a67f59;
background: rgba(255, 255, 255, 0.5);
}
.token.atrule,
.token.attr-value,
.token.keyword,
.token.class-name {
color: #1990b8;
}
.token.regex,
.token.important {
color: #e90;
}
.language-css .token.string,
.style .token.string {
color: #a67f59;
background: rgba(255, 255, 255, 0.5);
}
.token.important {
font-weight: normal;
}
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
.namespace {
opacity: .7;
}
@media screen and (max-width: 767px) {
pre[class*="language-"]:before,
pre[class*="language-"]:after {
bottom: 14px;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
}
/* Plugin styles */
.token.tab:not(:empty):before,
.token.cr:before,
.token.lf:before {
color: #e0d7d1;
}
/* Plugin styles: Line Numbers */
pre[class*="language-"].line-numbers {
padding-left: 0;
}
pre[class*="language-"].line-numbers code {
padding-left: 3.8em;
}
pre[class*="language-"].line-numbers .line-numbers-rows {
left: 0;
}
/* Plugin styles: Line Highlight */
pre[class*="language-"][data-line] {
padding-top: 0;
padding-bottom: 0;
padding-left: 0;
}
pre[data-line] code {
position: relative;
padding-left: 4em;
}
pre .line-highlight {
margin-top: 0;
}
pre.line-numbers {
position: relative;
padding-left: 3.8em;
counter-reset: linenumber;
}
pre.line-numbers > code {
position: relative;
}
.line-numbers .line-numbers-rows {
position: absolute;
pointer-events: none;
top: 0;
font-size: 100%;
left: -3.8em;
width: 3em; /* works for line-numbers below 1000 lines */
letter-spacing: -1px;
border-right: 1px solid #999;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.line-numbers-rows > span {
pointer-events: none;
display: block;
counter-increment: linenumber;
}
.line-numbers-rows > span:before {
content: counter(linenumber);
color: #999;
display: block;
padding-right: 0.8em;
text-align: right;
}
pre[class*="language-"] {
margin: 0;
box-shadow: none;
max-height: none;
border-left: none;
}
pre[class*="language-"]::before, pre[class*="language-"]::after {
box-shadow: none;
display: none;
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,17 @@
var router = require('koa-router')();
var config = require('config');
var pastes = require('./controllers/pastes');
router.get('/', function *() {
yield this.render('index', {
pretty: config.prettyHtml,
title: 'Paste',
url: this.request.origin + '/',
highlights: config.highlights
});
});
router.post('/', pastes.create);
router.get('/:id', pastes.view);
module.exports = router;

@ -0,0 +1,7 @@
var app = require('./app');
var config = require('config');
var util = require('util');
module.exports = app.listen(process.env.PORT || config.port || 3000, function() {
util.log('Server started: http://localhost:%s/', this.address().port);
});

@ -0,0 +1,11 @@
extends layout
block head
link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha/css/bootstrap.min.css')
link(rel='stylesheet', href='/vendor/prism.css')
block content
pre.line-numbers
code(class='language-#{lang}')
| #{paste}
script(src='/vendor/prism.js')
script(src='/vendor/prism-line-numbers.js')

@ -0,0 +1,47 @@
extends layout
block head
link(rel='stylesheet', href='http://fonts.googleapis.com/css?family=Open+Sans:400,300,600')
link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha/css/bootstrap.min.css')
style.
html {
position: relative;
min-height: 100%;
}
body {
font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
margin-bottom: 60px;
}
textarea, textarea:required, textarea:invalid {
font-family: monospace, serif;
box-shadow: none;
}
footer {
width: 100%;
height: 35px;
position: absolute;
bottom: 0;
line-height: 35px;
}
block content
main.container.m-t-lg
h1.display-3.m-b-lg #{title}
a(href='https://github.com/JoeBiellik/paste')
img(style='position: absolute; top: 0; right: 0; border: 0;', src='https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png', alt='Fork me on GitHub')
form(action='/?redirect', method='POST', accept-charset='UTF-8')
fieldset.form-group
textarea.form-control(name='paste', rows='5', required, autofocus)
select.c-select.select-lg.m-t-md(name='highlight')
option(value='', selected) Choose syntax highlighting
each val, key in highlights
option(value='#{key}') #{val}
button.btn.btn-primary.btn-lg.m-t-md.m-l-md.pull-right(type='submit') Upload
footer.hidden-sm-down
pre.text-center.text-muted.m-b-0.
echo 'Hello World' | curl -F 'paste=&lt;-' #{url}
script(src='https://cdnjs.cloudflare.com/ajax/libs/autosize.js/3.0.13/autosize.min.js')
script.
autosize(document.querySelector('textarea'));

@ -0,0 +1,9 @@
doctype html
html(lang='en')
head
meta(http-equiv='Content-Type', content='text/html; charset=utf-8')
title #{title}
block head
body
block content
Loading…
Cancel
Save