aboutsummaryrefslogtreecommitdiff
path: root/v_windows/v/old/vlib/vweb/assets/assets.v
diff options
context:
space:
mode:
Diffstat (limited to 'v_windows/v/old/vlib/vweb/assets/assets.v')
-rw-r--r--v_windows/v/old/vlib/vweb/assets/assets.v201
1 files changed, 201 insertions, 0 deletions
diff --git a/v_windows/v/old/vlib/vweb/assets/assets.v b/v_windows/v/old/vlib/vweb/assets/assets.v
new file mode 100644
index 0000000..1240e41
--- /dev/null
+++ b/v_windows/v/old/vlib/vweb/assets/assets.v
@@ -0,0 +1,201 @@
+module assets
+
+// this module provides an AssetManager for combining
+// and caching javascript & css.
+import os
+import time
+import crypto.md5
+
+const (
+ unknown_asset_type_error = 'vweb.assets: unknown asset type'
+)
+
+struct AssetManager {
+mut:
+ css []Asset
+ js []Asset
+pub mut:
+ // when true assets will be minified
+ minify bool
+ // the directory to store the cached/combined files
+ cache_dir string
+}
+
+struct Asset {
+ file_path string
+ last_modified time.Time
+}
+
+// new_manager returns a new AssetManager
+pub fn new_manager() &AssetManager {
+ return &AssetManager{}
+}
+
+// add_css adds a css asset
+pub fn (mut am AssetManager) add_css(file string) bool {
+ return am.add('css', file)
+}
+
+// add_js adds a js asset
+pub fn (mut am AssetManager) add_js(file string) bool {
+ return am.add('js', file)
+}
+
+// combine_css returns the combined css as a string when to_file is false
+// when to_file is true it combines the css to disk and returns the path of the file
+pub fn (am AssetManager) combine_css(to_file bool) string {
+ return am.combine('css', to_file)
+}
+
+// combine_js returns the combined js as a string when to_file is false
+// when to_file is true it combines the css to disk and returns the path of the file
+pub fn (am AssetManager) combine_js(to_file bool) string {
+ return am.combine('js', to_file)
+}
+
+// include_css returns the html <link> tag(s) for including the css files in a page.
+// when combine is true the files are combined.
+pub fn (am AssetManager) include_css(combine bool) string {
+ return am.include('css', combine)
+}
+
+// include_js returns the html <script> tag(s) for including the js files in a page.
+// when combine is true the files are combined.
+pub fn (am AssetManager) include_js(combine bool) string {
+ return am.include('js', combine)
+}
+
+fn (am AssetManager) combine(asset_type string, to_file bool) string {
+ if am.cache_dir == '' {
+ panic('vweb.assets: you must set a cache dir.')
+ }
+ cache_key := am.get_cache_key(asset_type)
+ out_file := '$am.cache_dir/${cache_key}.$asset_type'
+ mut out := ''
+ // use cache
+ if os.exists(out_file) {
+ if to_file {
+ return out_file
+ }
+ cached := os.read_file(out_file) or { return '' }
+ return cached
+ }
+ // rebuild
+ for asset in am.get_assets(asset_type) {
+ data := os.read_file(asset.file_path) or { return '' }
+ out += data
+ }
+ if am.minify {
+ if asset_type == 'css' {
+ out = minify_css(out)
+ } else {
+ out = minify_js(out)
+ }
+ }
+ if !to_file {
+ return out
+ }
+ if !os.is_dir(am.cache_dir) {
+ os.mkdir(am.cache_dir) or { panic(err) }
+ }
+ mut file := os.create(out_file) or { panic(err) }
+ file.write(out.bytes()) or { panic(err) }
+ file.close()
+ return out_file
+}
+
+fn (am AssetManager) get_cache_key(asset_type string) string {
+ mut files_salt := ''
+ mut latest_modified := u64(0)
+ for asset in am.get_assets(asset_type) {
+ files_salt += asset.file_path
+ if asset.last_modified.unix > latest_modified {
+ latest_modified = asset.last_modified.unix
+ }
+ }
+ hash := md5.sum(files_salt.bytes()).hex()
+ return '$hash-$latest_modified'
+}
+
+fn (am AssetManager) include(asset_type string, combine bool) string {
+ assets := am.get_assets(asset_type)
+ mut out := ''
+ if asset_type == 'css' {
+ if combine {
+ file := am.combine(asset_type, true)
+ return '<link rel="stylesheet" href="$file">\n'
+ }
+ for asset in assets {
+ out += '<link rel="stylesheet" href="$asset.file_path">\n'
+ }
+ }
+ if asset_type == 'js' {
+ if combine {
+ file := am.combine(asset_type, true)
+ return '<script type="text/javascript" src="$file"></script>\n'
+ }
+ for asset in assets {
+ out += '<script type="text/javascript" src="$asset.file_path"></script>\n'
+ }
+ }
+ return out
+}
+
+// dont return option until size limit is removed
+// fn (mut am AssetManager) add(asset_type, file string) ?bool {
+fn (mut am AssetManager) add(asset_type string, file string) bool {
+ if !os.exists(file) {
+ // return error('vweb.assets: cannot add asset $file, it does not exist')
+ return false
+ }
+ asset := Asset{
+ file_path: file
+ last_modified: time.Time{
+ unix: u64(os.file_last_mod_unix(file))
+ }
+ }
+ if asset_type == 'css' {
+ am.css << asset
+ } else if asset_type == 'js' {
+ am.js << asset
+ } else {
+ panic('$assets.unknown_asset_type_error ($asset_type).')
+ }
+ return true
+}
+
+fn (am AssetManager) exists(asset_type string, file string) bool {
+ assets := am.get_assets(asset_type)
+ for asset in assets {
+ if asset.file_path == file {
+ return true
+ }
+ }
+ return false
+}
+
+fn (am AssetManager) get_assets(asset_type string) []Asset {
+ if asset_type != 'css' && asset_type != 'js' {
+ panic('$assets.unknown_asset_type_error ($asset_type).')
+ }
+ assets := if asset_type == 'css' { am.css } else { am.js }
+ return assets
+}
+
+// todo: implement proper minification
+pub fn minify_css(css string) string {
+ mut lines := css.split('\n')
+ for i, _ in lines {
+ lines[i] = lines[i].trim_space()
+ }
+ return lines.join(' ')
+}
+
+// todo: implement proper minification
+pub fn minify_js(js string) string {
+ mut lines := js.split('\n')
+ for i, _ in lines {
+ lines[i] = lines[i].trim_space()
+ }
+ return lines.join(' ')
+}