Skip to content
This repository has been archived by the owner on Nov 2, 2020. It is now read-only.

Commit

Permalink
feat(torrents/tags): Add tags page
Browse files Browse the repository at this point in the history
  • Loading branch information
Rhilip committed Jul 19, 2019
1 parent 3f31b88 commit 10be2f8
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 64 deletions.
4 changes: 3 additions & 1 deletion apps/controllers/TorrentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ public function actionDownload()
{
$tid = app()->request->get('id');

$torrent = new Torrent($tid); // If torrent is not exist or can't visit , a notfound exception will throw out........
// TODO add download rate limit

$torrent = new Torrent($tid); // TODO If torrent is not exist or can't visit , a notfound exception should throw out........
$filename = '[' . config('base.site_name') . ']' . $torrent->getTorrentName() . '.torrent';

app()->response->setHeader('Content-Type', 'application/x-bittorrent');
Expand Down
71 changes: 63 additions & 8 deletions apps/controllers/TorrentsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,80 @@ class TorrentsController extends Controller

public function actionIndex()
{
// TODO add pagination support
$fetch = app()->pdo->createCommand('SELECT `id` FROM torrents ORDER BY added_at DESC LIMIT 50;')->queryColumn();
return $this->actionSearch();
}

public function actionSearch()
{
// FIXME use model to support SQL-search or elesticsearch
// TODO add URI level Cache

$limit = app()->request->get('limit',50);
if (!filter_var($limit,FILTER_VALIDATE_INT) || $limit > 100) {
$limit = 100;
}
$page = app()->request->get('page',1);
if (!filter_var($page,FILTER_VALIDATE_INT)) {
$page = 1;
}

$_tags = app()->request->get('tags');
if ($_tags) {
$tags = array_map('trim', explode(',', $_tags));
} else {
$tags = [];
}

$fetch = app()->pdo->createCommand([
['SELECT DISTINCT t.`id`, t.`added_at` FROM `torrents` t '],
['INNER JOIN map_torrents_tags mtt on t.id = mtt.torrent_id INNER JOIN tags t2 on mtt.tag_id = t2.id ', 'if' => count($tags)],
['WHERE 1=1 '],
['AND t2.tag IN(:tags) ', 'if' => count($tags), 'params' => ['tags' => $tags]],
['ORDER BY `t`.`added_at` DESC '],
['LIMIT :offset, :rows', 'params' => ['offset' => ($page - 1) * $limit, 'rows' => $limit]],
])->queryColumn();

$count = app()->pdo->createCommand([
['SELECT COUNT(t.`id`) FROM `torrents` t '],
['INNER JOIN map_torrents_tags mtt on t.id = mtt.torrent_id INNER JOIN tags t2 on mtt.tag_id = t2.id ', 'if' => count($tags)],
['WHERE 1=1 '],
['AND t2.tag IN(:tags) ', 'if' => count($tags), 'params' => ['tags' => $tags]],
])->queryScalar();

$torrents = array_map(function ($id) {
return new Torrent($id);
}, $fetch);

return $this->render('torrents/list', [
'count' => $count,
'limit' => $limit,
'torrents' => $torrents
]);
}

public function actionSearch()
{
// TODO
}

public function actionTags()
{
// TODO
$search = trim(app()->request->get('search', ''));
$limit = app()->request->get('limit',50);
if (!filter_var($limit,FILTER_VALIDATE_INT) || $limit > 100) {
$limit = 100;
}
$page = app()->request->get('page',1);
if (!filter_var($page,FILTER_VALIDATE_INT)) $page = 1;

$tags = app()->pdo->createCommand([
['SELECT tags.*,COUNT(mtt.id) as `count` FROM tags LEFT JOIN map_torrents_tags mtt on tags.id = mtt.tag_id '],
['WHERE `tags`.`tag` LIKE :tag', 'if' => !empty($search), 'params' => ['tag' => '%' . $search . '%']],
['GROUP BY tags.id ORDER BY `tags`.`pinned`,`count` DESC '],
['LIMIT :offset, :rows', 'params' => ['offset' => ($page - 1) * $limit, 'rows' => $limit]],
])->queryAll();

if (count($tags) == 1) { // If this search tag is unique, just redirect to search page
return app()->response->redirect('/torrents/search?tags=' . $search);
}

$tag_count = app()->pdo->createCommand('SELECT COUNT(`id`) FROM `tags`')->queryScalar(); // TODO use `site_status` tables to store those data

return $this->render('torrents/tags', ['search' => $search, 'tags' => $tags, 'count' => $tag_count]);
}
}
3 changes: 3 additions & 0 deletions apps/public/static/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ body{background-color:#f6f6f6}
.required:after{position: static}

.captcha_img_load{width:150px;height:40px}
.pager-unset-margin{margin: unset}

/*-----------------------------------------------------------------------------------*/
/* 2. Layout of Header, Navigation & Menus
Expand Down Expand Up @@ -96,6 +97,8 @@ body{background-color:#f6f6f6}
.name-left{width:95%;}
#torrents_table td[data-item] {vertical-align: middle;}

#tags_list{margin-top:20px}

/* '/torrent/upload' */
#torrent_upload_table > tbody > tr > td:first-child{vertical-align:middle;text-align:right}
#torrent_file{display:inline;margin-right:10px;width:220px}
Expand Down
120 changes: 65 additions & 55 deletions apps/views/torrents/list.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
* @var League\Plates\Template\Template $this
* @var array $torrents
* @var \apps\models\Torrent $torrent
* @var int $count
* @var int $limit
*/

$time_now = time();
Expand All @@ -19,64 +21,72 @@

<?php $this->start('title')?>Torrents List<?php $this->end();?>

<?php $this->start('container')?>
<table class="table" id="torrents_table">
<thead>
<tr>
<th class="text-center" style="width: 20px" title="Type">Type</th>
<th class="text-center" style="width: 100%;" title="Torrent">Torrents</th>
<th class="text-center" style="width: 5px" title="Comment"><i class="fas fa-comment-alt fa-fw"></i></th>
<th class="text-center" style="width: 45px" title="Size">Size</th>
<th class="text-center" style="width: 80px" title="Date">Date</th>
<th class="text-center" style="width: 15px" title="Seeders"><i class="fas fa-arrow-up fa-fw color-seeding"></i></th>
<th class="text-center" style="width: 15px" title="Leechers"><i class="fas fa-arrow-down fa-fw color-leeching"></i></th>
<th class="text-center" style="width: 15px" title="Completed"><i class="fas fa-check fa-fw color-completed"></i></th>
<th class="text-center" style="width: 50px" title="Owner"><i class="fas fa-user fa-fw"></i></th>
</tr>
</thead>
<tbody>
<?php foreach ($torrents as $torrent): ?>
<tr data-tid="<?= $torrent->getId() ?>">
<td class="text-center" style="margin: 0;padding: 0"><?= ($torrent->getCategory())->getName() ?></td>
<td>
<div>
<div class="pull-left name-left">
<div data-item="t-main-info" data-title="<?= $this->e($torrent->getTitle()) ?>">
<!--suppress HtmlUnknownTarget -->
<a href="/torrent/details?id=<?= $torrent->getId() ?>" target="_blank"><b><?= $torrent->getTitle() ?></b></a>
</div>
<div data-item="t-sub-info">
<?php $tags = $torrent->getTags(); ?>
<?php if (count($tags) > 0) : ?>
<span data-item="t-tags">
<?php $this->start('container') ?>
<!-- TODO insert container head : For example, Search toolbox..... -->
<div class="row">
<div class="col-md-12">
<table class="table" id="torrents_table">
<thead>
<tr>
<th class="text-center" style="width: 20px" title="Type">Type</th>
<th class="text-center" style="width: 100%;" title="Torrent">Torrents</th>
<th class="text-center" style="width: 5px" title="Comment"><i class="fas fa-comment-alt fa-fw"></i></th>
<th class="text-center" style="width: 45px" title="Size">Size</th>
<th class="text-center" style="width: 80px" title="Date">Date</th>
<th class="text-center" style="width: 15px" title="Seeders"><i class="fas fa-arrow-up fa-fw color-seeding"></i></th>
<th class="text-center" style="width: 15px" title="Leechers"><i class="fas fa-arrow-down fa-fw color-leeching"></i></th>
<th class="text-center" style="width: 15px" title="Completed"><i class="fas fa-check fa-fw color-completed"></i></th>
<th class="text-center" style="width: 50px" title="Owner"><i class="fas fa-user fa-fw"></i></th>
</tr>
</thead>
<tbody>
<?php foreach ($torrents as $torrent): ?>
<tr data-tid="<?= $torrent->getId() ?>">
<td class="text-center" style="margin: 0;padding: 0"><?= ($torrent->getCategory())->getName() ?></td>
<td>
<div>
<div class="pull-left name-left">
<div data-item="t-main-info">
<span data-item="t-title" data-title="<?= $this->e($torrent->getTitle()) ?>">
<a href="/torrent/details?id=<?= $torrent->getId() ?>" target="_blank"><b><?= $torrent->getTitle() ?></b></a>
</span>
</div>
<div data-item="t-sub-info">
<?php $tags = $torrent->getTags(); ?>
<?php if (count($tags) > 0) : ?>
<span data-item="t-tags">
<?php foreach ($torrent->getTags() as $tag): ?>
<?php if ($tag['pinned']): // Only show pinned tag in torrent list ?>
<a href="/torrents/tags?tag=<?= $tag['tag'] ?>" class="label label-outline <?= $tag['class_name'] ?>"><?= $tag['tag'] ?></a>
<a href="/torrents/search?tags=<?= $tag['tag'] ?>" class="tag label label-outline <?= $tag['class_name'] ?>"><?= $tag['tag'] ?></a>
<?php endif; ?>
<?php endforeach; ?>
</span>&nbsp;
<?php endif; ?>
<span data-item="subtitle" data-subtitle="<?= $this->e($torrent->getSubtitle()) ?>"><?= $torrent->getSubtitle() ?></span>
</div>
</div>
<div class="pull-right">
<div class="text-right">
<!--suppress HtmlUnknownTarget --><a href="/torrent/download?id=<?= $torrent->getId() ?>"><i class="fas fa-download fa-fw"></i></a>
<a class="torrent-favour" href="javascript:" data-tid="<?= $torrent->getId() ?>"><i class="<?= app()->user->inBookmarkList($torrent->getId()) ? 'fas' : 'far' ?> fa-star fa-fw"></i></a>
</div>
</div>

</div>
</td>
<td class="text-center" data-item="t-commit" data-commit="0">0</td> <!-- TODO -->
<td class="text-center" data-item="t-size" data-size="<?= $torrent->getTorrentSize() ?>"><?= $this->batch($torrent->getTorrentSize(),'format_bytes_compact') ?></td>
<td class="text-center" data-item="t-added-date" data-timestamp="<?= strtotime($torrent->getAddedAt()) ?>" data-ttl="<?= $time_now - strtotime($torrent->getAddedAt()) ?>"><nobr><?= str_replace(' ','<br />',$torrent->getAddedAt()) ?></nobr></td>
<td class="text-center" data-item="t-seeder" data-seeder="<?= $this->e($torrent->getComplete()) ?>"><?= number_format($torrent->getComplete()) ?></td>
<td class="text-center" data-item="t-leecher" data-leecher="<?= $this->e($torrent->getIncomplete()) ?>"><?= number_format($torrent->getIncomplete()) ?></td>
<td class="text-center" data-item="t-completed" data-completed="<?= $this->e($torrent->getDownloaded()) ?>"><?= number_format($torrent->getDownloaded()) ?></td>
<td class="text-center" data-item="t-uploader" data-uploader="<?= $this->e($torrent->getOwnerId()) ?>"><?= get_torrent_uploader($torrent) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
<span data-item="subtitle" data-subtitle="<?= $this->e($torrent->getSubtitle()) ?>"><?= $torrent->getSubtitle() ?></span>
</div>
</div>
<div class="pull-right">
<div class="text-right">
<!--suppress HtmlUnknownTarget --><a href="/torrent/download?id=<?= $torrent->getId() ?>"><i class="fas fa-download fa-fw"></i></a>
<a class="torrent-favour" href="javascript:" data-tid="<?= $torrent->getId() ?>"><i class="<?= app()->user->inBookmarkList($torrent->getId()) ? 'fas' : 'far' ?> fa-star fa-fw"></i></a>
</div>
</div>
</div>
</td>
<td class="text-center" data-item="t-commit" data-commit="0">0</td> <!-- TODO -->
<td class="text-center" data-item="t-size" data-size="<?= $torrent->getTorrentSize() ?>"><?= $this->batch($torrent->getTorrentSize(),'format_bytes_compact') ?></td>
<td class="text-center" data-item="t-added-date" data-timestamp="<?= strtotime($torrent->getAddedAt()) ?>" data-ttl="<?= $time_now - strtotime($torrent->getAddedAt()) ?>"><nobr><?= str_replace(' ','<br />',$torrent->getAddedAt()) ?></nobr></td>
<td class="text-center" data-item="t-seeder" data-seeder="<?= $this->e($torrent->getComplete()) ?>"><?= number_format($torrent->getComplete()) ?></td>
<td class="text-center" data-item="t-leecher" data-leecher="<?= $this->e($torrent->getIncomplete()) ?>"><?= number_format($torrent->getIncomplete()) ?></td>
<td class="text-center" data-item="t-completed" data-completed="<?= $this->e($torrent->getDownloaded()) ?>"><?= number_format($torrent->getDownloaded()) ?></td>
<td class="text-center" data-item="t-uploader" data-uploader="<?= $this->e($torrent->getOwnerId()) ?>"><?= get_torrent_uploader($torrent) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<div class="text-center">
<ul class="pager pager-unset-margin" data-ride="remote_pager" data-rec-total="<?= $count ?>" data-rec-per-page="<?= $limit ?? 50 ?>"></ul>
</div>
</div>
</div>
<?php $this->end();?>
55 changes: 55 additions & 0 deletions apps/views/torrents/tags.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php
/**
* Created by PhpStorm.
* User: Rhilip
* Date: 7/19/2019
* Time: 7:39 PM
*
* @var League\Plates\Template\Template $this
* @var array $tags
* @var string $search
* @var int $count
* @var int $limit
*/
?>

<?= $this->layout('layout/base') ?>

<?php $this->start('title')?>Tags List<?php $this->end();?>

<?php $this->start('container')?>
<div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form method="get">
<div class="input-group">
<div class="input-control search-box search-box-circle has-icon-left has-icon-righ"
id="tags_search_div">
<input id="tags_search_input" type="text" name="search" class="form-control search-input" value="<?= $search ?? '' ?>">
<label for="tags_search_input" class="input-control-icon-left search-icon">
<i class="icon icon-search"></i>
</label>
</div>
<span class="input-group-btn">
<button class="btn btn-primary" type="submit">Search</button>
</span>
</div>
</form>
</div>
</div>
</div>
<div class="col-md-10 col-md-offset-1">
<div id="tags_list">
<?php foreach ($tags as $tag): ?>
<a class="btn" href="/torrents/search?tags=<?= $tag['tag'] ?>"><?= $tag['tag'] ?> <span class="label label-badge <?= $tag['class_name'] ?>"><?= $tag['count'] ?></span></a>
<?php endforeach; ?>
</div>
<div class="text-center">
<ul class="pager" data-ride="remote_pager" data-rec-total="<?= $count ?>" data-rec-per-page="<?= $limit ?? 50 ?>"></ul>
</div>
</div>
</div>
<?php $this->end();?>


0 comments on commit 10be2f8

Please sign in to comment.