feat: iTunes redirect

This commit is contained in:
relikd
2024-02-29 22:36:35 +01:00
parent a0033f28c5
commit bcdbaaf399
5 changed files with 70 additions and 32 deletions

View File

@@ -38,7 +38,7 @@
<div class="entry full">
<div>
<img src="$IMG">
<button onclick="installIpa($IDX)">Install</button>
<button onclick="installIPA($IDX)">Install</button>
</div>
<div class="info">
<h4>$TITLE</h4>
@@ -71,12 +71,16 @@
<div>$IMG</div>
<p>$DESCRIPTION</p>
</div>
<a class="screenshot" href="$URL" target="_blank"><img src="$URL"></a>
<a class="screenshot" href="$REF" target="_blank"><img src="$URL"></a>
<div class="randomAction">
Actions:
<button onclick="searchBundle($IDX, '&random=$IDX')">Show all versions</button>
<button onclick="randomIPA()">Next Random</button>
</div>
<div class="no-itunes">
<p>iTunes search disabled. No plist server configured.</p>
<a onclick="installIPA()">Configure now</a>
</div>
</div>
<div id="overlay" hidden>

View File

@@ -4,7 +4,7 @@ var baseUrls = {};
var PER_PAGE = 30;
var isInitial = true;
var previousSearch = '';
var plistGeneratorUrl = ''; // will append ?d=<data>
var plistServerUrl = ''; // will append ?d=<data>
NodeList.prototype.forEach = Array.prototype.forEach; // fix for < iOS 9.3
/*
@@ -164,11 +164,11 @@ function searchIPA(restorePage) {
* Random IPA
*/
function urlsToImgs(list) {
function urlsToImgs(redirectUrl, list) {
const template = getTemplate('.screenshot');
var rv = '<div class="carousel">';
for (var i = 0; i < list.length; i++) {
rv += renderTemplate(template, { $URL: list[i] });
rv += renderTemplate(template, { $REF: list[i], $URL: redirectUrl + list[i] });
}
return rv + '</div>';
}
@@ -190,15 +190,20 @@ function randomIPA(specificId) {
const entry = entryToDict(DB[idx]);
const output = document.getElementById('content');
output.innerHTML = '<h3>Random:</h3>' + entriesToStr('.full', [idx]);
output.firstElementChild.className += ' single';
output.lastElementChild.className += ' single';
output.innerHTML += renderTemplate(getTemplate('.randomAction'), { $IDX: idx });
if (!plistServerUrl) {
output.innerHTML += getTemplate('.no-itunes');
return;
}
// Append iTunes info to result
const redirectUrl = plistServerUrl + '?r='
const iTunesUrl = 'https://itunes.apple.com/lookup?bundleId=' + entry.bundleId;
loadFile(iTunesUrl, console.error, function (data) {
loadFile(redirectUrl + iTunesUrl, console.error, function (data) {
const obj = JSON.parse(data);
if (!obj || obj.resultCount < 1) {
output.innerHTML += '<p class="no-itunes">No iTunes results.</p>';
return;
}
const info = obj.results[0];
@@ -207,10 +212,10 @@ function randomIPA(specificId) {
var imgStr = '';
if (imgs1 && imgs1.length > 0) {
imgStr += '<p>iPhone Screenshots:</p>' + urlsToImgs(imgs1);
imgStr += '<p>iPhone Screenshots:</p>' + urlsToImgs(redirectUrl, imgs1);
}
if (imgs2 && imgs2.length > 0) {
imgStr += '<p>iPad Screenshots:</p>' + urlsToImgs(imgs2);
imgStr += '<p>iPad Screenshots:</p>' + urlsToImgs(redirectUrl, imgs2);
}
output.innerHTML += renderTemplate(getTemplate('.itunes'), {
@@ -386,7 +391,7 @@ function setPlistGen() {
alert('Server did not respond with a Plist file.');
return;
}
plistGeneratorUrl = testURL;
plistServerUrl = testURL;
document.getElementById('overlay').hidden = true;
saveConfig();
});
@@ -400,8 +405,8 @@ function utoa(data) {
return btoa(unescape(encodeURIComponent(data)));
}
function installIpa(idx) {
if (!plistGeneratorUrl) {
function installIPA(idx) {
if (!plistServerUrl) {
document.getElementById('overlay').hidden = false;
return;
}
@@ -423,7 +428,7 @@ function installIpa(idx) {
while (b64.slice(-1) === '=') {
b64 = b64.slice(0, -1);
}
// window.open(plistGeneratorUrl + '?d=' + b64);
const plistUrl = plistGeneratorUrl + '%3Fd%3D' + b64; // url encoded "?d="
// window.open(plistServerUrl + '?d=' + b64);
const plistUrl = plistServerUrl + '%3Fd%3D' + b64; // url encoded "?d="
window.open('itms-services://?action=download-manifest&url=' + plistUrl);
}

View File

@@ -83,7 +83,7 @@ h4 {
margin-left: 8px;
}
.itunes {
max-width: 600px;
max-width: 650px;
margin: 40px auto;
}
.carousel {
@@ -99,6 +99,10 @@ h4 {
.itunes p {
white-space: pre-wrap;
}
.no-itunes {
color: #777;
text-align: center;
}
/* Pagination */
.shortpage {

View File

@@ -1,5 +1,6 @@
#!/usr/bin/env python3
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.request import urlopen
from base64 import b64decode
import socket
import json
@@ -24,20 +25,38 @@ def generatePlist(data: dict) -> str:
class PlistServer(BaseHTTPRequestHandler):
def do_GET(self):
try:
b64 = self.path.split('?d=')[-1] + '=='
data = json.loads(b64decode(b64)) # type: dict
rv = generatePlist(data)
except Exception as e:
print(e)
rv = ''
def makeHeader(self, contentType):
self.send_response(200)
self.send_header('Access-Control-Allow-Origin', '*')
if rv:
self.send_header('Content-type', 'application/xml')
if contentType:
self.send_header('Content-type', contentType)
self.end_headers()
self.wfile.write(bytes(rv, 'utf-8') if rv else b'Parsing error')
def do_GET(self):
try:
action, value = self.path.split('?', 1)[-1].split('=', 1)
if action == 'r':
# http.client.HTTPResponse
with urlopen(value) as response:
mimeType = response.headers.get('Content-Type')
self.makeHeader(mimeType)
while True:
tmp = response.read(8096)
if not tmp:
break
self.wfile.write(tmp)
elif action == 'd':
data = json.loads(b64decode(value + '==')) # type: dict
rv = bytes(generatePlist(data), 'utf-8')
self.makeHeader('application/xml')
self.wfile.write(rv)
else:
return
except Exception as e:
print(e)
def getLocalIp():

View File

@@ -1,7 +1,10 @@
<?php
$X = json_decode(base64_decode($_GET['d']));
header('Access-Control-Allow-Origin: *');
if ($X->u) {
if ($_GET['r']) {
echo stream_get_contents(fopen($_GET['r'], "rb"));
} elseif ($_GET['d']) {
$X = json_decode(base64_decode($_GET['d']));
if ($X->u) {
header('Content-Type: application/xml');
echo '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
@@ -18,7 +21,10 @@ if ($X->u) {
<key>kind</key><string>software</string>
<key>title</key><string>'.$X->n.'</string>
</dict></dict></array></dict></plist>';
} else {
} else {
echo 'Parsing error.';
}
} else {
echo 'Error.';
}
?>