Commit b1ec9cf0 by Timothée Peignier

cleanup impot and style check

parent e6c8747b
from django.core.exceptions import ImproperlyConfigured
from django.conf import settings
......
......@@ -4,11 +4,11 @@ class FilterBase:
def filter_css(self, css):
raise NotImplementedError
def filter_js(self, js):
raise NotImplementedError
class FilterError(Exception):
"""
This exception is raised when a filter fails
"""
pass
\ No newline at end of file
"""This exception is raised when a filter fails"""
pass
......@@ -3,8 +3,8 @@ import subprocess
from compress.conf import settings
from compress.filter_base import FilterBase, FilterError
class ClosureCompressorFilter(FilterBase):
class ClosureCompressorFilter(FilterBase):
def filter_common(self, content, type_, arguments):
command = '%s %s' % (settings.COMPRESS_CLOSURE_BINARY, arguments)
......@@ -34,4 +34,4 @@ class ClosureCompressorFilter(FilterBase):
return filtered_css
def filter_js(self, js):
return self.filter_common(js, 'js', settings.COMPRESS_CLOSURE_JS_ARGUMENTS)
\ No newline at end of file
return self.filter_common(js, 'js', settings.COMPRESS_CLOSURE_JS_ARGUMENTS)
......@@ -11,6 +11,7 @@ ARGUMENTS = getattr(settings, 'CSSTIDY_ARGUMENTS', '--template=highest')
warnings.simplefilter('ignore', RuntimeWarning)
class CSSTidyFilter(FilterBase):
def filter_css(self, css):
tmp_file = tempfile.NamedTemporaryFile(mode='w+b')
......@@ -18,16 +19,16 @@ class CSSTidyFilter(FilterBase):
tmp_file.flush()
output_file = tempfile.NamedTemporaryFile(mode='w+b')
command = '%s %s %s %s' % (BINARY, tmp_file.name, ARGUMENTS, output_file.name)
command_output = os.popen(command).read()
filtered_css = output_file.read()
output_file.close()
tmp_file.close()
if self.verbose:
print command_output
return filtered_css
from compress.filters.jsmin.jsmin import jsmin
from compress.filter_base import FilterBase
class JSMinFilter(FilterBase):
def filter_js(self, js):
return jsmin(js)
\ No newline at end of file
return jsmin(js)
#!/usr/bin/python
# This code is original from jsmin by Douglas Crockford, it was translated to
# Python by Baruch Even. The original code had the following copyright and
# license.
......@@ -29,9 +30,9 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# */
from StringIO import StringIO
def jsmin(js):
ins = StringIO(js)
outs = StringIO()
......@@ -41,26 +42,31 @@ def jsmin(js):
str = str[1:]
return str
def isAlphanum(c):
"""return true if the character is a letter, digit, underscore,
dollar sign, or non-ASCII character.
"""
return ((c >= 'a' and c <= 'z') or (c >= '0' and c <= '9') or
(c >= 'A' and c <= 'Z') or c == '_' or c == '$' or c == '\\' or (c is not None and ord(c) > 126));
(c >= 'A' and c <= 'Z') or c == '_' or c == '$' or c == '\\' or (c is not None and ord(c) > 126))
class UnterminatedComment(Exception):
pass
class UnterminatedStringLiteral(Exception):
pass
class UnterminatedRegularExpression(Exception):
pass
class JavascriptMinify(object):
class JavascriptMinify(object):
def _outA(self):
self.outstream.write(self.theA)
def _outB(self):
self.outstream.write(self.theB)
......@@ -75,7 +81,7 @@ class JavascriptMinify(object):
c = self.instream.read(1)
if c >= ' ' or c == '\n':
return c
if c == '': # EOF
if c == '': # EOF
return '\000'
if c == '\r':
return '\n'
......@@ -135,7 +141,6 @@ class JavascriptMinify(object):
self._outA()
self.theA = self._get()
if action <= 3:
self.theB = self._next()
if self.theB == '/' and (self.theA == '(' or self.theA == ',' or
......@@ -159,7 +164,6 @@ class JavascriptMinify(object):
self._outA()
self.theB = self._next()
def _jsmin(self):
"""Copy the input to the output, deleting the characters which are
insignificant to JavaScript. Comments will be removed. Tabs will be
......@@ -215,4 +219,4 @@ class JavascriptMinify(object):
if __name__ == '__main__':
import sys
jsm = JavascriptMinify()
jsm.minify(sys.stdin, sys.stdout)
\ No newline at end of file
jsm.minify(sys.stdin, sys.stdout)
......@@ -3,8 +3,8 @@ import subprocess
from compress.conf import settings
from compress.filter_base import FilterBase, FilterError
class YUICompressorFilter(FilterBase):
class YUICompressorFilter(FilterBase):
def filter_common(self, content, type_, arguments):
command = '%s --type=%s %s' % (settings.COMPRESS_YUI_BINARY, type_, arguments)
......@@ -37,4 +37,4 @@ class YUICompressorFilter(FilterBase):
return self.filter_common(js, 'js', settings.COMPRESS_YUI_JS_ARGUMENTS)
def filter_css(self, css):
return self.filter_common(css, 'css', settings.COMPRESS_YUI_CSS_ARGUMENTS)
\ No newline at end of file
return self.filter_common(css, 'css', settings.COMPRESS_YUI_CSS_ARGUMENTS)
......@@ -3,6 +3,7 @@ from optparse import make_option
from django.conf import settings
class Command(NoArgsCommand):
option_list = NoArgsCommand.option_list + (
make_option('--force', action='store_true', default=False, help='Force update of all files, even if the source files are older than the current compressed file.'),
......@@ -11,14 +12,14 @@ class Command(NoArgsCommand):
args = ''
def handle_noargs(self, **options):
force = options.get('force', False)
verbosity = int(options.get('verbosity', 1))
from compress.utils import needs_update, filter_css, filter_js
for name, css in settings.COMPRESS_CSS.items():
u, version = needs_update(css['output_filename'],
u, version = needs_update(css['output_filename'],
css['source_filenames'])
if (force or u) or verbosity >= 2:
......@@ -37,7 +38,7 @@ class Command(NoArgsCommand):
if 'external_urls' in js:
u, version = False, "External"
else:
u, version = needs_update(js['output_filename'],
u, version = needs_update(js['output_filename'],
js['source_filenames'])
if (force or u) or verbosity >= 2:
......@@ -53,7 +54,7 @@ class Command(NoArgsCommand):
print
# Backwards compatibility for Django r9110
if not [opt for opt in Command.option_list if opt.dest=='verbosity']:
if not [opt for opt in Command.option_list if opt.dest == 'verbosity']:
Command.option_list += (
make_option('--verbosity', '-v', action="store", dest="verbosity",
default='1', type='choice', choices=['0', '1', '2'],
......
......@@ -2,10 +2,8 @@ import os
from django import template
from django.conf import settings as django_settings
from compress.conf import settings
from compress.utils import compress_root, compress_url, needs_update, filter_css, filter_js, get_output_filename, get_version, get_version_from_file
from compress.utils import compress_root, compress_url, needs_update, filter_css, filter_js, get_output_filename, get_version_from_file
register = template.Library()
......@@ -19,6 +17,7 @@ js_templates = {}
for key in settings.COMPRESS_JS:
settings.COMPRESS_JS[key]['template'] = template.loader.get_template(settings.COMPRESS_JS[key].get('template_name', 'compress/js.html'))
def render_common(obj, filename, version):
if settings.COMPRESS:
filename = get_output_filename(filename, version)
......@@ -29,15 +28,18 @@ def render_common(obj, filename, version):
context['url'] = filename
else:
context['url'] = compress_url(filename, prefix)
return obj['template'].render(context)
def render_css(css, filename, version=None):
return render_common(css, filename, version)
def render_js(js, filename, version=None):
return render_common(js, filename, version)
class CompressedCSSNode(template.Node):
def __init__(self, name):
self.name = name
......@@ -48,14 +50,14 @@ class CompressedCSSNode(template.Node):
try:
css = settings.COMPRESS_CSS[css_name]
except KeyError:
return '' # fail silently, do not return anything if an invalid group is specified
return '' # fail silently, do not return anything if an invalid group is specified
if settings.COMPRESS:
version = None
if settings.COMPRESS_AUTO:
u, version = needs_update(css['output_filename'],
u, version = needs_update(css['output_filename'],
css['source_filenames'])
if u:
filter_css(css)
......@@ -63,7 +65,7 @@ class CompressedCSSNode(template.Node):
filename_base, filename = os.path.split(css['output_filename'])
path_name = compress_root(filename_base)
version = get_version_from_file(path_name, filename)
return render_css(css, css['output_filename'], version)
else:
# output source files
......@@ -73,6 +75,7 @@ class CompressedCSSNode(template.Node):
return r
class CompressedJSNode(template.Node):
def __init__(self, name):
self.name = name
......@@ -83,24 +86,24 @@ class CompressedJSNode(template.Node):
try:
js = settings.COMPRESS_JS[js_name]
except KeyError:
return '' # fail silently, do not return anything if an invalid group is specified
return '' # fail silently, do not return anything if an invalid group is specified
if 'external_urls' in js:
r = ''
for url in js['external_urls']:
r += render_js(js, url)
return r
if settings.COMPRESS:
version = None
if settings.COMPRESS_AUTO:
u, version = needs_update(js['output_filename'],
u, version = needs_update(js['output_filename'],
js['source_filenames'])
if u:
filter_js(js)
else:
else:
filename_base, filename = os.path.split(js['output_filename'])
path_name = compress_root(filename_base)
version = get_version_from_file(path_name, filename) if settings.COMPRESS_VERSION else None
......@@ -113,6 +116,7 @@ class CompressedJSNode(template.Node):
r += render_js(js, source_file)
return r
#@register.tag
def compressed_css(parser, token):
try:
......@@ -123,6 +127,7 @@ def compressed_css(parser, token):
return CompressedCSSNode(name)
compressed_css = register.tag(compressed_css)
#@register.tag
def compressed_js(parser, token):
try:
......
import os
import re
import tempfile
from django.conf import settings as django_settings
from django.utils.http import urlquote
from django.dispatch import dispatcher
from compress.conf import settings
from compress.signals import css_filtered, js_filtered
def get_class(class_string):
"""
Convert a string version of a function name to the callable object.
"""
if not hasattr(class_string, '__bases__'):
try:
class_string = class_string.encode('ascii')
mod_name, class_name = get_mod_func(class_string)
......@@ -23,21 +20,21 @@ def get_class(class_string):
class_string = getattr(__import__(mod_name, {}, {}, ['']), class_name)
except (ImportError, AttributeError):
raise Exception('Failed to import filter %s' % class_string)
return class_string
def get_mod_func(callback):
"""
Converts 'django.views.news.stories.story_detail' to
('django.views.news.stories', 'story_detail')
"""
try:
dot = callback.rindex('.')
except ValueError:
return callback, ''
return callback[:dot], callback[dot+1:]
return callback[:dot], callback[dot + 1:]
def get_hexdigest(plaintext):
"""
Create a hexdigest from a plaintext string
......@@ -49,39 +46,44 @@ def get_hexdigest(plaintext):
import sha
return sha.new(plaintext).hexdigest()
def needs_update(output_file, source_files, verbosity=0):
"""
Scan the source files for changes and returns True if the output_file needs to be updated.
"""
version = get_version(source_files)
on = get_output_filename(output_file, version)
compressed_file_full = compress_root(on)
if not os.path.exists(compressed_file_full):
return True, version
update_needed = getattr(get_class(settings.COMPRESS_VERSIONING)(), 'needs_update')(output_file, source_files, version)
return update_needed
def compress_root(filename):
"""
Return the full path to ``filename``. ``filename`` is a relative path name in COMPRESS_ROOT
"""
return os.path.join(settings.COMPRESS_ROOT, filename)
def compress_source(filename):
"""
Return the full path to ``filename``. ``filename`` is a relative path name in COMPRESS_SOURCE
"""
return os.path.join(settings.COMPRESS_SOURCE, filename)
def compress_url(url, prefix=None):
if prefix:
return prefix + urlquote(url)
return settings.COMPRESS_URL + urlquote(url)
def concat(filenames, separator=''):
"""
Concatenate the files from the list of the ``filenames``, ouput separated with ``separator``.
......@@ -97,7 +99,7 @@ def concat(filenames, separator=''):
contents = fd.read()
fd.close()
if filename.lower().endswith('.css') and \
django_settings.COMPRESS_ROOT == settings.COMPRESS_SOURCE:
django_settings.COMPRESS_ROOT == settings.COMPRESS_SOURCE:
if django_settings.COMPRESS_URL.endswith('/'):
abspath = os.path.normpath(os.path.dirname(filename))
else:
......@@ -111,6 +113,7 @@ def concat(filenames, separator=''):
r += separator
return r
def save_file(filename, contents):
dirname = os.path.dirname(compress_root(filename))
if not os.path.exists(dirname):
......@@ -119,16 +122,19 @@ def save_file(filename, contents):
fd.write(contents)
fd.close()
def get_output_filename(filename, version):
if settings.COMPRESS_VERSION and version is not None:
return filename.replace(settings.COMPRESS_VERSION_PLACEHOLDER, version)
else:
return filename.replace(settings.COMPRESS_VERSION_PLACEHOLDER, settings.COMPRESS_VERSION_DEFAULT)
def get_version(source_files, verbosity=0):
version = getattr(get_class(settings.COMPRESS_VERSIONING)(), 'get_version')(source_files)
return version
def get_version_from_file(path, filename):
regex = re.compile(r'^%s$' % (get_output_filename(settings.COMPRESS_VERSION_PLACEHOLDER.join([re.escape(part) for part in filename.split(settings.COMPRESS_VERSION_PLACEHOLDER)]), r'([A-Za-z0-9]+)')))
results = []
......@@ -139,19 +145,21 @@ def get_version_from_file(path, filename):
results.sort()
return results[-1]
def remove_files(path, filename, verbosity=0):
def remove_files(path, filename, verbosity=0):
regex = re.compile(r'^%s$' % (os.path.basename(get_output_filename(settings.COMPRESS_VERSION_PLACEHOLDER.join([re.escape(part) for part in filename.split(settings.COMPRESS_VERSION_PLACEHOLDER)]), r'[A-Za-z0-9]+'))))
if os.path.exists(path):
for f in os.listdir(path):
if regex.match(f):
if verbosity >= 1:
print "Removing outdated file %s" % f
os.unlink(os.path.join(path, f))
def filter_common(obj, verbosity, filters, attr, separator, signal):
output = concat(obj['source_filenames'], separator)
filename = get_output_filename(obj['output_filename'], get_version(obj['source_filenames']))
if settings.COMPRESS_VERSION and settings.COMPRESS_VERSION_REMOVE_OLD:
......@@ -166,8 +174,10 @@ def filter_common(obj, verbosity, filters, attr, separator, signal):
save_file(filename, output)
signal.send(None)
def filter_css(css, verbosity=0):
return filter_common(css, verbosity, filters=settings.COMPRESS_CSS_FILTERS, attr='filter_css', separator='', signal=css_filtered)
def filter_js(js, verbosity=0):
return filter_common(js, verbosity, filters=settings.COMPRESS_JS_FILTERS, attr='filter_js', separator='', signal=js_filtered)
class VersioningBase(object):
def get_version(self, source_files):
raise NotImplementedError
def needs_update(self, output_file, source_files, version):
raise NotImplementedError
class VersioningError(Exception):
"""
This exception is raised when version creation fails
"""
pass
\ No newline at end of file
"""This exception is raised when version creation fails"""
pass
import os
from compress.conf import settings
from compress.utils import get_output_filename, get_hexdigest, compress_source
from compress.versioning.base import VersioningBase, VersioningError
......@@ -8,7 +6,8 @@ try:
import git
except ImportError:
raise VersioningError("Must have GitPython package installed to use git versioning")
class GitVersioningBase(VersioningBase):
def needs_update(self, output_file, source_files, version):
output_file_name = get_output_filename(output_file, version)
......@@ -16,25 +15,27 @@ class GitVersioningBase(VersioningBase):
of = output_file
try:
phi = of.index(ph)
old_version = output_file_name[phi:phi+len(ph)-len(of)]
old_version = output_file_name[phi:phi + len(ph) - len(of)]
return (version != old_version), version
except ValueError:
# no placeholder found, do not update, manual update if needed
return False, version
class GitRevVersioning(GitVersioningBase):
"""
Version as hash of revision of all files in sources_files list.
"""
def get_version(self, source_files):
repo = git.Repo(compress_source(source_files[0]))
kwargs = {'max_count' : 1}
kwargs = {'max_count': 1}
commit_revs = []
for f in source_files:
commit = [i for i in repo.iter_commits(paths=compress_source(f), **kwargs)][0]
commit_revs.append(commit.name_rev)
return get_hexdigest(', '.join(commit_revs))[0:16]
class GitHeadRevVersioning(GitVersioningBase):
"""
Version as hash of latest revision in HEAD. Assumes all sources_files in same git repo.
......@@ -42,4 +43,4 @@ class GitHeadRevVersioning(GitVersioningBase):
def get_version(self, source_files):
f = source_files[0]
repo = git.Repo(compress_source(f))
return get_hexdigest(repo.head.commit.name_rev)[0:16]
\ No newline at end of file
return get_hexdigest(repo.head.commit.name_rev)[0:16]
import cStringIO
from hashlib import md5, sha1
import os
from compress.conf import settings
from compress.utils import concat, get_output_filename
from compress.versioning.base import VersioningBase
class HashVersioningBase(VersioningBase):
def __init__(self, hash_method):
self.hash_method = hash_method
def needs_update(self, output_file, source_files, version):
output_file_name = get_output_filename(output_file, version)
ph = settings.COMPRESS_VERSION_PLACEHOLDER
of = output_file
try:
phi = of.index(ph)
old_version = output_file_name[phi:phi+len(ph)-len(of)]
old_version = output_file_name[phi:phi + len(ph) - len(of)]
return (version != old_version), version
except ValueError:
# no placeholder found, do not update, manual update if needed
return False, version
def get_version(self, source_files):
buf = concat(source_files)
s = cStringIO.StringIO(buf)
version = self.get_hash(s)
s.close()
return version
def get_hash(self, f, CHUNK=2**16):
return version
def get_hash(self, f, CHUNK=2 ** 16):
m = self.hash_method()
while 1:
chunk = f.read(CHUNK)
......@@ -38,10 +38,12 @@ class HashVersioningBase(VersioningBase):
m.update(chunk)
return m.hexdigest()
class MD5Versioning(HashVersioningBase):
def __init__(self):
super(MD5Versioning, self).__init__(md5)
class SHA1Versioning(HashVersioningBase):
def __init__(self):
super(SHA1Versioning, self).__init__(sha1)
\ No newline at end of file
super(SHA1Versioning, self).__init__(sha1)
......@@ -3,18 +3,15 @@ import os
from compress.utils import get_output_filename, compress_source, compress_root
from compress.versioning.base import VersioningBase
class MTimeVersioning(VersioningBase):
class MTimeVersioning(VersioningBase):
def get_version(self, source_files):
# Return the modification time for the newest source file
return str(max(
[int(os.stat(compress_source(f)).st_mtime) for f in source_files]))
[int(os.stat(compress_source(f)).st_mtime) for f in source_files]
))
def needs_update(self, output_file, source_files, version):
output_file_name = get_output_filename(output_file, version)
compressed_file_full = compress_root(output_file_name)
return (int(os.stat(compressed_file_full).st_mtime) < int(version)), version
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment