Merge commit 'a9dc73a68207553429e9441f74b7123261e97990' as 'utility'
This commit is contained in:
commit
35e8bb85f7
1
utility/.gitignore
vendored
Normal file
1
utility/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.lua
|
21
utility/LICENSE
Normal file
21
utility/LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018 Paul Liverman III
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
30
utility/calc.moon
Normal file
30
utility/calc.moon
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import bytes from require "resty.random"
|
||||||
|
import byte from string
|
||||||
|
import floor from math
|
||||||
|
|
||||||
|
-- return a random number between min/max
|
||||||
|
random = (min, max) ->
|
||||||
|
unless max
|
||||||
|
max = min or 1
|
||||||
|
min = 0
|
||||||
|
|
||||||
|
a, b = byte bytes(2), 1, 2
|
||||||
|
c, d = byte bytes(2), 1, 2
|
||||||
|
value = a + b * 256 + c * 65536 + d * 16777216 -- 0 to 4294967296
|
||||||
|
range = max - min
|
||||||
|
|
||||||
|
if max == floor(max) and min == floor(min)
|
||||||
|
return floor value * range / 4294967296 + min
|
||||||
|
else
|
||||||
|
return value * range / 4294967296 + min
|
||||||
|
|
||||||
|
-- map a value within a range of numbers to another range
|
||||||
|
map = (min1, max1, value, min2, max2) ->
|
||||||
|
range1 = max1 - min1
|
||||||
|
range2 = max2 - min2
|
||||||
|
return ((value - min1) * range2 / range1) + min2
|
||||||
|
|
||||||
|
{
|
||||||
|
:random
|
||||||
|
:map
|
||||||
|
}
|
36
utility/datetime.moon
Normal file
36
utility/datetime.moon
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import date, time from os
|
||||||
|
|
||||||
|
-- for database
|
||||||
|
now = ->
|
||||||
|
return date "!%Y-%m-%d %X"
|
||||||
|
|
||||||
|
-- database date -> display
|
||||||
|
pretty_date = (str) ->
|
||||||
|
year, month, day = str\match "(%d%d%d%d)-(%d%d)-(%d%d)"
|
||||||
|
return date "%B %d, %Y", time :year, :month, :day
|
||||||
|
|
||||||
|
-- from database
|
||||||
|
to_seconds = (str) ->
|
||||||
|
year, month, day, hour, min, sec = str\match "(%d%d%d%d)-(%d%d)-(%d%d) (%d%d):(%d%d):(%d%d)"
|
||||||
|
return time :year, :month, :day, :hour, :min, :sec
|
||||||
|
|
||||||
|
-- seconds -> for database
|
||||||
|
for_db = (seconds) ->
|
||||||
|
return date "!%Y-%m-%d %X", seconds
|
||||||
|
|
||||||
|
gmt_date = ->
|
||||||
|
return date "!*t"
|
||||||
|
|
||||||
|
gmt_time = ->
|
||||||
|
return time date "!*t"
|
||||||
|
|
||||||
|
{
|
||||||
|
none: "1970-01-01 00:00:00" -- TODO deprecate
|
||||||
|
zero: "1970-01-01 00:00:00" -- for use in database
|
||||||
|
:now
|
||||||
|
:pretty_date
|
||||||
|
:to_seconds
|
||||||
|
:for_db
|
||||||
|
:gmt_date
|
||||||
|
:gmt_time
|
||||||
|
}
|
9
utility/db.moon
Normal file
9
utility/db.moon
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
escape_similar_to = (str) ->
|
||||||
|
-- matches any of %_\|*+?{}()[]
|
||||||
|
-- puts a backslash in front of them
|
||||||
|
str = str\gsub "[%%_\\|%*%+%?{}%(%)%[%]]", "\\%1"
|
||||||
|
return str -- return on seperate line to avoid returning 2nd value from gsub
|
||||||
|
|
||||||
|
{
|
||||||
|
:escape_similar_to
|
||||||
|
}
|
23
utility/fs.moon
Normal file
23
utility/fs.moon
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
exists = (file_path) ->
|
||||||
|
if file = io.open file_path, "r"
|
||||||
|
file\close!
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
|
||||||
|
size = (file_or_path) ->
|
||||||
|
if "string" == type file_or_path
|
||||||
|
file = io.open file_or_path, "r"
|
||||||
|
size = file\seek "end"
|
||||||
|
file\close!
|
||||||
|
return size
|
||||||
|
else
|
||||||
|
current = file\seek!
|
||||||
|
size = file\seek "end"
|
||||||
|
file\seek "set", current
|
||||||
|
return size
|
||||||
|
|
||||||
|
{
|
||||||
|
:exists
|
||||||
|
:size
|
||||||
|
}
|
59
utility/gstring.moon
Normal file
59
utility/gstring.moon
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import insert, sort, concat from table
|
||||||
|
import sub, len from string
|
||||||
|
|
||||||
|
-- splits string by newline into array of strings
|
||||||
|
lines = (str) ->
|
||||||
|
tab = {}
|
||||||
|
for line in str\gmatch "[^\n]+"
|
||||||
|
insert tab, line
|
||||||
|
return tab
|
||||||
|
|
||||||
|
-- splits string by spaces into a table of strings
|
||||||
|
-- (handles bad spacing and duplicate substrings)
|
||||||
|
split = (str) ->
|
||||||
|
tab1, tab2 = {}, {}
|
||||||
|
for word in str\gmatch "%S+"
|
||||||
|
tab1[word] = true
|
||||||
|
for word in pairs tab1
|
||||||
|
insert tab2, word
|
||||||
|
return tab2
|
||||||
|
|
||||||
|
-- splits string by commas into a table of strings
|
||||||
|
-- (expects a well-formated string!)
|
||||||
|
comma_split = (str) ->
|
||||||
|
tab = {}
|
||||||
|
for word in str\gmatch "[^,]+"
|
||||||
|
insert tab, word
|
||||||
|
return tab
|
||||||
|
|
||||||
|
-- bool: does str1 start with str2
|
||||||
|
starts = (str1, str2) ->
|
||||||
|
return str2 == sub str1, 1, len str2
|
||||||
|
|
||||||
|
-- takes space-separated string and puts it in alphabetical order
|
||||||
|
-- (handles weird spacing, returns with single-spacing)
|
||||||
|
alphabetize = (str) ->
|
||||||
|
tab = split str
|
||||||
|
sort tab
|
||||||
|
return concat tab, " "
|
||||||
|
|
||||||
|
-- takes space-separated string and removes duplicate entries from it
|
||||||
|
remove_duplicates = (str) ->
|
||||||
|
strings = split str
|
||||||
|
tab, result = {}, {}
|
||||||
|
|
||||||
|
for str in *strings
|
||||||
|
tab[str] = true
|
||||||
|
for str in pairs tab
|
||||||
|
insert result, str
|
||||||
|
|
||||||
|
return concat result, " "
|
||||||
|
|
||||||
|
{
|
||||||
|
:lines
|
||||||
|
:split
|
||||||
|
:comma_split
|
||||||
|
:starts
|
||||||
|
:alphabetize
|
||||||
|
:remove_duplicates
|
||||||
|
}
|
33
utility/gtable.moon
Normal file
33
utility/gtable.moon
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
-- appends n arrays to the end of the first array
|
||||||
|
append = (tab1, ...) ->
|
||||||
|
for n = 1, select "#", ...
|
||||||
|
tab2 = select n, ...
|
||||||
|
for i = 1, #tab2
|
||||||
|
tab1[#tab1+1] = tab2[i]
|
||||||
|
return tab1
|
||||||
|
|
||||||
|
-- returns a new table shallow copying data from all arguments
|
||||||
|
-- later arguments overwrite any keys in earlier arguments
|
||||||
|
-- ignores non-table arguments (skipping them)
|
||||||
|
shallow_copy = (...) ->
|
||||||
|
new = {}
|
||||||
|
for n = 1, select "#", ...
|
||||||
|
tab = select n, ...
|
||||||
|
if "table" == type tab
|
||||||
|
for k,v in pairs tab
|
||||||
|
new[k] = v
|
||||||
|
return new
|
||||||
|
|
||||||
|
-- returns a new table with flipped keys and values
|
||||||
|
invert = (tab) ->
|
||||||
|
new = {}
|
||||||
|
for key, value in pairs tab
|
||||||
|
new[value] = key
|
||||||
|
return new
|
||||||
|
|
||||||
|
{
|
||||||
|
:append
|
||||||
|
:shallow_copy
|
||||||
|
shallow_merge: shallow_copy -- TODO deprecate
|
||||||
|
:invert
|
||||||
|
}
|
13
utility/migrations.moon
Normal file
13
utility/migrations.moon
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import create_table, types, create_index from require "lapis.db.schema"
|
||||||
|
|
||||||
|
{
|
||||||
|
[1518948992]: =>
|
||||||
|
create_table "settings", {
|
||||||
|
{"name", types.varchar primary_key: true, unique: true}
|
||||||
|
{"value", types.text null: true}
|
||||||
|
|
||||||
|
{"created_at", types.time}
|
||||||
|
{"updated_at", types.time}
|
||||||
|
}
|
||||||
|
create_index "settings", "name", unique: true
|
||||||
|
}
|
5
utility/models/Settings.moon
Normal file
5
utility/models/Settings.moon
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import Model from require "lapis.db.model"
|
||||||
|
|
||||||
|
class Settings extends Model
|
||||||
|
@timestamp: true
|
||||||
|
@primary_key: "name"
|
110
utility/settings.moon
Normal file
110
utility/settings.moon
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
import Settings from require "models"
|
||||||
|
|
||||||
|
totype = (str) ->
|
||||||
|
if value = tonumber str
|
||||||
|
return value
|
||||||
|
if str == "true"
|
||||||
|
return true
|
||||||
|
if str == "false"
|
||||||
|
return false
|
||||||
|
if str == "nil"
|
||||||
|
return nil
|
||||||
|
return str
|
||||||
|
|
||||||
|
cache = {}
|
||||||
|
|
||||||
|
get = (name, create=true) ->
|
||||||
|
setting = cache[name]
|
||||||
|
unless setting
|
||||||
|
setting = Settings\find :name
|
||||||
|
if (not setting) and create
|
||||||
|
setting = Settings\create :name
|
||||||
|
cache[name] = setting
|
||||||
|
|
||||||
|
if setting
|
||||||
|
return setting
|
||||||
|
else
|
||||||
|
return nil, "failed to load '#{name}' setting"
|
||||||
|
|
||||||
|
local settings
|
||||||
|
settings = {
|
||||||
|
get: (name, skip_index) ->
|
||||||
|
unless name
|
||||||
|
return settings.load!
|
||||||
|
|
||||||
|
unless skip_index -- for metamethods to not loop endlessly
|
||||||
|
return settings[name] if settings[name]
|
||||||
|
|
||||||
|
setting, err = get name
|
||||||
|
if setting
|
||||||
|
value = totype setting.value
|
||||||
|
settings[name] = value
|
||||||
|
return value
|
||||||
|
else
|
||||||
|
return nil, err
|
||||||
|
|
||||||
|
set: (name, value) ->
|
||||||
|
unless name
|
||||||
|
return settings.save!
|
||||||
|
|
||||||
|
setting, err = get name
|
||||||
|
if setting
|
||||||
|
settings[name] = value
|
||||||
|
return setting\update value: tostring value
|
||||||
|
else
|
||||||
|
return nil, err
|
||||||
|
|
||||||
|
save: (name) ->
|
||||||
|
if name
|
||||||
|
setting, err = get name
|
||||||
|
if setting
|
||||||
|
return setting\update value: tostring settings[name]
|
||||||
|
else
|
||||||
|
return nil, err
|
||||||
|
|
||||||
|
else
|
||||||
|
for name, value in pairs settings
|
||||||
|
switch name
|
||||||
|
when "get", "set", "save", "load", "delete"
|
||||||
|
nil
|
||||||
|
else
|
||||||
|
t = type value
|
||||||
|
if t == "function" or t == "table"
|
||||||
|
return nil, "cannot save '#{name}' setting, type '#{t}' not supported"
|
||||||
|
else
|
||||||
|
unless cache[name]
|
||||||
|
cache[name] = Settings\find :name
|
||||||
|
unless cache[name]
|
||||||
|
cache[name] = Settings\create :name
|
||||||
|
|
||||||
|
for name, setting in pairs cache
|
||||||
|
_, err = setting\update value: tostring settings[name]
|
||||||
|
return nil, err if err
|
||||||
|
return true
|
||||||
|
|
||||||
|
load: (name) ->
|
||||||
|
return settings.get name if name
|
||||||
|
|
||||||
|
all_settings = Settings\select "WHERE true"
|
||||||
|
for setting in *all_settings
|
||||||
|
name = setting.name
|
||||||
|
cache[name] = setting
|
||||||
|
settings[name] = totype setting.value
|
||||||
|
return settings
|
||||||
|
|
||||||
|
delete: (name) ->
|
||||||
|
if setting = get name, false
|
||||||
|
if setting\delete!
|
||||||
|
cache[name] = nil
|
||||||
|
settings[name] = nil
|
||||||
|
else
|
||||||
|
return nil, "failed to delete '#{name}' setting"
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return setmetatable settings, {
|
||||||
|
__call: (t, name) ->
|
||||||
|
return settings.get name, true
|
||||||
|
__index: (t, name) ->
|
||||||
|
return settings.get name, true
|
||||||
|
}
|
23
utility/shell.moon
Normal file
23
utility/shell.moon
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
quote = (str) ->
|
||||||
|
escaped = str\gsub "'", [['"'"']]
|
||||||
|
return "'#{escaped}'"
|
||||||
|
|
||||||
|
execute = (cmd, capture_exit_code=true) ->
|
||||||
|
local handle
|
||||||
|
if capture_exit_code
|
||||||
|
handle = io.popen "#{cmd}\necho $?"
|
||||||
|
else
|
||||||
|
handle = io.popen cmd
|
||||||
|
result = handle\read "*a"
|
||||||
|
handle\close!
|
||||||
|
|
||||||
|
exit_start, exit_end = result\find "(%d*)[%c]$"
|
||||||
|
exit_code = tonumber result\sub(exit_start, exit_end)\sub 1, -2
|
||||||
|
output = result\sub 1, exit_start - 1
|
||||||
|
|
||||||
|
return exit_code, output
|
||||||
|
|
||||||
|
{
|
||||||
|
:quote
|
||||||
|
:execute
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user