mirror of
https://github.com/YGGverse/YGGtracker.git
synced 2025-01-31 00:54:21 +00:00
initial commit
This commit is contained in:
parent
6e03cabcb1
commit
b6082d6eec
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
/.vscode/
|
||||
/vendor/
|
||||
|
||||
/database/yggtracker.mwb.bak
|
||||
/src/config/app.php
|
||||
|
||||
/composer.lock
|
104
README.md
104
README.md
@ -1 +1,103 @@
|
||||
# YGGtracker
|
||||
# YGGtracker
|
||||
|
||||
BitTorrent Catalog for Yggdrasil ecosystem
|
||||
|
||||
YGGtracker uses [Yggdrasil](https://github.com/yggdrasil-network/yggdrasil-go) IPv6 addresses to identify users without registration.
|
||||
|
||||
#### Online instances
|
||||
|
||||
* [http://[201:23b4:991a:634d:8359:4521:5576:15b7]/yggtracker](http://[201:23b4:991a:634d:8359:4521:5576:15b7]/yggtracker/)
|
||||
* [http://94.140.114.241/yggtracker](http://94.140.114.241/yggtracker/)
|
||||
|
||||
#### Trackers
|
||||
|
||||
* `http://[201:23b4:991a:634d:8359:4521:5576:15b7]/yggtracker/announce` [stats](http://[201:23b4:991a:634d:8359:4521:5576:15b7]/yggtracker/stats)
|
||||
* `http://[200:1e2f:e608:eb3a:2bf:1e62:87ba:e2f7]/announce` [stats](http://[200:1e2f:e608:eb3a:2bf:1e62:87ba:e2f7]/stats)
|
||||
|
||||
#### Requirements
|
||||
|
||||
```
|
||||
php8^
|
||||
php-pdo
|
||||
php-mysql
|
||||
sphinxsearch
|
||||
```
|
||||
#### Installation
|
||||
|
||||
* `git clone https://github.com/YGGverse/YGGtracker.git`
|
||||
* `cd YGGtracker`
|
||||
* `composer update`
|
||||
|
||||
#### Setup
|
||||
* Server configuration `/example/environment`
|
||||
* The web root dir is `/src/public`
|
||||
* Deploy the database using [MySQL Workbench](https://www.mysql.com/products/workbench) project presented in the `/database` folder
|
||||
* Install [Sphinx Search Server](https://sphinxsearch.com)
|
||||
* Configuration examples presented at `/config` folder
|
||||
* Set up the `/src/crontab` by following [example](https://github.com/YGGverse/YGGtracker/blob/main/%20example/environment%20/crontab)
|
||||
|
||||
#### Contribute
|
||||
|
||||
Please make new branch for each PR
|
||||
|
||||
```
|
||||
git checkout main
|
||||
git checkout -b my-pr-branch-name
|
||||
```
|
||||
|
||||
#### Roadmap
|
||||
|
||||
* [ ] Magnet
|
||||
+ [x] Options
|
||||
+ [x] Public
|
||||
+ [x] Sensitive
|
||||
+ [x] Comments
|
||||
+ [ ] Features
|
||||
+ [x] Stars
|
||||
+ [x] Downloads
|
||||
+ [ ] Comments
|
||||
+ [ ] Views
|
||||
+ [ ] Info page
|
||||
|
||||
* [ ] User
|
||||
+ [ ] Magnets
|
||||
+ [ ] Downloads
|
||||
+ [ ] Stars
|
||||
+ [ ] Following
|
||||
+ [ ] Followers
|
||||
+ [ ] Profile menu
|
||||
+ [ ] Magnets
|
||||
+ [ ] Downloads
|
||||
+ [ ] Stars
|
||||
+ [ ] Comments
|
||||
|
||||
* [x] Other
|
||||
+ [x] RSS
|
||||
+ [x] Moderation
|
||||
|
||||
#### Donate to contributors
|
||||
|
||||
* @d47081: [BTC](https://www.blockchain.com/explorer/addresses/btc/bc1qngdf2kwty6djjqpk0ynkpq9wmlrmtm7e0c534y) | [LTC](https://live.blockcypher.com/ltc/address/LUSiqzKsfB1vBLvpu515DZktG9ioKqLyj7) | [XMR](835gSR1Uvka19gnWPkU2pyRozZugRZSPHDuFL6YajaAqjEtMwSPr4jafM8idRuBWo7AWD3pwFQSYRMRW9XezqrK4BEXBgXE) | [ZEPH](ZEPHsADHXqnhfWhXrRcXnyBQMucE3NM7Ng5ZVB99XwA38PTnbjLKpCwcQVgoie8EJuWozKgBiTmDFW4iY7fNEgSEWyAy4dotqtX) | [DOGE](https://dogechain.info/address/D5Sez493ibLqTpyB3xwQUspZvJ1cxEdRNQ) | Support our server by order [Linux VPS](https://www.yourserver.se/portal/aff.php?aff=610)
|
||||
|
||||
#### License
|
||||
|
||||
* Engine sources [MIT License](https://github.com/YGGverse/YGGtracker/blob/main/LICENSE)
|
||||
|
||||
#### Components
|
||||
|
||||
[Icons](https://icons.getbootstrap.com)
|
||||
|
||||
#### Feedback
|
||||
|
||||
Feel free to [share](https://github.com/YGGverse/YGGtracker/issues) your ideas and bug reports!
|
||||
|
||||
#### Community
|
||||
|
||||
* [Mastodon](https://mastodon.social/@YGGverse)
|
||||
* [[matrix]](https://matrix.to/#/#YGGtracker:matrix.org)
|
||||
|
||||
#### See also
|
||||
|
||||
* [YGGo - YGGo! Distributed Web Search Engine ](https://github.com/YGGverse/YGGo)
|
||||
* [YGGwave ~ The Radio Catalog](https://github.com/YGGverse/YGGwave)
|
||||
* [YGGstate - Yggdrasil Network Explorer](https://github.com/YGGverse/YGGstate)
|
21
composer.json
Normal file
21
composer.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "yggverse/yggtracker",
|
||||
"description": "Public BitTorrent tracker for Yggdrasil network",
|
||||
"type": "library",
|
||||
"require": {
|
||||
"php": "^8.1",
|
||||
"yggverse/parser": ">=0.2.0"
|
||||
},
|
||||
"license": "MIT",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Yggverse\\Yggtracker\\": "src/"
|
||||
}
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "YGGverse"
|
||||
}
|
||||
],
|
||||
"minimum-stability": "alpha"
|
||||
}
|
BIN
database/yggtracker.mwb
Normal file
BIN
database/yggtracker.mwb
Normal file
Binary file not shown.
4
example/environment /crontab
Normal file
4
example/environment /crontab
Normal file
@ -0,0 +1,4 @@
|
||||
@reboot searchd
|
||||
@reboot indexer --all --rotate
|
||||
|
||||
* * * * * indexer magnet --rotate
|
52
example/environment /sphinx.conf
Normal file
52
example/environment /sphinx.conf
Normal file
@ -0,0 +1,52 @@
|
||||
source yggtracker
|
||||
{
|
||||
type = mysql
|
||||
|
||||
sql_port = 3306
|
||||
sql_host = localhost
|
||||
sql_user =
|
||||
sql_pass =
|
||||
sql_db =
|
||||
}
|
||||
|
||||
source magnet : yggtracker
|
||||
{
|
||||
sql_query = \
|
||||
SELECT `magnet`.`timeAdded`, \
|
||||
`magnet`.`timeUpdated`, \
|
||||
`magnet`.`magnetId`, \
|
||||
`magnet`.`metaTitle`, \
|
||||
`magnet`.`metaDescription`, \
|
||||
`magnet`.`dn`, \
|
||||
(SELECT GROUP_CONCAT(DISTINCT `keywordTopic`.`value`) \
|
||||
FROM `keywordTopic` \
|
||||
JOIN `magnetToKeywordTopic` ON (`magnetToKeywordTopic`.`magnetId` = `magnet`.`magnetId`) \
|
||||
WHERE `keywordTopic`.`keywordTopicId` = `magnetToKeywordTopic`.`keywordTopicId`) AS `keywords`, \
|
||||
(SELECT GROUP_CONCAT(DISTINCT `magnetComment`.`value`) \
|
||||
FROM `magnetComment` \
|
||||
WHERE `magnetComment`.`magnetId` = `magnet`.`magnetId`) AS `comments` \
|
||||
FROM `magnet`\
|
||||
|
||||
sql_attr_uint = magnetId
|
||||
}
|
||||
|
||||
index magnet
|
||||
{
|
||||
source = magnet
|
||||
path = /var/lib/sphinxsearch/data/magnet
|
||||
|
||||
morphology = stem_cz, stem_ar, lemmatize_de_all, lemmatize_ru_all, lemmatize_en_all # stem_enru
|
||||
|
||||
min_word_len = 2
|
||||
min_prefix_len = 2
|
||||
|
||||
html_strip = 1
|
||||
|
||||
index_exact_words = 1
|
||||
}
|
||||
|
||||
indexer
|
||||
{
|
||||
mem_limit = 256M
|
||||
lemmatizer_cache = 256M
|
||||
}
|
102
src/config/app.php.example
Normal file
102
src/config/app.php.example
Normal file
@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 YGGverse
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* 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 OR COPYRIGHT HOLDERS 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.
|
||||
*
|
||||
* Default configuration file example
|
||||
* Production name: app.php
|
||||
*
|
||||
* Project home page
|
||||
* https://github.com/YGGverse/YGGtracker
|
||||
*
|
||||
* Get support
|
||||
* https://github.com/YGGverse/YGGtracker/issues
|
||||
*/
|
||||
|
||||
// PHP
|
||||
declare(strict_types=1);
|
||||
|
||||
// Debug
|
||||
ini_set('display_errors', '1');
|
||||
ini_set('display_startup_errors', '1');
|
||||
error_reporting(E_ALL);
|
||||
|
||||
// Database
|
||||
define('DB_PORT', 3306);
|
||||
define('DB_HOST', 'localhost');
|
||||
define('DB_NAME', '');
|
||||
define('DB_USERNAME', '');
|
||||
define('DB_PASSWORD', '');
|
||||
|
||||
// Sphinx
|
||||
define('SPHINX_HOST', '127.0.0.1');
|
||||
define('SPHINX_PORT', 9306);
|
||||
|
||||
// Webapp
|
||||
define('WEBSITE_URL', '');
|
||||
define('WEBSITE_NAME', 'YGGtracker');
|
||||
define('WEBSITE_CSS_VERSION', 1);
|
||||
|
||||
define('WEBSITE_PAGINATION_LIMIT', 20);
|
||||
|
||||
define('WEBSITE_MAGNET_SHORT_META_DESCRIPTION_LENGTH', 480);
|
||||
|
||||
// Moderation
|
||||
define('MODERATOR_IP_LIST', (array)
|
||||
[
|
||||
'127.0.0.1', // at least one IP/moderator required
|
||||
// ...
|
||||
]
|
||||
);
|
||||
|
||||
// User
|
||||
define('USER_DEFAULT_APPROVED', false);
|
||||
|
||||
// Magnet
|
||||
define('MAGNET_DEFAULT_APPROVED', USER_DEFAULT_APPROVED);
|
||||
define('MAGNET_DEFAULT_PUBLIC', false);
|
||||
define('MAGNET_DEFAULT_COMMENTS', true);
|
||||
define('MAGNET_DEFAULT_SENSITIVE', false);
|
||||
|
||||
define('MAGNET_META_TITLE_MIN_LENGTH', 10);
|
||||
define('MAGNET_META_DESCRIPTION_MIN_LENGTH', 0);
|
||||
|
||||
// Trackers
|
||||
define('TRACKER_LINKS', (object)
|
||||
[
|
||||
'Tracker 1' => (object)
|
||||
[
|
||||
'announce' => 'http://[201:23b4:991a:634d:8359:4521:5576:15b7]/yggtracker/announce',
|
||||
'stats' => 'http://[201:23b4:991a:634d:8359:4521:5576:15b7]/yggtracker/stats',
|
||||
],
|
||||
'Tracker 2' => (object)
|
||||
[
|
||||
'announce' => 'http://[200:1e2f:e608:eb3a:2bf:1e62:87ba:e2f7]/announce',
|
||||
'stats' => 'http://[200:1e2f:e608:eb3a:2bf:1e62:87ba:e2f7]/stats',
|
||||
],
|
||||
// ...
|
||||
]
|
||||
);
|
||||
|
||||
// Yggdrasil
|
||||
define('YGGDRASIL_URL_REGEX', '/^0{0,1}[2-3][a-f0-9]{0,2}:/'); // thanks to @ygguser (https://github.com/YGGverse/YGGo/issues/1#issuecomment-1498182228 )
|
1032
src/library/database.php
Normal file
1032
src/library/database.php
Normal file
File diff suppressed because it is too large
Load Diff
49
src/library/sphinx.php
Normal file
49
src/library/sphinx.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
class Sphinx {
|
||||
|
||||
private $_sphinx;
|
||||
|
||||
public function __construct(string $host, int $port) {
|
||||
|
||||
$this->_sphinx = new PDO('mysql:host=' . $host . ';port=' . $port . ';charset=utf8', false, false, [PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8']);
|
||||
$this->_sphinx->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$this->_sphinx->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
|
||||
}
|
||||
|
||||
public function searchMagnetsTotal(string $keyword) {
|
||||
|
||||
$query = $this->_sphinx->prepare('SELECT COUNT(*) AS `total` FROM `magnet` WHERE MATCH(?)');
|
||||
|
||||
$query->execute(
|
||||
[
|
||||
$keyword
|
||||
]
|
||||
);
|
||||
|
||||
return $query->fetch()->total;
|
||||
}
|
||||
|
||||
public function searchMagnets(string $keyword, int $start, int $limit, int $maxMatches) {
|
||||
|
||||
$query = $this->_sphinx->prepare("SELECT *
|
||||
|
||||
FROM `magnet`
|
||||
|
||||
WHERE MATCH(?)
|
||||
|
||||
ORDER BY `magnetId` DESC, WEIGHT() DESC
|
||||
|
||||
LIMIT " . (int) ($start >= $maxMatches ? ($maxMatches > 0 ? $maxMatches - 1 : 0) : $start) . "," . (int) $limit . "
|
||||
|
||||
OPTION `max_matches`=" . (int) ($maxMatches >= 1 ? $maxMatches : 1));
|
||||
|
||||
$query->execute(
|
||||
[
|
||||
$keyword
|
||||
]
|
||||
);
|
||||
|
||||
return $query->fetchAll();
|
||||
}
|
||||
}
|
45
src/library/time.php
Normal file
45
src/library/time.php
Normal file
@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
class Time
|
||||
{
|
||||
public static function ago(int $time)
|
||||
{
|
||||
$diff = time() - $time;
|
||||
|
||||
if ($diff < 1)
|
||||
{
|
||||
return _('now');
|
||||
}
|
||||
|
||||
$values =
|
||||
[
|
||||
365 * 24 * 60 * 60 => _('year'),
|
||||
30 * 24 * 60 * 60 => _('month'),
|
||||
24 * 60 * 60 => _('day'),
|
||||
60 * 60 => _('hour'),
|
||||
60 => _('minute'),
|
||||
1 => _('second')
|
||||
];
|
||||
|
||||
$plural = [
|
||||
_('year') => _('years'),
|
||||
_('month') => _('months'),
|
||||
_('day') => _('days'),
|
||||
_('hour') => _('hours'),
|
||||
_('minute') => _('minutes'),
|
||||
_('second') => _('seconds')
|
||||
];
|
||||
|
||||
foreach ($values as $key => $value)
|
||||
{
|
||||
$result = $diff / $key;
|
||||
|
||||
if ($result >= 1)
|
||||
{
|
||||
$round = round($result);
|
||||
|
||||
return sprintf('%s %s ago', $round, $round > 1 ? $plural[$value] : $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
442
src/public/action.php
Normal file
442
src/public/action.php
Normal file
@ -0,0 +1,442 @@
|
||||
<?php
|
||||
|
||||
// Load dependencies
|
||||
require_once (__DIR__ . '/../config/app.php');
|
||||
require_once (__DIR__ . '/../library/database.php');
|
||||
require_once (__DIR__ . '/../../vendor/autoload.php');
|
||||
|
||||
// Connect database
|
||||
try {
|
||||
|
||||
$db = new Database(DB_HOST, DB_PORT, DB_NAME, DB_USERNAME, DB_PASSWORD);
|
||||
|
||||
} catch (Exception $e) {
|
||||
|
||||
var_dump($e);
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
// Define response
|
||||
$response = (object)
|
||||
[
|
||||
'success' => true,
|
||||
'message' => _('Internal server error')
|
||||
];
|
||||
|
||||
// Begin action request
|
||||
switch (isset($_GET['target']) ? urldecode($_GET['target']) : false)
|
||||
{
|
||||
case 'comment':
|
||||
|
||||
break;
|
||||
|
||||
case 'star':
|
||||
|
||||
// Yggdrasil connections only
|
||||
if (!preg_match(YGGDRASIL_URL_REGEX, $_SERVER['REMOTE_ADDR']))
|
||||
{
|
||||
$response->success = false;
|
||||
$response->message = _('Yggdrasil connection required for this action');
|
||||
}
|
||||
|
||||
// Init session
|
||||
else if (!$userId = $db->initUserId($_SERVER['REMOTE_ADDR'], USER_DEFAULT_APPROVED, time()))
|
||||
{
|
||||
$response->success = false;
|
||||
$response->message = _('Could not init user session');
|
||||
}
|
||||
|
||||
// Magnet exists
|
||||
else if (!$magnet = $db->getMagnet(isset($_GET['magnetId']) && $_GET['magnetId'] > 0 ? (int) $_GET['magnetId'] : 0))
|
||||
{
|
||||
$response->success = false;
|
||||
$response->message = _('Requested magnet not found');
|
||||
}
|
||||
|
||||
// Access allowed
|
||||
else if (!($_SERVER['REMOTE_ADDR'] == $db->getUser($magnet->userId)->address || in_array($_SERVER['REMOTE_ADDR'], MODERATOR_IP_LIST) || ($magnet->public && $magnet->approved))) {
|
||||
|
||||
$response->success = false;
|
||||
$response->message = _('Magnet not available for this action');
|
||||
}
|
||||
|
||||
// Validate callback
|
||||
else if (empty($_GET['callback']))
|
||||
{
|
||||
$response->success = false;
|
||||
$response->message = _('Callback required');
|
||||
}
|
||||
|
||||
// Validate base64
|
||||
else if (!$callback = (string) @base64_decode($_GET['callback']))
|
||||
{
|
||||
$response->success = false;
|
||||
$response->message = _('Invalid callback encoding');
|
||||
}
|
||||
|
||||
// Request valid
|
||||
else
|
||||
{
|
||||
// Star exists, trigger delete
|
||||
if ($db->findMagnetStarsTotalByUserId($magnet->magnetId, $userId))
|
||||
{
|
||||
$db->deleteMagnetStarByUserId($magnet->magnetId, $userId);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Star not exists, trigger add
|
||||
$db->addMagnetStar($magnet->magnetId, $userId, time());
|
||||
}
|
||||
|
||||
// Redirect to edit page
|
||||
header(
|
||||
sprintf('Location: %s', $callback)
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'download':
|
||||
|
||||
// Yggdrasil connections only
|
||||
if (!preg_match(YGGDRASIL_URL_REGEX, $_SERVER['REMOTE_ADDR']))
|
||||
{
|
||||
$response->success = false;
|
||||
$response->message = _('Yggdrasil connection required for this action');
|
||||
}
|
||||
|
||||
// Init session
|
||||
else if (!$userId = $db->initUserId($_SERVER['REMOTE_ADDR'], USER_DEFAULT_APPROVED, time()))
|
||||
{
|
||||
$response->success = false;
|
||||
$response->message = _('Could not init user session');
|
||||
}
|
||||
|
||||
// Magnet exists
|
||||
else if (!$magnet = $db->getMagnet(isset($_GET['magnetId']) && $_GET['magnetId'] > 0 ? (int) $_GET['magnetId'] : 0))
|
||||
{
|
||||
$response->success = false;
|
||||
$response->message = _('Requested magnet not found');
|
||||
}
|
||||
|
||||
// Access allowed
|
||||
else if (!($_SERVER['REMOTE_ADDR'] == $db->getUser($magnet->userId)->address || in_array($_SERVER['REMOTE_ADDR'], MODERATOR_IP_LIST) || ($magnet->public && $magnet->approved))) {
|
||||
|
||||
$response->success = false;
|
||||
$response->message = _('Magnet not available for this action');
|
||||
}
|
||||
|
||||
// Request valid
|
||||
else
|
||||
{
|
||||
// Download exists, trigger delete
|
||||
if (!$db->findMagnetDownloadsTotalByUserId($magnet->magnetId, $userId))
|
||||
{
|
||||
// Download not exists, add new record
|
||||
$db->addMagnetDownload($magnet->magnetId, $userId, time());
|
||||
}
|
||||
|
||||
// Build magnet link
|
||||
$link = [];
|
||||
|
||||
/// Exact Topic
|
||||
$link[] = sprintf('magnet:?xt=%s', $magnet->xt);
|
||||
|
||||
/// Display Name
|
||||
$link[] = sprintf('dn=%s', urlencode($magnet->dn));
|
||||
|
||||
// Keyword Topic
|
||||
$kt = [];
|
||||
|
||||
foreach ($db->findKeywordTopicByMagnetId($magnet->magnetId) as $result)
|
||||
{
|
||||
$kt[] = urlencode($db->getKeywordTopic($result->keywordTopicId)->value);
|
||||
}
|
||||
|
||||
$link[] = sprintf('kt=%s', implode('+', $kt));
|
||||
|
||||
/// Address Tracker
|
||||
foreach ($db->findAddressTrackerByMagnetId($magnet->magnetId) as $result)
|
||||
{
|
||||
$addressTracker = $db->getAddressTracker($result->addressTrackerId);
|
||||
|
||||
$scheme = $db->getScheme($addressTracker->schemeId);
|
||||
$host = $db->getHost($addressTracker->hostId);
|
||||
$port = $db->getPort($addressTracker->portId);
|
||||
$uri = $db->getUri($addressTracker->uriId);
|
||||
|
||||
$link[] = sprintf('tr=%s', urlencode($port->value ? sprintf('%s://%s:%s%s', $scheme->value,
|
||||
$host->value,
|
||||
$port->value,
|
||||
$uri->value) : sprintf('%s://%s%s', $scheme->value,
|
||||
$host->value,
|
||||
$uri->value)));
|
||||
}
|
||||
|
||||
/// Acceptable Source
|
||||
foreach ($db->findAcceptableSourceByMagnetId($magnet->magnetId) as $result)
|
||||
{
|
||||
$acceptableSource = $db->getAcceptableSource($result->acceptableSourceId);
|
||||
|
||||
$scheme = $db->getScheme($acceptableSource->schemeId);
|
||||
$host = $db->getHost($acceptableSource->hostId);
|
||||
$port = $db->getPort($acceptableSource->portId);
|
||||
$uri = $db->getUri($acceptableSource->uriId);
|
||||
|
||||
$link[] = sprintf('as=%s', urlencode($port->value ? sprintf('%s://%s:%s%s', $scheme->value,
|
||||
$host->value,
|
||||
$port->value,
|
||||
$uri->value) : sprintf('%s://%s%s', $scheme->value,
|
||||
$host->value,
|
||||
$uri->value)));
|
||||
}
|
||||
|
||||
/// Exact Source
|
||||
foreach ($db->findExactSourceByMagnetId($magnet->magnetId) as $result)
|
||||
{
|
||||
$eXactSource = $db->getExactSource($result->eXactSourceId);
|
||||
|
||||
$scheme = $db->getScheme($eXactSource->schemeId);
|
||||
$host = $db->getHost($eXactSource->hostId);
|
||||
$port = $db->getPort($eXactSource->portId);
|
||||
$uri = $db->getUri($eXactSource->uriId);
|
||||
|
||||
$link[] = sprintf('xs=%s', urlencode($port->value ? sprintf('%s://%s:%s%s', $scheme->value,
|
||||
$host->value,
|
||||
$port->value,
|
||||
$uri->value) : sprintf('%s://%s%s', $scheme->value,
|
||||
$host->value,
|
||||
$uri->value)));
|
||||
}
|
||||
|
||||
// Redirect to edit page
|
||||
header(
|
||||
sprintf('Location: %s', implode('&', $link))
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'new':
|
||||
|
||||
// Yggdrasil connections only
|
||||
if (!preg_match(YGGDRASIL_URL_REGEX, $_SERVER['REMOTE_ADDR']))
|
||||
{
|
||||
$response->success = false;
|
||||
$response->message = _('Yggdrasil connection required for this action');
|
||||
}
|
||||
|
||||
// Init session
|
||||
else if (!$userId = $db->initUserId($_SERVER['REMOTE_ADDR'], USER_DEFAULT_APPROVED, time()))
|
||||
{
|
||||
$response->success = false;
|
||||
$response->message = _('Could not init user session');
|
||||
}
|
||||
|
||||
// Validate link
|
||||
if (empty($_GET['magnet']))
|
||||
{
|
||||
$response->success = false;
|
||||
$response->message = _('Link required');
|
||||
}
|
||||
|
||||
// Validate base64
|
||||
else if (!$link = (string) @base64_decode($_GET['magnet']))
|
||||
{
|
||||
$response->success = false;
|
||||
$response->message = _('Invalid link encoding');
|
||||
}
|
||||
|
||||
// Validate magnet
|
||||
else if (!$magnet = Yggverse\Parser\Magnet::parse($link))
|
||||
{
|
||||
$response->success = false;
|
||||
$response->message = _('Invalid magnet link');
|
||||
}
|
||||
|
||||
// Request valid
|
||||
else
|
||||
{
|
||||
// Begin magnet registration
|
||||
try
|
||||
{
|
||||
$db->beginTransaction();
|
||||
|
||||
// Init magnet
|
||||
if (Yggverse\Parser\Urn::parse($magnet->xt))
|
||||
{
|
||||
if ($magnetId = $db->initMagnetId($userId,
|
||||
strip_tags($magnet->xt),
|
||||
strip_tags($magnet->xl),
|
||||
strip_tags($magnet->dn),
|
||||
$link,
|
||||
MAGNET_DEFAULT_PUBLIC,
|
||||
MAGNET_DEFAULT_COMMENTS,
|
||||
MAGNET_DEFAULT_SENSITIVE,
|
||||
MAGNET_DEFAULT_APPROVED,
|
||||
time()))
|
||||
{
|
||||
foreach ($magnet as $key => $value)
|
||||
{
|
||||
switch ($key)
|
||||
{
|
||||
case 'tr':
|
||||
foreach ($value as $tr)
|
||||
{
|
||||
if ($url = Yggverse\Parser\Url::parse($tr))
|
||||
{
|
||||
$db->initMagnetToAddressTrackerId(
|
||||
$magnetId,
|
||||
$db->initAddressTrackerId(
|
||||
$db->initSchemeId($url->host->scheme),
|
||||
$db->initHostId($url->host->name),
|
||||
$db->initPortId($url->host->port),
|
||||
$db->initUriId($url->page->uri)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'ws':
|
||||
foreach ($value as $ws)
|
||||
{
|
||||
// @TODO
|
||||
}
|
||||
break;
|
||||
case 'as':
|
||||
foreach ($value as $as)
|
||||
{
|
||||
if ($url = Yggverse\Parser\Url::parse($as))
|
||||
{
|
||||
$db->initMagnetToAcceptableSourceId(
|
||||
$magnetId,
|
||||
$db->initAcceptableSourceId(
|
||||
$db->initSchemeId($url->host->scheme),
|
||||
$db->initHostId($url->host->name),
|
||||
$db->initPortId($url->host->port),
|
||||
$db->initUriId($url->page->uri)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'xs':
|
||||
foreach ($value as $xs)
|
||||
{
|
||||
if ($url = Yggverse\Parser\Url::parse($xs))
|
||||
{
|
||||
$db->initMagnetToExactSourceId(
|
||||
$magnetId,
|
||||
$db->initExactSourceId(
|
||||
$db->initSchemeId($url->host->scheme),
|
||||
$db->initHostId($url->host->name),
|
||||
$db->initPortId($url->host->port),
|
||||
$db->initUriId($url->page->uri)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'mt':
|
||||
foreach ($value as $mt)
|
||||
{
|
||||
// @TODO
|
||||
}
|
||||
break;
|
||||
case 'x.pe':
|
||||
foreach ($value as $xPe)
|
||||
{
|
||||
// @TODO
|
||||
}
|
||||
break;
|
||||
case 'kt':
|
||||
foreach ($value as $kt)
|
||||
{
|
||||
$db->initMagnetToKeywordTopicId(
|
||||
$magnetId,
|
||||
$db->initKeywordTopicId(trim(mb_strtolower(strip_tags(html_entity_decode($kt)))))
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$db->commit();
|
||||
|
||||
// Redirect to edit page
|
||||
header(sprintf('Location: %s/edit.php?magnetId=%s', trim(WEBSITE_URL, '/'), $magnetId));
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
|
||||
var_dump($e);
|
||||
|
||||
$db->rollBack();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
header(
|
||||
sprintf('Location: %s', WEBSITE_URL)
|
||||
);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo WEBSITE_URL ?>/assets/theme/default/css/common.css?<?php echo WEBSITE_CSS_VERSION ?>" />
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo WEBSITE_URL ?>/assets/theme/default/css/framework.css?<?php echo WEBSITE_CSS_VERSION ?>" />
|
||||
<title>
|
||||
<?php echo sprintf(_('Oops - %s'), WEBSITE_NAME) ?>
|
||||
</title>
|
||||
<meta name="robots" content="noindex,nofollow"/>
|
||||
<meta name="author" content="YGGtracker" />
|
||||
<meta charset="UTF-8" />
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="container">
|
||||
<div class="row margin-t-8 text-center">
|
||||
<a class="logo" href="<?php echo WEBSITE_URL ?>"><?php echo str_replace('YGG', '<span>YGG</span>', WEBSITE_NAME) ?></a>
|
||||
<form class="margin-t-8" name="search" method="get" action="<?php echo WEBSITE_URL ?>/index.php">
|
||||
<input type="text" name="query" value="" placeholder="<?php echo _('search or submit magnet link') ?>" />
|
||||
<input type="submit" value="<?php echo _('submit') ?>" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="column width-100">
|
||||
<div class="padding-16 margin-y-8 border-radius-3 background-color-night">
|
||||
<div class="text-center"><?php echo $response->message ?></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<footer>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="column width-100 text-center margin-y-8">
|
||||
<a href="<?php echo WEBSITE_URL ?>/index.php?rss"><?php echo _('RSS') ?></a>
|
||||
|
|
||||
<?php foreach (TRACKER_LINKS as $name => $value) { ?>
|
||||
<a href="<?php echo $value->announce ?>"><?php echo $name ?></a>
|
||||
/
|
||||
<a href="<?php echo $value->stats ?>"><?php echo _('Stats') ?></a>
|
||||
|
|
||||
<?php } ?>
|
||||
<a href="https://github.com/YGGverse/YGGtracker"><?php echo _('GitHub') ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
71
src/public/assets/theme/default/css/common.css
Normal file
71
src/public/assets/theme/default/css/common.css
Normal file
@ -0,0 +1,71 @@
|
||||
* {
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #282b3c;
|
||||
color: #ccc;
|
||||
font-family: Sans-serif;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5 {
|
||||
display: inline-block;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
a,
|
||||
a:visited,
|
||||
a:active {
|
||||
color: #96d9a1;
|
||||
text-decoration: none;
|
||||
opacity: .9;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
opacity: 1;
|
||||
transition: opacity .5s ease-in-out;
|
||||
}
|
||||
|
||||
textarea:focus,
|
||||
input:focus {
|
||||
outline: none;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
textarea::placeholder,
|
||||
input::placeholder {
|
||||
color: #9698a5;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
input,
|
||||
textarea {
|
||||
background: #5d627d;
|
||||
color: #ccc;
|
||||
border: 0;
|
||||
border-radius: 3px;
|
||||
padding: 6px 8px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
input[type="submit"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
header a.logo {
|
||||
color: #ccc;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
header a.logo > span {
|
||||
color: #96d9a1;
|
||||
}
|
234
src/public/assets/theme/default/css/framework.css
Normal file
234
src/public/assets/theme/default/css/framework.css
Normal file
@ -0,0 +1,234 @@
|
||||
.container {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
max-width: 748px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.row {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.column {
|
||||
position: relative;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.float-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.text-color-green {
|
||||
color: #96d9a1;
|
||||
}
|
||||
|
||||
.text-color-red {
|
||||
color: #d77575;
|
||||
}
|
||||
|
||||
.text-color-pink {
|
||||
color: #a44399;
|
||||
}
|
||||
|
||||
.text-color-blue {
|
||||
color: #5785b7;
|
||||
}
|
||||
|
||||
.label {
|
||||
padding: 4px 8px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.label-green {
|
||||
color: #277b1b;
|
||||
border: 1px #92bc8c solid;
|
||||
}
|
||||
|
||||
.line-height-26 {
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
.border-radius-3 {
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.border-pink-light {
|
||||
border: 1px #9b6895 solid;
|
||||
}
|
||||
|
||||
.border-pink {
|
||||
border: 1px #a44399 solid;
|
||||
}
|
||||
|
||||
.border-bottom-pink {
|
||||
border-bottom: 1px #a44399 solid;
|
||||
}
|
||||
|
||||
.border-bottom-default {
|
||||
border-bottom: 1px #5d627d solid;
|
||||
}
|
||||
|
||||
.background-color-night {
|
||||
background-color: #34384f;
|
||||
}
|
||||
|
||||
.background-color-red {
|
||||
background-color: #9b4a4a;
|
||||
}
|
||||
|
||||
.cursor-default {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.cursor-help {
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.font-width-normal {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.font-size-12 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.font-size-22 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.padding-0 {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.padding-x-0 {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.padding-4 {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.padding-x-4 {
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
|
||||
.padding-8 {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.padding-y-8 {
|
||||
padding-top: 8px;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.padding-x-16 {
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
.padding-16 {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.margin-l-8 {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.margin-r-8 {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.margin-l-12 {
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
.margin-y-8 {
|
||||
margin-top: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.margin-t-8 {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.margin-b-8 {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.margin-b-16 {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.display-block {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.opacity-0 {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.opacity-06 {
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
.opacity-hover-1:hover {
|
||||
opacity: 1;
|
||||
transition: opacity .2s ease-in-out;
|
||||
}
|
||||
|
||||
*:hover > .parent-hover-opacity-09 {
|
||||
opacity: .9;
|
||||
transition: opacity .2s ease-in-out;
|
||||
}
|
||||
|
||||
.bloor-2 {
|
||||
filter: blur(2px);
|
||||
}
|
||||
|
||||
.bloor-hover-0:hover {
|
||||
filter: blur(0);
|
||||
}
|
||||
|
||||
/* responsive rules */
|
||||
|
||||
.width-100 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.width-50 {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.width-13px {
|
||||
width: 13px;
|
||||
}
|
||||
|
||||
@media (max-width: 1220px) {
|
||||
|
||||
.width-tablet-100 {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 512px) {
|
||||
|
||||
.width-mobile-100 {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
560
src/public/edit.php
Normal file
560
src/public/edit.php
Normal file
@ -0,0 +1,560 @@
|
||||
<?php
|
||||
|
||||
// Load dependencies
|
||||
require_once (__DIR__ . '/../config/app.php');
|
||||
require_once (__DIR__ . '/../library/database.php');
|
||||
require_once (__DIR__ . '/../../vendor/autoload.php');
|
||||
|
||||
// Connect database
|
||||
try {
|
||||
|
||||
$db = new Database(DB_HOST, DB_PORT, DB_NAME, DB_USERNAME, DB_PASSWORD);
|
||||
|
||||
} catch (Exception $e) {
|
||||
|
||||
var_dump($e);
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
// Define variables
|
||||
$response = (object)
|
||||
[
|
||||
'success' => true,
|
||||
'message' => false,
|
||||
'form' => (object)
|
||||
[
|
||||
'metaTitle' => (object)
|
||||
[
|
||||
'value' => false,
|
||||
'valid' => (object)
|
||||
[
|
||||
'success' => true,
|
||||
'message' => false,
|
||||
]
|
||||
],
|
||||
'metaDescription' => (object)
|
||||
[
|
||||
'value' => false,
|
||||
'valid' => (object)
|
||||
[
|
||||
'success' => true,
|
||||
'message' => false,
|
||||
]
|
||||
],
|
||||
'dn' => (object)
|
||||
[
|
||||
'value' => false,
|
||||
'valid' => (object)
|
||||
[
|
||||
'success' => true,
|
||||
'message' => false,
|
||||
]
|
||||
],
|
||||
'kt' => (object)
|
||||
[
|
||||
'value' => false,
|
||||
'valid' => (object)
|
||||
[
|
||||
'success' => true,
|
||||
'message' => false,
|
||||
]
|
||||
],
|
||||
'tr' => (object)
|
||||
[
|
||||
'value' => false,
|
||||
'valid' => (object)
|
||||
[
|
||||
'success' => true,
|
||||
'message' => false,
|
||||
]
|
||||
],
|
||||
'as' => (object)
|
||||
[
|
||||
'value' => false,
|
||||
'valid' => (object)
|
||||
[
|
||||
'success' => true,
|
||||
'message' => false,
|
||||
]
|
||||
],
|
||||
'xs' => (object)
|
||||
[
|
||||
'value' => false,
|
||||
'valid' => (object)
|
||||
[
|
||||
'success' => true,
|
||||
'message' => false,
|
||||
]
|
||||
],
|
||||
'public' => (object)
|
||||
[
|
||||
'value' => false,
|
||||
'valid' => (object)
|
||||
[
|
||||
'success' => true,
|
||||
'message' => false,
|
||||
]
|
||||
],
|
||||
'comments' => (object)
|
||||
[
|
||||
'value' => false,
|
||||
'valid' => (object)
|
||||
[
|
||||
'success' => true,
|
||||
'message' => false,
|
||||
]
|
||||
],
|
||||
'sensitive' => (object)
|
||||
[
|
||||
'value' => false,
|
||||
'valid' => (object)
|
||||
[
|
||||
'success' => true,
|
||||
'message' => false,
|
||||
]
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
// Yggdrasil connections only
|
||||
if (!preg_match(YGGDRASIL_URL_REGEX, $_SERVER['REMOTE_ADDR']))
|
||||
{
|
||||
$response->success = false;
|
||||
$response->message = _('Yggdrasil connection required to enable resource features');
|
||||
}
|
||||
|
||||
// Init session
|
||||
else if (!$userId = $db->initUserId($_SERVER['REMOTE_ADDR'], USER_DEFAULT_APPROVED, time()))
|
||||
{
|
||||
$response->success = false;
|
||||
$response->message = _('Could not init user session');
|
||||
}
|
||||
|
||||
// Init magnet
|
||||
else if (!$magnet = $db->getMagnet(isset($_GET['magnetId']) ? (int) $_GET['magnetId'] : 0)) {
|
||||
|
||||
$response->success = false;
|
||||
$response->message = _('Magnet not found!');
|
||||
}
|
||||
|
||||
// Validate access
|
||||
else if (!($_SERVER['REMOTE_ADDR'] == $db->getUser($magnet->userId)->address || in_array($_SERVER['REMOTE_ADDR'], MODERATOR_IP_LIST))) {
|
||||
|
||||
$response->success = false;
|
||||
$response->message = _('You have no permissions to edit this magnet!');
|
||||
}
|
||||
|
||||
// Process form
|
||||
else {
|
||||
|
||||
// Update form
|
||||
if (!empty($_POST)) {
|
||||
|
||||
// Approve by moderation request
|
||||
if (isset($_POST['approved']) && in_array($_SERVER['REMOTE_ADDR'], MODERATOR_IP_LIST))
|
||||
{
|
||||
$db->updateMagnetApproved($magnet->magnetId, true, time());
|
||||
}
|
||||
|
||||
// Set default approve status
|
||||
else
|
||||
{
|
||||
$db->updateMagnetApproved($magnet->magnetId, MAGNET_DEFAULT_APPROVED, time());
|
||||
}
|
||||
|
||||
// Meta
|
||||
if (MAGNET_META_TITLE_MIN_LENGTH <= mb_strlen($_POST['metaTitle']))
|
||||
{
|
||||
$db->updateMagnetMetaTitle($magnet->magnetId, trim(strip_tags(html_entity_decode($_POST['metaTitle']))), time());
|
||||
|
||||
$response->form->metaTitle->valid->success = true;
|
||||
$response->form->metaTitle->valid->message = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$response->form->metaTitle->valid->success = false;
|
||||
$response->form->metaTitle->valid->message = sprintf(_('* required, minimum %s chars'), MAGNET_META_TITLE_MIN_LENGTH);
|
||||
}
|
||||
|
||||
if (MAGNET_META_DESCRIPTION_MIN_LENGTH <= mb_strlen($_POST['metaDescription']))
|
||||
{
|
||||
$db->updateMagnetMetaDescription($magnet->magnetId, trim(strip_tags(html_entity_decode($_POST['metaDescription']))), time());
|
||||
}
|
||||
else
|
||||
{
|
||||
$response->form->metaDescription->valid->success = false;
|
||||
$response->form->metaDescription->valid->message = sprintf(_('* required, minimum %s chars'), MAGNET_META_DESCRIPTION_MIN_LENGTH);
|
||||
}
|
||||
|
||||
// Social
|
||||
$db->updateMagnetPublic($magnet->magnetId, isset($_POST['public']) ? true : false, time());
|
||||
$db->updateMagnetComments($magnet->magnetId, isset($_POST['comments']) ? true : false, time());
|
||||
$db->updateMagnetSensitive($magnet->magnetId, isset($_POST['sensitive']) ? true : false, time());
|
||||
|
||||
// Display Name
|
||||
if (isset($_POST['dn']))
|
||||
{
|
||||
$db->updateMagnetDn($magnet->magnetId, trim(strip_tags(html_entity_decode($_POST['dn']))), time());
|
||||
}
|
||||
|
||||
// Keyword Topic
|
||||
$db->deleteMagnetToKeywordTopicByMagnetId($magnet->magnetId);
|
||||
|
||||
if (!empty($_POST['kt']))
|
||||
{
|
||||
foreach (explode(PHP_EOL, str_replace(['#', ',', ' '], PHP_EOL, $_POST['kt'])) as $kt)
|
||||
{
|
||||
if (!empty(trim($kt)))
|
||||
{
|
||||
$db->initMagnetToKeywordTopicId(
|
||||
$magnet->magnetId,
|
||||
$db->initKeywordTopicId(trim(mb_strtolower(strip_tags(html_entity_decode($kt)))))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Address Tracker
|
||||
$db->deleteMagnetToAddressTrackerByMagnetId($magnet->magnetId);
|
||||
|
||||
if (!empty($_POST['tr']))
|
||||
{
|
||||
$response->form->tr->valid->success = false;
|
||||
$response->form->tr->valid->message = _('* please, provide at least one Yggdrasil address');
|
||||
|
||||
foreach (explode(PHP_EOL, str_replace(['#', ',', ' '], PHP_EOL, $_POST['tr'])) as $tr)
|
||||
{
|
||||
$tr = trim($tr);
|
||||
|
||||
if (!empty($tr))
|
||||
{
|
||||
if ($url = Yggverse\Parser\Url::parse($tr))
|
||||
{
|
||||
$db->initMagnetToAddressTrackerId(
|
||||
$magnet->magnetId,
|
||||
$db->initAddressTrackerId(
|
||||
$db->initSchemeId($url->host->scheme),
|
||||
$db->initHostId($url->host->name),
|
||||
$db->initPortId($url->host->port),
|
||||
$db->initUriId($url->page->uri)
|
||||
)
|
||||
);
|
||||
|
||||
if (preg_match(YGGDRASIL_URL_REGEX, $url->host->name))
|
||||
{
|
||||
$response->form->tr->valid->success = true;
|
||||
$response->form->tr->valid->message = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Acceptable Source
|
||||
$db->deleteMagnetToAcceptableSourceByMagnetId($magnet->magnetId);
|
||||
|
||||
if (!empty($_POST['as']))
|
||||
{
|
||||
$response->form->as->valid->success = false;
|
||||
$response->form->as->valid->message = _('* please, provide at least one Yggdrasil address');
|
||||
|
||||
foreach (explode(PHP_EOL, str_replace(['#', ',', ' '], PHP_EOL, $_POST['as'])) as $as)
|
||||
{
|
||||
$as = trim($as);
|
||||
|
||||
if (!empty($as))
|
||||
{
|
||||
if ($url = Yggverse\Parser\Url::parse($as))
|
||||
{
|
||||
$db->initMagnetToAcceptableSourceId(
|
||||
$magnet->magnetId,
|
||||
$db->initAcceptableSourceId(
|
||||
$db->initSchemeId($url->host->scheme),
|
||||
$db->initHostId($url->host->name),
|
||||
$db->initPortId($url->host->port),
|
||||
$db->initUriId($url->page->uri)
|
||||
)
|
||||
);
|
||||
|
||||
if (preg_match(YGGDRASIL_URL_REGEX, $url->host->name))
|
||||
{
|
||||
$response->form->as->valid->success = true;
|
||||
$response->form->as->valid->message = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exact Source
|
||||
$db->deleteMagnetToExactSourceByMagnetId($magnet->magnetId);
|
||||
|
||||
if (!empty($_POST['xs']))
|
||||
{
|
||||
$response->form->xs->valid->success = false;
|
||||
$response->form->xs->valid->message = _('* please, provide at least one Yggdrasil address');
|
||||
|
||||
foreach (explode(PHP_EOL, str_replace(['#', ',', ' '], PHP_EOL, $_POST['xs'])) as $xs)
|
||||
{
|
||||
$xs = trim($xs);
|
||||
|
||||
if (!empty($xs))
|
||||
{
|
||||
if ($url = Yggverse\Parser\Url::parse($xs))
|
||||
{
|
||||
$db->initMagnetToExactSourceId(
|
||||
$magnet->magnetId,
|
||||
$db->initExactSourceId(
|
||||
$db->initSchemeId($url->host->scheme),
|
||||
$db->initHostId($url->host->name),
|
||||
$db->initPortId($url->host->port),
|
||||
$db->initUriId($url->page->uri)
|
||||
)
|
||||
);
|
||||
|
||||
if (preg_match(YGGDRASIL_URL_REGEX, $url->host->name))
|
||||
{
|
||||
$response->form->xs->valid->success = true;
|
||||
$response->form->xs->valid->message = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh magnet data
|
||||
$magnet = $db->getMagnet($magnet->magnetId);
|
||||
}
|
||||
|
||||
// Meta Title, auto-replace with Display Name on empty value
|
||||
$response->form->metaTitle->value = $magnet->metaTitle ? $magnet->metaTitle : $magnet->dn;
|
||||
|
||||
// Meta Description
|
||||
$response->form->metaDescription->value = $magnet->metaDescription;
|
||||
|
||||
// Magnet settings
|
||||
$response->form->public->value = (bool) $magnet->public;
|
||||
$response->form->comments->value = (bool) $magnet->comments;
|
||||
$response->form->sensitive->value = (bool) $magnet->sensitive;
|
||||
|
||||
// Display Name
|
||||
$response->form->dn->value = $magnet->dn;
|
||||
|
||||
// Keyword Topic
|
||||
$kt = [];
|
||||
foreach ($db->findKeywordTopicByMagnetId($magnet->magnetId) as $result)
|
||||
{
|
||||
$kt[] = $db->getKeywordTopic($result->keywordTopicId)->value;
|
||||
}
|
||||
|
||||
$response->form->kt->value = implode(', ', $kt);
|
||||
|
||||
// Address Tracker
|
||||
$tr = [];
|
||||
foreach ($db->findAddressTrackerByMagnetId($magnet->magnetId) as $result)
|
||||
{
|
||||
$addressTracker = $db->getAddressTracker($result->addressTrackerId);
|
||||
|
||||
$scheme = $db->getScheme($addressTracker->schemeId);
|
||||
$host = $db->getHost($addressTracker->hostId);
|
||||
$port = $db->getPort($addressTracker->portId);
|
||||
$uri = $db->getUri($addressTracker->uriId);
|
||||
|
||||
$tr[] = $port->value ? sprintf('%s://%s:%s%s', $scheme->value,
|
||||
$host->value,
|
||||
$port->value,
|
||||
$uri->value) : sprintf('%s://%s%s', $scheme->value,
|
||||
$host->value,
|
||||
$uri->value);
|
||||
}
|
||||
|
||||
$response->form->tr->value = implode(PHP_EOL, $tr);
|
||||
|
||||
// Acceptable Source
|
||||
$as = [];
|
||||
foreach ($db->findAcceptableSourceByMagnetId($magnet->magnetId) as $result)
|
||||
{
|
||||
$acceptableSource = $db->getAcceptableSource($result->acceptableSourceId);
|
||||
|
||||
$scheme = $db->getScheme($acceptableSource->schemeId);
|
||||
$host = $db->getHost($acceptableSource->hostId);
|
||||
$port = $db->getPort($acceptableSource->portId);
|
||||
$uri = $db->getUri($acceptableSource->uriId);
|
||||
|
||||
$as[] = $port->value ? sprintf('%s://%s:%s%s', $scheme->value,
|
||||
$host->value,
|
||||
$port->value,
|
||||
$uri->value) : sprintf('%s://%s%s', $scheme->value,
|
||||
$host->value,
|
||||
$uri->value);
|
||||
}
|
||||
|
||||
$response->form->as->value = implode(PHP_EOL, $as);
|
||||
|
||||
// Exact Source
|
||||
$xs = [];
|
||||
foreach ($db->findExactSourceByMagnetId($magnet->magnetId) as $result)
|
||||
{
|
||||
$eXactSource = $db->getExactSource($result->eXactSourceId);
|
||||
|
||||
$scheme = $db->getScheme($eXactSource->schemeId);
|
||||
$host = $db->getHost($eXactSource->hostId);
|
||||
$port = $db->getPort($eXactSource->portId);
|
||||
$uri = $db->getUri($eXactSource->uriId);
|
||||
|
||||
$xs[] = $port->value ? sprintf('%s://%s:%s%s', $scheme->value,
|
||||
$host->value,
|
||||
$port->value,
|
||||
$uri->value) : sprintf('%s://%s%s', $scheme->value,
|
||||
$host->value,
|
||||
$uri->value);
|
||||
}
|
||||
|
||||
$response->form->xs->value = implode(PHP_EOL, $xs);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo WEBSITE_URL ?>/assets/theme/default/css/common.css?<?php echo WEBSITE_CSS_VERSION ?>" />
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo WEBSITE_URL ?>/assets/theme/default/css/framework.css?<?php echo WEBSITE_CSS_VERSION ?>" />
|
||||
<title>
|
||||
<?php echo sprintf(_('Edit - %s'), WEBSITE_NAME) ?>
|
||||
</title>
|
||||
<meta name="description" content="<?php echo _('BitTorrent Catalog for Yggdrasil') ?>" />
|
||||
<meta name="keywords" content="yggdrasil, yggverse, yggtracker, bittorrent, magnet, catalog" />
|
||||
<meta name="author" content="YGGtracker" />
|
||||
<meta charset="UTF-8" />
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="container">
|
||||
<div class="row margin-t-8 text-center">
|
||||
<a class="logo" href="<?php echo WEBSITE_URL ?>"><?php echo str_replace('YGG', '<span>YGG</span>', WEBSITE_NAME) ?></a>
|
||||
<form class="margin-t-8" name="search" method="get" action="<?php echo WEBSITE_URL ?>/index.php">
|
||||
<input type="text" name="query" value="" placeholder="<?php echo _('search or submit magnet link') ?>" />
|
||||
<input type="submit" value="<?php echo _('submit') ?>" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="column width-100">
|
||||
<?php if ($response->success) { ?>
|
||||
<div class="padding-x-16 text-right">
|
||||
<a href="<?php echo WEBSITE_URL ?>" target="_blank"><?php echo _('catalog') ?></a>
|
||||
<!-- <a href="<?php echo WEBSITE_URL ?>/magnet.php?magnetId=<?php echo $magnet->magnetId ?>" target="_blank"><?php echo _('magnet page') ?></a> -->
|
||||
</div>
|
||||
<div class="padding-16 margin-y-8 border-radius-3 background-color-night">
|
||||
<h2 class="margin-b-8"><?php echo _('Edit magnet') ?></h2>
|
||||
<form name="search" method="post" action="<?php echo WEBSITE_URL ?>/edit.php?magnetId=<?php echo $magnet->magnetId ?>">
|
||||
<fieldset class="display-block margin-b-16">
|
||||
<legend class="text-right width-100 padding-y-8 margin-b-8 border-bottom-default"><?php echo _('Meta') ?></legend>
|
||||
<label class="display-block margin-y-8"><?php echo _('Title') ?></label>
|
||||
<?php if ($response->form->metaTitle->valid->message) { ?>
|
||||
<div class="margin-b-8"><?php echo $response->form->metaTitle->valid->message ?></div>
|
||||
<?php } ?>
|
||||
<input class="width-100 <?php echo ($response->form->metaTitle->valid->success ? false : 'background-color-red') ?>" type="text" name="metaTitle" value="<?php echo $response->form->metaTitle->value ?>" placeholder="<?php echo _('Main title') ?>" maxlength="255" />
|
||||
<label class="display-block margin-y-8"><?php echo _('Description') ?></label>
|
||||
<?php if ($response->form->metaDescription->valid->message) { ?>
|
||||
<div class="margin-b-8"><?php echo $response->form->metaDescription->valid->message ?></div>
|
||||
<?php } ?>
|
||||
<textarea class="width-100 <?php echo ($response->form->metaDescription->valid->success ? false : 'background-color-red') ?>" name="metaDescription" placeholder="<?php echo _('Describe your magnet for others') ?>"><?php echo $response->form->metaDescription->value ?></textarea>
|
||||
</fieldset>
|
||||
<fieldset class="display-block margin-b-16">
|
||||
<legend class="text-right width-100 padding-y-8 margin-b-8 border-bottom-default"><?php echo _('BitTorrent') ?></legend>
|
||||
<label class="display-block margin-y-8"><?php echo _('Display Name (dn)') ?></label>
|
||||
<input class="width-100" type="text" name="dn" value="<?php echo $response->form->dn->value ?>" placeholder="<?php echo _('A filename to display to the user, for convenience') ?>" maxlength="255" />
|
||||
<label class="display-block margin-y-8"><?php echo _('Keyword Topic (kt)') ?></label>
|
||||
<textarea class="width-100" name="kt" placeholder="<?php echo _('Hash tag, comma separated, or one per line') ?>"><?php echo $response->form->kt->value ?></textarea>
|
||||
<label class="display-block margin-y-8"><?php echo _('Address Tracker (tr)') ?></label>
|
||||
<?php if ($response->form->tr->valid->message) { ?>
|
||||
<div class="margin-b-8"><?php echo $response->form->tr->valid->message ?></div>
|
||||
<?php } ?>
|
||||
<textarea class="width-100 <?php echo ($response->form->tr->valid->success ? false : 'background-color-red') ?>" name="tr" placeholder="<?php echo _('BitTorrent trackers list - comma separated, or one per line') ?>"><?php echo $response->form->tr->value ?></textarea>
|
||||
<label class="display-block margin-y-8"><?php echo _('Acceptable Source (as)') ?></label>
|
||||
<?php if ($response->form->as->valid->message) { ?>
|
||||
<div class="margin-b-8"><?php echo $response->form->as->valid->message ?></div>
|
||||
<?php } ?>
|
||||
<textarea class="width-100 <?php echo ($response->form->as->valid->success ? false : 'background-color-red') ?>" name="as" placeholder="<?php echo _('Web servers to a direct download - comma separated, or one per line') ?>"><?php echo $response->form->as->value ?></textarea>
|
||||
<label class="display-block margin-y-8"><?php echo _('eXact Source (xs)') ?></label>
|
||||
<?php if ($response->form->xs->valid->message) { ?>
|
||||
<div class="margin-b-8"><?php echo $response->form->xs->valid->message ?></div>
|
||||
<?php } ?>
|
||||
<textarea class="width-100 <?php echo ($response->form->xs->valid->success ? false : 'background-color-red') ?>" name="xs" placeholder="<?php echo _('URL of a P2P source for the file or the address of a hub - comma separated, or one per line') ?>"><?php echo $response->form->xs->value ?></textarea>
|
||||
</fieldset>
|
||||
<fieldset class="display-block">
|
||||
<legend class="text-right width-100 padding-y-8 margin-b-16 border-bottom-default"><?php echo _('Social') ?></legend>
|
||||
<div class="margin-b-8">
|
||||
<?php if ($response->form->public->value) { ?>
|
||||
<input type="checkbox" id="public" name="public" value="1" checked="checked" />
|
||||
<?php } else { ?>
|
||||
<input type="checkbox" id="public" name="public" value="1" />
|
||||
<?php } ?>
|
||||
<label class="margin-y-8" for="public"><?php echo _('Public') ?></label>
|
||||
</div>
|
||||
<div class="margin-b-8">
|
||||
<?php if ($response->form->comments->value) { ?>
|
||||
<input type="checkbox" id="comments" name="comments" value="1" checked="checked" />
|
||||
<?php } else { ?>
|
||||
<input type="checkbox" id="comments" name="comments" value="1" />
|
||||
<?php } ?>
|
||||
<label class="margin-y-8" for="comments"><?php echo _('Comments') ?></label>
|
||||
</div>
|
||||
<div class="margin-b-8">
|
||||
<?php if ($response->form->sensitive->value) { ?>
|
||||
<input type="checkbox" id="sensitive" name="sensitive" value="1" checked="checked" />
|
||||
<?php } else { ?>
|
||||
<input type="checkbox" id="sensitive" name="sensitive" value="1" />
|
||||
<?php } ?>
|
||||
<label class="margin-y-8" for="sensitive"><?php echo _('Sensitive') ?></label>
|
||||
</div>
|
||||
<?php if (in_array($_SERVER['REMOTE_ADDR'], MODERATOR_IP_LIST)) { ?>
|
||||
<div class="margin-b-8">
|
||||
<?php if (MAGNET_DEFAULT_APPROVED) { ?>
|
||||
<input type="checkbox" id="approved" name="approved" value="1" checked="checked" />
|
||||
<?php } else { ?>
|
||||
<input type="checkbox" id="approved" name="approved" value="1" />
|
||||
<?php } ?>
|
||||
<label class="margin-y-8" for="approved"><?php echo _('Approved') ?></label>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</fieldset>
|
||||
<fieldset class="display-block text-right">
|
||||
<input type="submit" value="<?php echo _('save') ?>" />
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
<?php } else { ?>
|
||||
<div class="padding-16 margin-y-8 border-radius-3 background-color-night">
|
||||
<div class="text-center"><?php echo $response->message ?></div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<footer>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="column width-100 text-center margin-y-8">
|
||||
<a href="<?php echo WEBSITE_URL ?>/index.php?rss"><?php echo _('RSS') ?></a>
|
||||
|
|
||||
<?php foreach (TRACKER_LINKS as $name => $value) { ?>
|
||||
<a href="<?php echo $value->announce ?>"><?php echo $name ?></a>
|
||||
/
|
||||
<a href="<?php echo $value->stats ?>"><?php echo _('Stats') ?></a>
|
||||
|
|
||||
<?php } ?>
|
||||
<a href="https://github.com/YGGverse/YGGtracker"><?php echo _('GitHub') ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
336
src/public/index.php
Normal file
336
src/public/index.php
Normal file
@ -0,0 +1,336 @@
|
||||
<?php
|
||||
|
||||
// Load dependencies
|
||||
require_once (__DIR__ . '/../config/app.php');
|
||||
require_once (__DIR__ . '/../library/sphinx.php');
|
||||
require_once (__DIR__ . '/../library/database.php');
|
||||
require_once (__DIR__ . '/../library/time.php');
|
||||
require_once (__DIR__ . '/../../vendor/autoload.php');
|
||||
|
||||
// Connect Sphinx
|
||||
try {
|
||||
|
||||
$sphinx = new Sphinx(SPHINX_HOST, SPHINX_PORT);
|
||||
|
||||
} catch(Exception $e) {
|
||||
|
||||
var_dump($e);
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
// Connect database
|
||||
try {
|
||||
|
||||
$db = new Database(DB_HOST, DB_PORT, DB_NAME, DB_USERNAME, DB_PASSWORD);
|
||||
|
||||
} catch (Exception $e) {
|
||||
|
||||
var_dump($e);
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
// Define variables
|
||||
$request = (object)
|
||||
[
|
||||
'query' => false,
|
||||
'page' => 1,
|
||||
];
|
||||
|
||||
// Prepare request
|
||||
$request->query = isset($_GET['query']) ? urldecode((string) $_GET['query']) : '';
|
||||
$request->page = isset($_GET['page']) && $_GET['page'] > 0 ? (int) $_GET['page'] : 1;
|
||||
|
||||
// Define response
|
||||
$response = (object)
|
||||
[
|
||||
'success' => true,
|
||||
'message' => false,
|
||||
'magnets' => [],
|
||||
];
|
||||
|
||||
// Yggdrasil connections only
|
||||
if (!preg_match(YGGDRASIL_URL_REGEX, $_SERVER['REMOTE_ADDR']))
|
||||
{
|
||||
$response->success = false;
|
||||
$response->message = _('Yggdrasil connection required to enable resource features');
|
||||
}
|
||||
|
||||
// Init session
|
||||
else if (!$userId = $db->initUserId($_SERVER['REMOTE_ADDR'], USER_DEFAULT_APPROVED, time()))
|
||||
{
|
||||
$response->success = false;
|
||||
$response->message = _('Could not init user session');
|
||||
}
|
||||
|
||||
// Request valid
|
||||
else
|
||||
{
|
||||
// Query is magnet link
|
||||
if ($magnet = Yggverse\Parser\Magnet::is($request->query))
|
||||
{
|
||||
header(
|
||||
sprintf('Location: %s/action.php?target=new&magnet=%s', WEBSITE_URL, base64_encode($request->query))
|
||||
);
|
||||
}
|
||||
|
||||
// Get index
|
||||
$total = $sphinx->searchMagnetsTotal($request->query);
|
||||
$results = $sphinx->searchMagnets(
|
||||
$request->query,
|
||||
$request->page * WEBSITE_PAGINATION_LIMIT - WEBSITE_PAGINATION_LIMIT,
|
||||
WEBSITE_PAGINATION_LIMIT,
|
||||
$total
|
||||
);
|
||||
|
||||
foreach ($results as $result)
|
||||
{
|
||||
if ($magnet = $db->getMagnet($result->magnetid))
|
||||
{
|
||||
$keywords = [];
|
||||
|
||||
foreach ($db->findKeywordTopicByMagnetId($magnet->magnetId) as $keyword)
|
||||
{
|
||||
$keywords[] = $db->getKeywordTopic($keyword->keywordTopicId)->value;
|
||||
}
|
||||
|
||||
$response->magnets[] = (object)
|
||||
[
|
||||
'magnetId' => $magnet->magnetId,
|
||||
'metaTitle' => $magnet->metaTitle ? htmlentities($magnet->metaTitle) : ($magnet->dn ? htmlentities($magnet->dn): false),
|
||||
'metaDescription' => $magnet->metaDescription ? nl2br(
|
||||
htmlentities(
|
||||
substr($magnet->metaDescription, 0, WEBSITE_MAGNET_SHORT_META_DESCRIPTION_LENGTH)
|
||||
)
|
||||
) : false,
|
||||
'approved' => (bool) $magnet->approved,
|
||||
'public' => (bool) $magnet->public,
|
||||
'sensitive' => (bool) $magnet->sensitive,
|
||||
'comments' => (bool) $magnet->comments,
|
||||
'timeAdded' => Time::ago($magnet->timeAdded),
|
||||
'timeUpdated' => Time::ago($magnet->timeUpdated),
|
||||
'keywords' => $keywords,
|
||||
'comment' => (object)
|
||||
[
|
||||
'total' => $db->getMagnetCommentsTotal($magnet->magnetId),
|
||||
'status' => $db->findMagnetCommentsTotalByUserId($magnet->magnetId, $userId),
|
||||
],
|
||||
'download' => (object)
|
||||
[
|
||||
'total' => $db->getMagnetDownloadsTotal($magnet->magnetId),
|
||||
'status' => $db->findMagnetDownloadsTotalByUserId($magnet->magnetId, $userId),
|
||||
],
|
||||
'star' => (object)
|
||||
[
|
||||
'total' => $db->getMagnetStarsTotal($magnet->magnetId),
|
||||
'status' => $db->findMagnetStarsTotalByUserId($magnet->magnetId, $userId),
|
||||
],
|
||||
'access' => (object)
|
||||
[
|
||||
'read' => ($_SERVER['REMOTE_ADDR'] == $db->getUser($magnet->userId)->address || in_array($_SERVER['REMOTE_ADDR'], MODERATOR_IP_LIST) || ($magnet->public && $magnet->approved)),
|
||||
'edit' => ($_SERVER['REMOTE_ADDR'] == $db->getUser($magnet->userId)->address || in_array($_SERVER['REMOTE_ADDR'], MODERATOR_IP_LIST)),
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_GET['rss']) && $response->success) { ?><?php
|
||||
header('Content-type: text/xml;charset=UTF-8');
|
||||
echo '<?xml version="1.0" encoding="UTF-8"?>' . PHP_EOL ?>
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<channel>
|
||||
<atom:link href="<?php echo WEBSITE_URL ?>/index.php<?php echo $request->query ? sprintf('?query=%s', urlencode($request->query)) : false ?>" rel="self" type="application/rss+xml"></atom:link>
|
||||
<title><?php echo WEBSITE_NAME ?></title>
|
||||
<description><?php echo _('BitTorrent Catalog for Yggdrasil') ?></description>
|
||||
<link><?php echo WEBSITE_URL ?>/index.php<?php echo $request->query ? sprintf('?query=%s', urlencode($request->query)) : false ?></link>
|
||||
<?php foreach ($response->magnets as $magnet) { ?>
|
||||
<?php if ($magnet->access->read) { ?>
|
||||
<item>
|
||||
<title><?php echo htmlspecialchars($magnet->metaTitle, ENT_QUOTES, 'UTF-8') ?></title>
|
||||
<guid><?php echo WEBSITE_URL ?>#magnet-<?php echo $magnet->magnetId ?></guid>
|
||||
<description><?php echo htmlspecialchars(strip_tags($magnet->metaDescription), ENT_QUOTES, 'UTF-8') ?></description>
|
||||
<link><?php echo WEBSITE_URL ?>#magnet-<?php echo $magnet->magnetId ?></link>
|
||||
</item>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
</channel>
|
||||
</rss>
|
||||
<?php } else { ?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo WEBSITE_URL ?>/assets/theme/default/css/common.css?<?php echo WEBSITE_CSS_VERSION ?>" />
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo WEBSITE_URL ?>/assets/theme/default/css/framework.css?<?php echo WEBSITE_CSS_VERSION ?>" />
|
||||
<title>
|
||||
<?php echo sprintf(_('%s - BitTorrent Catalog for Yggdrasil'), WEBSITE_NAME) ?>
|
||||
</title>
|
||||
<meta name="description" content="<?php echo _('BitTorrent Catalog for Yggdrasil') ?>" />
|
||||
<meta name="keywords" content="yggdrasil, yggverse, yggtracker, bittorrent, magnet, catalog" />
|
||||
<meta name="author" content="YGGtracker" />
|
||||
<meta charset="UTF-8" />
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="container">
|
||||
<div class="row margin-t-8 text-center">
|
||||
<a class="logo" href="<?php echo WEBSITE_URL ?>"><?php echo str_replace('YGG', '<span>YGG</span>', WEBSITE_NAME) ?></a>
|
||||
<form class="margin-t-8" name="search" method="get" action="<?php echo WEBSITE_URL ?>/index.php">
|
||||
<input type="text" name="query" value="<?php echo htmlentities($request->query) ?>" placeholder="<?php echo _('search or submit magnet link') ?>" />
|
||||
<input type="submit" value="<?php echo _('submit') ?>" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="column width-100">
|
||||
<?php if ($response->success) { ?>
|
||||
<?php if ($response->magnets) { ?>
|
||||
<?php foreach ($response->magnets as $magnet) { ?>
|
||||
<?php if ($magnet->access->read) { ?>
|
||||
<div class="padding-16
|
||||
margin-y-8
|
||||
border-radius-3
|
||||
background-color-night
|
||||
<?php echo !$magnet->public || !$magnet->approved ? 'opacity-06 opacity-hover-1' : false ?>">
|
||||
<div class="<?php echo $magnet->sensitive ? 'bloor-2 bloor-hover-0' : false ?>">
|
||||
<a name="magnet-<?php echo $magnet->magnetId ?>"></a>
|
||||
<h2><?php echo $magnet->metaTitle ?></h2>
|
||||
<div class="float-right opacity-0 parent-hover-opacity-09">
|
||||
<?php if ($magnet->access->edit) { ?>
|
||||
<a class="text-color-green margin-l-12" href="<?php echo WEBSITE_URL ?>/edit.php?magnetId=<?php echo $magnet->magnetId ?>" title="<?php echo _('Edit') ?>">
|
||||
<svg class="text-color-green" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-pencil-square" viewBox="0 0 16 16">
|
||||
<path d="M15.502 1.94a.5.5 0 0 1 0 .706L14.459 3.69l-2-2L13.502.646a.5.5 0 0 1 .707 0l1.293 1.293zm-1.75 2.456-2-2L4.939 9.21a.5.5 0 0 0-.121.196l-.805 2.414a.25.25 0 0 0 .316.316l2.414-.805a.5.5 0 0 0 .196-.12l6.813-6.814z"/>
|
||||
<path fill-rule="evenodd" d="M1 13.5A1.5 1.5 0 0 0 2.5 15h11a1.5 1.5 0 0 0 1.5-1.5v-6a.5.5 0 0 0-1 0v6a.5.5 0 0 1-.5.5h-11a.5.5 0 0 1-.5-.5v-11a.5.5 0 0 1 .5-.5H9a.5.5 0 0 0 0-1H2.5A1.5 1.5 0 0 0 1 2.5v11z"/>
|
||||
</svg>
|
||||
</a>
|
||||
<?php } else { ?>
|
||||
<!-- TODO
|
||||
<a class="text-color-pink margin-l-12" href="<?php echo WEBSITE_URL ?>/action.php?target=report&magnetId=<?php echo $magnet->magnetId ?>&callback=<?php echo base64_encode(sprintf('%s/index.php?query=%s#magnet-%s', WEBSITE_URL, urlencode($request->query), $magnet->magnetId)) ?>" title="<?php echo _('Report') ?>">
|
||||
<svg class="text-color-pink" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-flag" viewBox="0 0 16 16">
|
||||
<path d="M14.778.085A.5.5 0 0 1 15 .5V8a.5.5 0 0 1-.314.464L14.5 8l.186.464-.003.001-.006.003-.023.009a12.435 12.435 0 0 1-.397.15c-.264.095-.631.223-1.047.35-.816.252-1.879.523-2.71.523-.847 0-1.548-.28-2.158-.525l-.028-.01C7.68 8.71 7.14 8.5 6.5 8.5c-.7 0-1.638.23-2.437.477A19.626 19.626 0 0 0 3 9.342V15.5a.5.5 0 0 1-1 0V.5a.5.5 0 0 1 1 0v.282c.226-.079.496-.17.79-.26C4.606.272 5.67 0 6.5 0c.84 0 1.524.277 2.121.519l.043.018C9.286.788 9.828 1 10.5 1c.7 0 1.638-.23 2.437-.477a19.587 19.587 0 0 0 1.349-.476l.019-.007.004-.002h.001M14 1.221c-.22.078-.48.167-.766.255-.81.252-1.872.523-2.734.523-.886 0-1.592-.286-2.203-.534l-.008-.003C7.662 1.21 7.139 1 6.5 1c-.669 0-1.606.229-2.415.478A21.294 21.294 0 0 0 3 1.845v6.433c.22-.078.48-.167.766-.255C4.576 7.77 5.638 7.5 6.5 7.5c.847 0 1.548.28 2.158.525l.028.01C9.32 8.29 9.86 8.5 10.5 8.5c.668 0 1.606-.229 2.415-.478A21.317 21.317 0 0 0 14 7.655V1.222z"/>
|
||||
</svg>
|
||||
</a>
|
||||
-->
|
||||
<?php } ?>
|
||||
</div>
|
||||
<?php if ($magnet->metaDescription) { ?>
|
||||
<div class="margin-y-8"><?php echo $magnet->metaDescription ?></div>
|
||||
<?php } ?>
|
||||
<?php if ($magnet->keywords) { ?>
|
||||
<div class="margin-y-8">
|
||||
<?php foreach ($magnet->keywords as $keyword) { ?>
|
||||
<small>
|
||||
<a href="<?php echo WEBSITE_URL ?>/index.php?query=<?php echo urlencode($keyword) ?>">#<?php echo htmlentities($keyword) ?></a>
|
||||
</small>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div class="margin-t-8">
|
||||
<?php if (!$magnet->public) { ?>
|
||||
<span class="margin-r-8" title="<?php echo _('Private') ?>">
|
||||
<svg class="width-13px" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye-slash-fill" viewBox="0 0 16 16">
|
||||
<path d="m10.79 12.912-1.614-1.615a3.5 3.5 0 0 1-4.474-4.474l-2.06-2.06C.938 6.278 0 8 0 8s3 5.5 8 5.5a7.029 7.029 0 0 0 2.79-.588zM5.21 3.088A7.028 7.028 0 0 1 8 2.5c5 0 8 5.5 8 5.5s-.939 1.721-2.641 3.238l-2.062-2.062a3.5 3.5 0 0 0-4.474-4.474L5.21 3.089z"/>
|
||||
<path d="M5.525 7.646a2.5 2.5 0 0 0 2.829 2.829l-2.83-2.829zm4.95.708-2.829-2.83a2.5 2.5 0 0 1 2.829 2.829zm3.171 6-12-12 .708-.708 12 12-.708.708z"/>
|
||||
</svg>
|
||||
</span>
|
||||
<?php } ?>
|
||||
<?php if (!$magnet->approved) { ?>
|
||||
<span class="margin-r-8" title="<?php echo _('Waiting for approve') ?>">
|
||||
<svg class="width-13px" xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-hourglass-split" viewBox="0 0 16 16">
|
||||
<path d="M2.5 15a.5.5 0 1 1 0-1h1v-1a4.5 4.5 0 0 1 2.557-4.06c.29-.139.443-.377.443-.59v-.7c0-.213-.154-.451-.443-.59A4.5 4.5 0 0 1 3.5 3V2h-1a.5.5 0 0 1 0-1h11a.5.5 0 0 1 0 1h-1v1a4.5 4.5 0 0 1-2.557 4.06c-.29.139-.443.377-.443.59v.7c0 .213.154.451.443.59A4.5 4.5 0 0 1 12.5 13v1h1a.5.5 0 0 1 0 1h-11zm2-13v1c0 .537.12 1.045.337 1.5h6.326c.216-.455.337-.963.337-1.5V2h-7zm3 6.35c0 .701-.478 1.236-1.011 1.492A3.5 3.5 0 0 0 4.5 13s.866-1.299 3-1.48V8.35zm1 0v3.17c2.134.181 3 1.48 3 1.48a3.5 3.5 0 0 0-1.989-3.158C8.978 9.586 8.5 9.052 8.5 8.351z"/>
|
||||
</svg>
|
||||
</span>
|
||||
<?php } ?>
|
||||
<sup><?php echo $magnet->timeUpdated ? sprintf('Updated %s', $magnet->timeUpdated) : sprintf('Added %s', $magnet->timeAdded) ?></sup>
|
||||
<span class="float-right margin-l-12">
|
||||
<a href="<?php echo WEBSITE_URL ?>/action.php?target=star&magnetId=<?php echo $magnet->magnetId ?>&callback=<?php echo base64_encode(sprintf('%s/index.php?query=%s#magnet-%s', WEBSITE_URL, urlencode($request->query), $magnet->magnetId)) ?>" title="<?php echo _('Star') ?>">
|
||||
<?php if ($magnet->star->status) { ?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-star-fill" viewBox="0 0 16 16">
|
||||
<path d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"/>
|
||||
</svg>
|
||||
<?php } else { ?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-star" viewBox="0 0 16 16">
|
||||
<path d="M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256 4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73 3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356-.83 4.73zm4.905-2.767-3.686 1.894.694-3.957a.565.565 0 0 0-.163-.505L1.71 6.745l4.052-.576a.525.525 0 0 0 .393-.288L8 2.223l1.847 3.658a.525.525 0 0 0 .393.288l4.052.575-2.906 2.77a.565.565 0 0 0-.163.506l.694 3.957-3.686-1.894a.503.503 0 0 0-.461 0z"/>
|
||||
</svg>
|
||||
<?php } ?>
|
||||
</a>
|
||||
<sup><?php echo $magnet->star->total ?></sup>
|
||||
</span>
|
||||
<!--
|
||||
<span class="float-right margin-l-12">
|
||||
<a href="<?php echo WEBSITE_URL ?>/magnet.php?magnetId=<?php echo $magnet->magnetId ?>#comment" title="<?php echo _('Comment') ?>">
|
||||
<?php if ($magnet->comment->status) { ?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chat-fill" viewBox="0 0 16 16">
|
||||
<path d="M8 15c4.418 0 8-3.134 8-7s-3.582-7-8-7-8 3.134-8 7c0 1.76.743 3.37 1.97 4.6-.097 1.016-.417 2.13-.771 2.966-.079.186.074.394.273.362 2.256-.37 3.597-.938 4.18-1.234A9.06 9.06 0 0 0 8 15z"/>
|
||||
</svg>
|
||||
<?php } else { ?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chat" viewBox="0 0 16 16">
|
||||
<path d="M2.678 11.894a1 1 0 0 1 .287.801 10.97 10.97 0 0 1-.398 2c1.395-.323 2.247-.697 2.634-.893a1 1 0 0 1 .71-.074A8.06 8.06 0 0 0 8 14c3.996 0 7-2.807 7-6 0-3.192-3.004-6-7-6S1 4.808 1 8c0 1.468.617 2.83 1.678 3.894zm-.493 3.905a21.682 21.682 0 0 1-.713.129c-.2.032-.352-.176-.273-.362a9.68 9.68 0 0 0 .244-.637l.003-.01c.248-.72.45-1.548.524-2.319C.743 11.37 0 9.76 0 8c0-3.866 3.582-7 8-7s8 3.134 8 7-3.582 7-8 7a9.06 9.06 0 0 1-2.347-.306c-.52.263-1.639.742-3.468 1.105z"/>
|
||||
</svg>
|
||||
<?php } ?>
|
||||
</a>
|
||||
<sup><?php echo $magnet->comment->total ?></sup>
|
||||
</span>
|
||||
-->
|
||||
<span class="float-right margin-l-12">
|
||||
<a href="<?php echo WEBSITE_URL ?>/action.php?target=download&magnetId=<?php echo $magnet->magnetId ?>" title="<?php echo _('Download') ?>">
|
||||
<?php if ($magnet->download->status) { ?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down-circle-fill" viewBox="0 0 16 16">
|
||||
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.5 4.5a.5.5 0 0 0-1 0v5.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V4.5z"/>
|
||||
</svg>
|
||||
<?php } else { ?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down-circle" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M1 8a7 7 0 1 0 14 0A7 7 0 0 0 1 8zm15 0A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.5 4.5a.5.5 0 0 0-1 0v5.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V4.5z"/>
|
||||
</svg>
|
||||
<?php } ?>
|
||||
</a>
|
||||
<sup><?php echo $magnet->download->total ?></sup>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<?php } else { ?>
|
||||
<div class="padding-16 margin-y-8 border-radius-3 background-color-night">
|
||||
<div><?php echo _('Hidden content') ?></div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php } else { ?>
|
||||
<div class="padding-16 margin-y-8 border-radius-3 background-color-night">
|
||||
<h2 class="margin-b-8"><?php echo _('Not found') ?></h2>
|
||||
<div><?php echo _('Submit new magnet link by sending address to the search field') ?></div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<?php } else { ?>
|
||||
<div class="padding-16 margin-y-8 border-radius-3 background-color-night">
|
||||
<div class="text-center"><?php echo $response->message ?></div>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<footer>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="column width-100 text-center margin-y-8">
|
||||
<a href="<?php echo WEBSITE_URL ?>/index.php?rss<?php echo $request->query ? sprintf('&query=%s', urlencode($request->query)) : false ?>"><?php echo _('RSS') ?></a>
|
||||
|
|
||||
<?php foreach (TRACKER_LINKS as $name => $value) { ?>
|
||||
<a href="<?php echo $value->announce ?>"><?php echo $name ?></a>
|
||||
/
|
||||
<a href="<?php echo $value->stats ?>"><?php echo _('Stats') ?></a>
|
||||
|
|
||||
<?php } ?>
|
||||
<a href="https://github.com/YGGverse/YGGtracker"><?php echo _('GitHub') ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
<?php } ?>
|
Loading…
x
Reference in New Issue
Block a user