Add DB based collection regexes and import count for nzbs.

This commit is contained in:
Darko
2015-02-26 10:16:53 +01:00
parent 715311c936
commit dfec9156dd
17 changed files with 696 additions and 7 deletions
@@ -0,0 +1,64 @@
DROP TABLE IF EXISTS collection_regexes;
CREATE TABLE collection_regexes (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
group_regex VARCHAR(255) NULL COMMENT 'This is a regex to match against usenet groups',
regex VARCHAR(5000) NOT NULL COMMENT 'Regex used for collection grouping',
status TINYINT(1) UNSIGNED NOT NULL DEFAULT '1' COMMENT '1=ON 0=OFF',
description VARCHAR(1000) NOT NULL COMMENT 'Optional extra details on this regex',
ordinal INT SIGNED NOT NULL DEFAULT '0' COMMENT 'Order to run the regex in',
PRIMARY KEY (id),
INDEX ix_collection_regexes_group_regex (group_regex),
INDEX ix_collection_regexes_status (status),
INDEX ix_collection_regexes_ordinal (ordinal)
)
ENGINE = MYISAM
DEFAULT CHARSET = utf8
COLLATE = utf8_unicode_ci
AUTO_INCREMENT = 100000;
INSERT INTO collection_regexes (id, group_regex, regex, status, description, ordinal)
VALUES (
1,
'alt\\.binaries\\.teevee',
'/(?P<match1>\\[[\\d#]+\\]-\\[.+?\\]-\\[.+?\\])-\\[ (?P<match2>.+?) \\][- ]\\[\\d+\\/\\d+\\] - ".+?" yEnc$/i',
1,
'[278997]-[FULL]-[#a.b.erotica]-[ chi-the.walking.dead.xxx ]-[06/51] - "chi-the.walking.dead.xxx-s.mp4" yEnc ::: [######]-[FULL]-[#a.b.teevee@EFNet]-[ Misfits.S01.SUBPACK.DVDRip.XviD-P0W4DVD ] [1/5] - "Misfits.S01.SUBPACK.DVDRip.XviD-P0W4DVD.nfo" yEnc ::: Re: [147053]-[FULL]-[#a.b.teevee]-[ Top_Gear.20x04.HDTV_x264-FoV ]-[11/59] - "top_gear.20x04.hdtv_x264-fov.r00" yEnc',
0
), (
2,
'alt\\.binaries\\.teevee',
'/(?P<match1>\\[[\\d#]+\\]-\\[.+?\\]-\\[.+?\\])-\\[ (?P<match2>.+?) \\][ -]{0,3}".+?" yEnc$/i',
1,
'[185409]-[FULL]-[a.b.teeveeEFNet]-[ Dragon.Ball.Z.S03E24.1080p.WS.BluRay.x264-CCAT ]-"dragon.ball.z.s03e24.1080p.ws.bluray.x264-ccat.nfo" yEnc',
1
), (
3,
'alt\\.binaries\\.teevee',
'/^(?P<match1>\\[#a\\.b\\.teevee\\] .+? - \\[)\\d+\\/\\d+\\] - ".+?" yEnc$/',
1,
'[#a.b.teevee] Parks.and.Recreation.S01E01.720p.WEB-DL.DD5.1.H.264-CtrlHD - [01/24] - "Parks.and.Recreation.S01E01.720p.WEB-DL.DD5.1.H.264-CtrlHD.nfo"',
2
), (
4,
'alt\\.binaries\\.teevee',
'/^(?P<match1>[a-z0-9]+ - )\\[\\d+\\/\\d+\\] - "[a-z0-9]+\\..+?" yEnc$/',
1,
'ah63jka93jf0jh26ahjas558 - [01/22] - "ah63jka93jf0jh26ahjas558.par2" yEnc',
3
), (
5,
'alt\\.binaries\\.teevee',
'/^(?P<match1>[a-z0-9]+ \\()\\d+\\/\\d+\\) ".+?" - \\d+[,.]\\d+ [mMkKgG][bB] - yEnc$/',
1,
'fhdbg34rgjdsfd008c (42/43) "fhdbg34rgjdsfd008c.vol062+64.par2" - 3,68 GB - yEnc',
4
), (
6,
'alt\\.binaries\\.teevee',
'/^(?P<match1>[a-zA-Z0-9]+)\\[\\d+\\/\\d+\\] - ".+?" yEnc$/',
1,
't2EI3CdWdF0hi5b8L9tkx[08/52] - "t2EI3CdWdF0hi5b8L9tkx.part07.rar" yEnc',
5
);
UPDATE `tmux` SET `value` = '114' WHERE `setting` = 'sqlpatch';
+2
View File
@@ -0,0 +1,2 @@
INSERT IGNORE INTO `tmux` (`setting`, `value`) VALUES ('import_count','50000');
UPDATE `tmux` SET `value` = '115' WHERE `setting` = 'sqlpatch';
+26
View File
@@ -0,0 +1,26 @@
<?php
require_once("config.php");
require_once(WWW_DIR."/lib/adminpage.php");
require_once(WWW_DIR."/lib/CollectionsCleaning.php");
require_once(WWW_DIR."/lib/binaries.php");
// Login Check
$admin = new AdminPage;
if (!isset($_GET['action'])) {
exit();
}
switch($_GET['action']) {
case 1:
$id = (int) $_GET['col_id'];
(new CollectionsCleaning(['Settings' => $admin->settings]))->deleteRegex($id);
print "Regex $id deleted.";
break;
case 2:
$id = (int) $_GET['bin_id'];
(new Binaries(['Settings' => $admin->settings]))->deleteBlacklist($id);
print "Blacklist $id deleted.";
break;
}
@@ -0,0 +1,61 @@
<?php
require_once("config.php");
require_once(WWW_DIR."/lib/adminpage.php");
require_once(WWW_DIR."/lib/CollectionsCleaning.php");
require_once(WWW_DIR."/lib/category.php");
$page = new AdminPage();
$cc = new CollectionsCleaning(['Settings' => $page->settings]);
// Set the current action.
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'view';
switch($action) {
case 'submit':
if ($_POST["group_regex"] == "") {
$page->smarty->assign('error', "Group regex must not be empty!");
break;
}
if ($_POST["regex"] == "") {
$page->smarty->assign('error', "Regex cannot be empty");
break;
}
if ($_POST['description'] == '') {
$_POST['description'] = '';
}
if (!is_numeric($_POST['ordinal']) || $_POST['ordinal'] < 0) {
$page->smarty->assign('error', "Ordinal must be a number, 0 or higher.");
break;
}
if ($_POST["id"] == "") {
$cc->addRegex($_POST);
} else {
$cc->updateRegex($_POST);
}
header("Location:".WWW_TOP."/collection_regexes-list.php");
break;
case 'view':
default:
if (isset($_GET["id"])) {
$page->title = "Collections Regex Edit";
$id = $_GET["id"];
$r = $cc->getRegexByID($id);
} else {
$page->title = "Collections Regex Add";
$r = ['status' => 1];
}
$page->smarty->assign('regex', $r);
break;
}
$page->smarty->assign('status_ids', array(Category::STATUS_ACTIVE,Category::STATUS_INACTIVE));
$page->smarty->assign('status_names', array( 'Yes', 'No'));
$page->content = $page->smarty->fetch('collection_regexes-edit.tpl');
$page->render();
@@ -0,0 +1,29 @@
<?php
require_once("config.php");
require_once(WWW_DIR."/lib/adminpage.php");
require_once(WWW_DIR."/lib/CollectionsCleaning.php");
$page = new AdminPage();
$cc = new CollectionsCleaning(['Settings' => $page->settings]);
$page->title = "Collections Regex List";
$group = '';
if (isset($_REQUEST['group']) && !empty($_REQUEST['group'])) {
$group = $_REQUEST['group'];
}
$offset = isset($_REQUEST["offset"]) ? $_REQUEST["offset"] : 0;
$regex = $cc->getRegex($group, ITEMS_PER_PAGE, $offset);
$page->smarty->assign('regex', $regex);
$count = $cc->getCount($group);
$page->smarty->assign('pagertotalitems', $count);
$page->smarty->assign('pageroffset', $offset);
$page->smarty->assign('pageritemsperpage', ITEMS_PER_PAGE);
$page->smarty->assign('pagerquerybase', WWW_TOP . "/collection_regexes-list.php?" . $group . "offset=");
$page->smarty->assign('pager', $page->smarty->fetch("pager.tpl"));
$page->content = $page->smarty->fetch('collection_regexes-list.tpl');
$page->render();
@@ -0,0 +1,30 @@
<?php
require_once("config.php");
require_once(WWW_DIR."/lib/adminpage.php");
require_once(WWW_DIR."/lib/site.php");
require_once(WWW_DIR."/lib/CollectionsCleaning.php");
$page = new AdminPage();
$s = new Sites();
$site = $s->get();
$page->title = "Collections Regex Test";
$tpg = $page->site->tablepergroup;
$page->smarty->assign('tpg', $tpg);
if ($tpg) {
$group = trim(isset($_POST['group']) && !empty($_POST['group']) ? $_POST['group'] : '');
$regex = trim(isset($_POST['regex']) && !empty($_POST['regex']) ? $_POST['regex'] : '');
$limit = (isset($_POST['limit']) && is_numeric($_POST['limit']) ? $_POST['limit'] : 50);
$page->smarty->assign(['group' => $group, 'regex' => $regex, 'limit' => $limit]);
if ($group && $regex) {
$page->smarty->assign('data', (new CollectionsCleaning(['Settings' => $page->settings]))->testRegex($group, $regex, $limit));
}
}
$page->content = $page->smarty->fetch('collection_regexes-test.tpl');
$page->render();
+278 -2
View File
@@ -55,14 +55,208 @@ class CollectionsCleaning
public $subject = '';
/**
*
* @var \DB
*/
public function __construct()
public $pdo;
/**
* @var array Cache of regex and their TTL.
*/
protected $_regexCache;
/**
* @param array $options Class instances.
*/
public function __construct(array $options = array())
{
// Extensions.
$this->e0 = self::REGEX_FILE_EXTENSIONS;
$this->e1 = self::REGEX_FILE_EXTENSIONS . self::REGEX_END;
$this->e2 = self::REGEX_FILE_EXTENSIONS . self::REGEX_SUBJECT_SIZE . self::REGEX_END;
$defaults = [
'Settings' => null,
];
$options += $defaults;
$this->pdo = ($options['Settings'] instanceof DB ? $options['Settings'] : new DB());
}
/**
* Add a new regex.
*
* @param array $data
*
* @return bool
*/
public function addRegex(array $data)
{
return (bool)$this->pdo->queryInsert(
sprintf(
'INSERT INTO collection_regexes (group_regex, regex, status, description, ordinal) VALUES (%s, %s, %d, %s, %d)',
trim($this->pdo->escapeString($data['group_regex'])),
trim($this->pdo->escapeString($data['regex'])),
$data['status'],
trim($this->pdo->escapeString($data['description'])),
$data['ordinal']
)
);
}
/**
* Update a regex with new info.
*
* @param array $data
*
* @return bool
*/
public function updateRegex(array $data)
{
return (bool)$this->pdo->queryExec(
sprintf(
'UPDATE collection_regexes
SET group_regex = %s, regex = %s, status = %d, description = %s, ordinal = %d
WHERE id = %d',
trim($this->pdo->escapeString($data['group_regex'])),
trim($this->pdo->escapeString($data['regex'])),
$data['status'],
trim($this->pdo->escapeString($data['description'])),
$data['ordinal'],
$data['id']
)
);
}
/**
* Get a single regex using its id.
*
* @param int $id
*
* @return array
*/
public function getRegexByID($id)
{
return $this->pdo->queryOneRow(sprintf('SELECT * FROM collection_regexes WHERE id = %d', $id));
}
/**
* Get all regex.
*
* @param string $group_regex Optional, a keyword to find a group.
* @param int $limit Optional, amount of results to limit.
* @param int $offset Optional, the offset to use when limiting the result set.
*
* @return array
*/
public function getRegex($group_regex = '', $limit = 0, $offset = 0)
{
return $this->pdo->query(
sprintf(
'SELECT * FROM collection_regexes %s %s',
($group_regex ? ('WHERE group_regex ' . $this->pdo->likeString($group_regex)) : ''),
($limit ? ('LIMIT ' . $limit . ' OFFSET ' . $offset) : '')
)
);
}
/**
* Get the count of regex in the DB.
*
* @param string $group_regex Optional, keyword to find a group.
*
* @return int
*/
public function getCount($group_regex = '')
{
$query = $this->pdo->queryOneRow(
sprintf(
'SELECT COUNT(id) AS count FROM collection_regexes %s',
($group_regex ? ('WHERE group_regex ' . $this->pdo->likeString($group_regex)) : '')
)
);
return (int)$query['count'];
}
/**
* Delete a regex using its id.
*
* @param int $id
*/
public function deleteRegex($id)
{
$this->pdo->queryExec('DELETE FROM collection_regexes WHERE id = ' . $id);
}
/**
* Test a regex for a group name.
*
* Requires table per group to be on.
*
* @param string $groupName
* @param string $regex
* @param int $limit
*
* @return array
*/
public function testRegex($groupName, $regex, $limit)
{
$groups = new Groups(['Settings' => $this->pdo]);
$groupID = $groups->getIDByName($groupName);
if (!$groupID) {
return [];
}
$tableNames = $groups->getCBPTableNames(true, $groupID);
$rows = $this->pdo->query(
sprintf(
'SELECT
b.name, b.totalparts, b.currentparts, b.binaryhash,
c.fromname, c.collectionhash
FROM %s b
INNER JOIN %s c ON c.id = b.collection_id',
$tableNames['bname'], $tableNames['cname']
)
);
$data = [];
if ($rows) {
$limit--;
$hashes = [];
foreach ($rows as $row) {
if (preg_match($regex, $row['name'], $matches)) {
ksort($matches);
$string = $string2 = '';
foreach ($matches as $key => $match) {
if (!is_int($key)) {
$string .= $match;
$string2 .= '<br/>' . $key . ': ' . $match;
}
}
$files = 0;
if (preg_match('/[[(\s](\d{1,5})(\/|[\s_]of[\s_]|-)(\d{1,5})[])\s$:]/i', $row['name'], $fileCount)) {
$files = $fileCount[3];
}
$newCollectionHash = sha1($string . $row['fromname'] . $groupID . $files);
$data['New hash: ' . $newCollectionHash . $string2][$row['binaryhash']] = [
'file_name' => $row['name'],
'file_total_parts' => $row['totalparts'],
'file_current_parts' => $row['currentparts'],
'collection_poster' => $row['fromname'],
'old_collection_hash' => $row['collectionhash'],
];
if ($limit > 0) {
if (count($hashes) > $limit) {
break;
}
$hashes[$newCollectionHash] = '';
}
}
}
}
return $data;
}
/**
@@ -77,6 +271,13 @@ class CollectionsCleaning
{
$this->subject = $subject;
$this->groupName = $groupName;
// Try DB regex first.
$potentialString = $this->_processDBRegex();
if ($potentialString) {
return $potentialString;
}
switch ($groupName) {
case 'alt.binaries.0day.stuffz':
return $this->_0daystuffz();
@@ -271,6 +472,81 @@ class CollectionsCleaning
}
}
/**
* Get the regex from the DB, cache them locally for 15 mins.
* Cache them also in the cache server, as this script might be terminated.
*/
protected function _fetchRegex()
{
// Check if we need to do an initial cache or refresh our cache.
if (isset($this->_regexCache[$this->groupName]['ttl']) && (time() - $this->_regexCache[$this->groupName]['ttl']) < 900) {
return;
}
// Get all regex from DB which match the current group name. Cache them for 15 minutes. #CACHEDQUERY#
$this->_regexCache[$this->groupName]['regex'] = $this->pdo->query(
sprintf(
'SELECT c.regex FROM collection_regexes c WHERE %s REGEXP c.group_regex AND c.status = 1 ORDER BY c.ordinal ASC, c.group_regex ASC',
$this->pdo->escapeString($this->groupName)
), true, 900
);
// Set the TTL.
$this->_regexCache[$this->groupName]['ttl'] = time();
}
/**
* This will process the regex stored in the DB before trying hardcoded regex below.
*
* @return string
*/
protected function _processDBRegex()
{
$this->_fetchRegex();
$returnString = '';
// If there are no regex, return and try regex in this file.
if ($this->_regexCache[$this->groupName]['regex']) {
foreach ($this->_regexCache[$this->groupName]['regex'] as $regex) {
$returnString = $this->_matchDBRegex($regex['regex']);
// If this regex found something, break and return, or else continue trying other regex.
if ($returnString) {
break;
}
}
}
return $returnString;
}
/**
* Find matches on a regex taken from the database.
*
* Requires at least 1 named captured group.
*
* @param string $regex
*
* @return string
*/
protected function _matchDBRegex($regex)
{
$returnString = '';
if (preg_match($regex, $this->subject, $matches)) {
if (count($matches) > 0) {
// Sort the keys, the named key matches will be concatenated in this order.
ksort($matches);
foreach ($matches as $key => $value) {
// Ignore non-named capture groups. Only named capture groups are important.
if (is_int($key)) {
continue;
}
// Concatenate the string to return.
$returnString .= $value;
}
}
}
return $returnString;
}
// a.b.0daystuffz
protected function _0daystuffz()
{
+1
View File
@@ -212,6 +212,7 @@ class Tmux
(%1\$s 'seq_timer') AS seq_timer,
(%1\$s 'bins_timer') AS bins_timer,
(%1\$s 'back_timer') AS back_timer,
(%1\$s 'import_count') AS import_count,
(%1\$s 'import_timer') AS import_timer,
(%1\$s 'rel_timer') AS rel_timer,
(%1\$s 'fix_timer') AS fix_timer,
+1 -1
View File
@@ -117,7 +117,7 @@ class TmuxOutput extends Tmux
$buffer = '';
$state = ($this->runVar['settings']['is_running'] == 1) ? 'Running' : 'Disabled';
//$version = $this->_tvers . 'r' . $this->_vers;
$tversion = '0.6r0046';
$tversion = '0.6r0052';
$buffer .= sprintf($this->tmpMasks[2],
"Monitor $state v$tversion @ $this->_tvers [" . $this->_vers ."]: ",
+1 -1
View File
@@ -357,7 +357,7 @@ class TmuxRun extends Tmux
if (($runVar['settings']['import'] != 0) && ($runVar['killswitch']['pp'] == false)) {
$log = $this->writelog($runVar['panes']['zero'][1]);
shell_exec("tmux respawnp -t{$runVar['constants']['tmux_session']}:0.1 ' \
{$runVar['commands']['_phpn']} {$runVar['paths']['misc']}update_scripts/nix_scripts/multiprocessing/import.php {$runVar['settings']['nzbs']} {$runVar['settings']['nzbthreads']} true {$useFilenames} false $log; \
{$runVar['commands']['_phpn']} {$runVar['paths']['misc']}update/nix/multiprocessing/import.php {$runVar['settings']['nzbs']} {$runVar['settings']['nzbthreads']} true true {$useFilenames} {$runVar['settings']['import_count']} $log; \
date +\"{$this->_dateFormat}\"; {$runVar['commands']['_sleep']} {$runVar['settings']['import_timer']}' 2>&1 1> /dev/null"
);
+1 -1
View File
@@ -181,7 +181,7 @@ class Binaries
$this->_groups = ($options['Groups'] instanceof \Groups ? $options['Groups'] : new \Groups(['Settings' => $this->_pdo]));
$this->_colorCLI = ($options['ColorCLI'] instanceof \ColorCLI ? $options['ColorCLI'] : new \ColorCLI());
$this->_nntp = ($options['NNTP'] instanceof \NNTP ? $options['NNTP'] : new \NNTP(['Echo' => $this->_colorCLI, 'Settings' => $this->_pdo, 'ColorCLI' => $this->_colorCLI]));
$this->_collectionsCleaning = ($options['CollectionsCleaning'] instanceof \CollectionsCleaning ? $options['CollectionsCleaning'] : new \CollectionsCleaning());
$this->_collectionsCleaning = ($options['CollectionsCleaning'] instanceof \CollectionsCleaning ? $options['CollectionsCleaning'] : new \CollectionsCleaning(['Settings' => $this->_pdo]));
$this->_debug = (NN_DEBUG || NN_LOGGING);
@@ -389,7 +389,7 @@ function ajax_sharing_toggle_all(status)
$.ajax({
url : WWW_TOP + '/admin/ajax_sharing_settings.php?rand=' + rand_no,
data : { toggle_all: status },
dataType : "html",
dataType : "html"
});
}
else
@@ -631,6 +631,30 @@ function ajax_welcome_msg(bln)
});
}
/**
* ajax_collection_regex_delete()
*
* @param id binary id
*/
function ajax_collection_regex_delete(id)
{
// no caching of results
var rand_no = Math.random();
$.ajax({
url : WWW_TOP + '/admin/ajax_regex.php?action=1&rand=' + rand_no,
data : { col_id: id},
dataType : "html",
success : function(data)
{
$('div#message').html(data);
$('div#message').show('fast', function() {});
$('#row-'+id).fadeOut(2000);
$('#message').fadeOut(5000);
},
error: function(xhr,err,e) { alert( "Error in ajax_collection_regex_delete: " + err ); }
});
}
jQuery(function($){
$('#regexGroupSelect').change(function() {
@@ -8,6 +8,13 @@
<li><a href="{$smarty.const.WWW_TOP}/category-list.php?action=add">Edit</a> Categories</li>
<li><a href="{$smarty.const.WWW_TOP}/group-list.php">View</a> <a style="padding:0;" href="{$smarty.const.WWW_TOP}/group-edit.php">Add</a> <a style="padding:0;" href="{$smarty.const.WWW_TOP}/group-bulk.php">BulkAdd</a> Groups</li>
<li><a href="{$smarty.const.WWW_TOP}/regex-list.php">View</a> <a style="padding:0;" href="{$smarty.const.WWW_TOP}/regex-edit.php?action=add">Add</a> <a style="padding:0;" href="{$smarty.const.WWW_TOP}/regex-test.php">Test</a> <a style="padding:0;" href="{$smarty.const.WWW_TOP}/regex-submit.php">Send</a> Regex</li>
<li class="has-sub"><a href="#">Collections</a>
<ul>
<li><a href="{$smarty.const.WWW_TOP}/collection_regexes-edit.php?action=add">Add</a></li>
<li><a href="{$smarty.const.WWW_TOP}/collection_regexes-test.php?action=add">Test</a></li>
<li class="last"><a href="{$smarty.const.WWW_TOP}/collection_regexes-list.php">View</a></li>
</ul>
</li>
<li><a href="{$smarty.const.WWW_TOP}/binaryblacklist-list.php">View</a> <a style="padding:0;" href="{$smarty.const.WWW_TOP}/binaryblacklist-edit.php?action=add">Add</a> Blacklist</li>
<li><a href="{$smarty.const.WWW_TOP}/release-list.php">View Releases</a></li>
<li><a href="{$smarty.const.WWW_TOP}/preview-list.php">View Previews</a></li>
@@ -0,0 +1,74 @@
<h1>{$page->title}</h1>
{if $error != ''}
<div class="error">{$error}</div>
{/if}
<form action="{$SCRIPT_NAME}?action=submit" method="POST">
<table class="input">
<tr>
<td><label for="group_regex">Group:</label></td>
<td>
<input type="hidden" name="id" value="{$regex.id}" />
<input type="text" id="group_regex" name="group_regex" value="{$regex.group_regex|escape:html}" />
<div class="hint">
Regex to match against a group or multiple groups.<br />
Delimiters are already added, and PCRE_CASELESS is added after for case insensitivity.
An example of matching a single group: alt\.binaries\.example<br />
An example of matching multiple groups: alt\.binaries.*
</div>
</td>
</tr>
<tr>
<td><label for="regex">Regex:</label></td>
<td>
<textarea id="regex" name="regex" >{$regex.regex|escape:html}</textarea>
<div class="hint">
The regex to use when matching (grouping) collections.<br />
The regex delimiters are not added, you MUST add them. See <a href="http://php.net/manual/en/regexp.reference.delimiters.php">this</a> page.<br />
To make the regex case insensitive, add i after the last delimiter.<br />
You MUST include at least one regex capture group.<br />
You MUST name your regex capture groups.<br />
A string will be created from your matched capture groups.<br />
The string will form part of a "collection hash".<br />
The collection hash is used to group many parts together, to form the finalized release.<br />
The usenet group and name of the poster are added automatically when hashing.<br />
Capture groups are sorted alphabetically (by capture group name) when concatenating the string.<br />
The regex search will be done case insensitive.
</div>
</td>
</tr>
<tr>
<td><label for="description">Description:</label></td>
<td>
<textarea id="description" name="description" >{$regex.description|escape:html}</textarea>
<div class="hint">
Description for this regex.<br />
You can include an example usenet subject this regex would match on.
</div>
</td>
</tr>
<tr>
<td><label for="ordinal">Ordinal:</label></td>
<td>
<input class="ordinal" id="ordinal" name="ordinal" type="text" value="{$regex.ordinal}" />
<div class="hint">
The order to run this regex in.<br />
Must be a number, 0 or higher.<br />
If multiple regex have the same ordinal, MySQL will randomly sort them.
</div>
</td>
</tr>
<tr>
<td><label for="status">Active:</label></td>
<td>
{html_radios id="status" name='status' values=$status_ids output=$status_names selected=$regex.status separator='<br />'}
<div class="hint">Only active regex are used during the collection matching process.</div>
</td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" value="Save" />
</td>
</tr>
</table>
</form>
@@ -0,0 +1,43 @@
<h1>{$page->title}</h1>
<p>This page lists regex used for grouping usenet collections.</p>
<div id="message"></div>
<form name="groupsearch" action="" style="margin-bottom:5px;">
<label for="group">Search a group:</label>
<input id="group" type="text" name="group" value="{$group}" size="15" />
&nbsp;&nbsp;
<input type="submit" value="Go" />
</form>
{if $regex}
<div>{$pager}</div>
<table style="margin-top:10px;" class="data Sortable highlight">
<tr>
<th style="width:20px;">id</th>
<th>group</th>
<th style="width:25px;">edit</th>
<th>description</th>
<th style="width:40px;">delete</th>
<th>ordinal</th>
<th>status</th>
<th>regex</th>
</tr>
{foreach from=$regex item=row}
<tr id="row-{$row.id}" class="{cycle values=",alt"}">
<td>{$row.id}</td>
<td>{$row.group_regex}</td>
<td title="Edit this regex"><a href="{$smarty.const.WWW_TOP}/collection_regexes-edit.php?id={$row.id}">Edit</a></td>
<td>{$row.description|truncate:50:"...":true}</td>
<td title="Delete this regex"><a href="javascript:ajax_collection_regex_delete({$row.id})" onclick="return confirm('Are you sure? This will delete the regex from this list.');" >Delete</a></td>
<td>{$row.ordinal}</td>
{if $row.status==1}
<td style="color:#00CC66">Active</td>
{else}
<td style="color:#FF0000">Disabled</td>
{/if}
<td title="Edit this regex"><a href="{$smarty.const.WWW_TOP}/collection_regexes-edit.php?id={$row.id}">{$row.regex|escape:html|truncate:50:"...":true}</a></td>
</tr>
{/foreach}
</table>
<div style="margin-top: 15px">{$pager}</div>
{/if}
@@ -0,0 +1,44 @@
<h1>{$page->title}</h1>
<p>This page is used for testing regex for grouping usenet collections.<br />Enter the group name to test and a regex. Limit is how many collections to show max on the page, 0 for no limit(slow).</p>
{if $tpg}
<form name="search" action="" method="post" style="margin-bottom:5px;">
<label for="group" style="padding-right:1px">Group:</label>
<input id="group" type="text" name="group" value="{$group|htmlentities}" size="20" /><br />
<label for="regex" style="padding-right:1px">Regex:</label>
<input id="regex" type="text" name="regex" value="{$regex|htmlentities}" size="100" /><br/>
<label for="limit" style="padding-right:7px">Limit:</label>
<input id="limit" type="text" name="limit" value="{$limit}" size="8" /><br/>
<input type="submit" value="Test" />
</form>
{if $data}
{foreach from=$data key=hash item=collection}
<table style="margin-top:10px;" class="data">
<tr>
<th>{$hash}<br />Current Files: {count($collection)}</th>
</tr>
</table>
<table style="margin-top:10px;" class="data Sortable highlight">
<tr>
<th>name</th>
<th>current parts</th>
<th>total parts</th>
<th>poster</th>
<th>old hash</th>
</tr>
{foreach from=$collection item=row}
<tr id="row-{$row.new_collection_hash}" class="{cycle values=",alt"}">
<td>{$row.file_name}</td>
<td>{$row.file_current_parts}</td>
<td>{$row.file_total_parts}</td>
<td>{$row.collection_poster}</td>
<td>{$row.old_collection_hash}</td>
</tr>
{/foreach}
</table>
{/foreach}
{/if}
{else}
<p>The Table Per Group setting is required to be on to use this page, for performance reasons.</p>
{/if}
@@ -293,7 +293,7 @@
</tr>
<tr>
<td style="width:180px;"><label for="nzbs">Nzbs:</label></td>
<td style="width:180px;"><label for="nzbs">Nzbs Folder:</label></td>
<td>
<input id="nzbs" class="long" name="nzbs" type="text" value="{$ftmux->nzbs}"/>
@@ -304,6 +304,14 @@
</td>
</tr>
<tr>
<td style="width:180px;"><label for="import_count">Import nzbs per process:</label></td>
<td>
<input id="import_count" name="import_count" class="short" type="text" value="{$ftmux->import_count}"/>
<div class="hint">How many NZB files to import per process.</div>
</td>
</tr>
<tr>
<td style="width:180px;"><label for="import_timer">Import nzbs Sleep Timer:</label></td>
<td>