1
0
mirror of https://github.com/Tygs/0bin.git synced 2023-08-10 21:13:00 +03:00

55 Commits

Author SHA1 Message Date
sametmax
dcefd57875 Bumping version 2013-03-19 12:02:30 +01:00
sametmax
ff60fa9a3c Merge pull request #34 from lyda/misspellings
Misspelling check.
2013-03-05 16:20:18 -08:00
Kevin Lyda
d599aed09a Misspelling check.
Fixed the spelling using the following command:

  misspellings -s fix.sh $(find * -type f)
  sh fix.sh

Nothing very important, just was using it for a quick test.
2013-03-03 16:27:39 +00:00
sametmax
9a0efa7fa7 Merge pull request #30 from Natim/12_shorten_url_for_email_this
[CopyToClipboard] If there is no coloration, use the decrypted content
2013-01-31 07:31:15 -08:00
Rémy HUBSCHER
fb957f8cde If there is no coloration, use the decrypted content 2013-01-31 14:00:53 +01:00
sametmax
1e3a9e227d Merge pull request #27 from Natim/12_shorten_url_for_email_this
#12 - Problem for encoding URL when sending mail
2013-01-31 03:08:34 -08:00
Rémy HUBSCHER
ab9ef15de2 #12 - Problem for encoding URL when sending mail 2013-01-31 12:05:48 +01:00
sametmax
0c1bcfdc87 Merge pull request #17 from Natim/master
Display bin image file as image.
2013-01-31 02:25:40 -08:00
Rémy HUBSCHER
b241b86125 Fix w3c validation 2013-01-24 10:59:25 +01:00
Rémy HUBSCHER
6170665e1c dry e.preventDefault to minimum 2013-01-24 10:51:49 +01:00
Rémy HUBSCHER
6fffdc0371 Merge 18_shorten_over_https 2013-01-24 09:55:48 +01:00
Rémy HUBSCHER
2b9bf81fcd Merge 12_shorten_url_for_email_this 2013-01-24 09:53:04 +01:00
Rémy HUBSCHER
b729a678ea #21 - Resize too big images before upload 2013-01-19 19:40:44 +01:00
Rémy HUBSCHER
d57595297e Merge #19 fix 2013-01-19 18:54:51 +01:00
Rémy HUBSCHER
0cfd685e8c Read the request.body to prevent bottle from cutting it. 2013-01-19 18:50:07 +01:00
Rémy HUBSCHER
82ea02a60c Refs #12 - Shorten url before to actually send a mail 2013-01-19 18:32:06 +01:00
Rémy HUBSCHER
28bff88784 #18 - It is better to shorten URL over SSH since there is the encryption key - futhermore if you run 0bin over SSH. 2013-01-19 18:13:40 +01:00
Rémy HUBSCHER
b5de896ef6 #16 - When displaying an image add a download button 2013-01-19 17:48:04 +01:00
Rémy HUBSCHER
74bfee09c8 #17 - Add drag and drop file support. On the upload of an image, display it. 2013-01-19 17:05:37 +01:00
Rémy HUBSCHER
0879a8556e #17 - Detect images and display them as image files 2013-01-19 12:37:39 +01:00
Rémy HUBSCHER
b2a9812688 #17 - Add html5 file drag&drop on textarea 2013-01-19 11:31:03 +01:00
sametmax
303905aff5 Fixed grammar error 2012-10-07 15:33:46 +02:00
sametmax
451a282684 Improved comments handling in code detection 2012-09-07 17:07:53 +02:00
sametmax
8e318c768b Bumping version 2012-08-07 12:52:43 +02:00
sametmax
54e9098999 Fixing non breakable space insertion 2012-08-07 12:38:06 +02:00
sam
a045de73d1 Going back to a very simple 'send by email' link since the previous attempt didn't work as expected 2012-05-24 14:41:26 +02:00
sam
419f618a30 Typos 2012-05-23 18:46:18 +02:00
sam
72fc5d4646 Improved error handling on emai link 2012-05-23 16:20:46 +02:00
sametmax
16f3e2e474 Merge pull request #9 from dorey/email-links
allows quick-sending of email links.
2012-05-23 01:38:46 -07:00
dorey
60ddbf49c6 minimal javascript to automatically open up an email message (tested and works in chrome,ff when a mailto client is available.) 2012-05-23 01:52:20 -04:00
sam
6959fcbed9 Fix timedelta.in_seconds support in python 2.6 2012-05-22 20:11:38 +02:00
sam
d12718d9dd Expiration date is now displayed for each paste 2012-05-22 19:58:23 +02:00
sam
7b8108ea6b Try code detection, and if detected has plain text,, do not apply code coloration 2012-05-22 19:10:54 +02:00
sam
a824bc2a21 Expired pastes are removed from localStorage 2012-05-22 17:40:57 +02:00
sam
470194806e Make local storage format version decouple from 0bin version 2012-05-22 14:47:24 +02:00
sam
6860778f47 Prevent 0bin to crash if the locale formatting is not supported. Moved get_pastes_count into the Paste class. Added 0bin version as query parameter in the scrip and css tags URL 2012-05-22 14:39:34 +02:00
max
780c50f971 merging 2012-05-22 18:48:24 +07:00
max
02a5aa6cf6 Merging counter 2012-05-22 18:44:51 +07:00
sam
2b9a70c19b Recompressed static 2012-05-22 13:40:58 +02:00
sam
22774feb8f Changed short url provider 2012-05-22 13:40:17 +02:00
sam
dc4e482bb2 Added licence to readme 2012-05-22 12:49:12 +02:00
sam
7703b26333 Improved url sanitizing 2012-05-22 12:45:44 +02:00
sametmax
14b0b37bfb Merge pull request #8 from antoinec/br-fix
Fix typo on </br>
2012-05-22 02:46:58 -07:00
sametmax
84268bc2fe Merge pull request #7 from antoinec/pullrequest-4-fixed
Pullrequest #4 fixed
2012-05-22 02:44:50 -07:00
dorey
e584338776 allows quick-sending of email links. (#2) 2012-05-22 03:10:13 -04:00
Antoine Catton
8cb5457467 Add wrap-content end tag. 2012-05-21 20:00:48 +02:00
sam
f9e4f4acc0 Typo 2012-05-21 18:06:50 +02:00
sam
111255352c Improved FAQ 2012-05-21 18:01:52 +02:00
sam
fb60e4e332 Added pastebin article to FAQ 2012-05-21 13:38:53 +02:00
sam
c96e8b6006 Typo 2012-05-21 13:21:16 +02:00
sam
2b35351aeb Merge branch 'master' of sametmax-github:sametmax/0bin 2012-05-21 13:17:16 +02:00
sam
e83a7d6a58 Added a FAQ 2012-05-21 13:16:49 +02:00
max
3a07efeec0 Added faq 2012-05-21 17:44:21 +07:00
max
d72f60405a Added faq 2012-05-21 17:42:47 +07:00
Antoine Catton
6cfd005c98 Fix typo on </br> 2012-05-21 11:15:31 +02:00
30 changed files with 967 additions and 661 deletions

View File

@@ -11,7 +11,7 @@ be pasted in it. The idea is that one can (probably...) not be legally entitled
to `moderate the pastebin content`_ as he/she has no way to decrypt it.
It's an Python implementation of the
`zerobin project`_. It's easy to
`zerobin project`_ under the `WTF licence`_. It's easy to
install even if you know nothing about Python.
For now tested with IE9, and the last opera, safari, chrome and FF.
@@ -57,7 +57,7 @@ Other features
- copy paste to clipboard in a click;
- get paste short URL in a click;
- own previous pastes history;
- visual hash of a paste to easily tell it appart from others in a list.
- visual hash of a paste to easily tell it apart from others in a list.
Technologies used
==================
@@ -96,4 +96,5 @@ What does 0bin not implement?
.. _Bootstrap: http://twitter.github.com/bootstrap/
.. _VizHash.js: https://github.com/sametmax/VizHash.js
.. _Cherrypy: http://www.cherrypy.org/ (server only)
.. _is not worth it: http://stackoverflow.com/questions/201705/how-many-random-elements-before-md5-produces-collisions
.. _is not worth it: http://stackoverflow.com/questions/201705/how-many-random-elements-before-md5-produces-collisions
.. _WTF licence: http://en.wikipedia.org/wiki/WTFPL

View File

@@ -16,7 +16,7 @@ An Apache setup is still much more robust and secure than an easy installation.
Une installation apache est aussi beaucoup plus solide et sécurisé qu'une
installation facile. You'll benefit from having:
- the possiblity to have several projects listening to the port 80;
- the possibility to have several projects listening to the port 80;
- several Apache module at your disposal (like requests throttling);
- Apache robustness in front end: it's secure, and there is much less chance
it will crash under heavy load;
@@ -97,4 +97,4 @@ CGI
===
You can also run 0bin using CGI, but infortunaly we didn't have time to cover
it yet. Please contact us if you ever get the need to use it.
it yet. Please contact us if you ever get the need to use it.

View File

@@ -45,7 +45,7 @@ Other features
- copy paste to clipboard in a click;
- get paste short URL in a click;
- own previous pastes history;
- visual hash of a paste to easily tell it appart from others in a list.
- visual hash of a paste to easily tell it apart from others in a list.
Technologies used
==================
@@ -84,4 +84,4 @@ What does 0bin not implement?
.. _Bootstrap: http://twitter.github.com/bootstrap/
.. _VizHash.js: https://github.com/sametmax/VizHash.js
.. _Cherrypy: http://www.cherrypy.org/ (server only)
.. _is not worth it: http://stackoverflow.com/questions/201705/how-many-random-elements-before-md5-produces-collisions
.. _is not worth it: http://stackoverflow.com/questions/201705/how-many-random-elements-before-md5-produces-collisions

View File

@@ -24,7 +24,7 @@ Therefor there are two steps:
You will benefit from having:
- the possiblity to have several projects listening to the port 80;
- the possibility to have several projects listening to the port 80;
- several Apache module at your disposal (like requests throttling);
- Apache robustness in front end: it's secure, and there is much less chance
it will crash under heavy load;
@@ -40,7 +40,7 @@ Run 0bin as usual, but this time make it listen to a local port and host. E.G::
zerobin --host 127.0.0.1 --port 8000
In PHP, when you edit a file, the changes are immediatly visible. In Python,
In PHP, when you edit a file, the changes are immediately visible. In Python,
the whole code is often loaded in memory for performance reasons. This means
you have to restart the Python process to see the changes effect. Having a
separate process let you do this without having to restart the server.

View File

@@ -159,7 +159,7 @@ List of absolute path to directories containing templates that 0bin uses to
generate the web site pages. The first list items have priotity on the later.
If you wish to use your own templates, add the directory containing them
at the begining of the list::
at the beginning of the list::
from zerobin.defauls_settings import TEMPLATE_DIRS
@@ -225,4 +225,4 @@ Valeur approximative de limite de taille d'un paste.
Default = 500000 octets (500 ko)
Command line equivalent: None
Command line equivalent: None

View File

@@ -50,7 +50,7 @@ MENU = (
('Contact', 'mailto:your@email.com') # email
)
# limit size of pasted text in bytes. Be carefull allowing too much size can slow down user's
# limit size of pasted text in bytes. Be careful allowing too much size can slow down user's
# browser
MAX_SIZE = 1024 * 500
MAX_SIZE_KB = int(math.ceil(MAX_SIZE / 1024.0))

View File

@@ -33,8 +33,8 @@ Les serveurs Web Python modernes fonctionnent tous de la même manière, en suiv
une norme d'interfaçage: WSGI.
C'est la solution la plus performante, et celle recommandée. Mais elle demande
l'installation du modle Apache mod_wsgi. Si vous ne savez pas comment faire,
ou si vous ne pouvez pas le faire (par exemple sur un hébergement mutualisé
l'installation du model Apache mod_wsgi. Si vous ne savez pas comment faire,
ou si vous ne pouvez pas le faire (par example sur un hébergement mutualisé
qui ne le propose pas), il vous faudra choisir l'installation CGI.
Premièrement, assurez-vous d'avoir mod_wsgi installé et chargé (en tant qu'admin)::

View File

@@ -40,7 +40,7 @@ solutions.
*Pour un petit site:*
Lancer simplement 0bin en processus shell d'arrière plan. Exemple sous GNU/Linux::
Lancer simplement 0bin en processus shell d'arrière plan. Example sous GNU/Linux::
nohup python zerobin.py --host 0.0.0.0 --port 80 --compressed-static &

View File

@@ -1457,7 +1457,7 @@ class JSONPlugin(object):
if isinstance(rv, dict):
#Attempt to serialize, raises exception on failure
json_response = dumps(rv)
#Set content type only if serialization succesful
#Set content type only if serialization successful
response.content_type = 'application/json'
return json_response
return rv

View File

@@ -96,7 +96,7 @@ try:
from base64 import decodebytes as _base64_decodebytes
except ImportError:
# Python 3.0-
# since CherryPy claims compability with Python 2.3, we must use
# since CherryPy claims compatibility with Python 2.3, we must use
# the legacy API of base64
from base64 import decodestring as _base64_decodebytes

View File

@@ -598,7 +598,7 @@ class MemcachedSession(Session):
# Wrap all .get and .set operations in a single lock.
mc_lock = threading.RLock()
# This is a seperate set of locks per session id.
# This is a separate set of locks per session id.
locks = {}
servers = ['127.0.0.1:11211']

View File

@@ -312,7 +312,7 @@ class Daemonizer(SimplePlugin):
process still return proper exit codes. Therefore, if you use this
plugin to daemonize, don't use the return code as an accurate indicator
of whether the process fully started. In fact, that return code only
indicates if the process succesfully finished the first fork.
indicates if the process successfully finished the first fork.
"""
def __init__(self, bus, stdin='/dev/null', stdout='/dev/null',

View File

@@ -141,7 +141,7 @@ def get_sups():
def set_sups(target_sups):
"""
This is designed to give us a layer of abstraction from the system calls.
It also accomodates FreeBSD's idiosyncracy (which is POSIX-compliant) of
It also accommodates FreeBSD's idiosyncrasy (which is POSIX-compliant) of
keeping the egid in the supplementary groups list.
It also makes an effort to not call the setgroups routine if the target
group list is identical to the current one in force.

View File

@@ -82,7 +82,7 @@ setup(
# the notation major.minor[.patch[.sub]].
# More defails: http://peak.telecommunity.com/DevCenter/setuptools#id6
# E.G: "0.1", or "1.11.04", or "2"
version="0.1",
version="0.2",
# An iterable of strings with the names of all packages to be included
# for distribution. setup() will not recurse over this package, so it
@@ -107,7 +107,7 @@ setup(
##########################################################################
# Parameters you definitly should fill even if they are optional #
# Parameters you definitely should fill even if they are optional #
# You need to either fill or comment them, or setup.py install will fail #
##########################################################################
@@ -183,7 +183,7 @@ setup(
## Iterable of strings being names of modules you wish to include as well
## It's more accurate than a package
## espcially usefull if you have lonelly modules at the root level
## espcially useful if you have lonelly modules at the root level
# E.G: ['mod1', 'pkg.mod2'] if you have mod1.py and pkg/mod2.py
# py_modules= ,
@@ -226,7 +226,7 @@ setup(
# Iterable of string being metadata. You can't add yours and pypi is picky
# about the syntax, so just uncomment the one you want to set.
# It is adviced to at least provide "Operating System" and "Licence"
# It is advised to at least provide "Operating System" and "Licence"
# Incompatibel with 2.2.3- or 2.3-
classifiers=[
'Programming Language :: Python',
@@ -981,7 +981,7 @@ setup(
## A mapping of strings / iterable, the key being the name of a extra
## feature, and the iterable containing dependancy names.
## feature, and the iterable containing dependency names.
## Sometimes a project has "recommended" dependencies, that are not required
## for all uses of the project. For example, a project might offer optional PDF
## output if ReportLab is installed, and reStructuredText support if docutils

View File

@@ -1,37 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: ai ts=4 sts=4 et sw=4
"""
Exctract usefull infos from web server logs
"""
import re
# define your web server logs path
LOGS_PATH = "/var/log/nginx/access_0bin.log"
rexp = re.compile('(\d+\.\d+\.\d+\.\d+) - - \[([^\[\]:]+):(\d+:\d+:\d+) -(\d\d\d\d\)] ("[^"]*")(\d+) (-|\d+) ("[^"]*") (".*")\s*\Z')
f = open(LOGS_PATH, 'r')
for line in f:
a = rexp.match(line)
if not a is None:
# a.group(1) #IP address
# a.group(2) #day/month/year
# a.group(3) #time of day
# a.group(4) #timezone
# a.group(5) #request
# a.group(6) #code 200 for success, 404 for not found, etc.
# a.group(7) #bytes transferred
# a.group(8) #referrer
# a.group(9) #browser
print a.group(8) #referrer
f.close()

View File

@@ -4,4 +4,4 @@
from zerobin.routes import main
main()
main()

View File

@@ -4,4 +4,4 @@
from default_settings import VERSION
__version__ = VERSION
__version__ = VERSION

View File

@@ -5,9 +5,8 @@
######## NOT SETTINGS, JUST BOILER PLATE ##############
import os
import math
VERSION = '0.1'
VERSION = '0.2'
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
LIBS_DIR = os.path.join(os.path.dirname(ROOT_DIR), 'libs')
@@ -68,6 +67,6 @@ MENU = (
('Contact', 'mailto:your@email.com') # email
)
# limit size of pasted text in bytes. Be carefull allowing too much size can
# limit size of pasted text in bytes. Be careful allowing too much size can
# slow down user's browser
MAX_SIZE = 1024 * 500

View File

@@ -2,6 +2,7 @@
import os
import hashlib
import locale
from datetime import datetime, timedelta
@@ -112,10 +113,9 @@ class Paste(object):
return cls.load_from_file(cls.get_path(uuid))
def increment_counter(self):
"""
Increment pastes counter
Increment pastes counter
"""
# simple counter incrementation
@@ -131,7 +131,7 @@ class Paste(object):
try:
#make lock file
flock = open(lock_file, "w")
flock.write('lock')
flock.write('lock')
flock.close()
# init counter (first time)
@@ -157,7 +157,7 @@ class Paste(object):
#remove lock file
os.remove(lock_file)
except (IOError, OSError):
finally:
if os.path.isfile(lock_file):
#remove lock file
os.remove(lock_file)
@@ -205,6 +205,56 @@ class Paste(object):
return self
@classmethod
def get_pastes_count(cls):
"""
Return the number of created pastes.
(must have option DISPLAY_COUNTER enabled for the pastes to be
be counted)
"""
try:
locale.setlocale(locale.LC_ALL, 'en_US')
except:
pass
counter_file = os.path.join(settings.PASTE_FILES_ROOT, 'counter')
try:
count = long(open(counter_file).read(50))
except (IOError, OSError):
count = 0
return locale.format("%d", long(count), grouping=True)
@property
def humanized_expiration(self):
"""
Return the expiration date in a human friendly format.
In 3 minutes, or in 3 days or the 23/01/2102
"""
try:
expiration = self.expiration - datetime.now()
# in_seconds doesn't exist in python 2.6
expiration = expiration.days * 24 * 60 * 60 + expiration.seconds
except TypeError:
return None
if expiration < 60:
return 'in %s s' % expiration
if expiration < 60 * 60:
return 'in %s m' % int(expiration / 60)
if expiration < 60 * 60 * 24:
return 'in %s h' % int(expiration / (60 * 60))
if expiration < 60 * 60 * 24 * 10:
return 'in %s days(s)' % int(expiration / (60 * 60 * 24))
return 'the %s' % self.expiration.strftime('%m/%d/%Y')
def delete(self):
"""
Delete the paste file.

View File

@@ -3,14 +3,14 @@
# vim: ai ts=4 sts=4 et sw=4
"""
Main script including controller, rooting, dependancy management, and
Main script including controller, rooting, dependency management, and
server run.
"""
import os
import sys
import thread
import urlparse
from datetime import datetime, timedelta
# add project dir and libs dir to the PYTHON PATH to ensure they are
@@ -23,16 +23,16 @@ from bottle import (Bottle, run, static_file, view, request)
import clize
from paste import Paste
from utils import drop_privileges, dmerge, get_pastes_count
from utils import drop_privileges, dmerge
app = Bottle()
GLOBAL_CONTEXT = {
'settings': settings,
'pastes_count': get_pastes_count(),
'pastes_count': Paste.get_pastes_count(),
'refresh_counter': datetime.now()
}
@app.route('/')
@view('home')
@@ -48,42 +48,51 @@ def faq():
@app.route('/paste/create', method='POST')
def create_paste():
try:
body = urlparse.parse_qs(request.body.read(int(settings.MAX_SIZE * 1.1)))
except ValueError:
return {'status': 'error',
'message': u"Wrong data payload."}
try:
content = unicode(request.forms.get('content', ''), 'utf8')
except UnicodeDecodeError:
content = unicode(''.join(body['content']), 'utf8')
except (UnicodeDecodeError, KeyError):
return {'status': 'error',
'message': u"Encoding error: the paste couldn't be saved."}
if '{"iv":' not in content: # reject silently non encrypted content
return ''
if '{"iv":' not in content: # reject silently non encrypted content
return {'status': 'error',
'message': u"Wrong data payload."}
if content:
# check size of the paste. if more than settings return error without saving paste.
# prevent from unusual use of the system.
# need to be improved
# check size of the paste. if more than settings return error
# without saving paste. prevent from unusual use of the
# system. need to be improved
if len(content) < settings.MAX_SIZE:
expiration = request.forms.get('expiration', u'burn_after_reading')
expiration = body.get('expiration', [u'burn_after_reading'])[0]
paste = Paste(expiration=expiration, content=content)
paste.save()
# display counter
if settings.DISPLAY_COUNTER:
#increment paste counter
paste.increment_counter()
# if refresh time elapsed pick up new counter value
if GLOBAL_CONTEXT['refresh_counter'] + timedelta(seconds=settings.REFRESH_COUNTER) < datetime.now():
GLOBAL_CONTEXT['pastes_count'] = get_pastes_count()
GLOBAL_CONTEXT['refresh_counter'] = datetime.now()
# if refresh time elapsed pick up new counter value
now = datetime.now()
timeout = (GLOBAL_CONTEXT['refresh_counter']
+ timedelta(seconds=settings.REFRESH_COUNTER))
if timeout < now:
GLOBAL_CONTEXT['pastes_count'] = Paste.get_pastes_count()
GLOBAL_CONTEXT['refresh_counter'] = now
return {'status': 'ok',
'paste': paste.uuid}
return {'status': 'error',
'message': u"Serveur error: the paste couldn't be saved. Please try later."}
'message': u"Serveur error: the paste couldn't be saved. "
u"Please try later."}
@app.route('/paste/:paste_id')
@@ -102,7 +111,8 @@ def display_paste(paste_id):
# to the paste that happens during the paste creation
try:
keep_alive = paste.expiration.split('#')[1]
keep_alive = datetime.strptime(keep_alive, '%Y-%m-%d %H:%M:%S.%f')
keep_alive = datetime.strptime(keep_alive,
'%Y-%m-%d %H:%M:%S.%f')
keep_alive = now < keep_alive + timedelta(seconds=10)
except IndexError:
keep_alive = False
@@ -114,7 +124,6 @@ def display_paste(paste_id):
raise ValueError()
except (TypeError, ValueError):
#abort(404, u"This paste doesn't exist or has expired")
return error404(ValueError)
context = {'paste': paste, 'keep_alive': keep_alive}
@@ -134,8 +143,8 @@ def server_static(filename):
def get_app(debug=None, settings_file='', compressed_static=None):
"""
Return a tuple (settings, app) configured using passed options and
a setting file.
Return a tuple (settings, app) configured using passed
parameters and/or a setting file.
"""
if settings_file:
settings.update_with_file(os.path.abspath(settings_file))
@@ -157,8 +166,8 @@ def get_app(debug=None, settings_file='', compressed_static=None):
@clize.clize(coerce={'debug': bool, 'compressed_static': bool})
def runserver(host='', port='', debug=None, user='',
group='', settings_file='', compressed_static=None, version=False):
def runserver(host='', port='', debug=None, user='', group='',
settings_file='', compressed_static=None, version=False):
settings, app = get_app(debug, settings_file, compressed_static)
@@ -177,7 +186,7 @@ def runserver(host='', port='', debug=None, user='',
run(app, host=settings.HOST, port=settings.PORT, reloader=True,
server="cherrypy")
else:
run(app, host=settings.HOST, port=settings.PORT, server="cherrypy")
run(app, host=settings.HOST, port=settings.PORT, server="cherrypy")
def main():

View File

@@ -3,11 +3,13 @@
.brand {
font-size: 38px !important;
padding: 0px 55px 3px !important;
padding: 0 55px 3px !important;
text-shadow: 0 1px 0 rgba(255, 255, 255, .1), 0 0 30px rgba(255, 255, 255, .125);
-webkit-transition: all .2s linear;
-moz-transition: all .2s linear;
-o-transition: all .2s linear;
-ms-transition: all .2s linear;
transition: all .2s linear;
}
@@ -19,7 +21,6 @@
.brand em {
display: inline;
color: #D40202;
margin: 0px !important;
font-size: 27px;
}
@@ -28,7 +29,7 @@
font-style: italic;
text-align: right;
padding-top: 9px;
margin-bottom: 0px !important;
margin-bottom: 0 !important;
}
.center {
@@ -94,6 +95,8 @@ h4 p {
font-size: 80px;
text-shadow: 1px 3px 1px #DDD, 0 0 4px #333;
-webkit-transition: all 0.2s linear;
-o-transition: all .2s linear;
-ms-transition: all .2s linear;
-moz-transition: all .2s linear;
transition: all .2s linear;
margin-right: 7px;
@@ -162,7 +165,7 @@ input.hide-upload {
position: relative;
left: -110px;
-moz-opacity: 0;
filter: alpha(opacity: 0);
filter: alpha(opacity=0);
opacity: 0 ;
z-index: 2;
width: 100px;
@@ -181,9 +184,7 @@ input.hide-upload {
}
#paste-content.done {
background-color: white;
padding-top:1em;
#paste-content.linenums {
padding-left:0;
}
@@ -262,6 +263,7 @@ form {
form textarea {
overflow-y:auto;
min-height:250px;
}
button.btn, input[type="submit"].btn {
@@ -352,3 +354,37 @@ canvas {
color: red;
font-weight: bold;
}
#faq dt {
margin:2em 0 1em 0;
}
#faq p {
margin:1em;
}
#force-coloration {
text-decoration:underline;
}
#expiration-tag {
float:right;
margin:1em;
background:grey;
color:white;
font-size:0.8em;
padding:0 1ex;
opacity: 0.5;
filter: alpha(opacity=50);
font-weight:bold;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
-moz-background-clip: padding;
-webkit-background-clip: padding-box;
background-clip: padding-box;
}
#content.hover {
background-color: #eee;
}

View File

@@ -4,4 +4,4 @@ article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display
/* Prettify */
.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
/* Custom */
.brand{font-size:38px!important;padding:0 55px 3px!important;text-shadow:0 1px 0 rgba(255,255,255,.1),0 0 30px rgba(255,255,255,.125);-webkit-transition:all .2s linear;-moz-transition:all .2s linear;transition:all .2s linear}.brand span{font-size:48px;line-height:0}.brand em{display:inline;color:#d40202;margin:0!important;font-size:27px}.about{line-height:13px;font-style:italic;text-align:right;padding-top:9px;margin-bottom:0!important}.about span{font-size:10px}body{padding-top:60px;padding-bottom:40px}.sidebar-nav{padding:9px 0}select{width:135px}label{display:inline;margin-left:18px;font-style:italic;font-size:11px;color:#888}ul,ol{padding:0;margin:0}li{margin-left:-9px}p{margin:0 0 20px}.grey{color:#999}.nav-list{padding-right:0!important;font-size:12px}blockquote{width:630px;float:left}h4 p{float:left;font-size:80px;text-shadow:1px 3px 1px #DDD,0 0 4px #333;-webkit-transition:all .2s linear;-moz-transition:all .2s linear;transition:all .2s linear;margin-right:7px;margin-top:3px}h4#pixels-total{position:relative;width:166px;float:right;margin:8px 0 0 0;padding:0 0 0 54px;font-size:1.1em;line-height:1.4;font-weight:normal;color:#777;-webkit-border-top-right-radius:6px;-webkit-border-top-left-radius:20px;-moz-border-top-right-radius:6px;-moz-border-top-left-radius:20px;border-top-right-radius:6px;border-top-left-radius:20px}.greetings{clear:both;margin:0 auto;text-align:center;margin-top:40px}.alert .title{display:block}.btn-group{float:left}html.file-upload p.file-upload{float:left;margin:22px 0 0 21px;display:none}html.file-upload p.file-upload{display:inherit}html.no-file-upload p.file-upload{display:none}input.btn-upload{position:relative;left:-6px;width:100px;z-index:1;margin-top:-13px}input.hide-upload{position:relative;left:-110px;-moz-opacity:0;filter:alpha(opacity:0);opacity:0;z-index:2;width:100px;margin-top:-20px;cursor:pointer;cursor:hand;height:49px}#paste-content{background-color:white;padding:1em}#paste-content.done{background-color:white;padding-top:1em;padding-left:0}.submit-form{display:none}.paste-option{float:right}a#clip-button.hover{cursor:pointer;text-decoration:underline}li.L0,li.L1,li.L2,li.L3,li.L4,li.L5,li.L6,li.L7,li.L8,li.L9{list-style-type:decimal;background:inherit}.prettyprint.linenums{-webkit-box-shadow:inset 40px 0 0 #fbfbfc,inset 41px 0 0 #ececf0;-moz-box-shadow:inset 40px 0 0 #fbfbfc,inset 41px 0 0 #ececf0;box-shadow:inset 40px 0 0 #fbfbfc,inset 41px 0 0 #ececf0}ol.linenums{margin:0 0 0 55px}ol.linenums li{color:#bebec5;line-height:18px;text-shadow:0 1px 0 #fff}.prettyprint{padding:8px;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,monospace,serif;line-height:21px;font-size:12px}.kwd{color:#66F}.pun,.opn,.clo{color:#0A0}.lit{color:#933}.com{color:#C0C}form{padding-bottom:3em!important;padding-right:17px}form textarea{overflow-y:auto}button.btn,input[type="submit"].btn{margin-left:5px}.well{padding-bottom:40px;padding-right:17px}.legal{margin:0 auto;width:300px;text-align:center;margin-top:30px}.btn{margin-left:5px}.btn-primary,.btn-danger{position:relative;top:-4px}#alert-template{display:none}.progress{display:none}.progress .bar{width:25%;text-indent:10px;text-align:left}.lnk-option canvas{vertical-align:middle;margin-right:10px}.previous-pastes .item{margin-top:5px;vertical-align:middle;line-height:24px;padding-left:1em}li.item{margin-left:-13px;margin-right:-5px}.previous-pastes canvas{display:block;float:left;margin-right:5px}html.local-storage .no-local-storage{display:none}html.no-local-storage .local-storage{display:none}canvas{border:1px solid white}#wrap-content{display:none}.noscript{text-align:center;color:red;font-weight:bold}
.brand{font-size:38px!important;padding:0 55px 3px!important;text-shadow:0 1px 0 rgba(255,255,255,.1),0 0 30px rgba(255,255,255,.125);-webkit-transition:all .2s linear;-moz-transition:all .2s linear;-o-transition:all .2s linear;-ms-transition:all .2s linear;transition:all .2s linear}.brand span{font-size:48px;line-height:0}.brand em{display:inline;color:#d40202;font-size:27px}.about{line-height:13px;font-style:italic;text-align:right;padding-top:9px;margin-bottom:0!important}.center{text-align:center}.about span{font-size:10px}body{padding-top:60px;padding-bottom:40px}.sidebar-nav{padding:9px 0}select{width:135px}label{display:inline;margin-left:18px;font-style:italic;font-size:11px;color:#888}ul,ol{padding:0;margin:0}li{margin-left:-9px}p{margin:0 0 20px}.grey{color:#999}.nav-list{padding-right:0!important;font-size:12px}blockquote{width:630px;float:left}h4 p{float:left;font-size:80px;text-shadow:1px 3px 1px #DDD,0 0 4px #333;-webkit-transition:all .2s linear;-o-transition:all .2s linear;-ms-transition:all .2s linear;-moz-transition:all .2s linear;transition:all .2s linear;margin-right:7px;margin-top:3px}h4#pixels-total{position:relative;width:166px;float:right;margin:8px 0 0 0;padding:0 0 0 54px;font-size:1.1em;line-height:1.4;font-weight:normal;color:#777;-webkit-border-top-right-radius:6px;-webkit-border-top-left-radius:20px;-moz-border-top-right-radius:6px;-moz-border-top-left-radius:20px;border-top-right-radius:6px;border-top-left-radius:20px}.greetings{clear:both;margin:0 auto;text-align:center;margin-top:40px}.alert .title{display:block}.btn-group{float:left}html.file-upload p.file-upload{float:left;margin:22px 0 0 21px;display:none}html.file-upload p.file-upload{display:inherit}html.no-file-upload p.file-upload{display:none}input.btn-upload{position:relative;left:-6px;width:100px;z-index:1;margin-top:-13px}input.hide-upload{position:relative;left:-110px;-moz-opacity:0;filter:alpha(opacity=0);opacity:0;z-index:2;width:100px;margin-top:-20px;cursor:pointer;cursor:hand;height:49px}#paste-content{background-color:white;padding:1em}#paste-content.linenums{padding-left:0}.submit-form{display:none}.paste-option{float:right}a#clip-button.hover{cursor:pointer;text-decoration:underline}li.L0,li.L1,li.L2,li.L3,li.L4,li.L5,li.L6,li.L7,li.L8,li.L9{list-style-type:decimal;background:inherit}.prettyprint.linenums{-webkit-box-shadow:inset 40px 0 0 #fbfbfc,inset 41px 0 0 #ececf0;-moz-box-shadow:inset 40px 0 0 #fbfbfc,inset 41px 0 0 #ececf0;box-shadow:inset 40px 0 0 #fbfbfc,inset 41px 0 0 #ececf0}ol.linenums{margin:0 0 0 55px}ol.linenums li{color:#bebec5;line-height:18px;text-shadow:0 1px 0 #fff}.prettyprint{padding:8px;background-color:#f7f7f9;border:1px solid #e1e1e8}pre{font-family:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,monospace,serif;line-height:21px;font-size:12px}.kwd{color:#66F}.pun,.opn,.clo{color:#0A0}.lit{color:#933}.com{color:#C0C}form{padding-bottom:3em!important;padding-right:17px}form textarea{overflow-y:auto;min-height:250px}button.btn,input[type="submit"].btn{margin-left:5px}.well{padding-bottom:40px;padding-right:17px}.legal{margin:0 auto;width:300px;text-align:center;margin-top:30px}.btn{margin-left:5px}.btn-primary,.btn-danger{position:relative;top:-4px}#alert-template{display:none}.progress{display:none}.progress .bar{width:25%;text-indent:10px;text-align:left}.lnk-option canvas{vertical-align:middle;margin-right:10px}.previous-pastes .item{margin-top:5px;vertical-align:middle;line-height:24px;padding-left:1em}li.item{margin-left:-13px;margin-right:-5px}.previous-pastes canvas{display:block;float:left;margin-right:5px}html.local-storage .no-local-storage{display:none}html.no-local-storage .local-storage{display:none}canvas{border:1px solid white}#wrap-content{display:none}.noscript{text-align:center;color:red;font-weight:bold}#faq dt{margin:2em 0 1em 0}#faq p{margin:1em}#force-coloration{text-decoration:underline}#expiration-tag{float:right;margin:1em;background:grey;color:white;font-size:.8em;padding:0 1ex;opacity:.5;filter:alpha(opacity=50);font-weight:bold;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;-moz-background-clip:padding;-webkit-background-clip:padding-box;background-clip:padding-box}#content.hover{background-color:#eee}

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
// Author: Anthony McKale
//
// Note: modifed to javascript from orginal as2 found below
// Note: modifed to javascript from original as2 found below
// basically identical actual to as2
//
// http://www.razorberry.com/blog/archives/2004/08/22/lzw-compression-methods-in-as2/

File diff suppressed because one or more lines are too long

View File

@@ -5,7 +5,6 @@ import os
import glob
import tempfile
import sys
import locale
import default_settings
sys.path.append(default_settings.LIBS_DIR)
@@ -54,23 +53,6 @@ def dmerge(*args):
return dictionary
def get_pastes_count():
"""
Return the number of pastes created (must have option DISPLAY_COUNTER enabled)
"""
locale.setlocale(locale.LC_ALL, 'en_US')
counter_path = settings.PASTE_FILES_ROOT
counter_file = os.path.join(counter_path, 'counter')
try:
with open(counter_file, "r") as f:
count = f.read(50)
f.close
except IOError:
count = 0
return locale.format("%d", long(float(count)), grouping=True)
class SettingsContainer(object):
"""
Singleton containing the settings for the whole app

View File

@@ -1,3 +1,7 @@
<script type="text/javascript">
zerobin.paste_not_found = true;
</script>
<p class="alert alert-error">
<a class="close" data-dismiss="alert" href="#">×</a>
<strong class="title">404 Error!</strong>

View File

@@ -12,11 +12,13 @@
<link rel="shortcut icon" href="/favicon.ico">
%if settings.COMPRESSED_STATIC_FILES:
<link href="/static/css/style.min.css" rel="stylesheet" />
<link href="/static/css/style.min.css?{{ settings.VERSION }}"
rel="stylesheet" />
%else:
<link href="/static/css/prettify.css" rel="stylesheet" />
<link href="/static/css/bootstrap.css" rel="stylesheet">
<link href="/static/css/style.css" rel="stylesheet">
<link href="/static/css/style.css?{{ settings.VERSION }}"
rel="stylesheet">
%end
<!-- Le HTML5 shim, for IE7-8 support of HTML5 elements -->
@@ -25,11 +27,11 @@
<![endif]-->
%if settings.COMPRESSED_STATIC_FILES:
<script src="/static/js/main.min.js"></script>
<script src="/static/js/main.min.js?{{ settings.VERSION }}"></script>
%else:
<script src="/static/js/jquery-1.7.2.min.js"></script>
<script src="/static/js/sjcl.js"></script>
<script src="/static/js/behavior.js"></script>
<script src="/static/js/behavior.js?{{ settings.VERSION }}"></script>
%end
<script type="text/javascript">
@@ -126,10 +128,11 @@
<small>Edgar Allan Poe</small>
</blockquote>
%if settings.DISPLAY_COUNTER:
<h4 id="pixels-total" >
<p>ø</p>
<strong>{{ pastes_count }}</strong> </br>pastes øbinned
<strong>{{ pastes_count }}</strong> <br/>pastes øbinned
</h4>
%end
@@ -143,7 +146,7 @@
</footer>
%if settings.COMPRESSED_STATIC_FILES:
<script src="/static/js/additional.min.js"></script>
<script src="/static/js/additional.min.js?{{ settings.VERSION }}"></script>
%else:
<script src="/static/js/jquery.elastic.source.js"></script>
<script src="/static/js/lzw.js"></script>
@@ -156,6 +159,7 @@
<strong class="title"></strong>
<span class="message"></span>
</p>
</div><!--/wrap-content-->
</body>

View File

@@ -1,31 +1,67 @@
<div class="well">
<div class="well" id="faq">
<h1>FAQ</h1>
%for i, entry in enumerate(settings.MENU):
%if "mailto:" in entry[1]:
<p>If a question does not appear here you can
<span title="{{ entry[1].replace('mailto:', '').replace('@', '__AT__') }}"
class="email-link" >
contact us
</span>.
</p>
%end
%end
<hr width="90%">
<dl>
<dt>What's the name of the captain?</dt>
<dd>The name of the captain is Igloo !</dd>
</br>
<dt>What's the name of the captain?</dt>
<dd>The name of the captain is Igloo !</dd>
</br>
<dt>What's the name of the captain?</dt>
<dd>The name of the captain is Igloo !</dd>
<dt>How does it work?</dt>
<dd>
<p>We generate a random key, and encrypt the paste with it using
the <a href="http://crypto.stanford.edu/sjcl/">sjcl</a>
javascript library.</p>
<p>The content is sent encrypted to the server, which returns the
address of the newly created paste.</p>
<p>The javascript code then redirects to this address, but it adds the
encryption key in the URL hash (#).</p>
<p>When somebody want to read the paste, he usually just click on a link
with this URL. If the hash containing the key is part of it, Obin's
javascript will use it to decrypt the content sent by the server.</p>
<p>The browser never sends the hash to the server, so it does not
receives the key.</p>
</dd>
<dt>Javascript encryption is not secure!</dt>
<dd>
<p>No it's not.</p>
<p>The goal of 0bin is <strong>not</strong> to protect the users
or their secrets.</p>
<p>The goal is to make it hard to sue the host because of the
content users pasted in his service. The idea is that you can not
require somebody to moderate something he can't read</p>
</dd>
<dt>What if the server changes the Javascript code? Or in the case of a man
in the middle attack?</dt>
<dd>
<p>Read above.</p>
<p>0bin the is not built to protect the users content. It is built to
protect the host. If the user content is compromised, 0bin still
provides the host with the main feature: ignorance of the hosted content.</p>
<p>The case where the host himself compromises the encryption process
to read the content makes no sense: in that case he wouldn't have
installed 0bin in the first place. 0bin is here to protect him.</p>
<p><strong>If you want to be sure nobody can read your content, you should
not use 0bin</strong>. Use
<a href="https://crypto.cat/">cryptocat</a> (but JS crypto warnings apply)
or <a href="http://www.cypherpunks.ca/otr/">OTR</a> for chatting,
<a href="http://gnupg.org/">GPG</a>/<a href="http://enigmail.mozdev.org/home/index.php.html">enignmail</a>
for emails and <a href="http://www.truecrypt.org/">TrueCrypt</a> for storage.</p>
</dd>
<dt>How did you come out with such a cool idea?</dt>
<dd>
<p>We didn't, we based 0bin on
<a href="http://sebsauvage.net/paste/">sebsauvage's work</a>.</p>
<p>It was a reaction to
<a href="https://www.zdnet.com/blog/security/pastebin-to-hunt-for-hacker-pastes-anonymous-cries-censorship/11336">Pastebin been forced to moderate its content</a>
because of so many illegal stuffed posted to it. 0bin should be used the
same way <a href="pastebin.com">Pastebin</a> is for users. The only
difference is that if you host it, we hope the encryption
feature can be used as a defense. This is not proven though :-)</p>
</dd>
</dl>
</div>

View File

@@ -22,10 +22,10 @@
<div class="well paste-form">
<form action="/" method="get" accept-charset="utf-8">
<p class="lnk-option">
<a id="clip-button">Copy To Clipboard</a>
|
<a id="short-url" href=""
target="_blank">Get short url</a>
<a id="clip-button" href="#">Copy To Clipboard</a> |
<a id="short-url" href="#">Get short url</a> |
<a id="email-link" href="#">Email this</a>
<span class="paste-option btn-group top">
<button class="btn btn-clone"><i class="icon-camera"></i>&nbsp;Clone</button>
<button class="btn">New Paste</button>
@@ -36,8 +36,13 @@
<div class="bar"></div>
</div>
%expiration = paste.humanized_expiration
%if expiration:
<p id="expiration-tag">Expire {{ expiration }}</p>
%end
<p>
<pre id="paste-content" class="prettyprint linenums">
<pre id="paste-content" class="prettyprint">
<code>
{{ paste.content }}
</code>
@@ -66,14 +71,15 @@
<button type="submit" class="btn btn-primary">Submit</button>
<button class="btn btn-danger">Cancel clone</button>
</p>
<p>
<div>
<div class="progress progress-striped active">
<div class="bar"></div>
</div>
<textarea rows="10" style="width:100%;"
class="input-xlarge"
id="content" name="content"></textarea>
</p>
</div>
</form>
</div>