From 0a68866b07e32f5a0f4727b1e9fedffc37bbab0e Mon Sep 17 00:00:00 2001 From: Vinod Kurup Date: Wed, 18 Jan 2017 09:18:27 -0500 Subject: [PATCH] Add flake8 (found 1 test bug!) --- .hgignore | 7 -- README.rst | 2 +- docs/index.rst | 3 +- docs/motivation.rst | 6 +- docs/picker_config.rst | 35 ++++--- docs/screenshots.rst | 7 +- docs/setup.rst | 14 ++- docs/uploads.rst | 6 +- docs/wymeditor.rst | 6 +- file_picker/__init__.py | 8 +- file_picker/forms.py | 12 +-- file_picker/models.py | 3 - file_picker/sites.py | 1 + file_picker/static/css/filepicker.overlay.css | 32 +++---- file_picker/tests.py | 91 ++++++++++--------- file_picker/uploads/file_pickers.py | 5 +- file_picker/uploads/models.py | 4 +- file_picker/views.py | 26 +++--- .../sample_project/article/admin.py | 5 +- .../sample_project/article/models.py | 1 - .../sample_project/article/tests.py | 23 ----- sample_project/sample_project/bootstrap.py | 34 ------- setup.cfg | 3 + tox.ini | 7 +- 24 files changed, 137 insertions(+), 204 deletions(-) delete mode 100644 .hgignore delete mode 100644 sample_project/sample_project/article/tests.py delete mode 100644 sample_project/sample_project/bootstrap.py create mode 100644 setup.cfg diff --git a/.hgignore b/.hgignore deleted file mode 100644 index e2cfa91..0000000 --- a/.hgignore +++ /dev/null @@ -1,7 +0,0 @@ -syntax: glob -local_settings.py -*.pyc -*.db -.DS_Store -media/images -*.egg-info diff --git a/README.rst b/README.rst index 19a7a4b..bd36b53 100644 --- a/README.rst +++ b/README.rst @@ -25,7 +25,7 @@ Required ```````` * Python 2.7 (**note**: Python 3 is not yet supported) * `Django 1.8 to 1.10 (inclusive) `_ -* sorl-thumbnail==12.3 +* sorl-thumbnail==12.4a1 * `jQuery 1.4.x `_ * `jQuery Tools 1.2.x `_ * `AJAX Upload `_ (included) diff --git a/docs/index.rst b/docs/index.rst index cbd4491..e5bca15 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -10,7 +10,7 @@ Contents .. toctree:: :maxdepth: 2 - + setup uploads wymeditor @@ -25,4 +25,3 @@ Indices and tables * :ref:`genindex` * :ref:`modindex` * :ref:`search` - diff --git a/docs/motivation.rst b/docs/motivation.rst index da27abd..e6e690a 100644 --- a/docs/motivation.rst +++ b/docs/motivation.rst @@ -1,9 +1,9 @@ Motivation ========== -The deep concern while building file picker has been flexibility. Too many -projects focus on wrapping everything together so that they can make +The deep concern while building a file picker has been flexibility. Too many +projects focus on wrapping everything together so that they can make deep connections. Our main goal has been to build a application that facilitates connections, -that can be attached accross multiple applications and models. +that can be attached across multiple applications and models. diff --git a/docs/picker_config.rst b/docs/picker_config.rst index 049b5f8..fddee89 100644 --- a/docs/picker_config.rst +++ b/docs/picker_config.rst @@ -8,9 +8,9 @@ The FilePickerBase Class ======================== The base file picker class has a mixture of class based views and helper functions -for building the colorbox on the page. File pickers should be included in the +for building the colorbox on the page. File pickers should be included in the *file_pickers.py* file in the root directory of any app so that the auto-discovery -process can find it. +process can find it. Attributes @@ -21,7 +21,7 @@ Each picker can take a set of attributes for easy customization.:: from myapp.models import CustomModel from myapp.forms import CustomForm import file_pickers - + class CustomPicker(file_picker.FilePickerBase): form = CustomForm page_size = 4 @@ -30,22 +30,22 @@ Each picker can take a set of attributes for easy customization.:: extra_headers = ['Name', 'Body', 'Description',] ordering = '-date' - file_picker.site.register(CustomModel, CustomPicker, name='custom') - -None of these attributes are required and they all have sane defaults. + file_picker.site.register(CustomModel, CustomPicker, name='custom') + +None of these attributes are required and they all have sane defaults. -* *form*- If left blank is created by building a *ModelForm* from the model defined +* *form*- If left blank is created by building a *ModelForm* from the model defined in the register function. It is used to build the form on the Upload tab. -* *link_headers*- Defines the headers for the first set of columns which are used +* *link_headers*- Defines the headers for the first set of columns which are used to insert content into the textbox or WYSIWYG of your choice. By default it converts _ to ' ' and capitalizes first letter of the fields name. * *columns*- Defines the fields you want to be included on the listing page - and their ordering. + and their ordering. * *extra_headers*- The list is used to define the headers for the columns - and needs to be in the same order as columns. -* *ordering*- Defines the order of items on the listing page in + and needs to be in the same order as columns. +* *ordering*- Defines the order of items on the listing page in to be used as ``query_set.order_by('-date')``. Methods @@ -53,7 +53,7 @@ Methods The three main methods consist of *append*, *list*, and *upload_file*. List and upload_file take in the request object and act as views while append takes in an model item and helps -build the JSON output for list. Other methods are available but typically do not +build the JSON output for list. Other methods are available but typically do not need to be modified. append(obj) @@ -63,7 +63,7 @@ This method takes in *obj* which is a item from the model and outputs a dictiona to be used by list. This dictoinary is of the form.:: { - 'name': 'Name for the object.', + 'name': 'Name for the object.', 'url': 'The url to the file.', 'extra': { 'column_name_1': 'value', @@ -96,15 +96,12 @@ This takes in a *request* object and outputs.:: upload_file(request) ^^^^^^^^^^^^^^^^^^^^ -Builds the upload file form and is used to upload files in two steps, +Builds the upload file form and is used to upload files in two steps, file first then the other form parameters. If called without a POST it returns a JSON dictionary with the key form with an html block for the form. -If called with a file and then with the post, its a two step process. If the form -passed on the second step it returns the result of append for the object which +If called with a file and then with the post, it's a two step process. If the form +passed on the second step it returns the result of append for the object which was just created. - - - diff --git a/docs/screenshots.rst b/docs/screenshots.rst index d90ac53..bd82aed 100644 --- a/docs/screenshots.rst +++ b/docs/screenshots.rst @@ -5,18 +5,17 @@ Screenshots .. figure:: images/overlay_upload.png :align: center :width: 800px - + The upload pane from the sample project. .. figure:: images/browse.png :align: center :width: 800px - + The browser pane from the sample project. .. figure:: images/insert.png :align: center :width: 800px - - An example of inseting an image with File Picker. + An example of inseting an image with File Picker. diff --git a/docs/setup.rst b/docs/setup.rst index 3796f68..8b126cd 100644 --- a/docs/setup.rst +++ b/docs/setup.rst @@ -3,7 +3,7 @@ Basic Setup =========== -#. Use or create a model for storing images and/or files. For simplicity here +#. Use or create a model for storing images and/or files. For simplicity here we will use the models in ``file_picker.uploads``, Image and File. #. Use or create another model to contian the text field(s) to be inserted in @@ -12,11 +12,11 @@ Basic Setup #. To use the pickers on both the teaser and body fields use a *formfield_override* to override the widget with the ``file_picker.widgets.SimpleFilePickerWidget``:: - + import file_picker from django.contrib import admin from sample_project.article import models as article_models - + class PostAdmin(admin.ModelAdmin): formfield_overrides = { models.TextField: { @@ -26,10 +26,10 @@ Basic Setup }), }, } - + class Media: js = ("http://cdn.jquerytools.org/1.2.5/full/jquery.tools.min.js",) - + admin.site.register(article_models.Post, PostAdmin) @@ -38,10 +38,8 @@ Simple File Picker Widget .. class:: file_picker.widgets.SimpleFilePickerWidget -To use the simple file picker widget override the desired form field's widget. +To use the simple file picker widget override the desired form field's widget. It takes in a dictionary with expected keys `"image"` and/or `"file"` these define which link to use "Add Image" and/or "Add File". For an example of usage look at the. - - diff --git a/docs/uploads.rst b/docs/uploads.rst index cc3b810..01dadf2 100644 --- a/docs/uploads.rst +++ b/docs/uploads.rst @@ -5,7 +5,7 @@ The Uploads App ======================= Designed to make it easy to get File Picker up and running without having to add -models or register them with ``file_picker``. The uploads app includes two +models or register them with ``file_picker``. The uploads app includes two simple pickers which can be attached to your own projects text fields. For install instructions check out :ref:`setup` @@ -14,7 +14,7 @@ FilePicker .. class:: file_picker.uploads.file_pickers.FilePicker -Is a simple class based off of the ``file_picker.FilePickerBase`` +Is a simple class based off of the ``file_picker.FilePickerBase`` which is connected to the *File* model and can be found in the Uploads admin section. @@ -23,7 +23,7 @@ ImagePicker .. class:: file_picker.uploads.file_pickers.ImagePicker -Is a simple class based off of the ``file_picker.ImagePickerBase`` +Is a simple class based off of the ``file_picker.ImagePickerBase`` which is connected to the *Image* model and can be found in the Uploads admin section. diff --git a/docs/wymeditor.rst b/docs/wymeditor.rst index 7ceca90..e8eb2ed 100644 --- a/docs/wymeditor.rst +++ b/docs/wymeditor.rst @@ -2,8 +2,8 @@ The WYMeditor App ================= Included to make the intergration of File Picker with a popular WYSIWYG easy. -WYMeditor is a javascript based editor, its documentation can be found -`here `_. This application offers an extra form +WYMeditor is a javascript based editor, its documentation can be found +`here `_. This application offers an extra form widget for applying WYMeditor to a text field with buttons for files and images if desired. @@ -34,6 +34,6 @@ File Picker for each `TextField` in the form. ), }, } - + class Media: js = ("http://cdn.jquerytools.org/1.2.5/full/jquery.tools.min.js",) diff --git a/file_picker/__init__.py b/file_picker/__init__.py index 2ef186d..61c9930 100644 --- a/file_picker/__init__.py +++ b/file_picker/__init__.py @@ -1,6 +1,8 @@ -from file_picker.views import FilePickerBase, ImagePickerBase -from file_picker.sites import site, FilePickerSite -from file_picker import widgets +# Aliases allow users to import directly from file_picker.* +# FIXME: Should we deprecate this behavior? setup.py can't access __version__ unless django and deps are installed +from file_picker.views import FilePickerBase, ImagePickerBase # noqa +from file_picker.sites import site, FilePickerSite # noqa +from file_picker import widgets # noqa VERSION = (0, 6, 0,) __version__ = '.'.join(map(str, VERSION)) diff --git a/file_picker/forms.py b/file_picker/forms.py index 6afa474..3ecc2e4 100644 --- a/file_picker/forms.py +++ b/file_picker/forms.py @@ -2,7 +2,6 @@ from django import forms from django.db import models -from django.db.models import Q from django.db.models.base import FieldDoesNotExist from django.core.files.base import ContentFile @@ -13,7 +12,7 @@ class QueryForm(forms.Form): search = forms.CharField( max_length=300, required=False, ) - + def clean_page(self): page = self.cleaned_data.get('page') if not page: @@ -34,14 +33,14 @@ def model_to_AjaxItemForm(model): continue if isinstance(field, FIELD_EXCLUDES): exclude.append(field_name) - meta = type('Meta', (), { "model":model, "exclude": exclude}) + meta = type('Meta', (), {"model": model, "exclude": exclude}) modelform_class = type('modelform', (AjaxItemForm,), {"Meta": meta}) return modelform_class class AjaxItemForm(forms.ModelForm): file = forms.CharField(widget=forms.widgets.HiddenInput()) - + def clean_file(self): file = self.cleaned_data['file'] if not os.path.exists(file): @@ -52,8 +51,9 @@ def save(self, *args, **kwargs): item = super(AjaxItemForm, self).save(commit=False) # Strip any directory names from the filename filename = os.path.basename(self.cleaned_data['file']) - getattr(item, self.Meta.exclude[0]).save(filename, - ContentFile(open(str(self.cleaned_data['file']),'r').read()) + getattr(item, self.Meta.exclude[0]).save( + filename, + ContentFile(open(str(self.cleaned_data['file']), 'r').read()) ) item.save(*args, **kwargs) return item diff --git a/file_picker/models.py b/file_picker/models.py index 71a8362..e69de29 100644 --- a/file_picker/models.py +++ b/file_picker/models.py @@ -1,3 +0,0 @@ -from django.db import models - -# Create your models here. diff --git a/file_picker/sites.py b/file_picker/sites.py index dd30251..f1d8caf 100644 --- a/file_picker/sites.py +++ b/file_picker/sites.py @@ -61,4 +61,5 @@ def primary(self, request): data = {'pickers': pickers} return HttpResponse(json.dumps(data), content_type='application/json') + site = FilePickerSite() diff --git a/file_picker/static/css/filepicker.overlay.css b/file_picker/static/css/filepicker.overlay.css index 5c52235..00384ba 100644 --- a/file_picker/static/css/filepicker.overlay.css +++ b/file_picker/static/css/filepicker.overlay.css @@ -1,23 +1,23 @@ /* the overlayed element */ .file-picker-overlay { - + /* initially overlay is hidden */ display: none; - + /* growing background image */ background-image: url(../img/white.png); - - /* + + /* width after the growing animation finishes height is automatically calculated */ - width: 583px; + width: 583px; height: 450px; - + /* some padding to layout nested elements nicely */ padding: 35px; - /* a little styling */ + /* a little styling */ /* font-size:11px;*/ } @@ -31,11 +31,11 @@ } /* root element for tabs */ -ul.css-tabs { - margin: 0 !important; +ul.css-tabs { + margin: 0 !important; padding: 0; height: 30px; - border-bottom: 1px solid #417690; + border-bottom: 1px solid #417690; } /* single tab */ @@ -57,7 +57,7 @@ ul.css-tabs a { padding: 8px 30px; font-size: 12px; text-decoration: none; - border: 1px solid #417690; + border: 1px solid #417690; border-bottom: 0px; background-color: #417690; color: #FFF; @@ -70,20 +70,20 @@ ul.css-tabs a { ul.css-tabs a:hover { background-color: #B3C8D3; color: #417690; - -webkit-transition: background-color 0.1s linear; - -moz-transition: background-color 0.1s linear; + -webkit-transition: background-color 0.1s linear; + -moz-transition: background-color 0.1s linear; -o-transition: background-color 0.1s linear; } - + /* selected tab */ ul.css-tabs a.current { background-color: #FFF; border-bottom: 1px solid #FFF; - color: #417690; + color: #417690; cursor: default; } - + /* tab pane */ div.panes div.pane { display: none; diff --git a/file_picker/tests.py b/file_picker/tests.py index 2eb53db..ea752a5 100644 --- a/file_picker/tests.py +++ b/file_picker/tests.py @@ -17,7 +17,7 @@ class Image(models.Model): name = models.CharField(max_length=255) description_1 = models.TextField(blank=True) description_2 = models.TextField(blank=True) - file = models.ImageField(upload_to='images/') + file = models.ImageField(upload_to='images/') class MockRequest(object): @@ -27,7 +27,7 @@ class MockRequest(object): GET = {} POST = {} FILES = {} - + class MockImagePicker(file_picker.ImagePickerBase): def __init__(self, name, model, columns, extra_headers, extra={}): @@ -42,20 +42,20 @@ def __init__(self, name, model, columns, extra_headers, extra={}): class BasePickerTest(TestCase): """ - Base class to build the + Base class to build the """ def setUp(self): self.path = os.path.abspath('%s' % os.path.dirname(__file__)) self.image_file = File(open(os.path.join(self.path, 'static/img/attach.png')), "test_file.png") self.image = Image( - name = 'Test Image', - description_1 = 'test desc 1', - description_2 = 'test desc 2', - file = self.image_file, - ) + name='Test Image', + description_1='test desc 1', + description_2='test desc 2', + file=self.image_file, + ) self.image.save() self.request = MockRequest() - + class TestListPage(BasePickerTest): """ @@ -75,23 +75,23 @@ def test_all_fields(self): list_resp = json.loads(response.content) self.assertEquals(response.status_code, 200) self.assertEquals(self.field_names, list_resp['columns']) - self.assertEquals([capfirst(Image._meta.get_field(i).verbose_name) \ - for i in self.field_names], list_resp['extra_headers']) + self.assertEquals([capfirst(Image._meta.get_field(i).verbose_name) + for i in self.field_names], list_resp['extra_headers']) def test_columns(self): """ Test only columns defined. """ - columns = ['description_2', 'name',] + columns = ['description_2', 'name'] image_picker = MockImagePicker('image_test', Image, columns, None) response = image_picker.list(self.request) list_resp = json.loads(response.content) self.assertEquals(response.status_code, 200) self.assertEquals(columns, list_resp['columns']) - extra_headers = [capfirst(Image._meta.get_field(i).verbose_name) \ - for i in columns] + extra_headers = [capfirst(Image._meta.get_field(i).verbose_name) + for i in columns] self.assertEquals(extra_headers, list_resp['extra_headers']) - + def test_extra_headers(self): """ Test only extra headers defined. Should ignore it completely. @@ -101,9 +101,9 @@ def test_extra_headers(self): list_resp = json.loads(response.content) self.assertEquals(response.status_code, 200) self.assertEquals(self.field_names, list_resp['columns']) - self.assertEquals([capfirst(Image._meta.get_field(i).verbose_name) \ - for i in self.field_names], list_resp['extra_headers']) - + self.assertEquals([capfirst(Image._meta.get_field(i).verbose_name) + for i in self.field_names], list_resp['extra_headers']) + def test_columns_and_headers(self): """ Test custom columns and extra headers. @@ -116,7 +116,7 @@ def test_columns_and_headers(self): self.assertEquals(response.status_code, 200) self.assertEquals(columns, list_resp['columns']) self.assertEquals(extra_headers, list_resp['extra_headers']) - + def test_file_list(self): """ Make sure that the file list gives the correct url. @@ -128,7 +128,7 @@ def test_file_list(self): self.assertEquals(len(results), 1) result = results[0] self.assertEquals(result['url'], self.image.file.url) - + def test_extra_links(self): """ Test having multiple links works. @@ -137,6 +137,7 @@ def test_extra_links(self): 'link_headers': ['URL', 'URL Caps'], } link_content = ['Click to insert', 'Click to insert Cap'] + class CustomPicker(MockImagePicker): def append(self, obj): extra = {} @@ -147,14 +148,15 @@ def append(self, obj): else: value = unicode(value) extra[name] = value - return {'name': unicode(obj), 'url': getattr(obj, self.field).url, + return { + 'name': unicode(obj), + 'url': getattr(obj, self.field).url, 'extra': extra, - 'insert': [getattr(obj, self.field).url, - getattr(obj, self.field).url.upper(),], + 'insert': [getattr(obj, self.field).url, + getattr(obj, self.field).url.upper()], 'link_content': link_content, - } - image_picker = CustomPicker('image_test', Image, - None, None, extra=extra) + } + image_picker = CustomPicker('image_test', Image, None, None, extra=extra) response = image_picker.list(self.request) self.assertEquals(response.status_code, 200) resp = json.loads(response.content) @@ -164,19 +166,19 @@ def append(self, obj): self.assertEquals(len(result), 1) self.assertEquals(result[0]['insert'][0].upper(), result[0]['insert'][1]) self.assertEquals(result[0]['link_content'], link_content) - + def test_search_page(self): """ - Make sure that the search is checking text fields and finding the + Make sure that the search is checking text fields and finding the correct results. """ - for i in range(0,3): + for i in range(0, 3): image = Image( - name = 'no find %s' % i, - description_1 = 'desc 1 %s' % i, - description_2 = 'desc 2 %s' % i, - file = self.image_file, - ) + name='no find %s' % i, + description_1='desc 1 %s' % i, + description_2='desc 2 %s' % i, + file=self.image_file, + ) image.save() image_picker = MockImagePicker('image_test', Image, None, None) qs = image_picker.get_queryset('Test') @@ -188,7 +190,7 @@ def test_search_page(self): class TestUploadPage(TestCase): """ - Test the upload + Test the upload """ def setUp(self): self.request = MockRequest() @@ -204,13 +206,13 @@ def test_upload_form_page(self): resp = json.loads(response.content) self.assertEquals(response.status_code, 200) self.assertTrue('form' in resp) - + def test_upload(self): """ Test the file upload and post. """ request = self.request - request.FILES = {'userfile': self.image_file,} + request.FILES = {'userfile': self.image_file} response = self.image_picker.upload_file(request) self.assertEquals(response.status_code, 200) resp = json.loads(response.content) @@ -239,18 +241,19 @@ def setUp(self): self.picker_name = 'test-images' file_picker.site.register(Image, file_picker.ImagePickerBase, name=self.picker_name,) self.url = reverse('filepicker:index') - + def test_site_index(self): - response = self.client.get(self.url, {'pickers': [self.picker_name],}) + response = self.client.get(self.url, {'pickers': [self.picker_name]}) resp = json.loads(response.content) for key, value in resp['pickers'].items(): self.assertEquals(key, self.picker_name) self.assertEquals(value, '/file-picker/%s/' % self.picker_name) - + def test_images_urls(self): url = reverse('filepicker:%s:init' % self.picker_name) - response = self.client.get(self.url, {'pickers': [self.picker_name],}) - resp = json.loads(response.content) - for key, value in resp['pickers'].items(): - response = self.client.get(value, {}) + response = self.client.get(url) + data = json.loads(response.content) + urls = [u.values()[0] for u in data['urls'].values()] + for url in urls: + response = self.client.get(url) self.assertEquals(response.status_code, 200) diff --git a/file_picker/uploads/file_pickers.py b/file_picker/uploads/file_pickers.py index 0aad1ea..d38b64b 100644 --- a/file_picker/uploads/file_pickers.py +++ b/file_picker/uploads/file_pickers.py @@ -47,14 +47,13 @@ class ImagePicker(file_picker.ImagePickerBase): form = ImageForm columns = ('name', 'file_type', 'date_modified') extra_headers = ('Name', 'File Type', 'Date Modified') - + class FilePicker(file_picker.FilePickerBase): form = FileForm columns = ('name', 'file_type', 'date_modified') extra_headers = ('Name', 'File type', 'Date modified') - + file_picker.site.register(Image, ImagePicker, name='images') file_picker.site.register(File, FilePicker, name='files') - diff --git a/file_picker/uploads/models.py b/file_picker/uploads/models.py index 0431d04..e764c5f 100644 --- a/file_picker/uploads/models.py +++ b/file_picker/uploads/models.py @@ -1,8 +1,8 @@ import os -import datetime from django.db import models from django.conf import settings +from django.utils import timezone class BaseFileModel(models.Model): @@ -25,7 +25,7 @@ class Meta: def save(self, **kwargs): # dates - now = datetime.datetime.now() + now = timezone.now() if not self.pk: self.date_created = now self.date_modified = now diff --git a/file_picker/views.py b/file_picker/views.py index 4083f80..3f67e0b 100644 --- a/file_picker/views.py +++ b/file_picker/views.py @@ -11,8 +11,6 @@ from django.http import HttpResponse, HttpResponseServerError from django.core.paginator import Paginator, EmptyPage from django.core.urlresolvers import reverse -from django.core.files.uploadedfile import UploadedFile -from django.views.decorators.csrf import csrf_exempt from sorl.thumbnail.helpers import ThumbnailError from sorl.thumbnail import get_thumbnail @@ -20,14 +18,14 @@ from file_picker.forms import QueryForm, model_to_AjaxItemForm -logger = logging.getLogger('filepicker.views') +logger = logging.getLogger(__name__) class FilePickerBase(object): model = None form = None page_size = 4 - link_headers = ['Insert File',] + link_headers = ['Insert File', ] extra_headers = None columns = None ordering = None @@ -63,7 +61,6 @@ def __init__(self, name, model): if build_headers: self.extra_headers = extra_headers - def protect(self, view, csrf_exempt=False): def wrapper(*args, **kwargs): data = {} @@ -104,9 +101,11 @@ def append(self, obj): else: value = unicode(value) extra[name] = value - return {'name': unicode(obj), 'url': getattr(obj, self.field).url, + return { + 'name': unicode(obj), + 'url': getattr(obj, self.field).url, 'extra': extra, - 'insert': [getattr(obj, self.field).url,], + 'insert': [getattr(obj, self.field).url, ], 'link_content': ['Click to insert'], } @@ -132,7 +131,7 @@ def upload_file(self, request): for chunk in f.chunks(): fn.write(chunk) fn.close() - return HttpResponse(json.dumps({ 'name': fn.name }), content_type='application/json') + return HttpResponse(json.dumps({'name': fn.name}), content_type='application/json') else: form = self.form(request.POST or None) if form.is_valid(): @@ -172,7 +171,7 @@ def list(self, request): class ImagePickerBase(FilePickerBase): - link_headers = ['Thumbnail',] + link_headers = ['Thumbnail', ] def append(self, obj): json = super(ImagePickerBase, self).append(obj) @@ -183,10 +182,9 @@ def append(self, obj): logger.exception(e) thumb = None if thumb: - json['link_content'] = [img.format(thumb.url, 'image', - thumb.width, thumb.height,),] - json['insert'] = ['' % getattr(obj, self.field).url,] + json['link_content'] = [img.format(thumb.url, 'image', thumb.width, thumb.height), ] + json['insert'] = ['' % getattr(obj, self.field).url, ] else: - json['link_content'] = [img.format('', 'Not Found', 150, 150),] - json['insert'] = [img.format('', 'Not Found', 150, 150),] + json['link_content'] = [img.format('', 'Not Found', 150, 150), ] + json['insert'] = [img.format('', 'Not Found', 150, 150), ] return json diff --git a/sample_project/sample_project/article/admin.py b/sample_project/sample_project/article/admin.py index 9da69f0..fa53f2e 100644 --- a/sample_project/sample_project/article/admin.py +++ b/sample_project/sample_project/article/admin.py @@ -1,10 +1,7 @@ from django import forms from django.contrib import admin -from django.db import models from sample_project.article.models import Post -import file_picker - class PostForm(forms.ModelForm): @@ -25,7 +22,6 @@ class Meta(object): fields = '__all__' - class PostAdmin(admin.ModelAdmin): form = PostForm @@ -33,4 +29,5 @@ class PostAdmin(admin.ModelAdmin): class Media: js = ("http://cdn.jquerytools.org/1.2.5/full/jquery.tools.min.js",) + admin.site.register(Post, PostAdmin) diff --git a/sample_project/sample_project/article/models.py b/sample_project/sample_project/article/models.py index 9f74a00..3b41df3 100644 --- a/sample_project/sample_project/article/models.py +++ b/sample_project/sample_project/article/models.py @@ -1,4 +1,3 @@ -import datetime from django.db import models diff --git a/sample_project/sample_project/article/tests.py b/sample_project/sample_project/article/tests.py deleted file mode 100644 index 2247054..0000000 --- a/sample_project/sample_project/article/tests.py +++ /dev/null @@ -1,23 +0,0 @@ -""" -This file demonstrates two different styles of tests (one doctest and one -unittest). These will both pass when you run "manage.py test". - -Replace these with more appropriate tests for your application. -""" - -from django.test import TestCase - -class SimpleTest(TestCase): - def test_basic_addition(self): - """ - Tests that 1 + 1 always equals 2. - """ - self.failUnlessEqual(1 + 1, 2) - -__test__ = {"doctest": """ -Another way to test that 1 + 1 is equal to 2. - ->>> 1 + 1 == 2 -True -"""} - diff --git a/sample_project/sample_project/bootstrap.py b/sample_project/sample_project/bootstrap.py deleted file mode 100644 index e638789..0000000 --- a/sample_project/sample_project/bootstrap.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python -# bootstrap.py -# Bootstrap and setup a virtualenv with the specified requirements.txt -import os -import sys -import shutil -import subprocess -from optparse import OptionParser - - -usage = """usage: %prog [options]""" -parser = OptionParser(usage=usage) -parser.add_option("-c", "--clear", dest="clear", action="store_true", - help="clear out existing virtualenv") - - -def main(): - if "VIRTUAL_ENV" not in os.environ: - sys.stderr.write("$VIRTUAL_ENV not found.\n\n") - parser.print_usage() - sys.exit(-1) - (options, pos_args) = parser.parse_args() - virtualenv = os.environ["VIRTUAL_ENV"] - if options.clear: - subprocess.call(["virtualenv", "--clear", "--distribute", - virtualenv]) - file_path = os.path.dirname(__file__) - subprocess.call(["pip", "install", "-E", virtualenv, "--requirement", - os.path.join(file_path, "requirements/apps.txt")]) - - -if __name__ == "__main__": - main() - sys.exit(0) diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..9e2684e --- /dev/null +++ b/setup.cfg @@ -0,0 +1,3 @@ +[flake8] +exclude = migrations,docs,env,.tox +max-line-length = 120 diff --git a/tox.ini b/tox.ini index 85b7eff..ca5394a 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27-django{1.8,1.9,1.10},coverage,docs +envlist = py27-django{1.8,1.9,1.10},flake8,coverage,docs [testenv] basepython = @@ -14,6 +14,11 @@ setenv = DJANGO_SETTINGS_MODULE=sample_project.settings commands = {envpython} sample_project/manage.py test +[testenv:flake8] +basepython = python2.7 +deps = flake8>=3.2.1 +commands = flake8 . + [testenv:coverage] basepython = python2.7 commands =