diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/attr.lua | 232 | ||||
-rw-r--r-- | lib/util.lua | 11 |
2 files changed, 243 insertions, 0 deletions
diff --git a/lib/attr.lua b/lib/attr.lua new file mode 100644 index 0000000..8c1613a --- /dev/null +++ b/lib/attr.lua @@ -0,0 +1,232 @@ +#!/usr/bin/env lua + +local util = require 'lib/util' + +local extract = function (name, patterns) + local r + + for _, p in pairs(patterns) do + r = r or name:match(p) + name = name:gsub(p, '') + end + + return name, r +end + +local build_dlim = function (name, attrs) + local dlim ,r + + attrs = attrs or {} + dlim = '[%-%.%s]?' + local vcodecs = { + '[M]m[Pp][Ee][Gg]' .. dlim .. '[1234]', + } + local acodecs = { + '[Dd][Tt][Ss]' .. dlim .. '[Hh][Dd]', + '[Dd][Dd]' .. dlim .. '[57]%.1', + } + local sources= { + "[Ww][Ee][Bb]" .. dlim .. "[Dd][Ll]", + "[Hh][Dd]" .. dlim .. "[Tt][Vv]", + "[Hh][Dd]" .. dlim .. "[Tt][Ss]", + } + local series = { + '[Ss]%d%d?' .. dlim .. '[Ee]%d%d?', + } + local sizes = { + '%d%d%d' .. dlim .. '[Mm][Bb]', + '%d%d?%.%d%d?' .. dlim .. '[Gg][Bb]', + } + local depths = { + '1[02]' .. dlim .. '[Bb][Ii][Tt]' + } + + name, attrs.vcodec = extract(name, vcodecs) + name, attrs.source = extract(name, sources) + name, attrs.acodecs = extract(name, acodecs) + name, attrs.size = extract(name, sizes) + name, attrs.depth = extract(name, depths) + + name, r = extract(name, series) + if r then + attrs.season = tonumber(r:match('%d+')) + attrs.episode = tonumber(r:match('%d+$')) + end + + return name, attrs +end + +local build_atom = function (name, attrs) + local r, year + + attrs = attrs or {} + local vcodecs = { + "[Aa][Vv]1", + "[xXHh]26[345]", + "[Aa][Vv][Cc]", + "[Hh][Ee][Vv][Cc]", + "[Xx][Vv][Ii][Dd]", + } + local acodecs = { + "[Oo][Pp][Uu][Ss]", + "[Aa][Aa][Cc]", + "[Ee]?[Aa][Cc]3", + "[Dd][Tt][Ss]", + } + local sources= { + "[Bb][Ll][Uu][Rr][Aa][Yy]", + "[Bb][Rr][Rr][Ii][Pp]", + "[Dd][Vv][Dd][Rr][Ii][Pp]", + "[Ww][Ee][Bb][Rr][Ii][Pp]", + "[Hh][Dd][Rr][Ii][Pp]", + "[Rr][Ee][Rr][Ii][Pp]", + } + local reses = { + "2160[Pp]", + "1440[Pp]", + "1080[Pp]", + "720[Pp]", + "480[Pp]", + "[Uu][Hh][Dd]", + "4[Kk]" + } + local series = { + '%d%d[Xx]%d%d', + } + local channels = { + '6[Cc][Hh]', + '[57]%.1', + } + + name, attrs.vcodec = extract(name, vcodecs) + name, attrs.source = extract(name, sources) + name, attrs.res = extract(name, reses) + name, attrs.acodecs = extract(name, acodecs) + name, attrs.channel = extract(name, channels) + + name, r = extract(name, series) + if r then + attrs.season = tonumber(r:match('%d+')) + attrs.episode = tonumber(r:match('%d+$')) + end + + for y in name:gmatch('%d%d%d%d') do + year = tonumber(y) + if year > 1900 and year <= tonumber(os.date('%Y')) then + attrs.year = y + end + end + if attrs.year then + name = name:gsub(tostring(attrs.year), '') + end + + return name, attrs +end + +local build_low = function (name, attrs) + local low_attr, lows + + lows = { 'SDH' } + + low_attr = {} + for _, low in pairs(lows) do + low_attr[#low_attr + 1] = name:match(low) + name = name:gsub(low, '') + end + + attrs = attrs or {} + if #low_attr > 0 then + attrs.low = low_attr + end + + return name, attrs +end + +local build_title = function (name, attrs) + attrs.title = {} + for w in name:gmatch('%w+') do + attrs.title[#attrs.title + 1] = w + end + + if #attrs.title > 1 then + attrs.scene = attrs.title[#attrs.title] + attrs.title[#attrs.title] = nil + end + + return attrs +end + +local build = function (name) + local attrs = {} + + name = build_dlim(name, attrs) + name = build_atom(name, attrs) + name = build_low(name, attrs) + build_title(name, attrs) + + return attrs +end + +local weigh = function (a1, a2) + local key_score, score + + key_score = { + name = 10, + season = 10, + episode = 10, + source = 7, + scene = 5, + vcodec = 3, + acodec = 3, + rese = 2, + default = 1, + } + + score = 0 + for k, v in pairs(a1) do + if not a2[k] then + goto continue + end + + if k == 'name' then + for _, name in pairs(v) do + if util.array_search(a2.name, name) then + score = score + key_score.name + end + end + else + if v == a2[k] then + score = score + (key_score[k] or key_score.default) + end + end + + ::continue:: + end + + return score +end + +local fuzzy = function (name, tab) + local name_attr, high, score + + high = { + score = 0, + name = next(tab) + } + + name_attr = build(name) + for k in pairs(tab) do + score = weigh(name_attr, build(k)) + if score > high.score then + high.score = score + high.name = k + end + end + + return tab[high.name] +end + +return { + build = build, + fuzzy = fuzzy, +} diff --git a/lib/util.lua b/lib/util.lua index d52922d..6263507 100644 --- a/lib/util.lua +++ b/lib/util.lua @@ -70,6 +70,16 @@ local array_merge = function (a1, a2) return a end +local array_search = function (a, key) + for _, v in pairs(a) do + if v == key then + return true + end + end + + return false +end + local table_print = function (t) for k, v in pairs(t) do print( '|'.. k .. '=' .. v .. '|') @@ -186,6 +196,7 @@ return { table_print = table_print, table_match_or_any = table_match_or_any, array_merge = array_merge, + array_search = array_search, zip_ext_first = zip_ext_first, string_vid_path_to_name = string_vid_path_to_name, opensubtitles_hash = opensubtitles_hash, |