Merge branch 'dev'

This commit is contained in:
DariusIII
2020-04-23 16:30:50 +02:00
158 changed files with 3233 additions and 3018 deletions
+407
View File
@@ -0,0 +1,407 @@
<?php
namespace Blacklight;
use App\Models\Release;
use Elasticsearch\Common\Exceptions\BadRequest400Exception;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use sspat\ESQuerySanitizer\Sanitizer;
class ElasticSearchSiteSearch
{
/**
* @param string|array $phrases
* @param int $limit
* @return mixed
*/
public function indexSearch($phrases, int $limit)
{
$keywords = $this->sanitize($phrases);
try {
$search = [
'scroll' => '30s',
'index' => 'releases',
'body' => [
'query' => [
'query_string' => [
'query' => $keywords,
'fields' => ['searchname', 'plainsearchname', 'fromname', 'filename', 'name'],
'analyze_wildcard' => true,
'default_operator' => 'and',
],
],
'size' => $limit,
'sort' => [
'add_date' => [
'order' => 'desc',
],
'post_date' => [
'order' => 'desc',
],
],
],
];
$results = \Elasticsearch::search($search);
$searchResult = [];
while (isset($results['hits']['hits']) && count($results['hits']['hits']) > 0) {
foreach ($results['hits']['hits'] as $result) {
$searchResult[] = $result['_source']['id'];
}
// When done, get the new scroll_id
// You must always refresh your _scroll_id! It can change sometimes
$scroll_id = $results['_scroll_id'];
// Execute a Scroll request and repeat
$results = \Elasticsearch::scroll([
'scroll_id' => $scroll_id, //...using our previously obtained _scroll_id
'scroll' => '30s', // and the same timeout window
]
);
}
return $searchResult;
} catch (BadRequest400Exception $request400Exception) {
return [];
}
}
/**
* @param string|array $searchName
* @param int $limit
* @return array
*/
public function indexSearchApi($searchName, int $limit)
{
$keywords = $this->sanitize($searchName);
try {
$search = [
'scroll' => '30s',
'index' => 'releases',
'body' => [
'query' => [
'query_string' => [
'query' => $keywords,
'fields' => ['searchname', 'plainsearchname'],
'analyze_wildcard' => true,
'default_operator' => 'and',
],
],
'size' => $limit,
'sort' => [
'add_date' => [
'order' => 'desc',
],
'post_date' => [
'order' => 'desc',
],
],
],
];
$results = \Elasticsearch::search($search);
$searchResult = [];
while (isset($results['hits']['hits']) && count($results['hits']['hits']) > 0) {
foreach ($results['hits']['hits'] as $result) {
$searchResult[] = $result['_source']['id'];
}
// When done, get the new scroll_id
// You must always refresh your _scroll_id! It can change sometimes
$scroll_id = $results['_scroll_id'];
// Execute a Scroll request and repeat
$results = \Elasticsearch::scroll([
'scroll_id' => $scroll_id, //...using our previously obtained _scroll_id
'scroll' => '30s', // and the same timeout window
]
);
}
return $searchResult;
} catch (BadRequest400Exception $request400Exception) {
return [];
}
}
/**
* Search function used in TV, TV API, Movies and Anime searches.
* @param string|array $name
* @param int $limit
* @return array
*/
public function indexSearchTMA($name, $limit)
{
$keywords = $this->sanitize($name);
try {
$search = [
'scroll' => '30s',
'index' => 'releases',
'body' => [
'query' => [
'query_string' => [
'query' => $keywords,
'fields' => ['searchname', 'plainsearchname'],
'analyze_wildcard' => true,
'default_operator' => 'and',
],
],
'size' => $limit,
'sort' => [
'add_date' => [
'order' =>'desc',
],
'post_date' => [
'order' => 'desc',
],
],
],
];
$results = \Elasticsearch::search($search);
$searchResult = [];
while (isset($results['hits']['hits']) && count($results['hits']['hits']) > 0) {
foreach ($results['hits']['hits'] as $result) {
$searchResult[] = $result['_source']['id'];
}
// When done, get the new scroll_id
// You must always refresh your _scroll_id! It can change sometimes
$scroll_id = $results['_scroll_id'];
// Execute a Scroll request and repeat
$results = \Elasticsearch::scroll([
'scroll_id' => $scroll_id, //...using our previously obtained _scroll_id
'scroll' => '30s', // and the same timeout window
]
);
}
return $searchResult;
} catch (BadRequest400Exception $request400Exception) {
return [];
}
}
/**
* @param string|array $search
* @return array|\Illuminate\Support\Collection
*/
public function predbIndexSearch($search)
{
try {
$search = [
'scroll' => '30s',
'index' => 'predb',
'body' => [
'query' => [
'query_string' => [
'query' => $search,
'fields' => ['title'],
'analyze_wildcard' => true,
'default_operator' => 'and',
],
],
'size' => 1000,
],
];
$results = \Elasticsearch::search($search);
$ids = [];
while (isset($results['hits']['hits']) && count($results['hits']['hits']) > 0) {
foreach ($results['hits']['hits'] as $result) {
$ids[] = $result['_source']['id'];
}
if (empty($ids)) {
return collect();
}
// When done, get the new scroll_id
// You must always refresh your _scroll_id! It can change sometimes
$scroll_id = $results['_scroll_id'];
// Execute a Scroll request and repeat
$results = \Elasticsearch::scroll([
'scroll_id' => $scroll_id, //...using our previously obtained _scroll_id
'scroll' => '30s', // and the same timeout window
]
);
}
return $ids;
} catch (BadRequest400Exception $request400Exception) {
return [];
}
}
/**
* @param array $parameters
*/
public function insertRelease(array $parameters): void
{
$searchNameDotless = str_replace(['.', '-'], ' ', $parameters['searchname']);
$data = [
'body' => [
'id' => $parameters['id'],
'name' => $parameters['name'],
'searchname' => $parameters['searchname'],
'plainsearchname' => $searchNameDotless,
'fromname' => $parameters['fromname'],
'filename' => $parameters['filename'] ?? '',
'add_date' => now()->format('Y-m-d H:i:s'),
'post_date' => $parameters['postdate'],
],
'index' => 'releases',
'id' => $parameters['id'],
];
\Elasticsearch::index($data);
}
/**
* @param int $id
*/
public function updateRelease(int $id)
{
$new = Release::query()
->where('releases.id', $id)
->leftJoin('release_files as rf', 'releases.id', '=', 'rf.releases_id')
->select(['releases.id', 'releases.name', 'releases.searchname', 'releases.fromname', DB::raw('IFNULL(GROUP_CONCAT(rf.name SEPARATOR " "),"") filename')])
->groupBy('releases.id')
->first();
if ($new !== null) {
$searchNameDotless = str_replace(['.', '-'], ' ', $new->searchname);
$data = [
'body' => [
'doc' => [
'id' => $new->id,
'name' => $new->name,
'searchname' => $new->searchname,
'plainsearchname' => $searchNameDotless,
'fromname' => $new->fromname,
'filename' => $new->filename,
],
'doc_as_upsert' => true,
],
'index' => 'releases',
'id' => $new->id,
];
\Elasticsearch::update($data);
}
}
/**
* @param $searchTerm
* @return array
*/
public function searchPreDb($searchTerm)
{
$search = [
'index' => 'predb',
'body' => [
'query' => [
'query_string' => [
'query' => $searchTerm,
'fields' => ['title', 'filename'],
'analyze_wildcard' => true,
'default_operator' => 'and',
],
],
],
];
try {
$primaryResults = \Elasticsearch::search($search);
$results = [];
foreach ($primaryResults['hits']['hits'] as $primaryResult) {
$results[] = $primaryResult['_source'];
}
} catch (BadRequest400Exception $badRequest400Exception) {
return [];
}
return $results;
}
/**
* @param $parameters
*/
public function insertPreDb($parameters)
{
$data = [
'body' => [
'id' => $parameters['id'],
'title' => $parameters['title'],
'source' => $parameters['source'],
'filename' => $parameters['filename'],
],
'index' => 'predb',
'id' => $parameters['id'],
];
\Elasticsearch::index($data);
}
/**
* @param $parameters
*/
public function updatePreDb($parameters)
{
$data = [
'body' => [
'doc' => [
'id' => $parameters['id'],
'title' => $parameters['title'],
'filename' => $parameters['filename'],
'source' => $parameters['source'],
],
'doc_as_upsert' => true,
],
'index' => 'predb',
'id' => $parameters['id'],
];
\Elasticsearch::update($data);
}
/**
* @param array|string $phrases
* @return string
*/
private function sanitize($phrases): string
{
if (! is_array($phrases)) {
$wordArray = explode(' ', str_replace('.', ' ', $phrases));
} else {
$wordArray = $phrases;
}
$keywords = [];
foreach ($wordArray as $words) {
$tempWords = [];
$words = preg_split('/\s+/', $words);
foreach ($words as $st) {
if (Str::startsWith($st, ['!', '+', '-', '?', '*'])) {
$str = $st;
} elseif (Str::endsWith($st, ['+', '-', '?', '*'])) {
$str = $st;
} else {
$str = Sanitizer::escape($st);
}
$tempWords[] = $str;
}
$keywords = $tempWords;
}
return implode(' ', $keywords);
}
}
+8 -53
View File
@@ -4,7 +4,6 @@ namespace Blacklight;
use App\Models\Predb;
use App\Models\UsenetGroup;
use Elasticsearch\Common\Exceptions\BadRequest400Exception;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
@@ -64,6 +63,10 @@ class IRCScraper extends IRCClient
* @var \Blacklight\SphinxSearch
*/
protected $sphinxsearch;
/**
* @var ElasticSearchSiteSearch
*/
private $elasticsearch;
/**
* Construct.
@@ -135,6 +138,7 @@ class IRCScraper extends IRCClient
$this->_titleIgnoreRegex = config('irc_settings.scrape_irc_title_ignore');
}
$this->elasticsearch = new ElasticSearchSiteSearch();
$this->sphinxsearch = new SphinxSearch();
$this->_groupList = [];
@@ -291,30 +295,7 @@ class IRCScraper extends IRCClient
protected function _insertNewPre()
{
if (config('nntmux.elasticsearch_enabled') === true) {
$search = [
'index' => 'predb',
'body' => [
'query' => [
'query_string' => [
'query' => $this->_curPre['title'],
'fields' => ['title'],
'analyze_wildcard' => true,
'default_operator' => 'and',
],
],
],
];
try {
$results = \Elasticsearch::search($search);
$indexData = [];
foreach ($results['hits']['hits'] as $result) {
$indexData[] = $result['_source'];
}
} catch (BadRequest400Exception $badRequest400Exception) {
return;
}
$indexData = (new ElasticSearchSiteSearch())->predbIndexSearch($this->_curPre['title']);
} else {
$indexData = $this->sphinxsearch->searchIndexes('predb_rt', $this->_curPre['title'], ['title']);
}
@@ -364,18 +345,7 @@ class IRCScraper extends IRCClient
];
if (config('nntmux.elasticsearch_enabled') === true) {
$data = [
'body' => [
'id' => $parameters['id'],
'title' => $parameters['title'],
'source' => $parameters['source'],
'filename' => $parameters['filename'],
],
'index' => 'predb',
'id' => $parameters['id'],
];
\Elasticsearch::index($data);
$this->elasticsearch->insertPreDb($parameters);
} else {
$this->sphinxsearch->insertPredb($parameters);
}
@@ -429,22 +399,7 @@ class IRCScraper extends IRCClient
];
if (config('nntmux.elasticsearch_enabled') === true) {
$data = [
'body' => [
'doc' => [
'id' => $parameters['id'],
'title' => $parameters['title'],
'filename' => $parameters['filename'],
'source' => $parameters['source'],
],
'doc_as_upsert' => true,
],
'index' => 'predb',
'id' => $parameters['id'],
];
\Elasticsearch::update($data);
$this->elasticsearch->updatePreDb($parameters);
} else {
$this->sphinxsearch->updatePreDb($parameters);
}
+18 -130
View File
@@ -8,7 +8,6 @@ use App\Models\Release;
use App\Models\UsenetGroup;
use Blacklight\processing\PostProcess;
use Blacklight\utility\Utility;
use Elasticsearch\Common\Exceptions\BadRequest400Exception;
use Illuminate\Support\Arr;
/**
@@ -143,6 +142,10 @@ class NameFixer
* @var \Blacklight\ColorCLI
*/
protected $colorCli;
/**
* @var ElasticSearchSiteSearch
*/
private $elasticsearch;
/**
* @param array $options Class instances / Echo to cli.
@@ -173,6 +176,7 @@ class NameFixer
$this->consoletools = ($options['ConsoleTools'] instanceof ConsoleTools ? $options['ConsoleTools'] : new ConsoleTools());
$this->category = ($options['Categorize'] instanceof Categorize ? $options['Categorize'] : new Categorize(['Settings' => null]));
$this->sphinx = ($options['SphinxSearch'] instanceof SphinxSearch ? $options['SphinxSearch'] : new SphinxSearch());
$this->elasticsearch = new ElasticSearchSiteSearch();
}
/**
@@ -1034,24 +1038,7 @@ class NameFixer
$taggedRelease->update($updateColumns);
$taggedRelease->retag($determinedCategory['tags']);
if (config('nntmux.elasticsearch_enabled') === true) {
$newTitleDotless = str_replace(['.', '-'], ' ', $newTitle);
$data = [
'body' => [
'doc' => [
'id' => $release->releases_id,
'name' => $release->name,
'searchname' => $newTitle,
'plainsearchname' => $newTitleDotless,
'fromname' => $release->fromname,
],
'doc_as_upsert' => true,
],
'index' => 'releases',
'id' => $release->releases_id,
];
\Elasticsearch::update($data);
$this->elasticsearch->updateRelease($release->releases_id);
} else {
$this->sphinx->updateRelease($release->releases_id);
}
@@ -1075,33 +1062,7 @@ class NameFixer
);
$taggedRelease->retag($determinedCategory['tags']);
if (config('nntmux.elasticsearch_enabled') === true) {
$new = Release::query()
->where('releases.id', $release->releases_id)
->leftJoin('release_files as rf', 'releases.id', '=', 'rf.releases_id')
->select(['releases.id', 'releases.name', 'releases.searchname', 'releases.fromname', DB::raw('IFNULL(GROUP_CONCAT(rf.name SEPARATOR " "),"") filename')])
->groupBy('releases.id')
->first();
if ($new !== null) {
$newTitleDotless = str_replace(['.', '-'], ' ', $newTitle);
$data = [
'body' => [
'doc' => [
'id' => $release->releases_id,
'name' => $new->name,
'searchname' => $newTitle,
'plainsearchname' => $newTitleDotless,
'fromname' => $new->fromname,
'filename' => ! empty($new->filename) ? $new->filename : '',
],
'doc_as_upsert' => true,
],
'index' => 'releases',
'id' => $release->releases_id,
];
\Elasticsearch::update($data);
}
$this->elasticsearch->updateRelease($release->_releases_id);
} else {
$this->sphinx->updateRelease($release->releases_id);
}
@@ -1314,32 +1275,8 @@ class NameFixer
$this->_cleanMatchFiles();
$preMatch = $this->preMatch($this->_fileName);
if ($preMatch[0] === true) {
$preMatch[1] = $this->escapeString($preMatch[1]);
if (config('nntmux.elasticsearch_enabled') === true) {
$search = [
'index' => 'predb',
'body' => [
'query' => [
'query_string' => [
'query' => $preMatch[1],
'fields' => ['title', 'filename'],
'analyze_wildcard' => true,
'default_operator' => 'and',
],
],
],
];
try {
$primaryResults = \Elasticsearch::search($search);
$results = [];
foreach ($primaryResults['hits']['hits'] as $primaryResult) {
$results[] = $primaryResult['_source'];
}
} catch (BadRequest400Exception $badRequest400Exception) {
return false;
}
$results = $this->elasticsearch->searchPreDb($preMatch[1]);
} else {
$results = $this->sphinx->searchIndexes('predb_rt', $preMatch[1], ['filename', 'title']);
}
@@ -2518,37 +2455,13 @@ class NameFixer
$this->cleanFileNames();
if (! empty($this->_fileName)) {
if (config('nntmux.elasticsearch_enabled') === true) {
$this->_fileName = $this->escapeString($this->_fileName);
$search = [
'index' => 'predb',
'body' => [
'query' => [
'query_string' => [
'query' => $this->_fileName,
'fields' => ['title', 'filename'],
'analyze_wildcard' => true,
'default_operator' => 'and',
],
],
],
];
$results = $this->elasticsearch->searchPreDb($this->_fileName);
foreach ($results as $match) {
if (! empty($match)) {
$this->updateRelease($release, $match['title'], 'PreDb: Filename match', $echo, $type, $nameStatus, $show, $match['id']);
try {
$primaryResults = \Elasticsearch::search($search);
$results = [];
foreach ($primaryResults['hits']['hits'] as $primaryResult) {
$results[] = $primaryResult['_source'];
return true;
}
foreach ($results as $match) {
if (! empty($match)) {
$this->updateRelease($release, $match['title'], 'PreDb: Filename match', $echo, $type, $nameStatus, $show, $match['id']);
return true;
}
}
} catch (BadRequest400Exception $badRequest400Exception) {
return false;
}
} else {
foreach ($this->sphinx->searchIndexes('predb_rt', $this->_fileName, ['filename', 'title']) as $match) {
@@ -2580,38 +2493,13 @@ class NameFixer
$this->cleanFileNames();
if (! empty($this->_fileName)) {
if (config('nntmux.elasticsearch_enabled') === true) {
$this->_fileName = $this->escapeString($this->_fileName);
$search = [
'index' => 'predb',
'body' => [
'query' => [
'query_string' => [
'query' => $this->_fileName,
'fields' => ['title', 'filename'],
'analyze_wildcard' => true,
'default_operator' => 'and',
],
],
],
];
$results = $this->elasticsearch->searchPreDb($this->_fileName);
foreach ($results as $match) {
if (! empty($match)) {
$this->updateRelease($release, $match['title'], 'PreDb: Title match', $echo, $type, $nameStatus, $show, $match['id']);
try {
$primaryResults = \Elasticsearch::search($search);
$results = [];
foreach ($primaryResults['hits']['hits'] as $primaryResult) {
$results[] = $primaryResult['_source'];
return true;
}
foreach ($results as $match) {
if (! empty($match)) {
$this->updateRelease($release, $match['title'], 'PreDb: Title match', $echo, $type, $nameStatus, $show, $match['id']);
return true;
}
}
} catch (BadRequest400Exception $badRequest400Exception) {
return false;
}
} else {
foreach ($this->sphinx->searchIndexes('predb_rt', $this->_fileName, ['title']) as $match) {
+12 -257
View File
@@ -30,6 +30,10 @@ class Releases extends Release
* @var int
*/
public $passwordStatus;
/**
* @var ElasticSearchSiteSearch
*/
private $elasticSearch;
/**
* @var array Class instances.
@@ -39,6 +43,7 @@ class Releases extends Release
{
parent::__construct();
$this->sphinxSearch = new SphinxSearch();
$this->elasticSearch = new ElasticSearchSiteSearch();
}
/**
@@ -449,7 +454,7 @@ class Releases extends Release
$identifiers['i'] = $identifiers['i']['id'];
}
}
if ($identifiers['i'] !== false) {
if ($identifiers['i'] !== null) {
$params = [
'index' => 'releases',
'id' => $identifiers['i'],
@@ -580,49 +585,7 @@ class Releases extends Release
}
if (config('nntmux.elasticsearch_enabled') === true) {
$search = [
'scroll' => '30s',
'index' => 'releases',
'body' => [
'query' => [
'query_string' => [
'query' => implode(' ', $phrases),
'fields' => ['searchname', 'plainsearchname', 'fromname', 'filename', 'name'],
'analyze_wildcard' => true,
'default_operator' => 'and',
],
],
'size' => $limit,
'sort' => [
'add_date' => [
'order' =>'desc',
],
'post_date' => [
'order' => 'desc',
],
],
],
];
$results = \Elasticsearch::search($search);
$searchResult = [];
while (isset($results['hits']['hits']) && count($results['hits']['hits']) > 0) {
foreach ($results['hits']['hits'] as $result) {
$searchResult[] = $result['_source']['id'];
}
// When done, get the new scroll_id
// You must always refresh your _scroll_id! It can change sometimes
$scroll_id = $results['_scroll_id'];
// Execute a Scroll request and repeat
$results = \Elasticsearch::scroll([
'scroll_id' => $scroll_id, //...using our previously obtained _scroll_id
'scroll' => '30s', // and the same timeout window
]
);
}
$searchResult = $this->elasticSearch->indexSearch($phrases, $limit);
} else {
$results = $this->sphinxSearch->searchIndexes('releases_rt', '', [], $searchFields);
@@ -727,49 +690,7 @@ class Releases extends Release
{
if ($searchName !== -1) {
if (config('nntmux.elasticsearch_enabled') === true) {
$search = [
'scroll' => '30s',
'index' => 'releases',
'body' => [
'query' => [
'query_string' => [
'query' => $searchName,
'fields' => ['searchname', 'plainsearchname'],
'analyze_wildcard' => true,
'default_operator' => 'and',
],
],
'size' => $limit,
'sort' => [
'add_date' => [
'order' =>'desc',
],
'post_date' => [
'order' => 'desc',
],
],
],
];
$results = \Elasticsearch::search($search);
$searchResult = [];
while (isset($results['hits']['hits']) && count($results['hits']['hits']) > 0) {
foreach ($results['hits']['hits'] as $result) {
$searchResult[] = $result['_source']['id'];
}
// When done, get the new scroll_id
// You must always refresh your _scroll_id! It can change sometimes
$scroll_id = $results['_scroll_id'];
// Execute a Scroll request and repeat
$results = \Elasticsearch::scroll([
'scroll_id' => $scroll_id, //...using our previously obtained _scroll_id
'scroll' => '30s', // and the same timeout window
]
);
}
$searchResult = $this->elasticSearch->indexSearchApi($searchName, $limit);
} else {
$searchResult = Arr::pluck($this->sphinxSearch->searchIndexes('releases_rt', $searchName, ['searchname']), 'id');
}
@@ -918,49 +839,7 @@ class Releases extends Release
}
if (! empty($name)) {
if (config('nntmux.elasticsearch_enabled') === true) {
$search = [
'scroll' => '30s',
'index' => 'releases',
'body' => [
'query' => [
'query_string' => [
'query' => $name,
'fields' => ['searchname', 'plainsearchname'],
'analyze_wildcard' => true,
'default_operator' => 'and',
],
],
'size' => $limit,
'sort' => [
'add_date' => [
'order' =>'desc',
],
'post_date' => [
'order' => 'desc',
],
],
],
];
$results = \Elasticsearch::search($search);
$searchResult = [];
while (isset($results['hits']['hits']) && count($results['hits']['hits']) > 0) {
foreach ($results['hits']['hits'] as $result) {
$searchResult[] = $result['_source']['id'];
}
// When done, get the new scroll_id
// You must always refresh your _scroll_id! It can change sometimes
$scroll_id = $results['_scroll_id'];
// Execute a Scroll request and repeat
$results = \Elasticsearch::scroll([
'scroll_id' => $scroll_id, //...using our previously obtained _scroll_id
'scroll' => '30s', // and the same timeout window
]
);
}
$searchResult = $this->elasticSearch->indexSearchTMA($name, $limit);
} else {
$searchResult = Arr::pluck($this->sphinxSearch->searchIndexes('releases_rt', $name, ['searchname']), 'id');
}
@@ -1109,49 +988,7 @@ class Releases extends Release
}
if (! empty($name)) {
if (config('nntmux.elasticsearch_enabled') === true) {
$search = [
'scroll' => '30s',
'index' => 'releases',
'body' => [
'query' => [
'query_string' => [
'query' => $name,
'fields' => ['searchname', 'plainsearchname'],
'analyze_wildcard' => true,
'default_operator' => 'and',
],
],
'size' => $limit,
'sort' => [
'add_date' => [
'order' =>'desc',
],
'post_date' => [
'order' => 'desc',
],
],
],
];
$results = \Elasticsearch::search($search);
$searchResult = [];
while (isset($results['hits']['hits']) && count($results['hits']['hits']) > 0) {
foreach ($results['hits']['hits'] as $result) {
$searchResult[] = $result['_source']['id'];
}
// When done, get the new scroll_id
// You must always refresh your _scroll_id! It can change sometimes
$scroll_id = $results['_scroll_id'];
// Execute a Scroll request and repeat
$results = \Elasticsearch::scroll([
'scroll_id' => $scroll_id, //...using our previously obtained _scroll_id
'scroll' => '30s', // and the same timeout window
]
);
}
$searchResult = $this->elasticSearch->indexSearchTMA($name, $limit);
} else {
$searchResult = Arr::pluck($this->sphinxSearch->searchIndexes('releases_rt', $name, ['searchname']), 'id');
}
@@ -1235,49 +1072,7 @@ class Releases extends Release
{
if (! empty($name)) {
if (config('nntmux.elasticsearch_enabled') === true) {
$search = [
'scroll' => '30s',
'index' => 'releases',
'body' => [
'query' => [
'query_string' => [
'query' => $name,
'fields' => ['searchname', 'plainsearchname'],
'analyze_wildcard' => true,
'default_operator' => 'and',
],
],
'size' => $limit,
'sort' => [
'add_date' => [
'order' =>'desc',
],
'post_date' => [
'order' => 'desc',
],
],
],
];
$results = \Elasticsearch::search($search);
$searchResult = [];
while (isset($results['hits']['hits']) && count($results['hits']['hits']) > 0) {
foreach ($results['hits']['hits'] as $result) {
$searchResult[] = $result['_source']['id'];
}
// When done, get the new scroll_id
// You must always refresh your _scroll_id! It can change sometimes
$scroll_id = $results['_scroll_id'];
// Execute a Scroll request and repeat
$results = \Elasticsearch::scroll([
'scroll_id' => $scroll_id, //...using our previously obtained _scroll_id
'scroll' => '30s', // and the same timeout window
]
);
}
$searchResult = $this->elasticSearch->indexSearchTMA($name, $limit);
} else {
$searchResult = Arr::pluck($this->sphinxSearch->searchIndexes('releases_rt', $name, ['searchname']), 'id');
}
@@ -1360,47 +1155,7 @@ class Releases extends Release
{
if (! empty($name)) {
if (config('nntmux.elasticsearch_enabled') === true) {
$search = [
'scroll' => '30s',
'index' => 'releases',
'body' => [
'query' => [
'query_string' => [
'query' => $name,
'fields' => ['searchname', 'plainsearchname'],
'analyze_wildcard' => true,
'default_operator' => 'and',
],
],
'size' => $limit,
'sort' => [
'add_date' => [
'order' =>'desc',
],
'post_date' => [
'order' => 'desc',
],
],
],
];
$results = \Elasticsearch::search($search);
$searchResult = [];
while (isset($results['hits']['hits']) && count($results['hits']['hits']) > 0) {
foreach ($results['hits']['hits'] as $result) {
$searchResult[] = $result['_source']['id'];
}
// When done, get the new scroll_id
// You must always refresh your _scroll_id! It can change sometimes
$scroll_id = $results['_scroll_id'];
// Execute a Scroll request and repeat
$results = \Elasticsearch::scroll([
'scroll_id' => $scroll_id, //...using our previously obtained _scroll_id
'scroll' => '30s', // and the same timeout window
]
);
}
$searchResult = $this->elasticSearch->indexSearchTMA($name, $limit);
} else {
$searchResult = Arr::pluck($this->sphinxSearch->searchIndexes('releases_rt', $name, ['searchname']), 'id');
}
-14
View File
@@ -24,20 +24,6 @@ use Illuminate\Foundation\Application;
class ComposerScripts
{
public static function postInstallCmd()
{
$last = $output = $return = null;
if ((int) getenv('COMPOSER_DEV_MODE') === 1) {
echo 'Updating git hooks... ';
$last = exec('build/git-hooks/addHooks.sh', $output, $return);
if ($return > 0) {
echo PHP_EOL;
exit($last);
}
echo 'done'.PHP_EOL;
}
}
/**
* Handle the post-install Composer event.
*
+3 -2
View File
@@ -212,15 +212,16 @@ SQL_EXPORT;
}
/**
* @param null $settings
* @param null $settings
* @param array $options
*
* @return mixed|null
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function progress($settings = null, array $options = [])
{
$defaults = [
'path' => NN_ROOT.'cli'.DS.'data'.DS.'predb_progress.txt',
'path' => base_path().'/cli/data/predb_progress.txt',
'read' => true,
];
$options += $defaults;
+16 -36
View File
@@ -14,6 +14,7 @@ use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Opis\Closure\SerializableClosure;
use Spatie\Async\Pool;
use Symfony\Component\Process\Process;
/**
* Class Forking.
@@ -25,10 +26,6 @@ use Spatie\Async\Pool;
*/
class Forking
{
private const OUTPUT_NONE = 0; // Don't display child output.
private const OUTPUT_REALTIME = 1; // Display child output in real time.
private const OUTPUT_SERIALLY = 2; // Display child output when child is done.
/**
* @var \Blacklight\ColorCLI
*/
@@ -127,22 +124,6 @@ class Forking
$this->dnr_path = PHP_BINARY.' misc/update/multiprocessing/.do_not_run/switch.php "php ';
switch (config('nntmux.multiprocessing_child_output_type')) {
case 0:
$this->outputType = self::OUTPUT_NONE;
break;
case 1:
$this->outputType = self::OUTPUT_REALTIME;
break;
case 2:
$this->outputType = self::OUTPUT_SERIALLY;
break;
default:
$this->outputType = self::OUTPUT_REALTIME;
}
$this->dnr_path = PHP_BINARY.' misc/update/multiprocessing/.do_not_run/switch.php "php ';
$this->maxSize = (int) Settings::settingValue('..maxsizetoprocessnfo');
$this->minSize = (int) Settings::settingValue('..minsizetoprocessnfo');
$this->maxRetries = (int) Settings::settingValue('..maxnforetries') >= 0 ? -((int) Settings::settingValue('..maxnforetries') + 1) : Nfo::NFO_UNPROC;
@@ -653,16 +634,16 @@ class Forking
{
$type = $desc = '';
if ($this->processAdditional) {
$type = 'pp_additional ';
$type = 'additional true ';
$desc = 'additional postprocessing';
} elseif ($this->processNFO) {
$type = 'pp_nfo ';
$type = 'nfo true ';
$desc = 'nfo postprocessing';
} elseif ($this->processMovies) {
$type = 'pp_movie ';
$type = 'movies true ';
$desc = 'movies postprocessing';
} elseif ($this->processTV) {
$type = 'pp_tv ';
$type = 'tv true ';
$desc = 'tv postprocessing';
}
$pool = Pool::create()->concurrency($maxProcess)->timeout(config('nntmux.multiprocessing_max_child_time'));
@@ -671,7 +652,7 @@ class Forking
foreach ($releases as $release) {
if ($type !== '') {
$pool->add(function () use ($release, $type) {
$this->_executeCommand($this->dnr_path.$type.$release->id.(isset($release->renamed) ? (' '.$release->renamed) : '').'"');
$this->_executeCommand(PHP_BINARY.' misc/update/postprocess.php '.$type.$release->id);
}, 100000)->then(function () use ($desc, $count) {
$this->colorCli->primary('Finished task #'.$count.' for '.$desc);
})->catch(function (\Throwable $exception) {
@@ -944,20 +925,19 @@ class Forking
* Execute a shell command.
*
* @param string $command
* @return string
*/
protected function _executeCommand($command)
{
switch ($this->outputType) {
case self::OUTPUT_NONE:
exec($command);
break;
case self::OUTPUT_REALTIME:
passthru($command);
break;
case self::OUTPUT_SERIALLY:
echo shell_exec($command);
break;
}
$process = Process::fromShellCommandline('exec '.$command);
$process->setTimeout(360);
$process->run(function ($type, $buffer) {
if (Process::ERR === $type) {
echo $buffer;
}
});
return $process->getOutput();
}
/**
@@ -9,6 +9,7 @@ use App\Models\Settings;
use App\Models\UsenetGroup;
use Blacklight\Categorize;
use Blacklight\ColorCLI;
use Blacklight\ElasticSearchSiteSearch;
use Blacklight\NameFixer;
use Blacklight\Nfo;
use Blacklight\NNTP;
@@ -391,6 +392,10 @@ class ProcessAdditional
* @var \Mhor\MediaInfo\MediaInfo
*/
private $mediaInfo;
/**
* @var ElasticSearchSiteSearch
*/
private $elasticsearch;
/**
* ProcessAdditional constructor.
@@ -428,6 +433,7 @@ class ProcessAdditional
$this->_par2Info = new Par2Info();
$this->_nfo = $options['Nfo'] ?? new Nfo();
$this->sphinx = $options['SphinxSearch'] ?? new SphinxSearch();
$this->elasticsearch = new ElasticSearchSiteSearch();
$this->ffmpeg = FFMpeg::create(['timeout' => Settings::settingValue('..timeoutseconds')]);
$this->ffprobe = FFProbe::create();
$this->mediaInfo = new MediaInfo();
@@ -1176,33 +1182,7 @@ class ProcessAdditional
}
if ($this->_addedFileInfo > 0) {
if (config('nntmux.elasticsearch_enabled') === true) {
$new = Release::query()
->where('releases.id', $this->_release->id)
->leftJoin('release_files as rf', 'releases.id', '=', 'rf.releases_id')
->select(['releases.id', 'releases.name', 'releases.searchname', 'releases.fromname', DB::raw('IFNULL(GROUP_CONCAT(rf.name SEPARATOR " "),"") filename')])
->groupBy('releases.id')
->first();
if ($new !== null) {
$searchName = str_replace(['.', '-'], ' ', $new->searchname);
$data = [
'body' => [
'doc' => [
'id' => $this->_release->id,
'name' => $new->name,
'searchname' => $new->searchname,
'plainsearchname' => $searchName,
'fromname' => $new->fromname,
'filename' => ! empty($new->filename) ? $new->filename : '',
],
'doc_as_upsert' => true,
],
'index' => 'releases',
'id' => $this->_release->id,
];
\Elasticsearch::update($data);
}
$this->elasticsearch->updateRelease($this->_release->id);
} else {
$this->sphinx->updateRelease($this->_release->id);
}
@@ -1281,16 +1261,18 @@ class ProcessAdditional
// Get all the compressed files in the temp folder.
$files = $this->_getTempDirectoryContents('/.*\.([rz]\d{2,}|rar|zipx?|0{0,2}1)($|[^a-z0-9])/i');
foreach ($files as $file) {
if ($files !== false) {
foreach ($files as $file) {
// Check if the file exists.
if (File::isFile($file[0])) {
$rarData = @File::get($file[0]);
if ($rarData !== false) {
$this->_processCompressedData($rarData);
$foundCompressedFile = true;
// Check if the file exists.
if (File::isFile($file[0])) {
$rarData = @File::get($file[0]);
if ($rarData !== false) {
$this->_processCompressedData($rarData);
$foundCompressedFile = true;
}
File::delete($file[0]);
}
File::delete($file[0]);
}
}
@@ -1766,24 +1748,7 @@ class ProcessAdditional
$release->retag($newCat['tags']);
if (config('nntmux.elasticsearch_enabled') === true) {
$newTitleDotless = str_replace(['.', '-'], ' ', $newTitle);
$data = [
'body' => [
'doc' => [
'id' => $this->_release->id,
'name' => $this->_release->name,
'searchname' => $newTitle,
'plainsearchname' => $newTitleDotless,
'fromname' => $this->_release->fromname,
],
'doc_as_upsert' => true,
],
'index' => 'releases',
'id' => $this->_release->id,
];
\Elasticsearch::update($data);
$this->elasticsearch->updateRelease($this->_release->id);
} else {
$this->sphinx->updateRelease($this->_release->id);
}
+1 -1
View File
@@ -49,7 +49,7 @@ class Git extends GitRepository
$defaults = [
'create' => false,
'initialise' => false,
'filepath' => NN_ROOT,
'filepath' => base_path().'/',
];
$options += $defaults;
+1 -1
View File
@@ -255,7 +255,7 @@ class Utility
\define('NN_COVERS', Str::finish($path, '/'));
break;
case $path !== '' && $path[0] !== '/' && $path[1] !== ':' && $path[0] !== '\\':
\define('NN_COVERS', realpath(NN_ROOT.Str::finish($path, '/')));
\define('NN_COVERS', realpath(base_path().Str::finish($path, '/')));
break;
case empty($path): // Default to resources location.
default:
+7
View File
@@ -1,3 +1,10 @@
2020-04-12 DariusIII
* Chg: Update ElasticSearch search handling
2020-04-11 DariusIII
* Chg: Remove PayPal support
* Chg: Use Laravel 7 and remove omnipay for now
2020-03-29 DariusIII
* Chg: Start replacing constants with laravel equivalents
2020-03-01 DariusIII
* Chg: Move all third party api keys from database to .env file
2020-02-27 DariusIII
+2
View File
@@ -0,0 +1,2 @@
*
!.gitignore
View File
+2 -2
View File
@@ -48,10 +48,10 @@ class InstallNntmux extends Command
$error = false;
if ($this->confirm('Are you sure you want to install NNTmux? This will wipe your database!!')) {
if (file_exists(NN_ROOT.'_install/install.lock')) {
if (File::exists(base_path().'/_install/install.lock')) {
if ($this->confirm('Do you want to remove install.lock file so you can continue with install?')) {
$this->info('Removing install.lock file so we can continue with install process');
$remove = new Process('rm _install/install.lock');
$remove = Process::fromShellCommandline('exec rm _install/install.lock');
$remove->setTimeout(600);
$remove->run(function ($type, $buffer) {
if (Process::ERR === $type) {
+1 -1
View File
@@ -32,7 +32,7 @@ class TmuxUIStop extends Command
$tmux->stopIfRunning();
if ($this->option('kill') === true) {
$sessionName = Settings::settingValue('site.tmux.tmux_session');
$tmuxSession = new Process('tmux kill-session -t '.$sessionName);
$tmuxSession = Process::fromShellCommandline('exec tmux kill-session -t '.$sessionName);
$this->info('Killing active tmux session: '.$sessionName);
$tmuxSession->run();
if ($tmuxSession->isSuccessful()) {
@@ -64,7 +64,7 @@ class UpdateNNTmuxComposer extends Command
$command .= ' --prefer-dist';
}
$this->output->writeln('<comment>Running composer install process...</comment>');
$process = new Process($command);
$process = Process::fromShellCommandline('exec '.$command);
$process->setTimeout(360);
$process->run(function ($type, $buffer) {
if (Process::ERR === $type) {
+5 -5
View File
@@ -33,20 +33,20 @@ class Handler extends ExceptionHandler
* @param \Exception $exception
*
* @return void
* @throws \Exception
* @throws \Throwable
*/
public function report(Exception $exception)
public function report(\Throwable $exception)
{
parent::report($exception);
}
/**
* @param \Illuminate\Http\Request $request
* @param Exception $exception
* @param \Throwable $exception
* @return \Illuminate\Http\RedirectResponse|\Symfony\Component\HttpFoundation\Response
* @throws Exception
* @throws \Throwable
*/
public function render($request, Exception $exception)
public function render($request, \Throwable $exception)
{
if ($exception instanceof \Spatie\Permission\Exceptions\UnauthorizedException) {
abort(401);
+1 -1
View File
@@ -260,7 +260,7 @@ if (! function_exists('runCmd')) {
echo '-Running Command: '.PHP_EOL.' '.$command.PHP_EOL;
}
$process = new Process($command);
$process = Process::fromShellCommandline('exec '.$command);
$process->run();
$output = $process->getOutput();
+1 -1
View File
@@ -62,7 +62,7 @@ class Git
'dev',
],
],
'filepath' => NN_ROOT,
'filepath' => base_path().'/',
];
$config += $defaults;
+2 -2
View File
@@ -91,9 +91,9 @@ class ApiController extends BasePageController
$maxRequests = $res->role->apirequests;
$maxDownloads = $res->role->downloadrequests;
$time = UserRequest::whereUsersId($uid)->min('timestamp');
$apiOldestTime = $time !== null ? Carbon::createFromTimeString($time)->toRfc822String() : '';
$apiOldestTime = $time !== null ? Carbon::createFromTimeString($time)->toRfc2822String() : '';
$grabTime = UserDownload::whereUsersId($uid)->min('timestamp');
$oldestGrabTime = $grabTime !== null ? Carbon::createFromTimeString($grabTime)->toRfc822String() : '';
$oldestGrabTime = $grabTime !== null ? Carbon::createFromTimeString($grabTime)->toRfc2822String() : '';
}
// Record user access to the api, if its been called by a user (i.e. capabilities request do not require a user to be logged in or key provided).
+6 -6
View File
@@ -91,9 +91,9 @@ class ApiV2Controller extends BasePageController
);
$time = UserRequest::whereUsersId($user->id)->min('timestamp');
$apiOldestTime = $time !== null ? Carbon::createFromTimeString($time)->toRfc822String() : '';
$apiOldestTime = $time !== null ? Carbon::createFromTimeString($time)->toRfc2822String() : '';
$grabTime = UserDownload::whereUsersId($user->id)->min('timestamp');
$oldestGrabTime = $grabTime !== null ? Carbon::createFromTimeString($grabTime)->toRfc822String() : '';
$oldestGrabTime = $grabTime !== null ? Carbon::createFromTimeString($grabTime)->toRfc2822String() : '';
$response = [
'Total' => $relData[0]->_totalrows ?? 0,
@@ -160,9 +160,9 @@ class ApiV2Controller extends BasePageController
}
$time = UserRequest::whereUsersId($user->id)->min('timestamp');
$apiOldestTime = $time !== null ? Carbon::createFromTimeString($time)->toRfc822String() : '';
$apiOldestTime = $time !== null ? Carbon::createFromTimeString($time)->toRfc2822String() : '';
$grabTime = UserDownload::whereUsersId($user->id)->min('timestamp');
$oldestGrabTime = $grabTime !== null ? Carbon::createFromTimeString($grabTime)->toRfc822String() : '';
$oldestGrabTime = $grabTime !== null ? Carbon::createFromTimeString($grabTime)->toRfc2822String() : '';
$response = [
'Total' => $relData[0]->_totalrows ?? 0,
@@ -242,9 +242,9 @@ class ApiV2Controller extends BasePageController
);
$time = UserRequest::whereUsersId($user->id)->min('timestamp');
$apiOldestTime = $time !== null ? Carbon::createFromTimeString($time)->toRfc822String() : '';
$apiOldestTime = $time !== null ? Carbon::createFromTimeString($time)->toRfc2822String() : '';
$grabTime = UserDownload::whereUsersId($user->id)->min('timestamp');
$oldestGrabTime = $grabTime !== null ? Carbon::createFromTimeString($grabTime)->toRfc822String() : '';
$oldestGrabTime = $grabTime !== null ? Carbon::createFromTimeString($grabTime)->toRfc2822String() : '';
$response = [
'Total' => $relData[0]->_totalrows ?? 0,
@@ -4,9 +4,9 @@ namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Jobs\SendPasswordForgottenEmail;
use App\Mail\ForgottenPassword;
use App\Models\Settings;
use App\Models\User;
use DariusIII\Token\Facades\Token;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
use Illuminate\Http\Request;
@@ -64,7 +64,7 @@ class ForgotPasswordController extends Controller
//
// Generate a forgottenpassword guid, store it in the user table
//
$guid = \Token::random(32);
$guid = Token::random(32);
User::updatePassResetGuid($ret['id'], $guid);
//
// Send the email
@@ -2,11 +2,9 @@
namespace App\Http\Controllers;
use App\Models\PaypalPayment;
use App\Models\User;
use Blacklight\libraries\Geary;
use Illuminate\Http\Request;
use Omnipay\Omnipay;
use Spatie\Permission\Models\Role;
class BtcPaymentController extends BasePageController
@@ -86,100 +84,4 @@ class BtcPaymentController extends BasePageController
}
}
}
/**
* @param Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
* @throws \Exception
*/
public function paypal(Request $request)
{
$this->setPrefs();
$gateway = Omnipay::create('PayPal_Rest');
$gateway->initialize(['clientId' => env('PAYPAL_CLIENTID'), 'secret' => env('PAYPAL_SECRET'), 'testMode' => env('PAYPAL_TEST_MODE')]);
$amount = $request->input('amount');
// Do a purchase transaction on the gateway
try {
$transaction = $gateway->purchase([
'amount' => $amount,
'currency' => 'USD',
'description' => $this->userdata->id,
'returnUrl' => url('/').'/thankyou?id='.$this->userdata->id.'&amount='.$amount,
'cancelUrl' => url('/').'/payment_failed',
]);
$response = $transaction->send();
if ($response->isSuccessful()) {
return redirect($response->getRedirectUrl());
} elseif ($response->isRedirect()) {
return $response->redirect();
}
} catch (\Exception $e) {
echo "Exception caught while attempting authorize.\n";
echo 'Exception type == '.get_class($e)."\n";
echo 'Message == '.$e->getMessage()."\n";
}
}
/**
* @throws \Exception
*/
public function showPaypal()
{
$this->setPrefs();
$donation = Role::query()->where('donation', '>', 0)->get(['id', 'name', 'donation', 'addyears']);
$this->smarty->assign('donation', $donation);
$title = 'Become a supporter';
$meta_title = 'Become a supporter';
$meta_description = 'Become a supporter';
$content = $this->smarty->fetch('pay_by_paypal.tpl');
$this->smarty->assign(compact('content', 'meta_title', 'title', 'meta_description'));
$this->pagerender();
}
/**
* @param Request $request
* @throws \Exception
*/
public function paypalCallback(Request $request)
{
$this->setPrefs();
$amount = $request->input('amount');
$userId = $request->input('id');
$role = Role::query()->where('donation', $amount)->first();
$gateway = Omnipay::create('PayPal_Rest');
$gateway->initialize(['clientId' => env('PAYPAL_CLIENTID'), 'secret' => env('PAYPAL_SECRET'), 'testMode' => env('PAYPAL_TEST_MODE')]);
$response = $gateway->completePurchase(
[
'amount' => $amount,
'currency' => 'USD',
'description' => $userId,
'payerId' => $request->input('PayerID'),
'transactionReference' => $request->input('paymentId'),
])->send();
if ($response->isSuccessful()) {
$check = PaypalPayment::query()->where('transaction_id', $request->input('paymentId'))->first();
if ($check === null) {
User::updateUserRole($userId, $role->id);
User::updateUserRoleChangeDate($userId, null, $role->addyears);
PaypalPayment::query()->insert(['users_id' => $userId, 'transaction_id' => $request->input('paymentId'), 'created_at' => now(), 'updated_at' => now()]);
$title = 'Cheers!';
$meta_title = config('app.name').' - Payment Complete';
$meta_description = 'Payment Complete';
$content = $this->smarty->fetch('thankyou.tpl');
$this->smarty->assign(compact('content', 'meta_title', 'title', 'meta_description'));
$this->pagerender();
} else {
echo 'Transaction already exists!';
}
} else {
echo $response->getMessage();
}
}
}
+2 -2
View File
@@ -220,9 +220,9 @@ class RssController extends BasePageController
$maxDownloads = $res->role->downloadrequests;
$usedRequests = UserRequest::getApiRequests($uid);
$time = UserRequest::whereUsersId($uid)->min('timestamp');
$apiOldestTime = $time !== null ? Carbon::createFromTimeString($time)->toRfc822String() : '';
$apiOldestTime = $time !== null ? Carbon::createFromTimeString($time)->toRfc2822String() : '';
$grabTime = UserDownload::whereUsersId($uid)->min('timestamp');
$oldestGrabTime = $grabTime !== null ? Carbon::createFromTimeString($grabTime)->toRfc822String() : '';
$oldestGrabTime = $grabTime !== null ? Carbon::createFromTimeString($grabTime)->toRfc2822String() : '';
if ($res->hasRole('Disabled')) {
return response()->json(['error' => 'Your account is disabled'], 403);
-3
View File
@@ -63,8 +63,5 @@ class Kernel extends HttpKernel
'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
'role_or_permission' => \Spatie\Permission\Middlewares\RoleOrPermissionMiddleware::class,
'clearance' => \App\Http\Middleware\ClearanceMiddleware::class,
'fw-only-whitelisted' => \PragmaRX\Firewall\Middleware\FirewallWhitelist::class,
'fw-block-blacklisted' => \PragmaRX\Firewall\Middleware\FirewallBlacklist::class,
'fw-block-attacks' => \PragmaRX\Firewall\Middleware\BlockAttacks::class,
];
}
-1
View File
@@ -2,7 +2,6 @@
namespace App\Mail;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
-10
View File
@@ -1,10 +0,0 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class PaypalPayment extends Model
{
//
}
+2 -37
View File
@@ -4,6 +4,7 @@ namespace App\Models;
use Blacklight\ColorCLI;
use Blacklight\ConsoleTools;
use Blacklight\ElasticSearchSiteSearch;
use Blacklight\SphinxSearch;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
@@ -191,43 +192,7 @@ class Predb extends Model
$sql = self::query()->leftJoin('releases', 'releases.predb_id', '=', 'predb.id')->orderByDesc('predb.predate');
if (! empty($search)) {
if (config('nntmux.elasticsearch_enabled') === true) {
$search = [
'scroll' => '30s',
'index' => 'predb',
'body' => [
'query' => [
'query_string' => [
'query' => $search,
'fields' => ['title'],
'analyze_wildcard' => true,
'default_operator' => 'and',
],
],
'size' => 1000,
],
];
$results = \Elasticsearch::search($search);
$ids = [];
while (isset($results['hits']['hits']) && count($results['hits']['hits']) > 0) {
foreach ($results['hits']['hits'] as $result) {
$ids[] = $result['_source']['id'];
}
if (empty($ids)) {
return collect();
}
// When done, get the new scroll_id
// You must always refresh your _scroll_id! It can change sometimes
$scroll_id = $results['_scroll_id'];
// Execute a Scroll request and repeat
$results = \Elasticsearch::scroll([
'scroll_id' => $scroll_id, //...using our previously obtained _scroll_id
'scroll' => '30s', // and the same timeout window
]
);
}
$ids = (new ElasticSearchSiteSearch())->predbIndexSearch($search);
} else {
$sphinx = new SphinxSearch();
$ids = Arr::pluck($sphinx->searchIndexes('predb_rt', $search, ['title']), 'id');
+16 -46
View File
@@ -2,6 +2,7 @@
namespace App\Models;
use Blacklight\ElasticSearchSiteSearch;
use Blacklight\NZB;
use Blacklight\SphinxSearch;
use Conner\Tagging\Taggable;
@@ -296,21 +297,7 @@ class Release extends Model
);
if (config('nntmux.elasticsearch_enabled') === true) {
$data = [
'body' => [
'id' => $parameters['id'],
'name' => $parameters['name'],
'searchname' => $parameters['searchname'],
'fromname' => $parameters['fromname'],
'filename' => $parameters['filename'] ?? '',
'add_date' => now()->format('Y-m-d H:i:s'),
'post_date' => $parameters['postdate'],
],
'index' => 'releases',
'id' => $parameters['id'],
];
\Elasticsearch::index($data);
(new ElasticSearchSiteSearch())->insertRelease($parameters);
} else {
(new SphinxSearch())->insertRelease($parameters);
}
@@ -321,11 +308,11 @@ class Release extends Model
/**
* Used for release edit page on site.
*
* @param int $ID
* @param int $id
* @param string $name
* @param string $searchName
* @param string $fromName
* @param int $categoryID
* @param int $categoryId
* @param int $parts
* @param int $grabs
* @param int $size
@@ -333,23 +320,23 @@ class Release extends Model
* @param string $addedDate
* @param $videoId
* @param $episodeId
* @param int $imDbID
* @param int $aniDbID
* @param int $imDbId
* @param int $aniDbId
* @param string $tags
* @throws \Exception
*/
public static function updateRelease($ID, $name, $searchName, $fromName, $categoryID, $parts, $grabs, $size, $postedDate, $addedDate, $videoId, $episodeId, $imDbID, $aniDbID, string $tags = ''): void
public static function updateRelease($id, $name, $searchName, $fromName, $categoryId, $parts, $grabs, $size, $postedDate, $addedDate, $videoId, $episodeId, $imDbId, $aniDbId, string $tags = ''): void
{
$movieInfoId = null;
if (! empty($imDbID)) {
$movieInfoId = MovieInfo::whereImdbid($imDbID)->first(['id']);
if (! empty($imDbId)) {
$movieInfoId = MovieInfo::whereImdbid($imDbId)->first(['id']);
}
self::whereId($ID)->update(
self::whereId($id)->update(
[
'name' => $name,
'searchname' => $searchName,
'fromname' => $fromName,
'categories_id' => $categoryID,
'categories_id' => $categoryId,
'totalpart' => $parts,
'grabs' => $grabs,
'size' => $size,
@@ -357,37 +344,20 @@ class Release extends Model
'adddate' => $addedDate,
'videos_id' => $videoId,
'tv_episodes_id' => $episodeId,
'imdbid' => $imDbID,
'anidbid' => $aniDbID,
'imdbid' => $imDbId,
'anidbid' => $aniDbId,
'movieinfo_id' => $movieInfoId !== null ? $movieInfoId->id : $movieInfoId,
]
);
if (config('nntmux.elasticsearch_enabled') === true) {
$searchNameDotless = str_replace(['.', '-'], ' ', $searchName);
$data = [
'body' => [
'doc' => [
'id' => $ID,
'name' => $name,
'searchname' => $searchName,
'plainsearchname' => $searchNameDotless,
'fromname' => $fromName,
],
'doc_as_upsert' => true,
],
'index' => 'releases',
'id' => $ID,
];
\Elasticsearch::update($data);
(new ElasticSearchSiteSearch())->updateRelease($id);
} else {
(new SphinxSearch())->updateRelease($ID);
(new SphinxSearch())->updateRelease($id);
}
if (! empty($tags)) {
$newTags = explode(',', $tags);
self::find($ID)->retag($newTags);
self::find($id)->retag($newTags);
}
}
+2 -28
View File
@@ -2,10 +2,10 @@
namespace App\Models;
use Blacklight\ElasticSearchSiteSearch;
use Blacklight\SphinxSearch;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
/**
@@ -134,33 +134,7 @@ class ReleaseFile extends Model
ParHash::insertOrIgnore(['releases_id' => $id, 'hash' => $hash]);
}
if (config('nntmux.elasticsearch_enabled') === true) {
$new = Release::query()
->where('releases.id', $id)
->leftJoin('release_files as rf', 'releases.id', '=', 'rf.releases_id')
->select(['releases.id', 'releases.name', 'releases.searchname', 'releases.fromname', DB::raw('IFNULL(GROUP_CONCAT(rf.name SEPARATOR " "),"") filename')])
->groupBy('releases.id')
->first();
if ($new !== null) {
$searchName = str_replace(['.', '-'], ' ', $new->searchname);
$data = [
'body' => [
'doc' => [
'id' => $id,
'name' => $new->name,
'searchname' => $new->searchname,
'plainsearchname' => $searchName,
'fromname' => $new->fromname,
'filename' => ! empty($new->filename) ? $new->filename : '',
],
'doc_as_upsert' => true,
],
'index' => 'releases',
'id' => $id,
];
\Elasticsearch::update($data);
}
(new ElasticSearchSiteSearch())->updateRelease($id);
} else {
(new SphinxSearch())->updateRelease($id);
}
+2 -1
View File
@@ -6,6 +6,7 @@ use App\Jobs\SendAccountExpiredEmail;
use App\Jobs\SendAccountWillExpireEmail;
use App\Jobs\SendInviteEmail;
use Carbon\CarbonImmutable;
use DariusIII\Token\Token;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Http\Request;
use Illuminate\Notifications\Notifiable;
@@ -692,7 +693,7 @@ class User extends Authenticatable
*/
public static function generatePassword($length = 15): string
{
return \Token::random($length, true);
return Token::random($length, true);
}
/**
+15 -2
View File
@@ -6,8 +6,21 @@ require_once 'constants.php';
require_once dirname(__DIR__).DIRECTORY_SEPARATOR.'app/Extensions/util/PhpYenc.php';
use Dotenv\Dotenv;
use Dotenv\Repository\Adapter\EnvConstAdapter;
use Dotenv\Repository\Adapter\ServerConstAdapter;
use Dotenv\Repository\RepositoryBuilder;
$dotenv = Dotenv::create(dirname(__DIR__, 1));
$dotenv->load();
$adapters = [
new EnvConstAdapter(),
new ServerConstAdapter(),
];
$repository = RepositoryBuilder::create()
->withReaders($adapters)
->withWriters($adapters)
->immutable()
->make();
$dotenv = Dotenv::create($repository, dirname(__DIR__, 1), null)->load();
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
Executable → Regular
View File
+19 -20
View File
@@ -98,14 +98,14 @@
"dariusiii/laravel-database-trigger": "^2.0",
"dariusiii/php-itunes-api": "^1.0",
"dariusiii/rarinfo": "^2.5",
"dariusiii/tmdb-laravel": "^2.0",
"dariusiii/tmdb-laravel": "^3.0",
"dariusiii/token": "^3.0",
"dariusiii/zipper": "^2.0",
"dborsatto/php-giantbomb": "^1.0",
"doctrine/dbal": "^2.7",
"fideloper/proxy": "^4.2",
"foolz/sphinxql-query-builder": "^2.0",
"genealabs/laravel-caffeine": "^1.0",
"genealabs/laravel-caffeine": "^7.0",
"geoip2/geoip2": "^2.9",
"google/recaptcha": "^1.2",
"guzzlehttp/guzzle": "^6.3",
@@ -113,57 +113,57 @@
"intervention/image": "^2.4",
"intervention/imagecache": "^2.3",
"james-heinrich/getid3": "1.9.*",
"jamesmills/laravel-timezone": "^1.3",
"jamesmills/laravel-timezone": "^1.9",
"joshpinkney/tv-maze-php-api": "^1.0",
"jrean/laravel-user-verification": "^8.0",
"jrean/laravel-user-verification": "dev-master",
"junaidnasir/larainvite": "^3.0",
"kevinlebrun/colors.php": "^1.0",
"laravel/framework": "^6.0",
"laravel/horizon": "^3.7.2",
"laravel/scout": "^7.0",
"laravel/framework": "^7.0",
"laravel/horizon": "^4.2",
"laravel/scout": "^8.0.0",
"laravel/telescope": "^3.0",
"laravel/tinker": "^2.0",
"laravel/ui": "^2.0",
"laravelcollective/html": "^6.0",
"league/climate": "^3.4",
"league/omnipay": "^3",
"marcreichel/igdb-laravel": "^1.0",
"mhor/php-mediainfo": "^4.1",
"mhor/php-mediainfo": "^5.0",
"monicahq/laravel-cloudflare": "^1.3",
"monolog/monolog": "^2.0",
"nesbot/carbon": "^2.14",
"omnipay/paypal": "^3.0",
"pear/net_nntp": "^1.6.0",
"php-ffmpeg/php-ffmpeg": "^0.14",
"php-http/guzzle6-adapter": "^1.1",
"php-http/message": "^1.6",
"predis/predis": "^1.1",
"propaganistas/laravel-disposable-email": "^2.0",
"ramsey/uuid": "^3.7",
"rtconner/laravel-tagging": "^3.0",
"ramsey/uuid": "^4.0",
"rtconner/laravel-tagging": "^4.0",
"smarty/smarty": "^3.1",
"spatie/async": "^1.0",
"spatie/laravel-directory-cleanup": "^1.2",
"spatie/laravel-fractal": "^5.3",
"spatie/laravel-permission": "^3.0",
"vlucas/phpdotenv": "^3.0",
"sspat/es-query-sanitizer": "^1.0",
"vlucas/phpdotenv": "^4.0",
"voku/simple_html_dom": "^4.3",
"wildbit/swiftmailer-postmark": "^3.0",
"yab/laravel-scout-mysql-driver": "^2.1",
"ytake/laravel-smarty": "^3.0"
"yab/laravel-scout-mysql-driver": "^3.0",
"ytake/laravel-smarty": "^4.0"
},
"require-dev": {
"barryvdh/laravel-ide-helper": "^2.4",
"beyondcode/laravel-dump-server": "^1.0",
"beyondcode/laravel-dump-server": "^1.4",
"captainhook/captainhook": "^5.1",
"captainhook/plugin-composer": "^5.1",
"facade/ignition": "^1.6",
"facade/ignition": "^2.0",
"friendsofphp/php-cs-fixer": "^2.14",
"fzaninotto/faker": "~1.4",
"laracasts/generators": "^1.1",
"matt-allan/laravel-code-style": "^0.5.0",
"mockery/mockery": "^1.0",
"nunomaduro/collision": "^3.0",
"nunomaduro/collision": "^4.2.0",
"nunomaduro/larastan": "^0.5",
"php-coveralls/php-coveralls": "^2.0",
"phpunit/phpunit": "^8.0"
@@ -177,8 +177,7 @@
"@php artisan key:generate --ansi"
],
"post-install-cmd": [
"Blacklight\\build\\ComposerScripts::postInstall",
"Blacklight\\build\\ComposerScripts::postInstallCmd"
"Blacklight\\build\\ComposerScripts::postInstall"
],
"post-update-cmd": [
"Blacklight\\build\\ComposerScripts::postUpdate",
Generated
+1544 -1243
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -14,7 +14,7 @@
* Copyright (c) 2014-2017 Yuuki Takezawa
*/
/**
/*
* Smarty configure.
* @author yuuki.takezawa<yuuki.takezawa@comnect.jp.net>
* @license http://opensource.org/licenses/MIT MIT
@@ -83,8 +83,8 @@ return [
// redis configure
'redis' => [
[
'host' => '127.0.0.1',
'port' => 6379,
'host' => env('REDIS_HOST', '127.0.0.1'),
'port' => env('REDIS_PORT', '6379'),
'database' => 0,
],
],
+1 -1
View File
@@ -11,7 +11,7 @@
|
*/
/** @var \Illuminate\Database\Eloquent\Factory $factory */
/* @var \Illuminate\Database\Eloquent\Factory $factory */
$factory->define(App\User::class, function (Faker\Generator $faker) {
static $password;
@@ -14,7 +14,13 @@ class RemoveTextHash extends Migration
public function up()
{
Schema::table('release_comments', function (Blueprint $table) {
$table->dropUnique('ix_release_comments_hash_releases_id');
$sm = Schema::getConnection()->getDoctrineSchemaManager();
$indexesFound = $sm->listTableIndexes('release_comments');
if (array_key_exists('ix_release_comments_hash_releases_id', $indexesFound)) {
$table->dropUnique('ix_release_comments_hash_releases_id');
}
$table->dropColumn('text_hash');
});
}
+9 -8
View File
@@ -2,6 +2,7 @@
require_once dirname(__DIR__, 3).DIRECTORY_SEPARATOR.'bootstrap/autoload.php';
use App\Models\Release;
use App\Models\Settings;
use Blacklight\ColorCLI;
use Blacklight\NZB;
@@ -9,7 +10,7 @@ use Blacklight\ReleaseImage;
use Blacklight\Releases;
use Blacklight\utility\Utility;
$dir = NN_RES.'movednzbs/';
$dir = resource_path().'/movednzbs/';
$colorCli = new ColorCLI();
if (! isset($argv[1]) || ! in_array($argv[1], ['true', 'move'])) {
@@ -19,7 +20,7 @@ if (! isset($argv[1]) || ! in_array($argv[1], ['true', 'move'])) {
exit();
}
if (! is_dir($dir) && ! mkdir($dir) && ! is_dir($dir)) {
if (! File::isDirectory($dir) && ! File::makeDirectory($dir)) {
exit("ERROR: Could not create folder [$dir].".PHP_EOL);
}
@@ -27,7 +28,7 @@ $releases = new Releases();
$nzb = new NZB();
$releaseImage = new ReleaseImage();
$timestart = date('r');
$timestart = now()->toRfc2822String();
$checked = $moved = 0;
$couldbe = ($argv[1] === 'true') ? 'could be ' : '';
@@ -39,7 +40,7 @@ $itr = new \RecursiveIteratorIterator($dirItr, \RecursiveIteratorIterator::LEAVE
foreach ($itr as $filePath) {
$guid = stristr($filePath->getFilename(), '.nzb.gz', true);
if (is_file($filePath) && $guid) {
if (File::isFile($filePath) && $guid) {
$nzbfile = Utility::unzipGzipFile($filePath);
$nzbContents = $nzb->nzbFileList($nzbfile, ['no-file-key' => false, 'strip-count' => true]);
if (! $nzbfile || ! @simplexml_load_string($nzbfile) || count($nzbContents) === 0) {
@@ -60,17 +61,17 @@ $colorCli->header("Checked / releases deleted\n");
$checked = $deleted = 0;
$res = DB::select('SELECT id, guid, nzbstatus FROM releases');
$res = Release::query()->select(['id', 'guid', 'nzbstatus'])->get();
foreach ($res as $row) {
$nzbpath = $nzb->getNZBPath($row->guid);
if (! is_file($nzbpath)) {
if (! File::isFile($nzbpath)) {
$deleted++;
$releases->deleteSingle(['g' => $row->guid, 'i' => $row->id], $nzb, $releaseImage);
} elseif ($row->nzbstatus !== 1) {
DB::update(sprintf('UPDATE releases SET nzbstatus = 1 WHERE id = %d', $row->id));
Release::where('id', $row->id)->update(['nzbstatus' => 1]);
}
$checked++;
echo "$checked / $deleted\r";
}
$colorCli->header("\n".number_format($checked).' releases checked, '.number_format($deleted).' releases deleted.');
$colorCli->header("Script started at [$timestart], finished at [".date('r').']');
$colorCli->header("Script started at [$timestart], finished at [".now()->toRfc2822String().']');
+3 -3
View File
@@ -26,9 +26,9 @@ try {
echo $e;
}
$runVar['paths']['misc'] = NN_MISC;
$runVar['paths']['cli'] = NN_ROOT.'cli/';
$runVar['paths']['scraper'] = NN_MISC.'IRCScraper'.DS.'scrape.php';
$runVar['paths']['misc'] = base_path().'/misc/';
$runVar['paths']['cli'] = base_path().'/cli/';
$runVar['paths']['scraper'] = base_path().'/misc/IRCScraper/scrape.php';
$db_name = config('nntmux.db_name');
+1 -1
View File
@@ -7,7 +7,7 @@ use App\Models\Settings;
use Blacklight\ColorCLI;
use Blacklight\utility\Utility;
$DIR = NN_TMUX;
$DIR = base_path().'/misc/update/tmux/';
$import = Settings::settingValue('site.tmux.import') ?? 0;
$tmux_session = Settings::settingValue('site.tmux.tmux_session') ?? 0;
$seq = Settings::settingValue('site.tmux.sequential') ?? 0;
+14 -6
View File
@@ -25,12 +25,20 @@ if (isset($argv[1]) && ! is_numeric($argv[1])) {
$group = UsenetGroup::getByName($groupName);
if (is_array($group)) {
$binaries->updateGroup(
$group,
(isset($argv[2]) && is_numeric($argv[2]) && $argv[2] > 0 ? $argv[2] : $maxHeaders)
);
try {
$binaries->updateGroup(
$group,
(isset($argv[2]) && is_numeric($argv[2]) && $argv[2] > 0 ? $argv[2] : $maxHeaders)
);
} catch (Throwable $e) {
\Illuminate\Support\Facades\Log::error($e->getMessage());
}
}
} else {
$binaries->updateAllGroups((isset($argv[1]) && is_numeric($argv[1]) && $argv[1] > 0 ? $argv[1] :
$maxHeaders));
try {
$binaries->updateAllGroups((isset($argv[1]) && is_numeric($argv[1]) && $argv[1] > 0 ? $argv[1] :
$maxHeaders));
} catch (Throwable $e) {
\Illuminate\Support\Facades\Log::error($e->getMessage());
}
}
+6 -6
View File
@@ -13,17 +13,17 @@
"devDependencies": {
"axios": "^0.19",
"cross-env": "^7.0.2",
"jquery": "^3.4.1",
"laravel-mix": "^5.0.1",
"jquery": "3.4.1",
"laravel-mix": "^5.0.4",
"lodash": "^4.17.15",
"popper.js": "^1.16.1",
"resolve-url-loader": "^3.1.1",
"prettier": "^1.19.1",
"prettier": "^2.0.5",
"vue": "^2.6.11"
},
"dependencies": {
"@fancyapps/fancybox": "^3.5.7",
"@fortawesome/fontawesome-free": "^5.12.1",
"@fortawesome/fontawesome-free": "^5.13.0",
"animate.css": "^3.7.2",
"autosize": "^4.0.2",
"bootstrap": "^4.4.1",
@@ -35,11 +35,11 @@
"icheck": "^1.0.2",
"jquery-colorbox": "^1.6.4",
"jquery-goup": "^1.1.3",
"jquery-migrate": "^3.1.0",
"jquery-migrate": "3.1.0",
"nonblockjs": "^1.0.8",
"normalize.css": "^8.0.1",
"pace-js": "^1.0.2",
"pnotify": "^4.0.1",
"tinymce": "^5.2.0"
"tinymce": "^5.2.2"
}
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function () {
'use strict';
+1 -1
View File
@@ -4,6 +4,6 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
!function(){"use strict";function n(){}function o(n){return function(){return n}}function t(){return d}var e,r=tinymce.util.Tools.resolve("tinymce.PluginManager"),u=tinymce.util.Tools.resolve("tinymce.util.Tools"),l=function(n,t,e){var r="UL"===t?"InsertUnorderedList":"InsertOrderedList";n.execCommand(r,!1,!1===e?null:{"list-style-type":e})},i=function(e){e.addCommand("ApplyUnorderedListStyle",function(n,t){l(e,"UL",t["list-style-type"])}),e.addCommand("ApplyOrderedListStyle",function(n,t){l(e,"OL",t["list-style-type"])})},c=function(n){var t=n.getParam("advlist_number_styles","default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman");return t?t.split(/[ ,]/):[]},s=function(n){var t=n.getParam("advlist_bullet_styles","default,circle,square");return t?t.split(/[ ,]/):[]},f=o(!1),a=o(!0),d=(e={fold:function(n,t){return n()},is:f,isSome:f,isNone:a,getOr:m,getOrThunk:p,getOrDie:function(n){throw new Error(n||"error: getOrDie called on none.")},getOrNull:o(null),getOrUndefined:o(undefined),or:m,orThunk:p,map:t,each:n,bind:t,exists:f,forall:a,filter:t,equals:g,equals_:g,toArray:function(){return[]},toString:o("none()")},Object.freeze&&Object.freeze(e),e);function g(n){return n.isNone()}function p(n){return n()}function m(n){return n}function y(n,t,e){var r=function(n,t){for(var e=0;e<n.length;e++){if(t(n[e]))return e}return-1}(t.parents,L),i=-1!==r?t.parents.slice(0,r):t.parents,o=u.grep(i,N(n));return 0<o.length&&o[0].nodeName===e}function O(n,t,e,r,i,o){0<o.length?function(e,n,t,r,i,o){e.ui.registry.addSplitButton(n,{tooltip:t,icon:"OL"===i?"ordered-list":"unordered-list",presets:"listpreview",columns:3,fetch:function(n){n(u.map(o,function(n){return{type:"choiceitem",value:"default"===n?"":n,icon:"list-"+("OL"===i?"num":"bull")+"-"+("disc"===n||"decimal"===n?"default":n),text:function(n){return n.replace(/\-/g," ").replace(/\b\w/g,function(n){return n.toUpperCase()})}(n)}}))},onAction:function(){return e.execCommand(r)},onItemAction:function(n,t){l(e,i,t)},select:function(t){return S(e).map(function(n){return t===n}).getOr(!1)},onSetup:function(t){function n(n){t.setActive(y(e,n,i))}return e.on("NodeChange",n),function(){return e.off("NodeChange",n)}}})}(n,t,e,r,i,o):function(e,n,t,r,i){e.ui.registry.addToggleButton(n,{active:!1,tooltip:t,icon:"OL"===i?"ordered-list":"unordered-list",onSetup:function(t){function n(n){t.setActive(y(e,n,i))}return e.on("NodeChange",n),function(){return e.off("NodeChange",n)}},onAction:function(){return e.execCommand(r)}})}(n,t,e,r,i)}var v=function(e){function n(){return i}function t(n){return n(e)}var r=o(e),i={fold:function(n,t){return t(e)},is:function(n){return e===n},isSome:a,isNone:f,getOr:r,getOrThunk:r,getOrDie:r,getOrNull:r,getOrUndefined:r,or:n,orThunk:n,map:function(n){return v(n(e))},each:function(n){n(e)},bind:t,exists:t,forall:t,filter:function(n){return n(e)?i:d},toArray:function(){return[e]},toString:function(){return"some("+e+")"},equals:function(n){return n.is(e)},equals_:function(n,t){return n.fold(f,function(n){return t(e,n)})}};return i},h=function(n){return null===n||n===undefined?d:v(n)},L=function(n){return n&&/^(TH|TD)$/.test(n.nodeName)},N=function(t){return function(n){return n&&/^(OL|UL|DL)$/.test(n.nodeName)&&function(n,t){return n.$.contains(n.getBody(),t)}(t,n)}},S=function(n){var t=n.dom.getParent(n.selection.getNode(),"ol,ul"),e=n.dom.getStyle(t,"listStyleType");return h(e)},T=function(n){O(n,"numlist","Numbered list","InsertOrderedList","OL",c(n)),O(n,"bullist","Bullet list","InsertUnorderedList","UL",s(n))};!function b(){r.add("advlist",function(n){var t,e,r;e="lists",r=(t=n).settings.plugins?t.settings.plugins:"",-1!==u.inArray(r.split(/[ ,]/),e)&&(T(n),i(n))})}()}();
+12 -11
View File
@@ -4,32 +4,33 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function () {
'use strict';
var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
var isNamedAnchor = function (editor, node) {
return node.tagName === 'A' && editor.dom.getAttrib(node, 'href') === '';
};
var isValidId = function (id) {
return /^[A-Za-z][A-Za-z0-9\-:._]*$/.test(id);
};
var getId = function (editor) {
var selectedNode = editor.selection.getNode();
var isAnchor = selectedNode.tagName === 'A' && editor.dom.getAttrib(selectedNode, 'href') === '';
return isAnchor ? selectedNode.getAttribute('id') || selectedNode.getAttribute('name') : '';
return isNamedAnchor(editor, selectedNode) ? selectedNode.getAttribute('id') || selectedNode.getAttribute('name') : '';
};
var insert = function (editor, id) {
var selectedNode = editor.selection.getNode();
var isAnchor = selectedNode.tagName === 'A' && editor.dom.getAttrib(selectedNode, 'href') === '';
if (isAnchor) {
if (isNamedAnchor(editor, selectedNode)) {
selectedNode.removeAttribute('name');
selectedNode.id = id;
editor.undoManager.add();
} else {
editor.focus();
editor.selection.collapse(true);
editor.execCommand('mceInsertContent', false, editor.dom.createHTML('a', { id: id }));
editor.insertContent(editor.dom.createHTML('a', { id: id }));
}
};
var Anchor = {
@@ -41,10 +42,10 @@
var insertAnchor = function (editor, newId) {
if (!Anchor.isValidId(newId)) {
editor.windowManager.alert('Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.');
return true;
return false;
} else {
Anchor.insert(editor, newId);
return false;
return true;
}
};
var open = function (editor) {
@@ -76,7 +77,7 @@
],
initialData: { id: currentId },
onSubmit: function (api) {
if (!insertAnchor(editor, api.getData().id)) {
if (insertAnchor(editor, api.getData().id)) {
api.close();
}
}
@@ -91,13 +92,13 @@
};
var Commands = { register: register };
var isAnchorNode = function (node) {
var isNamedAnchorNode = function (node) {
return !node.attr('href') && (node.attr('id') || node.attr('name')) && !node.firstChild;
};
var setContentEditable = function (state) {
return function (nodes) {
for (var i = 0; i < nodes.length; i++) {
if (isAnchorNode(nodes[i])) {
if (isNamedAnchorNode(nodes[i])) {
nodes[i].attr('contenteditable', state);
}
}
+2 -2
View File
@@ -4,6 +4,6 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
!function(){"use strict";function e(o){return function(t){for(var e=0;e<t.length;e++)(n=t[e]).attr("href")||!n.attr("id")&&!n.attr("name")||n.firstChild||t[e].attr("contenteditable",o);var n}}var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),n=function(t){return/^[A-Za-z][A-Za-z0-9\-:._]*$/.test(t)},o=function(t){var e=t.selection.getNode();return"A"===e.tagName&&""===t.dom.getAttrib(e,"href")?e.getAttribute("id")||e.getAttribute("name"):""},r=function(t,e){var n=t.selection.getNode();"A"===n.tagName&&""===t.dom.getAttrib(n,"href")?(n.removeAttribute("name"),n.id=e,t.undoManager.add()):(t.focus(),t.selection.collapse(!0),t.execCommand("mceInsertContent",!1,t.dom.createHTML("a",{id:e})))},a=function(e){var t=o(e);e.windowManager.open({title:"Anchor",size:"normal",body:{type:"panel",items:[{name:"id",type:"input",label:"ID",placeholder:"example"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{id:t},onSubmit:function(t){!function(t,e){return n(e)?(r(t,e),!1):(t.windowManager.alert("Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores."),!0)}(e,t.getData().id)&&t.close()}})},i=function(t){t.addCommand("mceAnchor",function(){a(t)})},c=function(t){t.on("PreInit",function(){t.parser.addNodeFilter("a",e("false")),t.serializer.addNodeFilter("a",e(null))})},d=function(e){e.ui.registry.addToggleButton("anchor",{icon:"bookmark",tooltip:"Anchor",onAction:function(){return e.execCommand("mceAnchor")},onSetup:function(t){return e.selection.selectorChangedWithUnbind("a:not([href])",t.setActive).unbind}}),e.ui.registry.addMenuItem("anchor",{icon:"bookmark",text:"Anchor...",onAction:function(){return e.execCommand("mceAnchor")}})};!function u(){t.add("anchor",function(t){c(t),i(t),d(t)})}()}();
!function(){"use strict";function o(t,e){return"A"===e.tagName&&""===t.dom.getAttrib(e,"href")}function e(o){return function(t){for(var e=0;e<t.length;e++)(n=t[e]).attr("href")||!n.attr("id")&&!n.attr("name")||n.firstChild||t[e].attr("contenteditable",o);var n}}var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),n=function(t){return/^[A-Za-z][A-Za-z0-9\-:._]*$/.test(t)},r=function(t){var e=t.selection.getNode();return o(t,e)?e.getAttribute("id")||e.getAttribute("name"):""},i=function(t,e){var n=t.selection.getNode();o(t,n)?(n.removeAttribute("name"),n.id=e,t.undoManager.add()):(t.focus(),t.selection.collapse(!0),t.insertContent(t.dom.createHTML("a",{id:e})))},a=function(e){var t=r(e);e.windowManager.open({title:"Anchor",size:"normal",body:{type:"panel",items:[{name:"id",type:"input",label:"ID",placeholder:"example"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{id:t},onSubmit:function(t){!function(t,e){return n(e)?(i(t,e),!0):(t.windowManager.alert("Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores."),!1)}(e,t.getData().id)||t.close()}})},c=function(t){t.addCommand("mceAnchor",function(){a(t)})},u=function(t){t.on("PreInit",function(){t.parser.addNodeFilter("a",e("false")),t.serializer.addNodeFilter("a",e(null))})},d=function(e){e.ui.registry.addToggleButton("anchor",{icon:"bookmark",tooltip:"Anchor",onAction:function(){return e.execCommand("mceAnchor")},onSetup:function(t){return e.selection.selectorChangedWithUnbind("a:not([href])",t.setActive).unbind}}),e.ui.registry.addMenuItem("anchor",{icon:"bookmark",text:"Anchor...",onAction:function(){return e.execCommand("mceAnchor")}})};!function l(){t.add("anchor",function(t){u(t),c(t),d(t)})}()}();
+1 -1
View File
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function () {
'use strict';
+1 -1
View File
@@ -4,6 +4,6 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
!function(){"use strict";function i(t,e){if(e<0&&(e=0),3===t.nodeType){var n=t.data.length;n<e&&(e=n)}return e}function C(t,e,n){1!==e.nodeType||e.hasChildNodes()?t.setStart(e,i(e,n)):t.setStartBefore(e)}function y(t,e,n){1!==e.nodeType||e.hasChildNodes()?t.setEnd(e,i(e,n)):t.setEndAfter(e)}var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),o=tinymce.util.Tools.resolve("tinymce.Env"),k=function(t){return t.getParam("autolink_pattern",/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+\-]+@)(.+)$/i)},p=function(t){return t.getParam("default_link_target",!1)},w=function(t){return t.getParam("link_default_protocol","http","string")},r=function(t,e,n){var i,o,r,f,a,s,d,l,c,u,g=k(t),h=p(t);if("A"!==t.selection.getNode().tagName){if((i=t.selection.getRng(!0).cloneRange()).startOffset<5){if(!(l=i.endContainer.previousSibling)){if(!i.endContainer.firstChild||!i.endContainer.firstChild.nextSibling)return;l=i.endContainer.firstChild.nextSibling}if(c=l.length,C(i,l,c),y(i,l,c),i.endOffset<5)return;o=i.endOffset,f=l}else{if(3!==(f=i.endContainer).nodeType&&f.firstChild){for(;3!==f.nodeType&&f.firstChild;)f=f.firstChild;3===f.nodeType&&(C(i,f,0),y(i,f,f.nodeValue.length))}o=1===i.endOffset?2:i.endOffset-1-e}for(r=o;C(i,f,2<=o?o-2:0),y(i,f,1<=o?o-1:0),o-=1," "!==(u=i.toString())&&""!==u&&160!==u.charCodeAt(0)&&0<=o-2&&u!==n;);!function(t,e){return t===e||" "===t||160===t.charCodeAt(0)}(i.toString(),n)?(0===i.startOffset?C(i,f,0):C(i,f,o),y(i,f,r)):(C(i,f,o),y(i,f,r),o+=1),"."===(s=i.toString()).charAt(s.length-1)&&y(i,f,r-1),d=(s=i.toString().trim()).match(g);var m=w(t);d&&("www."===d[1]?d[1]=m+"://www.":/@$/.test(d[1])&&!/^mailto:/.test(d[1])&&(d[1]="mailto:"+d[1]),a=t.selection.getBookmark(),t.selection.setRng(i),t.execCommand("createlink",!1,d[1]+d[2]),!1!==h&&t.dom.setAttrib(t.selection.getNode(),"target",h),t.selection.moveToBookmark(a),t.nodeChanged())}},e=function(e){var n;e.on("keydown",function(t){if(13===t.keyCode)return function(t){r(t,-1,"")}(e)}),o.browser.isIE()?e.on("focus",function(){if(!n){n=!0;try{e.execCommand("AutoUrlDetect",!1,!0)}catch(t){}}}):(e.on("keypress",function(t){if(41===t.keyCode)return function(t){r(t,-1,"(")}(e)}),e.on("keyup",function(t){if(32===t.keyCode)return function(t){r(t,0,"")}(e)}))};!function n(){t.add("autolink",function(t){e(t)})}()}();
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function () {
'use strict';
+1 -1
View File
@@ -4,6 +4,6 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
!function(){"use strict";function d(e,t){var n=e.getBody();n&&(n.style.overflowY=t?"":"hidden",t||(n.scrollTop=0))}function h(e,t,n,i){var o=parseInt(e.getStyle(t,n,i),10);return isNaN(o)?0:o}var i=function(e){function t(){return n}var n=e;return{get:t,set:function(e){n=e},clone:function(){return i(t())}}},e=tinymce.util.Tools.resolve("tinymce.PluginManager"),v=tinymce.util.Tools.resolve("tinymce.Env"),r=tinymce.util.Tools.resolve("tinymce.util.Delay"),p=function(e){return e.fire("ResizeEditor")},y=function(e){return e.getParam("min_height",e.getElement().offsetHeight,"number")},z=function(e){return e.getParam("max_height",0,"number")},n=function(e){return e.getParam("autoresize_overflow_padding",1,"number")},b=function(e){return e.getParam("autoresize_bottom_margin",50,"number")},o=function(e){return e.getParam("autoresize_on_init",!0,"boolean")},u=function(e,t,n,i,o){r.setEditorTimeout(e,function(){C(e,t),n--?u(e,t,n,i,o):o&&o()},i)},C=function(e,t){var n,i,o,r=e.dom,u=e.getDoc();if(u)if(function(e){return e.plugins.fullscreen&&e.plugins.fullscreen.isFullscreen()}(e))d(e,!0);else{var s=u.documentElement,a=b(e);i=y(e);var f=h(r,s,"margin-top",!0),c=h(r,s,"margin-bottom",!0);(o=s.offsetHeight+f+c+a)<0&&(o=0);var g=e.getContainer().offsetHeight-e.getContentAreaContainer().offsetHeight;o+g>y(e)&&(i=o+g);var l=z(e);if(l&&l<i?(i=l,d(e,!0)):d(e,!1),i!==t.get()){if(n=i-t.get(),r.setStyle(e.getContainer(),"height",i+"px"),t.set(i),p(e),v.browser.isSafari()&&v.mac){var m=e.getWin();m.scrollTo(m.pageXOffset,m.pageYOffset)}e.hasFocus()&&e.selection.scrollIntoView(e.selection.getNode()),v.webkit&&n<0&&C(e,t)}}},s={setup:function(t,e){t.on("init",function(){var e=n(t);t.dom.setStyles(t.getBody(),{paddingLeft:e,paddingRight:e,"min-height":0})}),t.on("NodeChange SetContent keyup FullscreenStateChanged ResizeContent",function(){C(t,e)}),o(t)&&t.on("init",function(){u(t,e,20,100,function(){u(t,e,5,1e3)})})},resize:C},a=function(e,t){e.addCommand("mceAutoResize",function(){s.resize(e,t)})};!function t(){e.add("autoresize",function(e){if(e.settings.hasOwnProperty("resize")||(e.settings.resize=!1),!e.inline){var t=i(0);a(e,t),s.setup(e,t)}})}()}();
+1 -1
View File
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function (domGlobals) {
'use strict';
+1 -1
View File
@@ -4,6 +4,6 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
!function(n){"use strict";function r(t,e){var n=t||e,r=/^(\d+)([ms]?)$/.exec(""+n);return(r[2]?{s:1e3,m:6e4}[r[2]]:1)*parseInt(n,10)}function o(t){var e=t.getParam("autosave_prefix","tinymce-autosave-{path}{query}{hash}-{id}-");return e=(e=(e=(e=e.replace(/\{path\}/g,n.document.location.pathname)).replace(/\{query\}/g,n.document.location.search)).replace(/\{hash\}/g,n.document.location.hash)).replace(/\{id\}/g,t.id)}function a(t,e){var n=t.settings.forced_root_block;return""===(e=d.trim(void 0===e?t.getBody().innerHTML:e))||new RegExp("^<"+n+"[^>]*>((\xa0|&nbsp;|[ \t]|<br[^>]*>)+?|)</"+n+">|<br>$","i").test(e)}function i(t){var e=parseInt(v.getItem(o(t)+"time"),10)||0;return!((new Date).getTime()-e>function(t){return r(t.settings.autosave_retention,"20m")}(t))||(g(t,!1),!1)}function u(t){var e=o(t);!a(t)&&t.isDirty()&&(v.setItem(e+"draft",t.getContent({format:"raw",no_events:!0})),v.setItem(e+"time",(new Date).getTime().toString()),function(t){t.fire("StoreDraft")}(t))}function s(t){var e=o(t);i(t)&&(t.setContent(v.getItem(e+"draft"),{format:"raw"}),function(t){t.fire("RestoreDraft")}(t))}function c(t,e){var n=function(t){return r(t.settings.autosave_interval,"30s")}(t);e.get()||(m.setInterval(function(){t.removed||u(t)},n),e.set(!0))}function f(t){t.undoManager.transact(function(){s(t),g(t)}),t.focus()}var l=function(t){function e(){return n}var n=t;return{get:e,set:function(t){n=t},clone:function(){return l(e())}}},t=tinymce.util.Tools.resolve("tinymce.PluginManager"),m=tinymce.util.Tools.resolve("tinymce.util.Delay"),v=tinymce.util.Tools.resolve("tinymce.util.LocalStorage"),d=tinymce.util.Tools.resolve("tinymce.util.Tools"),g=function(t,e){var n=o(t);v.removeItem(n+"draft"),v.removeItem(n+"time"),!1!==e&&function(t){t.fire("RemoveDraft")}(t)};function y(r){for(var o=[],t=1;t<arguments.length;t++)o[t-1]=arguments[t];return function(){for(var t=[],e=0;e<arguments.length;e++)t[e]=arguments[e];var n=o.concat(t);return r.apply(null,n)}}function p(n,t){return function(t){t.setDisabled(!i(n));function e(){return t.setDisabled(!i(n))}return n.on("StoreDraft RestoreDraft RemoveDraft",e),function(){return n.off("StoreDraft RestoreDraft RemoveDraft",e)}}}var D=tinymce.util.Tools.resolve("tinymce.EditorManager");!function e(){t.add("autosave",function(t){var e=l(!1);return function(t){t.editorManager.on("BeforeUnload",function(t){var e;d.each(D.get(),function(t){t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&function(t){return t.getParam("autosave_ask_before_unload",!0)}(t)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))}),e&&(t.preventDefault(),t.returnValue=e)})}(t),function(t,e){c(t,e),t.ui.registry.addButton("restoredraft",{tooltip:"Restore last draft",icon:"restore-draft",onAction:function(){f(t)},onSetup:p(t)}),t.ui.registry.addMenuItem("restoredraft",{text:"Restore last draft",icon:"restore-draft",onAction:function(){f(t)},onSetup:p(t)})}(t,e),t.on("init",function(){(function(t){return t.getParam("autosave_restore_when_empty",!1)})(t)&&t.dom.isEmpty(t.getBody())&&s(t)}),function(t){return{hasDraft:y(i,t),storeDraft:y(u,t),restoreDraft:y(s,t),removeDraft:y(g,t),isEmpty:y(a,t)}}(t)})}()}(window);
+1 -1
View File
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function () {
'use strict';
+1 -1
View File
@@ -4,6 +4,6 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
!function(){"use strict";var o=tinymce.util.Tools.resolve("tinymce.PluginManager"),e=tinymce.util.Tools.resolve("tinymce.util.Tools"),t=function(t){t=e.trim(t);function o(o,e){t=t.replace(o,e)}return o(/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/gi,"[url=$1]$2[/url]"),o(/<font.*?color=\"(.*?)\".*?class=\"codeStyle\".*?>(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),o(/<font.*?color=\"(.*?)\".*?class=\"quoteStyle\".*?>(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),o(/<font.*?class=\"codeStyle\".*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),o(/<font.*?class=\"quoteStyle\".*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),o(/<span style=\"color: ?(.*?);\">(.*?)<\/span>/gi,"[color=$1]$2[/color]"),o(/<font.*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[color=$1]$2[/color]"),o(/<span style=\"font-size:(.*?);\">(.*?)<\/span>/gi,"[size=$1]$2[/size]"),o(/<font>(.*?)<\/font>/gi,"$1"),o(/<img.*?src=\"(.*?)\".*?\/>/gi,"[img]$1[/img]"),o(/<span class=\"codeStyle\">(.*?)<\/span>/gi,"[code]$1[/code]"),o(/<span class=\"quoteStyle\">(.*?)<\/span>/gi,"[quote]$1[/quote]"),o(/<strong class=\"codeStyle\">(.*?)<\/strong>/gi,"[code][b]$1[/b][/code]"),o(/<strong class=\"quoteStyle\">(.*?)<\/strong>/gi,"[quote][b]$1[/b][/quote]"),o(/<em class=\"codeStyle\">(.*?)<\/em>/gi,"[code][i]$1[/i][/code]"),o(/<em class=\"quoteStyle\">(.*?)<\/em>/gi,"[quote][i]$1[/i][/quote]"),o(/<u class=\"codeStyle\">(.*?)<\/u>/gi,"[code][u]$1[/u][/code]"),o(/<u class=\"quoteStyle\">(.*?)<\/u>/gi,"[quote][u]$1[/u][/quote]"),o(/<\/(strong|b)>/gi,"[/b]"),o(/<(strong|b)>/gi,"[b]"),o(/<\/(em|i)>/gi,"[/i]"),o(/<(em|i)>/gi,"[i]"),o(/<\/u>/gi,"[/u]"),o(/<span style=\"text-decoration: ?underline;\">(.*?)<\/span>/gi,"[u]$1[/u]"),o(/<u>/gi,"[u]"),o(/<blockquote[^>]*>/gi,"[quote]"),o(/<\/blockquote>/gi,"[/quote]"),o(/<br \/>/gi,"\n"),o(/<br\/>/gi,"\n"),o(/<br>/gi,"\n"),o(/<p>/gi,""),o(/<\/p>/gi,"\n"),o(/&nbsp;|\u00a0/gi," "),o(/&quot;/gi,'"'),o(/&lt;/gi,"<"),o(/&gt;/gi,">"),o(/&amp;/gi,"&"),t},i=function(t){t=e.trim(t);function o(o,e){t=t.replace(o,e)}return o(/\n/gi,"<br />"),o(/\[b\]/gi,"<strong>"),o(/\[\/b\]/gi,"</strong>"),o(/\[i\]/gi,"<em>"),o(/\[\/i\]/gi,"</em>"),o(/\[u\]/gi,"<u>"),o(/\[\/u\]/gi,"</u>"),o(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,'<a href="$1">$2</a>'),o(/\[url\](.*?)\[\/url\]/gi,'<a href="$1">$1</a>'),o(/\[img\](.*?)\[\/img\]/gi,'<img src="$1" />'),o(/\[color=(.*?)\](.*?)\[\/color\]/gi,'<font color="$1">$2</font>'),o(/\[code\](.*?)\[\/code\]/gi,'<span class="codeStyle">$1</span>&nbsp;'),o(/\[quote.*?\](.*?)\[\/quote\]/gi,'<span class="quoteStyle">$1</span>&nbsp;'),t};!function n(){o.add("bbcode",function(o){o.on("BeforeSetContent",function(o){o.content=i(o.content)}),o.on("PostProcess",function(o){o.set&&(o.content=i(o.content)),o.get&&(o.content=t(o.content))})})}()}();
+1 -1
View File
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function (domGlobals) {
'use strict';
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function () {
'use strict';
+1 -1
View File
@@ -4,6 +4,6 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=function(e,n){e.focus(),e.undoManager.transact(function(){e.setContent(n)}),e.selection.setCursorLocation(),e.nodeChanged()},o=function(e){return e.getContent({source_view:!0})},n=function(n){var e=o(n);n.windowManager.open({title:"Source Code",size:"large",body:{type:"panel",items:[{type:"textarea",name:"code"}]},buttons:[{type:"cancel",name:"cancel",text:"Cancel"},{type:"submit",name:"save",text:"Save",primary:!0}],initialData:{code:e},onSubmit:function(e){t(n,e.getData().code),e.close()}})},c=function(e){e.addCommand("mceCodeEditor",function(){n(e)})},i=function(e){e.ui.registry.addButton("code",{icon:"sourcecode",tooltip:"Source code",onAction:function(){return n(e)}}),e.ui.registry.addMenuItem("code",{icon:"sourcecode",text:"Source code",onAction:function(){return n(e)}})};!function u(){e.add("code",function(e){return c(e),i(e),{}})}()}();
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function (domGlobals) {
'use strict';
File diff suppressed because one or more lines are too long
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function (domGlobals) {
'use strict';
+1 -1
View File
@@ -4,6 +4,6 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
!function(o){"use strict";var i=tinymce.util.Tools.resolve("tinymce.PluginManager");!function n(){i.add("colorpicker",function(){o.console.warn("Color picker plugin is now built in to the core editor, please remove it from your editor configuration")})}()}(window);
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function (domGlobals) {
'use strict';
+1 -1
View File
@@ -4,6 +4,6 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
!function(n){"use strict";var o=tinymce.util.Tools.resolve("tinymce.PluginManager");!function e(){o.add("contextmenu",function(){n.console.warn("Context menu plugin is now built in to the core editor, please remove it from your editor configuration")})}()}(window);
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function (domGlobals) {
'use strict';
+1 -1
View File
@@ -4,6 +4,6 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
!function(i){"use strict";function n(){}function u(n){return function(){return n}}function t(){return a}var e,r=tinymce.util.Tools.resolve("tinymce.PluginManager"),c=tinymce.util.Tools.resolve("tinymce.util.Tools"),o=function(n,t){var e,r=n.dom,o=n.selection.getSelectedBlocks();o.length&&(e=r.getAttrib(o[0],"dir"),c.each(o,function(n){r.getParent(n.parentNode,'*[dir="'+t+'"]',r.getRoot())||r.setAttrib(n,"dir",e!==t?t:null)}),n.nodeChanged())},d=function(n){n.addCommand("mceDirectionLTR",function(){o(n,"ltr")}),n.addCommand("mceDirectionRTL",function(){o(n,"rtl")})},f=u(!1),l=u(!0),a=(e={fold:function(n,t){return n()},is:f,isSome:f,isNone:l,getOr:s,getOrThunk:N,getOrDie:function(n){throw new Error(n||"error: getOrDie called on none.")},getOrNull:u(null),getOrUndefined:u(undefined),or:s,orThunk:N,map:t,each:n,bind:t,exists:f,forall:l,filter:t,equals:m,equals_:m,toArray:function(){return[]},toString:u("none()")},Object.freeze&&Object.freeze(e),e);function m(n){return n.isNone()}function N(n){return n()}function s(n){return n}function g(n,t){var e=n.dom(),r=i.window.getComputedStyle(e).getPropertyValue(t),o=""!==r||function(n){var t=A(n)?n.dom().parentNode:n.dom();return t!==undefined&&null!==t&&t.ownerDocument.body.contains(t)}(n)?r:w(e,t);return null===o?undefined:o}function T(t,r){return function(e){function n(n){var t=p.fromDom(n.element);e.setActive(function(n){return"rtl"===g(n,"direction")?"rtl":"ltr"}(t)===r)}return t.on("NodeChange",n),function(){return t.off("NodeChange",n)}}}var E,O,y=function(e){function n(){return o}function t(n){return n(e)}var r=u(e),o={fold:function(n,t){return t(e)},is:function(n){return e===n},isSome:l,isNone:f,getOr:r,getOrThunk:r,getOrDie:r,getOrNull:r,getOrUndefined:r,or:n,orThunk:n,map:function(n){return y(n(e))},each:function(n){n(e)},bind:t,exists:t,forall:t,filter:function(n){return n(e)?o:a},toArray:function(){return[e]},toString:function(){return"some("+e+")"},equals:function(n){return n.is(e)},equals_:function(n,t){return n.fold(f,function(n){return t(e,n)})}};return o},D=function(n){return null===n||n===undefined?a:y(n)},h=function(n){if(null===n||n===undefined)throw new Error("Node cannot be null or undefined");return{dom:u(n)}},p={fromHtml:function(n,t){var e=(t||i.document).createElement("div");if(e.innerHTML=n,!e.hasChildNodes()||1<e.childNodes.length)throw i.console.error("HTML does not have a single root node",n),new Error("HTML must have a single root node");return h(e.childNodes[0])},fromTag:function(n,t){var e=(t||i.document).createElement(n);return h(e)},fromText:function(n,t){var e=(t||i.document).createTextNode(n);return h(e)},fromDom:h,fromPoint:function(n,t,e){var r=n.dom();return D(r.elementFromPoint(t,e)).map(h)}},_=(E="function",function(n){return function(n){if(null===n)return"null";var t=typeof n;return"object"==t&&(Array.prototype.isPrototypeOf(n)||n.constructor&&"Array"===n.constructor.name)?"array":"object"==t&&(String.prototype.isPrototypeOf(n)||n.constructor&&"String"===n.constructor.name)?"string":t}(n)===E}),v=Array.prototype.slice,C=(_(Array.from)&&Array.from,i.Node.ATTRIBUTE_NODE,i.Node.CDATA_SECTION_NODE,i.Node.COMMENT_NODE,i.Node.DOCUMENT_NODE,i.Node.DOCUMENT_TYPE_NODE,i.Node.DOCUMENT_FRAGMENT_NODE,i.Node.ELEMENT_NODE,i.Node.TEXT_NODE),A=(i.Node.PROCESSING_INSTRUCTION_NODE,i.Node.ENTITY_REFERENCE_NODE,i.Node.ENTITY_NODE,i.Node.NOTATION_NODE,"undefined"!=typeof i.window?i.window:Function("return this;")(),O=C,function(n){return function(n){return n.dom().nodeType}(n)===O}),w=function(n,t){return function(n){return n.style!==undefined&&_(n.style.getPropertyValue)}(n)?n.style.getPropertyValue(t):""},S=function(n){n.ui.registry.addToggleButton("ltr",{tooltip:"Left to right",icon:"ltr",onAction:function(){return n.execCommand("mceDirectionLTR")},onSetup:T(n,"ltr")}),n.ui.registry.addToggleButton("rtl",{tooltip:"Right to left",icon:"rtl",onAction:function(){return n.execCommand("mceDirectionRTL")},onSetup:T(n,"rtl")})};!function R(){r.add("directionality",function(n){d(n),S(n)})}()}(window);
+1 -1
View File
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function (domGlobals) {
'use strict';
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function (domGlobals) {
'use strict';
File diff suppressed because one or more lines are too long
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function (domGlobals) {
'use strict';
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function () {
'use strict';
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function () {
'use strict';
+1 -1
View File
@@ -4,6 +4,6 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
!function(){"use strict";var n=tinymce.util.Tools.resolve("tinymce.PluginManager"),o=function(n){n.addCommand("InsertHorizontalRule",function(){n.execCommand("mceInsertContent",!1,"<hr />")})},t=function(n){n.ui.registry.addButton("hr",{icon:"horizontal-rule",tooltip:"Horizontal line",onAction:function(){return n.execCommand("InsertHorizontalRule")}}),n.ui.registry.addMenuItem("hr",{icon:"horizontal-rule",text:"Horizontal line",onAction:function(){return n.execCommand("InsertHorizontalRule")}})};!function e(){n.add("hr",function(n){o(n),t(n)})}()}();
+2 -2
View File
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function (domGlobals) {
'use strict';
@@ -2109,7 +2109,7 @@
data.alt = meta.alt;
}
if (info.hasAccessibilityOptions) {
data.isDecorative = meta.isDecorative || false;
data.isDecorative = meta.isDecorative || data.isDecorative || false;
}
if (info.hasImageTitle && isString(meta.title)) {
data.title = meta.title;
File diff suppressed because one or more lines are too long
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function (domGlobals) {
'use strict';
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function () {
'use strict';
+1 -1
View File
@@ -4,6 +4,6 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
!function(){"use strict";function t(){}function n(t){return function(){return t}}function e(){return h}var r,o=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),f=tinymce.util.Tools.resolve("tinymce.EditorManager"),l=tinymce.util.Tools.resolve("tinymce.Env"),m=tinymce.util.Tools.resolve("tinymce.util.Tools"),c=function(t){return t.getParam("importcss_merge_classes")},i=function(t){return t.getParam("importcss_exclusive")},p=function(t){return t.getParam("importcss_selector_converter")},g=function(t){return t.getParam("importcss_selector_filter")},y=function(t){return t.getParam("importcss_groups")},v=function(t){return t.getParam("importcss_append")},d=function(t){return t.getParam("importcss_file_filter")},u=n(!1),s=n(!0),h=(r={fold:function(t,n){return t()},is:u,isSome:u,isNone:s,getOr:O,getOrThunk:x,getOrDie:function(t){throw new Error(t||"error: getOrDie called on none.")},getOrNull:n(null),getOrUndefined:n(undefined),or:O,orThunk:x,map:e,each:t,bind:e,exists:u,forall:s,filter:e,equals:_,equals_:_,toArray:function(){return[]},toString:n("none()")},Object.freeze&&Object.freeze(r),r);function _(t){return t.isNone()}function x(t){return t()}function O(t){return t}function T(n){return function(t){return function(t){if(null===t)return"null";var n=typeof t;return"object"==n&&(Array.prototype.isPrototypeOf(t)||t.constructor&&"Array"===t.constructor.name)?"array":"object"==n&&(String.prototype.isPrototypeOf(t)||t.constructor&&"String"===t.constructor.name)?"string":n}(t)===n}}function b(t,n){return function(t){for(var n=[],e=0,r=t.length;e<r;++e){if(!w(t[e]))throw new Error("Arr.flatten item "+e+" was not an array, input: "+t);M.apply(n,t[e])}return n}(function(t,n){for(var e=t.length,r=new Array(e),o=0;o<e;o++){var i=t[o];r[o]=n(i,o)}return r}(t,n))}function k(n){return"string"==typeof n?function(t){return-1!==t.indexOf(n)}:n instanceof RegExp?function(t){return n.test(t)}:n}function S(i,t,u){var c=[],e={};function s(t,n){var e,r=t.href;if((r=function(t){var n=l.cacheSuffix;return"string"==typeof t&&(t=t.replace("?"+n,"").replace("&"+n,"")),t}(r))&&u(r,n)&&!function(t,n){var e=t.settings,r=!1!==e.skin&&(e.skin||"oxide");if(r){var o=e.skin_url?t.documentBaseURI.toAbsolute(e.skin_url):f.baseURL+"/skins/ui/"+r,i=f.baseURL+"/skins/content/";return n===o+"/content"+(t.inline?".inline":"")+".min.css"||-1!==n.indexOf(i)}return!1}(i,r)){m.each(t.imports,function(t){s(t,!0)});try{e=t.cssRules||t.rules}catch(o){}m.each(e,function(t){t.styleSheet?s(t.styleSheet,!0):t.selectorText&&m.each(t.selectorText.split(","),function(t){c.push(m.trim(t))})})}}m.each(i.contentCSS,function(t){e[t]=!0}),u=u||function(t,n){return n||e[t]};try{m.each(t.styleSheets,function(t){s(t)})}catch(n){}return c}function A(t,n){var e,r=/^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(n);if(r){var o=r[1],i=r[2].substr(1).split(".").join(" "),u=m.makeMap("a,img");return r[1]?(e={title:n},t.schema.getTextBlockElements()[o]?e.block=o:t.schema.getBlockElements()[o]||u[o.toLowerCase()]?e.selector=o:e.inline=o):r[2]&&(e={inline:"span",title:n.substr(1),classes:i}),!1!==c(t)?e.classes=i:e.attributes={"class":i},e}}function P(t,n){return null===n||!1!==i(t)}var w=T("array"),E=T("function"),I=Array.prototype.slice,M=Array.prototype.push,j=(E(Array.from)&&Array.from,A),D=function(s){s.on("init",function(t){function r(t,n){if(function(t,n,e,r){return!(P(t,e)?n in r:n in e.selectors)}(s,t,n,i)){!function(t,n,e,r){P(t,e)?r[n]=!0:e.selectors[n]=!0}(s,t,n,i);var e=function(t,n,e,r){return(r&&r.selector_converter?r.selector_converter:p(t)?p(t):function(){return A(t,e)}).call(n,e,r)}(s,s.plugins.importcss,t,n);if(e){var r=e.name||a.DOM.uniqueId();return s.formatter.register(r,e),m.extend({},{title:e.title,format:r})}}return null}var o=function(){var n=[],e=[],r={};return{addItemToGroup:function(t,n){r[t]?r[t].push(n):(e.push(t),r[t]=[n])},addItem:function(t){n.push(t)},toFormats:function(){return b(e,function(t){var n=r[t];return 0===n.length?[]:[{title:t,items:n}]}).concat(n)}}}(),i={},u=k(g(s)),c=function(t){return m.map(t,function(t){return m.extend({},t,{original:t,selectors:{},filter:k(t.filter),item:{text:t.title,menu:[]}})})}(y(s));m.each(S(s,s.getDoc(),k(d(s))),function(e){if(-1===e.indexOf(".mce-")&&(!u||u(e))){var t=function(t,n){return m.grep(t,function(t){return!t.filter||t.filter(n)})}(c,e);if(0<t.length)m.each(t,function(t){var n=r(e,t);n&&o.addItemToGroup(t.title,n)});else{var n=r(e,null);n&&o.addItem(n)}}});var n=o.toFormats();s.fire("addStyleModifications",{items:n,replace:!v(s)})})},R=function(n){return{convertSelectorToFormat:function(t){return j(n,t)}}};!function U(){o.add("importcss",function(t){return D(t),R(t)})}()}();
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function () {
'use strict';
+1 -1
View File
@@ -4,6 +4,6 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
!function(){"use strict";function n(e){return e.getParam("insertdatetime_timeformat",e.translate("%H:%M:%S"))}function r(e){return e.getParam("insertdatetime_formats",["%H:%M:%S","%Y-%m-%d","%I:%M:%S %p","%D"])}function a(e,t){if((e=""+e).length<t)for(var n=0;n<t-e.length;n++)e="0"+e;return e}function i(e,t,n){return n=n||new Date,t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=t.replace("%D","%m/%d/%Y")).replace("%r","%I:%M:%S %p")).replace("%Y",""+n.getFullYear())).replace("%y",""+n.getYear())).replace("%m",a(n.getMonth()+1,2))).replace("%d",a(n.getDate(),2))).replace("%H",""+a(n.getHours(),2))).replace("%M",""+a(n.getMinutes(),2))).replace("%S",""+a(n.getSeconds(),2))).replace("%I",""+((n.getHours()+11)%12+1))).replace("%p",n.getHours()<12?"AM":"PM")).replace("%B",""+e.translate(f[n.getMonth()]))).replace("%b",""+e.translate(d[n.getMonth()]))).replace("%A",""+e.translate(s[n.getDay()]))).replace("%a",""+e.translate(l[n.getDay()]))).replace("%%","%")}var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=function(e){return e.getParam("insertdatetime_dateformat",e.translate("%Y-%m-%d"))},o=n,u=r,c=function(e){var t=r(e);return 0<t.length?t[0]:n(e)},m=function(e){return e.getParam("insertdatetime_element",!1)},l="Sun Mon Tue Wed Thu Fri Sat Sun".split(" "),s="Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" "),d="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),f="January February March April May June July August September October November December".split(" "),p=function(e,t){if(m(e)){var n=i(e,t),r=void 0;r=/%[HMSIp]/.test(t)?i(e,"%Y-%m-%dT%H:%M"):i(e,"%Y-%m-%d");var a=e.dom.getParent(e.selection.getStart(),"time");a?function(e,t,n,r){var a=e.dom.create("time",{datetime:n},r);t.parentNode.insertBefore(a,t),e.dom.remove(t),e.selection.select(a,!0),e.selection.collapse(!1)}(e,a,r,n):e.insertContent('<time datetime="'+r+'">'+n+"</time>")}else e.insertContent(i(e,t))},g=i,y=function(e){e.addCommand("mceInsertDate",function(){p(e,t(e))}),e.addCommand("mceInsertTime",function(){p(e,o(e))})},M=tinymce.util.Tools.resolve("tinymce.util.Tools"),S=function(e){function t(){return n}var n=e;return{get:t,set:function(e){n=e},clone:function(){return S(t())}}},v=function(n){var t=u(n),r=S(c(n));n.ui.registry.addSplitButton("insertdatetime",{icon:"insert-time",tooltip:"Insert date/time",select:function(e){return e===r.get()},fetch:function(e){e(M.map(t,function(e){return{type:"choiceitem",text:g(n,e),value:e}}))},onAction:function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];p(n,r.get())},onItemAction:function(e,t){r.set(t),p(n,t)}});n.ui.registry.addNestedMenuItem("insertdatetime",{icon:"insert-time",text:"Date/time",getSubmenuItems:function(){return M.map(t,function(e){return{type:"menuitem",text:g(n,e),onAction:function(e){return function(){r.set(e),p(n,e)}}(e)}})}})};!function h(){e.add("insertdatetime",function(e){y(e),v(e)})}()}();
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function () {
'use strict';
+1 -1
View File
@@ -4,6 +4,6 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=tinymce.util.Tools.resolve("tinymce.util.Tools"),t=function(e){return e.getParam("font_formats")},i=function(e){return e.getParam("fontsize_formats")},n=function(e,t){e.settings.fontsize_formats=t},l=function(e,t){e.settings.font_formats=t},s=function(e){return e.getParam("font_size_style_values","xx-small,x-small,small,medium,large,x-large,xx-large")},r=function(e,t){e.settings.inline_styles=t},o=function(e){!function(e){r(e,!1),i(e)||n(e,"8pt=1 10pt=2 12pt=3 14pt=4 18pt=5 24pt=6 36pt=7"),t(e)||l(e,"Andale Mono=andale mono,monospace;Arial=arial,helvetica,sans-serif;Arial Black=arial black,sans-serif;Book Antiqua=book antiqua,palatino,serif;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier,monospace;Georgia=georgia,palatino,serif;Helvetica=helvetica,arial,sans-serif;Impact=impact,sans-serif;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco,monospace;Times New Roman=times new roman,times,serif;Trebuchet MS=trebuchet ms,geneva,sans-serif;Verdana=verdana,geneva,sans-serif;Webdings=webdings;Wingdings=wingdings,zapf dingbats")}(e),e.on("PreInit",function(){return function(e){var t="p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table",i=a.explode(s(e)),n=e.schema;e.formatter.register({alignleft:{selector:t,attributes:{align:"left"}},aligncenter:{selector:t,attributes:{align:"center"}},alignright:{selector:t,attributes:{align:"right"}},alignjustify:{selector:t,attributes:{align:"justify"}},bold:[{inline:"b",remove:"all"},{inline:"strong",remove:"all"},{inline:"span",styles:{fontWeight:"bold"}}],italic:[{inline:"i",remove:"all"},{inline:"em",remove:"all"},{inline:"span",styles:{fontStyle:"italic"}}],underline:[{inline:"u",remove:"all"},{inline:"span",styles:{textDecoration:"underline"},exact:!0}],strikethrough:[{inline:"strike",remove:"all"},{inline:"span",styles:{textDecoration:"line-through"},exact:!0}],fontname:{inline:"font",toggle:!1,attributes:{face:"%value"}},fontsize:{inline:"font",toggle:!1,attributes:{size:function(e){return String(a.inArray(i,e.value)+1)}}},forecolor:{inline:"font",attributes:{color:"%value"},links:!0,remove_similar:!0,clear_child_styles:!0},hilitecolor:{inline:"font",styles:{backgroundColor:"%value"},links:!0,remove_similar:!0,clear_child_styles:!0}}),a.each("b,i,u,strike".split(","),function(e){n.addValidElements(e+"[*]")}),n.getElementRule("font")||n.addValidElements("font[face|size|color|style]"),a.each(t.split(","),function(e){var t=n.getElementRule(e);t&&(t.attributes.align||(t.attributes.align={},t.attributesOrder.push("align")))})}(e)})};!function c(){e.add("legacyoutput",function(e){o(e)})}()}();
+5 -4
View File
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function (domGlobals) {
'use strict';
@@ -336,7 +336,7 @@
return trimCaretContainers(text);
};
var isLink = function (elm) {
return elm && elm.nodeName === 'A' && !!elm.href;
return elm && elm.nodeName === 'A' && !!getHref(elm);
};
var hasLinks = function (elements) {
return global$3.grep(elements, isLink).length > 0;
@@ -1630,7 +1630,7 @@
var toggleActiveState = function (editor) {
return function (api) {
var nodeChangeHandler = function (e) {
return api.setActive(!editor.readonly && !!Utils.getAnchorElement(editor, e.element));
return api.setActive(!editor.mode.isReadOnly() && !!Utils.getAnchorElement(editor, e.element));
};
editor.on('NodeChange', nodeChangeHandler);
return function () {
@@ -1640,7 +1640,8 @@
};
var toggleEnabledState = function (editor) {
return function (api) {
api.setDisabled(!Utils.hasLinks(editor.dom.getParents(editor.selection.getStart())));
var parents = editor.dom.getParents(editor.selection.getStart());
api.setDisabled(!Utils.hasLinks(parents));
var nodeChangeHandler = function (e) {
return api.setDisabled(!Utils.hasLinks(e.parents));
};
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function (domGlobals) {
'use strict';
File diff suppressed because one or more lines are too long
+154 -184
View File
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function () {
'use strict';
@@ -255,34 +255,9 @@
var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools');
var global$2 = tinymce.util.Tools.resolve('tinymce.html.SaxParser');
var global$2 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');
var global$3 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');
var trimPx = function (value) {
return value.replace(/px$/, '');
};
var addPx = function (value) {
return /^[0-9.]+$/.test(value) ? value + 'px' : value;
};
var getSize = function (name) {
return function (elm) {
return elm ? trimPx(elm.style[name]) : '';
};
};
var setSize = function (name) {
return function (elm, value) {
if (elm) {
elm.style[name] = addPx(value);
}
};
};
var Size = {
getMaxWidth: getSize('maxWidth'),
getMaxHeight: getSize('maxHeight'),
setMaxWidth: setSize('maxWidth'),
setMaxHeight: setSize('maxHeight')
};
var global$3 = tinymce.util.Tools.resolve('tinymce.html.SaxParser');
var getVideoScriptMatch = function (prefixes, src) {
if (prefixes) {
@@ -294,50 +269,64 @@
}
};
var DOM = global$3.DOM;
var getEphoxEmbedIri = function (elm) {
return DOM.getAttrib(elm, 'data-ephox-embed-iri');
var DOM = global$2.DOM;
var trimPx = function (value) {
return value.replace(/px$/, '');
};
var isEphoxEmbed = function (html) {
var fragment = DOM.createFragment(html);
return getEphoxEmbedIri(fragment.firstChild) !== '';
var getEphoxEmbedData = function (attrs) {
var style = attrs.map.style;
var styles = style ? DOM.parseStyle(style) : {};
return {
type: 'ephox-embed-iri',
source: attrs.map['data-ephox-embed-iri'],
altsource: '',
poster: '',
width: get(styles, 'max-width').map(trimPx).getOr(''),
height: get(styles, 'max-height').map(trimPx).getOr('')
};
};
var htmlToDataSax = function (prefixes, html) {
var htmlToData = function (prefixes, html) {
var isEphoxEmbed = Cell(false);
var data = {};
global$2({
global$3({
validate: false,
allow_conditional_comments: true,
start: function (name, attrs) {
if (!data.source && name === 'param') {
data.source = attrs.map.movie;
}
if (name === 'iframe' || name === 'object' || name === 'embed' || name === 'video' || name === 'audio') {
if (!data.type) {
data.type = name;
if (isEphoxEmbed.get()) ; else if (has(attrs.map, 'data-ephox-embed-iri')) {
isEphoxEmbed.set(true);
data = getEphoxEmbedData(attrs);
} else {
if (!data.source && name === 'param') {
data.source = attrs.map.movie;
}
data = global$1.extend(attrs.map, data);
}
if (name === 'script') {
var videoScript = getVideoScriptMatch(prefixes, attrs.map.src);
if (!videoScript) {
return;
if (name === 'iframe' || name === 'object' || name === 'embed' || name === 'video' || name === 'audio') {
if (!data.type) {
data.type = name;
}
data = global$1.extend(attrs.map, data);
}
data = {
type: 'script',
source: attrs.map.src,
width: String(videoScript.width),
height: String(videoScript.height)
};
}
if (name === 'source') {
if (!data.source) {
data.source = attrs.map.src;
} else if (!data.altsource) {
data.altsource = attrs.map.src;
if (name === 'script') {
var videoScript = getVideoScriptMatch(prefixes, attrs.map.src);
if (!videoScript) {
return;
}
data = {
type: 'script',
source: attrs.map.src,
width: String(videoScript.width),
height: String(videoScript.height)
};
}
if (name === 'source') {
if (!data.source) {
data.source = attrs.map.src;
} else if (!data.altsource) {
data.altsource = attrs.map.src;
}
}
if (name === 'img' && !data.poster) {
data.poster = attrs.map.src;
}
}
if (name === 'img' && !data.poster) {
data.poster = attrs.map.src;
}
}
}).parse(html);
@@ -346,21 +335,6 @@
data.poster = data.poster || '';
return data;
};
var ephoxEmbedHtmlToData = function (html) {
var fragment = DOM.createFragment(html);
var div = fragment.firstChild;
return {
type: 'ephox-embed-iri',
source: getEphoxEmbedIri(div),
altsource: '',
poster: '',
width: Size.getMaxWidth(div),
height: Size.getMaxHeight(div)
};
};
var htmlToData = function (prefixes, html) {
return isEphoxEmbed(html) ? ephoxEmbedHtmlToData(html) : htmlToDataSax(prefixes, html);
};
var guess = function (url) {
var mimes = {
@@ -378,56 +352,57 @@
};
var Mime = { guess: guess };
var global$4 = tinymce.util.Tools.resolve('tinymce.html.Writer');
var global$4 = tinymce.util.Tools.resolve('tinymce.html.Schema');
var global$5 = tinymce.util.Tools.resolve('tinymce.html.Schema');
var global$5 = tinymce.util.Tools.resolve('tinymce.html.Writer');
var DOM$1 = global$3.DOM;
var DOM$1 = global$2.DOM;
var addPx = function (value) {
return /^[0-9.]+$/.test(value) ? value + 'px' : value;
};
var setAttributes = function (attrs, updatedAttrs) {
var name;
var i;
var value;
var attr;
for (name in updatedAttrs) {
value = '' + updatedAttrs[name];
if (attrs.map[name]) {
i = attrs.length;
for (var name_1 in updatedAttrs) {
var value = '' + updatedAttrs[name_1];
if (attrs.map[name_1]) {
var i = attrs.length;
while (i--) {
attr = attrs[i];
if (attr.name === name) {
var attr = attrs[i];
if (attr.name === name_1) {
if (value) {
attrs.map[name] = value;
attrs.map[name_1] = value;
attr.value = value;
} else {
delete attrs.map[name];
delete attrs.map[name_1];
attrs.splice(i, 1);
}
}
}
} else if (value) {
attrs.push({
name: name,
name: name_1,
value: value
});
attrs.map[name] = value;
attrs.map[name_1] = value;
}
}
};
var normalizeHtml = function (html) {
var writer = global$4();
var parser = global$2(writer);
parser.parse(html);
return writer.getContent();
var updateEphoxEmbed = function (data, attrs) {
var style = attrs.map.style;
var styleMap = style ? DOM$1.parseStyle(style) : {};
styleMap['max-width'] = addPx(data.width);
styleMap['max-height'] = addPx(data.height);
setAttributes(attrs, { style: DOM$1.serializeStyle(styleMap) });
};
var sources = [
'source',
'altsource'
];
var updateHtmlSax = function (html, data, updateAll) {
var writer = global$4();
var updateHtml = function (html, data, updateAll) {
var writer = global$5();
var isEphoxEmbed = Cell(false);
var sourceCount = 0;
var hasImage;
global$2({
global$3({
validate: false,
allow_conditional_comments: true,
comment: function (text) {
@@ -440,101 +415,94 @@
writer.text(text, raw);
},
start: function (name, attrs, empty) {
switch (name) {
case 'video':
case 'object':
case 'embed':
case 'img':
case 'iframe':
if (data.height !== undefined && data.width !== undefined) {
setAttributes(attrs, {
width: data.width,
height: data.height
});
}
break;
}
if (updateAll) {
if (isEphoxEmbed.get()) ; else if (has(attrs.map, 'data-ephox-embed-iri')) {
isEphoxEmbed.set(true);
updateEphoxEmbed(data, attrs);
} else {
switch (name) {
case 'video':
setAttributes(attrs, {
poster: data.poster,
src: ''
});
if (data.altsource) {
setAttributes(attrs, { src: '' });
case 'object':
case 'embed':
case 'img':
case 'iframe':
if (data.height !== undefined && data.width !== undefined) {
setAttributes(attrs, {
width: data.width,
height: data.height
});
}
break;
case 'iframe':
setAttributes(attrs, { src: data.source });
break;
case 'source':
if (sourceCount < 2) {
}
if (updateAll) {
switch (name) {
case 'video':
setAttributes(attrs, {
src: data[sources[sourceCount]],
type: data[sources[sourceCount] + 'mime']
poster: data.poster,
src: ''
});
if (!data[sources[sourceCount]]) {
if (data.altsource) {
setAttributes(attrs, { src: '' });
}
break;
case 'iframe':
setAttributes(attrs, { src: data.source });
break;
case 'source':
if (sourceCount < 2) {
setAttributes(attrs, {
src: data[sources[sourceCount]],
type: data[sources[sourceCount] + 'mime']
});
if (!data[sources[sourceCount]]) {
return;
}
}
sourceCount++;
break;
case 'img':
if (!data.poster) {
return;
}
hasImage = true;
break;
}
sourceCount++;
break;
case 'img':
if (!data.poster) {
return;
}
hasImage = true;
break;
}
}
writer.start(name, attrs, empty);
},
end: function (name) {
if (name === 'video' && updateAll) {
for (var index = 0; index < 2; index++) {
if (data[sources[index]]) {
var attrs = [];
attrs.map = {};
if (sourceCount < index) {
setAttributes(attrs, {
src: data[sources[index]],
type: data[sources[index] + 'mime']
});
writer.start('source', attrs, true);
if (!isEphoxEmbed.get()) {
if (name === 'video' && updateAll) {
for (var index = 0; index < 2; index++) {
if (data[sources[index]]) {
var attrs = [];
attrs.map = {};
if (sourceCount < index) {
setAttributes(attrs, {
src: data[sources[index]],
type: data[sources[index] + 'mime']
});
writer.start('source', attrs, true);
}
}
}
}
}
if (data.poster && name === 'object' && updateAll && !hasImage) {
var imgAttrs = [];
imgAttrs.map = {};
setAttributes(imgAttrs, {
src: data.poster,
width: data.width,
height: data.height
});
writer.start('img', imgAttrs, true);
if (data.poster && name === 'object' && updateAll && !hasImage) {
var imgAttrs = [];
imgAttrs.map = {};
setAttributes(imgAttrs, {
src: data.poster,
width: data.width,
height: data.height
});
writer.start('img', imgAttrs, true);
}
}
writer.end(name);
}
}, global$5({})).parse(html);
}, global$4({})).parse(html);
return writer.getContent();
};
var isEphoxEmbed$1 = function (html) {
var fragment = DOM$1.createFragment(html);
return DOM$1.getAttrib(fragment.firstChild, 'data-ephox-embed-iri') !== '';
};
var updateEphoxEmbed = function (html, data) {
var fragment = DOM$1.createFragment(html);
var div = fragment.firstChild;
Size.setMaxWidth(div, data.width);
Size.setMaxHeight(div, data.height);
return normalizeHtml(div.outerHTML);
};
var updateHtml = function (html, data, updateAll) {
return isEphoxEmbed$1(html) ? updateEphoxEmbed(html, data) : updateHtmlSax(html, data, updateAll);
};
var UpdateHtml = { updateHtml: updateHtml };
var urlPatterns = [
@@ -1059,9 +1027,9 @@
if (Settings.shouldFilterHtml(editor) === false) {
return html;
}
var writer = global$4();
var writer = global$5();
var blocked;
global$2({
global$3({
validate: false,
allow_conditional_comments: false,
comment: function (text) {
@@ -1075,14 +1043,16 @@
},
start: function (name, attrs, empty) {
blocked = true;
if (name === 'script' || name === 'noscript') {
if (name === 'script' || name === 'noscript' || name === 'svg') {
return;
}
for (var i = 0; i < attrs.length; i++) {
if (attrs[i].name.indexOf('on') === 0) {
return;
for (var i = attrs.length - 1; i >= 0; i--) {
var attrName = attrs[i].name;
if (attrName.indexOf('on') === 0) {
delete attrs.map[attrName];
attrs.splice(i, 1);
}
if (attrs[i].name === 'style') {
if (attrName === 'style') {
attrs[i].value = editor.dom.serializeStyle(editor.dom.parseStyle(attrs[i].value), name);
}
}
@@ -1095,7 +1065,7 @@
}
writer.end(name);
}
}, global$5({})).parse(html);
}, global$4({})).parse(html);
return writer.getContent();
};
var Sanitize = { sanitize: sanitize };
File diff suppressed because one or more lines are too long
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function () {
'use strict';
+1 -1
View File
@@ -4,6 +4,6 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
!function(){"use strict";function o(n,e){for(var t="",o=0;o<e;o++)t+=n;return t}var n=tinymce.util.Tools.resolve("tinymce.PluginManager"),i=function(n){var e=n.getParam("nonbreaking_force_tab",0);return"boolean"==typeof e?!0===e?3:0:e},a=function(n){return n.getParam("nonbreaking_wrap",!0,"boolean")},r=function(n,e){var t=a(n)||n.plugins.visualchars?'<span class="'+(function(n){return!!n.plugins.visualchars&&n.plugins.visualchars.isEnabled()}(n)?"mce-nbsp-wrap mce-nbsp":"mce-nbsp-wrap")+'" contenteditable="false">'+o("&nbsp;",e)+"</span>":o("&nbsp;",e);n.undoManager.transact(function(){return n.insertContent(t)})},e=function(n){n.addCommand("mceNonBreaking",function(){r(n,1)})},c=tinymce.util.Tools.resolve("tinymce.util.VK"),t=function(e){var t=i(e);0<t&&e.on("keydown",function(n){if(n.keyCode===c.TAB&&!n.isDefaultPrevented()){if(n.shiftKey)return;n.preventDefault(),n.stopImmediatePropagation(),r(e,t)}})},u=function(n){n.ui.registry.addButton("nonbreaking",{icon:"non-breaking",tooltip:"Nonbreaking space",onAction:function(){return n.execCommand("mceNonBreaking")}}),n.ui.registry.addMenuItem("nonbreaking",{icon:"non-breaking",text:"Nonbreaking space",onAction:function(){return n.execCommand("mceNonBreaking")}})};!function s(){n.add("nonbreaking",function(n){e(n),u(n),t(n)})}()}();
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function () {
'use strict';
+1 -1
View File
@@ -4,6 +4,6 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
!function(){"use strict";function c(n){return function(t){return-1!==(" "+t.attr("class")+" ").indexOf(n)}}function l(i,o,c){return function(t){var n=arguments,e=n[n.length-2],r=0<e?o.charAt(e-1):"";if('"'===r)return t;if(">"===r){var a=o.lastIndexOf("<",e);if(-1!==a)if(-1!==o.substring(a,e).indexOf('contenteditable="false"'))return t}return'<span class="'+c+'" data-mce-content="'+i.dom.encode(n[0])+'">'+i.dom.encode("string"==typeof n[1]?n[1]:n[0])+"</span>"}}var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),u=tinymce.util.Tools.resolve("tinymce.util.Tools"),f=function(t){return t.getParam("noneditable_noneditable_class","mceNonEditable")},s=function(t){return t.getParam("noneditable_editable_class","mceEditable")},d=function(t){var n=t.getParam("noneditable_regexp",[]);return n&&n.constructor===RegExp?[n]:n},n=function(n){var t,e,r="contenteditable";t=" "+u.trim(s(n))+" ",e=" "+u.trim(f(n))+" ";var a=c(t),i=c(e),o=d(n);n.on("PreInit",function(){0<o.length&&n.on("BeforeSetContent",function(t){!function(t,n,e){var r=n.length,a=e.content;if("raw"!==e.format){for(;r--;)a=a.replace(n[r],l(t,a,f(t)));e.content=a}}(n,o,t)}),n.parser.addAttributeFilter("class",function(t){for(var n,e=t.length;e--;)n=t[e],a(n)?n.attr(r,"true"):i(n)&&n.attr(r,"false")}),n.serializer.addAttributeFilter(r,function(t){for(var n,e=t.length;e--;)n=t[e],(a(n)||i(n))&&(0<o.length&&n.attr("data-mce-content")?(n.name="#text",n.type=3,n.raw=!0,n.value=n.attr("data-mce-content")):n.attr(r,null))})})};!function e(){t.add("noneditable",function(t){n(t)})}()}();
+1 -1
View File
@@ -4,7 +4,7 @@
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*
* Version: 5.2.0 (2020-02-13)
* Version: 5.2.2 (2020-04-23)
*/
(function () {
'use strict';

Some files were not shown because too many files have changed in this diff Show More