Merge pull request #78 from eyedeekay/bittorrent

Bittorrent
This commit is contained in:
idk
2020-02-26 01:43:39 +00:00
committed by GitHub
28 changed files with 807 additions and 230 deletions

View File

@@ -5,12 +5,14 @@ default: zip
install: uninstall
mkdir -p $(PREFIX)/share/webext/i2ppb@eyedeekay.github.io \
$(PREFIX)/share/webext/i2ppb@eyedeekay.github.io/i2pcontrol \
$(PREFIX)/share/webext/i2ppb@eyedeekay.github.io/torrent \
$(PREFIX)/share/mozilla/extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}
cp -r ./icons/ $(PREFIX)/share/webext/i2ppb@eyedeekay.github.io/
cp -r ./_locales/ $(PREFIX)/share/webext/i2ppb@eyedeekay.github.io/
cp -r ./options/ $(PREFIX)/share/webext/i2ppb@eyedeekay.github.io/
cp ./*.js $(PREFIX)/share/webext/i2ppb@eyedeekay.github.io/
cp ./i2pcontrol/i2pcontrol.js $(PREFIX)/share/webext/i2ppb@eyedeekay.github.io/i2pcontrol/i2pcontrol.js
cp ./torrent/*.js $(PREFIX)/share/webext/i2ppb@eyedeekay.github.io/torrent/
cp ./*.html $(PREFIX)/share/webext/i2ppb@eyedeekay.github.io/
cp ./*.css $(PREFIX)/share/webext/i2ppb@eyedeekay.github.io/
cp ./*.md $(PREFIX)/share/webext/i2ppb@eyedeekay.github.io/
@@ -38,8 +40,8 @@ clean:
## EVEN RELEASES are AMO RELEASES
## ODD RELEASES are SELFHOSTED RELEASES
MOZ_VERSION=0.56
VERSION=0.57
MOZ_VERSION=0.58
VERSION=0.59
## INCREMENT THIS EVERY TIME YOU DO A RELEASE
LAST_VERSION=0.55
@@ -80,6 +82,18 @@ index:
@echo "</body>" >> index.html
@echo "</html>" >> index.html
torrenthelp:
@echo "<!DOCTYPE html>" > torrent/index.html
@echo "<html>" >> torrent/index.html
@echo "<head>" >> torrent/index.html
@echo " <title>I2P in Private Browsing Mode</title>" >> torrent/index.html
@echo " <link rel=\"stylesheet\" type=\"text/css\" href =\"home.css\" />" >> torrent/index.html
@echo " <link rel=\"stylesheet\" type=\"text/css\" href =\"sidebar.css\" />" >> torrent/index.html
@echo "</head>" >> torrent/index.html
@echo "<body>" >> torrent/index.html
sed "s|magnetsub|[Magnet Link]($(MAGNET))|g" torrent/README.md | markdown >> torrent/index.html
@echo "</body>" >> torrent/index.html
@echo "</html>" >> torrent/index.html
xpi:
#wget -O ../i2ppb@eyedeekay.github.io.xpi \
@@ -116,7 +130,7 @@ zip: version
--exclude="web-ext-artifacts" \
--exclude="./*.pdf" -r -FS ../i2psetproxy.js.zip *
release:
release: index torrenthelp
cat desc debian/changelog | grep -B 10 "$(LAST_VERSION)" | gothub release -p -u eyedeekay -r I2P-in-Private-Browsing-Mode-Firefox -t $(VERSION) -n $(VERSION) -d -; true
delete-release:
@@ -246,6 +260,9 @@ fmt:
tidy --as-xhtml --drop-empty-elements no --input-xml --tidy-mark no -indent --indent-spaces 4 -wrap 0 --new-blocklevel-tags article,header,footer --new-inline-tags video,audio,canvas,ruby,rt,rp --break-before-br yes --sort-attributes alpha --vertical-space yes home.html > .home.html; mv .home.html home.html
tidy --as-xhtml --drop-empty-elements no --input-xml --tidy-mark no -indent --indent-spaces 4 -wrap 0 --new-blocklevel-tags article,header,footer --new-inline-tags video,audio,canvas,ruby,rt,rp --break-before-br yes --sort-attributes alpha --vertical-space yes toopie.html > .toopie.html; mv .toopie.html toopie.html
tidy --as-xhtml --drop-empty-elements no --input-xml --tidy-mark no -indent --indent-spaces 4 -wrap 0 --new-blocklevel-tags article,header,footer --new-inline-tags video,audio,canvas,ruby,rt,rp --break-before-br yes --sort-attributes alpha --vertical-space yes options/options.html > options/.options.html; mv options/.options.html options/options.html
make fmt-js
fmt-js:
find . -path ./node_modules -prune -o -name '*.js' -exec prettier --write {} \;
find . -path ./node_modules -prune -o -name '*.json' -exec prettier --write {} \;
@@ -291,3 +308,5 @@ rss: torrent
upload-rss:
gothub upload -R -u eyedeekay -r I2P-in-Private-Browsing-Mode-Firefox -t docs -n "releases.atom" -f releases.atom
webext:
web-ext run -u "about:devtools-toolbox?type=extension&id=i2ppb%40eyedeekay.github.io"

View File

@@ -1,14 +1,14 @@
I2P in Private Browsing Mode(Firefox-Only)
==========================================
This is an **Experimental** webextension which introduces a set of new "Private
Browsing" modes to Firefox-based browsers(Supporting webextensions) that makes
it easier to configure a browser to use I2P securely and adds features for
making I2P applications easier to use. It does this by isolating I2P-specific
settings to Contextual Identities within Firefox, then loading them
automatically when the user requests them. It also adds convenience and
management features specific to I2P like protocol handlers and native messaging
systems.
This is an webextension which introduces a set of new "Private Browsing" modes
to Firefox-based browsers(Supporting webextensions) that makes it easier to
configure a browser to use I2P securely and adds features for making I2P
applications easier to use. It does this by isolating I2P-specific settings to
Contextual Identities within Firefox, then loading them automatically when the
user requests them. It also adds convenience and management features, like an
embedded I2P console and Bittorrent integration with clients using the
transmission-rpc API.
Installation(Cross-Platform):
-----------------------------
@@ -127,6 +127,7 @@ Documents
* **[Smart Lander Design](https://github.com/eyedeekay/I2P-in-Private-Browsing-Mode-Firefox/releases/download/docs/Landing.Page.Documentation.pdf)**: This is the original outline of
the smart landing page which became the I2P home page within the browser and
the drop-down control panel.
* **[Other extensions](https://github.com/eyedeekay/I2P-in-Private-Browsing-Mode-Firefox/wiki/Other-Extensions)**: and how they work with this one.
Super Extra Important Background Info:
--------------------------------------
@@ -197,5 +198,3 @@ for updates, you can download the identical plugin from this repository's
releases page. The latest AMO Plugin will always be identical to the latest
github release, except for the version number, which must be incremented for
submission to AMO.
moz-extension://d63582fc-09fc-445a-b8aa-1c888ee2ffc0/toopie.html

View File

@@ -11,6 +11,10 @@
"message": "Your browser is now set up to use I2P.",
"description": "Description of the extension."
},
"extensionVersion": {
"message": "0.57",
"description": "Version of the extension."
},
"extensionStatus": {
"message": "It is a labs project for enhancing your I2P browsing experience.",
"description": "Release status of the extension."
@@ -63,6 +67,14 @@
"message": "These applications work with I2P directly to provide them with security and privacy.",
"description": "Description for application section."
},
"windowVisitConsole": {
"message": "Router Console: ",
"description": "Router Console label."
},
"routerConsole": {
"message": "The entrypoint for all other I2P applications is the I2P Router Console. To visit it, click here.",
"description": "Description for the router console."
},
"windowVisitHomepage": {
"message": "Home Page: ",
"description": "Home page for the extension label."

View File

@@ -93,7 +93,7 @@ gettingInfo.then(got => {
let port = info.value.http.split(":")[1];
if (port == "7644") {
var createBookmark = browser.bookmarks.create({
url: "http://localhost:7647/i2ptunnelmgr",
url: "http://localhost:7647/i2ptunnel",
title: "Hidden Services Manager",
parentId: bookmarkToolbar[0].id
});
@@ -101,11 +101,7 @@ gettingInfo.then(got => {
} else {
var createRhizomeBookmark = browser.bookmarks.create({
url:
"http://" +
control_host +
":" +
control_port +
"/i2ptunnelmgr",
"http://" + control_host + ":" + control_port + "/i2ptunnel",
title: "Hidden Services Manager",
parentId: bookmarkToolbar[0].id
});

View File

@@ -11,6 +11,7 @@ function contentUpdateById(id, message) {
// Information Section
contentUpdateById("text-section-header", "extensionName");
contentUpdateById("description", "extensionDescription");
contentUpdateById("i2pbrowser-version", "extensionVersion");
contentUpdateById("beta", "extensionStatus");
contentUpdateById("proxy-check", "proxyFailedStatus");
@@ -29,6 +30,8 @@ contentUpdateById("applicationHeader", "applicationHeader");
contentUpdateById("applicationExplain", "applicationExplain");
contentUpdateById("window-visit-index", "windowVisitHelppage");
contentUpdateById("help", "help");
contentUpdateById("window-visit-router", "windowVisitConsole");
contentUpdateById("routerConsole", "routerConsole");
contentUpdateById("window-visit-homepage", "windowVisitHomepage");
contentUpdateById("abouthome", "abouthome");
contentUpdateById("window-visit-i2ptunnel", "windowVisitI2ptunnel");

2
debian/rules vendored
View File

@@ -6,12 +6,14 @@
override_dh_auto_install:
mkdir -p $$(pwd)/debian/i2psetproxy.js/usr/share/webext/i2ppb@eyedeekay.github.io \
$$(pwd)/debian/i2psetproxy.js/usr/share/webext/i2ppb@eyedeekay.github.io/i2pcontrol \
$$(pwd)/debian/i2psetproxy.js/usr/share/webext/i2ppb@eyedeekay.github.io/torrent \
$$(pwd)/debian/i2psetproxy.js/usr/share/mozilla/extensions/{ec8030f7-c20a-464f-9b0e-13a3a9e97384}
cp -r ./icons/ $$(pwd)/debian/i2psetproxy.js/usr/share/webext/i2ppb@eyedeekay.github.io/
cp -r ./options/ $$(pwd)/debian/i2psetproxy.js/usr/share/webext/i2ppb@eyedeekay.github.io/
cp -r ./_locales/ $$(pwd)/debian/i2psetproxy.js/usr/share/webext/i2ppb@eyedeekay.github.io/
cp ./*.js $$(pwd)/debian/i2psetproxy.js/usr/share/webext/i2ppb@eyedeekay.github.io/
cp ./i2pcontrol/i2pcontrol.js $$(pwd)/debian/i2psetproxy.js/usr/share/webext/i2ppb@eyedeekay.github.io/i2pcontrol/
cp ./torrent/*.js $$(pwd)/debian/i2psetproxy.js/usr/share/webext/i2ppb@eyedeekay.github.io/torrent/
cp ./*.html $$(pwd)/debian/i2psetproxy.js/usr/share/webext/i2ppb@eyedeekay.github.io/
cp ./*.css $$(pwd)/debian/i2psetproxy.js/usr/share/webext/i2ppb@eyedeekay.github.io/
cp ./*.md $$(pwd)/debian/i2psetproxy.js/usr/share/webext/i2ppb@eyedeekay.github.io/

View File

@@ -79,8 +79,11 @@ p {
background: #f8f8ff;
min-width: 95%
}
#header,
.application-info,
.extended-info {
.browser-info,
.extended-info,
.search-info {
min-height: 3rem;
padding: 1rem;
margin-top: 1.5rem;
@@ -165,7 +168,6 @@ li {
margin: .5rem .5rem .5rem 32%
}
#readyness {
float: left;
padding-top: 1rem;
padding-bottom: 1rem;
margin: 1rem;
@@ -175,7 +177,8 @@ li {
text-align: center!important;
border: 1px solid #dee2e6;
border-radius: 2px;
box-shadow: inset 0 0 0 1px #fff,0 0 1px #ccc
box-shadow: inset 0 0 0 1px #fff,0 0 1px #ccc;
display: inline-block
}
#onboarding {
min-height: 5rem;
@@ -202,8 +205,6 @@ li {
border-radius: 2px;
box-shadow: inset 0 0 0 1px #fff,0 0 1px #ccc
}
#applicationExplain,
#controlExplain,
#linksExplain {
min-height: 5rem;
padding: .5rem;
@@ -211,12 +212,25 @@ li {
width: 30%;
min-width: 30%;
background: #dee2e6;
float: left;
text-align: center!important;
border: 1px solid #dee2e6;
border-radius: 2px;
box-shadow: inset 0 0 0 1px #fff,0 0 1px #ccc
}
#applicationExplain,
#controlExplain {
min-height: 5rem;
padding: .5rem;
margin: .5rem;
width: 30%;
min-width: 30%;
background: #dee2e6;
text-align: center!important;
border: 1px solid #dee2e6;
border-radius: 2px;
box-shadow: inset 0 0 0 1px #fff,0 0 1px #ccc;
float: left
}
#proxyReady {
min-height: 3rem;
padding: .5rem;

View File

@@ -10,11 +10,10 @@
</head>
<body>
<!--<div>-->
<script src="home.js" type="text/javascript"></script>
<script src="content.js" type="text/javascript"></script>
<div class='background'>
<div class='content'>
<div class='section-header'>
<div class="text-section-header">
<h1 id="text-section-header">I2P Browsing</h1>
</div>
@@ -88,19 +87,23 @@
</li>-->
<li class="application">
<a class="applicationName" href="toopie.html" id="window-visit-toopie" target="_blank">Toopie</a> <span class="applicationDesc" id="toopie">For information about your I2P router status, go here:</span>
<a class="applicationName" href="toopie.html" id="window-visit-toopie">Toopie</a> <span class="applicationDesc" id="toopie">For information about your I2P router status, go here:</span>
</li>
<li class="application">
<a class="applicationName" href="http://127.0.0.1:7657/i2ptunnel" id="window-visit-i2ptunnel" target="_blank">Hidden Services Manager</a> <span class="applicationDesc" id="i2ptunnel">I2P has a web-based interface for configuring .i2p services like web sites, to set up your own web sites, go here:</span>
<a class="applicationName" href="http://127.0.0.1:7657/" id="window-visit-router">Router Console</a> <span class="applicationDesc" id="routerConsole">The entrypoint for all other I2P applications is the I2P Router Console. To visit it, click here.</span>
</li>
<li class="application">
<a class="applicationName" href="http://127.0.0.1:7657/susimail" id="window-visit-susimail" target="_blank">E-Mail</a> <span class="applicationDesc" id="susimail">I2P also bundles a webmail client which can be used to access in-I2P e-mail. To use it, go here:</span>
<a class="applicationName" href="http://127.0.0.1:7657/i2ptunnel" id="window-visit-i2ptunnel">Hidden Services Manager</a> <span class="applicationDesc" id="i2ptunnel">I2P has a web-based interface for configuring .i2p services like web sites, to set up your own web sites, go here:</span>
</li>
<li class="application">
<a class="applicationName" href="http://127.0.0.1:7657/i2psnark" id="window-visit-snark" target="_blank">BitTorrent</a> <span class="applicationDesc" id="snark">I2P is capable of anonymous Peer-to-Peer file sharing, to use the built-in bittorrent client go here:</span>
<a class="applicationName" href="http://127.0.0.1:7657/susimail" id="window-visit-susimail">E-Mail</a> <span class="applicationDesc" id="susimail">I2P also bundles a webmail client which can be used to access in-I2P e-mail. To use it, go here:</span>
</li>
<li class="application">
<a class="applicationName" href="http://127.0.0.1:7657/i2psnark" id="window-visit-snark">BitTorrent</a> <span class="applicationDesc" id="snark">I2P is capable of anonymous Peer-to-Peer file sharing, to use the built-in bittorrent client go here:</span>
</li>
</ul>
@@ -120,15 +123,19 @@
<ul>
<li>
<a href="https://eyedeekay.github.io/I2P-in-Private-Browsing-Mode-Firefox/" id="window-visit-webpage">Homepage:</a> <span class="applicationDesc" id="webpage">More information is available here.</span>
<a href="http://i2p-projekt.i2p/" id="window-visit-i2p">I2P Project Homepage:</a> <span class="applicationDesc" id="i2ppage">More information is available here.</span>
</li>
<li>
<a href="https://github.com/eyedeekay/I2P-in-Private-Browsing-Mode-Firefox" id="window-visit-sources">Source Code:</a> <span class="applicationDesc" id="sources">Browse the source or contribute here.</span>
<a href="/index.html" id="window-visit-homepage">Webextension Homepage:</a> <span class="applicationDesc" id="webpage">More information is available here.</span>
</li>
<li>
<a href="https://github.com/eyedeekay/I2P-in-Private-Browsing-Mode-Firefox" id="window-visit-releases">Releases:</a> <span class="applicationDesc" id="releases">Check for new releases here.</span>
<a href="http://gittest.i2p/idk/I2P-in-Private-Browsing-Mode-Firefox" id="window-visit-sources">Source Code:</a> <span class="applicationDesc" id="sources">Browse the source of this webextension or contribute here.</span>
</li>
<li>
<a href="http://gittest.i2p/idk/I2P-in-Private-Browsing-Mode-Firefox/-/releases" id="window-visit-releases">Releases:</a> <span class="applicationDesc" id="releases">Check for new releases here.</span>
</li>
</ul>
@@ -138,6 +145,7 @@
</div>
</div>
</div>
<!--</div>-->
<script src="home.js" type="text/javascript"></script>
<script src="content.js" type="text/javascript"></script> <!--</div>-->
</body>
</html>

View File

@@ -105,7 +105,8 @@ function UpdateEchoElementByID(
) {
function updateelement(update) {
//console.log("(i2pcontrol)", update);
document.getElementById(ID).innerText = update;
if (document.getElementById(ID) !== null)
document.getElementById(ID).innerText = update;
}
let net = Echo(Query, control_host, control_port, control_path, password);
net.then(updateleement);
@@ -143,7 +144,8 @@ function UpdateGetRateElementByID(
) {
function updateelement(update) {
//console.log("(i2pcontrol)", update);
document.getElementById(ID).innerText = update;
if (document.getElementById(ID) !== null)
document.getElementById(ID).innerText = update;
}
let net = GetRate(Query, control_host, control_port, control_path, password);
net.then(updateleement);
@@ -180,7 +182,8 @@ function UpdateI2PControlElementByID(
) {
function updateelement(update) {
//console.log("(i2pcontrol)", update);
document.getElementById(ID).innerText = update;
if (document.getElementById(ID) !== null)
document.getElementById(ID).innerText = update;
}
let net = I2PControl(
Query,
@@ -229,7 +232,8 @@ function UpdateRouterInfoElementByID(
ID,
document.getElementById(ID)
);*/
document.getElementById(ID).innerText = update.result[Query];
if (document.getElementById(ID) !== null)
document.getElementById(ID).innerText = update.result[Query];
}
let net = RouterInfo(
@@ -273,8 +277,9 @@ function UpdateRouterManagerElementByID(
password = "itoopie"
) {
function updateelement(update) {
c; //onsole.log("(i2pcontrol)", update);
document.getElementById(ID).innerText = update;
//console.log("(i2pcontrol)", update);
if (document.getElementById(ID) !== null)
document.getElementById(ID).innerText = update;
}
let net = RouterManager(
Query,

Binary file not shown.

View File

@@ -195,7 +195,5 @@
<h3>Android addons.mozilla.org(Temporarily Disabled)</h3>
<p>If you would prefer to recieve automatic updates from AMO, the correct product page for this plugin is <a href="https://addons.mozilla.org/en-US/firefox/addon/i2p-in-private-browsing/">I2P In Private Browsing</a>. This absolutely requires a working outproxy. If you want to avoid the use of AMO for updates, you can download the identical plugin from this repository's releases page. The latest AMO Plugin will always be identical to the latest github release, except for the version number, which must be incremented for submission to AMO.</p>
<p>moz-extension://d63582fc-09fc-445a-b8aa-1c888ee2ffc0/toopie.html</p>
</body>
</html>

View File

@@ -54,4 +54,7 @@ img.readyness {
}
#torrentpanel {
display: none
}
.torrent-progress {
width: 100%
}

28
info.js
View File

@@ -3,7 +3,8 @@ function checkPeerConnection() {
getting.then(got => {
let webrtc = got.value;
console.log("checking webrtc", webrtc);
document.getElementById("enable-web-rtc").checked = webrtc;
if (document.getElementById("enable-web-rtc") !== null)
document.getElementById("enable-web-rtc").checked = webrtc;
});
}
@@ -34,7 +35,8 @@ function checkHistory() {
disable_history = false;
}
console.log("checking history", disable_history);
document.getElementById("disable-history").checked = disable_history;
if (document.getElementById("disable-history") !== null)
document.getElementById("disable-history").checked = disable_history;
});
}
@@ -85,7 +87,7 @@ document.addEventListener("click", clickEvent => {
showBrowsing();
} else if (clickEvent.target.id === "torrent-action") {
console.log("showing a torrent action");
showTorrents();
showTorrentsMenu();
} else if (clickEvent.target.id === "window-preface-title") {
console.log("attempting to create homepage tab");
goHome();
@@ -149,7 +151,7 @@ function showBrowsing() {
y.style.display = "none";
}
function showTorrents() {
function showTorrentsMenu() {
var x = document.getElementById("browserpanel");
x.style.display = "none";
var y = document.getElementById("torrentpanel");
@@ -212,7 +214,7 @@ function goSearch() {
}
let createData = {
url:
"http://legwork.i2p/yacysearch.html?" +
"http://yacy.idk.i2p/yacysearch.html?" +
"query=" +
document.getElementById("search-query").value
};
@@ -221,12 +223,18 @@ function goSearch() {
creating.then(onTabCreated, onTabError);
}
function routerAddr() {
if (!control_host) var control_host = "127.0.0.1";
if (!control_port) var control_port = "7657";
return control_host + ":" + control_port;
}
function goTunnel() {
function onTabError() {
console.log("I2PTunnel tab created");
}
let createData = {
url: "http://" + control_host + ":" + control_port + "/i2ptunnel"
url: "http://" + routerAddr() + "/i2ptunnel"
};
console.log("visiting i2ptunnel");
let creating = browser.tabs.create(createData);
@@ -238,7 +246,7 @@ function goMail() {
console.log("Mail tab created");
}
let createData = {
url: "http://" + control_host + ":" + control_port + "/susimail"
url: "http://" + routerAddr() + "/susimail"
};
console.log("visiting mail");
let creating = browser.tabs.create(createData);
@@ -250,7 +258,7 @@ function goSnark() {
console.log("Snark tab created");
}
let createData = {
url: "http://" + control_host + ":" + control_port + "/i2psnark"
url: "http://" + routerAddr() + "/i2psnark"
};
console.log("visiting snark");
let creating = browser.tabs.create(createData);
@@ -281,11 +289,11 @@ function onVisited(historyItem) {
}
}
UpdateContents();
if (UpdateContents !== undefined) UpdateContents();
const minutes = 0.2;
const interval = minutes * 60 * 1000;
setInterval(function() {
UpdateContents();
if (UpdateContents !== undefined) UpdateContents();
}, interval);

View File

@@ -7,8 +7,10 @@
},
"permissions": [
"theme",
"alarms",
"browsingData",
"bookmarks",
"contextMenus",
"management",
"notifications",
"proxy",
@@ -48,8 +50,11 @@
"page": "options/options.html"
},
"background": {
"persistent": true,
"scripts": [
"config.js",
"torrent/common.js",
"torrent/background.js",
"i2pcontrol/i2pcontrol.js",
"host.js",
"privacy.js",
@@ -69,11 +74,6 @@
"name": "RouterConsole",
"uriTemplate": "http://127.0.0.1:7657/%s"
},
{
"protocol": "ext+dati2p",
"name": "Dat over I2P",
"uriTemplate": "/dat.html#!/%s"
},
{
"protocol": "magnet",
"name": "I2PTorrent",

View File

@@ -19,7 +19,7 @@
</select>
</section>
<section class="scheme-options proxy-options">
<section class="scheme-options proxy-options" id="proxy-options">
<div class="title">
Proxy Options
</div>
@@ -36,7 +36,7 @@
</div>
</section>-->
<section class="scheme-options control-options">
<section class="scheme-options console-options" id="console-options">
<div>
<div class="title">
Router Console Options
@@ -49,7 +49,7 @@
</div>
</section>
<section class="scheme-options control-options">
<section class="scheme-options control-options" id="control-options">
<div>
<div class="title">
I2PControl RPC Client Options
@@ -66,23 +66,24 @@
</div>
</section>
<section class="scheme-options control-options">
<section class="scheme-options transmission-options" id="transmission-options">
<div>
<div class="title">
Bittorrent RPC Client Options
</div>
<p id="rpcHelpText">Configure your Bittorrent options here.</p>
<label id="btRpcPortText">Torrent RPC Host:</label> <input data="btrpchost" id="btrpchost" type="text" value="127.0.0.1">
<label id="btRpcHostText">Torrent RPC Host:</label> <input data="btrpchost" id="btrpchost" type="text" value="127.0.0.1">
<br>
<label id="btRpcHostText">Torrent RPC Port:</label> <input data="btrpcport" id="btrpcport" type="text" value="7657">
<label id="btRpcPortText">Torrent RPC Port:</label> <input data="btrpcport" id="btrpcport" type="text" value="7657">
<br>
<label id="btRpcPathText">Torrent RPC Path:</label> <input data="btrpcpath" id="btrpcpath" type="text" value="transmission/rpc">
<label id="btRpcPathText">Torrent RPC Path:</label> <input data="btrpcpath" id="btrpcpath" type="text" value="transmission/">
<br>
<label id="rpcPassText">Torrent RPC Password:</label> <input data="btrpcpass" id="btrpcpass" type="text" value="itoopie">
<label id="rpcPassText">Torrent RPC Password:</label> <input data="btrpcpass" id="btrpcpass" type="text" value="">
</div>
</section>
<input id="save-button" type="button" value="Save preferences">
<script src="options.js"></script>
<script src="options.js"></script> <!--<script src="/torrent/browser-polyfill.min.js"></script>
<script src="/torrent/options.js"></script>-->
</body>
</html>

View File

@@ -209,7 +209,7 @@ function checkStoredSettings(storedSettings) {
} else defaultSettings["bt_rpc_port"] = storedSettings.bt_rpc_port;
if (!storedSettings["bt_rpc_path"]) {
defaultSettings["bt_rpc_path"] = "transmission/rpc";
defaultSettings["bt_rpc_path"] = "transmission/";
} else defaultSettings["bt_rpc_path"] = storedSettings.bt_rpc_path;
if (!storedSettings["bt_rpc_pass"]) {
@@ -217,14 +217,23 @@ function checkStoredSettings(storedSettings) {
} else defaultSettings["bt_rpc_pass"] = storedSettings.bt_rpc_pass;
console.log("(options)(browserinfo) NATIVE PROXYSETTINGS", info.value);
defaultSettings["base_url"] =
"http://" +
defaultSettings["bt_rpc_host"] +
":" +
defaultSettings["bt_rpc_port"] +
"/" +
defaultSettings["bt_rpc_path"];
console.log(
"(options)",
defaultSettings["proxy_sheme"],
defaultSettings["proxy_scheme"],
defaultSettings["proxy_host"],
defaultSettings["proxy_port"],
defaultSettings["control_host"],
defaultSettings["control_port"]
defaultSettings["control_port"],
defaultSettings["base_url"]
);
chrome.storage.local.set(defaultSettings);
return defaultSettings;
}
@@ -323,6 +332,8 @@ function storeSettings() {
let bt_rpc_port = getBTRPCPort();
let bt_rpc_path = getBTRPCPath();
let bt_rpc_pass = getBTRPCPass();
let base_url =
"http://" + bt_rpc_host + ":" + bt_rpc_port + "/" + bt_rpc_path;
chrome.storage.local.set({
proxy_scheme,
proxy_host,

View File

@@ -20,7 +20,6 @@ function shouldProxyRequest(requestInfo) {
}
var handleContextProxyRequest = async function(requestDetails) {
console.log("(proxy)Searching for proxy by context");
try {
var handleProxyRequest = function(context) {
proxy = {
@@ -100,12 +99,12 @@ var handleContextProxyRequest = async function(requestDetails) {
};
var contextGet = async function(tabInfo) {
try {
//console.log("(proxy)Tab info from Function", tabInfo);
console.log("(proxy)Tab info from Function", tabInfo);
context = await browser.contextualIdentities.get(tabInfo.cookieStoreId);
return context;
} catch (error) {
console.error(error);
//return; //"firefox-default";
return "firefox-default";
}
};
var tabGet = async function(tabId) {

View File

@@ -291,40 +291,68 @@ var contextSetup = function(requestDetails) {
console.log("(isolate)Context Error", error);
}
};
var anyTabFind = async function(tabId) {
var normalTabFind = async function(tabId) {
if (tabId == undefined) {
return;
}
try {
var context = await browser.contextualIdentities.query({
name: webpref
var anoncontext = await browser.contextualIdentities.query({
name: titlepref
});
var localcontext = await browser.contextualIdentities.query({
name: localpref
});
console.log("(ISOLATE)", tabId.cookieStoreId);
if (
tabId.cookieStoreId == "firefox-default" ||
tabId.cookieStoreId == "firefox-private"
) {
if (tabId.cookieStoreId != context[0].cookieStoreId) {
function Create() {
function onCreated(tab) {
function closeOldTab() {
if (tabId.id != tab.id) {
console.log("(isolate) Closing un-isolated tab", tabId.id);
console.log("in favor of", tab.id);
console.log("with context", tab.cookieStoreId);
browser.tabs.remove(tabId.id);
}
console.log(
"(ISOLATE)",
tabId.cookieStoreId,
"not",
anoncontext[0].cookieStoreId,
localcontext[0].cookieStoreId
);
return;
}
if (
tabId.cookieStoreId != anoncontext[0].cookieStoreId ||
tabId.cookieStoreId != localcontext[0].cookieStoreId
) {
function Create() {
function onCreated(tab) {
function closeOldTab() {
if (
tabId.id != tab.id &&
tabId.cookieStoreId != tab.cookieStoreId
) {
console.log(
"(isolate) Closing isolated tab",
tabId.id,
"with context",
tabId.cookieStoreId
);
console.log(
"(isolate) in favor of",
tab.id,
"with context",
tab.cookieStoreId
);
browser.tabs.remove(tabId.id);
}
closeOldTab(tab);
}
var created = browser.tabs.create({
active: true,
cookieStoreId: context[0].cookieStoreId,
url: requestDetails.url
});
created.then(onCreated, onContextError);
closeOldTab(tab);
}
var gettab = browser.tabs.get(tabId.id);
gettab.then(Create, onContextError);
return tabId;
var created = browser.tabs.create({
active: true,
cookieStoreId: "firefox-default",
url: requestDetails.url
});
created.then(onCreated, onContextError);
}
var gettab = browser.tabs.get(tabId.id);
gettab.then(Create, onContextError);
return tabId;
}
} catch (error) {
console.log("(isolate)Context Error", error);
@@ -369,12 +397,6 @@ var contextSetup = function(requestDetails) {
}
let localhost = localHost(requestDetails.url);
let routerhost = routerHost(requestDetails.url);
if (!routerhost) {
if (localhost) {
var localtab = tab.then(localTabFind, onContextError);
return requestDetails;
}
}
if (routerhost) {
if (routerhost === "i2ptunnelmgr") {
var tunneltab = tab.then(i2ptunnelTabFind, onContextError);
@@ -390,7 +412,13 @@ var contextSetup = function(requestDetails) {
return requestDetails;
}
} else {
if (localhost) {
var localtab = tab.then(localTabFind, onContextError);
return requestDetails;
}
var normalTab = tab.then(normalTabFind, onContextError);
return requestDetails;
//return requestDetails;
}
}
} catch (error) {

View File

@@ -2,9 +2,6 @@ li {
width: 90%;
margin-left: 0
}
#readyness {
margin-top: -.5rem
}
#applicationExplain {
float: unset
}

14
torrent/README.md Normal file
View File

@@ -0,0 +1,14 @@
Acknowledgement
===============
**Many, many thanks to the [Transmitter](https://github.com/myfreeweb/transmitter)
webextension.**
This part of this plugin contains code which was adapted from the Transmitter
webextension, which is a minimal interface to the transmission-rpc interfaces of
many torrent clients, including for our purposes snark-rpc and BiglyBT.
Transmitter is released under the UNLICENSE. An original copy is available at
this URL: https://github.com/myfreeweb/transmitter/blob/master/UNLICENSE
A copy has also been included in this directory.

24
torrent/UNLICENSE Normal file
View File

@@ -0,0 +1,24 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>

247
torrent/background.js Normal file
View File

@@ -0,0 +1,247 @@
"use strict";
////// Session extraction
function setupExtractor() {
browser.webRequest.onHeadersReceived.removeListener(extractSession);
browser.storage.local.get("server").then(({ server }) => {
if (!server) {
return;
}
console.log("Session extractor setup for", server.base_url);
browser.webRequest.onBeforeSendHeaders.addListener(
extractSession,
{ urls: [server.base_url + "*"] },
["requestHeaders"]
);
});
}
setupExtractor();
function extractSession(requestDetails) {
const hdr = requestDetails.requestHeaders.filter(
x => x.name.toLowerCase() === "x-transmission-session-id"
)[0];
if (!hdr) {
return;
}
browser.storage.local.get("server").then(({ server }) => {
server.session = hdr.value;
browser.storage.local.set({ server });
});
}
////// Adding
function blobToBase64(blob) {
return new Promise((resolve, reject) => {
const rdr = new FileReader();
rdr.onload = () => resolve(rdr.result.substr(rdr.result.indexOf(",") + 1));
rdr.onerror = reject;
rdr.readAsDataURL(blob);
});
}
function addUrl(torrentUrl, downloadDir) {
let p,
params = {};
if (downloadDir) {
params = { "download-dir": downloadDir };
}
if (torrentUrl.startsWith("magnet:")) {
console.log("Adding magnet", torrentUrl);
params.filename = torrentUrl;
p = rpcCall("torrent-add", params);
} else {
// Download the torrent file *in the browser* to support private torrents
console.log("Downloading torrent", torrentUrl);
p = fetch(torrentUrl, {
method: "GET",
credentials: "include"
})
.then(resp => {
if (resp.ok) {
return resp.blob();
}
throw new Error("Could not download torrent");
})
.then(blobToBase64)
.then(b64 => {
params.metainfo = b64;
return rpcCall("torrent-add", params);
});
}
return p.then(x => {
updateBadge();
return x;
});
}
////// magnet: Handler
function handleUrl(requestDetails) {
return addUrl(
decodeURIComponent(
requestDetails.url.replace("http://transmitter.web-extension/", "")
)
).then(x => {
return browser.storage.local.get("server").then(({ server }) => {
return { redirectUrl: server.base_url + "web/" };
});
});
}
browser.webRequest.onBeforeRequest.addListener(
handleUrl,
{ urls: ["http://transmitter.web-extension/*"] },
["blocking"]
);
////// Context menu
function createContextMenu() {
browser.storage.local.get("server").then(({ server }) => {
browser.contextMenus.removeAll();
if (!server || !server.locations || !server.locations.length) {
browser.contextMenus.create({
id: "transmitter-add",
title: "Download with Transmission remote",
contexts: ["link"]
});
} else {
browser.contextMenus.create({
id: "transmitter-add",
title: "Download to Default location",
contexts: ["link"]
});
server.locations.forEach(location => {
browser.contextMenus.create({
id: "transmitter-add-loc-" + location.index,
title: "Download to " + location.name,
contexts: ["link"]
});
});
}
});
}
createContextMenu();
browser.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === "transmitter-add") {
return addUrl(info.linkUrl);
} else if (info.menuItemId.startsWith("transmitter-add-loc-")) {
let index = parseInt(info.menuItemId.substr("transmitter-add-loc-".length));
browser.storage.local.get("server").then(({ server }) => {
let path = server.locations[index].path;
addUrl(info.linkUrl, path);
});
}
});
////// Badge
function updateBadge() {
browser.storage.local.get("server").then(({ server }) => {
if (
server.badge !== "num" &&
server.badge !== "dl" &&
server.badge !== "ul" &&
server.badge !== "auto"
) {
return;
}
return rpcCall("session-stats", {}).then(response => {
const args = response.arguments; // lol the name 'arguments' means destructuring in strict mode is impossible
switch (server.badge) {
case "num":
browser.browserAction.setBadgeBackgroundColor({ color: "gray" });
browser.browserAction.setBadgeText({
text: "" + args.activeTorrentCount
});
break;
case "dl":
browser.browserAction.setBadgeBackgroundColor({ color: "green" });
browser.browserAction.setBadgeText({
text: formatSpeed(args.downloadSpeed)
});
break;
case "ul":
browser.browserAction.setBadgeBackgroundColor({ color: "blue" });
browser.browserAction.setBadgeText({
text: formatSpeed(args.uploadSpeed)
});
break;
case "auto":
if (args.downloadSpeed > 0) {
browser.browserAction.setBadgeBackgroundColor({ color: "green" });
browser.browserAction.setBadgeText({
text: formatSpeed(args.downloadSpeed)
});
} else if (args.uploadSpeed > 0) {
browser.browserAction.setBadgeBackgroundColor({ color: "blue" });
browser.browserAction.setBadgeText({
text: formatSpeed(args.uploadSpeed)
});
} else {
browser.browserAction.setBadgeBackgroundColor({ color: "gray" });
browser.browserAction.setBadgeText({
text: "" + args.activeTorrentCount
});
}
break;
}
});
});
}
browser.alarms.onAlarm.addListener(alarm => {
if (alarm.name === "transmitter-badge-update") {
return updateBadge();
}
});
function setupBadge() {
browser.alarms.clear("transmitter-badge-update").then(x => {
browser.storage.local.get("server").then(({ server }) => {
if (!server) {
return;
}
browser.alarms.create("transmitter-badge-update", {
periodInMinutes: parseInt(server.badge_interval || "1")
});
updateBadge();
});
});
}
setupBadge();
////// Storage updates
browser.storage.onChanged.addListener((changes, area) => {
if (!Object.keys(changes).includes("server")) {
return;
}
const oldv = changes.server.oldValue;
const newv = changes.server.newValue;
if (
!oldv ||
oldv.base_url !== newv.base_url ||
oldv.username !== newv.username ||
oldv.password !== newv.password ||
oldv.badge_interval !== newv.badge_interval ||
oldv.badge !== newv.badge ||
arraysEqualDeep(oldv.locations, newv.locations)
) {
setupExtractor();
setupBadge();
updateBadge();
createContextMenu();
}
});
function arraysEqualDeep(arr1, arr2) {
return JSON.stringify(arr1) !== JSON.stringify(arr2);
}

60
torrent/common.js Normal file
View File

@@ -0,0 +1,60 @@
"use strict";
////// RPC
function rpcCall(meth, args) {
return browser.storage.local.get(function(server) {
const myHeaders = {
"Content-Type": "application/json",
"x-transmission-session-id": server.session
};
//console.log("(torrent)", server.session)
if (server.username !== "" || server.btrpcpass !== "") {
myHeaders["Authorization"] =
"Basic " +
btoa((server.username || "") + ":" + (server.btrpcpass || ""));
}
//console.log("(torrent) rpc", server.base_url);
return fetch(server.base_url + "rpc", {
method: "POST",
headers: myHeaders,
body: JSON.stringify({ method: meth, arguments: args }),
credentials: "include" // allows HTTPS client certs!
})
.then(function(response) {
const session = response.headers.get("x-transmission-session-id");
if (session) {
browser.storage.local.get({}).then(function(storage) {
storage.session = session;
browser.storage.local.set(storage);
});
}
if (response.status === 409) {
return rpcCall(meth, args);
}
if (response.status >= 200 && response.status < 300) {
return response;
}
const error = new Error(response.statusText);
error.response = response;
throw error;
})
.then(function(response) {
return response.json();
});
});
}
////// Util
function formatSpeed(s) {
// Firefox shows 4 characters max
if (s < 1000 * 1000) {
return (s / 1000).toFixed() + "K";
}
if (s < 1000 * 1000 * 1000) {
return (s / 1000 / 1000).toFixed() + "M";
}
// You probably don't have that download speed…
return (s / 1000 / 1000 / 1000).toFixed() + "T";
}

23
torrent/index.html Normal file
View File

@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<title>I2P in Private Browsing Mode</title>
<link rel="stylesheet" type="text/css" href ="home.css" />
<link rel="stylesheet" type="text/css" href ="sidebar.css" />
</head>
<body>
<h1>Acknowledgement</h1>
<p><strong>Many, many thanks to the <a href="https://github.com/myfreeweb/transmitter">Transmitter</a>
webextension.</strong></p>
<p>This part of this plugin contains code which was adapted from the Transmitter
webextension, which is a minimal interface to the transmission-rpc interfaces of
many torrent clients, including for our purposes snark-rpc and BiglyBT.</p>
<p>Transmitter is released under the UNLICENSE. An original copy is available at
this URL: https://github.com/myfreeweb/transmitter/blob/master/UNLICENSE</p>
<p>A copy has also been included in this directory.</p>
</body>
</html>

153
torrent/popup.js Normal file
View File

@@ -0,0 +1,153 @@
"use strict";
var TrpcCall = async function(meth, args) {
const server = await browser.storage.local.get(null);
const myHeaders = {
"Content-Type": "application/json",
"x-transmission-session-id": server.session
};
console.log("(torrent) session", server.session);
if (server.username !== "" || server.btrpcpass !== "") {
myHeaders["Authorization"] =
"Basic " + btoa((server.username || "") + ":" + (server.btrpcpass || ""));
}
console.log("(torrent) rpcurl", server.base_url + "rpc");
return fetch(server.base_url + "rpc", {
method: "POST",
headers: myHeaders,
body: JSON.stringify({ method: meth, arguments: args }),
credentials: "include" // allows HTTPS client certs!
});
/*.then(function(response) {
console.log("(torrent) responses", response);
if (response.status === 409) {
return TrpcCall(meth, args);
}
if (response.status >= 200 && response.status < 300) {
return response;
}
const error = new Error(response.statusText);
error.response = response;
throw error;
});*/
};
const torrentsPane = document.getElementById("torrents-pane");
const configPane = document.getElementById("config-pane");
for (const opener of document.querySelectorAll(".config-opener")) {
opener.addEventListener("click", e => {
browser.runtime.openOptionsPage();
});
}
function showConfig(server) {
torrentsPane.hidden = true;
configPane.hidden = false;
}
const torrentsSearch = document.getElementById("torrents-search");
const torrentsList = document.getElementById("torrents-list");
const torrentsTpl = document.getElementById("torrents-tpl");
const torrentsError = document.getElementById("torrents-error");
const getArgs = {
fields: ["name", "percentDone", "rateDownload", "rateUpload", "queuePosition"]
};
let cachedTorrents = [];
function renderTorrents(newTorrents) {
if (torrentsList.children.length < newTorrents.length) {
const dif = newTorrents.length - torrentsList.children.length;
for (let i = 0; i < dif; i++) {
const node = document.importNode(torrentsTpl.content, true);
torrentsList.appendChild(node);
}
} else if (torrentsList.children.length > newTorrents.length) {
const oldLen = torrentsList.children.length;
const dif = oldLen - newTorrents.length;
for (let i = 1; i <= dif; i++) {
torrentsList.removeChild(torrentsList.children[oldLen - i]);
}
}
for (let i = 0; i < newTorrents.length; i++) {
const torr = newTorrents[i];
const cont = torrentsList.children[i];
const speeds =
"↓ " +
formatSpeed(torr.rateDownload) +
"B/s ↑ " +
formatSpeed(torr.rateUpload) +
"B/s";
cont.querySelector(".torrent-name").textContent = torr.name;
cont.querySelector(".torrent-speeds").textContent = speeds;
cont.querySelector(".torrent-progress").value = torr.percentDone * 100;
}
}
function searchTorrents() {
let newTorrents = cachedTorrents;
const val = torrentsSearch.value.toLowerCase().trim();
if (val.length > 0) {
newTorrents = newTorrents.filter(x => x.name.toLowerCase().includes(val));
}
renderTorrents(newTorrents);
}
torrentsSearch.addEventListener("change", searchTorrents);
torrentsSearch.addEventListener("keyup", searchTorrents);
function refreshTorrents(server) {
console.log("(torrent) initiating", server);
return TrpcCall("torrent-get", getArgs).then(function(response) {
const session = response.headers.get("x-transmission-session-id");
if (session) {
browser.storage.local.get({}).then(function(storage) {
storage.session = session;
browser.storage.local.set(storage);
});
}
let sponse = response.json();
sponse.then(function(response) {
console.log("(torrent) refreshing", response);
let newTorrents = response.arguments.torrents;
newTorrents.sort((x, y) => y.queuePosition - x.queuePosition);
cachedTorrents = newTorrents;
torrentsSearch.hidden = newTorrents.length <= 8;
if (torrentsSearch.hidden) {
torrentsSearch.value = "";
renderTorrents(newTorrents);
} else {
searchTorrents();
}
});
});
}
function refreshTorrentsLogErr(server) {
return refreshTorrents(server).catch(err => {
console.error(err);
torrentsError.textContent = "Error: " + err.toString();
});
}
function showTorrents(server) {
torrentsPane.hidden = false;
configPane.hidden = true;
for (const opener of document.querySelectorAll(".webui-opener")) {
opener.href = server.base_url + "web/";
}
console.log("(torrent) showing torrents");
refreshTorrents(server).catch(_ => refreshTorrentsLogErr(server));
setInterval(() => refreshTorrentsLogErr(server), 2000);
}
//let store =
browser.storage.local.get(function(server) {
console.log("(torrent) querying storage", server);
if (server && server.base_url && server.base_url !== "") {
showTorrents(server);
} else {
showConfig(server);
}
});

View File

@@ -1,82 +0,0 @@
var hello = "hello bittorrent";
function makeid(length) {
var result = "";
var characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
function send(
message,
control_host = "127.0.0.1",
control_port = "7657",
control_path = "transmission/rpc"
) {
async function postData(url = "", data = {}) {
// Default options are marked with *
let requestBody = JSON.stringify(data);
//console.log("(i2pcontrol)", requestBody, data);
let opts = {
method: "POST", // *GET, POST, PUT, DELETE, etc.
mode: "cors", // no-cors, *cors, same-origin
cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
credentials: "same-origin", // include, *same-origin, omit
headers: {
"Content-Type": "application/json"
},
redirect: "follow", // manual, *follow, error
referrerPolicy: "no-referrer", // no-referrer, *client
body: requestBody // body data type must match "Content-Type" header
};
const response = await fetch(url, opts);
return await response.json(); // parses JSON response into native JavaScript objects
}
return postData(
"http://" + control_host + ":" + control_port + "/" + control_path + "/",
message
);
}
function authenticate(
password = "transmission",
control_host = "127.0.0.1",
control_port = "7657",
control_path = "transmission/rpc"
) {
let store = browser.storage.local.get("rpc_pass");
if (store != undefined) {
console.log("Stored password found");
password = store;
}
function auth(got) {
var json = new Object();
json["id"] = makeid(6);
json["jsonrpc"] = "2.0";
json["method"] = "Authenticate";
json["params"] = new Object();
json["params"]["API"] = 1;
json["params"]["Password"] = password;
return send(json);
}
store.then(auth);
}
async function GetToken(
password,
control_host = "127.0.0.1",
control_port = "7657",
control_path = "transmission/rpc"
) {
let me = authenticate(password);
return await me.then(gettoken);
}
function gettoken(authtoken) {
return authtoken.result.Token;
}

BIN
transmissionrpc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 577 KiB

View File

@@ -4,7 +4,8 @@
<meta charset="utf-8">
<link href="search.css" rel="stylesheet">
<link href="home.css" rel="stylesheet">
<link href="info.css" rel="stylesheet">
<link href="info.css" rel="stylesheet"><!--<link href="torrent/popup.css" rel="stylesheet">-->
<title>
</title>
</head>
@@ -16,35 +17,32 @@
<div id="browserpanel">
<div class="panel">
<div class="section-header panel-section panel-section-header">
<div class="section-header panel-section panel-section-header" id="headline">
<div class="text-section-header" id="text-section-header">
<h1>The Invisible Internet Browser</h1>
<h1 id="text-section-header">The Invisible Internet Browser</h1>
</div>
</div>
<div class="topnav">
<a class="applicationName window-visit-homepage" href="#" id="window-visit-homepage" target="_blank">Home Page</a> <!--<form action="http://legwork.i2p/yacysearch.html?" method="get">
<input id="search-query" name="query" placeholder="Search on legwork.i2p(Opens a new tab)" type="search"> <input id="search-submit" text="Submit" type="submit">
</form>-->
</div>
<div class="search-info">
<div id="i2pbrowser-version">
</div>
<div class="panel-section-separator">
</div>
<div class="topnav">
<a class="applicationName window-visit-homepage" href="#" id="window-visit-homepage" target="_blank">Home Page</a>
<form action="http://yacy.idk.i2p/yacysearch.html?" method="get">
<input id="search-query" name="query" placeholder="Search on yacy.idk.i2p(Opens a new tab)" type="search"> <input id="search-submit" text="Submit" type="submit">
</form>
</div>
<div id="i2pbrowser-version">
</div>
<div class="hideIfI2PProxyOff" id="readyness">
<img class="readyness" src="http://proxy.i2p/themes/console/images/local_up.png"> <span id="proxy-check">Proxy is ready.</span>
</div>
<div class="hideIfI2PProxyOff" id="readyness">
<img class="readyness" src="http://proxy.i2p/themes/console/images/local_up.png"> <span id="proxy-check">Proxy is ready.</span>
</div>
<div id="i2pbrowser-description">
<p id="description">You are now able to use I2P in this browser.</p>
<div id="i2pbrowser-description">
<p id="description">You are now able to use I2P in this browser.</p>
<p id="beta">It is experimental.</p>
</div>
<div class="panel-section-separator">
<p id="beta">It is experimental.</p>
</div>
</div>
<div class="browser-info">
@@ -111,26 +109,63 @@
<p>
</p>
</div>
<div id="torrentpanel">
<div class="panel" id="torrentstatus">
<div class="section-header panel-section panel-section-header">
<div class="text-section-header" id="text-section-torrents-header">
<h3>Torrent Downloads</h3>
</div>
</div>
<div id="torrentsection">
Torrents go here.
</div>
</div>
</div>
<script src="context.js"></script>
<script src="privacy.js"></script>
<script src="info.js"></script>
<script crossorigin="anonymous" src="content.js"></script>
<script src="i2pcontrol/i2pcontrol.js"></script>
</div>
</div>
<div id="torrentpanel">
<div class="panel" id="torrentstatus">
<div class="section-header panel-section panel-section-header">
<div class="text-section-header" id="text-section-torrents-header">
<h3>Torrent Downloads</h3>
</div>
</div>
<div hidden="" id="config-pane">
<strong>Torrent RPC Configuration</strong>
<br>
The server address is not set yet.
<br>
<a class="config-opener" href="#">Open the settings</a> to continue.
</div>
<div hidden="" id="torrents-pane">
<header>
<h1>Torrent Controls</h1>
<a class="webui-opener" href="#" target="_blank"><img alt="Open Web UI" src="icon.svg"></a> <!--<a class="config-opener" href="#">
<img alt="Settings" src="gear.svg"></a>
<a class="info-opener" href="https://github.com/myfreeweb/transmitter" target="_blank">
<img alt="Extension Info" src="info.svg"></a>-->
</header>
<input id="torrents-search" placeholder="Search…" type="search">
<template id="torrents-tpl">
<ul>
<li>
<div class="torrent-head">
<div class="torrent-name">
</div>
<div class="torrent-speeds">
</div>
</div>
<progress class="torrent-progress" max="100"></progress>
</li>
</ul>
</template>
<ul id="torrents-list">
</ul>
<div id="torrents-error">
</div>
</div>
</div>
</div>
<script src="context.js"></script>
<script src="privacy.js"></script>
<script src="i2pcontrol/i2pcontrol.js"></script>
<script src="info.js"></script>
<script crossorigin="anonymous" src="content.js"></script>
<script src="torrent/popup.js"></script>
<script src="torrent/common.js"></script>
</body>
</html>