file.lua (4850B)
1 -- @module file 2 local file = {} 3 -- 4 local lfs = require 'lfs' 5 local mimetypes = require 'mimetypes' 6 local lume = require 'satelito.lib.lume.lume' 7 local dirtree = require 'satelito.dirtree' 8 9 -- Check if a file exists 10 function file.exists(filepath) 11 local _file = io.open(filepath, 'r') 12 13 if _file ~= nil then 14 _file:close() 15 16 return filepath 17 else 18 return false 19 end 20 end 21 22 -- Open & read the content of a file 23 function file.read(filepath) 24 if not filepath then 25 print('A file is missing ...') 26 end 27 28 local _file = assert(io.open(filepath, 'r')) 29 local content = _file:read '*a' 30 31 _file:close() 32 33 return content 34 end 35 36 -- Create a file and add data in it 37 function file.write(filepath, data) 38 local _file = io.open(filepath, 'w+') 39 40 _file:write(data) 41 _file:close() 42 43 return assert(lfs.attributes(filepath).mode == 'file') 44 end 45 46 -- Get basename from a file path 47 function file.get_basename(filepath) 48 return filepath:gsub('(.*/)(.*)', '%2') 49 end 50 51 -- Get the directory of a file 52 function file.get_dirname(filepath) 53 return filepath:match("(.*/)") and filepath:match("(.*/)") or '' 54 end 55 56 -- Get directory basename 57 function file.get_basedir(dirname) 58 return dirname:match('^.+/(.+)$') 59 end 60 61 function file.get_relpath(filepath, dirname) 62 return filepath:sub((dirname):len() + 1) 63 end 64 65 function file.get_permalink(filepath, dirname, url) 66 return url .. '/' .. file.get_relpath(filepath, dirname):match('(.+)%..*') .. '.html' 67 end 68 69 function file.get_exportlink(filepath, dirname, htmlpath) 70 return htmlpath .. file.get_relpath(filepath, dirname):match('(.+)%..*') .. '.html' 71 end 72 73 function file.get_metafile(filepath) 74 if lfs.attributes(filepath:match('(.+)%..*') .. '.lua') then 75 return dofile(filepath:match('(.+)%..*') .. '.lua') 76 else 77 return nil 78 end 79 end 80 81 -- Get the modified file from a list of paths 82 function file.get_lastmodified(filelist) 83 return math.max( 84 table.unpack( 85 lume.map(filelist, 86 function(fl) 87 return lfs.attributes(fl).modification 88 end 89 ))) 90 end 91 92 -- Check if the file is markdown 93 function file.is_markdown(filepath) 94 return (mimetypes.guess(filepath) == 'text/x-markdown') 95 end 96 97 -- Check if the file is HTML 98 function file.is_html(filepath) 99 return (mimetypes.guess(filepath) == 'text/html') 100 end 101 102 -- Check if the file is index.md 103 function file.is_index(filepath) 104 return (file.get_basename(filepath) == 'index.md') or (file.get_basename(filepath) == 'index.html') 105 end 106 107 -- Check if the file is content (markdown or html) 108 function file.is_content(filepath) 109 assert(filepath, filepath..' does not exists') 110 return (mimetypes.guess(filepath) == 'text/x-markdown') or (mimetypes.guess(filepath) == 'text/html') 111 end 112 113 -- Check if the file is lua 114 function file.is_lua(filepath) 115 return (mimetypes.guess(filepath) == 'text/x-lua') 116 end 117 118 function file.get_rellink(filepath, dirname) 119 if file.is_index(filepath) then 120 return '/' .. file.get_dirname(file.get_relpath(filepath, dirname)) 121 else 122 return '/' .. file.get_relpath(filepath, dirname):match('(.+)%..*') .. '.html' 123 end 124 end 125 126 -- Get a list of relative children paths from a filepath 127 function file.get_list(filepath, dirname) 128 local collection = {} 129 130 for subfilepath in dirtree.get(file.get_dirname(filepath)) do 131 if subfilepath 132 and file.is_content(subfilepath) 133 and not file.is_index(subfilepath) 134 then 135 collection[#collection+1] = file.get_relpath(subfilepath, dirname) 136 end 137 end 138 139 return collection 140 end 141 142 -- Get a table collection of contents 143 function file.get_collection(collection) 144 if collection and type(collection) == 'table' then 145 local collection_list = {} 146 local contentdir = _G.Satelito.contentdir 147 148 for i = 1, #collection do 149 if lfs.attributes(contentdir..collection[i]).mode == 'directory' then 150 collection_list[#collection_list+1] = file.get_list(contentdir..collection[i], contentdir) 151 else 152 collection_list[#collection_list+1] = { collection[i] } 153 end 154 end 155 156 return lume.concat(table.unpack(collection_list)) 157 end 158 159 return 160 end 161 162 -- Create a dirtree 163 function file.mkdir(filepath) 164 local sep, pStr = package.config:sub(1, 1), '' 165 -- Check if the filepath is absolute or relative 166 local _filepath = (string.find(filepath, lfs.currentdir()) 167 and filepath 168 or lfs.currentdir() .. '/' .. filepath) 169 170 -- 171 for dir in _filepath:gmatch('[^' .. sep .. ']+') do 172 pStr = pStr .. sep .. dir 173 lfs.mkdir(pStr) 174 end 175 end 176 -- 177 178 --- Export a file to a specific location 179 -- @name file.export 180 -- @param filepath the location path of the file 181 -- @param filecontent a string that is a code block 182 -- @return execute a file.write function 183 function file.export(filepath, filecontent) 184 file.mkdir(file.get_dirname(filepath)) 185 return file.write(filepath, filecontent) 186 end 187 188 return file