2011-11-07 08:48:00 -08:00
|
|
|
import os
|
|
|
|
from fnmatch import fnmatch
|
2024-04-24 09:50:42 -04:00
|
|
|
|
2020-06-17 03:26:48 -04:00
|
|
|
import yaml
|
2011-11-07 08:48:00 -08:00
|
|
|
from django.conf import settings
|
|
|
|
|
|
|
|
DATA_URI_START = "<!--[if (!IE)|(gte IE 8)]><!-->"
|
|
|
|
DATA_URI_END = "<!--<![endif]-->"
|
|
|
|
MHTML_START = "<!--[if lte IE 7]>"
|
|
|
|
MHTML_END = "<![endif]-->"
|
|
|
|
|
2024-04-24 09:43:56 -04:00
|
|
|
|
2011-11-07 08:48:00 -08:00
|
|
|
class JammitAssets:
|
2024-04-24 09:43:56 -04:00
|
|
|
ASSET_FILENAME = "assets.yml"
|
2011-11-07 08:48:00 -08:00
|
|
|
|
2012-01-14 10:59:10 -08:00
|
|
|
def __init__(self, assets_dir):
|
2011-11-07 08:48:00 -08:00
|
|
|
"""
|
|
|
|
Initializes the Jammit object by reading the assets.yml file and
|
|
|
|
stores all javascripts and stylesheets in memory for easy lookup
|
|
|
|
in templates.
|
|
|
|
"""
|
2012-01-14 10:59:10 -08:00
|
|
|
self.assets_dir = assets_dir
|
2011-11-07 08:48:00 -08:00
|
|
|
self.assets = self.read_assets()
|
2024-04-24 09:43:56 -04:00
|
|
|
|
2011-11-07 08:48:00 -08:00
|
|
|
def read_assets(self):
|
|
|
|
"""
|
|
|
|
Read the assets from the YAML and store it as a lookup dictionary.
|
|
|
|
"""
|
2012-01-14 10:59:10 -08:00
|
|
|
filepath = os.path.join(self.assets_dir, self.ASSET_FILENAME)
|
2020-06-17 03:26:48 -04:00
|
|
|
|
2024-04-24 09:43:56 -04:00
|
|
|
with open(filepath, "r") as yaml_file:
|
2020-06-17 03:26:48 -04:00
|
|
|
return yaml.safe_load(yaml_file)
|
2024-04-24 09:43:56 -04:00
|
|
|
|
2011-11-07 08:48:00 -08:00
|
|
|
def render_tags(self, asset_type, asset_package):
|
|
|
|
"""
|
|
|
|
Returns rendered <script> and <link> tags for the given package name. Will
|
2024-04-24 09:43:56 -04:00
|
|
|
either be a single tag or a list of tags as a string, depending on
|
2011-11-07 08:48:00 -08:00
|
|
|
`use_compressed_assets` profile setting.
|
|
|
|
"""
|
|
|
|
tags = []
|
2024-04-24 09:43:56 -04:00
|
|
|
if not getattr(settings, "DEBUG_ASSETS", settings.DEBUG):
|
|
|
|
if asset_type == "javascripts":
|
|
|
|
asset_type_ext = "js"
|
|
|
|
elif asset_type == "stylesheets":
|
|
|
|
asset_type_ext = "css"
|
|
|
|
if asset_type == "javascripts":
|
2011-11-07 08:48:00 -08:00
|
|
|
tag = self.javascript_tag_compressed(asset_package, asset_type_ext)
|
2024-04-24 09:43:56 -04:00
|
|
|
elif asset_type == "stylesheets":
|
2011-11-07 08:48:00 -08:00
|
|
|
tag = self.stylesheet_tag_compressed(asset_package, asset_type_ext)
|
|
|
|
tags.append(tag)
|
|
|
|
else:
|
|
|
|
patterns = self.assets[asset_type][asset_package]
|
|
|
|
for pattern in patterns:
|
|
|
|
paths = FileFinder.filefinder(pattern)
|
|
|
|
for path in paths:
|
2024-04-24 09:43:56 -04:00
|
|
|
if asset_type == "javascripts":
|
2011-11-07 08:48:00 -08:00
|
|
|
tag = self.javascript_tag(path)
|
2024-04-24 09:43:56 -04:00
|
|
|
elif asset_type == "stylesheets":
|
2011-11-07 08:48:00 -08:00
|
|
|
tag = self.stylesheet_tag(path)
|
|
|
|
tags.append(tag)
|
|
|
|
tags = self.uniquify(tags)
|
2024-04-24 09:43:56 -04:00
|
|
|
return "\n".join(tags)
|
|
|
|
|
2011-11-24 11:07:23 -05:00
|
|
|
def render_code(self, asset_type, asset_package):
|
|
|
|
text = []
|
|
|
|
patterns = self.assets[asset_type][asset_package]
|
2024-04-24 09:43:56 -04:00
|
|
|
|
2011-11-24 11:07:23 -05:00
|
|
|
for pattern in patterns:
|
|
|
|
paths = FileFinder.filefinder(pattern)
|
|
|
|
for path in paths:
|
|
|
|
newsblur_dir = settings.NEWSBLUR_DIR
|
|
|
|
abs_filename = os.path.join(newsblur_dir, path)
|
2024-04-24 09:43:56 -04:00
|
|
|
f = open(abs_filename, "r")
|
2011-11-24 11:07:23 -05:00
|
|
|
code = f.read()
|
2024-04-24 09:43:56 -04:00
|
|
|
if asset_type == "stylesheets":
|
|
|
|
code = code.replace('"', '\\"').replace("\n", " ")
|
2011-11-24 11:07:23 -05:00
|
|
|
text.append(code)
|
2024-04-24 09:43:56 -04:00
|
|
|
|
|
|
|
return "".join(text)
|
|
|
|
|
2011-11-07 08:48:00 -08:00
|
|
|
def uniquify(self, tags):
|
|
|
|
"""
|
|
|
|
Returns a uniquified list of script/link tags, preserving order.
|
|
|
|
"""
|
|
|
|
seen = set()
|
|
|
|
unique = []
|
2024-04-24 09:43:56 -04:00
|
|
|
|
2011-11-07 08:48:00 -08:00
|
|
|
for tag in tags:
|
|
|
|
if tag not in seen:
|
|
|
|
unique.append(tag)
|
|
|
|
seen.add(tag)
|
2011-11-24 11:07:23 -05:00
|
|
|
|
2011-11-07 08:48:00 -08:00
|
|
|
return unique
|
2024-04-24 09:43:56 -04:00
|
|
|
|
2011-11-07 08:48:00 -08:00
|
|
|
def javascript_tag(self, path):
|
2011-11-24 11:07:23 -05:00
|
|
|
return '<script src="/%s" type="text/javascript" charset="utf-8"></script>' % path
|
2024-04-24 09:43:56 -04:00
|
|
|
|
2011-11-07 08:48:00 -08:00
|
|
|
def javascript_tag_compressed(self, asset_package, asset_type_ext):
|
2024-04-24 09:43:56 -04:00
|
|
|
filename = "static/%s.%s" % (asset_package, asset_type_ext)
|
2011-11-07 08:48:00 -08:00
|
|
|
asset_mtime = int(os.path.getmtime(filename))
|
2024-04-24 09:43:56 -04:00
|
|
|
path = "%s?%s" % (filename, asset_mtime)
|
2011-11-07 08:48:00 -08:00
|
|
|
return self.javascript_tag(path)
|
2024-04-24 09:43:56 -04:00
|
|
|
|
2011-11-07 08:48:00 -08:00
|
|
|
def stylesheet_tag(self, path):
|
2011-11-24 11:07:23 -05:00
|
|
|
return '<link rel="stylesheet" href="/%s" type="text/css" charset="utf-8">' % path
|
2011-11-07 08:48:00 -08:00
|
|
|
|
|
|
|
def stylesheet_tag_compressed(self, asset_package, asset_type_ext):
|
2024-04-24 09:43:56 -04:00
|
|
|
datauri_filename = "static/%s-datauri.%s" % (asset_package, asset_type_ext)
|
|
|
|
original_filename = "static/%s.%s" % (asset_package, asset_type_ext)
|
2011-11-07 08:48:00 -08:00
|
|
|
asset_mtime = int(os.path.getmtime(datauri_filename))
|
2024-04-24 09:43:56 -04:00
|
|
|
datauri_path = "%s?%s" % (datauri_filename, asset_mtime)
|
|
|
|
original_path = "%s?%s" % (original_filename, asset_mtime)
|
|
|
|
|
|
|
|
return "\n".join(
|
|
|
|
[
|
|
|
|
DATA_URI_START,
|
|
|
|
self.stylesheet_tag(datauri_path),
|
|
|
|
DATA_URI_END,
|
|
|
|
MHTML_START,
|
|
|
|
self.stylesheet_tag(original_path),
|
|
|
|
MHTML_END,
|
|
|
|
]
|
|
|
|
)
|
2011-11-07 08:48:00 -08:00
|
|
|
|
|
|
|
|
2024-04-24 09:43:56 -04:00
|
|
|
class FileFinder:
|
2011-11-07 08:48:00 -08:00
|
|
|
@classmethod
|
|
|
|
def filefinder(cls, pattern):
|
|
|
|
paths = []
|
2024-04-24 09:43:56 -04:00
|
|
|
if "**" in pattern:
|
|
|
|
folder, wild, pattern = pattern.partition("/**/")
|
2011-11-07 08:48:00 -08:00
|
|
|
for f in cls.recursive_find_files(folder, pattern):
|
2011-11-24 11:07:23 -05:00
|
|
|
paths.append(f)
|
2011-11-07 08:48:00 -08:00
|
|
|
else:
|
|
|
|
folder, pattern = os.path.split(pattern)
|
|
|
|
for f in cls.find_files(folder, pattern):
|
|
|
|
# print f, paths
|
2011-11-24 11:07:23 -05:00
|
|
|
paths.append(f)
|
2011-11-07 08:48:00 -08:00
|
|
|
return paths
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def recursive_find_files(cls, folder, pattern):
|
|
|
|
for root, dirs, files in os.walk(folder):
|
|
|
|
for f in files:
|
|
|
|
if fnmatch(f, pattern):
|
|
|
|
yield os.path.join(root, f)
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def find_files(cls, folder, pattern):
|
|
|
|
listdir = os.listdir(folder)
|
|
|
|
listdir.sort()
|
|
|
|
for entry in listdir:
|
|
|
|
if not os.path.isdir(entry) and fnmatch(entry, pattern):
|
|
|
|
yield os.path.join(folder, entry)
|