v0.9.0
- update wtv-home:/home: "Ultra Willies" no longer selected by default - update: allow socket timeout definition via config - fix: fixed reading of POST DATA from SECURE ON request - experiment with OISP and WNI tellyscripts - enhancement: Support UserServiceVault - update: enable Download-o-Rama style updates. MSNTV DealerDemo included as a demo
This commit is contained in:
@@ -1,41 +1,176 @@
|
||||
// todo: async (and make this work anyway)
|
||||
// todo: async
|
||||
|
||||
var content_dir = service_dir + '/content/';
|
||||
var diskmap_dir = content_dir + '/diskmaps/';
|
||||
var path = require("path");
|
||||
|
||||
if (request_headers.post_data) {
|
||||
console.log(request_headers.post_data.toString('CryptoJS.enc.Latin1'))
|
||||
var content_dir = "content/"
|
||||
var diskmap_dir = content_dir + "diskmaps/";
|
||||
|
||||
function generateDownloadList(diskmap_group_data, update_list, diskmap_data) {
|
||||
// create WebTV Download List
|
||||
|
||||
var newest_file_epoch = 0;
|
||||
var download_list = '';
|
||||
|
||||
if (diskmap_data.partition_size) {
|
||||
download_list += "CREATE " + diskmap_data.base + "\n";
|
||||
download_list += "partition-size: " + diskmap_data.partition_size + "\n\n";
|
||||
}
|
||||
|
||||
download_list += "CREATE-GROUP " + diskmap_group_data + "-UPDATE\n";
|
||||
download_list += "state: invalid\n";
|
||||
download_list += "base: " + diskmap_data.base + ".GROUP-UPDATE/\n\n";
|
||||
|
||||
Object.keys(update_list).forEach(function (k) {
|
||||
if (parseInt(update_list[k]["Last-modified"]) > newest_file_epoch) newest_file_epoch = parseInt(update_list[k]["Last-modified"]);
|
||||
download_list += "DISPLAY " + update_list[k].display + "\n\n";
|
||||
download_list += "GET " + update_list[k].file.replace(diskmap_data.base, "") + "\n";
|
||||
download_list += "group: " + diskmap_group_data + "-UPDATE\n";
|
||||
download_list += "location: " + service_name + ":/" + update_list[k].location + "\n";
|
||||
download_list += "file-permission: r\n"
|
||||
download_list += "wtv-checksum: " + update_list[k]["wtv-checksum"] + "\n";
|
||||
download_list += "service-source-location: /webtv/content/" + service_name.replace("wtv-","") + "d/" + update_list[k].location + "\n";
|
||||
download_list += "client-dest-location: " + update_list[k].file + "\n\n";
|
||||
});
|
||||
|
||||
download_list += "CREATE-GROUP " + diskmap_group_data + "\n";
|
||||
download_list += "state: invalid\n";
|
||||
download_list += "service-owned: " + (diskmap_data.service_owned || false) + "\n";
|
||||
download_list += "base: " + diskmap_data.base + "\n\n";
|
||||
|
||||
Object.keys(update_list).forEach(function (k) {
|
||||
download_list += "DELETE " + update_list[k].file.replace(diskmap_data.base, "") + "\n";
|
||||
download_list += "group: " + diskmap_group_data + "\n\n";
|
||||
});
|
||||
|
||||
Object.keys(update_list).forEach(function (k) {
|
||||
download_list += "RENAME " + update_list[k].file.replace(diskmap_data.base, "") + "\n";
|
||||
download_list += "group: " + diskmap_group_data + "-UPDATE\n";
|
||||
download_list += "destination-group: " + diskmap_group_data + "\n";
|
||||
download_list += "location: " + update_list[k].file.replace(diskmap_data.base, "") + "\n\n";
|
||||
});
|
||||
|
||||
download_list += "DELETE-GROUP " + diskmap_group_data + "-UPDATE\n\n";
|
||||
|
||||
download_list += "SET-GROUP " + diskmap_group_data + "\n";
|
||||
download_list += "state: ok\n";
|
||||
download_list += "version: " + newest_file_epoch + "\n";
|
||||
download_list += "last-checkup-time: " + new Date().toUTCString().replace("GMT", "+0000") + "\n\n";
|
||||
|
||||
return download_list;
|
||||
}
|
||||
|
||||
if (request_headers.query.diskmap) {
|
||||
if (fs.lstatSync(diskmap_dir + request_headers.query.diskmap + ".txt")) {
|
||||
var diskmap_data = fs.readFileSync(diskmap_dir + request_headers.query.diskmap + ".txt").toString();
|
||||
// try to parse diskmap and get an accurate timestamp for webtv versioning
|
||||
// check all files in the diskmap and return the timestamp of the most recently modified
|
||||
function processGroup(diskmap_primary_group, diskmap_group_data, diskmap_subgroup = null) {
|
||||
// parse webtv post
|
||||
var output_data = '';
|
||||
var post_data = request_headers.post_data.toString(CryptoJS.enc.Latin1).split("\n");
|
||||
var post_data_current_directory = '';
|
||||
var post_data_current_file = '';
|
||||
var post_data_fileinfo = new Array();
|
||||
var post_data_filecount = -1;
|
||||
|
||||
data = '';
|
||||
var latest_file_ts = 0;
|
||||
diskmap_data.split("\n").forEach(function (v) {
|
||||
if (v.indexOf(" sync ") != -1) {
|
||||
v = v.trim();
|
||||
var vcon = v.substring(v.indexOf("content/"));
|
||||
vcon = vcon.replace("content/", content_dir)
|
||||
var vconstat = Math.floor(fs.lstatSync(vcon).mtimeMs / 1000);
|
||||
if (vconstat > latest_file_ts) {
|
||||
latest_file_ts = vconstat
|
||||
}
|
||||
// todo read client post and only give whats needed
|
||||
// instead of all that is available
|
||||
// vconstat has the mtime of each file, we need to parse the post_data
|
||||
data += v + "\n";
|
||||
} else {
|
||||
data += v + "\n";
|
||||
Object.keys(post_data).forEach(function (k) {
|
||||
if (post_data[k] == "") return;
|
||||
if (post_data[k].substring(0, 7) == "file://") {
|
||||
post_data_current_directory = post_data[k];
|
||||
post_data_current_file = post_data[k];
|
||||
}
|
||||
if (post_data[k].indexOf(":") > 0) {
|
||||
var post_data_line = post_data[k].split(":")
|
||||
var post_data_line_name = post_data_line[0];
|
||||
post_data_line.shift();
|
||||
var post_data_line_data = post_data_line.join(":");
|
||||
|
||||
if (!post_data_fileinfo[post_data_filecount]) post_data_fileinfo[post_data_filecount] = new Array();
|
||||
|
||||
if (post_data_line_name == "Last-modified") {
|
||||
post_data_fileinfo[post_data_filecount][post_data_line_name] = (Date.parse(post_data_line_data) / 1000);
|
||||
} else if (post_data_line_name == "Content-length") {
|
||||
post_data_fileinfo[post_data_filecount][post_data_line_name] = parseInt(post_data_line_data);
|
||||
}
|
||||
else {
|
||||
post_data_fileinfo[post_data_filecount][post_data_line_name] = post_data_line_data;
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
post_data_filecount++;
|
||||
post_data_current_file = post_data_current_directory + post_data[k];
|
||||
post_data_fileinfo[post_data_filecount] = new Array();
|
||||
post_data_fileinfo[post_data_filecount].file = post_data_current_file
|
||||
}
|
||||
});
|
||||
var wtv_download_list = new Array();
|
||||
Object.keys(diskmap_group_data.files).forEach(function (k) {
|
||||
if (!diskmap_group_data.files[k].location) diskmap_group_data.files[k].location = diskmap_group_data.location + diskmap_group_data.files[k].file.replace(diskmap_group_data.base, "");
|
||||
var post_match_file = null;
|
||||
Object.keys(service_vaults).forEach(function (g) {
|
||||
if (post_match_file != null) return;
|
||||
post_match_file = service_vaults[g].path + "/" + service_name + "/" + diskmap_group_data.files[k].location;
|
||||
if (!fs.existsSync(post_match_file)) post_match_file = null;
|
||||
});
|
||||
//data = diskmap_data.replace("!VERS!", latest_file_ts);
|
||||
var post_match_file_lstat = fs.lstatSync(post_match_file);
|
||||
var post_match_result = post_data_fileinfo.find(el => el["file"] === diskmap_group_data.files[k].file) || false;
|
||||
var post_match_file_data = new Buffer.from(fs.readFileSync(post_match_file, {
|
||||
encoding: null,
|
||||
flags: 'r'
|
||||
}));
|
||||
diskmap_group_data.files[k]["Last-modified"] = (post_match_file_lstat.mtime / 1000);
|
||||
diskmap_group_data.files[k]["Content-length"] = post_match_file_lstat.size;
|
||||
diskmap_group_data.files[k]["wtv-checksum"] = CryptoJS.MD5(CryptoJS.lib.WordArray.create(post_match_file_data)).toString(CryptoJS.enc.Hex).toLowerCase();
|
||||
if (!diskmap_group_data.files[k].display) diskmap_group_data.files[k].display = diskmap_group_data.display;
|
||||
|
||||
if (post_match_result) {
|
||||
// md5s match, so client doesn't need file
|
||||
if (diskmap_group_data.files[k]['wtv-checksum'] == post_match_result["wtv-checksum"]) return;
|
||||
else wtv_download_list.push(diskmap_group_data.files[k]);
|
||||
} else {
|
||||
wtv_download_list.push(diskmap_group_data.files[k]);
|
||||
}
|
||||
var diskmap_group_name = (diskmap_subgroup == null) ? diskmap_primary_group : diskmap_primary_group + "-" + diskmap_subgroup;
|
||||
output_data = generateDownloadList(diskmap_group_name, wtv_download_list, diskmap_group_data)
|
||||
});
|
||||
return output_data;
|
||||
}
|
||||
|
||||
if (request_headers.query.diskmap && request_headers.query.group && request_headers.post_data) {
|
||||
var diskmap_json_file = null;
|
||||
Object.keys(service_vaults).forEach(function (g) {
|
||||
if (diskmap_json_file != null) return;
|
||||
diskmap_json_file = service_vaults[g].path + "/" + service_name + "/" + diskmap_dir + request_headers.query.diskmap + ".json";
|
||||
if (!fs.existsSync(diskmap_json_file)) diskmap_json_file = null;
|
||||
});
|
||||
|
||||
if (diskmap_json_file != null) {
|
||||
if (fs.lstatSync(diskmap_json_file)) {
|
||||
try {
|
||||
// read diskmap
|
||||
var diskmap_data = JSON.parse(fs.readFileSync(diskmap_json_file).toString());
|
||||
if (!diskmap_data[request_headers.query.group]) {
|
||||
throw ("Invalid diskmap data (group does not match)");
|
||||
}
|
||||
data = '';
|
||||
diskmap_data = diskmap_data[request_headers.query.group];
|
||||
/*if (!diskmap_data.display) {
|
||||
Object.keys(diskmap_data).forEach(function (k) {
|
||||
if (diskmap_data[k]) data += processGroup(request_headers.query.group,diskmap_data[k],k);
|
||||
});
|
||||
} else { */
|
||||
data = processGroup(request_headers.query.group, diskmap_data);
|
||||
//}
|
||||
|
||||
headers = "200 OK\nContent-Type: wtv/download-list";
|
||||
} catch (e) {
|
||||
var errpage = doErrorPage(400);
|
||||
headers = errpage[0];
|
||||
data = errpage[1];
|
||||
console.log("wtv-update:/sync error", e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var errpage = doErrorPage(404,"The requested DiskMap does not exist.");
|
||||
headers = errpage[0];
|
||||
data = errpage[1];
|
||||
console.log("wtv-update:/sync error", "could not find diskmap");
|
||||
}
|
||||
}
|
||||
|
||||
headers = `200 OK
|
||||
Content-type: text/download-list`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user