diff --git a/build.sh b/build.sh index 9cb9746..163b2ce 100644 --- a/build.sh +++ b/build.sh @@ -4,7 +4,7 @@ for d in *; do if [ -d "$d" ]; then echo -e "\n> $d.plug:" cd $d - tar -cvzf ../$d.201.tgz * + tar -cvzf ../$d.203.tgz * cd .. fi -done \ No newline at end of file +done diff --git a/tivix/main.tengo b/tivix/main.tengo new file mode 100644 index 0000000..26c8451 --- /dev/null +++ b/tivix/main.tengo @@ -0,0 +1,84 @@ +url := "http://tv.tivix.co/" +srv := import("server") +txt := import("text") +jsn := import("json") +stg := import("settings") +cat := stg.cat +fav := cat == "*" +cat = cat == "*" ? "" : cat +vid := "video:resolve:" + srv.base_url + "video.tengo?str=" + string(stg.str) + "&cid=" + +// get the page: +r := srv.request(url + cat) +panic(is_error(r) ? r : r.status != 200 ? r.status : undefined) + +// parse categories: +c := [{label: "Избранные", action: "execute:fetch:" + srv.base_url + "set.tengo?id={ID}&cat=*", enable: !fav}] +for m in txt.re_find("(?s)class=\"menuuuuuu\">(.+?)", r.body, 3) { + for i in txt.re_find("(?s).+?href=\"/(.*?)\"(.+?)>(.+?)<", m[1].text, -1) { + cc := {label: i[3].text, action: "execute:fetch:" + srv.base_url + "set.tengo?id={ID}&cat="+ i[1].text} + if !fav && len(i[2].text) > 3 { + cc.enable = false + cat = (i[1].text == "" ? "" : "{col:msx-white}") + i[3].text + } + c = append(c, cc) + } +} + +// parse channels: +if fav { + cat = "{col:msx-yellow}Избранные" + if r = srv.file("favs.json"); r { + panic(is_error(r) ? r : undefined) + r = jsn.decode(r) + panic(is_error(r) ? r : !is_array(r) ? "Wrong format of file favs.json" : undefined) + for i := 0; i < len(r); i++ { + r[i].playerLabel = r[i].headline + r[i].action = vid + r[i].id + } + } else { r = [] } +} else if r = txt.re_find("(?s)class=\"all_tv\".+? 0 { + epg[i-1] = "{col:msx-yellow}" + epg[i-1] + "{col:msx-white}" + nrs.cur = i - 1 + } + } else { + nrs.now = [epg[i].start_at, epg[i].name] + } + } + epg[i] = tms.time_format(epg[i].start_at, "15:04") + "{tb}" + epg[i].name + } + } +} +// prepare the answer: +if fn := srv.read("now"); !is_array(epg) || len(epg) < 1 { + epg = fn ? {titleHeader: "Программа недоступна!"} : undefined + cid = fn ? ("update:content:" + cid) : "player:label:duration:{ico:sensors}" +} else if fn { + epg = {live: { + type: "schedule", from: tms.time_unix(nrs.now[0]) * 1000, to: tms.time_unix(nrs.nxt[0]) * 1000, + titleHeader: "{ico:add}{col:msx-white}{progress:time:hh:mm} " + nrs.now[1], + titleFooter: "{ico:remove}{countdown:time:hh:mm} " + nrs.nxt[1], + over: {action: "execute:service:fetch:" + srv.base_url + "programme.tengo?now=true&cid=" + cid} + }} + cid = "update:content:" + cid +} else { + if nrs.cur < 0 { + epg = append(["{col:msx-yellow}...{col:msx-white}"], epg...) + } else if l := len(epg) - 10; l > 0 && nrs.cur > 0 { + epg = epg[nrs.cur < l ? nrs.cur : l:] + } + tuf := tms.time_unix(nrs.now[0]) + tut := tms.time_unix(nrs.nxt[0]) + epg = {actions: [ + {action: "trigger:player:execute:service:fetch:" + srv.base_url + "progress.tengo?b=" + tuf + "&e=" + tut + "&cid=" + cid}, + {action: "player:info:text:" + txt.join(epg, "{br}")}, + {action: "player:label:position:{VALUE}{tb}{col:msx-white}" + nrs.now[1]}, + {action: "player:label:duration:{VALUE}"}, + {action: "player:video:position:" + string(tms.time_unix(now) - tuf)}, + {action: "player:video:duration:" + string(tut - tuf)} + ]} + cid = "data" +} +// answer: +srv.write(jsn.encode({response: {status: 200, data: {action: cid, data: epg}}})) \ No newline at end of file diff --git a/tivix/progress.tengo b/tivix/progress.tengo new file mode 100644 index 0000000..a6c3cc0 --- /dev/null +++ b/tivix/progress.tengo @@ -0,0 +1,13 @@ +s := import("server") +t := import("times") +b := s.read("b") +e := s.read("e") +panic(b == "" || e == "" ? 400 : undefined) +b = int(b) +e = int(e) +n := t.time_unix(t.now()) +a := "player:video:position:" + string(n - b) +if n > e { + a = "execute:service:fetch:" + s.base_url + "programme.tengo?cid=" + s.read("cid") +} +s.write("{\"response\":{\"status\":200,\"data\":{\"action\":\"" + a + "\"}}}") diff --git a/tivix/set.tengo b/tivix/set.tengo new file mode 100644 index 0000000..462c3a8 --- /dev/null +++ b/tivix/set.tengo @@ -0,0 +1,42 @@ +srv := import("server") +jsn := import("json") +stg := import("settings") +rtn := {response: {status: 200, data: {action: "reload:content"}}} +if r := srv.read("str"); r { + stg.set(int(r, 0)) + rtn.response.data.action = "[back|reload:content]" +} else if r = srv.read("cat"); is_string(r) { + stg.set(r) + rtn.response.data.action = "[back|reload:content]" +} else if c := srv.read("cid"); c { + ch := false + if r = srv.file(stg.fav); r { + panic(is_error(r) ? r : undefined) + r = jsn.decode(r) + } + r = is_array(r) ? r : [] + l := len(r) + for i := 0; i < l; i++ { + if r[i].id == c { + splice(r, i, 1) + i = l + ch = true + } + } + if t := srv.read("ttl"); t { + r = append(r, {id: c, headline: t, image: srv.read("img")}) + ch = true + rtn.response.data.action = "success:" + t + " добавлен в {col:msx-yellow}избранные" + } + if ch { + r = jsn.encode(r) + panic(is_error(r) ? r : undefined) + srv.file(stg.fav, r) + } +} else { + rtn = {type: "list", headline: "Видео:", extension: "Tivix", template: {enumerate: false, type: "button", layout: "0,0,8,1"}, items: []} + for i, n in stg.hls { + rtn.items = append(rtn.items, {label: n, action: "execute:fetch:" + srv.base_url + "set.tengo?id={ID}&str=" + string(i)}) + } +} +srv.write(jsn.encode(rtn)) diff --git a/tivix/settings.tengo b/tivix/settings.tengo new file mode 100644 index 0000000..06688ae --- /dev/null +++ b/tivix/settings.tengo @@ -0,0 +1,22 @@ +s := import("server") +i := s.read("id") || "*" +p := s.memory() || {} +if !is_map(p[i]) { p[i] = {cat: "", str: 0} } +h := ["прямой HLS", "проксировать HLS"] +if s.settings.ffmpeg() { h = append(h, "конвертировать в MPEGTS") } +export { + fav: "favs.json", + cat: p[i].cat, + str: p[i].str, + hls: h, + set: func(arg) { + r := false + if r = is_string(arg); r { + p[i].cat = arg + } else if r = is_int(arg); r { + p[i].str = arg > 0 && arg < len(h) ? arg : 0 + } + if r { s.memory(p) } + return r + } +} \ No newline at end of file diff --git a/tivix/video.tengo b/tivix/video.tengo new file mode 100644 index 0000000..12ea26b --- /dev/null +++ b/tivix/video.tengo @@ -0,0 +1,29 @@ +srv := import("server") +txt := import("text") +cid := srv.read("cid") +panic(cid ? undefined : 400) +url := "http://tv.tivix.co/" + +b := srv.request(url + cid + ".html") +panic(is_error(b) ? b : b.status != 200 ? b.status : undefined) + +b = txt.re_find("(?s)firstIpProtect.+?'(.+?)'.+?secondIpProtect.+?'(.+?)'.+?portProtect.+?'(.+?)'.+?new Playerjs.+?file.*?:.*?\"(.+?)\"", b.body, 1)[0][1:] + +b[3] = txt.trim_prefix(b[3].text, "#2") +for i := txt.last_index(b[3], "//"); i > -1; i = txt.last_index(b[3], "//"){ + b [3]= b[3][:i] + b[3][i+50:] +} +b[3] = import("base64").decode(b[3]) + +b = txt.replace(txt.replace(txt.replace(b[3], "{v3}", b[2].text, 1), "{v2}", b[1].text, 1), "{v1}", b[0].text, 1) + +if s := int(srv.read("str"), 0); s == 2 { + b = srv.settings.ffmpeg(b, ["-referer", url], ["-c", "copy"]) + panic(b == "" ? "ffmpeg is not set" : undefined) +} else if s == 1 { + b = "http://" + srv.host + "/proxy.m3u8?header=Referer%3A" + srv.encode_uri(url) + "&link=" + srv.encode_uri(b) +} else { + r := srv.request(b, {header: {Referer: url}}) + panic(is_error(r) ? r : r.status == 200 ? undefined : r.status) +} +srv.write("{\"response\":{\"status\":200,\"data\":{\"url\":\"", srv.settings.player(b), "\"}}}") diff --git a/torlook/find.tengo b/torlook/find.tengo new file mode 100644 index 0000000..c4277e4 --- /dev/null +++ b/torlook/find.tengo @@ -0,0 +1,42 @@ +srv := import("server") +txt := import("text") +jsn := import("json") +url := "https://torlook.info/" +stg := srv.memory() +stg = is_array(stg) && len(stg) == 4 ? stg : ["seeders", false, false, false] +its := [] +panic(srv.method != "POST" ? 400 : undefined) +fnd := jsn.decode(srv.read()) +panic(is_error(fnd) ? fnd : !is_map(fnd) || !is_string(fnd.data) ? 400 : undefined) +fnd = fnd.data +r := srv.request( + url + "?cinema=on&s=" + srv.encode_uri(fnd) + "&sort=" + stg[0] + (stg[1] ? "&forced=on" : ""), + {header: {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"}} +) +panic(is_error(r) ? r : r.status != 200 ? r.status : undefined) +if r = txt.re_find("(?s)webResult.+?item.+?(.+?).+?(.+?)<.+?class=\"size\">(.+?)<.+?class=\"date\">(.+?)<.+?class=\"arrow-up\".+?>(.+?)<.+?data-src=\"(.+?)\"", r.body, -1); is_array(r) { + for i in r { its = append(its, { + headline: txt.re_replace("<.+?>", i[1].text, ""), + titleFooter: i[3].text + "{tb}{ico:msx-white:attach-file}" + txt.replace(i[4].text, " ", " ", 1) + + "{tb}{ico:msx-white:calendar-today} " + i[5].text + "{tb}{ico:msx-white:arrow-upward} " + i[6].text, + data: url + srv.encode_uri(i[7].text, true) + })} +} else { + its = append(its, {label: "{dic:message:playlist_empty|Empty}", icon: "msx-yellow:warning", extensionIcon: "msx-white:refresh", action: "reload:content"}) +} + +srv.write(jsn.encode({response: {status: 200, data: {action: "content:data", data:{ + type: "list", headline: "Torlook", extension: "{ico:search}{col:msx-white}" + fnd, cache: false, compress: true, items: its, flag: "FIND", + template: {type: "control", layout: "0,0," + (stg[2] ? "8" : "16") + ",2", action: "execute:" + srv.base_url + "magnet.tengo?"}, + header: {items:[ + {type: "control", icon: "arrow-back-ios", label: "TOP-50", action: "close:FIND", layout: "0,0,3,1"}, + { + type: "control", icon: "search", extensionIcon: "keyboard", layout: "3,0,10,1", + id: "search", label: fnd, action: "execute:http://" + srv.host + "/msx/input", + data: {action: "[cleanup|close:FIND|execute:" + srv.base_url + "find.tengo]", headline: "Torlook:", value: fnd} + },{ + type: "button", icon: "tune", iconSize: "small", layout: "13,0,3,1", + action: "execute:info:dictionary:" + srv.base_url + "set.tengo?find=" + srv.encode_uri(fnd), data: undefined + } + ]} +}}}})) \ No newline at end of file diff --git a/torlook/magnet.tengo b/torlook/magnet.tengo new file mode 100644 index 0000000..e8de893 --- /dev/null +++ b/torlook/magnet.tengo @@ -0,0 +1,15 @@ +srv := import("server") +jsn := import("json") + +panic(srv.method != "POST" ? 400 : undefined) +u := srv.read() +u = jsn.decode(u) +panic(is_error(u) ? u : undefined) +u = u.data || "" +panic(u == "" ? 400 : undefined) + +u = srv.request(u, {header: {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"}}) +panic(is_error(u) ? u : u.status == 200 ? undefined : u.status) +u = import("text").re_find("(?s)\"(.+?)

.+?torstat.+?(.+?)<", r.body, -1); is_array(r) { + for i in r { + b := i[2].text + i = txt.re_find("href=\"/(.+?)\">(.+?)<", i[1].text, 2) + i = i[len(i) > 1 && org ? 1 : 0] + its = append(its, {label: i[2].text, extensionLabel: b, data: srv.decode_uri(i[1].text)}) + } +} else { + its = append(its, {label: "{dic:message:playlist_empty|Empty}", icon: "msx-yellow:warning", extensionIcon: "msx-white:refresh", action: "reload:content"}) +} + +srv.write(import("json").encode({ + type: "list", headline: "Torlook", extension: "TOP-50 (kinopoisk)", cache: false, compress: true, items: its, + ready: {action: "execute:info:dictionary:" + srv.base_url + "trans.tengo"}, + template: {type: "control", icon: "search", layout: "0,0,16,1", action: "execute:" + srv.base_url + "find.tengo"}, + header: {items:[ + { + type: "control", icon: "title", layout: "0,0,3,1", action: "execute:" + srv.base_url + "set.tengo", data: 3, + label: org ? "{txt:msx-white-soft:Рус} {ico:toggle-on} Origin" : "Рус {ico:toggle-off} {txt:msx-white-soft:Origin}" + },{ + type: "control", icon: "search", extensionIcon: "keyboard", layout: "3,0,10,1", + id: "search", label: "Torrents search", action: "execute:http://" + srv.host + "/msx/input", + data: {action: "[cleanup|execute:" + srv.base_url + "find.tengo]", headline: "Torlook:"} + },{ + type: "button", icon: "tune", iconSize: "small", layout: "13,0,3,1", + action: "execute:info:dictionary:" + srv.base_url + "set.tengo", data: undefined + } + ]} +})) \ No newline at end of file diff --git a/torlook/manifest.json b/torlook/manifest.json new file mode 100644 index 0000000..04b6b09 --- /dev/null +++ b/torlook/manifest.json @@ -0,0 +1,5 @@ +{ + "Label": "Torlook", + "Image": "{BASE_URL}tor.svg", + "Torrent": true +} \ No newline at end of file diff --git a/torlook/set.tengo b/torlook/set.tengo new file mode 100644 index 0000000..20a0df1 --- /dev/null +++ b/torlook/set.tengo @@ -0,0 +1,51 @@ +srv := import("server") +jsn := import("json") +stg := srv.memory() +stg = is_array(stg) && len(stg) == 4 ? stg : ["seeders", false, false, false] +if srv.method == "POST" { + b := jsn.decode(srv.read()) + panic(is_error(b) ? b : undefined) + rtn := {response: {status: 200, data: {action: "reload:panel"}}} + if b.info { + ru := b.info.dictionary && is_string(b.info.dictionary.name) ? b.info.dictionary.name[:3] : "" + f := srv.read("find") + f = f ? srv.encode_uri(f) : "" + rtn.response.data.action = "panel:" +srv.base_url + "set.tengo?find=" + f + (ru == "Rus" || ru == "Ukr" ? "&ru" : "") + } else if is_string(b.data) { + stg[0] = b.data + srv.memory(stg) + } else if b = int(b.data, 0); b > 0 && b < len(stg) { + stg[b] = !stg[b] + srv.memory(stg) + if b == 3 { rtn.response.data.action = "reload:content" } + } + srv.write(jsn.encode(rtn)) +} else { + ru := is_string(srv.read("ru")) + f := srv.read("find") + srv.write(jsn.encode({ + type: "list", headline: ru ? "Параметры поиска:" : "Search properties:", extension: "Torlook", + template: {enumerate: false, type: "control", layout: "0,0,8,1", action: "execute:" + srv.base_url + "set.tengo"}, + items: [ + { + icon: "remove-red-eye", label: ru ? "представление результатов:" : "results view:", data: 2, + extensionLabel: "{ico:" + (stg[2] ? "" : "msx-white:") + "splitscreen} {ico:msx-white:toggle-o" + (stg[2] ? "n" : "ff") + "} {ico:" + (stg[2] ? "msx-white:" : "") + "grid-view}" + },{ + icon: "sort", label: ru ? "сортировать по сидам" : "order by seeders", data: "seeders", + extensionIcon: stg[0] == "seeders" ? "msx-white:radio-button-on" : "radio-button-off" + },{ + icon: "sort", label: ru ? "сортировать по дате" : "order by date", data: "date", + extensionIcon: stg[0] == "date" ? "msx-white:radio-button-on" : "radio-button-off" + },{ + icon: "sort", label: ru ? "сортировать по размеру" : "order by size", data: "size", + extensionIcon: stg[0] == "size" ? "msx-white:radio-button-on" : "radio-button-off" + },{ + icon: "manage-search", label: ru ? "форсированный поиск" : "forced search", data: 1, + extensionIcon: stg[1] ? "msx-white:check-box" : "check-box-outline-blank" + },{ + type: "button", label: "{dic:label:apply|Apply}", data: f, + action: "[cleanup|close:FIND|execute:" + srv.base_url + "find.tengo]", enable: f ? true : false + } + ] + })) +} diff --git a/torlook/tor.svg b/torlook/tor.svg new file mode 100644 index 0000000..1621b90 --- /dev/null +++ b/torlook/tor.svg @@ -0,0 +1,18 @@ + + + + + +binoculars 128 + + + + + + + + + + + + diff --git a/torlook/trans.tengo b/torlook/trans.tengo new file mode 100644 index 0000000..06e5439 --- /dev/null +++ b/torlook/trans.tengo @@ -0,0 +1,11 @@ +srv := import("server") +jsn := import("json") +rtn := {response: {status: 200, data: {action: "[]"}}} +if srv.method == "POST" { + if l := jsn.decode(srv.read()); !is_error(l) && is_map(l) && is_map(l.info) && is_map(l.info.dictionary) && is_string(l.info.dictionary.name) { + if l = l.info.dictionary.name[:3]; l == "Rus" || l == "Ukr" { + rtn.response.data = {action: "update:content:search", data: {label: "Поиск торрентов"}} + } + } +} +srv.write(jsn.encode(rtn)) \ No newline at end of file