From 008cf2eb0d97908fbe1fccb1d1a032bd4b282d93 Mon Sep 17 00:00:00 2001 From: Julio M Alegria Date: Sat, 24 Jan 2015 18:58:09 -0800 Subject: [PATCH] Getting ready to submit to PyPI --- .gitignore | 12 +++++- LICENSE.txt | 26 ++++++++---- MANIFEST.in | 3 ++ README.md | 93 ------------------------------------------ README.rst | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++ VERSION.txt | 1 + setup.cfg | 2 + setup.py | 24 ++++++++++- 8 files changed, 169 insertions(+), 105 deletions(-) create mode 100644 MANIFEST.in delete mode 100644 README.md create mode 100644 README.rst create mode 100644 VERSION.txt create mode 100644 setup.cfg diff --git a/.gitignore b/.gitignore index 4417ca1..18957c4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,13 @@ *.py[cod] *.db *~ -.DS_Store -.*.swp +*.egg +*.egg-info +dist +build +eggs +sdist +develop-eggs +.installed.cfg +pip-log.txt +.DS_Store \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt index 1b1ddd9..871c3c8 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,8 +1,18 @@ -/* - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - */ \ No newline at end of file +The MIT-Zero License + +Copyright (c) 2015 Julio M Alegria + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..d8676f1 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,3 @@ +recursive-include chunked_upload * +include *.rst +include *.txt \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index c27a1c9..0000000 --- a/README.md +++ /dev/null @@ -1,93 +0,0 @@ -# django-chunked-upload - -This simple django app enables users to upload large files to Django in multiple chunks, with the ability to resume if -the upload is interrupted. - -This app is intented to work with [JQuery-File-Upload](https://github.com/blueimp/jQuery-File-Upload) by -[Sebastian Tschan](https://blueimp.net/). - -## Typical usage - -1. An initial POST request is sent to the url linked to `ChunkedUploadView` (or any subclass) with the first chunk of -the file. The key of this chunk can be overriden in the view (class attribute `field_name`). Example: - - {'my_file': } - -2. In return, server with response with the `upload_id`, the current `offset` and the when will the upload expire -(`expires`). Example: - - {'upload_id': '5230ec1f59d1485d9d7974b853802e31', - 'offset': 10000, - 'expires': '2013-07-18T17:56:22.186Z'} - -3. Repeatedly POST subsequent chunks using the `upload_id` to identify the upload to the url linked to -`ChunkedUploadView` (or any subclass). Example: - - {'upload_id': '5230ec1f59d1485d9d7974b853802e31', - 'my_file': } - - -4. Server will continue responding with the `upload_id`, the current `offset` and the expiration date (`expires`). - -5. Finally, when upload is completed, a POST request is sent to the url linked to `ChunkedUploadCompleteView` -(or any subclass). This request must include the `upload_id` and the `md5` checksum (hex). Example: - - {'upload_id': '5230ec1f59d1485d9d7974b853802e31', - 'md5': 'fc3ff98e8c6a0d3087d515c0473f8677'} - -6. If everything is OK, server will response with status code 200 and the data returned in the method `get_response_data` -(if any). - -### Possible error responses: - -* User is not authenticated. Server responds 403 (Forbidden). -* Upload has expired. Server responds 410 (Gone). -* `upload_id` does not match any upload. Server responds 404 (Not found). -* No chunk file is found in the indicated key. Server responds 400 (Bad request). -* Request does not contain `Content-Range` header. Server responds 400 (Bad request). -* Size of file exceeds limit (if specified). Server responds 400 (Bad request). -* Offsets does not match. Server responds 400 (Bad request). -* `md5` checksums does not match. Server responds 400 (Bad request). - -## Settings - -Add any of these variables into your project settings to override them. - -#### `CHUNKED_UPLOAD_EXPIRATION_DELTA` - -* How long after creation the upload will expire. -* Default: `datetime.timedelta(days=1)` - -#### `CHUNKED_UPLOAD_PATH` - -* Path where uploading files will be stored until completion. -* Default: `'chunked_uploads/%Y/%m/%d'` - -#### `CHUNKED_UPLOAD_STORAGE_CLASS` - -* Storage system (should be a class). -* Default: `None` (use default storage system) - -#### `CHUNKED_UPLOAD_ABSTRACT_MODEL` - -* Boolean that defines if the `ChunkedUpload` model will be abstract or not ([what does abstract model mean?](https://docs.djangoproject.com/en/1.4/ref/models/options/#abstract)). -* Default: `True` - -#### `CHUNKED_UPLOAD_ENCODER` - -* Function used to encode response data. Receives a dict and returns a string. -* Default: `DjangoJSONEncoder().encode` - -#### `CHUNKED_UPLOAD_MIMETYPE` - -* Mimetype for the response data. -* Default: `'application/json'` - -#### `CHUNKED_UPLOAD_MAX_BYTES` - -* Max amount of data (in bytes) that can be uploaded. `None` means no limit. -* Default: `None` - -## Support - -If you find any bug or you want to propose a new feature, please use the [issues tracker](https://github.com/juliomalegria/django-chunked-upload/issues). I'll be happy to help you! :-) diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..4fac407 --- /dev/null +++ b/README.rst @@ -0,0 +1,113 @@ +django-chunked-upload +===================== + +This simple django app enables users to upload large files to Django in multiple chunks, with the ability to resume if the upload is interrupted. + +This app is intented to work with `JQuery-File-Upload `__ by `Sebastian Tschan `__. + +License: `MIT-Zero `__. + +Typical usage +------------- + +1. An initial POST request is sent to the url linked to ``ChunkedUploadView`` (or any subclass) with the first chunk of the file. The name of the chunk file can be overriden in the view (class attribute ``field_name``). Example: + +:: + + {"my_file": } + +2. In return, server with response with the ``upload_id``, the current ``offset`` and the when will the upload expire (``expires``). Example: + +:: + + { + "upload_id": "5230ec1f59d1485d9d7974b853802e31", + "offset": 10000, + "expires": "2013-07-18T17:56:22.186Z" + } + +3. Repeatedly POST subsequent chunks using the ``upload_id`` to identify the upload to the url linked to ``ChunkedUploadView`` (or any subclass). Example: + +:: + + { + "upload_id": "5230ec1f59d1485d9d7974b853802e31", + "my_file": + } + +4. Server will continue responding with the ``upload_id``, the current ``offset`` and the expiration date (``expires``). + +5. Finally, when upload is completed, a POST request is sent to the url linked to ``ChunkedUploadCompleteView`` (or any subclass). This request must include the ``upload_id`` and the ``md5`` checksum (hex). Example: + +:: + + { + "upload_id": "5230ec1f59d1485d9d7974b853802e31", + "md5": "fc3ff98e8c6a0d3087d515c0473f8677" + } + +6. If everything is OK, server will response with status code 200 and the data returned in the method ``get_response_data`` (if any). + +Possible error responses: +~~~~~~~~~~~~~~~~~~~~~~~~~ + +* User is not authenticated. Server responds 403 (Forbidden). +* Upload has expired. Server responds 410 (Gone). +* ``upload_id`` does not match any upload. Server responds 404 (Not found). +* No chunk file is found in the indicated key. Server responds 400 (Bad request). +* Request does not contain ``Content-Range`` header. Server responds 400 (Bad request). +* Size of file exceeds limit (if specified). Server responds 400 (Bad request). +* Offsets does not match. Server responds 400 (Bad request). +* ``md5`` checksums does not match. Server responds 400 (Bad request). + +Settings +-------- + +Add any of these variables into your project settings to override them. + +``CHUNKED_UPLOAD_EXPIRATION_DELTA`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* How long after creation the upload will expire. +* Default: ``datetime.timedelta(days=1)`` + +``CHUNKED_UPLOAD_PATH`` +~~~~~~~~~~~~~~~~~~~~~~~ + +* Path where uploading files will be stored until completion. +* Default: ``'chunked_uploads/%Y/%m/%d'`` + +``CHUNKED_UPLOAD_STORAGE_CLASS`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Storage system (should be a class) +* Default: ``None`` (use default storage system) + +``CHUNKED_UPLOAD_ABSTRACT_MODEL`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Boolean that defines if the ``ChunkedUpload`` model will be abstract or not (`what does abstract model mean? `__) +* Default: ``True`` + +``CHUNKED_UPLOAD_ENCODER`` +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Function used to encode response data. Receives a dict and returns a string +* Default: ``DjangoJSONEncoder().encode`` + +``CHUNKED_UPLOAD_MIMETYPE`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Mimetype for the response data. +* Default: ``'application/json'`` + +``CHUNKED_UPLOAD_MAX_BYTES`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Max amount of data (in bytes) that can be uploaded. ``None`` means no limit +* Default: ``None`` + +Support +------- + +If you find any bug or you want to propose a new feature, please use the `issues tracker `__. I'll be happy to help you! :-) diff --git a/VERSION.txt b/VERSION.txt new file mode 100644 index 0000000..afaf360 --- /dev/null +++ b/VERSION.txt @@ -0,0 +1 @@ +1.0.0 \ No newline at end of file diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..11e9ec4 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[metadata] +description-file = README.rst \ No newline at end of file diff --git a/setup.py b/setup.py index 60463d0..d0b3866 100644 --- a/setup.py +++ b/setup.py @@ -1,12 +1,32 @@ -# -*- coding: UTF-8 -*- +#!/usr/bin/env python -# Import from the Standard Library try: from setuptools import setup except ImportError: from distutils.core import setup +with open('VERSION.txt', 'r') as v: + version = v.read().strip() + +with open('README.rst', 'r') as r: + readme = r.read() + +download_url = ( + 'https://github.com/juliomalegria/django-chunked-upload/tarball/%s' +) + + setup( name='django-chunked-upload', packages=['chunked_upload'], + version=version, + description=('Upload large files to Django in multiple chunks, with the ' + 'ability to resume if the upload is interrupted.'), + long_description=readme, + author='Julio M Alegria', + author_email='juliomalegria@gmail.com', + url='https://github.com/juliomalegria/django-chunked-upload', + download_url=download_url % version, + install_requires=[], + license='MIT-Zero' )