mirror of
https://github.com/Stremio/stremio-shell-ng.git
synced 2026-05-05 23:19:08 +00:00
Merge branch 'main' into feat/discord-rich-presence
Some checks failed
Continuous integration / test (push) Has been cancelled
Some checks failed
Continuous integration / test (push) Has been cancelled
This commit is contained in:
commit
71e1fc4dad
14 changed files with 1790 additions and 1471 deletions
6
.github/workflows/test.yml
vendored
6
.github/workflows/test.yml
vendored
|
|
@ -11,7 +11,11 @@ jobs:
|
|||
- name: disable git eol translation
|
||||
run: git config --global core.autocrlf false
|
||||
- name: checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Check version
|
||||
run: node stremiover.js check
|
||||
- name: Stable with rustfmt and clippy
|
||||
uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
|
|
|
|||
19
Cargo.lock
generated
19
Cargo.lock
generated
|
|
@ -895,18 +895,18 @@ checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a"
|
|||
|
||||
[[package]]
|
||||
name = "libmpv2"
|
||||
version = "4.0.0"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7befa1412ea58aeed5f36da1ad795f15bc6aefd554455f5134f1d4f7b6522e7f"
|
||||
checksum = "3e0c3802b4bb1a18adbf5659b078ce24cb8e16c79ff695557f4e10af2a44722a"
|
||||
dependencies = [
|
||||
"libmpv2-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libmpv2-sys"
|
||||
version = "4.0.0"
|
||||
version = "4.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42124ba90561beede41d5e6ef64eef63fc1395cf83217e3dd1157294f7dcdb56"
|
||||
checksum = "edb32cabe7176b7d270b0dca6ff418b75187ae8d3854423e3d06fbff376841e4"
|
||||
|
||||
[[package]]
|
||||
name = "libz-rs-sys"
|
||||
|
|
@ -1624,7 +1624,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "stremio-shell-ng"
|
||||
version = "5.0.15"
|
||||
version = "5.0.20"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.4.2",
|
||||
|
|
@ -1648,6 +1648,7 @@ dependencies = [
|
|||
"sha2",
|
||||
"url",
|
||||
"urlencoding",
|
||||
"uuid",
|
||||
"webview2",
|
||||
"webview2-sys",
|
||||
"whoami",
|
||||
|
|
@ -1993,11 +1994,13 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
|||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "0.8.2"
|
||||
version = "1.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
||||
checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f"
|
||||
dependencies = [
|
||||
"getrandom 0.2.12",
|
||||
"getrandom 0.3.3",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "stremio-shell-ng"
|
||||
version = "5.0.15"
|
||||
version = "5.0.20"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
|
|
@ -23,8 +23,8 @@ winapi = { version = "0.3.9", features = [
|
|||
] }
|
||||
webview2 = "0.1.4"
|
||||
webview2-sys = "0.1.1"
|
||||
libmpv2 = "4.0.0"
|
||||
libmpv2-sys = "4.0.0"
|
||||
libmpv2 = "4.1.0"
|
||||
libmpv2-sys = "4.0.1"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
clap = { version = "4", features = ["derive", "unicode"] }
|
||||
|
|
@ -40,7 +40,7 @@ sha2 = "0.10"
|
|||
reqwest = { version = "0.12", features = ["stream", "json", "blocking"] }
|
||||
rand = "0.8"
|
||||
url = { version = "2", features = ["serde"] }
|
||||
|
||||
uuid = { version = "1.19", features = ["v4"]}
|
||||
|
||||
[build-dependencies]
|
||||
winres = "0.1"
|
||||
|
|
|
|||
|
|
@ -1,21 +1,2 @@
|
|||
param (
|
||||
[String]$pw = $( Read-Host "Password" )
|
||||
)
|
||||
|
||||
$thread = Start-ThreadJob -InputObject ($pw) -ScriptBlock {
|
||||
$wshell = New-Object -ComObject wscript.shell;
|
||||
$pw = "$($input)~"
|
||||
while ($true) {
|
||||
while ( -not $wshell.AppActivate("Token Logon")) {
|
||||
Start-Sleep 1
|
||||
}
|
||||
Start-Sleep 1
|
||||
$wshell.SendKeys($pw, $true)
|
||||
Start-Sleep 1
|
||||
}
|
||||
}
|
||||
|
||||
cargo build --release --target aarch64-pc-windows-msvc
|
||||
& "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" /DSIGN "/Sstremiosign=`$qsigntool.exe`$q sign /fd SHA256 /t http://timestamp.digicert.com /n `$qSmart Code OOD`$q `$f" "setup\Stremio-arm64.iss"
|
||||
|
||||
Stop-Job -Job $thread
|
||||
|
|
|
|||
21
build.ps1
21
build.ps1
|
|
@ -1,21 +1,2 @@
|
|||
param (
|
||||
[String]$pw = $( Read-Host "Password" )
|
||||
)
|
||||
|
||||
$thread = Start-ThreadJob -InputObject ($pw) -ScriptBlock {
|
||||
$wshell = New-Object -ComObject wscript.shell;
|
||||
$pw = "$($input)~"
|
||||
while ($true) {
|
||||
while ( -not $wshell.AppActivate("Token Logon")) {
|
||||
Start-Sleep 1
|
||||
}
|
||||
Start-Sleep 1
|
||||
$wshell.SendKeys($pw, $true)
|
||||
Start-Sleep 1
|
||||
}
|
||||
}
|
||||
|
||||
cargo build --release --target x86_64-pc-windows-msvc
|
||||
& "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" /DSIGN "/Sstremiosign=`$qC:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x86\signtool.exe`$q sign /fd SHA256 /t http://timestamp.digicert.com /n `$qSmart Code OOD`$q `$f" "setup\Stremio.iss"
|
||||
|
||||
Stop-Job -Job $thread
|
||||
& "C:\Program Files (x86)\Inno Setup 6\ISCC.exe" /DSIGN "/Sstremiosign=`$qsigntool`$q sign /fd SHA256 /t http://timestamp.digicert.com /n `$qSmart Code OOD`$q `$f" "setup\Stremio.iss"
|
||||
|
|
|
|||
19
src/main.rs
19
src/main.rs
|
|
@ -9,7 +9,9 @@ use clap::Parser;
|
|||
use native_windows_gui::{self as nwg, NativeUi};
|
||||
mod stremio_app;
|
||||
use crate::stremio_app::{
|
||||
constants::{DEV_ENDPOINT, IPC_PATH, STA_ENDPOINT, STREMIO_SERVER_DEV_MODE, WEB_ENDPOINT},
|
||||
constants::{
|
||||
DEV_ENDPOINT, IPC_PATH, SERVER_IPC_KEY, STA_ENDPOINT, STREMIO_SERVER_DEV_MODE, WEB_ENDPOINT,
|
||||
},
|
||||
MainWindow, PipeClient,
|
||||
};
|
||||
|
||||
|
|
@ -38,6 +40,12 @@ struct Opt {
|
|||
force_update: bool,
|
||||
#[clap(long, help = "Check for RC updates")]
|
||||
release_candidate: bool,
|
||||
#[clap(
|
||||
long,
|
||||
default_value = "",
|
||||
help = "Secret key for communication with the server. By default it is randomly generrated on startup"
|
||||
)]
|
||||
server_ipc_key: String,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
@ -54,6 +62,15 @@ fn main() {
|
|||
|
||||
let opt = Opt::parse();
|
||||
|
||||
std::env::set_var(
|
||||
SERVER_IPC_KEY,
|
||||
if opt.server_ipc_key.is_empty() {
|
||||
uuid::Uuid::new_v4().to_string()
|
||||
} else {
|
||||
opt.server_ipc_key.clone()
|
||||
},
|
||||
);
|
||||
|
||||
let command = match opt.command {
|
||||
Some(file) => {
|
||||
if Path::new(&file).exists() {
|
||||
|
|
|
|||
|
|
@ -13,4 +13,5 @@ pub const UPDATE_ENDPOINT: [&str; 3] = [
|
|||
];
|
||||
pub const STREMIO_SERVER_DEV_MODE: &str = "STREMIO_SERVER_DEV_MODE";
|
||||
pub const SRV_BUFFER_SIZE: usize = 1024;
|
||||
pub const SERVER_IPC_KEY: &str = "SERVER_IPC_KEY";
|
||||
pub const SRV_LOG_SIZE: usize = 20;
|
||||
|
|
|
|||
|
|
@ -41,9 +41,17 @@ impl PlayerProprChange {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
|
||||
struct PlayerEndedError {
|
||||
message: String,
|
||||
critical: bool,
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
|
||||
pub struct PlayerEnded {
|
||||
reason: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
error: Option<PlayerEndedError>,
|
||||
}
|
||||
impl PlayerEnded {
|
||||
fn string_from_end_reason(data: EndFileReason) -> String {
|
||||
|
|
@ -53,9 +61,24 @@ impl PlayerEnded {
|
|||
_ => "other".to_string(),
|
||||
}
|
||||
}
|
||||
pub fn from_end_reason(data: EndFileReason) -> Self {
|
||||
pub fn from_end_reason(data: EndFileReason, error: &str) -> Self {
|
||||
Self {
|
||||
reason: Self::string_from_end_reason(data),
|
||||
error: if data == mpv_end_file_reason::Error {
|
||||
if error.is_empty() {
|
||||
Some(PlayerEndedError {
|
||||
message: "Unknown error".to_string(),
|
||||
critical: true,
|
||||
})
|
||||
} else {
|
||||
Some(PlayerEndedError {
|
||||
message: error.to_string(),
|
||||
critical: true,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
None
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -162,6 +185,7 @@ pub enum FpProp {
|
|||
SubDelay,
|
||||
SubScale,
|
||||
CacheBufferingState,
|
||||
DemuxerCacheTime,
|
||||
SubPos,
|
||||
Speed,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,26 +59,42 @@ fn propr_change_tokens() {
|
|||
|
||||
#[test]
|
||||
fn ended_tokens() {
|
||||
let error_tokens: [Token; 12] = [
|
||||
Token::Struct {
|
||||
name: "PlayerEnded",
|
||||
len: 2,
|
||||
},
|
||||
Token::Str("reason"),
|
||||
Token::Str("error"),
|
||||
Token::Str("error"),
|
||||
Token::Some,
|
||||
Token::Struct {
|
||||
name: "PlayerEndedError",
|
||||
len: 2,
|
||||
},
|
||||
Token::Str("message"),
|
||||
Token::Str("Unknown error"),
|
||||
Token::Str("critical"),
|
||||
Token::Bool(true),
|
||||
Token::StructEnd,
|
||||
Token::StructEnd,
|
||||
];
|
||||
let tokens: [Token; 4] = [
|
||||
Token::Struct {
|
||||
name: "PlayerEnded",
|
||||
len: 1,
|
||||
},
|
||||
Token::Str("reason"),
|
||||
Token::None,
|
||||
Token::Str("quit"),
|
||||
Token::StructEnd,
|
||||
];
|
||||
let mut typed_tokens = tokens.clone();
|
||||
typed_tokens[2] = Token::Str("error");
|
||||
assert_tokens(
|
||||
&PlayerEnded::from_end_reason(mpv_end_file_reason::Error),
|
||||
&typed_tokens,
|
||||
&PlayerEnded::from_end_reason(mpv_end_file_reason::Error, ""),
|
||||
&error_tokens,
|
||||
);
|
||||
let mut typed_tokens = tokens.clone();
|
||||
typed_tokens[2] = Token::Str("quit");
|
||||
assert_tokens(
|
||||
&PlayerEnded::from_end_reason(mpv_end_file_reason::Quit),
|
||||
&typed_tokens,
|
||||
&PlayerEnded::from_end_reason(mpv_end_file_reason::Quit, ""),
|
||||
&tokens,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -103,11 +103,20 @@ fn create_event_thread(
|
|||
}
|
||||
|
||||
// -1.0 means to block and wait for an event.
|
||||
let event = match event_context.wait_event(-1.) {
|
||||
Some(Ok(event)) => event,
|
||||
let (event, error) = match event_context.wait_event(-1.) {
|
||||
Some(Ok(event)) => (event, ""),
|
||||
Some(Err(error)) => {
|
||||
eprintln!("Event errored: {error:?}");
|
||||
continue;
|
||||
if let libmpv2::Error::Raw(e) = error {
|
||||
(
|
||||
Event::EndFile(
|
||||
libmpv2_sys::mpv_end_file_reason_MPV_END_FILE_REASON_ERROR,
|
||||
),
|
||||
libmpv2_sys::mpv_error_str(e),
|
||||
)
|
||||
} else {
|
||||
eprintln!("Unhandled event error: {error:?}");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// dummy event received (may be created on a wake up call or on timeout)
|
||||
None => continue,
|
||||
|
|
@ -124,7 +133,7 @@ fn create_event_thread(
|
|||
),
|
||||
Event::EndFile(reason) => PlayerResponse(
|
||||
"mpv-event-ended",
|
||||
PlayerEvent::End(PlayerEnded::from_end_reason(reason)),
|
||||
PlayerEvent::End(PlayerEnded::from_end_reason(reason, error)),
|
||||
),
|
||||
Event::Shutdown => {
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use crate::stremio_app::constants::SERVER_IPC_KEY;
|
||||
use crate::stremio_app::ipc;
|
||||
use native_windows_gui::{self as nwg, PartialUi};
|
||||
use once_cell::unsync::OnceCell;
|
||||
|
|
@ -153,6 +154,12 @@ impl PartialUi for WebView {
|
|||
}).expect("Cannot add full screen element changed");
|
||||
|
||||
webview.add_content_loading(move |wv, _| {
|
||||
wv.execute_script(format!(
|
||||
"window.stremio_server_ipc_key='{}'",
|
||||
std::env::var(SERVER_IPC_KEY).unwrap_or_default()
|
||||
).as_str(), |_| Ok(())
|
||||
).expect("Cannot add SERVER_IPC_KEY to webview");
|
||||
|
||||
wv.execute_script(r##"
|
||||
try{
|
||||
/* Disable context menus */
|
||||
|
|
|
|||
69
stremiover.js
Normal file
69
stremiover.js
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
#!/usr/bin/env node
|
||||
const { readFileSync, writeFileSync } = require('fs');
|
||||
|
||||
function getGitVersion() {
|
||||
const { execSync } = require('child_process');
|
||||
let ver = execSync('git describe --tags --abbrev=0').toString().match(/^v(?<version>\d+\.\d+.\d+)/);
|
||||
if (ver === null || typeof ver.groups !== "object" || typeof ver.groups.version !== "string") return null;
|
||||
return ver.groups.version;
|
||||
}
|
||||
function getCargoVersion(str) {
|
||||
const psection = '[package]\n'
|
||||
const poffset = str.indexOf(psection)
|
||||
if (poffset === -1) {
|
||||
console.error(`No ${psection}`)
|
||||
return null;
|
||||
}
|
||||
const voffset = str.indexOf('\nversion', poffset + psection.length);
|
||||
if (voffset === -1) {
|
||||
console.error(`No version`)
|
||||
return null;
|
||||
} const vstart = str.indexOf('"', voffset) + 1;
|
||||
if (vstart === 0) return null;
|
||||
const vend = str.indexOf('"', vstart);
|
||||
|
||||
return { vstart, vend, version: str.slice(vstart, vend) }
|
||||
}
|
||||
|
||||
switch (process.argv[2]) {
|
||||
case 'check': {
|
||||
const cver = getCargoVersion(readFileSync('Cargo.toml').toString());
|
||||
const gver = getGitVersion();
|
||||
if (gver !== cver.version) {
|
||||
console.error(`Fatal error: the version in Cargo.toml (v${cver.version}) doesn't match latest tag (v${gver})!`);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log('Cargo versino matches the git tag ' + gver);
|
||||
break;
|
||||
}
|
||||
case 'update': {
|
||||
let newVer = process.argv[3];
|
||||
if (!newVer) {
|
||||
const ghv = getGitVersion().split('.')
|
||||
const patch = (parseInt(ghv.pop(), 10) + 1).toString(10);
|
||||
ghv.push(patch);
|
||||
newVer = ghv.join('.');
|
||||
console.log(`WRNING: No new version provided. Using GH version + 1`)
|
||||
}
|
||||
const toml = readFileSync('Cargo.toml').toString();
|
||||
const cver = getCargoVersion(toml);
|
||||
if (cver.version === newVer) {
|
||||
console.log('Warinig: the new version is the same as the version in Cargo.toml')
|
||||
}
|
||||
const newtoml = toml.slice(0, cver.vstart) + newVer + toml.slice(cver.vend)
|
||||
writeFileSync('Cargo.toml', newtoml);
|
||||
console.log(`Cargo.toml updated to v${newVer}`);
|
||||
console.log('Changes can be upstreamed by the following commands:\n');
|
||||
console.log('git add Cargo.toml');
|
||||
console.log(`git commit -m "Version updated to v${newVer}"`);
|
||||
console.log(`git tag -a v${newVer} -m "Release of v${newVer}"`);
|
||||
console.log('git push && git push --tags');
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.log(`usage: ${process.argv[0]} check|update ver`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,3 +1,8 @@
|
|||
$tag = $(git describe --abbrev=0)
|
||||
aws s3 cp --acl public-read ".\StremioSetup-v$((get-item .\StremioSetup*.exe).VersionInfo.ProductVersion.Trim()).exe" s3://stremio-artifacts/stremio-shell-ng/$tag/
|
||||
|
||||
foreach ($installer in (get-item .\StremioSetup*.exe)) {
|
||||
if ($tag.StartsWith("v$($installer.VersionInfo.ProductVersion.Trim())")) {
|
||||
aws s3 cp --acl public-read "$installer" s3://stremio-artifacts/stremio-shell-ng/$tag/
|
||||
}
|
||||
}
|
||||
node ./generate_descriptor.js --tag=$tag
|
||||
|
|
|
|||
Loading…
Reference in a new issue