diff --git a/README.rst b/README.rst index b796ae7..30e8fea 100644 --- a/README.rst +++ b/README.rst @@ -17,3 +17,7 @@ possible to be installed into an existing Django project like a regular app. You can find a live example on http://dpaste.de/ Further documentation can be found here: https://docs.elephant.house/dpaste/ + +.. image:: https://raw.githubusercontent.com/bartTC/dpaste/master/docs/_static/dpaste_de_screenshot.png + :alt: A screenshot of https://dpaste.de/ + :width: 60% diff --git a/docs/_static/dpaste_de_screenshot.png b/docs/_static/dpaste_de_screenshot.png new file mode 100644 index 0000000..1df3cff Binary files /dev/null and b/docs/_static/dpaste_de_screenshot.png differ diff --git a/docs/_static/logo.svg b/docs/_static/logo.svg new file mode 100644 index 0000000..85641e5 --- /dev/null +++ b/docs/_static/logo.svg @@ -0,0 +1,13 @@ + + + + Group Copy + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/docs/api.rst b/docs/api.rst index 6405ff5..2e26d0d 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1,128 +1,129 @@ -=== -API -=== +============ +API Endpoint +============ dpaste provides a simple API endpoint to create new snippets. All you need to -do is a simple ``POST`` request to the API endpoint ``/api/``:: +do is a simple ``POST`` request to the API endpoint, usually ``/api/``: +.. http:post:: /api/ - POST http://dpaste.de/api/ + Create a new Snippet on this dpaste installation. It returns the full + URL that snippet was created. + **Example request**: -Available POST data for an API call: -==================================== + .. code-block:: bash -``content`` (required) -~~~~~~~~~~~~~~~~~~~~~~ + $ curl -X POST -F "format=url" -F "content=ABC" https:/dpaste.de/api/ -The UTF-8 encoded string you want to paste. + Host: dpaste.de + User-Agent: curl/7.54.0 + Accept: */* -``lexer`` (optional) -~~~~~~~~~~~~~~~~~~~~ + **Example response**: -The lexer string key used for highlighting. See `lexer list`_ for a full list -of choices. Default: ``text``. + .. sourcecode:: json -``format`` (optional) -~~~~~~~~~~~~~~~~~~~~~ - -The format of the API response. Choices are: - -* ``default`` — Returns a full qualified URL wrapped in quotes. Example:: - - "https://dpaste.de/xsWd" - -* ``url`` — Returns the full qualified URL to the snippet, without surrounding - quotes, but with a line break. Example:: - - https://dpaste.de/xsWd\n - -* ``json`` — Returns a JSON object containing the URL, lexer and content of the - the snippet. Example:: - - - { - "url": "https://dpaste.de/xsWd", + { "lexer": "python", - "content": "The text body of the snippet." - } + "url": "https://dpaste.de/EBKU", + "content": "ABC" + } + + :form content: (required) The UTF-8 encoded string you want to paste. + + :form lexer: (optional) The lexer string key used for highlighting. See + the ``CODE_FORMATTER`` property in :ref:`settings` for a full list + of choices. Default: ``_code``. + + :form format: (optional) The format of the API response. Choices are: + + * ``default`` — Returns a full qualified URL wrapped in quotes. + Example: ``"https://dpaste.de/xsWd"`` + + * ``url`` — Returns the full qualified URL to the snippet, without surrounding + quotes, but with a line break. Example: ``https://dpaste.de/xsWd\n`` + + * ``json`` — Returns a JSON object containing the URL, lexer and content of the + the snippet. Example: + + .. code-block:: json + + { + "url": "https://dpaste.de/xsWd", + "lexer": "python", + "content": "The text body of the snippet." + } -``expires`` (optional) -~~~~~~~~~~~~~~~~~~~~~~ + :form expires: (optional) A keyword to indicate the lifetime of a snippet in + seconds. The values are + predefined by the server. Calling this with an invalid value returns a HTTP 400 + BadRequest together with a list of valid values. Default: ``2592000``. In the + default configuration valid values are: -A keyword to indicate the lifetime of a snippetn in seconds. The values are -predefined by the server. Calling this with an invalid value returns a HTTP 400 -BadRequest together with a list of valid values. Default: ``2592000``. In the -default configuration valid values are: + * onetime + * never + * 3600 + * 604800 + * 2592000 -* onetime -* never -* 3600 -* 604800 -* 2592000 + :form filename: (optional) A filename which we use to determine a lexer, if + ``lexer`` is not set. In case we can't determine a file, the lexer will + fallback to ``plain`` code (no highlighting). A given ``lexer`` will overwrite + any filename! Example: -``filename`` (optional) -~~~~~~~~~~~~~~~~~~~~~~~ + .. code-block:: json -A filename which we use to determine a lexer, if ``lexer`` is not set. In case -we can't determine a file, the lexer will fallback to ``plain`` code (no -highlighting). A given ``lexer`` will overwrite any filename! Example:: + { + "url": "https://dpaste.de/xsWd", + "lexer": "", + "filename": "python", + "content": "The text body of the snippet." + } - { - "url": "https://dpaste.de/xsWd", - "lexer": "", - "filename": "python", - "content": "The text body of the snippet." - } + This will create a ``python`` highlighted snippet. However in this example: -This will create a ``python`` highlighted snippet. However in this example:: + .. code-block:: json - { - "url": "https://dpaste.de/xsWd", - "lexer": "php", - "filename": "python", - "content": "The text body of the snippet." - } + { + "url": "https://dpaste.de/xsWd", + "lexer": "php", + "filename": "python", + "content": "The text body of the snippet." + } -Since the lexer is set too, we will create a ``php`` highlighted snippet. + Since the lexer is set too, we will create a ``php`` highlighted snippet. -.. note:: Since ``lexer`` defaults to ``python`` you have to specifically - unset it when using ``filename``. + :statuscode 200: No Error. + :statuscode 400: One of the above form options was invalid, + the response will contain a meaningful error message. -.. hint:: You need to adjust the setting ``DPASTE_BASE_URL`` which is used - to generate the full qualified URL in the API response. See :doc:`settings`. +.. hint:: If yuo have a standalone installation and your API returns + ``https://dpaste.de/`` as the domain, you need to adjust the setting + ``BASE_URL`` property. See :ref:`settings`. -.. note:: When creating new snippets via the API, they won't be listed on the - history page since they are related to a browser session. -.. _lexer list: https://github.com/bartTC/dpaste/blob/master/dpaste/highlight.py#L25 +Third party API integration into editors +======================================== -Example code snippets: -====================== +subdpaste + a Sublime Editor plugin: https://github.com/bartTC/SubDpaste +Marmalade + an Emacs plugin: http://marmalade-repo.org/packages/dpaste_de +atom-dpaste + for the Atom editor: https://atom.io/packages/atom-dpaste -A sample Python 2 script to publish snippets:: +You can also paste your file content to the API via curl, directly from the +command line: - #!/usr/bin/env python - - import urllib - import urllib2 - import sys - - def paste_code(): - request = urllib2.Request( - 'https://dpaste.de/api/', - urllib.urlencode([('content', sys.stdin.read())]), - ) - response = urllib2.urlopen(request) - # Strip surrounding quotes (NB: response has no trailing newline) - print response.read()[1:-1] - - if __name__ == '__main__': - paste_code() - -You can simply use curl to publish a whole file:: +.. code-block:: bash $ alias dpaste="curl -F 'format=url' -F 'content=<-' https://dpaste.de/api/" $ cat foo.txt | dpaste https://dpaste.de/ke2pB + +.. note:: If you wrote or know a third party dpaste plugin or extension, + please open an *Issue* on Github_ and it's added here. + +.. _Github: https://github.com/bartTC/dpaste diff --git a/docs/conf.py b/docs/conf.py index 8442f22..aa93909 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -41,6 +41,7 @@ release = '' extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.viewcode', + 'sphinxcontrib.httpdomain', ] # Add any paths that contain templates here, relative to this directory. @@ -81,6 +82,12 @@ try: import sphinx_rtd_theme html_theme = "sphinx_rtd_theme" html_theme_path = ["_themes", ] + html_theme_options = { + 'logo_only': True, + 'display_version': False, + } + html_logo = "_static/logo.svg" + except ImportError: html_theme = 'alabaster' @@ -163,4 +170,4 @@ texinfo_documents = [ ] -# -- Extension configuration ------------------------------------------------- \ No newline at end of file +# -- Extension configuration ------------------------------------------------- diff --git a/docs/index.rst b/docs/index.rst index e30e05d..7fa1a86 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,26 +1,50 @@ +.. _index: + ====== dpaste ====== -dpaste is a Django based pastebin. It's intended to run separately but its also -possible to be installed into an existing Django project like a regular app. +.. image:: https://img.shields.io/pypi/v/dpaste.svg + :target: https://pypi.org/project/dpaste/ -.. note:: dpaste requires at a minimum Python 3.4 and Django 1.11. +.. image:: https://travis-ci.org/bartTC/dpaste.svg?branch=master + :target: https://travis-ci.org/bartTC/dpaste -Contents: +.. image:: https://api.codacy.com/project/badge/Coverage/185cfbe9b4b447e59a40f816c4a5ebf4 + :target: https://www.codacy.com/app/bartTC/dpaste + +.. image:: https://api.codacy.com/project/badge/Grade/185cfbe9b4b447e59a40f816c4a5ebf4 + :target: https://www.codacy.com/app/bartTC/dpaste + + +dpaste is a pastebin_ application written in Python using the Django +framework. You can find a live installation on `dpaste.de`_. + +.. image:: _static/dpaste_de_screenshot.png + :alt: A screenshot of https://dpaste.de/ + :width: 60% + +The project is intended to run standalone as any regular Django Project, +but it's also possible to install it into an existing project as a typical +Django application. + +The code is open source and available on Github: +https://github.com/bartTC/dpaste. If you found bugs, have problems or ideas with +the project or the website installation, please create an *Issue* there. + +dpaste requires at a minimum **Python 3.4** and **Django 1.11**. + +Documentation +============= .. toctree:: :maxdepth: 1 - local_development - integration + standalone_installation + project_installation + management_commands settings api -.. - Indices and tables - ================== - * :ref:`genindex` - * :ref:`modindex` - * :ref:`search` - +.. _dpaste.de: https://dpaste.de/ +.. _pastebin: https://en.wikipedia.org/wiki/Pastebin diff --git a/docs/integration.rst b/docs/integration.rst deleted file mode 100644 index 785797c..0000000 --- a/docs/integration.rst +++ /dev/null @@ -1,46 +0,0 @@ -========================================= -Integrate dpaste into an existing project -========================================= - -Install the latest dpaste release in your environment. This will install all -necessary dependencies of dpaste as well:: - - pip install dpaste - -Add ``dpaste.apps.dpasteAppConfig`` to your ``INSTALLED_APPS``:: - - INSTALLED_APPS = ( - 'django.contrib.sessions', - 'django.contrib.staticfiles', - # ... - 'dpaste.apps.dpasteAppConfig', - ) - -Add ``dpaste`` — and if you want — the ``dpaste_api`` to your urlpatterns:: - - urlpatterns = patterns('', - # ... - - url(r'pastebin/', include('dpaste.urls.dpaste')), - url(r'pastebin/api/', include('dpaste.urls.dpaste_api')), - ) - -Finally just migrate the database schema:: - - manage.py migrate dpaste - - -Purge expired snippets -====================== - -Do not forget to setup a cron job to purge expired snippets. You need to -run the management command ``cleanup_snippets``. A cron job I use looks like:: - - 30 * * * * /srv/dpaste.de/bin/python /srv/dpaste.de/bin/manage.py cleanup_snippets > /dev/null - -Note also that dpaste does *not* come with Django admin integration. You need -to setup an register the models in an ``admin.py`` yourself. - -.. note:: - - For further customization see :doc:`settings`. diff --git a/docs/local_development.rst b/docs/local_development.rst deleted file mode 100644 index 7affff4..0000000 --- a/docs/local_development.rst +++ /dev/null @@ -1,54 +0,0 @@ -.. _local_development: - -================= -Local Development -================= - - -Installation for local development -================================== - -Local development is done with `pipenv`_ to maintain packages. - -Installation:: - - $ cd dpaste/ - - $ npm install - $ pipenv install --dev - -Copy the settings file and edit it, to meet your needs:: - - $ cp dpaste/settings/local.py.example dpaste/settings/local.py - $ nano dpaste/settings/local.py - -Run the testsuite:: - - $ pipenv run ./runtests.py - -To run the project on your local machine:: - - $ pipenv run ./manage.py migrate - $ pipenv run ./manage.py runserver - - -Testing -======= - -dpaste is continuously tested on Travis_. You can also run the test -suite locally with tox_:: - - $ cd dpaste/ - $ pip install tox - $ tox - -A more manual approach is installing it all by hand in a virtual environment. -This is also the preferred way to setup an environment for local development:: - - $ cd dpaste/ - $ pipenv install --dev - $ pipenv run ./runtests.py - -.. _Travis: https://travis-ci.org/bartTC/dpaste -.. _tox: http://tox.readthedocs.org/en/latest/ -.. _pipenv: https://docs.pipenv.org/ diff --git a/docs/management_commands.rst b/docs/management_commands.rst new file mode 100644 index 0000000..61d4385 --- /dev/null +++ b/docs/management_commands.rst @@ -0,0 +1,41 @@ +.. _management_commands: + +=================== +Management Commands +=================== + +.. _purge_expired_snippets: + +Purge expired snippets +====================== + +dpaste ships with a management command ``cleanup_snippets`` that removes +expired snippets. To run it locally do: + +.. code-block:: bash + + $ pipenv run ./managepy cleanup_snippets + +Options +------- + +--dry-run Does not actually delete the snippets. + This is useful for local testing. + +Setup a Crontab +--------------- + +It's important that you setup a crontab or similar to remove expired snippets +as soon as they reach their expiration date. A crontab line might look like: + +.. code-block:: bash + + */5 * * * * /srv/dpaste.de/pipenv run manage.py cleanup_snippets > /dev/null + + +.. note:: If you use the *database* session backend, you may also need to setup + a crontab that removes the expired entries from the session database. + + See the related `Django Documentation`_ for details. + +.. _Django Documentation: https://docs.djangoproject.com/en/2.0/ref/django-admin/#django-admin-clearsessions diff --git a/docs/project_installation.rst b/docs/project_installation.rst new file mode 100644 index 0000000..111b898 --- /dev/null +++ b/docs/project_installation.rst @@ -0,0 +1,43 @@ +.. _project_installation: + +==================== +Project Installation +==================== + +.. important:: This documentation describes the installation of dpaste + into an existing Django project. If you want to run the application + standalone, see :ref:`standalone_installation`. + +Install the latest dpaste release in your environment. This will install all +necessary dependencies of dpaste as well: + +.. code-block:: bash + + $ pip install dpaste + +Add ``dpaste.apps.dpasteAppConfig`` to your ``INSTALLED_APPS`` list: + +.. code-block:: python + + INSTALLED_APPS = ( + 'django.contrib.sessions', + # ... + 'dpaste.apps.dpasteAppConfig', + ) + +Add ``dpaste`` and the (optiona) ``dpaste_api`` url patterns: + +.. code-block:: python + + urlpatterns = patterns('', + # ... + + url(r'my-pastebin/', include('dpaste.urls.dpaste')), + url(r'my-pastebin/api/', include('dpaste.urls.dpaste_api')), + ) + +Finally, migrate the database schema: + +.. code-block:: bash + + $ manage.py migrate dpaste diff --git a/docs/settings.rst b/docs/settings.rst index c9ae60f..210edcc 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -1,3 +1,5 @@ +.. _settings: + ========================== Settings and Configuration ========================== @@ -8,11 +10,11 @@ behavior. To do so, you need to override dpaste's AppConfig. This is a feature -`introduced in Django 1.9`_ and allows you to set settings more programmatically. - -Please see the source of ``dpaste.apps.dpasteAppConfig`` for a full list -of settings and functions you can override. +`introduced in Django 1.9`_ and allows you to set settings more +programmatically. +See :ref:`current_appconfig` for a full list of settings and functions you +can override. Example for your custom AppConfig: ================================== @@ -34,3 +36,13 @@ Example for your custom AppConfig: ] .. _introduced in Django 1.9: https://docs.djangoproject.com/en/1.9/ref/applications/ + +.. _current_appconfig: + +Current AppConfig with default values +===================================== + +This is the file content of ``dpaste/apps.py``: + +.. literalinclude:: ../dpaste/apps.py + :language: python diff --git a/docs/standalone_installation.rst b/docs/standalone_installation.rst new file mode 100644 index 0000000..d3e72ba --- /dev/null +++ b/docs/standalone_installation.rst @@ -0,0 +1,125 @@ +.. _standalone_installation: + +============================================== +Standalone Installation (or local development) +============================================== + +.. important:: This documentation describes the installation of dpaste + as a standalone project, primarily for local development. If you want + to integrate the application into your existing Django project, see + :ref:`project_installation`. + +The project uses `pipenv`_ to maintain and install dependencies. Install it +once globally with pip: + +.. code:: bash + + $ pip install pipenv + +Then checkout the Git project code from Github and install the Node and +Python dependencies. + +.. code-block:: bash + + $ cd dpaste/ + $ pipenv install --dev # Installs the project and Python dependencies + $ npm install # Installs the node dependencies and compiles + # the static files (JS/CSS). + +Copy the sample settings file and edit it, to meet your needs: + +.. code-block:: bash + + $ cp dpaste/settings/local.py.example dpaste/settings/local.py + +Run the testsuite to make sure everything was built correctly: + +.. code-block:: bash + + $ pipenv run ./runtests.py + +Finally, to run the project on your local machine: + +.. code-block:: bash + + $ pipenv run ./manage.py migrate + $ pipenv run ./manage.py runserver + +If this is a public, standalone installation, make sure you purge +the expired snippets regularly. See :ref:`purge_expired_snippets`. + +CSS and Javascript development +============================== + +Both CSS and Javascript files need to be compiled and compressed. The resulting +files are not commited with the project code. + +There are some helper scripts you can invoke with ``npm`` + +``npm start`` + Compile the static files and run the Django runserver. +``npm run build`` + Compile static files. +``npm run build-js`` + Compile only JS files. +``npm run build-css`` + Compile only CSS files. +``npm run watch-css`` + Same as ``build-css`` but it automatically watches for changes in the + CSS files and re-compiles it. +``npm run docs`` + Compile this documentation. The result will be in ``docs/_build/html``. +``npm run watch-docs`` + Same as ``docs`` but it automatically watches for changes in the + documentation files and re-compiles the docs. + + +.. note:: See ``npm run --list`` for the full and most recent list of + helper scripts. + +Testing with Tox +================ + +dpaste is continuously tested online with Travis_. You can also run the test +suite locally with tox_. Tox automatically tests the project against multiple +Python and Django versions. + +Similar to ``pipenv`` it's useful to have tox installed globally: + +.. code-block:: bash + + $ pip install tox + +Then simply call it from the project directory. + +.. code-block:: bash + + $ cd dpaste/ + $ tox + +.. code-block:: text + :caption: Example tox output: + + $ tox + + py35-django-111 create: /tmp/tox/dpaste/py35-django-111 + SKIPPED:InterpreterNotFound: python3.5 + py36-django-111 create: /tmp/tox/dpaste/py36-django-111 + py36-django-111 installdeps: django>=1.11,<1.12 + py36-django-111 inst: /tmp/tox/dpaste/dist/dpaste-3.0a1.zip + + ................... + ---------------------------------------------------------------------- + Ran 48 tests in 1.724s + OK + + + SKIPPED: py35-django-111: InterpreterNotFound: python3.5 + SKIPPED: py35-django-20: InterpreterNotFound: python3.5 + py36-django-111: commands succeeded + py36-django-20: commands succeeded + congratulations :) + +.. _Travis: https://travis-ci.org/bartTC/dpaste +.. _tox: http://tox.readthedocs.org/en/latest/ +.. _pipenv: https://docs.pipenv.org/