mirror of
https://github.com/DarrenOfficial/dpaste.git
synced 2024-12-23 15:13:06 +11:00
Initial commit after move to linode
This commit is contained in:
commit
a2e4e83c20
65 changed files with 3333 additions and 0 deletions
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
*~
|
||||
*.pyc
|
||||
docs/_build/*
|
||||
uploads
|
||||
pastebin/conf/local/*.py
|
||||
dev.db
|
||||
pastebin.egg-info
|
308
.pylintrc
Normal file
308
.pylintrc
Normal file
|
@ -0,0 +1,308 @@
|
|||
# lint Python modules using external checkers.
|
||||
#
|
||||
# This is the main checker controlling the other ones and the reports
|
||||
# generation. It is itself both a raw checker and an astng checker in order
|
||||
# to:
|
||||
# * handle message activation / deactivation at the module level
|
||||
# * handle some basic but necessary stats'data (number of classes, methods...)
|
||||
#
|
||||
[MASTER]
|
||||
|
||||
# Specify a configuration file.
|
||||
#rcfile=
|
||||
|
||||
# Python code to execute, usually for sys.path manipulation such as
|
||||
# pygtk.require().
|
||||
#init-hook=
|
||||
|
||||
# Profiled execution.
|
||||
profile=no
|
||||
|
||||
# Add <file or directory> to the black list. It should be a base name, not a
|
||||
# path. You may set this option multiple times.
|
||||
ignore=conf
|
||||
ignore=migrations
|
||||
|
||||
# Pickle collected data for later comparisons.
|
||||
persistent=yes
|
||||
|
||||
# Set the cache size for astng objects.
|
||||
cache-size=500
|
||||
|
||||
# List of plugins (as comma separated values of python modules names) to load,
|
||||
# usually to register additional checkers.
|
||||
load-plugins=
|
||||
|
||||
|
||||
[MESSAGES CONTROL]
|
||||
|
||||
# Enable only checker(s) with the given id(s). This option conflicts with the
|
||||
# disable-checker option
|
||||
#enable-checker=
|
||||
|
||||
# Enable all checker(s) except those with the given id(s). This option
|
||||
# conflicts with the enable-checker option
|
||||
#disable-checker=
|
||||
|
||||
# Enable all messages in the listed categories (IRCWEF).
|
||||
#enable-msg-cat=
|
||||
|
||||
# Disable all messages in the listed categories (IRCWEF).
|
||||
disable-msg-cat=I
|
||||
|
||||
# Enable the message(s) with the given id(s).
|
||||
#enable-msg=
|
||||
|
||||
# Disable the message(s) with the given id(s).
|
||||
disable=W0704,W0201,W0142,W0232,R0903,C0301
|
||||
|
||||
|
||||
[REPORTS]
|
||||
|
||||
# Set the output format. Available formats are text, parseable, colorized, msvs
|
||||
# (visual studio) and html
|
||||
output-format=text
|
||||
|
||||
# Include message's id in output
|
||||
include-ids=yes
|
||||
|
||||
# Put messages in a separate file for each module / package specified on the
|
||||
# command line instead of printing them on stdout. Reports (if any) will be
|
||||
# written in a file name "pylint_global.[txt|html]".
|
||||
files-output=no
|
||||
|
||||
# Tells wether to display a full report or only the messages
|
||||
reports=yes
|
||||
|
||||
# Python expression which should return a note less than 10 (10 is the highest
|
||||
# note). You have access to the variables errors warning, statement which
|
||||
# respectivly contain the number of errors / warnings messages and the total
|
||||
# number of statements analyzed. This is used by the global evaluation report
|
||||
# (R0004).
|
||||
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
|
||||
|
||||
# Add a comment according to your evaluation note. This is used by the global
|
||||
# evaluation report (R0004).
|
||||
comment=no
|
||||
|
||||
# Enable the report(s) with the given id(s).
|
||||
#enable-report=
|
||||
|
||||
# Disable the report(s) with the given id(s).
|
||||
#disable-report=
|
||||
|
||||
|
||||
# checks for :
|
||||
# * doc strings
|
||||
# * modules / classes / functions / methods / arguments / variables name
|
||||
# * number of arguments, local variables, branchs, returns and statements in
|
||||
# functions, methods
|
||||
# * required module attributes
|
||||
# * dangerous default values as arguments
|
||||
# * redefinition of function / method / class
|
||||
# * uses of the global statement
|
||||
#
|
||||
[BASIC]
|
||||
|
||||
# Required attributes for module, separated by a comma
|
||||
required-attributes=
|
||||
|
||||
# Regular expression which should only match functions or classes name which do
|
||||
# not require a docstring
|
||||
no-docstring-rgx=__.*__|get_absolute_url
|
||||
|
||||
# Regular expression which should only match correct module names
|
||||
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
|
||||
|
||||
# Regular expression which should only match correct module level names
|
||||
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
|
||||
|
||||
# Regular expression which should only match correct class names
|
||||
class-rgx=[A-Z_][a-zA-Z0-9]+$
|
||||
|
||||
# Regular expression which should only match correct function names
|
||||
function-rgx=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Regular expression which should only match correct method names
|
||||
method-rgx=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Regular expression which should only match correct instance attribute names
|
||||
attr-rgx=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Regular expression which should only match correct argument names
|
||||
argument-rgx=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Regular expression which should only match correct variable names
|
||||
variable-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}$)
|
||||
|
||||
# Regular expression which should only match correct list comprehension /
|
||||
# generator expression variable names
|
||||
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
|
||||
|
||||
# Good variable names which should always be accepted, separated by a comma
|
||||
good-names=i,j,k,v,qs,urlpatterns,register,p,a,t,r,u,x,f,e,setUp,tearDown
|
||||
|
||||
# Bad variable names which should always be refused, separated by a comma
|
||||
bad-names=foo,bar,baz,toto,tutu,tata
|
||||
|
||||
# List of builtins function names that should not be used, separated by a comma
|
||||
bad-functions=map,filter,apply,input
|
||||
|
||||
|
||||
# try to find bugs in the code using type inference
|
||||
#
|
||||
[TYPECHECK]
|
||||
|
||||
# Tells wether missing members accessed in mixin class should be ignored. A
|
||||
# mixin class is detected if its name ends with "mixin" (case insensitive).
|
||||
ignore-mixin-members=yes
|
||||
|
||||
# List of classes names for which member attributes should not be checked
|
||||
# (useful for classes with attributes dynamicaly set).
|
||||
ignored-classes=SQLObject
|
||||
|
||||
# When zope mode is activated, add a predefined set of Zope acquired attributes
|
||||
# to generated-members.
|
||||
zope=no
|
||||
|
||||
# List of members which are set dynamically and missed by pylint inference
|
||||
# system, and so shouldn't trigger E0201 when accessed.
|
||||
generated-members=objects,DoesNotExist,id,pk,_default_manager,_meta
|
||||
# checks for
|
||||
# * unused variables / imports
|
||||
# * undefined variables
|
||||
# * redefinition of variable from builtins or from an outer scope
|
||||
# * use of variable before assigment
|
||||
#
|
||||
[VARIABLES]
|
||||
|
||||
# Tells wether we should check for unused import in __init__ files.
|
||||
init-import=no
|
||||
|
||||
# A regular expression matching names used for dummy variables (i.e. not used).
|
||||
dummy-variables-rgx=_|dummy
|
||||
|
||||
# List of additional names supposed to be defined in builtins. Remember that
|
||||
# you should avoid to define new builtins when possible.
|
||||
additional-builtins=
|
||||
|
||||
|
||||
# checks for :
|
||||
# * methods without self as first argument
|
||||
# * overridden methods signature
|
||||
# * access only to existant members via self
|
||||
# * attributes not defined in the __init__ method
|
||||
# * supported interfaces implementation
|
||||
# * unreachable code
|
||||
#
|
||||
[CLASSES]
|
||||
|
||||
# List of interface methods to ignore, separated by a comma. This is used for
|
||||
# instance to not check methods defines in Zope's Interface base class.
|
||||
ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
|
||||
|
||||
# List of method names used to declare (i.e. assign) instance attributes.
|
||||
defining-attr-methods=__init__,__new__,setUp
|
||||
|
||||
|
||||
# checks for sign of poor/misdesign:
|
||||
# * number of methods, attributes, local variables...
|
||||
# * size, complexity of functions, methods
|
||||
#
|
||||
[DESIGN]
|
||||
|
||||
# Maximum number of arguments for function / method
|
||||
max-args=5
|
||||
|
||||
# Maximum number of locals for function / method body
|
||||
max-locals=15
|
||||
|
||||
# Maximum number of return / yield for function / method body
|
||||
max-returns=6
|
||||
|
||||
# Maximum number of branch for function / method body
|
||||
max-branchs=12
|
||||
|
||||
# Maximum number of statements in function / method body
|
||||
max-statements=50
|
||||
|
||||
# Maximum number of parents for a class (see R0901).
|
||||
max-parents=7
|
||||
|
||||
# Maximum number of attributes for a class (see R0902).
|
||||
max-attributes=7
|
||||
|
||||
# Minimum number of public methods for a class (see R0903).
|
||||
min-public-methods=2
|
||||
|
||||
# Maximum number of public methods for a class (see R0904).
|
||||
max-public-methods=20
|
||||
|
||||
|
||||
# checks for
|
||||
# * external modules dependencies
|
||||
# * relative / wildcard imports
|
||||
# * cyclic imports
|
||||
# * uses of deprecated modules
|
||||
#
|
||||
[IMPORTS]
|
||||
|
||||
# Deprecated modules which should not be used, separated by a comma
|
||||
deprecated-modules=regsub,string,TERMIOS,Bastion,rexec
|
||||
|
||||
# Create a graph of every (i.e. internal and external) dependencies in the
|
||||
# given file (report R0402 must not be disabled)
|
||||
import-graph=
|
||||
|
||||
# Create a graph of external dependencies in the given file (report R0402 must
|
||||
# not be disabled)
|
||||
ext-import-graph=
|
||||
|
||||
# Create a graph of internal dependencies in the given file (report R0402 must
|
||||
# not be disabled)
|
||||
int-import-graph=
|
||||
|
||||
|
||||
# checks for :
|
||||
# * unauthorized constructions
|
||||
# * strict indentation
|
||||
# * line length
|
||||
# * use of <> instead of !=
|
||||
#
|
||||
[FORMAT]
|
||||
|
||||
# Maximum number of characters on a single line.
|
||||
max-line-length=88
|
||||
|
||||
# Maximum number of lines in a module
|
||||
max-module-lines=1000
|
||||
|
||||
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
|
||||
# tab).
|
||||
indent-string=' '
|
||||
|
||||
|
||||
# checks for:
|
||||
# * warning notes in the code like FIXME, XXX
|
||||
# * PEP 263: source code with non ascii character but no encoding declaration
|
||||
#
|
||||
[MISCELLANEOUS]
|
||||
|
||||
# List of note tags to take in consideration, separated by a comma.
|
||||
notes=FIXME,XXX,TODO
|
||||
|
||||
|
||||
# checks for similarities and duplicated code. This computation may be
|
||||
# memory / CPU intensive, so you should disable it if you experiments some
|
||||
# problems.
|
||||
#
|
||||
[SIMILARITIES]
|
||||
|
||||
# Minimum lines number of a similarity.
|
||||
min-similarity-lines=4
|
||||
|
||||
# Ignore comments when computing similarities.
|
||||
ignore-comments=yes
|
||||
|
||||
# Ignore docstrings when computing similarities.
|
||||
ignore-docstrings=yes
|
4
README
Normal file
4
README
Normal file
|
@ -0,0 +1,4 @@
|
|||
Developer documentation is available in Sphinx format in the docs directory.
|
||||
|
||||
Initial installation instructions (including how to build the documentation as
|
||||
HTML) can be found in docs/install.rst.
|
88
docs/Makefile
Normal file
88
docs/Makefile
Normal file
|
@ -0,0 +1,88 @@
|
|||
# Makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER =
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
|
||||
|
||||
.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
|
||||
clean:
|
||||
-rm -rf _build/*
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in _build/html."
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) _build/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in _build/dirhtml."
|
||||
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) _build/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in _build/htmlhelp."
|
||||
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) _build/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in _build/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator _build/qthelp/pastebin.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile _build/qthelp/pastebin.qhc"
|
||||
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in _build/latex."
|
||||
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
|
||||
"run these through (pdf)latex."
|
||||
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes
|
||||
@echo
|
||||
@echo "The overview file is in _build/changes."
|
||||
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in _build/linkcheck/output.txt."
|
||||
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) _build/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in _build/doctest/output.txt."
|
195
docs/conf.py
Normal file
195
docs/conf.py
Normal file
|
@ -0,0 +1,195 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# pastebin documentation build configuration file, created by
|
||||
# sphinx-quickstart on Wed Aug 19 10:27:46 2009.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys, os
|
||||
import datetime
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.append(os.path.abspath('.'))
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = ['sphinx.ext.autodoc']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'pastebin'
|
||||
copyright = u'%d, Martin Mahner' % datetime.date.today().year
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '1.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.0'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of documents that shouldn't be included in the build.
|
||||
#unused_docs = []
|
||||
|
||||
# List of directories, relative to source directory, that shouldn't be searched
|
||||
# for source files.
|
||||
exclude_trees = ['_build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
|
||||
# -- Options for HTML output ---------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. Major themes that come with
|
||||
# Sphinx are currently 'default' and 'sphinxdoc'.
|
||||
html_theme = 'default'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_use_modindex = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = ''
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'pastebindoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output --------------------------------------------------
|
||||
|
||||
# The paper size ('letter' or 'a4').
|
||||
#latex_paper_size = 'letter'
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#latex_font_size = '10pt'
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'pastebin.tex', u'pastebin Documentation',
|
||||
u'Martin Mahner', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#latex_preamble = ''
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_use_modindex = True
|
18
docs/deployment.rst
Normal file
18
docs/deployment.rst
Normal file
|
@ -0,0 +1,18 @@
|
|||
Deployment
|
||||
==========
|
||||
|
||||
Staging/Development
|
||||
-------------------
|
||||
|
||||
`Fabric <http://pypi.python.org/pypi/Fabric>`_ is used to allow developers to
|
||||
easily push changes to a previously setup development/staging environment.
|
||||
To get started, run the following command from within your virtual
|
||||
environment::
|
||||
|
||||
pip install fabric==0.9.3
|
||||
fab --fabfile src/pastebin/fabfile.py -l
|
||||
|
||||
This will install Fabric and provide a list of available commands.
|
||||
|
||||
When run from src/pastebin, you can just run ``fab [command]`` (i.e. without
|
||||
the ``-fabfile`` flag).
|
18
docs/index.rst
Normal file
18
docs/index.rst
Normal file
|
@ -0,0 +1,18 @@
|
|||
Welcome to pastebin's documentation!
|
||||
=====================================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
install
|
||||
deployment
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
57
docs/install.rst
Normal file
57
docs/install.rst
Normal file
|
@ -0,0 +1,57 @@
|
|||
==================
|
||||
Installation
|
||||
==================
|
||||
|
||||
Pre-Requisites
|
||||
===============
|
||||
|
||||
* `setuptools <http://pypi.python.org/pypi/setuptools>`_
|
||||
* `virtualenv <http://pypi.python.org/pypi/virtualenv>`_
|
||||
|
||||
To install all of these system dependencies on a Debian-based system, run::
|
||||
|
||||
sudo apt-get install python-setuptools
|
||||
sudo easy_install virtualenv
|
||||
|
||||
|
||||
Creating the Virtual Environment
|
||||
================================
|
||||
|
||||
First, create a clean base environment using virtualenv::
|
||||
|
||||
virtualenv pastebin
|
||||
cd pastebin
|
||||
source bin/activate
|
||||
|
||||
|
||||
Installing the Project
|
||||
======================
|
||||
|
||||
Install the requirements and the project source::
|
||||
|
||||
cd path/to/your/pastebin/repository
|
||||
pip install -r requirements.pip
|
||||
pip install -e .
|
||||
|
||||
|
||||
Configuring a Local Environment
|
||||
===============================
|
||||
|
||||
If you're just checking the project out locally, you can copy some example
|
||||
configuration files to get started quickly::
|
||||
|
||||
cp pastebin/conf/local/example/* pastebin/conf/local
|
||||
manage.py syncdb --migrate
|
||||
|
||||
|
||||
Building Documentation
|
||||
======================
|
||||
|
||||
Documentation is available in ``docs`` and can be built into a number of
|
||||
formats using `Sphinx <http://pypi.python.org/pypi/Sphinx>`_. To get started::
|
||||
|
||||
pip install Sphinx
|
||||
cd docs
|
||||
make html
|
||||
|
||||
This creates the documentation in HTML format at ``docs/_build/html``.
|
92
fabfile.py
vendored
Normal file
92
fabfile.py
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
from fabric.api import env, local, run, require, cd
|
||||
from fabric.operations import _prefix_commands, _prefix_env_vars
|
||||
|
||||
env.disable_known_hosts = True # always fails for me without this
|
||||
env.hosts = ['pastebin.dev.lincolnloop.com']
|
||||
env.root = '/opt/webapps/pastebin'
|
||||
env.proj_root = env.root + '/src/pastebin'
|
||||
env.proj_repo = 'git@github.com:myuser/myrepo.git'
|
||||
env.pip_file = env.proj_root + '/requirements.pip'
|
||||
|
||||
|
||||
def deploy():
|
||||
"""Update source, update pip requirements, syncdb, restart server"""
|
||||
update()
|
||||
update_reqs()
|
||||
syncdb()
|
||||
restart()
|
||||
|
||||
|
||||
def switch(branch):
|
||||
"""Switch the repo branch which the server is using"""
|
||||
with cd(env.proj_root):
|
||||
ve_run('git checkout %s' % branch)
|
||||
restart()
|
||||
|
||||
|
||||
def version():
|
||||
"""Show last commit to repo on server"""
|
||||
with cd(env.proj_root):
|
||||
sshagent_run('git log -1')
|
||||
|
||||
|
||||
def restart():
|
||||
"""Restart Apache process"""
|
||||
run('touch %s/etc/apache/django.wsgi' % env.root)
|
||||
|
||||
|
||||
def update_reqs():
|
||||
"""Update pip requirements"""
|
||||
ve_run('yes w | pip install -r %s' % env.pip_file)
|
||||
|
||||
|
||||
def update():
|
||||
"""Updates project source"""
|
||||
with cd(env.proj_root):
|
||||
sshagent_run('git pull')
|
||||
|
||||
|
||||
def syncdb():
|
||||
"""Run syncdb (along with any pending south migrations)"""
|
||||
ve_run('manage.py syncdb --migrate')
|
||||
|
||||
|
||||
def clone():
|
||||
"""Clone the repository for the first time"""
|
||||
with cd('%s/src' % env.root):
|
||||
sshagent_run('git clone %s' % env.proj_repo)
|
||||
ve_run('pip install -e %s' % env.proj_root)
|
||||
|
||||
with cd('%s/pastebin/conf/local' % env.proj_root):
|
||||
run('ln -s ../dev/__init__.py')
|
||||
run('ln -s ../dev/settings.py')
|
||||
|
||||
|
||||
def ve_run(cmd):
|
||||
"""
|
||||
Helper function.
|
||||
Runs a command using the virtualenv environment
|
||||
"""
|
||||
require('root')
|
||||
return sshagent_run('source %s/bin/activate; %s' % (env.root, cmd))
|
||||
|
||||
|
||||
def sshagent_run(cmd):
|
||||
"""
|
||||
Helper function.
|
||||
Runs a command with SSH agent forwarding enabled.
|
||||
|
||||
Note:: Fabric (and paramiko) can't forward your SSH agent.
|
||||
This helper uses your system's ssh to do so.
|
||||
"""
|
||||
# Handle context manager modifications
|
||||
wrapped_cmd = _prefix_commands(_prefix_env_vars(cmd), 'remote')
|
||||
try:
|
||||
host, port = env.host_string.split(':')
|
||||
return local(
|
||||
"ssh -p %s -A %s@%s '%s'" % (port, env.user, host, wrapped_cmd)
|
||||
)
|
||||
except ValueError:
|
||||
return local(
|
||||
"ssh -A %s@%s '%s'" % (env.user, env.host_string, wrapped_cmd)
|
||||
)
|
0
pastebin/__init__.py
Normal file
0
pastebin/__init__.py
Normal file
0
pastebin/apps/__init__.py
Normal file
0
pastebin/apps/__init__.py
Normal file
0
pastebin/apps/api/__init__.py
Normal file
0
pastebin/apps/api/__init__.py
Normal file
29
pastebin/apps/api/handlers.py
Normal file
29
pastebin/apps/api/handlers.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
import datetime
|
||||
import re
|
||||
from piston.utils import rc
|
||||
from piston.handler import AnonymousBaseHandler
|
||||
from pastebin.apps.dpaste.models import Snippet
|
||||
|
||||
class SnippetHandler(AnonymousBaseHandler):
|
||||
allowed_methods = ('GET', 'POST')
|
||||
fields = ('title', 'content',)
|
||||
exclude = ('id', re.compile(r'^private_'))
|
||||
model = Snippet
|
||||
|
||||
def content_size(self, blogpost):
|
||||
return len(blogpost.content)
|
||||
|
||||
def read(self, request, secret_id):
|
||||
post = Snippet.objects.get(secret_id=secret_id)
|
||||
return post
|
||||
|
||||
def create(self, request):
|
||||
if not request.POST.get('content'):
|
||||
return rc.BAD_REQUEST
|
||||
|
||||
s = Snippet.objects.create(
|
||||
content=request.POST.get('content'),
|
||||
expires=datetime.datetime.now()+datetime.timedelta(seconds=60*60*24*30)
|
||||
)
|
||||
s.save()
|
||||
return 'http://dpaste.de%s' % s.get_absolute_url()
|
1
pastebin/apps/dpaste/__init__.py
Normal file
1
pastebin/apps/dpaste/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
__version__ = '0.2.3'
|
13
pastebin/apps/dpaste/admin.py
Normal file
13
pastebin/apps/dpaste/admin.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
from pastebin.apps.dpaste.models import Snippet
|
||||
from django.contrib import admin
|
||||
|
||||
class SnippetAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
'__unicode__',
|
||||
'author',
|
||||
'lexer',
|
||||
'published',
|
||||
'expires',
|
||||
)
|
||||
|
||||
admin.site.register(Snippet, SnippetAdmin)
|
109
pastebin/apps/dpaste/forms.py
Normal file
109
pastebin/apps/dpaste/forms.py
Normal file
|
@ -0,0 +1,109 @@
|
|||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from pastebin.apps.dpaste.models import Snippet
|
||||
from pastebin.apps.dpaste.highlight import LEXER_LIST_ALL, LEXER_LIST, LEXER_DEFAULT
|
||||
import datetime
|
||||
|
||||
#===============================================================================
|
||||
# Snippet Form and Handling
|
||||
#===============================================================================
|
||||
|
||||
EXPIRE_CHOICES = (
|
||||
(3600, _(u'In one hour')),
|
||||
(3600*24*7, _(u'In one week')),
|
||||
(3600*24*30, _(u'In one month')),
|
||||
(3600*24*30*12*100, _(u'Save forever')), # 100 years, I call it forever ;)
|
||||
)
|
||||
|
||||
EXPIRE_DEFAULT = 3600*24*30
|
||||
|
||||
class SnippetForm(forms.ModelForm):
|
||||
|
||||
lexer = forms.ChoiceField(
|
||||
choices=LEXER_LIST,
|
||||
initial=LEXER_DEFAULT,
|
||||
label=_(u'Lexer'),
|
||||
)
|
||||
|
||||
expire_options = forms.ChoiceField(
|
||||
choices=EXPIRE_CHOICES,
|
||||
initial=EXPIRE_DEFAULT,
|
||||
label=_(u'Expires'),
|
||||
)
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
super(SnippetForm, self).__init__(*args, **kwargs)
|
||||
self.request = request
|
||||
|
||||
try:
|
||||
if self.request.session['userprefs'].get('display_all_lexer', False):
|
||||
self.fields['lexer'].choices = LEXER_LIST_ALL
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
try:
|
||||
self.fields['author'].initial = self.request.session['userprefs'].get('default_name', '')
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
def save(self, parent=None, *args, **kwargs):
|
||||
|
||||
# Set parent snippet
|
||||
if parent:
|
||||
self.instance.parent = parent
|
||||
|
||||
# Add expire datestamp
|
||||
self.instance.expires = datetime.datetime.now() + \
|
||||
datetime.timedelta(seconds=int(self.cleaned_data['expire_options']))
|
||||
|
||||
# Save snippet in the db
|
||||
super(SnippetForm, self).save(*args, **kwargs)
|
||||
|
||||
# Add the snippet to the user session list
|
||||
if self.request.session.get('snippet_list', False):
|
||||
if len(self.request.session['snippet_list']) >= getattr(settings, 'MAX_SNIPPETS_PER_USER', 10):
|
||||
self.request.session['snippet_list'].pop(0)
|
||||
self.request.session['snippet_list'] += [self.instance.pk]
|
||||
else:
|
||||
self.request.session['snippet_list'] = [self.instance.pk]
|
||||
|
||||
return self.request, self.instance
|
||||
|
||||
class Meta:
|
||||
model = Snippet
|
||||
fields = (
|
||||
'title',
|
||||
'content',
|
||||
'author',
|
||||
'lexer',
|
||||
)
|
||||
|
||||
|
||||
#===============================================================================
|
||||
# User Settings
|
||||
#===============================================================================
|
||||
|
||||
USERPREFS_FONT_CHOICES = [(None, _(u'Default'))] + [
|
||||
(i, i) for i in sorted((
|
||||
'Monaco',
|
||||
'Bitstream Vera Sans Mono',
|
||||
'Courier New',
|
||||
'Consolas',
|
||||
))
|
||||
]
|
||||
|
||||
USERPREFS_SIZES = [(None, _(u'Default'))] + [(i, '%dpx' % i) for i in range(5, 25)]
|
||||
|
||||
class UserSettingsForm(forms.Form):
|
||||
|
||||
default_name = forms.CharField(label=_(u'Default Name'), required=False)
|
||||
display_all_lexer = forms.BooleanField(
|
||||
label=_(u'Display all lexer'),
|
||||
required=False,
|
||||
widget=forms.CheckboxInput,
|
||||
help_text=_(u'This also enables the super secret \'guess lexer\' function.'),
|
||||
)
|
||||
font_family = forms.ChoiceField(label=_(u'Font Family'), required=False, choices=USERPREFS_FONT_CHOICES)
|
||||
font_size = forms.ChoiceField(label=_(u'Font Size'), required=False, choices=USERPREFS_SIZES)
|
||||
line_height = forms.ChoiceField(label=_(u'Line Height'), required=False, choices=USERPREFS_SIZES)
|
43
pastebin/apps/dpaste/highlight.py
Normal file
43
pastebin/apps/dpaste/highlight.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
from pygments.lexers import get_all_lexers, get_lexer_by_name, guess_lexer
|
||||
from pygments.styles import get_all_styles
|
||||
from pygments.formatters import HtmlFormatter
|
||||
from pygments.util import ClassNotFound
|
||||
from pygments import highlight
|
||||
|
||||
LEXER_LIST_ALL = sorted([(i[1][0], i[0]) for i in get_all_lexers()])
|
||||
LEXER_LIST = (
|
||||
('bash', 'Bash'),
|
||||
('c', 'C'),
|
||||
('css', 'CSS'),
|
||||
('diff', 'Diff'),
|
||||
('django', 'Django/Jinja'),
|
||||
('html', 'HTML'),
|
||||
('irc', 'IRC logs'),
|
||||
('js', 'JavaScript'),
|
||||
('php', 'PHP'),
|
||||
('pycon', 'Python console session'),
|
||||
('pytb', 'Python Traceback'),
|
||||
('python', 'Python'),
|
||||
('python3', 'Python 3'),
|
||||
('rst', 'Restructured Text'),
|
||||
('sql', 'SQL'),
|
||||
('text', 'Text only'),
|
||||
)
|
||||
LEXER_DEFAULT = 'python'
|
||||
|
||||
|
||||
class NakedHtmlFormatter(HtmlFormatter):
|
||||
def wrap(self, source, outfile):
|
||||
return self._wrap_code(source)
|
||||
def _wrap_code(self, source):
|
||||
for i, t in source:
|
||||
yield i, t
|
||||
|
||||
def pygmentize(code_string, lexer_name='text'):
|
||||
return highlight(code_string, get_lexer_by_name(lexer_name), NakedHtmlFormatter())
|
||||
|
||||
def guess_code_lexer(code_string, default_lexer='unknown'):
|
||||
try:
|
||||
return guess_lexer(code_string).name
|
||||
except ClassNotFound:
|
||||
return default_lexer
|
BIN
pastebin/apps/dpaste/locale/de/LC_MESSAGES/django.mo
Normal file
BIN
pastebin/apps/dpaste/locale/de/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
236
pastebin/apps/dpaste/locale/de/LC_MESSAGES/django.po
Normal file
236
pastebin/apps/dpaste/locale/de/LC_MESSAGES/django.po
Normal file
|
@ -0,0 +1,236 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-05-07 12:23+0200\n"
|
||||
"PO-Revision-Date: 2008-08-10 01:20+0100\n"
|
||||
"Last-Translator: Martin Mahner <martin@mahner.org>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: forms.py:13
|
||||
msgid "In one hour"
|
||||
msgstr "In einer Stunde"
|
||||
|
||||
#: forms.py:14
|
||||
msgid "In one week"
|
||||
msgstr "In einer Woche"
|
||||
|
||||
#: forms.py:15
|
||||
msgid "In one month"
|
||||
msgstr "In einem Monat"
|
||||
|
||||
#: forms.py:16
|
||||
msgid "Save forever"
|
||||
msgstr "Für immer speichern"
|
||||
|
||||
#: forms.py:26 models.py:20
|
||||
msgid "Lexer"
|
||||
msgstr "Syntax"
|
||||
|
||||
#: forms.py:32 models.py:22
|
||||
msgid "Expires"
|
||||
msgstr "Erlischt"
|
||||
|
||||
#: forms.py:87 forms.py:96
|
||||
msgid "Default"
|
||||
msgstr "Standard"
|
||||
|
||||
#: forms.py:100
|
||||
msgid "Default Name"
|
||||
msgstr "Standard Name"
|
||||
|
||||
#: forms.py:102
|
||||
msgid "Display all lexer"
|
||||
msgstr "Alle Syntaxformate anzeigen"
|
||||
|
||||
#: forms.py:105
|
||||
msgid "This also enables the super secret 'guess lexer' function."
|
||||
msgstr "Dies aktiviert auch die super geheime 'Syntax erraten' Funktion."
|
||||
|
||||
#: forms.py:107
|
||||
msgid "Font Family"
|
||||
msgstr "Schriftart"
|
||||
|
||||
#: forms.py:108
|
||||
msgid "Font Size"
|
||||
msgstr "Schriftgröße"
|
||||
|
||||
#: forms.py:109
|
||||
msgid "Line Height"
|
||||
msgstr "Zeilenhöhe"
|
||||
|
||||
#: models.py:15
|
||||
msgid "Secret ID"
|
||||
msgstr "Geheime ID"
|
||||
|
||||
#: models.py:16
|
||||
msgid "Title"
|
||||
msgstr "Titel"
|
||||
|
||||
#: models.py:17
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
||||
|
||||
#: models.py:18
|
||||
msgid "Content"
|
||||
msgstr "Inhalt"
|
||||
|
||||
#: models.py:19
|
||||
msgid "Highlighted Content"
|
||||
msgstr "Gehighlighteter Content"
|
||||
|
||||
#: models.py:21
|
||||
msgid "Published"
|
||||
msgstr "Veröffentlicht"
|
||||
|
||||
#: views.py:145
|
||||
msgid "No changes were made between this two files."
|
||||
msgstr "Zwischen diesen beiden Dateien wurden keine Änderungen durchgeführt."
|
||||
|
||||
#: templates/dpaste/snippet_details.html:18
|
||||
#: templates/dpaste/snippet_details.html:21
|
||||
#: templates/dpaste/snippet_details.html:44
|
||||
#: templates/dpaste/snippet_details.html:81
|
||||
#: templates/dpaste/snippet_details.html:83
|
||||
#: templates/dpaste/snippet_list.html:4 templates/dpaste/snippet_list.html:13
|
||||
msgid "Snippet"
|
||||
msgstr "Snippet"
|
||||
|
||||
#: templates/dpaste/snippet_details.html:23
|
||||
#, python-format
|
||||
msgid "(Copy of <a href=\"%(parent_url)s\">snippet #%(parent_id)s</a>)"
|
||||
msgstr "(Kopie von <a href=\"%(parent_url)s\">Snippet #%(parent_id)s</a>)"
|
||||
|
||||
#: templates/dpaste/snippet_details.html:25
|
||||
#: templates/dpaste/snippet_list.html:14
|
||||
msgid "DATETIME_FORMAT"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_details.html:25
|
||||
msgid "UTC"
|
||||
msgstr "UTC"
|
||||
|
||||
#: templates/dpaste/snippet_details.html:35
|
||||
msgid "Time to life"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_details.html:38
|
||||
msgid "Really delete this snippet?"
|
||||
msgstr "Wirklich dieses Snippet löschen?"
|
||||
|
||||
#: templates/dpaste/snippet_details.html:41
|
||||
msgid "Wordwrap"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_details.html:45
|
||||
#, python-format
|
||||
msgid "by %(author)s"
|
||||
msgstr "von %(author)s"
|
||||
|
||||
#: templates/dpaste/snippet_details.html:59
|
||||
msgid "Write an answer"
|
||||
msgstr "Schreibe eine Antwort"
|
||||
|
||||
#: templates/dpaste/snippet_details.html:69
|
||||
msgid "History"
|
||||
msgstr "Verlauf"
|
||||
|
||||
#: templates/dpaste/snippet_details.html:89
|
||||
msgid "Compare"
|
||||
msgstr "Vergleichen"
|
||||
|
||||
#: templates/dpaste/snippet_details.html:94
|
||||
msgid "Options"
|
||||
msgstr "Optionen"
|
||||
|
||||
#: templates/dpaste/snippet_details.html:95
|
||||
msgid "View raw"
|
||||
msgstr "Rohformat"
|
||||
|
||||
#: templates/dpaste/snippet_diff.html:4
|
||||
msgid "Close"
|
||||
msgstr "Schließen"
|
||||
|
||||
#: templates/dpaste/snippet_diff.html:5
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" Diff between\n"
|
||||
" <a href=\"%(filea_url)s\">Snippet #%(filea_id)s</a>\n"
|
||||
" and\n"
|
||||
" <a href=\"%(fileb_url)s\">Snippet #%(fileb_id)s</a>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" Diff zwischen\n"
|
||||
" <a href=\"%(filea_url)s\">Snippet #%(filea_id)s</a>\n"
|
||||
" und\n"
|
||||
" <a href=\"%(fileb_url)s\">Snippet #%(fileb_id)s</a>\n"
|
||||
" "
|
||||
|
||||
#: templates/dpaste/snippet_form.html:10
|
||||
msgid "Guess lexer"
|
||||
msgstr "Syntax erraten"
|
||||
|
||||
#: templates/dpaste/snippet_form.html:15
|
||||
msgid "Paste it"
|
||||
msgstr "Paste es"
|
||||
|
||||
#: templates/dpaste/snippet_list.html:6
|
||||
#, python-format
|
||||
msgid "Your latest %(snippets_max)s snippets"
|
||||
msgstr "Deine neuesten %(snippets_max)s Snippets"
|
||||
|
||||
#: templates/dpaste/snippet_list.html:19
|
||||
msgid "No snippets available."
|
||||
msgstr "Keine Snippets verfügbar"
|
||||
|
||||
#: templates/dpaste/snippet_list.html:24 templates/dpaste/userprefs.html:25
|
||||
msgid "DATA_STORED_IN_A_COOKIE_HINT"
|
||||
msgstr ""
|
||||
"<p><strong>Hinweis:</strong> Deine Daten werden in einem Cookie gespeichert."
|
||||
|
||||
#: templates/dpaste/snippet_new.html:4 templates/dpaste/snippet_new.html:8
|
||||
msgid "New snippet"
|
||||
msgstr "Neues Snippet"
|
||||
|
||||
#: templates/dpaste/snippet_new.html:5
|
||||
msgid "Paste a new snippet"
|
||||
msgstr "Schreibe ein neues Snippet"
|
||||
|
||||
#: templates/dpaste/snippet_new.html:14
|
||||
msgid "DPASTE_HOMEPAGE_TITLE"
|
||||
msgstr "dpaste"
|
||||
|
||||
#: templates/dpaste/snippet_new.html:15
|
||||
msgid "DPASTE_HOMEPAGE_DESCRIPTION"
|
||||
msgstr ""
|
||||
"dpaste.de ist ein Codespeicher inspiriert von <a href=\"http://dpaste.com/"
|
||||
"\">dpaste.com</a>. Die Vorteile und den Quellcode dieser Seite findest du "
|
||||
"bei <a href=\"http://code.google.com/p/django-paste/\">Google Code</a>."
|
||||
|
||||
#: templates/dpaste/userprefs.html:5 templates/dpaste/userprefs.html.py:15
|
||||
msgid "User Settings"
|
||||
msgstr "Benutzereinstellungen"
|
||||
|
||||
#: templates/dpaste/userprefs.html:11
|
||||
msgid "USER_PREFS_SAVED_SUCCESSFULLY"
|
||||
msgstr "Deine Einstellungen wurden erfolgreich gespeichert."
|
||||
|
||||
#: templates/dpaste/userprefs.html:20
|
||||
msgid "Save settings"
|
||||
msgstr "Einstellungen speichern"
|
||||
|
||||
#~ msgid "WHAT_IS_THIS_TITLE"
|
||||
#~ msgstr "Was ist das hier?"
|
||||
|
||||
#~ msgid "Youre displaying the whole bunch of lexers!"
|
||||
#~ msgstr "Du siehst derzeit das ganze Bündel an Lexern!"
|
BIN
pastebin/apps/dpaste/locale/en/LC_MESSAGES/django.mo
Normal file
BIN
pastebin/apps/dpaste/locale/en/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
226
pastebin/apps/dpaste/locale/en/LC_MESSAGES/django.po
Normal file
226
pastebin/apps/dpaste/locale/en/LC_MESSAGES/django.po
Normal file
|
@ -0,0 +1,226 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-05-07 12:23+0200\n"
|
||||
"PO-Revision-Date: 2008-08-10 01:19+0100\n"
|
||||
"Last-Translator: Martin Mahner <martin@mahner.org>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: forms.py:13
|
||||
msgid "In one hour"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:14
|
||||
msgid "In one week"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:15
|
||||
msgid "In one month"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:16
|
||||
msgid "Save forever"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:26 models.py:20
|
||||
msgid "Lexer"
|
||||
msgstr "Syntax"
|
||||
|
||||
#: forms.py:32 models.py:22
|
||||
msgid "Expires"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:87 forms.py:96
|
||||
msgid "Default"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:100
|
||||
msgid "Default Name"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:102
|
||||
msgid "Display all lexer"
|
||||
msgstr "Display all syntax modes"
|
||||
|
||||
#: forms.py:105
|
||||
msgid "This also enables the super secret 'guess lexer' function."
|
||||
msgstr "This also enables the super secret 'guess syntax' function."
|
||||
|
||||
#: forms.py:107
|
||||
msgid "Font Family"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:108
|
||||
msgid "Font Size"
|
||||
msgstr ""
|
||||
|
||||
#: forms.py:109
|
||||
msgid "Line Height"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:15
|
||||
msgid "Secret ID"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:16
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:17
|
||||
msgid "Author"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:18
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:19
|
||||
msgid "Highlighted Content"
|
||||
msgstr ""
|
||||
|
||||
#: models.py:21
|
||||
msgid "Published"
|
||||
msgstr ""
|
||||
|
||||
#: views.py:145
|
||||
msgid "No changes were made between this two files."
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_details.html:18
|
||||
#: templates/dpaste/snippet_details.html:21
|
||||
#: templates/dpaste/snippet_details.html:44
|
||||
#: templates/dpaste/snippet_details.html:81
|
||||
#: templates/dpaste/snippet_details.html:83
|
||||
#: templates/dpaste/snippet_list.html:4 templates/dpaste/snippet_list.html:13
|
||||
msgid "Snippet"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_details.html:23
|
||||
#, python-format
|
||||
msgid "(Copy of <a href=\"%(parent_url)s\">snippet #%(parent_id)s</a>)"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_details.html:25
|
||||
#: templates/dpaste/snippet_list.html:14
|
||||
msgid "DATETIME_FORMAT"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_details.html:25
|
||||
msgid "UTC"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_details.html:35
|
||||
msgid "Time to life"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_details.html:38
|
||||
msgid "Really delete this snippet?"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_details.html:41
|
||||
msgid "Wordwrap"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_details.html:45
|
||||
#, python-format
|
||||
msgid "by %(author)s"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_details.html:59
|
||||
msgid "Write an answer"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_details.html:69
|
||||
msgid "History"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_details.html:89
|
||||
msgid "Compare"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_details.html:94
|
||||
msgid "Options"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_details.html:95
|
||||
msgid "View raw"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_diff.html:4
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_diff.html:5
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" Diff between\n"
|
||||
" <a href=\"%(filea_url)s\">Snippet #%(filea_id)s</a>\n"
|
||||
" and\n"
|
||||
" <a href=\"%(fileb_url)s\">Snippet #%(fileb_id)s</a>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_form.html:10
|
||||
msgid "Guess lexer"
|
||||
msgstr "Guess syntax"
|
||||
|
||||
#: templates/dpaste/snippet_form.html:15
|
||||
msgid "Paste it"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_list.html:6
|
||||
#, python-format
|
||||
msgid "Your latest %(snippets_max)s snippets"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_list.html:19
|
||||
msgid "No snippets available."
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_list.html:24 templates/dpaste/userprefs.html:25
|
||||
msgid "DATA_STORED_IN_A_COOKIE_HINT"
|
||||
msgstr "<p><strong>Remember:</strong> Your data is stored in a cookie.</p>"
|
||||
|
||||
#: templates/dpaste/snippet_new.html:4 templates/dpaste/snippet_new.html:8
|
||||
msgid "New snippet"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_new.html:5
|
||||
msgid "Paste a new snippet"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/snippet_new.html:14
|
||||
msgid "DPASTE_HOMEPAGE_TITLE"
|
||||
msgstr "dpaste"
|
||||
|
||||
#: templates/dpaste/snippet_new.html:15
|
||||
msgid "DPASTE_HOMEPAGE_DESCRIPTION"
|
||||
msgstr ""
|
||||
"dpaste is code pastebin originally inspired by <a href=\"http://dpaste."
|
||||
"com/\">dpaste.com</a>. Find the advantages and the public sourcecode on <a "
|
||||
"href=\"http://code.google.com/p/django-paste/\">Google Code</a>."
|
||||
|
||||
#: templates/dpaste/userprefs.html:5 templates/dpaste/userprefs.html.py:15
|
||||
msgid "User Settings"
|
||||
msgstr ""
|
||||
|
||||
#: templates/dpaste/userprefs.html:11
|
||||
msgid "USER_PREFS_SAVED_SUCCESSFULLY"
|
||||
msgstr "Your preferences were successfully saved."
|
||||
|
||||
#: templates/dpaste/userprefs.html:20
|
||||
msgid "Save settings"
|
||||
msgstr ""
|
||||
|
||||
#~ msgid "WHAT_IS_THIS_TITLE"
|
||||
#~ msgstr "What is this?"
|
0
pastebin/apps/dpaste/management/__init__.py
Normal file
0
pastebin/apps/dpaste/management/__init__.py
Normal file
0
pastebin/apps/dpaste/management/commands/__init__.py
Normal file
0
pastebin/apps/dpaste/management/commands/__init__.py
Normal file
22
pastebin/apps/dpaste/management/commands/cleanup_snippets.py
Normal file
22
pastebin/apps/dpaste/management/commands/cleanup_snippets.py
Normal file
|
@ -0,0 +1,22 @@
|
|||
import datetime
|
||||
import sys
|
||||
from optparse import make_option
|
||||
from django.core.management.base import CommandError, LabelCommand
|
||||
from pastebin.apps.dpaste.models import Snippet
|
||||
|
||||
class Command(LabelCommand):
|
||||
option_list = LabelCommand.option_list + (
|
||||
make_option('--dry-run', '-d', action='store_true', dest='dry_run',
|
||||
help='Don\'t do anything.'),
|
||||
)
|
||||
help = "Purges snippets that are expired"
|
||||
|
||||
def handle(self, *args, **options):
|
||||
deleteable_snippets = Snippet.objects.filter(expires__lte=datetime.datetime.now())
|
||||
sys.stdout.write(u"%s snippets gets deleted:\n" % deleteable_snippets.count())
|
||||
for d in deleteable_snippets:
|
||||
sys.stdout.write(u"- %s (%s)\n" % (d.secret_id, d.expires))
|
||||
if options.get('dry_run'):
|
||||
sys.stdout.write(u'Dry run - Doing nothing! *crossingfingers*\n')
|
||||
else:
|
||||
deleteable_snippets.delete()
|
48
pastebin/apps/dpaste/models.py
Normal file
48
pastebin/apps/dpaste/models.py
Normal file
|
@ -0,0 +1,48 @@
|
|||
import datetime
|
||||
import difflib
|
||||
import random
|
||||
import mptt
|
||||
from django.db import models
|
||||
from django.db.models import permalink
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from pastebin.apps.dpaste.highlight import LEXER_DEFAULT, pygmentize
|
||||
|
||||
t = 'abcdefghijkmnopqrstuvwwxyzABCDEFGHIJKLOMNOPQRSTUVWXYZ1234567890'
|
||||
def generate_secret_id(length=4):
|
||||
return ''.join([random.choice(t) for i in range(length)])
|
||||
|
||||
class Snippet(models.Model):
|
||||
secret_id = models.CharField(_(u'Secret ID'), max_length=4, blank=True)
|
||||
title = models.CharField(_(u'Title'), max_length=120, blank=True)
|
||||
author = models.CharField(_(u'Author'), max_length=30, blank=True)
|
||||
content = models.TextField(_(u'Content'), )
|
||||
content_highlighted = models.TextField(_(u'Highlighted Content'), blank=True)
|
||||
lexer = models.CharField(_(u'Lexer'), max_length=30, default=LEXER_DEFAULT)
|
||||
published = models.DateTimeField(_(u'Published'), blank=True)
|
||||
expires = models.DateTimeField(_(u'Expires'), blank=True, help_text='asdf')
|
||||
parent = models.ForeignKey('self', null=True, blank=True, related_name='children')
|
||||
|
||||
class Meta:
|
||||
ordering = ('-published',)
|
||||
|
||||
def get_linecount(self):
|
||||
return len(self.content.splitlines())
|
||||
|
||||
def content_splitted(self):
|
||||
return self.content_highlighted.splitlines()
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.pk:
|
||||
self.published = datetime.datetime.now()
|
||||
self.secret_id = generate_secret_id()
|
||||
self.content_highlighted = pygmentize(self.content, self.lexer)
|
||||
super(Snippet, self).save(*args, **kwargs)
|
||||
|
||||
@permalink
|
||||
def get_absolute_url(self):
|
||||
return ('snippet_details', (self.secret_id,))
|
||||
|
||||
def __unicode__(self):
|
||||
return '%s' % self.secret_id
|
||||
|
||||
mptt.register(Snippet, order_insertion_by=['content'])
|
1
pastebin/apps/dpaste/templates/dpaste/base.html
Normal file
1
pastebin/apps/dpaste/templates/dpaste/base.html
Normal file
|
@ -0,0 +1 @@
|
|||
{% extends "base.html" %}
|
174
pastebin/apps/dpaste/templates/dpaste/snippet_details.html
Normal file
174
pastebin/apps/dpaste/templates/dpaste/snippet_details.html
Normal file
|
@ -0,0 +1,174 @@
|
|||
{% extends "dpaste/base.html" %}
|
||||
{% load mptt_tags %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block extrahead %}
|
||||
{% if request.session.userprefs %}
|
||||
<style type="text/css" media="all">
|
||||
.code{
|
||||
{# FIXME: Thats stupid #}
|
||||
{% ifnotequal request.session.userprefs.font_family "None" %}font-family: {{ request.session.userprefs.font_family }} !important;{% endifnotequal %}
|
||||
{% ifnotequal request.session.userprefs.font_size "None" %}font-size: {{ request.session.userprefs.font_size }}px !important;{% endifnotequal %}
|
||||
{% ifnotequal request.session.userprefs.line_height "None" %}line-height: {{ request.session.userprefs.line_height }}px !important;{% endifnotequal %}
|
||||
}
|
||||
</style>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}{% trans "Snippet" %} #{{ snippet.pk }}{% endblock %}
|
||||
{% block headline %}
|
||||
<h1>
|
||||
{% trans "Snippet" %} #{{ snippet.pk }}
|
||||
{% if snippet.parent_id %}
|
||||
{% blocktrans with snippet.parent.get_absolute_url as parent_url and snippet.parent.id as parent_id %}(Copy of <a href="{{ parent_url }}">snippet #{{ parent_id }}</a>){% endblocktrans %}
|
||||
{% endif %}
|
||||
<span class="date">{{ snippet.published|date:_("DATETIME_FORMAT") }} ({% trans "UTC" %})</span>
|
||||
</h1>
|
||||
{% endblock %}
|
||||
{% load dpaste_tags %}
|
||||
|
||||
{% block content %}
|
||||
<div id="diff" style="display:none;">diff</div>
|
||||
|
||||
<div class="accordion">
|
||||
<div class="snippet-options">
|
||||
<abbr title="{% trans "Time to life" %}">TTL:</abbr> {{ snippet.expires|timeuntil }}
|
||||
—
|
||||
{% if snippet.pk|in_list:request.session.snippet_list %}
|
||||
<a onclick="return confirm('{% trans "Really delete this snippet?" %}')" href="{% url snippet_delete snippet.secret_id %}">Delete now!</a>
|
||||
—
|
||||
{% endif %}
|
||||
<a id="toggleWordwrap" href="#">{% trans "Wordwrap" %}</a>
|
||||
</div>
|
||||
<h2>
|
||||
{% if snippet.title %}{{ snippet.title }}{% else %} {% trans "Snippet" %} #{{ snippet.id}}{% endif %}
|
||||
<span>{% if snippet.author %}{% blocktrans with snippet.author as author %}by {{ author }}{% endblocktrans %}{% endif %}</span>
|
||||
</h2>
|
||||
|
||||
<div class="container">
|
||||
<div class="snippet">
|
||||
<table>
|
||||
<tr>
|
||||
<th><pre class="code">{% for l in lines %}<a href="#l{{ forloop.counter }}" id="l{{ forloop.counter }}">{{ forloop.counter }}</a>{% endfor %}</pre></th>
|
||||
<td><pre class="code">{% for line in snippet.content_splitted %}<div class="line" id="l{{ forloop.counter }}">{% if line %}{{ line|safe }}{% else %} {% endif %}</div>{% endfor %}</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>{% trans "Write an answer" %} →</h2>
|
||||
<div class="container" style="display: none;">
|
||||
{% include "dpaste/snippet_form.html" %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
{% block sidebar %}
|
||||
<h2>{% trans "History" %}</h2>
|
||||
|
||||
<form method="get" id="diffform" action="{% url snippet_diff %}">
|
||||
{% csrf_token %}
|
||||
<div class="tree">
|
||||
{% for tree_item,structure in tree|tree_info %}
|
||||
{% if structure.new_level %}<ul><li>{% else %}</li><li>{% endif %}
|
||||
<div>
|
||||
<span class="diff">
|
||||
<input type="radio" name="a" value="{{ tree_item.id }}" {% ifequal tree_item.id snippet.parent_id %}checked="checked"{% endifequal %}/>
|
||||
<input type="radio" name="b" value="{{ tree_item.id }}" {% ifequal snippet tree_item %}checked="checked"{% endifequal %}/>
|
||||
</span>
|
||||
{% ifequal snippet tree_item %}
|
||||
<strong>{% trans "Snippet" %} #{{ tree_item.id }}</strong>
|
||||
{% else %}
|
||||
<a href="{{ tree_item.get_absolute_url }}">{% trans "Snippet" %} #{{ tree_item.id }}</a>
|
||||
{% endifequal %}
|
||||
</div>
|
||||
{% for level in structure.closed_levels %}</li></ul>{% endfor %}
|
||||
{% endfor %}
|
||||
<div class="submit">
|
||||
<input type="submit" value="{% trans "Compare" %}"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<h2>{% trans "Options" %}</h2>
|
||||
<p><a href="{% url snippet_details_raw snippet.secret_id %}">{% trans "View raw" %}</a></p>
|
||||
{% endblock %}
|
||||
|
||||
{% block script_footer %}
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.5.2/jquery-ui.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function(){
|
||||
|
||||
curLine = document.location.hash;
|
||||
if(curLine.substring(0,2) == '#l'){
|
||||
$('div.snippet div.line'+curLine).addClass('marked');
|
||||
}
|
||||
|
||||
$("div.accordion").accordion({
|
||||
autoHeight: false,
|
||||
header: 'h2',
|
||||
animation: 'bounceslide',
|
||||
duration: 2000,
|
||||
});
|
||||
|
||||
/**
|
||||
* Diff Ajax Call
|
||||
*/
|
||||
$("form#diffform").submit(function() {
|
||||
$.get("{% url snippet_diff %}", {
|
||||
a: $("input[name=a]:checked").val(),
|
||||
b: $("input[name=b]:checked").val()
|
||||
}, function(data){
|
||||
$('#diff').html(data).slideDown('fast');
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
/**
|
||||
* Wordwrap
|
||||
*/
|
||||
$('#toggleWordwrap').toggle(
|
||||
function(){
|
||||
$('div.snippet pre.code').css('white-space', 'pre-wrap');
|
||||
return false;
|
||||
},
|
||||
function(){
|
||||
$('div.snippet pre.code').css('white-space', 'pre');
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Line Highlighting
|
||||
*/
|
||||
$('div.snippet th a').each(function(i){
|
||||
$(this).click(function(){
|
||||
var j = $(this).text();
|
||||
$('div.snippet div.line.marked').removeClass('marked');
|
||||
$('div.snippet div.line#l'+j).toggleClass('marked');
|
||||
});
|
||||
});
|
||||
|
||||
{% if request.session.userprefs.display_all_lexer %}
|
||||
/**
|
||||
* Lexer Guessing
|
||||
*/
|
||||
$('#guess_lexer_btn').click(function(){
|
||||
$.getJSON('{% url snippet_guess_lexer %}',
|
||||
{'codestring': $('#id_content').val()},
|
||||
function(data){
|
||||
if(data.lexer == "unknown"){
|
||||
$('#guess_lexer_btn').css('color', 'red');
|
||||
}else{
|
||||
$('#id_lexer').val(data.lexer);
|
||||
$('#guess_lexer_btn').css('color', 'inherit');
|
||||
}
|
||||
});
|
||||
});
|
||||
{% endif %}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -0,0 +1 @@
|
|||
{{ snippet.content|safe }}
|
13
pastebin/apps/dpaste/templates/dpaste/snippet_diff.html
Normal file
13
pastebin/apps/dpaste/templates/dpaste/snippet_diff.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
{% load i18n %}
|
||||
|
||||
<h2>
|
||||
<span style="float:right;">(<a href="#" onclick="$('#diff').slideUp('fast'); return false;">{% trans "Close" %}</a>)</span>
|
||||
{% blocktrans with fileA.get_absolute_url as filea_url and fileB.get_absolute_url as fileb_url and fileA.id as filea_id and fileB.id as fileb_id %}
|
||||
Diff between
|
||||
<a href="{{ filea_url }}">Snippet #{{ filea_id }}</a>
|
||||
and
|
||||
<a href="{{ fileb_url }}">Snippet #{{ fileb_id }}</a>
|
||||
{% endblocktrans %}
|
||||
</h2>
|
||||
|
||||
<pre class="code">{{ difftext|safe }}</pre>
|
19
pastebin/apps/dpaste/templates/dpaste/snippet_form.html
Normal file
19
pastebin/apps/dpaste/templates/dpaste/snippet_form.html
Normal file
|
@ -0,0 +1,19 @@
|
|||
{% load i18n %}
|
||||
<form method="post" action="." class="snippetform">
|
||||
{% csrf_token %}
|
||||
<ol>
|
||||
{% for field in snippet_form %}
|
||||
<li>
|
||||
{{ field.errors }}
|
||||
{{ field.label_tag }}
|
||||
{{ field }}
|
||||
{% if request.session.userprefs.display_all_lexer %}
|
||||
{% ifequal field.name "lexer" %}
|
||||
<input type="button" value="{% trans "Guess lexer" %}" id="guess_lexer_btn"/>
|
||||
{% endifequal %}
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
<li class="submit"><input type="submit" value="{% trans "Paste it" %}"/></li>
|
||||
</ol>
|
||||
</form>
|
26
pastebin/apps/dpaste/templates/dpaste/snippet_list.html
Normal file
26
pastebin/apps/dpaste/templates/dpaste/snippet_list.html
Normal file
|
@ -0,0 +1,26 @@
|
|||
{% extends "dpaste/base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "Snippet" %} #{{ snippet.pk }}{% endblock %}
|
||||
{% block headline %}
|
||||
<h1>{% blocktrans %}Your latest {{ snippets_max }} snippets{% endblocktrans %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if snippet_list %}
|
||||
{% for snippet in snippet_list %}
|
||||
<h2>
|
||||
<a href="{{ snippet.get_absolute_url }}">{% trans "Snippet" %} #{{ snippet.pk }}</a>
|
||||
~ {{ snippet.published|date:_("DATETIME_FORMAT") }}
|
||||
</h2>
|
||||
<p style="color: #555; margin: 8px 0 20px 0;">{{ snippet.content|truncatewords:40 }}</p>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<p>{% trans "No snippets available." %}</p>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<div class="hint">
|
||||
{% trans "DATA_STORED_IN_A_COOKIE_HINT" %}
|
||||
</div>
|
||||
{% endblock %}
|
39
pastebin/apps/dpaste/templates/dpaste/snippet_new.html
Normal file
39
pastebin/apps/dpaste/templates/dpaste/snippet_new.html
Normal file
|
@ -0,0 +1,39 @@
|
|||
{% extends "dpaste/base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "New snippet" %}{% endblock %}
|
||||
{% block headline %}<h1>{% trans "Paste a new snippet" %}</h1>{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>{% trans "New snippet" %}</h2>
|
||||
{% include "dpaste/snippet_form.html" %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block sidebar %}
|
||||
<h2>{% trans "DPASTE_HOMEPAGE_TITLE" %}</h2>
|
||||
<p>{% trans "DPASTE_HOMEPAGE_DESCRIPTION" %}</p>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block script_footer %}
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
jQuery(document).ready(function(){
|
||||
{% if request.session.userprefs.display_all_lexer %}
|
||||
$('#guess_lexer_btn').click(function(){
|
||||
$.getJSON('{% url snippet_guess_lexer %}',
|
||||
{'codestring': $('#id_content').val()},
|
||||
function(data){
|
||||
if(data.lexer == "unknown"){
|
||||
$('#guess_lexer_btn').css('color', 'red');
|
||||
}else{
|
||||
$('#id_lexer').val(data.lexer);
|
||||
$('#guess_lexer_btn').css('color', 'inherit');
|
||||
}
|
||||
});
|
||||
});
|
||||
{% endif %}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
28
pastebin/apps/dpaste/templates/dpaste/userprefs.html
Normal file
28
pastebin/apps/dpaste/templates/dpaste/userprefs.html
Normal file
|
@ -0,0 +1,28 @@
|
|||
{% extends "dpaste/base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block headline %}
|
||||
<h1>{% trans "User Settings" %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if settings_saved %}
|
||||
<div class="success">
|
||||
{% trans "USER_PREFS_SAVED_SUCCESSFULLY" %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<h2>{% trans "User Settings" %}</h2>
|
||||
|
||||
<form class="snippetform" method="post" action=".">
|
||||
{% csrf_token %}
|
||||
<ol>
|
||||
{{ settings_form.as_ul }}
|
||||
<li class="submit"><input type="submit" value="{% trans "Save settings" %}"/></li>
|
||||
</ol>
|
||||
</form>
|
||||
|
||||
<div class="hint">
|
||||
{% trans "DATA_STORED_IN_A_COOKIE_HINT" %}
|
||||
</div>
|
||||
{% endblock %}
|
1
pastebin/apps/dpaste/templatetags/__init__.py
Normal file
1
pastebin/apps/dpaste/templatetags/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
__version__ = '0.1'
|
7
pastebin/apps/dpaste/templatetags/dpaste_tags.py
Normal file
7
pastebin/apps/dpaste/templatetags/dpaste_tags.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
from django.template import Library
|
||||
|
||||
register = Library()
|
||||
|
||||
@register.filter
|
||||
def in_list(value,arg):
|
||||
return value in arg
|
14
pastebin/apps/dpaste/urls.py
Normal file
14
pastebin/apps/dpaste/urls.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
from django.conf.urls.defaults import patterns, url
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
urlpatterns = patterns('pastebin.apps.dpaste.views',
|
||||
url(r'^$', 'snippet_new', name='snippet_new'),
|
||||
url(r'^guess/$', 'guess_lexer', name='snippet_guess_lexer'),
|
||||
url(r'^diff/$', 'snippet_diff', name='snippet_diff'),
|
||||
url(r'^your-latest/$', 'snippet_userlist', name='snippet_userlist'),
|
||||
url(r'^your-settings/$', 'userprefs', name='snippet_userprefs'),
|
||||
url(r'^(?P<snippet_id>[a-zA-Z0-9]{4})/$', 'snippet_details', name='snippet_details'),
|
||||
url(r'^(?P<snippet_id>[a-zA-Z0-9]{4})/delete/$', 'snippet_delete', name='snippet_delete'),
|
||||
url(r'^(?P<snippet_id>[a-zA-Z0-9]{4})/raw/$', 'snippet_details', {'template_name': 'dpaste/snippet_details_raw.html', 'is_raw': True}, name='snippet_details_raw'),
|
||||
)
|
165
pastebin/apps/dpaste/views.py
Normal file
165
pastebin/apps/dpaste/views.py
Normal file
|
@ -0,0 +1,165 @@
|
|||
from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404
|
||||
from django.template.context import RequestContext
|
||||
from django.http import HttpResponseRedirect, HttpResponseBadRequest, HttpResponse, HttpResponseForbidden
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from pastebin.apps.dpaste.forms import SnippetForm, UserSettingsForm
|
||||
from pastebin.apps.dpaste.models import Snippet
|
||||
from pastebin.apps.dpaste.highlight import pygmentize, guess_code_lexer
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils import simplejson
|
||||
import difflib
|
||||
|
||||
def snippet_new(request, template_name='dpaste/snippet_new.html'):
|
||||
|
||||
if request.method == "POST":
|
||||
snippet_form = SnippetForm(data=request.POST, request=request)
|
||||
if snippet_form.is_valid():
|
||||
request, new_snippet = snippet_form.save()
|
||||
return HttpResponseRedirect(new_snippet.get_absolute_url())
|
||||
else:
|
||||
snippet_form = SnippetForm(request=request)
|
||||
|
||||
template_context = {
|
||||
'snippet_form': snippet_form,
|
||||
}
|
||||
|
||||
return render_to_response(
|
||||
template_name,
|
||||
template_context,
|
||||
RequestContext(request)
|
||||
)
|
||||
|
||||
|
||||
def snippet_details(request, snippet_id, template_name='dpaste/snippet_details.html', is_raw=False):
|
||||
|
||||
snippet = get_object_or_404(Snippet, secret_id=snippet_id)
|
||||
|
||||
tree = snippet.get_root()
|
||||
tree = tree.get_descendants(include_self=True)
|
||||
|
||||
new_snippet_initial = {
|
||||
'content': snippet.content,
|
||||
'lexer': snippet.lexer,
|
||||
}
|
||||
|
||||
if request.method == "POST":
|
||||
snippet_form = SnippetForm(data=request.POST, request=request, initial=new_snippet_initial)
|
||||
if snippet_form.is_valid():
|
||||
request, new_snippet = snippet_form.save(parent=snippet)
|
||||
return HttpResponseRedirect(new_snippet.get_absolute_url())
|
||||
else:
|
||||
snippet_form = SnippetForm(initial=new_snippet_initial, request=request)
|
||||
|
||||
template_context = {
|
||||
'snippet_form': snippet_form,
|
||||
'snippet': snippet,
|
||||
'lines': range(snippet.get_linecount()),
|
||||
'tree': tree,
|
||||
}
|
||||
|
||||
response = render_to_response(
|
||||
template_name,
|
||||
template_context,
|
||||
RequestContext(request)
|
||||
)
|
||||
|
||||
if is_raw:
|
||||
response['Content-Type'] = 'text/plain'
|
||||
return response
|
||||
else:
|
||||
return response
|
||||
|
||||
def snippet_delete(request, snippet_id):
|
||||
snippet = get_object_or_404(Snippet, secret_id=snippet_id)
|
||||
try:
|
||||
snippet_list = request.session['snippet_list']
|
||||
except KeyError:
|
||||
return HttpResponseForbidden('You have no recent snippet list, cookie error?')
|
||||
if not snippet.pk in snippet_list:
|
||||
return HttpResponseForbidden('That\'s not your snippet, sucka!')
|
||||
snippet.delete()
|
||||
return HttpResponseRedirect(reverse('snippet_new'))
|
||||
|
||||
def snippet_userlist(request, template_name='dpaste/snippet_list.html'):
|
||||
|
||||
try:
|
||||
snippet_list = get_list_or_404(Snippet, pk__in=request.session.get('snippet_list', None))
|
||||
except ValueError:
|
||||
snippet_list = None
|
||||
|
||||
template_context = {
|
||||
'snippets_max': getattr(settings, 'MAX_SNIPPETS_PER_USER', 10),
|
||||
'snippet_list': snippet_list,
|
||||
}
|
||||
|
||||
return render_to_response(
|
||||
template_name,
|
||||
template_context,
|
||||
RequestContext(request)
|
||||
)
|
||||
|
||||
|
||||
def userprefs(request, template_name='dpaste/userprefs.html'):
|
||||
|
||||
if request.method == 'POST':
|
||||
settings_form = UserSettingsForm(request.POST, initial=request.session.get('userprefs', None))
|
||||
if settings_form.is_valid():
|
||||
request.session['userprefs'] = settings_form.cleaned_data
|
||||
settings_saved = True
|
||||
else:
|
||||
settings_form = UserSettingsForm(initial=request.session.get('userprefs', None))
|
||||
settings_saved = False
|
||||
|
||||
template_context = {
|
||||
'settings_form': settings_form,
|
||||
'settings_saved': settings_saved,
|
||||
}
|
||||
|
||||
return render_to_response(
|
||||
template_name,
|
||||
template_context,
|
||||
RequestContext(request)
|
||||
)
|
||||
|
||||
def snippet_diff(request, template_name='dpaste/snippet_diff.html'):
|
||||
|
||||
if request.GET.get('a').isdigit() and request.GET.get('b').isdigit():
|
||||
try:
|
||||
fileA = Snippet.objects.get(pk=int(request.GET.get('a')))
|
||||
fileB = Snippet.objects.get(pk=int(request.GET.get('b')))
|
||||
except ObjectDoesNotExist:
|
||||
return HttpResponseBadRequest(u'Selected file(s) does not exist.')
|
||||
else:
|
||||
return HttpResponseBadRequest(u'You must select two snippets.')
|
||||
|
||||
if fileA.content != fileB.content:
|
||||
d = difflib.unified_diff(
|
||||
fileA.content.splitlines(),
|
||||
fileB.content.splitlines(),
|
||||
'Original',
|
||||
'Current',
|
||||
lineterm=''
|
||||
)
|
||||
difftext = '\n'.join(d)
|
||||
difftext = pygmentize(difftext, 'diff')
|
||||
else:
|
||||
difftext = _(u'No changes were made between this two files.')
|
||||
|
||||
template_context = {
|
||||
'difftext': difftext,
|
||||
'fileA': fileA,
|
||||
'fileB': fileB,
|
||||
}
|
||||
|
||||
return render_to_response(
|
||||
template_name,
|
||||
template_context,
|
||||
RequestContext(request)
|
||||
)
|
||||
|
||||
def guess_lexer(request):
|
||||
code_string = request.GET.get('codestring', False)
|
||||
response = simplejson.dumps({'lexer': guess_code_lexer(code_string)})
|
||||
return HttpResponse(response)
|
40
pastebin/bin/manage.py
Executable file
40
pastebin/bin/manage.py
Executable file
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env python
|
||||
import os
|
||||
import sys
|
||||
from django import get_version
|
||||
from django.core.management import execute_from_command_line, LaxOptionParser
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
# Work out the project module name and root directory, assuming that this file
|
||||
# is located at [project]/bin/manage.py
|
||||
PROJECT_DIR, PROJECT_MODULE_NAME = os.path.split(
|
||||
os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
|
||||
|
||||
# Check that the project module can be imported.
|
||||
try:
|
||||
__import__(PROJECT_MODULE_NAME)
|
||||
except ImportError:
|
||||
# Couldn't import the project, place it on the Python path and try again.
|
||||
sys.path.append(PROJECT_DIR)
|
||||
try:
|
||||
__import__(PROJECT_MODULE_NAME)
|
||||
except ImportError:
|
||||
sys.stderr.write("Error: Can't import the \"%s\" project module." %
|
||||
PROJECT_MODULE_NAME)
|
||||
sys.exit(1)
|
||||
|
||||
def has_settings_option():
|
||||
parser = LaxOptionParser(usage="%prog subcommand [options] [args]",
|
||||
version=get_version(),
|
||||
option_list=BaseCommand.option_list)
|
||||
try:
|
||||
options = parser.parse_args(sys.argv[:])[0]
|
||||
except:
|
||||
return False # Ignore any option errors at this point.
|
||||
return bool(options.settings)
|
||||
|
||||
if not has_settings_option() and not 'DJANGO_SETTINGS_MODULE' in os.environ:
|
||||
settings_module = '%s.conf.local.settings' % PROJECT_MODULE_NAME
|
||||
os.environ['DJANGO_SETTINGS_MODULE'] = settings_module
|
||||
|
||||
execute_from_command_line()
|
0
pastebin/conf/__init__.py
Normal file
0
pastebin/conf/__init__.py
Normal file
0
pastebin/conf/common/__init__.py
Normal file
0
pastebin/conf/common/__init__.py
Normal file
0
pastebin/conf/common/urls/__init__.py
Normal file
0
pastebin/conf/common/urls/__init__.py
Normal file
9
pastebin/conf/common/urls/admin.py
Normal file
9
pastebin/conf/common/urls/admin.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
from django.conf.urls.defaults import patterns, include
|
||||
from django.contrib import admin
|
||||
|
||||
admin.autodiscover()
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^admin/doc/', include('django.contrib.admindocs.urls')),
|
||||
(r'^admin/', include(admin.site.urls)),
|
||||
)
|
0
pastebin/conf/dev/__init__.py
Normal file
0
pastebin/conf/dev/__init__.py
Normal file
17
pastebin/conf/dev/settings.py
Normal file
17
pastebin/conf/dev/settings.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
from pastebin.conf.settings import *
|
||||
|
||||
DEBUG = True
|
||||
TEMPLATE_DEBUG = DEBUG
|
||||
|
||||
ROOT_URLCONF = 'pastebin.conf.dev.urls'
|
||||
|
||||
MEDIA_ROOT = os.path.join(VAR_ROOT, 'uploads')
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.postgresql_psycopg2',
|
||||
'NAME': 'pastebin',
|
||||
# 'USER': 'dbuser',
|
||||
# 'PASSWORD': 'dbpassword',
|
||||
}
|
||||
}
|
9
pastebin/conf/dev/urls.py
Normal file
9
pastebin/conf/dev/urls.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
from django.conf.urls.defaults import *
|
||||
from django.conf import settings
|
||||
|
||||
CONF_MODULE = '%s.conf' % settings.PROJECT_MODULE_NAME
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'', include('%s.urls' % CONF_MODULE)),
|
||||
(r'', include('%s.common.urls.admin' % CONF_MODULE)),
|
||||
)
|
105
pastebin/conf/settings.py
Normal file
105
pastebin/conf/settings.py
Normal file
|
@ -0,0 +1,105 @@
|
|||
# Import global settings to make it easier to extend settings.
|
||||
from django.conf.global_settings import *
|
||||
|
||||
#==============================================================================
|
||||
# Generic Django project settings
|
||||
#==============================================================================
|
||||
|
||||
DEBUG = False
|
||||
TEMPLATE_DEBUG = DEBUG
|
||||
|
||||
# Local time zone for this installation. Choices can be found here:
|
||||
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
|
||||
TIME_ZONE = 'America/Chicago'
|
||||
USE_I18N = True
|
||||
SITE_ID = 1
|
||||
|
||||
# Make this unique, and don't share it with anybody.
|
||||
SECRET_KEY = ''
|
||||
|
||||
#==============================================================================
|
||||
# I18N
|
||||
#==============================================================================
|
||||
|
||||
USE_I18N = True
|
||||
USE_L10N = False
|
||||
|
||||
LANGUAGE_CODE = 'en'
|
||||
LANGUAGES = (
|
||||
('en', 'English'),
|
||||
)
|
||||
|
||||
#==============================================================================
|
||||
# Calculation of directories relative to the module location
|
||||
#==============================================================================
|
||||
import os
|
||||
import sys
|
||||
import pastebin
|
||||
|
||||
PROJECT_DIR, PROJECT_MODULE_NAME = os.path.split(
|
||||
os.path.dirname(os.path.realpath(pastebin.__file__))
|
||||
)
|
||||
|
||||
PYTHON_BIN = os.path.dirname(sys.executable)
|
||||
if os.path.exists(os.path.join(PYTHON_BIN, 'activate_this.py')):
|
||||
# Assume that the presence of 'activate_this.py' in the python bin/
|
||||
# directory means that we're running in a virtual environment. Set the
|
||||
# variable root to $VIRTUALENV/var.
|
||||
VAR_ROOT = os.path.join(os.path.dirname(PYTHON_BIN), 'var')
|
||||
if not os.path.exists(VAR_ROOT):
|
||||
os.mkdir(VAR_ROOT)
|
||||
else:
|
||||
# Set the variable root to the local configuration location (which is
|
||||
# ignored by the repository).
|
||||
VAR_ROOT = os.path.join(PROJECT_DIR, PROJECT_MODULE_NAME, 'conf', 'local')
|
||||
|
||||
#==============================================================================
|
||||
# Static files
|
||||
#==============================================================================
|
||||
|
||||
STATIC_ROOT = os.path.join(VAR_ROOT, 'static')
|
||||
|
||||
#==============================================================================
|
||||
# Project URLS and media settings
|
||||
#==============================================================================
|
||||
|
||||
MEDIA_URL = '/uploads/'
|
||||
STATIC_URL = '/static/'
|
||||
ADMIN_MEDIA_PREFIX = '/static/admin/'
|
||||
|
||||
MEDIA_ROOT = os.path.join(VAR_ROOT, 'uploads')
|
||||
|
||||
ROOT_URLCONF = 'pastebin.conf.urls'
|
||||
|
||||
LOGIN_URL = '/accounts/login/'
|
||||
LOGOUT_URL = '/accounts/logout/'
|
||||
LOGIN_REDIRECT_URL = '/'
|
||||
|
||||
#==============================================================================
|
||||
# Templates
|
||||
#==============================================================================
|
||||
|
||||
TEMPLATE_DIRS = (
|
||||
os.path.join(PROJECT_DIR, PROJECT_MODULE_NAME, 'templates'),
|
||||
)
|
||||
|
||||
INSTALLED_APPS = (
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.sites',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.staticfiles',
|
||||
'mptt',
|
||||
'piston',
|
||||
'pastebin',
|
||||
'pastebin.apps.dpaste',
|
||||
)
|
||||
|
||||
#==============================================================================
|
||||
# App specific settings
|
||||
#==============================================================================
|
||||
|
||||
# How many recent snippets to save for every user? IDs of this snippets are
|
||||
# stored in the user session.
|
||||
MAX_SNIPPETS_PER_USER = 25
|
0
pastebin/conf/test/__init__.py
Normal file
0
pastebin/conf/test/__init__.py
Normal file
16
pastebin/conf/test/settings.py
Normal file
16
pastebin/conf/test/settings.py
Normal file
|
@ -0,0 +1,16 @@
|
|||
from pastebin.conf.settings import *
|
||||
|
||||
DEBUG = False
|
||||
TEMPLATE_DEBUG = DEBUG
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': ':memory:',
|
||||
}
|
||||
}
|
||||
ROOT_URLCONF = 'pastebin.conf.test.urls'
|
||||
|
||||
INSTALLED_APPS += ('django_nose',)
|
||||
|
||||
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
|
9
pastebin/conf/test/urls.py
Normal file
9
pastebin/conf/test/urls.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
from django.conf.urls.defaults import *
|
||||
from django.conf import settings
|
||||
|
||||
CONF_MODULE = '%s.conf' % settings.PROJECT_MODULE_NAME
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'', include('%s.urls' % CONF_MODULE)),
|
||||
(r'', include('%s.common.urls.admin' % CONF_MODULE)),
|
||||
)
|
26
pastebin/conf/urls.py
Normal file
26
pastebin/conf/urls.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
from django.conf.urls.defaults import *
|
||||
from django.conf import settings
|
||||
from django.contrib import admin
|
||||
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||
from piston.resource import Resource
|
||||
from pastebin.apps.api.handlers import SnippetHandler
|
||||
|
||||
admin.autodiscover()
|
||||
snippet_resource = Resource(handler=SnippetHandler)
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^', include('pastebin.apps.dpaste.urls')),
|
||||
|
||||
# Static
|
||||
url(r'^about/$', 'django.views.generic.simple.direct_to_template', {'template': 'about.html'}, name='about'),
|
||||
|
||||
# Bla
|
||||
(r'^i18n/', include('django.conf.urls.i18n')),
|
||||
(r'^admin/(.*)', include(admin.site.urls)),
|
||||
|
||||
# API
|
||||
url(r'^api/(?P<secret_id>[^/]+)/$', snippet_resource),
|
||||
url(r'^api/$', snippet_resource),
|
||||
)
|
||||
|
||||
urlpatterns += staticfiles_urlpatterns()
|
BIN
pastebin/locale/de/LC_MESSAGES/django.mo
Normal file
BIN
pastebin/locale/de/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
253
pastebin/locale/de/LC_MESSAGES/django.po
Normal file
253
pastebin/locale/de/LC_MESSAGES/django.po
Normal file
|
@ -0,0 +1,253 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: dpaste\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-05-29 17:48-0500\n"
|
||||
"PO-Revision-Date: 2011-05-30 00:56+0100\n"
|
||||
"Last-Translator: Martin Mahner <martin@mahner.org>\n"
|
||||
"Language-Team: de <martin@mahner.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
"X-Poedit-Language: German\n"
|
||||
"X-Poedit-Country: GERMANY\n"
|
||||
"X-Poedit-SourceCharset: utf-8\n"
|
||||
|
||||
#: apps/dpaste/forms.py:13
|
||||
msgid "In one hour"
|
||||
msgstr "In einer Stunde"
|
||||
|
||||
#: apps/dpaste/forms.py:14
|
||||
msgid "In one week"
|
||||
msgstr "In einer Woche"
|
||||
|
||||
#: apps/dpaste/forms.py:15
|
||||
msgid "In one month"
|
||||
msgstr "In einem Monat"
|
||||
|
||||
#: apps/dpaste/forms.py:16
|
||||
msgid "Save forever"
|
||||
msgstr "Für immer"
|
||||
|
||||
#: apps/dpaste/forms.py:26
|
||||
#: apps/dpaste/models.py:20
|
||||
msgid "Lexer"
|
||||
msgstr "Syntax"
|
||||
|
||||
#: apps/dpaste/forms.py:32
|
||||
#: apps/dpaste/models.py:22
|
||||
msgid "Expires"
|
||||
msgstr "Verfällt"
|
||||
|
||||
#: apps/dpaste/forms.py:87
|
||||
#: apps/dpaste/forms.py:96
|
||||
msgid "Default"
|
||||
msgstr "Standard"
|
||||
|
||||
#: apps/dpaste/forms.py:100
|
||||
msgid "Default Name"
|
||||
msgstr "Standardname"
|
||||
|
||||
#: apps/dpaste/forms.py:102
|
||||
msgid "Display all lexer"
|
||||
msgstr "Alle Syntax anzeigen"
|
||||
|
||||
#: apps/dpaste/forms.py:105
|
||||
msgid "This also enables the super secret 'guess lexer' function."
|
||||
msgstr "Dies aktiviert auch die super geheime 'Syntax erraten' Funktion."
|
||||
|
||||
#: apps/dpaste/forms.py:107
|
||||
msgid "Font Family"
|
||||
msgstr "Schriftart"
|
||||
|
||||
#: apps/dpaste/forms.py:108
|
||||
msgid "Font Size"
|
||||
msgstr "Schriftgröße"
|
||||
|
||||
#: apps/dpaste/forms.py:109
|
||||
msgid "Line Height"
|
||||
msgstr "Zeilenhöhe"
|
||||
|
||||
#: apps/dpaste/models.py:15
|
||||
msgid "Secret ID"
|
||||
msgstr "Geheime ID"
|
||||
|
||||
#: apps/dpaste/models.py:16
|
||||
msgid "Title"
|
||||
msgstr "Titel"
|
||||
|
||||
#: apps/dpaste/models.py:17
|
||||
msgid "Author"
|
||||
msgstr "Autor"
|
||||
|
||||
#: apps/dpaste/models.py:18
|
||||
msgid "Content"
|
||||
msgstr "Inhalt"
|
||||
|
||||
#: apps/dpaste/models.py:19
|
||||
msgid "Highlighted Content"
|
||||
msgstr "Gefärbter Inhalt"
|
||||
|
||||
#: apps/dpaste/models.py:21
|
||||
msgid "Published"
|
||||
msgstr "Veröffentlicht"
|
||||
|
||||
#: apps/dpaste/views.py:148
|
||||
msgid "No changes were made between this two files."
|
||||
msgstr "Zwischen diesen Dateien wurden keine Änderungen vorgenommen."
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:18
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:21
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:44
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:82
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:84
|
||||
#: apps/dpaste/templates/dpaste/snippet_list.html:4
|
||||
#: apps/dpaste/templates/dpaste/snippet_list.html:13
|
||||
msgid "Snippet"
|
||||
msgstr "Snippet"
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:23
|
||||
#, python-format
|
||||
msgid "(Copy of <a href=\"%(parent_url)s\">snippet #%(parent_id)s</a>)"
|
||||
msgstr "(Kopie von <a href=\"%(parent_url)s\">Snippet #%(parent_id)s</a>)"
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:25
|
||||
#: apps/dpaste/templates/dpaste/snippet_list.html:14
|
||||
msgid "DATETIME_FORMAT"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:25
|
||||
msgid "UTC"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:35
|
||||
msgid "Time to life"
|
||||
msgstr "Time to live"
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:38
|
||||
msgid "Really delete this snippet?"
|
||||
msgstr "Dieses Snippet wirklich löschen?"
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:41
|
||||
msgid "Wordwrap"
|
||||
msgstr "Wordwrap"
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:45
|
||||
#, python-format
|
||||
msgid "by %(author)s"
|
||||
msgstr "von %(author)s"
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:59
|
||||
msgid "Write an answer"
|
||||
msgstr "Eine Antwort schreiben"
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:69
|
||||
msgid "History"
|
||||
msgstr "Geschichte"
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:90
|
||||
msgid "Compare"
|
||||
msgstr "Vergleichen"
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:95
|
||||
msgid "Options"
|
||||
msgstr "Einstellungen"
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:96
|
||||
msgid "View raw"
|
||||
msgstr "Rohformat"
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_diff.html:4
|
||||
msgid "Close"
|
||||
msgstr "Schließen"
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_diff.html:5
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" Diff between\n"
|
||||
" <a href=\"%(filea_url)s\">Snippet #%(filea_id)s</a>\n"
|
||||
" and\n"
|
||||
" <a href=\"%(fileb_url)s\">Snippet #%(fileb_id)s</a>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
" Diff zwischen\n"
|
||||
" <a href=\"%(filea_url)s\">Snippet #%(filea_id)s</a>\n"
|
||||
" und\n"
|
||||
" <a href=\"%(fileb_url)s\">Snippet #%(fileb_id)s</a>\n"
|
||||
" "
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_form.html:12
|
||||
msgid "Guess lexer"
|
||||
msgstr "Syntax erraten"
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_form.html:17
|
||||
msgid "Paste it"
|
||||
msgstr "Paste it"
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_list.html:6
|
||||
#, python-format
|
||||
msgid "Your latest %(snippets_max)s snippets"
|
||||
msgstr "Deine letzten %(snippets_max)s Snippets"
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_list.html:19
|
||||
msgid "No snippets available."
|
||||
msgstr "Keine Snippets verfügbar."
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_list.html:24
|
||||
#: apps/dpaste/templates/dpaste/userprefs.html:26
|
||||
msgid "DATA_STORED_IN_A_COOKIE_HINT"
|
||||
msgstr "Deine Daten werden in einem Cookie gespeichert."
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_new.html:4
|
||||
#: apps/dpaste/templates/dpaste/snippet_new.html:8
|
||||
#: templates/base.html:9
|
||||
#: templates/base.html.py:16
|
||||
msgid "New snippet"
|
||||
msgstr "Neues Snippet"
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_new.html:5
|
||||
msgid "Paste a new snippet"
|
||||
msgstr "Paste ein neues Snippet"
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_new.html:14
|
||||
msgid "DPASTE_HOMEPAGE_TITLE"
|
||||
msgstr " "
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_new.html:15
|
||||
msgid "DPASTE_HOMEPAGE_DESCRIPTION"
|
||||
msgstr " "
|
||||
|
||||
#: apps/dpaste/templates/dpaste/userprefs.html:5
|
||||
#: apps/dpaste/templates/dpaste/userprefs.html:15
|
||||
msgid "User Settings"
|
||||
msgstr "Einstellungen"
|
||||
|
||||
#: apps/dpaste/templates/dpaste/userprefs.html:11
|
||||
msgid "USER_PREFS_SAVED_SUCCESSFULLY"
|
||||
msgstr "Deine Einstellungen wurden gespeichert."
|
||||
|
||||
#: apps/dpaste/templates/dpaste/userprefs.html:21
|
||||
msgid "Save settings"
|
||||
msgstr "Einstellungen speichern"
|
||||
|
||||
#: templates/base.html:38
|
||||
msgid "Recent snippets"
|
||||
msgstr "Letzte Snippets"
|
||||
|
||||
#: templates/base.html:39
|
||||
msgid "Settings"
|
||||
msgstr "Einstellungen"
|
||||
|
||||
#: templates/base.html:40
|
||||
#, fuzzy
|
||||
msgid "About"
|
||||
msgstr "Über"
|
||||
|
BIN
pastebin/locale/en/LC_MESSAGES/django.mo
Normal file
BIN
pastebin/locale/en/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
246
pastebin/locale/en/LC_MESSAGES/django.po
Normal file
246
pastebin/locale/en/LC_MESSAGES/django.po
Normal file
|
@ -0,0 +1,246 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: dpaste\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2011-05-29 17:48-0500\n"
|
||||
"PO-Revision-Date: 2011-05-30 01:01+0100\n"
|
||||
"Last-Translator: Martin Mahner <martin@mahner.org>\n"
|
||||
"Language-Team: en <martin@mahner.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
"X-Poedit-Language: German\n"
|
||||
"X-Poedit-Country: GERMANY\n"
|
||||
"X-Poedit-SourceCharset: utf-8\n"
|
||||
|
||||
#: apps/dpaste/forms.py:13
|
||||
msgid "In one hour"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/forms.py:14
|
||||
msgid "In one week"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/forms.py:15
|
||||
msgid "In one month"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/forms.py:16
|
||||
msgid "Save forever"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/forms.py:26
|
||||
#: apps/dpaste/models.py:20
|
||||
msgid "Lexer"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/forms.py:32
|
||||
#: apps/dpaste/models.py:22
|
||||
msgid "Expires"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/forms.py:87
|
||||
#: apps/dpaste/forms.py:96
|
||||
msgid "Default"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/forms.py:100
|
||||
msgid "Default Name"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/forms.py:102
|
||||
msgid "Display all lexer"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/forms.py:105
|
||||
msgid "This also enables the super secret 'guess lexer' function."
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/forms.py:107
|
||||
msgid "Font Family"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/forms.py:108
|
||||
msgid "Font Size"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/forms.py:109
|
||||
msgid "Line Height"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/models.py:15
|
||||
msgid "Secret ID"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/models.py:16
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/models.py:17
|
||||
msgid "Author"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/models.py:18
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/models.py:19
|
||||
msgid "Highlighted Content"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/models.py:21
|
||||
msgid "Published"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/views.py:148
|
||||
msgid "No changes were made between this two files."
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:18
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:21
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:44
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:82
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:84
|
||||
#: apps/dpaste/templates/dpaste/snippet_list.html:4
|
||||
#: apps/dpaste/templates/dpaste/snippet_list.html:13
|
||||
msgid "Snippet"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:23
|
||||
#, python-format
|
||||
msgid "(Copy of <a href=\"%(parent_url)s\">snippet #%(parent_id)s</a>)"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:25
|
||||
#: apps/dpaste/templates/dpaste/snippet_list.html:14
|
||||
msgid "DATETIME_FORMAT"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:25
|
||||
msgid "UTC"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:35
|
||||
msgid "Time to life"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:38
|
||||
msgid "Really delete this snippet?"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:41
|
||||
msgid "Wordwrap"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:45
|
||||
#, python-format
|
||||
msgid "by %(author)s"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:59
|
||||
msgid "Write an answer"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:69
|
||||
msgid "History"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:90
|
||||
msgid "Compare"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:95
|
||||
msgid "Options"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_details.html:96
|
||||
msgid "View raw"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_diff.html:4
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_diff.html:5
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" Diff between\n"
|
||||
" <a href=\"%(filea_url)s\">Snippet #%(filea_id)s</a>\n"
|
||||
" and\n"
|
||||
" <a href=\"%(fileb_url)s\">Snippet #%(fileb_id)s</a>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_form.html:12
|
||||
msgid "Guess lexer"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_form.html:17
|
||||
msgid "Paste it"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_list.html:6
|
||||
#, python-format
|
||||
msgid "Your latest %(snippets_max)s snippets"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_list.html:19
|
||||
msgid "No snippets available."
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_list.html:24
|
||||
#: apps/dpaste/templates/dpaste/userprefs.html:26
|
||||
msgid "DATA_STORED_IN_A_COOKIE_HINT"
|
||||
msgstr "Your data is stored in a cookie."
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_new.html:4
|
||||
#: apps/dpaste/templates/dpaste/snippet_new.html:8
|
||||
#: templates/base.html:9
|
||||
#: templates/base.html.py:16
|
||||
msgid "New snippet"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_new.html:5
|
||||
msgid "Paste a new snippet"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_new.html:14
|
||||
msgid "DPASTE_HOMEPAGE_TITLE"
|
||||
msgstr "dpaste.de"
|
||||
|
||||
#: apps/dpaste/templates/dpaste/snippet_new.html:15
|
||||
msgid "DPASTE_HOMEPAGE_DESCRIPTION"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/userprefs.html:5
|
||||
#: apps/dpaste/templates/dpaste/userprefs.html:15
|
||||
msgid "User Settings"
|
||||
msgstr ""
|
||||
|
||||
#: apps/dpaste/templates/dpaste/userprefs.html:11
|
||||
msgid "USER_PREFS_SAVED_SUCCESSFULLY"
|
||||
msgstr "Your settings were saved."
|
||||
|
||||
#: apps/dpaste/templates/dpaste/userprefs.html:21
|
||||
msgid "Save settings"
|
||||
msgstr ""
|
||||
|
||||
#: templates/base.html:38
|
||||
msgid "Recent snippets"
|
||||
msgstr ""
|
||||
|
||||
#: templates/base.html:39
|
||||
msgid "Settings"
|
||||
msgstr ""
|
||||
|
||||
#: templates/base.html:40
|
||||
msgid "About"
|
||||
msgstr ""
|
||||
|
0
pastebin/static/.gitignore
vendored
Normal file
0
pastebin/static/.gitignore
vendored
Normal file
384
pastebin/static/theme.css
Normal file
384
pastebin/static/theme.css
Normal file
|
@ -0,0 +1,384 @@
|
|||
body{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
a:link,
|
||||
a:visited{
|
||||
color: #3D813A;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover{
|
||||
color: #52AA4D;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
hr.clear{
|
||||
clear: both;
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
div.success{
|
||||
background-color: green;
|
||||
color: White;
|
||||
margin: 10px 0;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
div.success a{
|
||||
color: White;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
div.hint{
|
||||
padding: 5px 20px;
|
||||
background-color: #F7F1C9;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
|
||||
/* *******************************************
|
||||
* Header
|
||||
******************************************* */
|
||||
|
||||
#header{
|
||||
background-color: #D6F1B7;
|
||||
border-bottom: 1px solid #C6EB9A;
|
||||
padding: 10px 20px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#header span.new_snippet{
|
||||
float: right;
|
||||
}
|
||||
|
||||
#header h1{
|
||||
margin: 0;
|
||||
color: #555555;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#header h1 span.date{
|
||||
color: gray;
|
||||
color: #666;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
#header a:link,
|
||||
#header a:visited{
|
||||
text-decoration: none;
|
||||
color: #333;
|
||||
font-weight: Bold;
|
||||
}
|
||||
|
||||
#header a:hover{
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* *******************************************
|
||||
* Content
|
||||
******************************************* */
|
||||
|
||||
#content{
|
||||
padding: 0 20px;
|
||||
margin: 0;
|
||||
width: 70%;
|
||||
float: left;
|
||||
}
|
||||
|
||||
|
||||
#content h2{
|
||||
font-size: 1.3em;
|
||||
line-height: 1.6em;
|
||||
}
|
||||
|
||||
#content h2 span{
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
div.accordion h2{
|
||||
cursor: pointer;
|
||||
color: #3D813A;
|
||||
}
|
||||
|
||||
div.accordion h2:hover{
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/* *******************************************
|
||||
* Snippet table
|
||||
******************************************* */
|
||||
div.snippet{
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
div.snippet-options{
|
||||
float: right;
|
||||
font-size: 0.9em;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
div.snippet table{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
div.snippet table td{
|
||||
margin: 0;
|
||||
padding: 0 4px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
div.snippet table th{
|
||||
border-right: 1px solid #ccc;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
div.snippet table th a{
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
color: #888;
|
||||
text-align: right;
|
||||
padding: 0 4px 0 18px;
|
||||
}
|
||||
|
||||
/* *******************************************
|
||||
* Form
|
||||
******************************************* */
|
||||
form.snippetform ol{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
form.snippetform ol li{
|
||||
margin: 0;
|
||||
padding: 5px 10px;
|
||||
border-bottom: 1px solid #EEE;
|
||||
clear: left;
|
||||
}
|
||||
|
||||
form.snippetform label{
|
||||
width: 125px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
form.snippetform #id_content{
|
||||
width: 80%;
|
||||
height: 290px;
|
||||
font-family: monospace;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
form.snippetform #id_author,
|
||||
form.snippetform #id_title{
|
||||
width: 60%;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
form.snippetform li.submit input{
|
||||
margin-left: 125px;
|
||||
}
|
||||
|
||||
form.snippetform ul.errorlist,
|
||||
form.snippetform ul.errorlist li{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
color: #c00;
|
||||
font-weight: bold;
|
||||
border: none;
|
||||
}
|
||||
|
||||
form.snippetform ul.errorlist li{
|
||||
padding: 10px 0 5px 0;
|
||||
}
|
||||
/* *******************************************
|
||||
* History + Tree
|
||||
******************************************* */
|
||||
|
||||
#sidebar{
|
||||
padding: 0 20px 0 10px;
|
||||
margin: 20px 0 0 0;
|
||||
float: right;
|
||||
width: 20%;
|
||||
overflow: auto;
|
||||
border-left: 1px solid #DDD;
|
||||
}
|
||||
|
||||
#sidebar h2{
|
||||
font-size: 1em;
|
||||
border-bottom: 1px solid #DDD;
|
||||
color: #888;
|
||||
margin-top: 0;
|
||||
text-transform: uppercase;
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
div.tree{
|
||||
margin: 0 0 15px 0;
|
||||
line-height: 1.8em;
|
||||
}
|
||||
|
||||
div.tree ul,
|
||||
div.tree ul li{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
div.tree ul li{
|
||||
clear: both;
|
||||
}
|
||||
|
||||
div.tree ul li div{
|
||||
border-bottom: 1px solid #EEE;
|
||||
}
|
||||
|
||||
div.tree span.diff{
|
||||
float: right;
|
||||
}
|
||||
|
||||
div.tree strong{
|
||||
color: #111;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
div.tree ul li li{
|
||||
padding-left: 0;
|
||||
margin-left: 15px;
|
||||
color: #ccc;
|
||||
list-style: circle;
|
||||
}
|
||||
|
||||
div.tree div.submit{
|
||||
margin: 8px 0 0 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
div.tree div.submit input{
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
/* *******************************************
|
||||
* Footer
|
||||
******************************************* */
|
||||
|
||||
#footer{
|
||||
position: fixed;
|
||||
right: 1em;
|
||||
bottom: 1em;
|
||||
}
|
||||
|
||||
#footer form.setlang{
|
||||
display: inline;
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
||||
#footer form.setlang input,
|
||||
#footer form.setlang select{
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
#footer a:link,
|
||||
#footer a:visited{
|
||||
background-color: #D6F1B7;
|
||||
color: #555;
|
||||
text-decoration: none;
|
||||
padding: 3px 6px;
|
||||
}
|
||||
|
||||
#footer a:hover,
|
||||
#footer a:active{
|
||||
background-color: #D6F1B7;
|
||||
color: #000;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* *******************************************
|
||||
* Pygments
|
||||
******************************************* */
|
||||
|
||||
pre.code {
|
||||
font-family: "Bitstream Vera Sans Mono", Monaco, Consolas, monospace;
|
||||
font-size: 12px;
|
||||
line-height: 17px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
pre.code div.line:hover{
|
||||
background-color: #FFFFE6;
|
||||
}
|
||||
|
||||
pre.code div.line.marked,
|
||||
pre.code div.line.marked *{
|
||||
background-color: #BAE688 !important;
|
||||
}
|
||||
|
||||
.code .c { color: #999988; font-style: italic } /* Comment */
|
||||
/* .code .err { color: #a61717; background-color: #e3d2d2 } /* Error */
|
||||
.code .k { font-weight: bold } /* Keyword */
|
||||
.code .o { font-weight: bold } /* Operator */
|
||||
.code .cm { color: #999988; font-style: italic } /* Comment.Multiline */
|
||||
.code .cp { color: #999999; font-weight: bold } /* Comment..codeproc */
|
||||
.code .c1 { color: #999988; font-style: italic } /* Comment.Single */
|
||||
.code .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
|
||||
.code .ge { font-style: italic } /* Generic.Emph */
|
||||
.code .gr { color: #aa0000 } /* Generic.Error */
|
||||
.code .gh { color: #999999 } /* Generic.Heading */
|
||||
.code .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
|
||||
.code .go { color: #888888 } /* Generic.Output */
|
||||
.code .gp { color: #555555 } /* Generic.Prompt */
|
||||
.code .gs { font-weight: bold } /* Generic.Strong */
|
||||
.code .gu { color: #aaaaaa } /* Generic.Subheading */
|
||||
.code .gt { color: #aa0000 } /* Generic.Traceback */
|
||||
.code .kc { font-weight: bold } /* Keyword.Constant */
|
||||
.code .kd { font-weight: bold } /* Keyword.Declaration */
|
||||
.code .kp { font-weight: bold } /* Keyword.Pseudo */
|
||||
.code .kr { font-weight: bold } /* Keyword.Reserved */
|
||||
.code .kt { color: #445588; font-weight: bold } /* Keyword.Type */
|
||||
.code .m { color: #009999 } /* Literal.Number */
|
||||
.code .s { color: #bb8844 } /* Literal.String */
|
||||
.code .na { color: #008080 } /* Name.Attribute */
|
||||
.code .nb { color: #999999 } /* Name.Builtin */
|
||||
.code .nc { color: #445588; font-weight: bold } /* Name.Class */
|
||||
.code .no { color: #ff99ff } /* Name.Constant */
|
||||
.code .ni { color: #800080 } /* Name.Entity */
|
||||
.code .ne { color: #990000; font-weight: bold } /* Name.Exception */
|
||||
.code .nf { color: #990000; font-weight: bold } /* Name.Function */
|
||||
.code .nn { color: #555555 } /* Name.Namespace */
|
||||
.code .nt { color: #000080 } /* Name.Tag */
|
||||
.code .nv { color: purple } /* Name.Variable */
|
||||
.code .ow { font-weight: bold } /* Operator.Word */
|
||||
.code .mf { color: #009999 } /* Literal.Number.Float */
|
||||
.code .mh { color: #009999 } /* Literal.Number.Hex */
|
||||
.code .mi { color: #009999 } /* Literal.Number.Integer */
|
||||
.code .mo { color: #009999 } /* Literal.Number.Oct */
|
||||
.code .sb { color: #bb8844 } /* Literal.String.Backtick */
|
||||
.code .sc { color: #bb8844 } /* Literal.String.Char */
|
||||
.code .sd { color: #bb8844 } /* Literal.String.Doc */
|
||||
.code .s2 { color: #bb8844 } /* Literal.String.Double */
|
||||
.code .se { color: #bb8844 } /* Literal.String.Escape */
|
||||
.code .sh { color: #bb8844 } /* Literal.String.Heredoc */
|
||||
.code .si { color: #bb8844 } /* Literal.String.Interpol */
|
||||
.code .sx { color: #bb8844 } /* Literal.String.Other */
|
||||
.code .sr { color: #808000 } /* Literal.String.Regex */
|
||||
.code .s1 { color: #bb8844 } /* Literal.String.Single */
|
||||
.code .ss { color: #bb8844 } /* Literal.String.Symbol */
|
||||
.code .bp { color: #999999 } /* Name.Builtin.Pseudo */
|
||||
.code .vc { color: #ff99ff } /* Name.Variable.Class */
|
||||
.code .vg { color: #ff99ff } /* Name.Variable.Global */
|
||||
.code .vi { color: #ff99ff } /* Name.Variable.Instance */
|
||||
.code .il { color: #009999 } /* Literal.Number.Integer.Long */
|
9
pastebin/templates/404.html
Normal file
9
pastebin/templates/404.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block headline %}
|
||||
<h1>404 Not found</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<p>Snippet you have searched is not available (anymore).</p>
|
||||
{% endblock %}
|
9
pastebin/templates/500.html
Normal file
9
pastebin/templates/500.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block headline %}
|
||||
<h1>500 Internal Server Error</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<p>Sorry, there was an error with your request. My fault!</p>
|
||||
{% endblock %}
|
64
pastebin/templates/about.html
Normal file
64
pastebin/templates/about.html
Normal file
|
@ -0,0 +1,64 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block headline %}
|
||||
<h1>About dpaste.de</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<p>Description follows...</p>
|
||||
|
||||
|
||||
<h2>API</h2>
|
||||
|
||||
<pre>#!/usr/bin/env python
|
||||
|
||||
import urllib
|
||||
import urllib2
|
||||
import sys
|
||||
|
||||
def paste_code():
|
||||
request = urllib2.Request(
|
||||
'http://dpaste.de/api/',
|
||||
urllib.urlencode([('content', ''.join(sys.stdin.readlines()))]),
|
||||
)
|
||||
response = urllib2.urlopen(request)
|
||||
print response.read()[1:-1]
|
||||
|
||||
if __name__ == '__main__':
|
||||
paste_code()</pre>
|
||||
|
||||
<p>Save this script in <code>/usr/local/bin/dpaste</code> and <code>chmod +x ..filepath</code>.</p>
|
||||
<p>Usage: <code>cat foo.txt | dpaste</code></p>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block sidebar %}
|
||||
<h2>Imprint</h2>
|
||||
|
||||
<p>
|
||||
<strong>Address</strong>
|
||||
</p>
|
||||
<p>
|
||||
Martin Mahner<br/>
|
||||
Lauterbacher Str. 4<br/>
|
||||
DE-18581 Putbus<br/>
|
||||
Germany
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Jabber/E-Mail:</strong>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="mailto:martin@mahner.org">martin@mahner.org</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Phone:</strong>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
+49 38301 890(770+8)<sup>1</sup><br/><br/>
|
||||
<small style="font-size:0.9em;"><sup>1</sup> Yes, that's math!</small>
|
||||
</p>
|
||||
{% endblock %}
|
62
pastebin/templates/base.html
Normal file
62
pastebin/templates/base.html
Normal file
|
@ -0,0 +1,62 @@
|
|||
{% load i18n %}
|
||||
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>dpaste.de: {% block title %}{% trans "New snippet" %}{% endblock %}</title>
|
||||
<link rel="stylesheet" media="screen, projection" href="{{ STATIC_URL }}theme.css"/>
|
||||
{% block extrahead %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="header">
|
||||
<span class="new_snippet"><a href="{% url snippet_new %}">{% trans "New snippet" %} →</a></span>
|
||||
{% block headline %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<div id="sidebar">
|
||||
{% block sidebar %}{% endblock %}
|
||||
</div>
|
||||
|
||||
|
||||
<div id="content">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
<div id="footer">
|
||||
{% comment %}
|
||||
<form action="/i18n/setlang/" method="post" class="setlang">
|
||||
{% csrf_token %}
|
||||
<select name="language">
|
||||
{% for lang in LANGUAGES %}
|
||||
<option {% ifequal LANGUAGE_CODE lang.0 %}selected="selected"{% endifequal %} value="{{ lang.0 }}">{{ lang.1 }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
{% endcomment %}
|
||||
<a href="{% url snippet_userlist %}">{% trans "Recent snippets" %}</a>
|
||||
<a href="{% url snippet_userprefs %}">{% trans "Settings" %}</a>
|
||||
<a href="{% url about %}">{% trans "About" %}</a>
|
||||
</div>
|
||||
|
||||
{% block script_footer %}{% endblock %}
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-90910-20']);
|
||||
_gaq.push(['_setDomainName', '.dpaste.de']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
4
requirements.pip
Normal file
4
requirements.pip
Normal file
|
@ -0,0 +1,4 @@
|
|||
django==1.3
|
||||
mptt==0.4.2
|
||||
piston==0.2.2
|
||||
pygments==1.4
|
16
server_configs/dev/apache.conf
Normal file
16
server_configs/dev/apache.conf
Normal file
|
@ -0,0 +1,16 @@
|
|||
<VirtualHost *:9000>
|
||||
ServerName pastebin.dev.lincolnloop.com
|
||||
ServerAdmin webmaster@dev.lincolnloop.com
|
||||
|
||||
ErrorLog /var/log/apache2/pastebin.dev.lincolnloop.com.log
|
||||
|
||||
WSGIDaemonProcess pastebin user=www-data inactivity-timeout=600
|
||||
WSGIProcessGroup pastebin
|
||||
WSGIScriptAlias / /opt/webapps/pastebin.dev.lincolnloop.com/etc/apache/django.wsgi
|
||||
|
||||
<Directory /opt/webapps/pastebin.dev.lincolnloop.com/etc/apache>
|
||||
Order deny,allow
|
||||
Allow from all
|
||||
</Directory>
|
||||
|
||||
</VirtualHost>
|
13
server_configs/dev/django.wsgi
Normal file
13
server_configs/dev/django.wsgi
Normal file
|
@ -0,0 +1,13 @@
|
|||
import os, sys
|
||||
import site
|
||||
|
||||
site.addsitedir('/opt/webapps/pastebin/lib/python2.5/site-packages')
|
||||
|
||||
|
||||
sys.stdout = sys.stderr
|
||||
|
||||
os.environ['DJANGO_SETTINGS_MODULE'] = 'pastebin.conf.local.settings'
|
||||
|
||||
import django.core.handlers.wsgi
|
||||
|
||||
application = django.core.handlers.wsgi.WSGIHandler()
|
31
server_configs/dev/nginx.conf
Normal file
31
server_configs/dev/nginx.conf
Normal file
|
@ -0,0 +1,31 @@
|
|||
upstream pastebin {
|
||||
server pastebin.dev.lincolnloop.com:9000;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name www.pastebin.dev.lincolnloop.com;
|
||||
rewrite ^/(.*) http://pastebin.dev.lincolnloop.com/$1 permanent;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name pastebin.dev.lincolnloop.com;
|
||||
root /var/www/pastebin.dev.lincolnloop.com/;
|
||||
access_log /var/log/nginx/pastebin.dev.lincolnloop.com.access.log;
|
||||
|
||||
location / {
|
||||
if (-f $request_filename/index.html) {
|
||||
rewrite (.*) $1/index.html break;
|
||||
}
|
||||
if (!-f $request_filename) {
|
||||
proxy_pass http://pastebin;
|
||||
}
|
||||
include /etc/nginx/proxy-setup.inc.conf;
|
||||
}
|
||||
|
||||
# Serve up apache log on dev host. Useful for debugging.
|
||||
location /apache.log {
|
||||
alias /var/log/apache2/pastebin.dev.lincolnloop.com.log;
|
||||
}
|
||||
}
|
9
setup.py
Normal file
9
setup.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/env python
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
setup(name='pastebin',
|
||||
version='0.1',
|
||||
packages=find_packages(),
|
||||
package_data={'pastebin': ['bin/*.*', 'static/*.*', 'templates/*.*']},
|
||||
exclude_package_data={'pastebin': ['bin/*.pyc']},
|
||||
scripts=['pastebin/bin/manage.py'])
|
Loading…
Reference in a new issue