Files
scripts/update_github.pl

320 lines
11 KiB
Perl

#!/perl -w
use strict;
use warnings;
use File::Slurp qw(:std);
use File::stat;
use File::Path;
use Archive::Zip; # imports
# use IO::Socket::SSL;
use LWP::UserAgent;
use Data::Printer;
use Crypt::SSLeay;
use Net::SSL;
use Mojo::DOM;
use File::Path qw(make_path);
use Win32::Shortcut;
use JSON;
use File::Copy::Recursive qw(dirmove);
use LWP::Protocol::http;
use LWP::Protocol::https;
push(@LWP::Protocol::http::EXTRA_SOCK_OPTS, MaxLineLength => 16384);
# push(@LWP::Protocol::https::EXTRA_SOCK_OPTS, MaxLineLength => 16384);
$ENV{PERL_NET_HTTPS_SSL_SOCKET_CLASS} = "Net::SSL";
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
my $downloadfolder = 'D:\\Downloads\\';
my $mcp_json_pfad = "C:\\Users\\steff\\.lmstudio\\mcp.json";
my $mcp_json = read_file($mcp_json_pfad);
$mcp_json = decode_json($mcp_json);
my $mcp_change;
my $apps = {
'solidcraft' => {
apiurl => 'https://api.github.com/repos/tangency-labs/solidcraft/releases',
apiregex => 'solidcraft-(.*)-windows-x64-portable.zip',
ext => 'zip',
link => 'solidcraft.exe',
mcp => 'solidcraft-cli.exe'
},
'gridcraft' => {
apiurl => 'https://api.github.com/repos/storytold/gridcraft/releases',
apiregex => 'gridcraft-(.*)-windows-x64-portable.zip',
ext => 'zip',
link => 'gridcraft.exe',
mcp => 'gridcraft-cli.exe'
},
'photocraft' => {
apiurl => 'https://api.github.com/repos/storytold/photocraft/releases',
apiregex => 'photocraft-(.*)-windows-x64-portable.zip',
ext => 'zip',
link => 'photocraft.exe',
mcp => 'photocraft-cli.exe'
},
'vectorcraft' => {
apiurl => 'https://api.github.com/repos/storytold/vectorcraft/releases',
apiregex => 'vectorcraft-(.*)-windows-x64-portable.zip',
ext => 'zip',
link => 'vectorcraft.exe',
mcp => 'vectorcraft-cli.exe'
},
'filmcraft' => {
apiurl => 'https://api.github.com/repos/storytold/filmcraft/releases',
apiregex => 'filmcraft-(.*)-windows-x64-portable.zip',
ext => 'zip',
link => 'filmcraft.exe',
mcp => 'filmcraft-cli.exe'
},
'lightcraft' => {
apiurl => 'https://api.github.com/repos/storytold/lightcraft/releases',
apiregex => 'lightcraft-(.*)-windows-x64-portable.zip',
ext => 'zip',
link => 'lightcraft.exe',
mcp => 'lightcraft-cli.exe'
},
'pdfcraft' => {
apiurl => 'https://api.github.com/repos/storytold/pdfcraft/releases',
apiregex => 'pdfcraft-(.*)-windows-x64-portable.zip',
ext => 'zip',
link => 'pdfcraft.exe',
mcp => 'pdfcraft-cli.exe'
},
'effectcraft' => {
apiurl => 'https://api.github.com/repos/storytold/effectcraft/releases',
apiregex => 'effectcraft-(.*)-windows-x64-portable.zip',
ext => 'zip',
link => 'effectcraft.exe',
mcp => 'effectcraft-cli.exe'
},
'designcraft' => {
apiurl => 'https://api.github.com/repos/storytold/designcraft/releases',
apiregex => 'designcraft-(.*)-windows-x64-portable.zip',
ext => 'zip',
link => 'designcraft.exe',
mcp => 'designcraft-cli.exe'
},
'figcraft' => {
apiurl => 'https://api.github.com/repos/storytold/figcraft/releases',
apiregex => 'figcraft-(.*)-windows-x64-portable.zip',
ext => 'zip',
link => 'figcraft.exe',
mcp => 'figcraft-cli.exe'
},
'wordcraft' => {
apiurl => 'https://api.github.com/repos/storytold/wordcraft/releases',
apiregex => 'wordcraft-(.*)-windows-x64-portable.zip',
ext => 'zip',
link => 'wordcraft.exe',
mcp => 'wordcraft-cli.exe'
},
'soundcraft' => {
apiurl => 'https://api.github.com/repos/storytold/soundcraft/releases',
apiregex => 'soundcraft-(.*)-windows-x64-portable.zip',
ext => 'zip',
link => 'soundcraft.exe',
mcp => 'soundcraft-cli.exe'
},
'deckcraft' => {
apiurl => 'https://api.github.com/repos/storytold/deckcraft/releases',
apiregex => 'deckcraft-(.*)-windows-x64-portable.zip',
ext => 'zip',
link => 'deckcraft.exe',
mcp => 'deckcraft-cli.exe'
},
'cadcraft' => {
apiurl => 'https://api.github.com/repos/storytold/cadcraft/releases',
apiregex => 'cadcraft-(.*)-windows-x64-portable.zip',
ext => 'zip',
link => 'cadcraft.exe',
mcp => 'cadcraft-cli.exe'
},
'Detect_It_Easy' => {
apiurl => 'https://api.github.com/repos/horsicq/DIE-engine/releases',
apiregex => 'die_win64_portable_(.*)_x64.zip',
ext => 'zip',
link => 'die.exe'
},
'ghidra' => {
apiurl => 'https://api.github.com/repos/NationalSecurityAgency/ghidra/releases',
apiregex => 'ghidra_(.*)_PUBLIC_20261016.zip',
ext => 'zip',
link => 'ghidraRun.bat'
}
};
if ( !-d "C:\\temp" ) {
make_path("C:\\temp");
}
if ( !-d "C:\\temp\\github" ) {
make_path("C:\\temp\\github");
}
my $ua = LWP::UserAgent->new(timeout => 10);
$ua->max_redirect( 3 );
$ua->agent('Mozilla/5.0 (compatible; AppDownloader/1.0)');
# $ua->show_progress( 1 );
for my $app ( sort keys %$apps ) {
my $apiurl = $apps->{$app}->{apiurl};
my $apiregex = $apps->{$app}->{apiregex};
my $ext = $apps->{$app}->{ext};
my $link = $apps->{$app}->{link} // undef;
my $mcp = $apps->{$app}->{mcp} // undef;
if ( !$link ) {
print "keine ausfuehrbare Datei\n";
exit;
}
# 3. Request erstellen und Header für JSON setzen
my $req = HTTP::Request->new(GET => $apiurl);
$req->header('Accept' => 'application/vnd.github+json');
# Optional: Falls du einen Token hast (für höhere Limits / private Repos)
$req->header('Authorization' => 'Bearer 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');
# 4. Anfrage absenden
my $res = $ua->request($req);
# 5. Prüfen, ob die Anfrage erfolgreich war
if ($res->is_success) {
# Den JSON-String aus dem Response-Body holen
my $json_text = $res->decoded_content;
# JSON in eine Perl-Datenstruktur (Hash) umwandeln
my $data = decode_json($json_text);
my $da = @$data[0];
my $tagname = $da->{tag_name};
if ( $tagname =~ /nightly/ ) {
print "keine Nightly\n";
next;
}
my $dateiname;
my $downloadurl;
my $ver;
my $folder;
for my $as ( @{$da->{assets}} ) {
if ( $as->{name} =~ /$apiregex/ ) {
$dateiname = $as->{name};
$ver = $1;
$downloadurl = $as->{browser_download_url};
$folder = $dateiname =~ s/\.$ext//r;
}
}
my $folderinzip = $apps->{$app}->{folderinzip} && $apps->{$app}->{folderinzip} eq 'same_as_file' ? $folder : $apps->{$app}->{folderinzip};
if ($folderinzip) {
$folderinzip = $folderinzip =~ s/XXX/$ver/r;
}
if ( -e "D:\\portable\\$app\\$ver\\$link" ) {
print "$app V$ver existiert\n";
} else {
if ( !-e $downloadfolder.$dateiname ) {
print "downloade $app\n";
my $response = $ua->get($downloadurl, ':content_file' => $downloadfolder.$dateiname);
}
if ( -e $downloadfolder.$dateiname ) {
my $obj = Archive::Zip->new(); # new instance
my $status = $obj->read($downloadfolder.$dateiname); # read file contents
if ($status != 0) {
die('Error in file!');
} else {
# entpacken der DAten in ein tempverzeichnis
if ( !-d "C:\\temp\\github\\$app" ) {
make_path("C:\\temp\\github\\$app");
}
if ( !-d "D:\\portable\\$app" ) {
make_path("D:\\portable\\$app");
}
if ( !-d "D:\\portable\\$app\\$ver" ) {
make_path("D:\\portable\\$app\\$ver");
}
# lesen
my @inhalt = read_dir("D:\\portable\\$app\\$ver");
if ( scalar @inhalt == 0 ) {
print "entpacke $downloadfolder$dateiname\n";
my $err = $obj->extractTree(undef, "C:\\temp\\github\\$app"); # extract files
}
my @inhaltnew = read_dir("C:\\temp\\github\\$app");
if ( -e "C:\\temp\\github\\$app\\$link" ) {
dirmove("C:\\temp\\github\\$app", "D:\\portable\\$app\\$ver");
} else {
for my $in ( @inhaltnew ) {
if ( -d "C:\\temp\\github\\$app\\$in" ) {
if ( -e "C:\\temp\\github\\$app\\$in\\$link" ) {
dirmove("C:\\temp\\github\\$app\\$in", "D:\\portable\\$app\\$ver");
}
}
}
rmtree "C:\\temp\\github\\$app";
}
# alte Versionen löschen
my @inhaltwithnewversion = read_dir("D:\\portable\\$app");
for my $in ( @inhaltwithnewversion ) {
next if $in eq $ver;
if ( -d "D:\\portable\\$app\\$in" ) {
rmtree "D:\\portable\\$app\\$in";
}
}
unlink($downloadfolder.$dateiname );
print "zip datei von $app gelöscht\n";
}
}
if ($link && -e "D:\\portable\\$app\\$ver\\$link" ) {
my $linknew = Win32::Shortcut->new();
if ( -e "C:\\Users\\steff\\Desktop\\$app.lnk" ) {
$linknew->Load("C:\\Users\\steff\\Desktop\\$app.lnk");
print "aendere link D:\\portable\\$app\\$ver\\$link\n";
} else {
print "erstelle link D:\\portable\\$app\\$ver\\$link\n";
}
$linknew->Path("D:\\portable\\$app\\$ver\\$link");
$linknew->WorkingDirectory("D:\\portable\\$app\\$ver");
$linknew->Description("$app-$ver");
$linknew->Save("C:\\Users\\steff\\Desktop\\$app.lnk");
$linknew->Close();
}
}
if ( $mcp && -e "D:\\portable\\$app\\$ver\\$mcp" ) {
my $mcpdata = {
args => [
"mcp"
],
command => "D:\\portable\\$app\\$ver\\$mcp"
};
$mcp_json->{mcpServers}->{$app} = $mcpdata;
$mcp_change = 1;
}
} else {
print "Fehler bei der Abfrage: " . $res->status_line . "\n";
}
}
if ( $mcp_change ) {
write_file($mcp_json_pfad, to_json($mcp_json, {utf8 => 1, pretty => 1}) )
}
system("pause");
1;