mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 21:46:11 +05:00
update
This commit is contained in:
@@ -1,75 +1,80 @@
|
|||||||
// Torrents
|
// Torrents
|
||||||
function addTorrent(link, title, poster, save, done, fail){
|
function addTorrent(link, title, poster, save) {
|
||||||
torrent("add",link,null,title,poster,save,done,fail);
|
torrent("add", link, null, title, poster, save, done, fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTorrent(hash, done, fail){
|
function getTorrent(hash, done, fail) {
|
||||||
torrent("get",null,hash,null,null,null,done,fail);
|
torrent("get", null, hash, null, null, null, done, fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
function remTorrent(hash, done, fail){
|
function remTorrent(hash, done, fail) {
|
||||||
torrent("rem",null,hash,null,null,null,done,fail);
|
torrent("rem", null, hash, null, null, null, done, fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
function listTorrent(done, fail){
|
function listTorrent(done, fail) {
|
||||||
torrent("list",null,null,null,null,null,done,fail);
|
torrent("list", null, null, null, null, null, done, fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
function dropTorrent(hash, done, fail){
|
function dropTorrent(hash, done, fail) {
|
||||||
torrent("drop",null,hash,null,null,null,done,fail);
|
torrent("drop", null, hash, null, null, null, done, fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
function torrent(action, link, hash, title, poster, save, done, fail){
|
function torrent(action, link, hash, title, poster, save, done, fail) {
|
||||||
var req = JSON.stringify({ action:action, link: link, title: title, poster: poster, save_to_db: save});
|
|
||||||
$.post('/torrents',req)
|
|
||||||
.done(function( data ) {
|
var req = JSON.stringify({action: action, link: link, title: title, poster: poster, save_to_db: save});
|
||||||
|
$.post('/torrents', req)
|
||||||
|
.done(function (data) {
|
||||||
if (done)
|
if (done)
|
||||||
done(data);
|
done(data);
|
||||||
})
|
})
|
||||||
.fail(function( data ) {
|
.fail(function (data) {
|
||||||
if (fail)
|
if (fail)
|
||||||
fail(data);
|
fail(data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
function getSettings(done, fail){
|
function getSettings(done, fail) {
|
||||||
sendApi("get",null,"/settings",done,fail);
|
sendApi("get", null, "/settings", done, fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSettings(sets, done, fail){
|
function setSettings(sets, done, fail) {
|
||||||
sendApi("set",sets,"/settings",done,fail);
|
sendApi("set", sets, "/settings", done, fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
// Viewed
|
// Viewed
|
||||||
function listViewed(done, fail){
|
function listViewed(done, fail) {
|
||||||
sendApi("list",null,"/viewed",done,fail);
|
sendApi("list", null, "/viewed", done, fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setViewed(hash, index, done, fail){
|
function setViewed(hash, index, done, fail) {
|
||||||
var obj = {"hash":hash, "file_index":index};
|
var obj = {"hash": hash, "file_index": index};
|
||||||
sendApi("set",obj,"/viewed",done,fail);
|
sendApi("set", obj, "/viewed", done, fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
function remViewed(hash, index, done, fail){
|
function remViewed(hash, index, done, fail) {
|
||||||
var obj = {"hash":hash, "file_index":index};
|
var obj = {"hash": hash, "file_index": index};
|
||||||
sendApi("rem",obj,"/viewed",done,fail);
|
sendApi("rem", obj, "/viewed", done, fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
function sendApi(action, obj, path, done, fail){
|
function sendApi(action, obj, path, done, fail) {
|
||||||
if (obj==null)
|
if (obj == null)
|
||||||
obj={};
|
obj = {};
|
||||||
obj[action]=action;
|
obj[action] = action;
|
||||||
var req = JSON.stringify(obj);
|
var req = JSON.stringify(obj);
|
||||||
$.post(path,req)
|
$.post(path, req)
|
||||||
.done(function( data ) {
|
.done(function (data) {
|
||||||
if (done)
|
if (done)
|
||||||
done(data);
|
done(data);
|
||||||
})
|
})
|
||||||
.fail(function( data ) {
|
.fail(function (data) {
|
||||||
if (fail)
|
if (fail)
|
||||||
fail(data);
|
fail(data);
|
||||||
});
|
});
|
||||||
@@ -78,6 +83,6 @@ function sendApi(action, obj, path, done, fail){
|
|||||||
function humanizeSize(size) {
|
function humanizeSize(size) {
|
||||||
if (typeof size == 'undefined' || size == 0)
|
if (typeof size == 'undefined' || size == 0)
|
||||||
return "";
|
return "";
|
||||||
var i = Math.floor( Math.log(size) / Math.log(1024) );
|
var i = Math.floor(Math.log(size) / Math.log(1024));
|
||||||
return ( size / Math.pow(1024, i) ).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
|
return (size / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
|
||||||
}
|
}
|
||||||
@@ -1,41 +1,155 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<title>TorrServer</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<link href="` + faviconB64 + `" rel="icon" type="image/x-icon">
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width"/>
|
||||||
|
<script src="https://unpkg.com/react@latest/umd/react.development.js" crossorigin="anonymous"></script>
|
||||||
|
<script src="https://unpkg.com/react-dom@latest/umd/react-dom.development.js"></script>
|
||||||
|
<script src="https://unpkg.com/@material-ui/core@latest/umd/material-ui.development.js" crossorigin="anonymous"></script>
|
||||||
|
<script src="https://unpkg.com/babel-standalone@latest/babel.min.js" crossorigin="anonymous"></script>
|
||||||
|
<!-- Fonts to support Material Design -->
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"/>
|
||||||
|
<!-- Icons to support Material Design -->
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"/>
|
||||||
|
|
||||||
<script src="https://code.jquery.com/jquery-3.5.1.min.js" crossorigin="anonymous"></script>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/2.5.4/umd/popper.min.js" crossorigin="anonymous"></script>
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
|
|
||||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
|
|
||||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.bundle.min.js" integrity="sha384-LtrjvnR4Twt/qOuYxE721u19sVFLVSA4hf/rRt6PrZTmiPltdZcI7q7PXQBYTKyf" crossorigin="anonymous"></script>
|
|
||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.11.0/underscore-min.js"></script>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.2/angular.min.js"></script>
|
|
||||||
|
|
||||||
<title>TorrServer ` + version.Version + `</title>
|
|
||||||
</head>
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
|
||||||
<body ng-app="app">
|
<script type="text/babel">
|
||||||
<link rel="stylesheet" href="/main.css">
|
|
||||||
<script src="/api.js"></script>
|
|
||||||
<script src="/main.js"></script>
|
|
||||||
|
|
||||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
class App extends React.Component {
|
||||||
<div class="navbar-nav">
|
constructor(props) {
|
||||||
<a href="#" class="nav-item nav-link torrents">Torrents</a>
|
super(props);
|
||||||
<a href="#" class="nav-item nav-link settings">Settings</a>
|
this.state = {
|
||||||
<a href="#" class="nav-item nav-link cache">Cache</a>
|
error: null,
|
||||||
<a href="#" class="nav-item nav-link about">About</a>
|
version: "",
|
||||||
</div>
|
};
|
||||||
</nav>
|
}
|
||||||
|
|
||||||
<div id="torrents"></div>
|
componentDidMount() {
|
||||||
|
fetch("/echo")
|
||||||
|
.then(res => res.text())
|
||||||
|
.then(
|
||||||
|
(txt) => {
|
||||||
|
this.setState({
|
||||||
|
version: txt
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate() {
|
||||||
|
document.title = 'TorrServer ' + this.state.version;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Container maxWidth="sm">
|
||||||
|
<div style={'marginTop: 24'}>
|
||||||
|
<Typography variant="h4" component="h1" gutterBottom>
|
||||||
|
CDN v4-beta example
|
||||||
|
</Typography>
|
||||||
|
<ProTip/>
|
||||||
|
<Copyright/>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TorrentList extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {date: new Date()};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.timerID = setInterval(
|
||||||
|
() => this.tick(),
|
||||||
|
1000
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
clearInterval(this.timerID);
|
||||||
|
}
|
||||||
|
|
||||||
|
tick() {
|
||||||
|
this.setState({
|
||||||
|
date: new Date()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>Привет, мир!</h1>
|
||||||
|
<h2>Сейчас {this.state.date.toLocaleTimeString()}.</h2>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const {
|
||||||
|
colors,
|
||||||
|
CssBaseline,
|
||||||
|
ThemeProvider,
|
||||||
|
Typography,
|
||||||
|
Container,
|
||||||
|
makeStyles,
|
||||||
|
createMuiTheme,
|
||||||
|
Box,
|
||||||
|
SvgIcon,
|
||||||
|
Link,
|
||||||
|
} = MaterialUI;
|
||||||
|
|
||||||
|
// Create a theme instance.
|
||||||
|
const theme = createMuiTheme({
|
||||||
|
palette: {
|
||||||
|
primary: {
|
||||||
|
main: '#556cd6',
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
main: '#19857b',
|
||||||
|
},
|
||||||
|
error: {
|
||||||
|
main: colors.red.A400,
|
||||||
|
},
|
||||||
|
background: {
|
||||||
|
default: '#fff',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function LightBulbIcon(props) {
|
||||||
|
return (
|
||||||
|
<SvgIcon {...props}>
|
||||||
|
<path d="M9 21c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-1H9v1zm3-19C8.14 2 5 5.14 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.86-3.14-7-7-7zm2.85 11.1l-.85.6V16h-4v-2.3l-.85-.6C7.8 12.16 7 10.63 7 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 1.63-.8 3.16-2.15 4.1z"/>
|
||||||
|
</SvgIcon>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const useStyles = makeStyles(theme => ({
|
||||||
|
root: {
|
||||||
|
margin: theme.spacing(6, 0, 3),
|
||||||
|
},
|
||||||
|
lightBulb: {
|
||||||
|
verticalAlign: 'middle',
|
||||||
|
marginRight: theme.spacing(1),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<ThemeProvider theme={theme}>
|
||||||
|
<CssBaseline/>
|
||||||
|
<App/>
|
||||||
|
</ThemeProvider>,
|
||||||
|
document.getElementById('root')
|
||||||
|
);
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -1,84 +1,153 @@
|
|||||||
package template
|
package template
|
||||||
|
|
||||||
import (
|
|
||||||
"server/version"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (t *Template) parseMainPage() {
|
func (t *Template) parseMainPage() {
|
||||||
t.parsePage("mainPage", mainPage)
|
t.parsePage("mainPage", mainPage)
|
||||||
}
|
}
|
||||||
|
|
||||||
const mainPage = `
|
const mainPage = `
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html>
|
||||||
` + header + `
|
<head>
|
||||||
<body>
|
<title>TorrServer</title>
|
||||||
<p> TorrServer ` + version.Version + `</p>
|
|
||||||
|
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width"/>
|
||||||
|
<script src="https://unpkg.com/react@latest/umd/react.development.js" crossorigin="anonymous"></script>
|
||||||
|
<script src="https://unpkg.com/react-dom@latest/umd/react-dom.development.js"></script>
|
||||||
|
<script src="https://unpkg.com/@material-ui/core@latest/umd/material-ui.development.js" crossorigin="anonymous"></script>
|
||||||
|
<script src="https://unpkg.com/babel-standalone@latest/babel.min.js" crossorigin="anonymous"></script>
|
||||||
|
<!-- Fonts to support Material Design -->
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"/>
|
||||||
|
<!-- Icons to support Material Design -->
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"/>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
|
||||||
|
<script type="text/babel">
|
||||||
|
|
||||||
|
class App extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
error: null,
|
||||||
|
version: "",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
fetch("/echo")
|
||||||
|
.then(res => res.text())
|
||||||
|
.then(
|
||||||
|
(txt) => {
|
||||||
|
this.setState({
|
||||||
|
version: txt
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate() {
|
||||||
|
document.title = 'TorrServer ' + this.state.version;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Torrent/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TorrentList extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {date: new Date()};
|
||||||
|
}
|
||||||
|
componentDidMount() {
|
||||||
|
this.timerID = setInterval(
|
||||||
|
() => this.tick(),
|
||||||
|
1000
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
clearInterval(this.timerID);
|
||||||
|
}
|
||||||
|
|
||||||
|
tick() {
|
||||||
|
this.setState({
|
||||||
|
date: new Date()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>Привет, мир!</h1>
|
||||||
|
<h2>Сейчас {this.state.date.toLocaleTimeString()}.</h2>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const {
|
||||||
|
colors,
|
||||||
|
CssBaseline,
|
||||||
|
ThemeProvider,
|
||||||
|
Typography,
|
||||||
|
Container,
|
||||||
|
makeStyles,
|
||||||
|
createMuiTheme,
|
||||||
|
Box,
|
||||||
|
SvgIcon,
|
||||||
|
Link,
|
||||||
|
} = MaterialUI;
|
||||||
|
|
||||||
|
// Create a theme instance.
|
||||||
|
const theme = createMuiTheme({
|
||||||
|
palette: {
|
||||||
|
primary: {
|
||||||
|
main: '#556cd6',
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
main: '#19857b',
|
||||||
|
},
|
||||||
|
error: {
|
||||||
|
main: colors.red.A400,
|
||||||
|
},
|
||||||
|
background: {
|
||||||
|
default: '#fff',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function LightBulbIcon(props) {
|
||||||
|
return (
|
||||||
|
<SvgIcon {...props}>
|
||||||
|
<path d="M9 21c0 .55.45 1 1 1h4c.55 0 1-.45 1-1v-1H9v1zm3-19C8.14 2 5 5.14 5 9c0 2.38 1.19 4.47 3 5.74V17c0 .55.45 1 1 1h6c.55 0 1-.45 1-1v-2.26c1.81-1.27 3-3.36 3-5.74 0-3.86-3.14-7-7-7zm2.85 11.1l-.85.6V16h-4v-2.3l-.85-.6C7.8 12.16 7 10.63 7 9c0-2.76 2.24-5 5-5s5 2.24 5 5c0 1.63-.8 3.16-2.15 4.1z"/>
|
||||||
|
</SvgIcon>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const useStyles = makeStyles(theme => ({
|
||||||
|
root: {
|
||||||
|
margin: theme.spacing(6, 0, 3),
|
||||||
|
},
|
||||||
|
lightBulb: {
|
||||||
|
verticalAlign: 'middle',
|
||||||
|
marginRight: theme.spacing(1),
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<App/>,
|
||||||
|
document.getElementById('root')
|
||||||
|
);
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
`
|
`
|
||||||
|
|
||||||
const tmp = `
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.wrap {
|
|
||||||
white-space: normal;
|
|
||||||
word-wrap: break-word;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
.content {
|
|
||||||
margin: 1%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
|
||||||
<span class="navbar-brand mx-auto">
|
|
||||||
TorrServer ` + version.Version + `
|
|
||||||
</span>
|
|
||||||
</nav>
|
|
||||||
<div class="content">
|
|
||||||
<div>
|
|
||||||
<label for="magnet">Добавить торрент: </label>
|
|
||||||
<input id="magnet" class="w-100" autocomplete="off">
|
|
||||||
</div>
|
|
||||||
<div class="btn-group d-flex" role="group">
|
|
||||||
<button id="buttonAdd" class="btn w-100" onclick="addTorr()"><i class="fas fa-plus"></i> Добавить</button>
|
|
||||||
<button id="buttonUpload" class="btn w-100"><i class="fas fa-file-upload"></i> Загрузить файл</button>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<div>
|
|
||||||
<a href="/torrent/playlist.m3u" rel="external" class="btn btn-primary w-100" role="button" ><i class="fas fa-th-list"></i> Плейлист всех торрентов</a>
|
|
||||||
</div>
|
|
||||||
<br>
|
|
||||||
<h3>Торренты: </h3>
|
|
||||||
<div id="torrents"></div>
|
|
||||||
<br>
|
|
||||||
<div class="btn-group-vertical d-flex" role="group">
|
|
||||||
<a href="/settings" rel="external" class="btn btn-primary w-100" role="button"><i class="fas fa-cog"></i> Настройки</a>
|
|
||||||
<a href="/cache" rel="external" class="btn btn-primary w-100" role="button"><i class="fas fa-info"></i> Кэш</a>
|
|
||||||
<button id="buttonShutdown" class="btn btn-primary w-100" onclick="shutdown()"><i class="fas fa-power-off"></i> Закрыть сервер</button>
|
|
||||||
</div>
|
|
||||||
<form id="uploadForm" style="display:none" action="/torrent/upload" method="post">
|
|
||||||
<input type="file" id="filesUpload" style="display:none" multiple onchange="uploadTorrent()" name="files"/>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<footer class="page-footer navbar-dark bg-dark">
|
|
||||||
<span class="navbar-brand d-flex justify-content-center">
|
|
||||||
<a rel="external" style="text-decoration: none;" href="/about">Описание</a>
|
|
||||||
</span>
|
|
||||||
</footer>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
<script id="contactTemplate" type="text/template">
|
|
||||||
<img src="<%= photo %>" alt="<%= name %>" />
|
|
||||||
<h1><%= name %><span><%= type %></span></h1>
|
|
||||||
<div><%= address %></div>
|
|
||||||
<dl>
|
|
||||||
<dt>Tel:</dt><dd><%= tel %></dd>
|
|
||||||
<dt>Email:</dt><dd><a href="mailto:<%= email %>"><%= email %></a></dd>
|
|
||||||
</dl>
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
`
|
|
||||||
|
|||||||
Reference in New Issue
Block a user