transmission-card
transmission-card copied to clipboard
Add an option to add torrent through a file
Here is some prototype code. Though it doesn't work since the second function is asynchronous and the Hass object is out of its scope. Currently lacking braincells to come up with a solution. The first function is called using an onclick event from a button, that could be positioned on the right side of the input field.
_addTorrentViaFileButton(event) {
var x = document.createElement("INPUT");
x.setAttribute("type", "file");
x.addEventListener("change", this._addTorrentViaFile);
x.click();
};
async _addTorrentViaFile(event) {
let base64string = await new Promise((resolve) => {
let file = event.currentTarget.files[0];
const fileReader = new FileReader();
fileReader.readAsDataURL(file);
fileReader.onload = () => {
resolve(fileReader.result);
};
});
this.hass.callService('transmission', 'add_torrent', { entry_id: `${this._getConfigEntry()}`, torrent: base64string });
};
Perhaps one way of doing it would be changing the value of the input field to the calculated base64 value and then using this to emulate the Enter keyboard event https://stackoverflow.com/questions/3276794/jquery-or-pure-js-simulate-enter-key-pressed-for-testing
Got it working by emulating the keyboard event. Waiting for the previous PR to be merged to avoid conflicts.
According to the transmission integration, it should support base64 encoded torrent files. Though I have tried 2 and for both I had gotten a service call error claiming the file name is too long. Perhaps it would have been better to convert the torrent file into a magnet link. Any other ideas?
According to the transmission integration documentationpage:
It can either be a URL (HTTP, HTTPS or FTP), magnet link or a local file (make sure that the path is white listed).
Not sure encoded file in base64 is supported
What the Developer Tools -> services in HA show: Add a new torrent to download (URL, magnet link or Base64 encoded).
async function convertToMagnet(torrentFile) {
const reader = new FileReader();
reader.readAsArrayBuffer(torrentFile);
return new Promise((resolve, reject) => {
reader.onloadend = () => {
const buf = new Uint8Array(reader.result);
const infoHash = sha1(buf);
resolve(`magnet:?xt=urn:btih:${infoHash}`);
}
});
}
function sha1(buf) {
const crypto = window.crypto || window.msCrypto;
const hash = crypto.subtle.digest('SHA-1', buf);
const digest = new Uint8Array(hash);
const hex = Array.prototype.map.call(digest, x => (x < 16 ? "0" : "") + x.toString(16)).join("");
return hex;
}
Only issue is, this only works when accessing the page through https. In the end, we could make the file upload option disappear when accessing through http unless we find a workaround. Issue is with the window.crypto.subtle - when accessing through http, it's undefined
Only issue is, this only works when accessing the page through https. In the end, we could make the file upload option disappear when accessing through http unless we find a workaround. Issue is with the window.crypto.subtle - when accessing through http, it's undefined
When on http put a disabled Upload icon and on its tooltip explain that file upload only works over https.