pull/1/head
zorlan 2019-09-25 15:45:58 +08:00
parent 4214dc2899
commit 19e77d03c8
146 changed files with 7812 additions and 1334 deletions

View File

@ -1,12 +1,12 @@
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^app/(\w+)/(.*)$ app/$1/index.php [QSA,PT,L,E=PATH_INFO:$2]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,PT,L,E=PATH_INFO:$1]
<IfModule mod_rewrite.c>
Options +FollowSymlinks -Multiviews
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^app/(\w+)/(.*)$ app/$1/index.php [QSA,PT,L,E=PATH_INFO:$2]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,PT,L,E=PATH_INFO:$1]
</IfModule>

View File

@ -66,13 +66,13 @@ class Init{
}
if($s_userid>0){
$GLOBALS['user']=$muser->getByUid($s_userid);
if(!empty($GLOBALS['user'])){
$GLOBALS['user']=$GLOBALS['user']->toArray();
$GLOBALS['user']['group']=model('Usergroup')->getById($GLOBALS['user']['groupid']);
if(!empty($GLOBALS['user']['group'])){
$GLOBALS['user']['group']=$GLOBALS['user']['group']->toArray();
if(model('Usergroup')->is_admin($GLOBALS['user']['group'])){
$GLOBALS['_sc']['user']=$muser->getByUid($s_userid);
if(!empty($GLOBALS['_sc']['user'])){
$GLOBALS['_sc']['user']=$GLOBALS['_sc']['user']->toArray();
$GLOBALS['_sc']['user']['group']=model('Usergroup')->getById($GLOBALS['_sc']['user']['groupid']);
if(!empty($GLOBALS['_sc']['user']['group'])){
$GLOBALS['_sc']['user']['group']=$GLOBALS['_sc']['user']['group']->toArray();
if(model('Usergroup')->is_admin($GLOBALS['_sc']['user']['group'])){
session('is_admin',true);
}else{
session('is_admin',null);
@ -81,7 +81,7 @@ class Init{
}
}
if(!empty($GLOBALS['user'])&&session('is_admin')){
if(!empty($GLOBALS['_sc']['user'])&&session('is_admin')){
/*是管理员,进行下列操作*/
if('index'==$curController&&'index'==strtolower(request()->action())){
@ -108,38 +108,32 @@ class Init{
}
/*通用操作,全局变量*/
$mconfig=model('Config');
$latestDate=$mconfig->max('dateline');
$keyConfig='cache_config_all';
$cacheConfig=cache($keyConfig);
$configList=array();
if(empty($cacheConfig)||$cacheConfig['update_time']!=$latestDate){
$configDbList=$mconfig->column('*');
$configDbList=empty($configDbList)?array():$configDbList;
foreach ($configDbList as $configItem){
$configItem=$mconfig->convertData($configItem);
$configList[$configItem['cname']]=$configItem['data'];
}
cache($keyConfig,array('update_time'=>$latestDate,'list'=>$configList));
}else{
$configList=$cacheConfig['list'];
$configList=$mconfig->getConfigList();
if(empty($configList)){
$mconfig->cacheConfigList();
$configList=$mconfig->getConfigList();
}
$GLOBALS['config']=$configList;
$GLOBALS['_sc']['c']=$configList;
if(!empty($GLOBALS['config']['site']['closelog'])){
if(!empty($GLOBALS['_sc']['c']['site']['closelog'])){
\think\Log::init(array('type'=>'test','level'=>array()));
}
if(!empty($GLOBALS['config']['site']['dblong'])){
if(!empty($GLOBALS['_sc']['c']['site']['dblong'])){
$dbParams=config('database.params');
$dbParams[\PDO::ATTR_PERSISTENT]=true;
config('database.params',$dbParams);
}
$GLOBALS['clientinfo']=clientinfo();
if(!empty($GLOBALS['clientinfo'])){
$GLOBALS['clientinfo']=base64_encode(json_encode($GLOBALS['clientinfo']));
if(empty($GLOBALS['_sc']['c']['download_img'])){
$GLOBALS['_sc']['c']['download_img']=$mconfig->get_img_config_from_caiji($GLOBALS['_sc']['c']['caiji']);
}
$GLOBALS['_sc']['clientinfo']=clientinfo();
if(!empty($GLOBALS['_sc']['clientinfo'])){
$GLOBALS['_sc']['clientinfo']=base64_encode(json_encode($GLOBALS['_sc']['clientinfo']));
}
@ -150,7 +144,7 @@ class Init{
$usertoken=md5($usertoken);
session('usertoken',$usertoken);
}
$GLOBALS['usertoken']=$usertoken;
$GLOBALS['_sc']['usertoken']=$usertoken;
}
}

View File

@ -34,22 +34,37 @@ class Collect extends Command{
if(is_array($cacheConfig)){
\think\Config::set($cacheConfig);
}
if ($input->hasOption('cli_user')){
$cliUser=$input->getOption('cli_user');
$cliUser=base64_decode($cliUser);
$cliUser=explode('_', $cliUser);
$muser=new \skycaiji\admin\model\User();
$user=$muser->where('username',$cliUser[0])->find();
if(!empty($user)){
$user['username']=strtolower($user['username']);
$op=$input->getArgument('op');
static $loginOps=array('task','batch');
if(in_array($op, $loginOps)){
if ($input->hasOption('cli_user')){
if($user['username']==$cliUser[0]&&$cliUser[1]==md5($user['username'].$user['password'])){
session('user_id',$user['uid']);
$cliUser=$input->getOption('cli_user');
$cliUser=base64_decode($cliUser);
$cliUser=explode('_', $cliUser);
if(!empty($cliUser[0])){
$muser=new \skycaiji\admin\model\User();
$user=$muser->where('username',$cliUser[0])->find();
if(!empty($user)){
$user['username']=strtolower($user['username']);
if($user['username']==$cliUser[0]&&$cliUser[1]==md5($user['username'].$user['password'])){
session('user_id',$user['uid']);
}
}
}
}
if(!session('?user_id')){
$this->error_msg('抱歉,必须传入账号信息!');
}
}
$op=$input->getArgument('op');
$rootUrl=\think\Config::get('root_website').'/index.php?s=';
if('task'==$op){
@ -59,29 +74,74 @@ class Collect extends Command{
$taskId=intval($taskId);
}
$curUrl=\think\Config::get('root_website').'/admin/task/collect?backstage=1&id='.urlencode($taskId);
$curUrl=$rootUrl.'/admin/task/collect&backstage=1&id='.urlencode($taskId);
\think\Request::create($curUrl);
define('BIND_MODULE', "admin/task/collect");
}elseif('auto'==$op){
$curUrl=\think\Config::get('root_website').'/admin/api/collect?backstage=1';
\think\Request::create($curUrl);
define('BIND_MODULE', "admin/api/collect");
\think\App::run()->send();
}elseif('batch'==$op){
$taskIds='';
if ($input->hasOption('task_ids')){
$taskIds=$input->getOption('task_ids');
}
$curUrl=\think\Config::get('root_website').'/admin/task/collectBatch?backstage=1&ids='.urlencode($taskIds);
$curUrl=$rootUrl.'/admin/task/collectBatch&backstage=1&ids='.urlencode($taskIds);
\think\Request::create($curUrl);
define('BIND_MODULE', "admin/task/collectBatch");
\think\App::run()->send();
}elseif('backstage'==$op){
set_time_limit(0);
$curKey=CacheModel::getInstance()->getCache('admin_index_backstage_key', 'data');
do{
$cacheKey=CacheModel::getInstance()->getCache('admin_index_backstage_key', 'data');
if(empty($curKey)||$curKey!=$cacheKey){
$this->error_msg('密钥错误,请在后台运行');
}
$mconfig=new \skycaiji\admin\model\Config();
$caijiConfig=$mconfig->getConfig('caiji','data');
if($caijiConfig['server']!='cli'){
$this->error_msg('不是cli命令行模式');
}
if(empty($caijiConfig['auto'])){
$this->error_msg('未开启自动采集');
}
if($caijiConfig['run']!='backstage'){
$this->error_msg('不是后台运行方式');
}
$url=$rootUrl.'/admin/api/collect&backstage=1';
try{
\util\Curl::get($url,null,array('timeout'=>3));
}catch(\Exception $ex){
}
$waitTime=$caijiConfig['interval']*60;
$waitTime=$waitTime>0?$waitTime:60;
sleep($waitTime);
}while(1==1);
}elseif('auto'==$op){
$curUrl=$rootUrl.'/admin/api/collect&backstage=1';
\think\Request::create($curUrl);
define('BIND_MODULE', "admin/api/collect");
\think\App::run()->send();
}
\think\App::run()->send();
}
protected function error_msg($msg){
exit($msg);
}
}

View File

@ -66,7 +66,7 @@ function program_filemd5_list($path,&$md5FileList){
}
/*验证用户token*/
function check_usertoken(){
if($GLOBALS['usertoken']!=input('_usertoken_')){
if($GLOBALS['_sc']['usertoken']!=input('_usertoken_')){
return false;
}else{
return true;
@ -75,7 +75,7 @@ function check_usertoken(){
/*输出用户token*/
function html_usertoken(){
return '<input type="hidden" name="_usertoken_" value="'.$GLOBALS['usertoken'].'" />';
return '<input type="hidden" name="_usertoken_" value="'.$GLOBALS['_sc']['usertoken'].'" />';
}
/*判断正在执行采集任务*/
@ -106,35 +106,24 @@ function cli_command_exec($paramStr){
}
}
static $php_ext_path=null;
if(!isset($php_ext_path)){
$ini_all=ini_get_all();
$php_ext_path=$ini_all['extension_dir']['local_value'];
$phpExeFile=$GLOBALS['_sc']['c']['caiji']['server_php'];
if(empty($phpExeFile)){
$phpExeFile=model('Config')->detect_php_exe();
}
if($php_ext_path){
$phpPath=preg_replace('/[\/\\\]ext[\/\\\]*$/i', '', $php_ext_path);
if(IS_WIN){
$phpPath.=DIRECTORY_SEPARATOR.'php.exe';
}
}else{
$phpPath='php';
}
$commandStr=$phpPath;
$commandStr=$phpExeFile;
if(IS_WIN){
$commandStr='"'.$commandStr.'"';
}
$cliUser=strtolower($GLOBALS['user']['username']);
$cliUser=$cliUser.'_'.md5($cliUser.$GLOBALS['user']['password']);
$cliUser=strtolower($GLOBALS['_sc']['user']['username']);
$cliUser=$cliUser.'_'.md5($cliUser.$GLOBALS['_sc']['user']['password']);
$paramStr.=' --cli_user '.base64_encode($cliUser);
$commandStr.=' '.config('root_path').DIRECTORY_SEPARATOR.'caiji '.$paramStr;
$descriptorspec = array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
@ -156,4 +145,37 @@ function is_official_url($url){
}else{
return false;
}
}
function convert_html2json($html,$returnStr=false){
static $jsonpRegExp='/^(\s*[\$\w\-]+\s*[\{\(])+(?P<json>[\s\S]+)(?P<end>[\}\]])\s*\)\s*[\;]{0,1}/i';
$json=json_decode($html,true);
if(!empty($json)){
if($returnStr){
$json=$html;
}
}elseif(preg_match($jsonpRegExp,$html,$json)){
$json=trim($json['json']).$json['end'];
if(!$returnStr){
$json=json_decode($json,true);
}
}
return $json?$json:null;
}
function array_filter_keep0($list){
if(is_array($list)){
foreach ($list as $k=>$v){
if(empty($v)&&$v!==0&&$v!=='0'){
unset($list[$k]);
}
}
}
return $list;
}

View File

@ -33,7 +33,7 @@ class Api extends BaseController{
if(!IS_CLI){
ignore_user_abort(true);
if($GLOBALS['config']['caiji']['server']=='cli'){
if($GLOBALS['_sc']['c']['caiji']['server']=='cli'){
cli_command_exec('collect auto');
exit();
@ -55,19 +55,19 @@ class Api extends BaseController{
}
ignore_user_abort(true);
if($GLOBALS['config']['caiji']['timeout']>0){
set_time_limit(60*$GLOBALS['config']['caiji']['timeout']);
if($GLOBALS['_sc']['c']['caiji']['timeout']>0){
set_time_limit(60*$GLOBALS['_sc']['c']['caiji']['timeout']);
}else{
set_time_limit(0);
}
if(empty($GLOBALS['config']['caiji']['auto'])){
if(empty($GLOBALS['_sc']['c']['caiji']['auto'])){
$this->error('请先开启自动采集','Admin/Setting/caiji');
}
$lastCollectTime=cache('last_collect_time');
if($GLOBALS['config']['caiji']['interval']>0){
if($GLOBALS['_sc']['c']['caiji']['interval']>0){
$waitTime=(60*$GLOBALS['config']['caiji']['interval'])-abs(time()-$lastCollectTime);
$waitTime=(60*$GLOBALS['_sc']['c']['caiji']['interval'])-abs(time()-$lastCollectTime);
if($waitTime>0){
$this->error('再次采集需等待'.(($waitTime<60)?($waitTime.'秒'):(sprintf("%.2f", $waitTime/60).'分钟')),'Admin/Api/collect',null,$waitTime);
}

View File

@ -61,9 +61,6 @@ class App extends BaseController {
$appData['app_class']=$mapp->get_class_vars($appClass);
}
$this->assign('app',$app);
$this->assign('appUrl',$appUrl);
$this->assign('navid',$navid);

View File

@ -30,7 +30,7 @@ class Backstage extends BaseController{
'os'=>php_uname('s').' '.php_uname('r'),
'php'=>PHP_VERSION,
'db'=>config('database.type'),
'version'=>$GLOBALS['config']['version']?$GLOBALS['config']['version']:constant("SKYCAIJI_VERSION"),
'version'=>$GLOBALS['_sc']['c']['version']?$GLOBALS['_sc']['c']['version']:constant("SKYCAIJI_VERSION"),
'server'=>$_SERVER["SERVER_SOFTWARE"],
'upload_max'=>ini_get('upload_max_filesize')
);
@ -42,7 +42,7 @@ class Backstage extends BaseController{
$runInfo['auto_status']='良好';
/*设置采集状态*/
if($GLOBALS['config']['caiji']['auto']){
if($GLOBALS['_sc']['c']['caiji']['auto']){
$lastTime=cache('last_collect_time');
$taskAutoCount=model('Task')->where('auto',1)->count();
@ -55,9 +55,9 @@ class Backstage extends BaseController{
if($lastTime>0){
$runInfo['auto_status']='运行良好';
$serverData['caiji']='最近采集:'.date('Y-m-d H:i:s',$lastTime).' &nbsp;';
if($GLOBALS['config']['caiji']['run']=='backstage'){
if($GLOBALS['_sc']['c']['caiji']['run']=='backstage'){
if(NOW_TIME-$lastTime>60*($GLOBALS['config']['caiji']['interval']+15)){
if(NOW_TIME-$lastTime>60*($GLOBALS['_sc']['c']['caiji']['interval']+15)){
$serverData['caiji'].='<p class="help-block">自动采集似乎停止了,请<a href="'.
url('Admin/Setting/caiji').'">重新保存设置</a>以便激活采集</p>';
@ -78,6 +78,45 @@ class Backstage extends BaseController{
$upgradeDb=true;
}
$LocSystem=new \skycaiji\install\event\LocSystem();
$systemData=$LocSystem->environment();
$systemWarning=array('php'=>array(),'path_write'=>array(),'path_read'=>array());
if(is_array($systemData['php'])){
foreach ($systemData['php'] as $k=>$v){
if(empty($v[1])){
$systemWarning['php'][$v[0]]=$v[0];
}
}
}
if(is_array($systemData['path'])){
foreach ($systemData['path'] as $k=>$v){
if(empty($v[1])){
$systemWarning['path_write'][$v[0]]=$v[0];
}
if(empty($v[2])){
$systemWarning['path_read'][$v[0]]=$v[0];
}
}
}
$hasSystemWarning=false;
foreach ($systemWarning as $k=>$v){
if(!empty($v)){
$hasSystemWarning=true;
}
}
if(!$hasSystemWarning){
$systemWarning=null;
}
$adminIndexData=cache('backstage_admin_index');
$timeout=NOW_TIME-(3600*24*30);
$mcacheSource=CacheModel::getInstance('source_url');
@ -89,12 +128,14 @@ class Backstage extends BaseController{
$mcacheCont=CacheModel::getInstance('cont_url');
$mcacheCont->db()->where('dateline','<',$timeout)->delete();
$GLOBALS['content_header']='后台管理';
$GLOBALS['breadcrumb']=breadcrumb(array('首页'));
$GLOBALS['_sc']['p_name']='后台管理';
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Backstage/index'),'title'=>'首页')));
$this->assign('runInfo',$runInfo);
$this->assign('serverData',$serverData);
$this->assign('upgradeDb',$upgradeDb);
$this->assign('systemWarning',$systemWarning);
$this->assign('adminIndexData',$adminIndexData);
return $this->fetch('backstage/index');
}
@ -105,10 +146,21 @@ class Backstage extends BaseController{
}
/*获取推送消息*/
public function adminIndexAction(){
$callback=input('?'.config('var_jsonp_handler'))?input(config('var_jsonp_handler')):config('default_jsonp_handler');
$html=get_html('https://www.skycaiji.com/store/client/adminIndex?v='.SKYCAIJI_VERSION.'&'.config('var_jsonp_handler').'='.rawurlencode($callback),null,null,'utf-8');
header('Content-Type:application/json;charset=utf-8');
exit($html);
$refresh=input('refresh');
$data=cache('backstage_admin_index');
$data=is_array($data)?$data:array();
if($refresh||empty($data['html'])){
$data=get_html('https://www.skycaiji.com/store/client/adminIndex?v='.SKYCAIJI_VERSION,null,null,'utf-8');
$data=json_decode($data,true);
$data=array(
'ver'=>$data['ver'],
'html'=>$data['html']
);
cache('backstage_admin_index',$data);
}
return json($data);
}
/*后台任务操作*/
public function backstageTaskAction(){
@ -221,7 +273,7 @@ class Backstage extends BaseController{
}
}
/*生成js语言包文件*/
public function createJsLangAction(){
$langs=array();
$langs['zh-cn']='zh-cn';
@ -259,4 +311,5 @@ class Backstage extends BaseController{
}
print_r ( $repeatList );
}
}

View File

@ -76,8 +76,8 @@ class Collected extends BaseController {
$taskList=model('Task')->where(array('id'=>array('in',$taskIds)))->column('name','id');
}
}
$GLOBALS['content_header']=lang('collected_list');
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('Collected/list'),'title'=>lang('collected_list'))));
$GLOBALS['_sc']['p_name']=lang('collected_list');
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Collected/list'),'title'=>'已采集数据'),array('url'=>url('Collected/list'),'title'=>'数据列表')));
}
$this->assign('search',$search);
$this->assign('dataList',$dataList);
@ -122,4 +122,135 @@ class Collected extends BaseController {
$this->success(lang('op_success'),'list');
}
}
/*图表显示*/
public function chartAction(){
$GLOBALS['_sc']['p_name']='已采集数据:统计图表';
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Collected/list'),'title'=>'已采集数据'),array('url'=>url('Collected/chart'),'title'=>'统计图表')));
return $this->fetch();
}
public function chartOpAction(){
$op=input('op');
$mcollected=model('Collected');
$nowTime=time();
$nowYear=intval(date('Y',$nowTime));
$nowMonth=intval(date('m',$nowTime));
$nowDay=intval(date('d',$nowTime));
if(in_array($op,array('today','this_month','this_year','years'))){
$dataList = array (
'name'=>array(),
'success' => array (),
'failed' => array ()
);
$dateList=array();
if($op=='today'){
for($i=0;$i<24;$i++){
$start=$nowYear.'-'.$nowMonth.'-'.$nowDay.' '.$i.':00';
$end=strtotime($start.' +1 hour')-1;
$start=strtotime($start);
$dateList[$i+1]=array('name'=>($i+1).'点','start'=>$start,'end'=>$end);
}
}if($op=='this_month'){
$endDay=date('d',strtotime("{$nowYear}-{$nowMonth}-1 +1 month -1 day"));
$endDay=intval($endDay);
for($i=1;$i<=$endDay;$i++){
$start=$nowYear.'-'.$nowMonth.'-'.$i;
$end=strtotime($start.' +1 day')-1;
$start=strtotime($start);
$dateList[$i]=array('name'=>$i.'号','start'=>$start,'end'=>$end);
}
}elseif($op=='this_year'){
for($i=1;$i<=12;$i++){
$start=$nowYear.'-'.$i.'-1';
$end=strtotime($start.' +1 month')-1;
$start=strtotime($start);
$dateList[$i]=array('name'=>$i.'月','start'=>$start,'end'=>$end);
}
}elseif($op=='years'){
$minTime=$mcollected->min('addtime');
$minYear=intval(date('Y',$minTime));
for($i=$nowYear;$i>=$minYear;$i--){
$start=$i.'-1-1';
$end=strtotime($start.' +1 year')-1;
$start=strtotime($start);
$dateList[$i]=array('name'=>$i.'年','start'=>$start,'end'=>$end);
}
}
foreach ($dateList as $k=>$v){
$dataList['name'][$k]=$v['name'];
$dataList['success'][$k]=$mcollected->where(array(
'addtime'=>array('between',array($v['start'],$v['end'])),
'target'=>array('<>','')
))->count();
$dataList['failed'][$k]=$mcollected->where(array(
'addtime'=>array('between',array($v['start'],$v['end'])),
'error'=>array('<>','')
))->count();
}
$this->success('',null,$dataList);
}elseif($op=='release'){
$dataList = array (
'name'=>array(),
'success' => array (),
'failed' => array (),
);
foreach(config('release_modules') as $module){
if($module=='api'){
continue;
}
$dataList['name'][$module]=lang('rele_module_'.$module);
$dataList['success'][$module]=$mcollected->where(array(
'release'=>$module,
'target'=>array('<>','')
))->count();
$dataList['failed'][$module]=$mcollected->where(array(
'release'=>$module,
'error'=>array('<>','')
))->count();
}
$this->success('',null,$dataList);
}elseif($op=='task'){
$dataList = array (
'name'=>array(),
'total' => array (),
);
$list=$mcollected->field('task_id,count(id) as ct')->group('task_id')->having('count(id)>0')->select();
$taskIds=array();
foreach($list as $v){
$taskIds[$v['task_id']]=$v['task_id'];
}
if($taskIds){
$taskList=model('Task')->where('id','in',$taskIds)->column('name','id');
}
foreach($list as $v){
if(isset($taskList[$v['task_id']])){
$dataList['name'][$v['task_id']]=$taskList[$v['task_id']];
$dataList['total'][$v['task_id']]=$v['ct'];
}
}
$this->success('',null,$dataList);
}
}
}

View File

@ -60,7 +60,7 @@ class Collector extends BaseController {
}
if($collId>0){
$tab_link=trim(input('tab_link'),'#');
$this->success(lang('op_success'),'Collector/set?task_id='.$taskId.($tab_link?'&tab_link='.$tab_link:''));
$this->success(lang('op_success'),'Collector/set?task_id='.$taskId.($tab_link?'&tab_link='.$tab_link:'').(input('?easymode')?'&easymode=1':''));
}else{
$this->error(lang('op_failed'));
}
@ -68,8 +68,14 @@ class Collector extends BaseController {
if(!empty($collData)){
$collData['config']=unserialize($collData['config']);
}
$GLOBALS['content_header']=lang('coll_set').lang('separator').lang('task_module_'.$taskData['module']);
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('Task/edit?id='.$taskData['id']),'title'=>lang('task').lang('separator').$taskData['name']),lang('coll_set')));
$GLOBALS['_sc']['p_name']=lang('coll_set').lang('separator').lang('task_module_'.$taskData['module']);
if(input('?easymode')){
$GLOBALS['_sc']['p_name'].=' <small><a href="'.url('Collector/set?task_id='.$taskId).'" onclick="if(window.top){window.top.location.href=$(this).attr(\'href\');return false;}">普通模式</a></small>';
}else{
$GLOBALS['_sc']['p_name'].=' <small><a href="'.url('Cpattern/easymode?task_id='.$taskId).'">简单模式</a></small>';
}
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Task/edit?id='.$taskData['id']),'title'=>lang('task').lang('separator').$taskData['name']),array('url'=>url('Collector/set?task_id='.$taskData['id']),'title'=>lang('coll_set'))));
$this->assign('collData',$collData);
$this->assign('taskData',$taskData);
return $this->fetch();

View File

@ -11,6 +11,7 @@
namespace skycaiji\admin\controller;
use skycaiji\admin\model\FuncApp;
/*采集器:规则采集*/
class Cpattern extends BaseController {
/**
@ -178,7 +179,7 @@ class Cpattern extends BaseController {
$field['num_end']=intval($field['num_end']);
$field['num_end'] = max ( $field['num_start'], $field ['num_end'] );
break;
case 'words':if(empty($field['words']))$this->error('固定文字不能为空!');break;
case 'list':if(empty($field['list']))$this->error('随机抽取不能为空!');break;
case 'extract':if(empty($field['extract']))$this->error('请选择字段!');break;
case 'merge':if(empty($field['merge']))$this->error('字段组合不能为空!');break;
@ -225,6 +226,16 @@ class Cpattern extends BaseController {
$this->assign('type',$type);
$op=input('op');
$transApiLangs=null;
if(!empty($GLOBALS['_sc']['c']['translate'])&&!empty($GLOBALS['_sc']['c']['translate']['open'])){
$transApiLangs=\util\Translator::get_api_langs($GLOBALS['_sc']['c']['translate']['api']);
$transApiLangs=$transApiLangs?$transApiLangs:null;
}
$this->assign('transApiLangs',$transApiLangs);
if(empty($type)){
if(empty($op)){
@ -263,6 +274,39 @@ class Cpattern extends BaseController {
}
}
}
/*获取函数插件列表*/
public function process_funcAction(){
$module=input('module');
if(empty($module)){
$this->error('模块错误');
}
$mfuncApp=new FuncApp();
$cacheName='cpattern_process_func_methods_'.$module;
$cacheFuncs=cache($cacheName);
$enableApps=$mfuncApp->where(array('module'=>$module,'enable'=>1))->column('uptime','app');
$enableApps=md5(serialize($enableApps));
$apps=array();
if(empty($cacheFuncs)||$enableApps!=$cacheFuncs['key']||abs(time()-$cacheFuncs['time'])>600){
$appList=$mfuncApp->where(array('module'=>$module,'enable'=>1))->column('uptime','app');
$apps=array();
if(!empty($appList)){
foreach ($appList as $k=>$v){
$appClass=$mfuncApp->get_app_class($module, $k);
if(!empty($appClass['methods'])){
$apps[$k]=$appClass;
}
}
}
cache($cacheName,array('list'=>$apps,'time'=>time(),'key'=>md5(serialize($appList))));
}else{
$apps=$cacheFuncs['list'];
}
$this->success('',null,$apps);
}
/**
* 内容分页
* 添加分页字段
@ -351,7 +395,7 @@ class Cpattern extends BaseController {
model('Task')->loadConfig($taskData['config']);
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('Collector/set?task_id='.$taskData['id']),'title'=>lang('task').lang('separator').$taskData['name']),'测试'));
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Collector/set?task_id='.$taskData['id']),'title'=>lang('task').lang('separator').$taskData['name']),array('url'=>url('Cpattern/test&op='.$op.'&coll_id='.$coll_id),'title'=>'测试')));
if('source_urls'==$op){
@ -388,7 +432,7 @@ class Cpattern extends BaseController {
$eCpattern->success('',null,array('urls'=>$levelData['urls'],'levelName'=>$levelData['levelName'],'nextLevel'=>$levelData['nextLevel']));
}elseif('cont_url'==$op){
$GLOBALS['content_header']='测试抓取';
$GLOBALS['_sc']['p_name']='测试抓取';
$cont_url=input('cont_url','','trim');
$test=input('test');
@ -463,7 +507,7 @@ class Cpattern extends BaseController {
$num=0;
foreach ($eCpattern->exclude_cont_urls[$md5Url] as $k=>$v){
$num+=count($v);
$num+=count((array)$v);
}
$msg='通过数据处理排除了'.$num.'条数据';
}
@ -505,7 +549,7 @@ class Cpattern extends BaseController {
}
}elseif('match'==$op){
$GLOBALS['content_header']='模拟匹配';
$GLOBALS['_sc']['p_name']='模拟匹配';
if(request()->isPost()){
$type=strtolower(input('type'));
$content=input('content','','trim');
@ -563,42 +607,61 @@ class Cpattern extends BaseController {
}elseif('elements'==$op){
$cont_url=input('cont_url','','trim');
if(!preg_match('/^\w+\:\/\//',$cont_url)){
$cont_url='http://'.$cont_url;
}
$html=$eCpattern->get_html($cont_url,false,$eCpattern->config['url_post']);
$jsonData=null;
if(preg_match('/^\{[\s\S]*\}$/',$html)){
$jsonData=json_decode($html,true);
$jsonData=$jsonData?$jsonData:null;
}
$this->redirect('Cpattern/browser?coll_id='.$coll_id.'&url='.rawurlencode($cont_url));
}
}
/*编辑规则:简单模式*/
public function easymodeAction(){
$taskId=input('task_id/d',0);
$collId=model('Collector')->where('task_id',$taskId)->value('id');
$this->assign('taskId',$taskId);
$this->assign('collId',$collId);
return $this->fetch();
}
/*浏览器*/
public function browserAction(){
$coll_id=input('coll_id/d',0);
$mcoll=model('Collector');
$collData=$mcoll->where(array('id'=>$coll_id))->find();
if(empty($collData)){
$collData=array();
}else{
$collData=$collData->toArray();
}
$eCpattern=controller('admin/Cpattern','event');
$eCpattern->init($collData);
$url=input('url','','trim');
if(!preg_match('/^\w+\:\/\//',$url)){
$url='http://'.$url;
}
$html=$eCpattern->get_html($url,false,$eCpattern->config['url_post']);
$jsonHtml=convert_html2json($html,true);
$config=$eCpattern->config;
$config=is_array($config)?$config:array();
if(empty($jsonHtml)){
$publicUrl=config('root_website').'/public';
$jscss="\r\n<!-- 以下为蓝天采集器代码 -->\r\n".'<script src="%s/jquery/jquery.min.js?%s"></script>'
."\r\n".'<script src="%s/static/js/admin/cpattern_elements.js?%s"></script>'
."\r\n".'<link rel="stylesheet" href="%s/static/css/cpattern_elements.css?%s">';
$jscss=sprintf($jscss,$publicUrl,config('html_v'),$publicUrl,config('html_v'),$publicUrl,config('html_v'));
$html=preg_replace('/<script[^<>]*?>[\s\S]*?<\/script>/i', '', $html);
$html=preg_replace('/<meta[^<>]*charset[^<>]*?>/i', '', $html);
header("Content-type:text/html;charset=utf-8");
$eCpattern->assign('html',$html);
$eCpattern->assign('config',$config);
if(empty($jsonData)){
$html=preg_replace('/<script[^<>]*?>[\s\S]*?<\/script>/i', '', $html);
$html=preg_replace('/<meta[^<>]*charset[^<>]*?>/i', '', $html);
$html.=$jscss."\r\n".'<script>$(document).ready(function(){skycaijiCE.init();});</script>';
ob_clean();
header("Content-type:text/html;charset=utf-8");
exit($html);
}else{
$GLOBALS['content_header']='分析元素';
$eCpattern->assign('html',$html);
$eCpattern->assign('jscss',$jscss);
return $eCpattern->fetch('cpattern:test_elements');
}
return $eCpattern->fetch('cpattern:browser');
}else{
$GLOBALS['_sc']['p_name']='分析网页';
$eCpattern->assign('jsonHtml',$jsonHtml);
return $eCpattern->fetch('cpattern:browser_json');
}
}
/*名称命名规范*/

View File

@ -12,6 +12,7 @@
namespace skycaiji\admin\controller;
use plugin;
use skycaiji\admin\model\FuncApp;
class Develop extends BaseController {
public static $typeList = array (
'number' => '数字(number)',
@ -162,8 +163,9 @@ class Develop extends BaseController {
}
}
$GLOBALS['content_header']='开发CMS发布插件 <small><a href="https://www.skycaiji.com/manual/doc/cms" target="_blank"><span class="glyphicon glyphicon-info-sign"></span></a></small>';
$GLOBALS['breadcrumb']=breadcrumb(array('开发工具','开发CMS发布插件'));
$GLOBALS['_sc']['p_name']='开发CMS发布插件 <small><a href="https://www.skycaiji.com/manual/doc/cms" target="_blank"><span class="glyphicon glyphicon-info-sign"></span></a></small>';
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Mystore/ReleaseApp'),'title'=>'CMS发布插件'),array('url'=>url('Develop/releaseCms'),'title'=>'开发CMS发布插件')));
$this->assign('config',$config);
$this->assign('is_old_plugin',$is_old_plugin);
return $this->fetch('releaseCms');
@ -537,8 +539,6 @@ EOF;
$codeAppPhp=preg_replace($matchVar, 'public $'.$reVar.'='.$reCont.';', $codeAppPhp);
}else{
preg_match_all($matchVar,$codeAppPhp,$asd);
$codeAppPhp=preg_replace($matchVar, 'public $'.$reVar."='".addslashes($reCont)."';", $codeAppPhp);
}
}
@ -561,12 +561,12 @@ EOF;
$this->success('修改成功','Develop/app?app='.$app);
}
}else{
$GLOBALS['content_header']='开发应用程序 <small><a href="https://www.skycaiji.com/manual/doc/app" target="_blank"><span class="glyphicon glyphicon-info-sign"></span></a></small>';
$GLOBALS['_sc']['p_name']='开发应用程序 <small><a href="https://www.skycaiji.com/manual/doc/app" target="_blank"><span class="glyphicon glyphicon-info-sign"></span></a></small>';
if($appData){
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('App/manage?app='.$appData['app']),'title'=>$appData['config']['name']),'开发应用'));
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('App/manage?app='.$appData['app']),'title'=>$appData['config']['name']),array('url'=>url('Develop/app?app='.$appData['app']),'title'=>'开发应用')));
}else{
$GLOBALS['breadcrumb']=breadcrumb(array('开发工具','应用程序'));
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Mystore/app'),'title'=>'应用程序'),array('url'=>url('Develop/app'),'title'=>'开发应用')));
}
$appClass=$mapp->app_class($app);
@ -743,6 +743,94 @@ EOF;
$this->error();
}
}
/*开发函数插件*/
public function funcAction(){
$mfuncApp=new FuncApp();
if(request()->isPost()){
if(input('?edit')){
$app=input('app');
$name=input('name');
$name=strip_tags($name);
$funcData=$mfuncApp->where('app',$app)->find();
if(empty($funcData)){
$this->error('插件不存在');
}
$mfuncApp->where('id',$funcData['id'])->update(array('name'=>$name,'uptime'=>time()));
$this->success('修改成功','Develop/func?app='.$app);
}else{
$module=input('module');
$copyright=input('copyright');
$identifier=input('identifier');
$name=input('name');
$methods=input('methods/a');
if(empty($module)){
$this->error('请选择类型');
}
$module=$mfuncApp->format_module($module);
$copyright=$mfuncApp->format_copyright($copyright);
$identifier=$mfuncApp->format_identifier($identifier);
if(!$mfuncApp->right_module($module)){
$this->error('类型错误');
}
if(!$mfuncApp->right_identifier($identifier)){
$this->error('功能标识只能由字母或数字组成,且首个字符必须是字母!');
}
if(!$mfuncApp->right_copyright($copyright)){
$this->error('作者版权只能由字母或数字组成,且首个字符必须是字母!');
}
$newMethods=array();
foreach ($methods['method'] as $k=>$v){
if(preg_match('/^[a-z\_]\w*/',$v)){
foreach ($methods as $mk=>$mv){
$newMethods[$mk][$k]=$mv[$k];
}
}
}
$methods=$newMethods;
unset($newMethods);
if(empty($methods['method'])){
$this->error('请添加方法!');
}
$app=$mfuncApp->app_name($copyright,$identifier);
$id=$mfuncApp->createApp($module,$app,array('name'=>$name,'methods'=>$methods));
if($id>0){
$this->success('创建成功','Develop/func?app='.$app);
}else{
$this->error('创建失败');
}
}
}else{
$GLOBALS['_sc']['p_name']='开发函数插件 <small><a href="https://www.skycaiji.com/manual/doc/func" target="_blank"><span class="glyphicon glyphicon-info-sign"></span></a></small>';
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Mystore/funcApp'),'title'=>'函数插件'),array('url'=>url('Develop/func'),'title'=>'开发函数插件')));
if(input('?app')){
$funcData=$mfuncApp->where('app',input('app'))->find();
if(!empty($funcData)){
$funcClass=$mfuncApp->get_app_class($funcData['module'],$funcData['app']);
$funcClass['name']=$funcData['name'];
$this->assign('funcClass',$funcClass);
}
}
$this->assign('modules',$mfuncApp->funcModules);
return $this->fetch();
}
}
public function _format_array($arr,$headStr=''){
if(is_array($arr)){

View File

@ -18,116 +18,107 @@ class Index extends BaseController{
}
/*后台运行采集,会无限运行下去*/
public function backstageAction(){
if(empty($GLOBALS['config']['caiji']['auto'])){
$this->error('请先开启自动采集');
}
if(!input('?autorun')){
$key=input('key');
$cacheKey=CacheModel::getInstance()->getCache('admin_index_backstage_key', 'data');
if(empty($key)||$key!=$cacheKey){
$this->error('参数错误');
$this->error('密钥错误,请在后台运行');
}
$runtime=input('runtime/d');
if(empty($runtime)){
$runtime=time();
cache('caiji_auto_backstage_runtime',$runtime);
}else{
$cache_runtime=cache('caiji_auto_backstage_runtime');
$cache_runtime=intval($cache_runtime);
if($runtime<$cache_runtime){
$this->error('终止旧进程');
}
}
$curlCname='caiji_auto_curltime_'.$runtime;
if(input('?curltime')){
$cacheCurl=cache($curlCname);
if(!empty($cacheCurl)&&$cacheCurl>input('curltime')){
$this->error('终止过期进程');
}
cache($curlCname,input('curltime'));
}
ignore_user_abort(true);
set_time_limit(0);
$mconfig=new \skycaiji\admin\model\Config();
$caijiConfig=$mconfig->where('cname','caiji')->find();
$caijiConfig=$mconfig->convertData($caijiConfig);
$caijiConfig=$mconfig->getConfig('caiji','data');
if(empty($caijiConfig['data']['auto'])||$caijiConfig['data']['run']!='backstage'){
$this->error('自动采集已停止');
if(empty($caijiConfig['auto'])){
$this->error('请先开启自动采集');
}
try{
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, url('Admin/Api/collect?backstage=1',null,false,true) );
curl_setopt ( $ch, CURLOPT_TIMEOUT, 3 );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, 1 );
curl_setopt ( $ch, CURLOPT_HEADER, 1 );
curl_setopt ( $ch, CURLOPT_NOBODY, 1 );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, FALSE );
curl_exec ( $ch );
curl_close ( $ch );
}catch(\Exception $ex){
if($caijiConfig['run']!='backstage'){
$this->error('不是后台运行方式');
}
sleep(15);
if($GLOBALS['config']['caiji']['auto']){
if($caijiConfig['server']=='cli'){
cli_command_exec('collect backstage');
}else{
$curlCname='caiji_auto_curltime_'.$key;
if(input('?curltime')){
$cacheCurl=cache($curlCname);
if(!empty($cacheCurl)&&$cacheCurl>input('curltime')){
$this->error('终止过期进程');
}
cache($curlCname,input('curltime'));
}
ignore_user_abort(true);
set_time_limit(0);
try{
get_html(url('Admin/Api/collect?backstage=1',null,false,true),null,array('timeout'=>3));
}catch(\Exception $ex){
}
sleep(15);
try{
$maxTimes=0;
do {
$cacheKey=CacheModel::getInstance()->getCache('admin_index_backstage_key', 'data');
if(empty($key)||$key!=$cacheKey){
$this->error('密钥错误,终止进程');
}
$caijiConfig=$mconfig->getConfig('caiji','data');
if(empty($caijiConfig['auto'])){
$this->error('请先开启自动采集');
}
if($caijiConfig['run']!='backstage'){
$this->error('不是后台运行方式');
}
$curltime=time();
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, url('Admin/Index/backstage?autorun=1&runtime='.$runtime.'&curltime='.$curltime,null,false,true) );
curl_setopt ( $ch, CURLOPT_TIMEOUT, 2 );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, 1 );
curl_setopt ( $ch, CURLOPT_HEADER, 1 );
curl_setopt ( $ch, CURLOPT_NOBODY, 1 );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, FALSE );
curl_exec ( $ch );
curl_close ( $ch );
sleep(1);
@get_html(url('Admin/Index/backstage?key='.$key.'&curltime='.$curltime,null,false,true),null,array('timeout'=>2));
sleep(5);
$cacheCurl=cache($curlCname);
$continue=false;
if(empty($cacheCurl)||$cacheCurl<$curltime){
$maxTimes++;
if((empty($cacheCurl)||$cacheCurl<$curltime)&&$maxTimes<=3){
$continue=true;
}
}while($continue);
}catch(\Exception $ex){
}
exit();
}
exit();
}
/*访问执行采集*/
public function caijiAction(){
if(empty($GLOBALS['config']['caiji']['auto'])){
if(empty($GLOBALS['_sc']['c']['caiji']['auto'])){
$this->error('请先开启自动采集','Admin/Setting/caiji');
}
@get_html(url('Admin/Api/collect?backstage=1',null,false,true),null,array('timeout'=>3));
$waitTime=$GLOBALS['config']['caiji']['interval']*60;
$waitTime=$waitTime>0?$waitTime:3;
$waitTime=$GLOBALS['_sc']['c']['caiji']['interval']*60;
$waitTime=$waitTime>0?$waitTime:60;
$this->success('正在采集...','Admin/Index/caiji',null,$waitTime);
}
/*任务api发布*/
@ -138,11 +129,11 @@ class Index extends BaseController{
public function loginAction(){
if(request()->isPost()){
if(!check_usertoken()){
$this->error(lang('usertoken_error'));
$this->error(lang('usertoken_error'),'Admin/Index/login');
}
$mcacheLogin=CacheModel::getInstance('login');
$config_login=$GLOBALS['config']['site']['login'];
$config_login=$GLOBALS['_sc']['c']['site']['login'];
$clientIpMd5=md5(request()->ip());
if(!empty($config_login['limit'])){
@ -155,7 +146,7 @@ class Index extends BaseController{
if(input('post.sublogin')){
$username=strtolower(trim(input('post.username')));
$pwd=trim(input('post.password'));
if($GLOBALS['config']['site']['verifycode']){
if($GLOBALS['_sc']['c']['site']['verifycode']){
$verifycode=trim(input('post.verifycode'));
$check=check_verify($verifycode);
@ -241,7 +232,7 @@ class Index extends BaseController{
/*退出*/
public function logoutAction(){
\think\Cookie::delete('login_history');
unset($GLOBALS['user']);
unset($GLOBALS['_sc']['user']);
session('user_id',null);
session('is_admin',null);
$this->success(lang('op_success'),'Admin/Index/index');
@ -291,9 +282,9 @@ class Index extends BaseController{
if($step===1){
if(!check_usertoken()){
$this->error(lang('usertoken_error'));
$this->error(lang('usertoken_error'),'Admin/Index/find_password');
}
if($GLOBALS['config']['site']['verifycode']){
if($GLOBALS['_sc']['c']['site']['verifycode']){
$verifycode=trim(input('verifycode'));
$check=check_verify($verifycode);
@ -370,7 +361,7 @@ class Index extends BaseController{
}else{
if($step===2){
$emailStatus=array('success'=>false,'msg'=>'');
if(empty($GLOBALS['config']['email'])){
if(empty($GLOBALS['_sc']['c']['email'])){
$emailStatus['msg']=lang('config_error_none_email');
}else{
$waitTime=60;
@ -384,7 +375,7 @@ class Index extends BaseController{
$minutes=floor($expire/60);
$yzm=mt_rand(100000,999999);
session($waitSname,NOW_TIME);
$mailReturn=send_mail($GLOBALS['config']['email'], $stepSession['user']['email'], $stepSession['user']['username'],lang('find_pwd_email_subject'),lang('find_pwd_email_body',array('yzm'=>$yzm,'minutes'=>$minutes)));
$mailReturn=send_mail($GLOBALS['_sc']['c']['email'], $stepSession['user']['email'], $stepSession['user']['username'],lang('find_pwd_email_subject'),lang('find_pwd_email_body',array('yzm'=>$yzm,'minutes'=>$minutes)));
if($mailReturn===true){
$yzmSname='send_yzm.'.md5($username);
session(array('name'=>$yzmSname,'expire'=>$expire));

View File

@ -11,17 +11,9 @@
namespace skycaiji\admin\controller;
use skycaiji\admin\model\FuncApp;
class Mystore extends BaseController {
public function indexAction(){
$this->redirect('Mystore/rule');
}
public function ruleAction(){
@ -66,8 +58,8 @@ class Mystore extends BaseController {
}
}
$GLOBALS['content_header']='已下载';
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('Mystore/index'),'title'=>'已下载'),lang('rule_'.$type)));
$GLOBALS['_sc']['p_name']='已下载';
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Mystore/rule'),'title'=>'已下载:'.lang('rule_'.$type))));
$this->assign('ruleList',$ruleList);
@ -103,9 +95,9 @@ class Mystore extends BaseController {
$auto=input('auto/d',0);
model('Config')->setConfig('store_auto_check_rule',$auto);
if($auto){
$this->success('设置为自动检测更新');
$this->success('规则设置为自动检测更新');
}else{
$this->error('设置为手动检测更新');
$this->error('规则设置为手动检测更新');
}
}elseif($op=='check_store_update'){
@ -213,8 +205,8 @@ class Mystore extends BaseController {
}
}
$GLOBALS['content_header']='已下载';
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('Mystore/index'),'title'=>'已下载'),'发布插件'));
$GLOBALS['_sc']['p_name']='已下载';
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Mystore/releaseApp'),'title'=>'已下载:发布插件')));
$this->assign('appList',$appList);
return $this->fetch('releaseApp');
@ -242,65 +234,13 @@ class Mystore extends BaseController {
$this->success(lang('op_success'),'Mystore/ReleaseApp');
}elseif($op=='auto_check'){
$auto=input('auto/d');
model('Config')->setConfig('store_auto_check_plugin',$auto);
if($auto){
$this->success('设置为自动检测更新');
}else{
$this->error('设置为手动检测更新');
}
$this->_auto_check_plugin();
}elseif($op=='check_store_update'){
$ids=input('ids/a');
$appList=model('ReleaseApp')->where(array('module'=>'cms','id'=>array('in',$ids)))->column('*','app');
$appList1=array();
foreach ($appList as $k=>$v){
$appList1[$v['app'].'_'.$v['provider_id']]=$v;
}
$appList=$appList1;
unset($appList1);
$uptimeList=array();
if(!empty($appList)){
$provList=array();
$provApps=array();
foreach ($appList as $v){
$provList[$v['provider_id']]=$v['provider_id'];
$provApps[$v['provider_id']][$v['app']]=$v['app'];
}
if(!empty($provList)){
$provList=model('Provider')->where('id','in',$provList)->column('*','id');
}else{
$provList=array();
}
foreach ($provApps as $provId=>$apps){
$apps=implode(',',$apps);
$apps=rawurlencode($apps);
$url='https://www.skycaiji.com';
if(!empty($provId)&&!empty($provList[$provId])){
$url=$provList[$provId]['url'];
}
$url.='/client/plugin/update?apps='.$apps;
$uptimeList=get_html($url,null,array('timeout'=>2));
$uptimeList=json_decode($uptimeList,true);
if(!empty($uptimeList)){
foreach ($uptimeList as $app=>$uptime){
if($uptime>0&&$uptime>$appList[$app.'_'.$provId]['uptime']){
$updateList[]=$appList[$app.'_'.$provId]['id'];
}
}
}
}
}
$updateList=$this->_check_store_plugin_update($appList);
if(!empty($updateList)){
$this->success('',null,$updateList);
}else{
@ -392,8 +332,8 @@ class Mystore extends BaseController {
}
}
$GLOBALS['content_header']='应用程序';
$GLOBALS['breadcrumb']=breadcrumb(array('应用程序'));
$GLOBALS['_sc']['p_name']='应用程序';
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Mystore/app'),'title'=>'应用程序')));
$this->assign('pagenav',$pagenav);
$this->assign('dbApps',$dbApps);
@ -411,9 +351,9 @@ class Mystore extends BaseController {
$auto=input('auto/d');
model('Config')->setConfig('store_auto_check_app',$auto);
if($auto){
$this->success('设置为自动检测更新');
$this->success('应用设置为自动检测更新');
}else{
$this->error('设置为手动检测更新');
$this->error('应用设置为手动检测更新');
}
}elseif($op=='check_store_update'){
@ -480,4 +420,164 @@ class Mystore extends BaseController {
}
}
}
/*函数插件*/
public function funcAppAction(){
$page=max(1,input('p/d',0));
$cond=array();
$sortBy=input('sort','desc');
$sortBy=($sortBy=='asc')?'asc':'desc';
$orderKey=input('order');
$this->assign('sortBy',$sortBy);
$this->assign('orderKey',$orderKey);
$orderBy=!empty($orderKey)?($orderKey.' '.$sortBy):'id desc';
$mfuncApp=model('FuncApp');
$limit=20;
$count=$mfuncApp->where($cond)->count();
$appList=$mfuncApp->where($cond)->order($orderBy)->paginate($limit,false,paginate_auto_config());
$pagenav = $appList->render();
$this->assign('pagenav',$pagenav);
$appList=$appList->all();
if(!empty($appList)){
$provList=array();
foreach ($appList as $k=>$v){
if(!empty($v['provider_id'])){
$provList[$v['provider_id']]=$v['provider_id'];
}
}
$provList=model('Provider')->where('id','in',$provList)->column('*','id');
foreach ($appList as $k=>$v){
$url='https://www.skycaiji.com';
if(!empty($v['provider_id'])&&!empty($provList[$v['provider_id']])){
$url=$provList[$v['provider_id']]['url'];
}
$appList[$k]['store_url']=$url.'/client/plugin/detail?app='.$v['app'];
}
}
$GLOBALS['_sc']['p_name']='已下载';
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Mystore/funcApp'),'title'=>'已下载:函数插件')));
$this->assign('appList',$appList);
$this->assign('modules',$mfuncApp->funcModules);
return $this->fetch('func');
}
public function funcAppOpAction(){
$op=input('op');
$id=input('id');
$ops=array('item'=>array('delete','enable','detail'),'list'=>array('deleteall','check_store_update'),'else'=>array('auto_check'));
if(!in_array($op,$ops['item'])&&!in_array($op,$ops['list'])&&!in_array($op,$ops['else'])){
$this->error(lang('invalid_op'));
}
$mfuncApp=new FuncApp();
$appData=$mfuncApp->where('id',$id)->find();
if($op=='detail'){
$appClass=empty($appData)?array():$mfuncApp->get_app_class($appData['module'], $appData['app']);
$this->success('',null,$appClass);
}elseif($op=='enable'){
$enable=input('enable/d');
$mfuncApp->where('id',$appData['id'])->update(array('enable'=>$enable));
$this->success();
}elseif($op=='delete'){
if(!empty($appData['module'])&&!empty($appData['app'])){
$filename=$mfuncApp->filename($appData['module'], $appData['app']);
if(file_exists($filename)){
unlink($filename);
}
}
$mfuncApp->where('id',$appData['id'])->delete();
$this->success('删除成功');
}elseif($op=='deleteall'){
$ids=input('ids/a');
if(is_array($ids)&&count($ids)>0){
$mfuncApp->where(array('id'=>array('in',$ids)))->delete();
}
$this->success(lang('op_success'),'Mystore/funcApp');
}elseif($op=='auto_check'){
$this->_auto_check_plugin();
}elseif($op=='check_store_update'){
$ids=input('ids/a');
$appList=model('FuncApp')->where(array('id'=>array('in',$ids)))->column('*','app');
$updateList=$this->_check_store_plugin_update($appList);
if(!empty($updateList)){
$this->success('',null,$updateList);
}else{
$this->error();
}
}
}
/*插件设置自动检测*/
public function _auto_check_plugin(){
$auto=input('auto/d');
model('Config')->setConfig('store_auto_check_plugin',$auto);
if($auto){
$this->success('插件设置为自动检测更新');
}else{
$this->error('插件设置为手动检测更新');
}
}
/*检测插件云平台c插件更新*/
public function _check_store_plugin_update($appList=array()){
$appList1=array();
foreach ($appList as $k=>$v){
$appList1[$v['app'].'_'.$v['provider_id']]=$v;
}
$appList=$appList1;
unset($appList1);
$uptimeList=array();
$updateList=array();
if(!empty($appList)){
$provList=array();
$provApps=array();
foreach ($appList as $v){
$provList[$v['provider_id']]=$v['provider_id'];
$provApps[$v['provider_id']][$v['app']]=$v['app'];
}
if(!empty($provList)){
$provList=model('Provider')->where('id','in',$provList)->column('*','id');
}else{
$provList=array();
}
foreach ($provApps as $provId=>$apps){
$apps=implode(',',$apps);
$apps=rawurlencode($apps);
$url='https://www.skycaiji.com';
if(!empty($provId)&&!empty($provList[$provId])){
$url=$provList[$provId]['url'];
}
$url.='/client/plugin/update?apps='.$apps;
$uptimeList=get_html($url,null,array('timeout'=>2));
$uptimeList=json_decode($uptimeList,true);
if(!empty($uptimeList)){
foreach ($uptimeList as $app=>$uptime){
if($uptime>0&&$uptime>$appList[$app.'_'.$provId]['uptime']){
$updateList[]=$appList[$app.'_'.$provId]['id'];
}
}
}
}
}
return $updateList;
}
}

View File

@ -31,8 +31,8 @@ class Provider extends BaseController {
$pagenav=$list->render();
$list=$list->all();
$GLOBALS['content_header']='第三方平台';
$GLOBALS['breadcrumb']=breadcrumb(array('第三方平台'));
$GLOBALS['_sc']['p_name']='第三方平台';
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Provider/list'),'title'=>'第三方平台')));
$this->assign('list',$list);
$this->assign('pagenav',$pagenav);
@ -76,7 +76,7 @@ class Provider extends BaseController {
$sort=input('sort/d',0);
$enable=input('enable/d',0);
$domain=\skycaiji\admin\model\Provider::matchDomain($url);
$domain=\skycaiji\admin\model\Provider::match_domain($url);
if(empty($domain)){
$this->error('网址格式错误');
}

View File

@ -0,0 +1,250 @@
<?php
/*
|--------------------------------------------------------------------------
| SkyCaiji (蓝天采集器)
|--------------------------------------------------------------------------
| Copyright (c) 2018 https://www.skycaiji.com All rights reserved.
|--------------------------------------------------------------------------
| 使用协议 https://www.skycaiji.com/licenses
|--------------------------------------------------------------------------
*/
namespace skycaiji\admin\controller;
class Proxy extends BaseController {
public function listAction(){
$mproxy=model('Proxyip');
$cond=array();
$search=array(
'num'=>input('num/d',200),
'ip'=>input('ip'),
'user'=>input('user'),
'pwd'=>input('pwd'),
'type'=>input('?type')?input('type'):'all',
'invalid'=>input('?invalid')?input('invalid'):'all',
);
if(!empty($search['ip'])){
$cond['ip']=array('like',addslashes($search['ip']).'%');
}
if($search['type']!='all'){
$cond['type']=$search['type'];
}
if($search['invalid']!='all'){
$cond['invalid']=$search['invalid'];
}
if(!empty($search['user'])){
$cond['user']=$search['user'];
}
if(!empty($search['pwd'])){
$cond['pwd']=$search['pwd'];
}
$count=$mproxy->where($cond)->count();
if($count>0){
$dataList=$mproxy->where($cond)->order('addtime desc,no desc')->paginate($search['num'],false,paginate_auto_config());
$pagenav=$dataList->render();
$pagenav=str_replace('class="pagination', 'class="pagination pagination-sm no-margin pull-right', $pagenav);
$this->assign('pagenav',$pagenav);
$dataList=$dataList->all();
$dataList=empty($dataList)?array():$dataList;
foreach ($dataList as $k=>$v){
$v=$v->toArray();
foreach ($v as $vk=>$vv){
$v[$vk]=htmlspecialchars($vv,ENT_QUOTES);
}
$dataList[$k]=$v;
}
$this->assign('dataList',$dataList);
}
$urlParams=input('param.');
$urlParams=http_build_query($urlParams);
$this->assign('proxyTypes',$mproxy->proxy_types());
$this->assign('search',$search);
$this->assign('urlParams',$urlParams);
return $this->fetch();
}
public function opAction(){
$op=input('op');
$listUrl=input('url_params','','trim');
$listUrl='Proxy/list?'.ltrim($listUrl,'?');
$mproxy=model('Proxyip');
if($op=='delete'){
$ip=input('ip');
$mproxy->where('ip',$ip)->delete();
$this->success('删除成功',$listUrl);
}elseif($op=='delete_all'){
$ips=input('ips','','trim');
$ips=empty($ips)?array():json_decode($ips,true);
$ips=array_map('trim', $ips);
if(!empty($ips)){
$mproxy->where('ip','in',$ips)->delete();
}
$this->success('删除成功',$listUrl);
}elseif($op=='update_all'){
$ips=input('ips','','trim');
$ip_list=input('ip_list','','trim');
$user_list=input('user_list','','trim');
$pwd_list=input('pwd_list','','trim');
$type_list=input('type_list','','trim');
$ips=empty($ips)?array():json_decode($ips,true);
$ip_list=empty($ip_list)?array():json_decode($ip_list,true);
$user_list=empty($user_list)?array():json_decode($user_list,true);
$pwd_list=empty($pwd_list)?array():json_decode($pwd_list,true);
$type_list=empty($type_list)?array():json_decode($type_list,true);
$ips=array_map('trim', $ips);
$ip_list=array_map('trim', $ip_list);
$user_list=array_map('trim', $user_list);
$pwd_list=array_map('trim', $pwd_list);
$type_list=array_map('trim', $type_list);
for($i=0;$i<count($ips);$i++){
$mproxy->strict(false)->where('ip',$ips[$i])->update(array(
'ip'=>$ip_list[$i],
'user'=>$user_list[$i],
'pwd'=>$pwd_list[$i],
'type'=>$type_list[$i],
));
}
$this->success('修改成功',$listUrl);
}
}
public function addAction(){
$mproxy=model('Proxyip');
$proxyTypes=$mproxy->proxy_types();
if(request()->isPost()){
$ip_list=input('ip_list/a','','trim');
$user_list=input('user_list/a','','trim');
$pwd_list=input('pwd_list/a','','trim');
$type_list=input('type_list/a','','trim');
if(!empty($ip_list)){
foreach($ip_list as $k=>$v){
$newData=array(
'ip'=>$v,
'user'=>$user_list[$k],
'pwd'=>$pwd_list[$k],
'type'=>$type_list[$k],
'addtime'=>NOW_TIME
);
$mproxy->db()->strict(false)->insert($newData,true);
}
$this->success('添加成功');
}else{
$this->error('请添加ip');
}
}else{
$this->assign('proxyTypes',$proxyTypes);
return $this->fetch();
}
}
/*批量添加代理*/
public function batchAction(){
$mproxy=model('Proxyip');
$proxyTypes=$mproxy->proxy_types();
if(request()->isPost()){
$type=input('type');
$ips=input('ips','',null);
$fmt=input('format','','trim');
$user=input('user','','trim');
$pwd=input('pwd','','trim');
$ipList=array();
if(!empty($fmt)&&preg_match_all('/[^\r\n]+/',$ips,$mips)){
foreach ($mips[0] as $ip){
$ip=model('Proxyip')->get_format_ips($ip,$fmt,false);
if(empty($ip)){
continue;
}
$ipList[]=$ip;
}
}
$ipList=$mproxy->ips_format2db($ipList,array(
'type'=>$type,
'user'=>$user,
'pwd'=>$pwd
));
if(empty($ipList)){
$this->error('没有匹配到数据');
}
if(input('is_test')){
$ips='';
$proxyTypes=array_flip($proxyTypes);
foreach($ipList as $ip){
$ips.=$ip['ip'].' - '.$proxyTypes[$ip['type']].($ip['user']?(' - '.$ip['user'].':'.$ip['pwd']):'').PHP_EOL;
}
$this->success($ips);
}else{
$mproxy->strict(false)->insertAll($ipList,true,500);
$this->success('批量添加成功');
}
}else{
$this->assign('proxyTypes',$proxyTypes);
return $this->fetch();
}
}
public function clearInvalidAction(){
$mproxy=model('Proxyip');
$mproxy->where('invalid',1)->delete();
$this->success('清理完成','Setting/proxy');
}
public function testApiAction(){
$config=input('config/a','','trim');
$mproxy=model('Proxyip');
$html=get_html($config['api_url']);
$ips=$mproxy->get_format_ips($html,$config['api_format'],true);
$ips=$mproxy->ips_format2db ( $ips, array (
'type' => $config ['api_type'],
'user' => $config ['api_user'],
'pwd' => $config ['api_pwd'],
) );
$types=$mproxy->proxy_types();
$types=array_flip($types);
$ipsStr='';
foreach ($ips as $ip){
if(empty($ip)){
continue;
}
$ipsStr.=$ip['ip'].' - '.$types[$ip['type']].($ip['user']?(' - '.$ip['user'].':'.$ip['pwd']):'').PHP_EOL;
}
$ips=$ipsStr;
unset($ipsStr);
$this->assign('ips',$ips);
return $this->fetch('testApi');
}
}

View File

@ -60,8 +60,8 @@ class Release extends BaseController{
$this->error(lang('op_failed'));
}
}else{
$GLOBALS['content_header']=lang('rele_set');
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('Task/edit?id='.$taskData['id']),'title'=>lang('task').lang('separator').$taskData['name']),lang('rele_set')));
$GLOBALS['_sc']['p_name']=lang('rele_set');
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Task/edit?id='.$taskData['id']),'title'=>lang('task').lang('separator').$taskData['name']),array('url'=>url('Release/set?task_id='.$taskData['id']),'title'=>lang('rele_set'))));
$this->assign('taskData',$taskData);
if(!empty($releData)){

View File

@ -11,6 +11,7 @@
namespace skycaiji\admin\controller;
use skycaiji\admin\model\CacheModel;
class Setting extends BaseController {
/*站点设置*/
public function siteAction(){
@ -35,8 +36,8 @@ class Setting extends BaseController {
$mconfig->setConfig('site',$config);
$this->success(lang('op_success'),'Setting/site');
}else{
$GLOBALS['content_header']=lang('setting_site');
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('Setting/site'),'title'=>lang('setting_site'))));
$GLOBALS['_sc']['p_name']=lang('setting_site');
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Setting/site'),'title'=>lang('setting_site'))));
$siteConfig=$mconfig->getConfig('site','data');
$this->assign('siteConfig',$siteConfig);
}
@ -46,15 +47,68 @@ class Setting extends BaseController {
public function caijiAction(){
$mconfig=model('Config');
if(request()->isPost()){
if($mconfig->where('cname','download_img')->count()<=0){
$caijiConfig=$mconfig->getConfig('caiji','data');
$imgConfig=$mconfig->get_img_config_from_caiji($caijiConfig);
if(!empty($imgConfig)){
$mconfig->setConfig('download_img',$imgConfig);
}
}
$config=array();
$config['robots']=input('robots/d',0);
$config['auto']=input('auto/d',0);
$config['run']=input('run');
$config['server']=input('server');
$config['server_php']=input('server_php');
$config['num']=input('num/d',0);
$config['interval']=input('interval/d',0);
$config['timeout']=input('timeout/d',0);
$config['html_interval']=input('html_interval/d',0);
$config['real_time']=input('real_time/d',0);
unset($config['download_img']);
if($config['server']=='cli'){
if(!function_exists('proc_open')){
$this->error('抱歉cli命令行模式需开启proc_open函数');
}
}
$mconfig->setConfig('caiji',$config);
if($config['auto']){
remove_auto_collecting();
if($config['run']=='backstage'){
$runkey=md5(time().rand(1, 1000000));
CacheModel::getInstance()->setCache('admin_index_backstage_key', $runkey);
@get_html(url('Admin/Index/backstage?key='.$runkey,null,false,true),null,array('timeout'=>3));
}
}
$this->success(lang('op_success'),'Setting/caiji');
}else{
$GLOBALS['_sc']['p_name']=lang('setting_caiji');
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Setting/caiji'),'title'=>lang('setting_caiji'))));
$caijiConfig=$mconfig->getConfig('caiji','data');
$caijiConfig=is_array($caijiConfig)?$caijiConfig:array();
$phpExeFile=$mconfig->detect_php_exe();
$this->assign('caijiConfig',$caijiConfig);
$this->assign('phpExeFile',$phpExeFile);
}
return $this->fetch();
}
/*图片本地化设置*/
public function download_imgAction(){
$mconfig=model('Config');
if(request()->isPost()){
$config=array();
$config['download_img']=input('download_img/d',0);
$config['img_path']=trim(input('img_path',''));
$config['img_url']=input('img_url','','trim');
@ -62,45 +116,54 @@ class Setting extends BaseController {
$config['img_timeout']=input('img_timeout/d',0);
$config['img_interval']=input('img_interval/d',0);
$config['img_max']=input('img_max/d',0);
if($config['server']=='cli'){
if(!function_exists('proc_open')){
$this->error('抱歉cli命令行模式需开启proc_open函数');
}
}
if(!empty($config['img_path'])){
$checkImgPath=$mconfig->check_img_path($config['img_path']);
if(!$checkImgPath['success']){
$this->error($checkImgPath['msg']);
}
}
if(!empty($config['img_url'])){
$checkImgUrl=$mconfig->check_img_url($config['img_url']);
if(!$checkImgUrl['success']){
$this->error($checkImgUrl['msg']);
}
}
$mconfig->setConfig('caiji',$config);
if($config['auto']){
remove_auto_collecting();
if($config['run']=='backstage'){
@get_html(url('Admin/Index/backstage?autorun=1',null,false,true),null,array('timeout'=>3));
}
$config['name_custom_path']=input('name_custom_path','');
$config['name_custom_name']=input('name_custom_name','');
if(!empty($config['img_path'])){
$checkImgPath=$mconfig->check_img_path($config['img_path']);
if(!$checkImgPath['success']){
$this->error($checkImgPath['msg']);
}
}
$this->success(lang('op_success'),'Setting/caiji');
if(!empty($config['img_url'])){
$checkImgUrl=$mconfig->check_img_url($config['img_url']);
if(!$checkImgUrl['success']){
$this->error($checkImgUrl['msg']);
}
}
$checkNamePath=$mconfig->check_img_name_path($config['name_custom_path']);
if($config['img_name']=='custom'){
if(empty($config['name_custom_path'])){
$this->error('请输入图片名称自定义目录');
}
if(!$checkNamePath['success']){
$this->error($checkNamePath['msg']);
}
}else{
if(!$checkNamePath['success']){
$config['name_custom_path']='';
}
}
$mconfig->setConfig('download_img',$config);
$this->success(lang('op_success'),'Setting/download_img');
}else{
$GLOBALS['content_header']=lang('setting_caiji');
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('Setting/caiji'),'title'=>lang('setting_caiji'))));
$caijiConfig=$mconfig->getConfig('caiji','data');
$this->assign('caijiConfig',$caijiConfig);
$GLOBALS['_sc']['p_name']='图片本地化设置';
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Setting/caiji'),'title'=>lang('setting_caiji')),array('url'=>url('Setting/download_img'),'title'=>'图片本地化')));
$imgConfig=$mconfig->getConfig('download_img','data');
if(empty($imgConfig)){
$caijiConfig=$mconfig->getConfig('caiji','data');
$imgConfig=$mconfig->get_img_config_from_caiji($caijiConfig);
}
$this->assign('imgConfig',$imgConfig);
return $this->fetch('download_img');
}
return $this->fetch();
}
/*代理设置*/
public function proxyAction(){
@ -111,10 +174,12 @@ class Setting extends BaseController {
$ip_list=input('ip_list','','trim');
$user_list=input('user_list','','trim');
$pwd_list=input('pwd_list','','trim');
$type_list=input('type_list','','trim');
$ip_list=empty($ip_list)?null:json_decode($ip_list,true);
$user_list=empty($user_list)?null:json_decode($user_list,true);
$pwd_list=empty($pwd_list)?null:json_decode($pwd_list,true);
$ip_list=empty($ip_list)?array():json_decode($ip_list,true);
$user_list=empty($user_list)?array():json_decode($user_list,true);
$pwd_list=empty($pwd_list)?array():json_decode($pwd_list,true);
$type_list=empty($type_list)?array():json_decode($type_list,true);
$config['open']=input('open/d',0);
$config['failed']=input('failed/d',0);
@ -132,13 +197,14 @@ class Setting extends BaseController {
if(!empty($ip_list)&&is_array($ip_list)){
$mproxy->where(array('ip'=>array('not in',$ip_list)))->delete();
$ip_list=array_map('trim', $ip_list);
$user_list=array_map('trim', $user_list);
$pwd_list=array_map('trim', $pwd_list);
$type_list=array_map('trim', $type_list);
foreach ($ip_list as $k=>$v){
for($k=count($ip_list);$k>=0;$k--){
$v=$ip_list[$k];
if(empty($v)){
continue;
@ -147,10 +213,12 @@ class Setting extends BaseController {
'ip'=>$v,
'user'=>$user_list[$k],
'pwd'=>$pwd_list[$k],
'type'=>$type_list[$k],
'invalid'=>0,
'failed'=>0,
'num'=>0,
'time'=>0,
'addtime'=>NOW_TIME,
);
if($mproxy->where(array('ip'=>$newData['ip']))->count()>0){
@ -162,60 +230,44 @@ class Setting extends BaseController {
$mproxy->db()->insert($newData,true);
}
}
}else{
$mproxy->where('1=1')->delete();
}
$config['api']=input('api/a','','trim');
$config['apis']=input('apis/a','','trim');
$config['apis']=is_array($config['apis'])?$config['apis']:array();
foreach ($config['apis'] as $k=>$v){
if(empty($v['api_url'])||!preg_match('/^\w+\:\/\//',$v['api_url'])){
unset($config['apis'][$k]);
}
}
$config['apis']=array_values($config['apis']);
$mconfig->setConfig('proxy',$config);
$this->success(lang('op_success'),'Setting/Proxy');
}else{
$GLOBALS['content_header']='代理设置';
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('Setting/Proxy'),'title'=>'代理设置')));
$GLOBALS['_sc']['p_name']='代理设置';
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Setting/caiji'),'title'=>lang('setting_caiji')),array('url'=>url('Setting/Proxy'),'title'=>'代理')));
$proxyConfig=$mconfig->getConfig('proxy','data');
$proxyConfig['ip_list']=$mproxy->column('*');
$proxyConfig['ip_count']=$mproxy->count();
$this->assign('proxyConfig',$proxyConfig);
$this->assign('proxyTypes',$mproxy->proxy_types());
}
return $this->fetch();
}
/*批量添加代理*/
public function proxyBatchAction(){
if(request()->isPost()){
$ips=input('ips');
$fmt=input('format');
$fmt=str_replace(array('[ip]','[端口]','[用户名]','[密码]')
,array('(?P<ip>(\d+\.)+\d+)','(?P<port>\d+)','(?P<user>[^\s]+)','(?P<pwd>[^\s]+)')
,$fmt);
$ipList=array();
if(preg_match_all('/[^\r\n]+/',$ips,$m_ips)){
foreach ($m_ips[0] as $ip){
if(preg_match('/'.$fmt.'/',$ip,$ipInfo)){
$ipList[]=array(
'ip'=>$ipInfo['ip'].':'.$ipInfo['port'],
'user'=>$ipInfo['user'],
'pwd'=>$ipInfo['pwd'],
);
}
}
}
if(empty($ipList)){
$this->error('没有匹配到数据');
}else{
$this->success('',null,$ipList);
}
}else{
return $this->fetch('proxyBatch');
}
}
/*翻译设置*/
public function translateAction(){
$mconfig=model('Config');
$apiTypes=array('baidu','youdao','qq');
if(request()->isPost()){
$config=array();
$config['open']=input('open/d',0);
$config['api']=input('api','','strtolower');
$config['baidu']=input('baidu/a',null,'trim');
$config['youdao']=input('youdao/a',null,'trim');
foreach ($apiTypes as $v){
$config[$v]=input($v.'/a',null,'trim');
}
if(!empty($config['api'])){
if(empty($config[$config['api']])){
@ -231,18 +283,21 @@ class Setting extends BaseController {
$mconfig->setConfig('translate',$config);
$this->success(lang('op_success'),'Setting/translate');
}else{
$GLOBALS['content_header']='翻译设置';
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('Setting/translate'),'title'=>'翻译设置')));
$GLOBALS['_sc']['p_name']='翻译设置';
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Setting/caiji'),'title'=>lang('setting_caiji')),array('url'=>url('Setting/translate'),'title'=>'翻译')));
$transConfig=$mconfig->getConfig('translate','data');
foreach ($transConfig['baidu'] as $k=>$v){
$transConfig['baidu'][$k]=htmlspecialchars($v,ENT_QUOTES);
}
foreach ($transConfig['youdao'] as $k=>$v){
$transConfig['youdao'][$k]=htmlspecialchars($v,ENT_QUOTES);
$apiLangs=array();
foreach ($apiTypes as $api){
$transConfig[$api]=is_array($transConfig[$api])?$transConfig[$api]:array();
foreach ($transConfig[$api] as $k=>$v){
$transConfig[$api][$k]=htmlspecialchars($v,ENT_QUOTES);
}
$apiLangs[$api]=\util\Translator::get_api_langs($api);
$apiLangs[$api]=is_array($apiLangs[$api])?implode(', ',$apiLangs[$api]):'';
}
$this->assign('transConfig',$transConfig);
$this->assign('apiLangs',$apiLangs);
return $this->fetch();
}
}
@ -272,8 +327,8 @@ class Setting extends BaseController {
$this->success(lang('op_success'),'Setting/email');
}
}else{
$GLOBALS['content_header']=lang('setting_email');
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('Setting/email'),'title'=>lang('setting_email'))));
$GLOBALS['_sc']['p_name']=lang('setting_email');
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Setting/email'),'title'=>lang('setting_email'))));
$emailConfig=$mconfig->getConfig('email','data');
$this->assign('emailConfig',$emailConfig);
}
@ -317,8 +372,8 @@ class Setting extends BaseController {
}
$this->success(lang('op_success'),'Setting/page_render');
}else{
$GLOBALS['content_header']='页面渲染设置 <small><a href="https://www.skycaiji.com/manual/doc/page_render" target="_blank"><span class="glyphicon glyphicon-info-sign"></span></a></small>';
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('Setting/page_render'),'title'=>'页面渲染设置')));
$GLOBALS['_sc']['p_name']='页面渲染设置 <small><a href="https://www.skycaiji.com/manual/doc/page_render" target="_blank"><span class="glyphicon glyphicon-info-sign"></span></a></small>';
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Setting/caiji'),'title'=>lang('setting_caiji')),array('url'=>url('Setting/page_render'),'title'=>'页面渲染')));
$config=$mconfig->getConfig('page_render','data');
$this->assign('config',$config);
@ -329,7 +384,7 @@ class Setting extends BaseController {
$toolIsOpen=$chromeSoket->hostIsOpen();
$this->assign('toolIsOpen',$toolIsOpen);
}
return $this->fetch();
return $this->fetch('page_render');
}
}
/*清理缓存目录*/

View File

@ -14,7 +14,7 @@ namespace skycaiji\admin\controller;
class Store extends BaseController {
public function isLoginAction(){
if(empty($GLOBALS['user'])){
if(empty($GLOBALS['_sc']['user'])){
$this->dispatchJump(false,lang('user_error_is_not_admin'),url('Admin/Index/index',null,null,true));
}else{
$this->dispatchJump(true);
@ -34,7 +34,7 @@ class Store extends BaseController {
$url=$provData['url'];
$url.=strpos($url, '?')===false?'?':'&';
$url.='clientinfo='.urlencode($GLOBALS['clientinfo']);
$url.='clientinfo='.urlencode($GLOBALS['_sc']['clientinfo']);
$this->assign('provData',$provData);
}
@ -46,8 +46,8 @@ class Store extends BaseController {
}
$GLOBALS['content_header']=lang('store');
$GLOBALS['breadcrumb']=breadcrumb(array(lang('store')));
$GLOBALS['_sc']['p_name']=lang('store');
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Store/index'),'title'=>lang('store'))));
$this->assign('url',$url);
return $this->fetch();
@ -124,8 +124,14 @@ class Store extends BaseController {
$newData['provider_id']=$this->_getStoreProvid($plugin['store_url']);
if($plugin['type']=='release'){
model('ReleaseApp')->addCms($newData,$plugin['code'],$plugin['tpl']);
$this->dispatchJump(true);
}elseif($plugin['type']=='func'){
$newData['module']=$plugin['module'];
model('FuncApp')->addFunc($newData,$plugin['code']);
$this->dispatchJump(true);
}else{
$this->dispatchJump(false);
}
@ -245,6 +251,8 @@ class Store extends BaseController {
$cond=array('app'=>array('in',$apps),'provider_id'=>$provId);
if($type=='release'||$type=='cms'){
$list=model('ReleaseApp')->where($cond)->column('uptime','app');
}elseif($type=='func'){
$list=model('FuncApp')->where($cond)->column('uptime','app');
}elseif($type=='app'){
foreach ($apps as $app){

View File

@ -121,8 +121,8 @@ class Task extends BaseController {
$this->assign('pagenav',$pagenav);
}
$showChange=$show=='list'?'folder':'list';
$GLOBALS['content_header']=lang('task_list').' <small><a href="'.url('Task/list?show='.$showChange).'">'.lang('task_change_'.$showChange).'</a></small>';
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('Task/list'),'title'=>lang('task_list'))));
$GLOBALS['_sc']['p_name']=lang('task_list').' <small><a href="'.url('Task/list?show='.$showChange).'">'.lang('task_change_'.$showChange).'</a></small>';
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Task/list'),'title'=>lang('task_list'))));
return $this->fetch('list_'.$show);
}
/*任务列表,打开文件夹*/
@ -221,8 +221,8 @@ class Task extends BaseController {
$mtaskgroup=model('Taskgroup');
$tgSelect=$mtaskgroup->getLevelSelect();
$GLOBALS['content_header']=lang('task_add');
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('Task/list'),'title'=>lang('task_list')),lang('task_add')));
$GLOBALS['_sc']['p_name']=lang('task_add');
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Task/list'),'title'=>lang('task_list')),array('url'=>url('Task/add'),'title'=>lang('task_add'))));
$this->assign('tgSelect',$tgSelect);
@ -287,8 +287,8 @@ class Task extends BaseController {
$mtaskgroup=model('Taskgroup');
$tgSelect=$mtaskgroup->getLevelSelect();
$GLOBALS['content_header']=lang('task_edit');
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('Task/list'),'title'=>lang('task_list')),lang('task_edit')));
$GLOBALS['_sc']['p_name']=lang('task_edit').''.$taskData['name'];
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Task/list'),'title'=>lang('task_list')),array('url'=>url('Task/edit?id='.$taskData['id']),'title'=>$taskData['name'])));
$this->assign('tgSelect',$tgSelect);
$this->assign('taskData',$taskData);
@ -431,7 +431,7 @@ class Task extends BaseController {
if(!IS_CLI){
ignore_user_abort(true);
if($GLOBALS['config']['caiji']['server']=='cli'){
if($GLOBALS['_sc']['c']['caiji']['server']=='cli'){
cli_command_exec('collect task --task_id '.$taskId);
exit();
@ -460,7 +460,7 @@ class Task extends BaseController {
if(!IS_CLI){
ignore_user_abort(true);
if($GLOBALS['config']['caiji']['server']=='cli'){
if($GLOBALS['_sc']['c']['caiji']['server']=='cli'){
cli_command_exec('collect batch --task_ids '.implode(',',$taskIds));
exit();
@ -472,8 +472,8 @@ class Task extends BaseController {
ignore_user_abort(false);
}
if($GLOBALS['config']['caiji']['timeout']>0){
set_time_limit(60*$GLOBALS['config']['caiji']['timeout']);
if($GLOBALS['_sc']['c']['caiji']['timeout']>0){
set_time_limit(60*$GLOBALS['_sc']['c']['caiji']['timeout']);
}else{
set_time_limit(0);
}
@ -498,30 +498,30 @@ class Task extends BaseController {
}
/*将任务标记为后台运行*/
public function _backstage_task($taskId){
$GLOBALS['backstage_task_runtime']=time();
$GLOBALS['_sc']['backstage_task_runtime']=time();
if(model('Task')->where('id',$taskId)->count()>0){
$mcache=CacheModel::getInstance('backstage_task');
$mcache->db()->strict(false)->insert(array(
'cname'=>$taskId,
'dateline'=>$GLOBALS['backstage_task_runtime'],
'dateline'=>$GLOBALS['_sc']['backstage_task_runtime'],
'ctype'=>0,
'data'=>''
),true);
if(!isset($GLOBALS['backstage_task_ids'])){
$GLOBALS['backstage_task_ids']=array();
if(!isset($GLOBALS['_sc']['backstage_task_ids'])){
$GLOBALS['_sc']['backstage_task_ids']=array();
}
$GLOBALS['backstage_task_ids'][$taskId]=$taskId;
$GLOBALS['_sc']['backstage_task_ids'][$taskId]=$taskId;
static $registered=false;
if(!$registered){
register_shutdown_function(function(){
if(!empty($GLOBALS['backstage_task_ids'])&&is_array($GLOBALS['backstage_task_ids'])){
if(!empty($GLOBALS['_sc']['backstage_task_ids'])&&is_array($GLOBALS['_sc']['backstage_task_ids'])){
$mcache=\skycaiji\admin\model\CacheModel::getInstance('backstage_task');
$mcache->db()->strict(false)->where('cname','in',$GLOBALS['backstage_task_ids'])->update(array('ctype'=>1,'data'=>time()));
$mcache->db()->strict(false)->where('cname','in',$GLOBALS['_sc']['backstage_task_ids'])->update(array('ctype'=>1,'data'=>time()));
}
});
$registered=true;
@ -532,8 +532,8 @@ class Task extends BaseController {
public function _collect($taskId){
static $setted_timeout=null;
if(!isset($setted_timeout)){
if($GLOBALS['config']['caiji']['timeout']>0){
set_time_limit(60*$GLOBALS['config']['caiji']['timeout']);
if($GLOBALS['_sc']['c']['caiji']['timeout']>0){
set_time_limit(60*$GLOBALS['_sc']['c']['caiji']['timeout']);
}else{
set_time_limit(0);
}
@ -579,11 +579,11 @@ class Task extends BaseController {
$acoll->init($collData);
$arele=controller('admin/R'.strtolower($releData['module']),'event');
$arele->init($releData);
$GLOBALS['real_time_release']=&$arele;
$GLOBALS['_sc']['real_time_release']=&$arele;
if('api'==$releData['module']){
$GLOBALS['config']['caiji']['real_time']=0;
$GLOBALS['_sc']['c']['caiji']['real_time']=0;
$cacheApiData=$arele->get_cache_fields();
@ -598,7 +598,7 @@ class Task extends BaseController {
$all_field_list=array();
$caijiNum=intval($GLOBALS['config']['caiji']['num']);
$caijiNum=intval($GLOBALS['_sc']['c']['caiji']['num']);
$taskNum=intval($taskData['config']['num']);
if($taskNum<=0||($caijiNum>0&&$taskNum>$caijiNum)){
@ -620,10 +620,10 @@ class Task extends BaseController {
}elseif(is_array($field_list)&&!empty($field_list)){
$all_field_list=array_merge($all_field_list,$field_list);
$taskNum-=count($field_list);
$taskNum-=count((array)$field_list);
}
if($taskNum>0){
$this->echo_msg('采集到'.count($field_list).'条数据,还差'.$taskNum.'条','orange');
$this->echo_msg('采集到'.count((array)$field_list).'条数据,还差'.$taskNum.'条','orange');
}
}
}else{
@ -640,8 +640,8 @@ class Task extends BaseController {
if(empty($all_field_list)){
$this->echo_msg('没有采集到数据','orange');
}else{
$this->echo_msg('采集到'.count($all_field_list).'条数据','green');
if(empty($GLOBALS['config']['caiji']['real_time'])){
$this->echo_msg('采集到'.count((array)$all_field_list).'条数据','green');
if(empty($GLOBALS['_sc']['c']['caiji']['real_time'])){
$addedNum=$arele->export($all_field_list);
$this->echo_msg('成功发布'.$addedNum.'条数据','green');
@ -653,7 +653,7 @@ class Task extends BaseController {
$mtask=model('Task');
$mcoll=model('Collector');
$mrele=model('Release');
$caijiNum=intval($GLOBALS['config']['caiji']['num']);
$caijiNum=intval($GLOBALS['_sc']['c']['caiji']['num']);
$caijiLimit=false;
if($caijiNum>0){
$caijiLimit=true;
@ -690,7 +690,7 @@ class Task extends BaseController {
$arele='\\skycaiji\\admin\\event\\R'.strtolower($releData['module']);
$arele=new $arele();
$arele->init($releData);
$GLOBALS['real_time_release']=&$arele;
$GLOBALS['_sc']['real_time_release']=&$arele;
$this->echo_msg('<div style="background:#efefef;padding:5px;margin:5px 0;text-align:center;">正在执行任务:'.$taskData['name'].'</div>','black');
$all_field_list=array();
@ -711,8 +711,8 @@ class Task extends BaseController {
}elseif(is_array($field_list)&&!empty($field_list)){
$all_field_list=array_merge($all_field_list,$field_list);
$taskNum-=count($field_list);
$caijiNum-=count($field_list);
$taskNum-=count((array)$field_list);
$caijiNum-=count((array)$field_list);
}
}
}else{
@ -728,9 +728,9 @@ class Task extends BaseController {
if(empty($all_field_list)){
$this->echo_msg('任务:'.$taskData['name'].' 没有采集到数据','orange');
}else{
$this->echo_msg('任务:'.$taskData['name'].' 采集到'.count($all_field_list).'条数据','green');
$this->echo_msg('任务:'.$taskData['name'].' 采集到'.count((array)$all_field_list).'条数据','green');
if(empty($GLOBALS['config']['caiji']['real_time'])){
if(empty($GLOBALS['_sc']['c']['caiji']['real_time'])){
$addedNum=$arele->export($all_field_list);
$this->echo_msg('成功发布'.$addedNum.'条数据','green');

View File

@ -74,8 +74,8 @@ class Taskgroup extends BaseController {
$parentTgList=$mtaskgroup->where(array('parent_id'=>0))->order('sort desc')->column('name','id');
$this->assign('parentTgList',$parentTgList);
$GLOBALS['content_header']=lang('taskgroup_list');
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('Taskgroup/list'),'title'=>lang('taskgroup_list'))));
$GLOBALS['_sc']['p_name']=lang('taskgroup_list');
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Taskgroup/list'),'title'=>lang('taskgroup_list'))));
return $this->fetch();
}
/**
@ -102,8 +102,8 @@ class Taskgroup extends BaseController {
$parentTgList=$mtaskgroup->where(array('parent_id'=>0))->order('sort desc')->column('name','id');
$this->assign('parentTgList',$parentTgList);
$GLOBALS['content_header']=lang('taskgroup_add');
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('Taskgroup/list'),'title'=>lang('taskgroup_list')),lang('taskgroup_add')));
$GLOBALS['_sc']['p_name']=lang('taskgroup_add');
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Taskgroup/list'),'title'=>lang('taskgroup_list')),array('url'=>url('Taskgroup/add'),'title'=>lang('taskgroup_add'))));
if(request()->isAjax()){
return view('add_ajax');
@ -160,8 +160,8 @@ class Taskgroup extends BaseController {
$this->assign('parentTgList',$parentTgList);
$this->assign('tgData',$tgData);
$GLOBALS['content_header']=lang('taskgroup_edit');
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('Taskgroup/list'),'title'=>lang('taskgroup_list')),lang('taskgroup_edit')));
$GLOBALS['_sc']['p_name']=lang('taskgroup_edit').''.$tgData['name'];
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Taskgroup/list'),'title'=>lang('taskgroup_list')),array('url'=>url('Taskgroup/edit?id='.$tgData['id']),'title'=>$tgData['name'])));
if(request()->isAjax()){
return view('add_ajax');

View File

@ -14,8 +14,8 @@ use skycaiji\admin\model\DbCommon;
class Tool extends BaseController {
/*文件管理*/
public function fileManagerAction(){
$GLOBALS['content_header']='文件管理';
$GLOBALS['breadcrumb']=breadcrumb(array('文件管理'));
$GLOBALS['_sc']['p_name']='文件管理';
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Tool/fileManager'),'title'=>'文件管理')));
return $this->fetch('fileManager');
}
/*elfinder文件管理器*/
@ -86,8 +86,8 @@ class Tool extends BaseController {
}
}
}
$GLOBALS['content_header']='错误日志';
$GLOBALS['breadcrumb']=breadcrumb(array('错误日志'));
$GLOBALS['_sc']['p_name']='错误日志';
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Tool/logs'),'title'=>'错误日志')));
$this->assign('logList',$logList);
return $this->fetch();
}
@ -156,8 +156,8 @@ class Tool extends BaseController {
$this->error('',null,array('files'=>$error_files));
}
}else{
$GLOBALS['content_header']='校验文件';
$GLOBALS['breadcrumb']=breadcrumb(array('校验文件'));
$GLOBALS['_sc']['p_name']='校验文件';
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Tool/checkfile'),'title'=>'校验文件')));
return $this->fetch();
}
}
@ -207,7 +207,7 @@ class Tool extends BaseController {
$this->error('没有获取到表');
}
if(!version_compare($check_db['version'],$GLOBALS['config']['version'],'=')){
if(!version_compare($check_db['version'],$GLOBALS['_sc']['c']['version'],'=')){
$this->error('校验文件版本与数据库版本不一致');
}
@ -417,8 +417,8 @@ class Tool extends BaseController {
}
}
}else{
$GLOBALS['content_header']='校验数据库';
$GLOBALS['breadcrumb']=breadcrumb(array('校验数据库'));
$GLOBALS['_sc']['p_name']='校验数据库';
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Tool/checkdb'),'title'=>'校验数据库')));
return $this->fetch();
}
}
@ -433,18 +433,14 @@ class Tool extends BaseController {
$html=get_html($url);
}
if(!empty($html)){
if(preg_match($eCpattern::$jsonpRegExp,$html,$json)){
$json=trim($json['json']).'}';
}
$json=convert_html2json($html,true);
}
$this->success('','',array('json'=>$json));
}else{
$GLOBALS['content_header']='JSON解析';
$GLOBALS['breadcrumb']=breadcrumb(array('JSON解析'));
return $this->fetch();
$GLOBALS['_sc']['p_name']='JSON解析';
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('Tool/json_tree'),'title'=>'JSON解析')));
return $this->fetch('json_tree');
}
}
}

View File

@ -17,21 +17,29 @@ class Upgrade extends BaseController{
public function __construct(){
parent::__construct();
set_time_limit(3600);
$this->oldFilePath=config('root_path').'/data/program/backup/skycaiji'.$GLOBALS['config']['version'];
$this->newFilePath=config('root_path').'/data/program/upgrade/skycaiji'.$GLOBALS['config']['version'];
$this->oldFilePath=config('root_path').'/data/program/backup/skycaiji'.$GLOBALS['_sc']['c']['version'];
$this->newFilePath=config('root_path').'/data/program/upgrade/skycaiji'.$GLOBALS['_sc']['c']['version'];
}
/*检测更新*/
public function newVersionAction(){
$version=get_html('https://www.skycaiji.com/upgrade/program/version?v='.SKYCAIJI_VERSION,null,null,'utf-8');
$version=json_decode($version,true);
$version=is_array($version)?$version:array();
$new_version=trim($version['new_version']);
$cur_version=$GLOBALS['config']['version'];
$cur_version=$GLOBALS['_sc']['c']['version'];
if(version_compare($new_version,$cur_version)>=1){
$this->success('',null,$version);
}else{
$this->error();
if(version_compare($new_version,$cur_version,'>')){
$version['is_new_version']=true;
}
$cacheIx=cache('backstage_admin_index');
if(empty($cacheIx)||$cacheIx['ver']!=$version['admin_index_ver']){
$version['is_new_admin_index']=true;
}
$this->success('',null,$version);
}
/*
* 下载的文件完整性检测
@ -89,10 +97,11 @@ class Upgrade extends BaseController{
}
}
$fileUrl='https://www.skycaiji.com/upgrade/program/getFile?filename='.rawurlencode(base64_encode($fileName));
$result=\Requests::get($fileUrl,array(),array('timeout'=>100,'verify'=>false));
if(200==$result->status_code){
$curl=\util\Curl::get($fileUrl,null,array('timeout'=>100));
if($curl->isOk){
$newFile=$result->body;
$newFile=$curl->body;
$oldFile=file_get_contents(config('root_path').$fileName);
if(!empty($oldFile)){

View File

@ -24,8 +24,8 @@ class User extends BaseController {
$this->assign('pagenav',$pagenav);
$userList=$userList->all();
$GLOBALS['content_header']=lang('user_list');
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('User/list'),'title'=>lang('user_list'))));
$GLOBALS['_sc']['p_name']=lang('user_list');
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('User/list'),'title'=>lang('user_list'))));
$groupList=model('Usergroup')->column('*','id');
$this->assign('userList',$userList);
@ -38,10 +38,10 @@ class User extends BaseController {
$musergroup=model('Usergroup');
if(request()->isPost()){
if(!check_usertoken()){
$this->error(lang('usertoken_error'));
$this->error(lang('usertoken_error'),'Admin/User/add');
}
if($GLOBALS['config']['site']['verifycode']){
if($GLOBALS['_sc']['c']['site']['verifycode']){
$verifycode=trim(input('verifycode'));
$check=check_verify($verifycode);
@ -65,7 +65,7 @@ class User extends BaseController {
$newData['password']=\skycaiji\admin\model\User::pwd_encrypt($newData['password'],$newData['salt']);
$newGroup=$musergroup->getById($newData['groupid']);
if($musergroup->user_level_limit($newGroup['level'])){
$this->error('您不能添加“'.$GLOBALS['user']['group']['name'].'”用户组');
$this->error('您不能添加“'.$GLOBALS['_sc']['user']['group']['name'].'”用户组');
}
$newData['regtime']=NOW_TIME;
$muser->isUpdate(false)->allowField(true)->save($newData);
@ -75,9 +75,9 @@ class User extends BaseController {
$this->error(lang('op_failed'));
}
}else{
$subGroupList=$musergroup->get_sub_level($GLOBALS['user']['groupid']);
$GLOBALS['content_header']=lang('user_add');
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('User/list'),'title'=>lang('user_list')),lang('user_add')));
$subGroupList=$musergroup->get_sub_level($GLOBALS['_sc']['user']['groupid']);
$GLOBALS['_sc']['p_name']=lang('user_add');
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('User/list'),'title'=>lang('user_list')),array('url'=>url('User/add'),'title'=>lang('user_add'))));
$this->assign('subGroupList',$subGroupList);
return $this->fetch();
}
@ -95,16 +95,16 @@ class User extends BaseController {
}
$userData['group']=$musergroup->getById($userData['groupid']);
$isOwner=($GLOBALS['user']['uid']==$userData['uid'])?true:false;
$isOwner=($GLOBALS['_sc']['user']['uid']==$userData['uid'])?true:false;
if(!$isOwner&&$musergroup->user_level_limit($userData['group']['level'])){
$this->error('您不能编辑“'.$userData['group']['name'].'”组的用户');
}
if(request()->isPost()){
if(!check_usertoken()){
$this->error(lang('usertoken_error'));
$this->error(lang('usertoken_error'),'Admin/User/edit?uid='.$userData['uid']);
}
if($GLOBALS['config']['site']['verifycode']){
if($GLOBALS['_sc']['c']['site']['verifycode']){
$verifycode=trim(input('verifycode'));
$check=check_verify($verifycode);
@ -135,7 +135,7 @@ class User extends BaseController {
}
$newGroup=$musergroup->getById($newData['groupid']);
if($musergroup->user_level_limit($newGroup['level'])){
$this->error('您不能改为“'.$GLOBALS['user']['group']['name'].'”用户组');
$this->error('您不能改为“'.$GLOBALS['_sc']['user']['group']['name'].'”用户组');
}
if($isOwner||empty($newData['groupid'])){
@ -147,11 +147,11 @@ class User extends BaseController {
}else{
$this->assign('userData',$userData);
$subGroupList=$musergroup->get_sub_level($GLOBALS['user']['groupid']);
$subGroupList=$musergroup->get_sub_level($GLOBALS['_sc']['user']['groupid']);
$this->assign('subGroupList',$subGroupList);
$this->assign('isOwner',$isOwner);
$GLOBALS['content_header']=lang('user_edit');
$GLOBALS['breadcrumb']=breadcrumb(array(array('url'=>url('User/list'),'title'=>lang('user_list')),lang('user_edit')));
$GLOBALS['_sc']['p_name']=lang('user_edit').''.$userData['username'];
$GLOBALS['_sc']['p_nav']=breadcrumb(array(array('url'=>url('User/list'),'title'=>lang('user_list')),array('url'=>url('User/edit?uid='.$userData['uid']),'title'=>$userData['username'])));
return $this->fetch();
}
}
@ -166,7 +166,7 @@ class User extends BaseController {
if(empty($userData)){
$this->error(lang('user_error_empty_user'));
}
if($userData['uid']==$GLOBALS['user']['uid']){
if($userData['uid']==$GLOBALS['_sc']['user']['uid']){
$this->error('不能删除自己');
}

View File

@ -17,7 +17,7 @@ abstract class Collector extends \skycaiji\admin\controller\BaseController {
public function error($msg = '', $url = null, $data = array(), $wait = 3, array $header = []){
if(is_collecting()){
parent::echo_msg($msg,'red');
$this->echo_msg($msg,'red');
return null;
}else{
parent::error($msg,$url,$data,$wait,$header);
@ -26,6 +26,17 @@ abstract class Collector extends \skycaiji\admin\controller\BaseController {
/*采集器的输出内容需要重写,只有正在采集时才输出内容*/
public function echo_msg($str,$color='red',$echo=true,$end_str=''){
if(is_collecting()){
static $pause_session=null;
if(!isset($pause_session)){
if(session_status()!==2){
session_start();
}
\think\Session::pause();
$pause_session=true;
}
parent::echo_msg($str,$color,$echo,$end_str);
}
}
@ -56,9 +67,9 @@ abstract class Collector extends \skycaiji\admin\controller\BaseController {
public function set_html_interval(){
if(is_collecting()){
if($GLOBALS['config']['caiji']['html_interval']>0){
if($GLOBALS['_sc']['c']['caiji']['html_interval']>0){
sleep($GLOBALS['config']['caiji']['html_interval']);
sleep($GLOBALS['_sc']['c']['caiji']['html_interval']);
return true;

View File

@ -17,20 +17,25 @@ class Cpattern extends CpatternBase{
if(!defined('IS_COLLECTING')){
define('IS_COLLECTING', 1);
}
@session_start();
\think\Session::pause();
if(!$this->show_opened_tools){
$opened_tools=array();
if($GLOBALS['_sc']['c']['caiji']['robots']){
$opened_tools[]='遵守robots协议';
}
if($this->config['page_render']){
$opened_tools[]='页面渲染';
}
if($GLOBALS['config']['caiji']['download_img']){
if($GLOBALS['_sc']['c']['download_img']['download_img']){
$opened_tools[]='图片本地化';
}
if($GLOBALS['config']['proxy']['open']){
if($GLOBALS['_sc']['c']['proxy']['open']){
$opened_tools[]='代理';
}
if($GLOBALS['_sc']['c']['translate']['open']){
$opened_tools[]='翻译';
}
if(!empty($opened_tools)){
$this->echo_msg('开启功能:'.implode('、', $opened_tools),'black');
}
@ -80,7 +85,7 @@ class Cpattern extends CpatternBase{
}
}
$source_interval=$GLOBALS['config']['caiji']['interval']*60;
$source_interval=$GLOBALS['_sc']['c']['caiji']['interval']*60;
$time_interval_list=array();
$source_urls=array();
@ -311,6 +316,37 @@ class Cpattern extends CpatternBase{
}else{
$config=$cacheConfig['config'];
}
if($config['request_headers']['open']){
$taskHeaders=array();
if(!empty($config['request_headers']['useragent'])){
$taskHeaders['useragent']=$config['request_headers']['useragent'];
}
if(!empty($config['request_headers']['cookie'])){
$taskHeaders['cookie']=$config['request_headers']['cookie'];
}
if(!empty($config['request_headers']['referer'])){
$taskHeaders['referer']=$config['request_headers']['referer'];
}
if(!empty($config['request_headers']['custom_names'])){
foreach ($config['request_headers']['custom_names'] as $k=>$v){
if(!empty($v)){
$taskHeaders[$v]=$config['request_headers']['custom_vals'][$k];
}
}
}
$GLOBALS['_sc']['task_request_headers']=array(
'request_headers'=>$config['request_headers'],
'headers'=>$taskHeaders
);
}else{
$GLOBALS['_sc']['task_request_headers']=null;
}
$this->config=$config;
}
@ -976,21 +1012,15 @@ class Cpattern extends CpatternBase{
}
}elseif(in_array($module,$fieldArr1)){
if($module=='words'){
if(empty($this->first_loop_field)){
$val=$this->$field_func($field_params);
}else{
if(empty($this->first_loop_field)){
$val=$this->$field_func($field_params);
}else{
$val=array();
foreach ($this->field_val_list[$this->first_loop_field]['values'][$cur_url_md5] as $v_k=>$v_v){
$val[$v_k]=$this->$field_func($field_params);
}
$val=array();
foreach ($this->field_val_list[$this->first_loop_field]['values'][$cur_url_md5] as $v_k=>$v_v){
$val[$v_k]=$this->$field_func($field_params);
}
}
}elseif(in_array($module,$fieldArr2)){
@ -1090,7 +1120,7 @@ class Cpattern extends CpatternBase{
$this->field_val_list[$field_name]['values'][$cur_url_md5]=$val;
}
if(!empty($GLOBALS['config']['caiji']['download_img'])&&!empty($val)){
if(!empty($GLOBALS['_sc']['c']['download_img']['download_img'])&&!empty($val)){
$valImgs=array();
if(preg_match_all('/<img[^<>]*\bsrc=[\'\"]*(\w+\:\/\/[^\'\"\s]+)[\'\"]*/i',$val,$imgUrls)){
@ -1141,7 +1171,7 @@ class Cpattern extends CpatternBase{
if(!preg_match('/^\w+\:\/\//',$page_url)){
return $this->error($page_url.'网址不完整');
}
if(empty($this->config['paging']['max'])||(count($this->used_paging_urls[$contMd5])<$this->config['paging']['max'])){
if(empty($this->config['paging']['max'])||(count((array)$this->used_paging_urls[$contMd5])<$this->config['paging']['max'])){
$this->set_html_interval();
$this->echo_msg("——采集分页:<a href='{$page_url}' target='_blank'>{$page_url}</a>",'black');
@ -1323,9 +1353,9 @@ class Cpattern extends CpatternBase{
if(empty($this->first_loop_field)){
foreach ($this->field_val_list as $fieldName=>$fieldVal){
$val_values=array_filter($fieldVal['values']);
$val_values=array_filter_keep0($fieldVal['values']);
$val_values=implode($this->config['new_paging_fields'][$fieldName]['delimiter'], $val_values);
$val_imgs=array();
if(!empty($fieldVal['imgs'])){
foreach ($fieldVal['imgs'] as $v){
@ -1518,7 +1548,7 @@ class Cpattern extends CpatternBase{
/*执行采集返回未使用的网址*/
public function _collect_unused_cont_urls($cont_urls=array(),$echo_str=''){
$mcollected=model('Collected');
$count_conts=count($cont_urls);
$count_conts=count((array)$cont_urls);
if($this->config['url_repeat']){
$db_cont_urls=array();
@ -1567,7 +1597,7 @@ class Cpattern extends CpatternBase{
$this->echo_msg('','',true,'<div style="padding-left:30px;">');
$level_data=$this->collLevelUrls($source_url,$level);
$this->echo_msg($level_str.'抓取到'.$level.'级“'.$this->config['level_urls'][$level-1]['name'].'”网址'.count($level_data['urls']).'条','black');
$this->echo_msg($level_str.'抓取到'.$level.'级“'.$this->config['level_urls'][$level-1]['name'].'”网址'.count((array)$level_data['urls']).'条','black');
$mcollected=model('Collected');
$mcacheLevel=CacheModel::getInstance('level_url');
@ -1579,7 +1609,7 @@ class Cpattern extends CpatternBase{
$level_urls["level_{$level}:{$level_url}"]=$level_url;
}
$level_interval=$GLOBALS['config']['caiji']['interval']*60;
$level_interval=$GLOBALS['_sc']['c']['caiji']['interval']*60;
$time_interval_list=array();
$cacheLevels=$mcacheLevel->db()->where(array('cname'=>array('in',array_map('md5', array_keys($level_urls)))))->column('dateline','cname');
@ -1651,7 +1681,7 @@ class Cpattern extends CpatternBase{
if(count($this->collected_field_list)>=$this->collect_num){
if($cur_level_i<count($level_data['urls'])){
if($cur_level_i<count((array)$level_data['urls'])){
$finished_source=false;
}
break;
@ -1730,9 +1760,9 @@ class Cpattern extends CpatternBase{
if(input('?backstage')){
$backstageDate=CacheModel::getInstance('backstage_task')->db()->field('dateline')->where('cname',$this->collector['task_id'])->find();
if(empty($backstageDate)||$GLOBALS['backstage_task_runtime']<$backstageDate['dateline']){
if(empty($backstageDate)||$GLOBALS['_sc']['backstage_task_runtime']<$backstageDate['dateline']){
unset($GLOBALS['backstage_task_ids'][$this->collector['task_id']]);
unset($GLOBALS['_sc']['backstage_task_ids'][$this->collector['task_id']]);
exit('终止进程');
}
}
@ -1750,7 +1780,7 @@ class Cpattern extends CpatternBase{
$is_loop=empty($this->first_loop_field)?false:true;
if(!empty($field_vals_list)){
$is_real_time=false;
if(!empty($GLOBALS['config']['caiji']['real_time'])&&!empty($GLOBALS['real_time_release'])){
if(!empty($GLOBALS['_sc']['c']['caiji']['real_time'])&&!empty($GLOBALS['_sc']['real_time_release'])){
$is_real_time=true;
}
@ -1775,7 +1805,7 @@ class Cpattern extends CpatternBase{
unset($field_vals_list[$k]);
}
}
$this->echo_msg($echo_str.'已过滤'.count($loop_exists_urls).'条重复数据','black');
$this->echo_msg($echo_str.'已过滤'.count((array)$loop_exists_urls).'条重复数据','black');
}
}
if(isset($this->exclude_cont_urls[$md5_cont_url])){
@ -1783,7 +1813,7 @@ class Cpattern extends CpatternBase{
$excludeNum=0;
foreach($this->exclude_cont_urls[$md5_cont_url] as $k=>$v){
$excludeNum+=count($v);
$excludeNum+=count((array)$v);
}
$this->echo_msg($echo_str.'通过数据处理排除了'.$excludeNum.'条数据','black');
@ -1823,7 +1853,7 @@ class Cpattern extends CpatternBase{
if($is_real_time){
$GLOBALS['real_time_release']->export(array($collected_data));
$GLOBALS['_sc']['real_time_release']->export(array($collected_data));
unset($collected_data['fields']);
unset($collected_data['title']);
@ -1889,7 +1919,7 @@ class Cpattern extends CpatternBase{
$this->used_source_urls[$cont_key]=1;
}
}
if($this->collect_num>0&&count($this->collected_field_list)>=$this->collect_num){
break;
}

View File

@ -108,6 +108,8 @@ class CpatternBase extends Collector{
$cont_urls[$k]=$v['match'];
}
}
}else{
$cont_urls=array();
}
}else{
@ -127,6 +129,8 @@ class CpatternBase extends Collector{
);
}
}
}else{
$cont_urls=array();
}
}
}
@ -462,23 +466,18 @@ class CpatternBase extends Collector{
}
return $val;
}
/**
* json提取方法可调用$field_params传入规则参数
* @param array $field_params
* @param string $html
* @return string
*/
public static $jsonpRegExp='/^(\s*[\$\w\-]+\s*[\{\(])+(?P<json>[\s\S]+)\}\s*\)\s*[\;]{0,1}/i';
public function field_module_json($field_params,$html,$cur_url=''){
static $jsonList=array();
$jsonKey=!empty($cur_url)?md5($cur_url):md5($html);
if(!isset($jsonList[$jsonKey])){
$jsonList[$jsonKey]=json_decode($html,true);
if(empty($jsonList[$jsonKey])&&preg_match(self::$jsonpRegExp, $html,$json)){
$json=trim($json['json']).'}';
$jsonList[$jsonKey]=json_decode($json,true);
}
$jsonList[$jsonKey]=convert_html2json($html);
}
$jsonArrType=$field_params['json_arr'];
if($field_params['json_loop']){
@ -508,12 +507,7 @@ class CpatternBase extends Collector{
$jsonArr=&$jsonArrOrStr;
}else{
$jsonArr=json_decode($jsonArrOrStr,true);
if(empty($jsonArr)&&preg_match(self::$jsonpRegExp,$jsonArrOrStr,$jsonArrOrStr)){
$jsonArr=trim($jsonArrOrStr['json']).'}';
$jsonArr=json_decode($jsonArr,true);
}
$jsonArr=convert_html2json($jsonArrOrStr);
unset($jsonArrOrStr);
}
$val='';
@ -652,7 +646,7 @@ class CpatternBase extends Collector{
return $fieldVal;
}
public function process_f_replace($fieldVal,$params){
return preg_replace('/'.$params['replace_from'].'/i',$params['replace_to'], $fieldVal);
return preg_replace('/'.$params['replace_from'].'/ui',$params['replace_to'], $fieldVal);
}
public function process_f_tool($fieldVal,$params){
@ -667,16 +661,16 @@ class CpatternBase extends Collector{
}
if(in_array('is_img', $params['tool_list'])){
if(!empty($GLOBALS['config']['caiji']['download_img'])){
if(!empty($GLOBALS['_sc']['c']['download_img']['download_img'])){
$fieldVal=preg_replace('/(\bhttp[s]{0,1}\:\/\/[^\s]+)/i','{[img]}'."$1".'{[/img]}',$fieldVal);
$fieldVal=preg_replace('/(?<![\'\"])(\bhttp[s]{0,1}\:\/\/[^\s\'\"\<\>]+)(?![\'\"])/i','{[img]}'."$1".'{[/img]}',$fieldVal);
}
}
return $fieldVal;
}
public function process_f_translate($fieldVal,$params){
if(!empty($GLOBALS['config']['translate'])&&!empty($GLOBALS['config']['translate']['open'])){
if(!empty($GLOBALS['_sc']['c']['translate'])&&!empty($GLOBALS['_sc']['c']['translate']['open'])){
$fieldVal=\util\Translator::translate($fieldVal, $params['translate_from'], $params['translate_to']);
}
@ -698,8 +692,8 @@ class CpatternBase extends Collector{
$batch_re=$batch_list[$listMd5][0];
$batch_to=$batch_list[$listMd5][1];
}
$batch_re=is_array($batch_re)?$batch_re:null;
$batch_to=is_array($batch_to)?$batch_to:null;
$batch_re=is_array($batch_re)?$batch_re:array();
$batch_to=is_array($batch_to)?$batch_to:array();
if(!empty($batch_re)&&count($batch_re)==count($batch_to)){
$fieldVal=str_replace($batch_re, $batch_to, $fieldVal);
@ -717,45 +711,31 @@ class CpatternBase extends Collector{
}
return $fieldVal;
}
public function process_f_func($fieldVal,$params){
public function process_f_func($fieldVal,$params,$curUrlMd5,$loopIndex,$contUrlMd5){
if(!empty($params['func_name'])){
if(!function_exists($params['func_name'])){
$field_val_list=null;
if(preg_match('/\[\x{5b57}\x{6bb5}\:(.+?)\]/u',$params['func_param'])){
if(empty($this->first_loop_field)){
$this->error('数据处理》无效的函数:'.$params['func_name']);
$field_val_list=array();
foreach ($this->field_val_list as $k=>$v){
$field_val_list[$k]=$v['values'][$curUrlMd5];
}
}else{
if(array_key_exists($params['func_name'], config('allow_process_func'))||array_key_exists($params['func_name'], config('EXTEND_PROCESS_FUNC'))){
static $func_param_list=array();
$funcParam=null;
if(empty($params['func_param'])){
$funcParam=array($fieldVal);
}else{
$fparamMd5=md5($params['func_param']);
if(!isset($func_param_list[$fparamMd5])){
if(preg_match_all('/[^\r\n]+/', $params['func_param'],$mfuncParam)){
$func_param_list[$fparamMd5]=$mfuncParam[0];
}
}
$funcParam=$func_param_list[$fparamMd5];
foreach ($funcParam as $k=>$v){
$funcParam[$k]=str_replace('###', $fieldVal, $v);
}
}
if(!empty($funcParam)&&is_array($funcParam)){
try {
$fieldVal=call_user_func_array($params['func_name'], $funcParam);
}catch (\Exception $ex){
}
}
}else{
$this->error('数据处理》未配置函数:'.$params['func_name']);
$field_val_list=array();
foreach ($this->field_val_list as $k=>$v){
$field_val_list[$k]=is_array($v['values'][$curUrlMd5])?$v['values'][$curUrlMd5][$loopIndex]:$v['values'][$curUrlMd5];
}
}
}
$result=$this->execute_plugin_func('process', $params['func_name'], $fieldVal, $params['func_param'], $field_val_list);
if(isset($result)){
$fieldVal=$result;
}
return $fieldVal;
}
public function process_f_filter($fieldVal,$params,$curUrlMd5,$loopIndex,$contUrlMd5){
@ -874,59 +854,16 @@ class CpatternBase extends Collector{
}
break;
case 'func':
if(!empty($ifVal)){
$funcMd5=md5($ifVal);
if(!isset($func_list[$funcMd5])){
if(preg_match_all('/[^\r\n]+/',$ifVal,$funcParam)){
$funcParam=$funcParam[0];
}else{
$funcParam=array($ifVal);
}
$func_list[$funcMd5]=$funcParam;
}else{
$funcParam=$func_list[$funcMd5];
}
$funcName=$funcParam[0];
$isTurn=false;
if(strpos($funcName,'!')===0){
$funcName=substr($funcName, 1);
$isTurn=true;
}
unset($funcParam[0]);
if(empty($funcParam)){
$funcParam=array($fieldVal);
}else{
foreach($funcParam as $k=>$v){
$funcParam[$k]=str_replace('###', $fieldVal, $v);
}
}
if(!function_exists($funcName)){
$this->error('数据处理》条件判断》无效的函数:'.$funcName);
}else{
if(array_key_exists($funcName, config('allow_process_if'))||array_key_exists($funcName, config('EXTEND_PROCESS_IF'))){
try {
$result=call_user_func_array($funcName, $funcParam);
if($isTurn){
$result=$result?false:true;
}
}catch (\Exception $ex){
$this->error('数据处理》条件判断》函数'.$funcName.'运行错误,'.$ex->getMessage());
}
}else{
$this->error('数据处理》条件判断》未配置函数:'.$funcName);
}
}
$funcName=$params['if_addon']['func'][$ifk];
$isTurn=$params['if_addon']['turn'][$ifk];
$isTurn=$isTurn?true:false;
$result=$this->execute_plugin_func('processIf', $funcName, $fieldVal, $ifVal);
$result=$result?true:false;
if($isTurn){
$result=$result?false:true;
}
break;
case 'has':$result=stripos($fieldVal,$ifVal)!==false?true:false;break;
case 'nhas':$result=stripos($fieldVal,$ifVal)===false?true:false;break;
@ -1023,12 +960,66 @@ class CpatternBase extends Collector{
}
return $fieldVal;
}
/*调用接口*/
public function process_f_api($fieldVal,$params){
$url=$params['api_url'];
$result=null;
if(!empty($url)){
$isLoc=false;
if(!preg_match('/^\w+\:\/\//', $url)&&strpos($url, '/')===0){
$isLoc=true;
$url=config('root_website').$url;
}
if(preg_match('/^\w+\:\/\//', $url)){
$postData=array();
if(is_array($params['api_params'])){
foreach ($params['api_params']['name'] as $k=>$v){
if(empty($v)){
continue;
}
$val=$params['api_params']['val'][$k];
$addon=$params['api_params']['addon'][$k];
switch ($val){
case 'field':$val=$fieldVal;break;
case 'timestamp':$val=time();break;
case 'time':$addon=$addon?$addon:'Y-m-d H:i:s';$val=date($addon,time());break;
case 'custom':$val=$addon;break;
}
$postData[$v]=$val;
}
}
if($params['api_type']=='post'){
$postData=empty($postData)?true:$postData;
}else{
if($postData){
$url.=(strpos($url,'?')===false?'?':'&').http_build_query($postData);
}
$postData=null;
}
if($isLoc){
$result=get_html($url,null,array(),'utf-8',$postData);
}else{
$result=$this->get_html($url,false,$postData);
}
if(isset($result)){
$fieldVal=$this->rule_module_json_data(array('json'=>$params['api_json'],'json_arr'=>$params['api_json_arr'],'json_arr_implode'=>$params['api_json_implode']),$result);
}
}
}
return $fieldVal;
}
/*数据处理*/
public function process_field($fieldVal,$process,$curUrlMd5,$loopIndex,$contUrlMd5){
if(empty($process)){
return $fieldVal;
}
static $funcs=array('filter','if');
static $funcs=array('func','filter','if');
foreach ($process as $params){
if(empty($this->first_loop_field)){
@ -1164,6 +1155,8 @@ class CpatternBase extends Collector{
$urls=array_unique($urls[0]);
$urls=array_values($urls);
}else{
$urls=array();
}
return $urls;
}else{
@ -1269,15 +1262,159 @@ class CpatternBase extends Collector{
}
return $tags;
}
/*获取源码*/
public function get_html($url,$open_cache=false,$is_post=false){
if($open_cache&&!empty($this->html_cache_list[$url])){
return $this->html_cache_list[$url];
/**
* 执行数据处理》使用函数
* @param string $module 模块
* @param string $funcName 函数/方法
* @param string $fieldVal 字段值
* @param string $paramsStr 输入的参数(有换行符)
* @param array $fieldValList 所有字段值(调用字段时使用)
*/
public function execute_plugin_func($module,$funcName,$fieldVal,$paramsStr,$fieldValList=null){
static $func_class_list=array('process'=>array(),'processIf'=>array());
$class_list=&$func_class_list[$module];
$options = array (
'process' => array (
'name' => '使用函数',
'config'=>'allow_process_func',
'extend'=>'EXTEND_PROCESS_FUNC',
),
'processIf' => array (
'name' => '条件判断》使用函数',
'config'=>'allow_process_if',
'extend'=>'EXTEND_PROCESS_IF',
)
);
$options=$options[$module];
$result=null;
if(!empty($funcName)){
$success=false;
if(strpos($funcName, ':')!==false){
$funcName=explode(':', $funcName);
}
if(!is_array($funcName)){
if(!function_exists($funcName)){
$this->error('数据处理》'.$options['name'].'》无效的函数:'.$funcName);
}elseif(!array_key_exists($funcName, config($options['config']))&&!array_key_exists($funcName, config($options['extend']))){
$this->error('数据处理》'.$options['name'].'》未配置函数:'.$funcName);
}else{
$success=true;
}
}else{
$className=$funcName[0];
$methodName=$funcName[1];
if(!isset($class_list[$className])){
$enable=model('FuncApp')->field('enable')->where(array('app'=>$className,'module'=>$module))->value('enable');
if($enable){
$class=model('FuncApp')->app_classname($module,$className);
if(!class_exists($class)){
$class_list[$className]=1;
}else{
$class=new $class();
$class_list[$className]=$class;
}
}else{
$class_list[$className]=2;
}
}
if(is_object($class_list[$className])){
if(!method_exists($class_list[$className], $methodName)){
$this->error('数据处理》'.$options['name'].'》不存在方法:'.$className.'-&gt;'.$methodName);
}else{
$success=true;
}
}else{
$msg='数据处理》'.$options['name'].'》';
if($class_list[$className]==1){
$msg.='不存在插件:';
}elseif($class_list[$className]==2){
$msg.='已禁用插件:';
}else{
$msg.='无效的插件:';
}
$this->error($msg.$className);
}
}
if($success){
static $func_param_list=array();
$funcParam=null;
if(empty($paramsStr)){
$funcParam=array($fieldVal);
}else{
$fparamMd5=md5($paramsStr);
if(!isset($func_param_list[$fparamMd5])){
if(preg_match_all('/[^\r\n]+/',$paramsStr,$mfuncParam)){
$func_param_list[$fparamMd5]=$mfuncParam[0];
}
}
$funcParam=$func_param_list[$fparamMd5];
if($funcParam){
foreach ($funcParam as $k=>$v){
$v=str_replace('###', $fieldVal, $v);
if($fieldValList&&preg_match_all('/\[\x{5b57}\x{6bb5}\:(.+?)\]/u',$v,$match_fields)){
for($i=0;$i<count($match_fields[0]);$i++){
$v=str_replace($match_fields[0][$i],$fieldValList[$match_fields[1][$i]],$v);
}
}
$funcParam[$k]=$v;
}
}
}
if(!empty($funcParam)&&is_array($funcParam)){
try {
if(!is_array($funcName)){
$result=call_user_func_array($funcName, $funcParam);
}else{
$result=call_user_func_array(array($class_list[$funcName[0]],$funcName[1]), $funcParam);
}
}catch (\Exception $ex){
}
}
}
}
return $result;
}
/**
* 获取源码
* @param string $url 网址
* @param bool $openCache 开启缓存网页数据,$postData有数据时最好关闭$postData为true根据$url缓存
* @param bool|array $postData 开启post模式或者传递post数组true会将$url中的get参数转换成post数组
*/
public function get_html($url,$openCache=false,$postData=false){
if(!empty($GLOBALS['_sc']['c']['caiji']['robots'])){
if(!model('Collector')->abide_by_robots($url)){
$this->error('robots拒绝访问的网址'.$url);
return null;
}
}
$urlMd5=md5($url);
if($openCache&&!empty($this->html_cache_list[$urlMd5])){
return $this->html_cache_list[$urlMd5];
}
$is_post=$postData?true:false;
$pageRenderTool=null;
if($this->config['page_render']){
$pageRenderTool=$GLOBALS['config']['page_render']['tool'];
$pageRenderTool=$GLOBALS['_sc']['c']['page_render']['tool'];
if(empty($pageRenderTool)){
$this->error('页面渲染未设置,请检查<a href="'.url('Setting/page_render').'" target="_blank">渲染设置</a>','Setting/page_render');
@ -1288,33 +1425,23 @@ class CpatternBase extends Collector{
$html=null;
$headers=array();
$options=array();
if($this->config['request_headers']['open']){
if(!empty($GLOBALS['_sc']['task_request_headers'])){
if(!empty($this->config['request_headers']['useragent'])){
$headers=$GLOBALS['_sc']['task_request_headers']['headers'];
if(!empty($headers['useragent'])){
$options['useragent']=$this->config['request_headers']['useragent'];
}
if(!empty($this->config['request_headers']['cookie'])){
$headers['cookie']=$this->config['request_headers']['cookie'];
}
if(!empty($this->config['request_headers']['referer'])){
$headers['referer']=$this->config['request_headers']['referer'];
}
if(!empty($this->config['request_headers']['custom_names'])){
foreach ($this->config['request_headers']['custom_names'] as $k=>$v){
if(!empty($v)){
$headers[$v]=$this->config['request_headers']['custom_vals'][$k];
}
}
$options['useragent']=$headers['useragent'];
}
unset($headers['useragent']);
}
$mproxy=model('Proxyip');
$proxy_ip=null;
if(!empty($GLOBALS['config']['proxy']['open'])){
$proxyDbIp=null;
if(!empty($GLOBALS['_sc']['c']['proxy']['open'])){
$proxy_ip=$mproxy->get_usable_ip();
$proxyIp=$mproxy->to_proxy_ip($proxy_ip);
$proxyDbIp=$mproxy->get_usable_ip();
$proxyIp=$mproxy->to_proxy_ip($proxyDbIp);
if(!empty($proxyIp)){
@ -1331,8 +1458,30 @@ class CpatternBase extends Collector{
}else{
$urlPost='';
}
if(is_string($postData)){
if($urlPost){
$urlPost.=$postData?('&'.$postData):'';
}else{
$urlPost=$postData;
}
}elseif(is_array($postData)){
if($urlPost){
if(preg_match_all('/([^\&]+?)\=([^\&]*)/',$urlPost,$mUrlPost)){
$urlPostData=array();
foreach($mUrlPost[1] as $k=>$v){
$urlPostData[$v]=rawurldecode($mUrlPost[2][$k]);
}
$urlPost=$urlPostData;
unset($urlPostData);
}
}
$urlPost=is_array($urlPost)?$urlPost:array();
$urlPost=array_merge($urlPost,$postData);
unset($postData);
}
}
if($pageRenderTool){
if(!empty($options['useragent'])){
@ -1340,15 +1489,11 @@ class CpatternBase extends Collector{
$headers['user-agent']=$options['useragent'];
unset($options['useragent']);
}
if(!empty($options['proxy'])){
$options['proxy']=$proxy_ip;
}
if($pageRenderTool=='chrome'){
$chromeConfig=$GLOBALS['config']['page_render']['chrome'];
$chromeConfig=$GLOBALS['_sc']['c']['page_render']['chrome'];
try {
$chromeSocket=new \util\ChromeSocket($chromeConfig['host'],$chromeConfig['port'],$GLOBALS['config']['page_render']['timeout'],$chromeConfig['filename']);
$chromeSocket=new \util\ChromeSocket($chromeConfig['host'],$chromeConfig['port'],$GLOBALS['_sc']['c']['page_render']['timeout'],$chromeConfig['filename']);
$chromeSocket->newTab();
$chromeSocket->websocket(null);
if($is_post){
@ -1367,16 +1512,17 @@ class CpatternBase extends Collector{
}
}else{
if($is_post){
$html=get_html($url,$headers,$options,$this->config['charset'],$urlPost);
$urlPost=$urlPost?$urlPost:'';
}else{
$html=get_html($url,$headers,$options,$this->config['charset']);
$urlPost=null;
}
$html=get_html($url,$headers,$options,$this->config['charset'],$urlPost);
}
if($html==null){
if(!empty($proxy_ip)){
$mproxy->set_ip_failed($proxy_ip);
if(!empty($proxyDbIp)){
$mproxy->set_ip_failed($proxyDbIp);
}
return null;
}
@ -1393,8 +1539,8 @@ class CpatternBase extends Collector{
return \skycaiji\admin\event\Cpattern::create_complete_url($matche[1], $base_url, $domain_url);
},$html);
}
if($open_cache){
$this->html_cache_list[$url]=$html;
if($openCache){
$this->html_cache_list[$urlMd5]=$html;
}
return $html;
}

View File

@ -9,7 +9,6 @@
|--------------------------------------------------------------------------
*/
/*发布设置:本地cms*/
namespace skycaiji\admin\event;
use skycaiji\admin\model\CacheModel;
class Rapi extends Release{

View File

@ -11,6 +11,7 @@
/*发布设置:本地cms*/
namespace skycaiji\admin\event;
class Rcms extends Release{
protected $rele_cms_list=array();
/**

View File

@ -9,7 +9,6 @@
|--------------------------------------------------------------------------
*/
/*发布设置:本地cms*/
namespace skycaiji\admin\event;
use skycaiji\admin\model\DbCommon;
class Rdb extends Release{

View File

@ -74,7 +74,7 @@ class ReleaseBase extends \skycaiji\admin\controller\BaseController{
return '';
}
$val=$collFieldVal['value'];
if(!empty($GLOBALS['config']['caiji']['download_img'])){
if(!empty($GLOBALS['_sc']['c']['download_img']['download_img'])){
if(!empty($collFieldVal['img'])){
@ -96,8 +96,8 @@ class ReleaseBase extends \skycaiji\admin\controller\BaseController{
$curI++;
if($curI<$total){
if(!empty($GLOBALS['config']['caiji']['img_interval'])){
sleep($GLOBALS['config']['caiji']['img_interval']);
if(!empty($GLOBALS['_sc']['c']['download_img']['img_interval'])){
sleep($GLOBALS['_sc']['c']['download_img']['img_interval']);
}
}
}
@ -110,8 +110,8 @@ class ReleaseBase extends \skycaiji\admin\controller\BaseController{
static $imgPaths=array();
static $imgUrls=array();
$img_path=$GLOBALS['config']['caiji']['img_path'];
$img_url=$GLOBALS['config']['caiji']['img_url'];
$img_path=$GLOBALS['_sc']['c']['download_img']['img_path'];
$img_url=$GLOBALS['_sc']['c']['download_img']['img_url'];
if(!isset($imgPaths[$img_path])){
if(empty($img_path)){
@ -142,6 +142,15 @@ class ReleaseBase extends \skycaiji\admin\controller\BaseController{
return $url;
}
if(!empty($GLOBALS['_sc']['c']['caiji']['robots'])){
if(!model('Collector')->abide_by_robots($url)){
$this->echo_msg('robots拒绝访问的网址'.$url);
return $url;
}
}
static $imgList=array();
$key=md5($url);
if(!isset($imgList[$key])){
@ -153,43 +162,75 @@ class ReleaseBase extends \skycaiji\admin\controller\BaseController{
}
$filename='';
$imgurl='';
$imgname='';
$isExists=false;
$imgname=$GLOBALS['_sc']['c']['download_img']['img_name'];
if('url'==$GLOBALS['config']['caiji']['img_name']){
if('url'==$imgname){
$imgname=substr($key,0,2).'/'.substr($key,-2,2).'/';
$imgname=substr($key,0,2).'/'.substr($key,-2,2).'/'.$key.'.'.$prop;
$filename=$img_path.$imgname;
$isExists=file_exists($filename);
if(!$isExists){
$imgname=substr($key,0,2).'/'.substr($key,2).'.'.$prop;
$filename=$img_path.$imgname;
$isExists=file_exists($filename);
}
}elseif('custom'==$imgname){
$imgname=model('Config')->convert_img_name_path($GLOBALS['_sc']['c']['download_img']['name_custom_path'],$url);
$imgname.='/'.$key.'.'.$prop;
$filename=$img_path.$imgname;
$isExists=file_exists($filename);
}else{
$imgname=date('Y-m-d',NOW_TIME).'/';
$imgname=date('Y-m-d',NOW_TIME).'/'.$key.'.'.$prop;
$filename=$img_path.$imgname;
$isExists=file_exists($filename);
}
$imgname.=$key.'.'.$prop;
$filename=$img_path.$imgname;
$imgurl=$img_url.$imgname;
if(!file_exists($filename)){
if(!$isExists){
$mproxy=model('Proxyip');
try {
$options=array();
if(!empty($GLOBALS['config']['caiji']['img_timeout'])){
$headers=array();
if(!empty($GLOBALS['_sc']['task_request_headers'])&&!empty($GLOBALS['_sc']['task_request_headers']['request_headers']['download_img'])){
$options['timeout']=$GLOBALS['config']['caiji']['img_timeout'];
$headers=$GLOBALS['_sc']['task_request_headers']['headers'];
if(!empty($headers['useragent'])){
$options['useragent']=$headers['useragent'];
}
unset($headers['useragent']);
}
if(!empty($GLOBALS['config']['proxy']['open'])){
if(!empty($GLOBALS['_sc']['c']['download_img']['img_timeout'])){
$proxy_ip=$mproxy->get_usable_ip();
$proxyIp=$mproxy->to_proxy_ip($proxy_ip);
$options['timeout']=$GLOBALS['_sc']['c']['download_img']['img_timeout'];
}
if(!empty($GLOBALS['_sc']['c']['proxy']['open'])){
$proxyIp=$mproxy->get_usable_ip();
$proxyIp=$mproxy->to_proxy_ip($proxyIp);
if(!empty($proxyIp)){
$options['proxy']=$proxyIp;
}
}
if(!empty($GLOBALS['config']['caiji']['img_max'])){
if(!empty($GLOBALS['_sc']['c']['download_img']['img_max'])){
$options['max_bytes']=intval($GLOBALS['config']['caiji']['img_max'])*1024*1024;
$options['max_bytes']=intval($GLOBALS['_sc']['c']['download_img']['img_max'])*1024*1024;
}
$imgCode=get_html($url,null,$options,'utf-8');
$imgCode=get_html($url,$headers,$options,'utf-8');
if(!empty($imgCode)){

View File

@ -9,7 +9,6 @@
|--------------------------------------------------------------------------
*/
/*发布设置:本地cms*/
namespace skycaiji\admin\event;
class Rfile extends Release {
/**

View File

@ -0,0 +1,137 @@
<?php
/*
|--------------------------------------------------------------------------
| SkyCaiji (蓝天采集器)
|--------------------------------------------------------------------------
| Copyright (c) 2018 https://www.skycaiji.com All rights reserved.
|--------------------------------------------------------------------------
| 使用协议 https://www.skycaiji.com/licenses
|--------------------------------------------------------------------------
*/
/*发布设置:调用接口*/
namespace skycaiji\admin\event;
class Rtoapi extends Release{
protected $url_list=array();
/**
* 设置页面post过来的config
* @param unknown $config
*/
public function setConfig($config){
$toapi=input('toapi/a','','trim');
if(empty($toapi['url'])){
$this->error('请输入接口地址');
}
if(empty($toapi['response']['id'])){
$this->error('请输入响应id的健名');
}
if(is_array($toapi['param_name'])){
$toapi['param_name']=array_array_map('trim', $toapi['param_name']);
foreach ($toapi['param_name'] as $k=>$v){
if(empty($v)){
unset($toapi['param_name'][$k]);
unset($toapi['param_val'][$k]);
unset($toapi['param_addon'][$k]);
}
}
}
$config['toapi']=$toapi;
return $config;
}
/*导出数据*/
public function export($collFieldsList,$options=null){
$addedNum=0;
if(empty($this->config['toapi']['url'])){
$this->echo_msg('接口地址为空');
}else{
$urlMd5=md5($this->config['toapi']['url']);
$url='';
if(!isset($this->url_list[$urlMd5])){
$url=$this->config['toapi']['url'];
if(strpos($url, '/')===0){
$url=config('root_website').$url;
}elseif(!preg_match('/^\w+\:\/\//', $url)){
$url='http://'.$url;
}
$this->url_list[$urlMd5]=$url;
}else{
$url=$this->url_list[$urlMd5];
}
$response=$this->config['toapi']['response'];
$response=is_array($response)?$response:array();
foreach ($collFieldsList as $collFieldsKey=>$collFields){
$contTitle=$collFields['title'];
$contUrl=$collFields['url'];
$collFields=$collFields['fields'];
$params=array();
if(is_array($this->config['toapi']['param_name'])){
foreach($this->config['toapi']['param_name'] as $k=>$pname){
if(empty($pname)){
continue;
}
$pval=$this->config['toapi']['param_val'][$k];
if(empty($pval)){
$params[$pname]=$pval;
}elseif($pval=='custom'){
$params[$pname]=$this->config['toapi']['param_addon'][$k];
}elseif(preg_match('/^field\:(.+)$/ui',$pval,$fieldName)){
$params[$pname]=$this->get_field_val($collFields[$fieldName[1]]);
}
}
}
if($this->config['toapi']['type']=='post'){
$params=is_array($params)?$params:'';
}else{
$url.=(strpos($url,'?')===false?'?':'&').http_build_query($params);
$params=null;
}
$json=get_html($url,null,array(),'utf-8',$params);
$json=json_decode($json,true);
$returnData=array('id'=>'','target'=>'','desc'=>'','error'=>'');
if(!empty($response['id'])&&isset($json[$response['id']])){
foreach ($returnData as $k=>$v){
if(isset($response[$k])){
$returnData[$k]=$json[$response[$k]]?$json[$response[$k]]:'';
}else{
$returnData[$k]='';
}
}
if($returnData['id']>0){
$addedNum++;
if($returnData['id']>1&&empty($returnData['target'])){
$returnData['target']='编号:'.$returnData['id'];
}
}
}else{
$returnData['id']=0;
$returnData['error']='无响应状态';
}
$this->record_collected($contUrl,$returnData,$this->release,$contTitle);
unset($collFieldsList[$collFieldsKey]['fields']);
}
}
return $addedNum;
}
}
?>

View File

@ -76,8 +76,8 @@ return array(
'user_login_in'=>'登录中...',
'user_auto_login'=>'正在自动登录...',
'usertoken_error'=>'用户token错误请刷新页面重新获取',
'usertoken_error'=>'用户token错误请刷新界面重新获取或清除浏览器缓存',
'task'=>'任务',
'task_add'=>'添加任务',
'task_edit'=>'编辑任务',
@ -166,6 +166,7 @@ return array(
'process_module_batch'=>'批量替换',
'process_module_substr'=>'截取字符串',
'process_module_func'=>'使用函数',
'process_module_api'=>'调用接口',
'p_m_if_1'=>'满足条件采集',
'p_m_if_2'=>'满足条件不采集',
@ -182,7 +183,8 @@ return array(
'rele_module'=>'发布方式',
'rele_module_cms'=>'本地CMS程序',
'rele_module_db'=>'数据库',
'rele_module_api'=>'API接口',
'rele_module_api'=>'生成API',
'rele_module_toapi'=>'调用接口',
'rele_module_file'=>'文件存储',
'rele_module_diy'=>'自定义插件',
'rele_btn_detect'=>'开始检测',
@ -206,6 +208,7 @@ return array(
'collected_rele_cms'=>'CMS',
'collected_rele_db'=>'数据库',
'collected_rele_file'=>'文件',
'collected_rele_toapi'=>'接口',
'collected_rele_api'=>'API',
'collected_rele_diy'=>'插件',

View File

@ -42,6 +42,8 @@ class App extends BaseModel{
$config=array();
}
$appClass->config=is_array($config)?$config:array();
}else{
$appClass->config=array();
}
}
}

View File

@ -54,6 +54,7 @@ class CacheModel{
* @return mixed
*/
public function getCache($cname,$key=null){
$cache=$this->db()->where('cname',$cname)->find();
switch($cache['ctype']){
case 1:$cache['data']=intval($cache['data']);break;

View File

@ -26,7 +26,110 @@ class Collector extends BaseModel{
$this->strict(false)->where(array('id'=>$id))->update($data);
}
/*遵守robots协议*/
public function abide_by_robots($url){
static $robotsList=array();
$domain=null;
if(preg_match('/^(\w+\:\/\/[^\/\\\]+)(.*)$/i',$url,$domain)){
$url='/'.ltrim($domain[2],'\/\\');
$domain=rtrim($domain[1],'\/\\');
}
if(empty($domain)){
return true;
}
$robots=array();
if(isset($robotsList[$domain])){
$robots=$robotsList[$domain];
}else{
$robotsTxt=get_html($domain.'/robots.txt');
if(!empty($robotsTxt)){
$robotsTxt=preg_replace('/\#[^\r\n]*$/m', '', $robotsTxt);
$rule=null;
if(preg_match('/\bUser-agent\s*:\s*skycaiji\s+(?P<rule>[\s\S]+?)(?=((\bUser-agent\s*\:)|\s*$))/i',$robotsTxt,$rule)){
$rule=$rule['rule'];
}elseif(preg_match('/\bUser-agent\s*:\s*\*\s+(?P<rule>[\s\S]+?)(?=((\bUser-agent\s*\:)|\s*$))/i',$robotsTxt,$rule)){
$rule=$rule['rule'];
}else{
$rule=null;
}
if(!empty($rule)){
static $replace=array('\\','/','.','*','?','~','!','@','#','%','&','(',')','[',']','{','}','+','=','|',':',',');
static $replaceTo=array('\\\\','\/','\.','.*','\?','\~','\!','\@','\#','\%','\&','\(','\)','\[','\]','\{','\}','\+','\=','\|','\:','\,');
$allow=array();
$disallow=array();
if(preg_match_all('/\bAllow\s*:([^\r\n]+)/i',$rule,$allow)){
$allow=array_unique($allow[1]);
}else{
$allow=array();
}
if(preg_match_all('/\bDisallow\s*:([^\r\n]+)/i',$rule,$disallow)){
$disallow=array_unique($disallow[1]);
}else{
$disallow=array();
}
$robots=array(
'allow'=>$allow,
'disallow'=>$disallow
);
foreach ($robots as $k=>$v){
foreach ($v as $vk=>$vv){
$vv=trim($vv);
if(empty($vv)||$vv=='/'){
unset($v[$vk]);
}else{
$vv=str_replace($replace, $replaceTo, $vv);
if(strpos($vv,'\/')===0){
$vv='^'.$vv;
}
$v[$vk]=$vv;
}
}
$robots[$k]=$v;
}
}
}
$robotsList[$domain]=$robots;
}
if(empty($robots)){
return true;
}
if(!empty($robots['allow'])){
foreach ($robots['allow'] as $v){
if(preg_match('/'.$v.'/', $url)){
return true;
break;
}
}
}
if(!empty($robots['disallow'])){
foreach ($robots['disallow'] as $v){
if(preg_match('/'.$v.'/', $url)){
return false;
break;
}
}
}
return true;
}
}
?>

View File

@ -30,6 +30,7 @@ class Config extends BaseModel {
* @return mixed
*/
public function getConfig($cname,$key=null){
$item=$this->where('cname',$cname)->find();
if(!empty($item)){
$item=$item->toArray();
@ -55,7 +56,29 @@ class Config extends BaseModel {
}
$data['dateline']=time();
$this->insert($data,true);
$this->cacheConfigList();
}
/*缓存所有配置*/
public function cacheConfigList(){
$keyConfig='cache_config_all';
$configDbList=$this->column('*');
$configDbList=empty($configDbList)?array():$configDbList;
$configList=array();
foreach ($configDbList as $configItem){
$configItem=$this->convertData($configItem);
$configList[$configItem['cname']]=$configItem['data'];
}
cache($keyConfig,array('list'=>$configList));
}
public function getConfigList(){
$keyConfig='cache_config_all';
$cacheConfig=cache($keyConfig);
$configList=$cacheConfig['list'];
return is_array($configList)?$configList:array();
}
/*设置版本号*/
public function setVersion($version){
$version=trim(strtoupper($version),'V');
@ -111,5 +134,105 @@ class Config extends BaseModel {
}
return $return;
}
public function check_img_name_path($path){
static $check_list=array();
if(!isset($check_list[$path])){
$return=array('success'=>false,'msg'=>'');
if(!empty($path)){
if(!preg_match('/^(\w+|\-|\/|(\[(年|月|日|时|前两位|后两位)\]))+$/u',$path)){
$return['msg']='图片名称自定义目录只能输入字母、数字、- 、/ 或 标签';
}else{
if(preg_match('/^\/+$/', $path)){
$return['msg']='图片名称自定义目录不能只由/组成';
}else{
$return['success']=true;
}
}
}
$check_list[$path]=$return;
}else{
$return=$check_list[$path];
}
return $return;
}
public function convert_img_name_path($path,$url){
$check=$this->check_img_name_path($path);
if($check['success']){
$md5=md5($url);
static $tags=array('[年]','[月]','[日]','[时]','[前两位]','[后两位]');
$tagsRe=array(
date('Y',NOW_TIME),
date('m',NOW_TIME),
date('d',NOW_TIME),
date('H',NOW_TIME),
substr($md5,0,2),
substr($md5,-2,2),
);
$path=preg_replace('/\/{2,}/', '/', $path);
$path=str_replace($tags, $tagsRe, $path);
$path=trim($path,'/');
}else{
$path='temp';
}
return $path;
}
public function get_img_config_from_caiji($caijiConfig){
$config=array();
if(!empty($caijiConfig)){
static $vars=array('download_img','img_path','img_url','img_name','img_timeout','img_interval','img_max');
foreach ($vars as $var){
if(isset($caijiConfig[$var])){
$config[$var]=$caijiConfig[$var];
}
}
}
return $config;
}
public function detect_php_exe(){
static $php_filename=null;
if(!isset($php_filename)){
$ds=DIRECTORY_SEPARATOR;
$ini_all=ini_get_all();
$php_ext_path=$ini_all['extension_dir']['local_value'];
if($php_ext_path){
$php_ext_path=preg_replace('/[\/\\\]+/', '/', $php_ext_path);
$phpPaths=explode('/', $php_ext_path);
$phpPath='';
if(IS_WIN){
foreach ($phpPaths as $v){
$phpPath.=$v.$ds;
if(is_file($phpPath.'php-cli.exe')){
$php_filename=$phpPath.'php-cli.exe';
break;
}elseif(is_file($phpPath.'php.exe')){
$php_filename=$phpPath.'php.exe';
break;
}
}
}else{
foreach ($phpPaths as $v){
$phpPath.=$v.$ds;
if(is_file($phpPath.'bin'.$ds.'php')){
$php_filename=$phpPath.'bin'.$ds.'php';
break;
}
}
}
}else{
$php_filename='php';
}
}
return $php_filename;
}
}
?>

View File

@ -32,7 +32,7 @@ class DbCommon{
'break_reconnect'=>true,
'params'=>array(),
);
if(!empty($GLOBALS['config']['site']['dblong'])){
if(!empty($GLOBALS['_sc']['c']['site']['dblong'])){
$this->config['params'][\PDO::ATTR_PERSISTENT]=true;
}

View File

@ -0,0 +1,219 @@
<?php
/*
|--------------------------------------------------------------------------
| SkyCaiji (蓝天采集器)
|--------------------------------------------------------------------------
| Copyright (c) 2018 https://www.skycaiji.com All rights reserved.
|--------------------------------------------------------------------------
| 使用协议 https://www.skycaiji.com/licenses
|--------------------------------------------------------------------------
*/
namespace skycaiji\admin\model;
class FuncApp extends BaseModel{
protected $tableName='func_app';
public $funcPath;
public $funcModules=array(
'process'=>array (
'name'=>'数据处理',
'loc'=>'数据处理》使用函数'
),
'processIf'=>array(
'name'=>'条件判断',
'loc'=>'数据处理》条件判断》使用函数'
)
);
public function __construct($data = []){
parent::__construct($data);
$this->funcPath=config('plugin_path').DIRECTORY_SEPARATOR.'func'.DIRECTORY_SEPARATOR;
}
/*添加入库*/
public function insertApp($data){
$data=is_array($data)?$data:array();
$data['module']=$this->format_module($data['module']);
$data['name']=strip_tags($data['name']);
$data['addtime']=time();
$data['enable']=0;
$data['uptime']=$data['uptime']>0?$data['uptime']:time();
return $this->strict(false)->insert($data,false,true);
}
/*创建插件并入库*/
public function createApp($module,$app,$appData=array()){
$module=$this->format_module($module);
$funcFile=$this->filename($module,$app);
$funcTpl=file_get_contents(config('app_path').'/public/func_app/class.tpl');
$name=$appData['name'];
if(!empty($appData['name'])){
$appData['name']="/**\r\n * ".$appData['name']."\r\n */";
}else{
$appData['name']='';
}
if(is_array($appData['methods'])){
$methods='';
foreach ($appData['methods']['method'] as $k=>$v){
if(preg_match('/^[a-z\_]\w*/',$v)){
$methods.="\r\n /**\r\n * ".strip_tags($appData['methods']['comment'][$k])."\r\n */"
."\r\n public function {$v}(\$val){\r\n return \$val;\r\n }";
}
}
$appData['methods']=$methods;
}else{
$appData['methods']='';
}
$funcTpl=str_replace(array('{$module}','{$classname}','{$name}','{$methods}'), array($module,$app,$appData['name'],$appData['methods']), $funcTpl);
if(write_dir_file($funcFile,$funcTpl)){
return $this->insertApp(array('module'=>$module,'app'=>$app,'name'=>$name));
}else{
return false;
}
}
/*添加插件*/
public function addFunc($func,$code=''){
if(empty($func['app'])){
return false;
}
$func['module']=$this->format_module($func['module']);
$func['uptime']=$func['uptime']>0?$func['uptime']:time();
$funcData=$this->where('app',$func['app'])->find();
$success=false;
if(!empty($funcData)){
$this->strict(false)->where('app',$func['app'])->update($func);
$success=true;
}else{
$func['id']=$this->insertApp($func);
$success=$func['id']>0?true:false;
}
if($success){
$funcAppPath=config('plugin_path').'/func';
if(!empty($code)){
write_dir_file($funcAppPath.'/'.$func['module'].'/'.ucfirst($func['app']).'.php', $code);
}
}
return $success;
}
public function filename($module,$app){
$module=$this->format_module($module);
return $this->funcPath."{$module}/{$app}.php";
}
/*获取插件文件类的属性*/
public function get_app_class($module,$app){
$module=$this->format_module($module);
$filename=$this->funcPath."{$module}/{$app}.php";
if(file_exists($filename)){
$class=$this->app_classname($module, $app);
if(class_exists($class)){
$copyright='';
$identifier='';
if(preg_match('/^(\w+?)([A-Z])(\w*)$/',$app,$mapp)){
$identifier=$mapp[1];
$copyright=$mapp[2].$mapp[3];
}
$class=new $class();
$reClass = new \ReflectionClass($class);
$name=$reClass->getDocComment();
$name=preg_replace('/^[\/\*\s]+/m', '', $name);
$name=trim($name);
$reMethods=$reClass->getMethods(\ReflectionMethod::IS_PUBLIC);
$methods=array();
if(!empty($reMethods)){
foreach ($reMethods as $reMethod){
$comment=$reMethod->getDocComment();
$comment=preg_replace('/^[\/\*\s]+/m', '', $comment);
$comment=trim($comment);
$methods[$reMethod->name]=array('comment'=>$comment);
}
}
return array (
'module' => $module,
'app' => $app,
'filename' => $filename,
'copyright' => $copyright,
'identifier' => $identifier,
'name' => $name,
'methods' => $methods
);
}
}
return array();
}
public function app_classname($module,$app){
return '\\plugin\\func\\'.$module.'\\'.$app;
}
/*转换成app名称*/
public function app_name($copyright,$identifier){
$copyright=$this->format_copyright($copyright);
$identifier=$this->format_identifier($identifier);
return $identifier.$copyright;
}
public function format_module($module){
return $module;
}
public function format_copyright($copyright){
return ucfirst(strtolower($copyright));
}
public function format_identifier($identifier){
return ucfirst(strtolower($identifier));
}
public function right_module($module){
if(empty($this->funcModules[$module])){
return false;
}else{
return true;
}
}
public function right_copyright($copyright){
if(preg_match('/^[a-z]+[a-z0-9]*$/i',$copyright)){
return true;
}else{
return false;
}
}
public function right_identifier($identifier){
if(preg_match('/^[a-z]+[a-z0-9]*$/i',$identifier)){
return true;
}else{
return false;
}
}
/*获取所有插件类*/
public function get_class_list($module){
$apps=$this->get_app_list($module);
$classList=array();
foreach($apps as $app){
$class=$this->get_app_class($module,$app);
if(!empty($class)){
$classList[$app]=$class;
}
}
return $classList;
}
public function get_app_list($module){
$apps=scandir($this->funcPath.$module);
$appList=array();
if(!empty($apps)){
foreach($apps as $app){
if(preg_match('/(\w+)\.php/i',$app,$mapp)){
$appList[$app]=$mapp[1];
}
}
}
return $appList;
}
}
?>

View File

@ -13,10 +13,11 @@ namespace skycaiji\admin\model;
/*第三方服务商*/
class Provider extends BaseModel{
/*匹配域名*/
public static function matchDomain($url){
public static function match_domain($url){
$domain=null;
if(preg_match('/^\w+\:\/\/[\w\-]+(\.[\w\-]+)*(\:\d+){0,1}/', $url,$domain)){
$domain=rtrim($domain[0],'/');
$domain=strtolower($domain);
}else{
$domain=null;
}
@ -24,7 +25,7 @@ class Provider extends BaseModel{
}
/*获取id*/
public function getIdByUrl($url){
$url=self::matchDomain($url);
$url=self::match_domain($url);
if(is_official_url($url)){
$url=null;

View File

@ -16,25 +16,27 @@ class Proxyip extends BaseModel {
public $setting;
public function __construct($data=[]){
parent::__construct($data);
$this->setting=$GLOBALS['config']['proxy'];
$this->setting=$GLOBALS['_sc']['c']['proxy'];
}
/*转换成get_html中格式的ip*/
public function to_proxy_ip($proxy_ip){
$proxyIp=null;
if(empty($proxy_ip)||empty($proxy_ip['ip'])){
/*数据库ip转换成get_html格式的ip*/
public function to_proxy_ip($proxyDbIp){
if(empty($proxyDbIp)||empty($proxyDbIp['ip'])){
$proxyIp=null;
return null;
}
if(empty($proxy_ip['user'])){
$ip=explode(':',$proxyDbIp['ip']);
if(empty($ip[0])){
return null;
}
$proxyIp=array(
'ip'=>$ip[0],
'port'=>$ip[1],
'type'=>$proxyDbIp['type'],
);
if(!empty($proxyDbIp['user'])){
$proxyIp=$proxy_ip['ip'];
}else{
$proxyIp=array(
$proxy_ip['ip'],
$proxy_ip['user'],
$proxy_ip['pwd']
);
$proxyIp['user']=$proxyDbIp['user'];
$proxyIp['pwd']=$proxyDbIp['pwd'];
}
return $proxyIp;
}
@ -43,7 +45,6 @@ class Proxyip extends BaseModel {
if(!empty($this->setting['open'])){
$cond=array();
$cond['invalid']=0;
if(!empty($this->setting['use'])){
if($this->setting['use']=='num'){
@ -57,7 +58,25 @@ class Proxyip extends BaseModel {
$cond['num']=array('lt',1);
}
$cond['invalid']=0;
$proxyipData=$this->where($cond)->find();
if(empty($proxyipData)&&!empty($this->setting['api']['open'])){
$apiInsert=strtolower($this->setting['api']['insert']);
if(empty($apiInsert)){
if($this->where('invalid',0)->count()<=0){
$this->add_api_ips($this->setting);
$proxyipData=$this->where($cond)->find();
}
}elseif($apiInsert=='end'){
$this->add_api_ips($this->setting);
$proxyipData=$this->where($cond)->find();
}
}
if(empty($proxyipData)){
@ -117,6 +136,118 @@ class Proxyip extends BaseModel {
}
$this->strict(false)->where(array('ip'=>$proxy_ip['ip']))->update($upData);
}
/*代理类型*/
public function proxy_types(){
return array('http(s)'=>'','socks4'=>'socks4','socks5'=>'socks5');
}
/*匹配格式的ip*/
public function get_format_ips($html,$format,$multiple=false){
if(empty($html)||empty($format)){
return null;
}
$format=$this->convert_format($format);
if(!$multiple){
$ip=null;
if(preg_match('/'.$format.'/i',$html,$mip)){
$ip=array(
'ip'=>$mip['ip'],
'port'=>$mip['port'],
'user'=>$mip['user'],
'pwd'=>$mip['pwd'],
);
}
return $ip;
}else{
$ips=array();
if(preg_match_all('/'.$format.'/i',$html,$mips)){
for($i=0;$i<count($mips[0]);$i++){
$ips[$mips['ip'][$i].':'.$mips['port'][$i]]=array(
'ip'=>$mips['ip'][$i],
'port'=>$mips['port'][$i],
'user'=>$mips['user'][$i],
'pwd'=>$mips['pwd'][$i],
);
}
}
return $ips;
}
return null;
}
public function convert_format($format){
static $list=array();
$md5=md5($format);
if(!isset($list[$md5])){
$format=preg_replace('/\\\*([\'\/])/',"\\\\$1",$format);
$format=str_replace(array('[ip]','[端口]','[用户名]','[密码]','(*)')
,array('(?P<ip>(\d+\.){3}\d+)','(?P<port>\d+)','(?P<user>[^\s\\\'\"\<\>\,]*)','(?P<pwd>[^\s\\\'\"\<\>\,]*)','[\s\S]*?')
,$format);
$list[$md5]=$format;
}else{
$format=$list[$md5];
}
return $format;
}
public function ips_format2db($ipList,$default=array()){
$ipList=is_array($ipList)?$ipList:array();
$default=is_array($default)?$default:array();
foreach ($ipList as $k=>$ip){
if(empty($ip)||empty($ip['ip'])){
unset($ipList[$k]);
continue;
}
if(empty($ip['user'])){
$ip['user']=$default['user'];
$ip['pwd']=$default['pwd'];
}
$ip['ip']=$ip['ip'].':'.$ip['port'];
$ip['type']=$default['type'];
$ip['addtime']=NOW_TIME;
unset($ip['port']);
$ipList[$k]=$ip;
}
return $ipList;
}
private function add_api_ips(){
$config=$this->setting;
if(!is_array($config)||empty($config['api'])||empty($config['api']['open'])||!is_array($config['apis'])){
return;
}
foreach ($config['apis'] as $api){
if(empty($api['api_url'])||!preg_match('/^\w+\:\/\//',$api['api_url'])||empty($api['api_format'])){
continue;
}
$timeout=intval($api['api_interval']);
$timeout=$timeout>0?$timeout*60:60;
$cname=md5($api['api_url']);
$mcahce=CacheModel::getInstance('proxy_api');
if($mcahce->expire($cname,$timeout)){
$mcahce->setCache($cname, 1);
$html=get_html($api['api_url']);
$ips=$this->get_format_ips($html, $api['api_format'],true);
$ips = $this->ips_format2db ( $ips, array (
'type' => $api ['api_type']?$api ['api_type']:'',
'user' => $api ['api_user']?$api ['api_user']:'',
'pwd' => $api ['api_pwd']?$api ['api_pwd']:'',
) );
if(!empty($ips)){
$this->strict(false)->insertAll($ips,true,500);
}
}
}
}
}
?>

View File

@ -22,35 +22,35 @@ class Task extends BaseModel{
static $global_config=null;
if(!isset($global_config)){
$global_config=$GLOBALS['config'];
$global_config=$GLOBALS['_sc']['c'];
}
if(!empty($global_config['caiji']['download_img'])){
if(!empty($global_config['download_img']['download_img'])){
if($config['download_img']=='n'){
$GLOBALS['config']['caiji']['download_img']=0;
$GLOBALS['_sc']['c']['download_img']['download_img']=0;
}else{
$GLOBALS['config']['caiji']['download_img']=1;
$GLOBALS['_sc']['c']['download_img']['download_img']=1;
}
}else{
$GLOBALS['config']['caiji']['download_img']=0;
$GLOBALS['_sc']['c']['download_img']['download_img']=0;
}
if(!empty($global_config['proxy']['open'])){
if($config['proxy']=='n'){
$GLOBALS['config']['proxy']['open']=0;
$GLOBALS['_sc']['c']['proxy']['open']=0;
}else{
$GLOBALS['config']['proxy']['open']=1;
$GLOBALS['_sc']['c']['proxy']['open']=1;
}
}else{
$GLOBALS['config']['proxy']['open']=0;
$GLOBALS['_sc']['c']['proxy']['open']=0;
}
$GLOBALS['config']['caiji']['img_path']=empty($config['img_path'])?$global_config['caiji']['img_path']:$config['img_path'];
$GLOBALS['config']['caiji']['img_url']=empty($config['img_url'])?$global_config['caiji']['img_url']:$config['img_url'];
$GLOBALS['_sc']['c']['download_img']['img_path']=empty($config['img_path'])?$global_config['download_img']['img_path']:$config['img_path'];
$GLOBALS['_sc']['c']['download_img']['img_url']=empty($config['img_url'])?$global_config['download_img']['img_url']:$config['img_url'];
}
}

View File

@ -40,7 +40,7 @@ class User extends BaseModel{
*/
public static function right_pwd($pwd,$name='password'){
$return=array('name'=>$name);
if(!preg_match('/^[a-zA-Z0-9\!\@\#\$\%\^\&\*]{6,20}$/i', $pwd)){
if(!preg_match('/^[a-zA-Z0-9\`\~\!\@\#\$\%\^\*\(\)\-\_\+\=\|\{\}\[\]\:\;\,\.\?\&\'\"\<\>]{6,30}$/i', $pwd)){
$return['msg']=lang('user_error_password');
}else{
$return['success']=true;

View File

@ -22,7 +22,7 @@ class Usergroup extends BaseModel{
}
/*等级限制:判断当前用户组等级小于等于传入的等级*/
public function user_level_limit($level){
if($GLOBALS['user']['group']['level']<=$level){
if($GLOBALS['_sc']['user']['group']['level']<=$level){
return true;
}else{
return false;

View File

@ -75,8 +75,11 @@
</tr>
{/if}
<tr>
<th>社区论坛</th>
<td><a href="http://bbs.skycaiji.com" target="_blank">SkyCaiji交流社区</a></td>
<th>官方网站</th>
<td>
<a href="http://bbs.skycaiji.com" target="_blank">社区</a>&nbsp;
<a href="http://www.skycaiji.com" target="_blank">官网</a>
</td>
</tr>
<tr>
<th>清除缓存</th>
@ -114,7 +117,35 @@
</div>
</div>
</div>
<div id="skycaiji_admin_index">
{if !empty($systemWarning)}
<div class="callout callout-warning">
{if !empty($systemWarning['php'])}
请开启PHP模块{:implode(' , ',$systemWarning['php'])}<br/>
{/if}
{if !empty($systemWarning['path_write'])}
请设置可写权限:{:implode(' , ',$systemWarning['path_write'])}<br/>
{/if}
{if !empty($systemWarning['path_read'])}
请设置可读权限:{:implode(' , ',$systemWarning['path_read'])}<br/>
{/if}
</div>
{/if}
<div class="box box-default">
<div class="box-header with-border">
<h3 class="box-title" style="font-size:16px;">系统消息</h3>
<div class="box-tools pull-right">
<button class="btn btn-box-tool" id="refresh_admin_index"><i class="fa fa-refresh"></i></button>
</div>
</div>
<div class="box-body" id="skycaiji_admin_index" style="padding:0;">
{if !empty($adminIndexData)}
{$adminIndexData['html']}
{/if}
</div>
<div class="overlay" style="display:none;">
<i class="fa fa-refresh fa-spin"></i>
</div>
</div>
{/block}

View File

@ -0,0 +1,64 @@
{extend name="common:main" /}
{block name="cssjs"}
<script type="text/javascript" src="__PUBLIC__/static/js/chart.min.js?{$Think.config.html_v}"></script>
<script type="text/javascript" src="__PUBLIC__/static/js/admin/collected.js?{$Think.config.html_v}"></script>
<style type="text/css">
.chart-box{height:315px;padding-top:5px;padding-bottom:10px;}
</style>
{/block}
{block name="content"}
<div class="row">
<div class="col-md-8">
<div class="nav-tabs-custom" id="chart_date">
<ul class="nav nav-tabs">
<li class="active"><a href="javascript:;" data-chart-op="today">今日</a></li>
<li><a href="javascript:;" data-chart-op="this_month">本月</a></li>
<li><a href="javascript:;" data-chart-op="this_year">今年</a></li>
<li><a href="javascript:;" data-chart-op="years">全部</a></li>
</ul>
<div class="tab-content" style="padding-top:0;padding-bottom:0;">
<div class="tab-pane active chart-box">
<div class="overlay chart-loading" style="font-size:30px;text-align:center;margin-top:110px;">
<i class="fa fa-refresh fa-spin"></i>
</div>
<div class="chart"><canvas class="chart-canvas"></canvas></div>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="box box-primary" id="chart_release">
<div class="box-header with-border">
<h3 class="box-title">发布方式</h3>
</div>
<div class="box-body chart-box">
<div class="chart">
<canvas class="chart-canvas" style="display:none;"></canvas>
</div>
</div>
<div class="overlay chart-loading">
<i class="fa fa-refresh fa-spin"></i>
</div>
</div>
</div>
<div class="col-md-12">
<div class="box box-primary" id="chart_task">
<div class="box-header with-border">
<h3 class="box-title">任务</h3>
</div>
<div class="box-body chart-box">
<div class="chart">
<canvas class="chart-canvas" style="display:none;"></canvas>
</div>
</div>
<div class="overlay chart-loading">
<i class="fa fa-refresh fa-spin"></i>
</div>
</div>
</div>
</div>
<script type="text/javascript">
window.collectedClass.chart_init();
</script>
{/block}

View File

@ -12,7 +12,7 @@
</div>
<form id="form_list" method="post" ajax-submit="true" action="{:url('Collected/op')}">
<div class="table-responsive">
<table id="list_table" class="table table-bordered table-hover datatable">
<table id="list_table" class="table table-hover datatable">
<thead>
<tr>
<th width="60" class="chk">{$Think.lang.select}</th>
@ -46,13 +46,13 @@
<tfoot>
<tr>
<td class="chk"><label><input type="checkbox" id="chkall" onclick="checkall(this,'ids[]')" />全部</label></td>
<td colspan="4">
<td colspan="6">
<button type="button" class="btn btn btn-danger" id="deleteall">{$Think.lang.delete}</button>
</td>
</tr>
{if condition="!empty($pagenav)"}
<tr>
<td colspan="5">{$pagenav}</td>
<td colspan="6">{$pagenav}</td>
</tr>
{/if}
</tfoot>

View File

@ -8,6 +8,10 @@
<input type="hidden" name="module" value="{$taskData['module']}" />
<input type="hidden" name="tab_link" value="{:input('tab_link')}" />
<input type="hidden" name="effective" value="" />
{if input('?easymode')}
<input type="hidden" name="easymode" value="1" />
{/if}
{if condition="$taskData['module']=='pattern'"}
{include file="cpattern:set" /}
{elseif condition="$taskData['module']=='weixin'" /}

View File

@ -1,4 +1,4 @@
{if condition="!empty($GLOBALS['browser_is_old'])"}
{if condition="!empty($GLOBALS['_sc']['browser_is_old'])"}
<div class="alert alert-error alert-dismissible fade in" role="alert" style="position:fixed;top:0;z-index:9999;width:100%;">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
您的浏览器版本过低不能完全展现页面效果请使用谷歌、火狐或IE9及以上版本的浏览器

View File

@ -40,10 +40,9 @@
<script src="__PUBLIC__/addon/adminlte/fastclick.js?{$Think.config.html_v}"></script>
<!-- AdminLTE App -->
<script src="__PUBLIC__/adminlte/dist/js/adminlte.min.js?{$Think.config.html_v}"></script>
<script src="__PUBLIC__/static/js/bootbox.min.js?{$Think.config.html_v}"></script>
<!-- custom -->
<script src="__PUBLIC__/static/js/common.js?{$Think.config.html_v}"></script>
<script src="__PUBLIC__/static/js/admin.js?{$Think.config.html_v}"></script>
<link href="__PUBLIC__/static/css/admin.css?{$Think.config.html_v}" rel="stylesheet" type="text/css">
<script type="text/javascript" src="__PUBLIC__/static/js/langs/{php}echo defined('LANG_SET')?LANG_SET:config('DEFAULT_LANG');{/php}.js?{$Think.config.html_v}"></script>
<script type="text/javascript">var site_config={root:"__ROOT__",pub:"__PUBLIC__",clientinfo:"{$GLOBALS['clientinfo']}"};</script>
<script type="text/javascript">var site_config={root:"__ROOT__",pub:"__PUBLIC__",clientinfo:"{$GLOBALS['_sc']['clientinfo']}"};</script>

View File

@ -26,10 +26,10 @@
<li class="dropdown user user-menu">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
<span class="glyphicon glyphicon-user"></span>
<span>{$GLOBALS['user']['username']}</span>
<span>{$GLOBALS['_sc']['user']['username']}</span>
</a>
<ul class="dropdown-menu">
<li><a href="{:url('User/edit?uid='.$GLOBALS['user']['uid'])}">{$Think.lang.user_edit}</a></li>
<li><a href="{:url('User/edit?uid='.$GLOBALS['_sc']['user']['uid'])}">{$Think.lang.user_edit}</a></li>
<li><a href="{:url('Admin/Index/logout')}">{$Think.lang.logout}</a></li>
</ul>
</li>
@ -38,6 +38,7 @@
</nav>
</header>
{php}$curMenu=array(strtolower(request()->controller())=>' menu-open cur-menu');{/php}
{php}$curSubm=array(strtolower(request()->action())=>' menu-open cur-menu');{/php}
<aside class="main-sidebar">
<section class="sidebar">
<ul class="sidebar-menu" data-widget="tree">
@ -64,13 +65,13 @@
<ul class="treeview-menu">
<li><a href="{:url('Admin/Task/list')}"><i class="fa fa-circle-o"></i> {$Think.lang.task_list}</a></li>
<li><a href="{:url('Admin/Task/add')}"><i class="fa fa-circle-o"></i> {$Think.lang.task_add}</a></li>
<li class="treeview">
<li class="treeview{$curMenu['taskgroup']}">
<a href="#"><i class="fa fa-circle-o"></i> {$Think.lang.taskgroup}
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu" style="display:none;">
<ul class="treeview-menu">
<li><a href="{:url('Taskgroup/list')}"><i class="fa fa-circle-o"></i> {$Think.lang.taskgroup_list}</a></li>
<li><a href="{:url('Taskgroup/add')}"><i class="fa fa-circle-o"></i> {$Think.lang.taskgroup_add}</a></li>
</ul>
@ -95,7 +96,8 @@
</a>
<ul class="treeview-menu" style="display:block;">
<li><a href="{:url('Admin/Mystore/rule')}"><i class="fa fa-circle-o"></i> 采集规则</a></li>
<li><a href="{:url('Admin/Mystore/ReleaseApp')}"><i class="fa fa-circle-o"></i> 发布插件</a></li>
<li><a href="{:url('Admin/Mystore/releaseApp')}"><i class="fa fa-circle-o"></i> 发布插件</a></li>
<li><a href="{:url('Admin/Mystore/funcApp')}"><i class="fa fa-circle-o"></i> 函数插件</a></li>
<li><a href="{:url('Admin/Mystore/app')}"><i class="fa fa-circle-o"></i> 应用程序</a></li>
</ul>
</li>
@ -109,7 +111,8 @@
</span>
</a>
<ul class="treeview-menu">
<li><a href="{:url('Admin/Collected/list')}"><i class="fa fa-circle-o"></i> {$Think.lang.collected_list}</a></li>
<li><a href="{:url('Admin/Collected/list')}"><i class="fa fa-circle-o"></i> 数据列表</a></li>
<li><a href="{:url('Admin/Collected/chart')}"><i class="fa fa-circle-o"></i> 统计图表</a></li>
</ul>
</li>
<li class="treeview{$curMenu['user']}">
@ -131,27 +134,28 @@
</span>
</a>
<ul class="treeview-menu">
<li class="treeview">
<li class="treeview{$curMenu['develop']}">
<a href="#"><i class="fa fa-circle-o"></i> 开发
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu" style="display:none;">
<ul class="treeview-menu">
<li><a href="{:url('Admin/Develop/releaseCms')}"><i class="fa fa-circle-o"></i> CMS发布插件</a></li>
<li><a href="{:url('Admin/Develop/func')}"><i class="fa fa-circle-o"></i> 函数插件</a></li>
<li><a href="{:url('Admin/Develop/app')}"><i class="fa fa-circle-o"></i> 应用程序</a></li>
</ul>
</li>
<li><a href="{:url('Admin/Tool/fileManager')}"><i class="fa fa-circle-o"></i> 文件管理</a></li>
<li><a href="{:url('Admin/Tool/json_tree')}" target="_blank"><i class="fa fa-circle-o"></i> JSON解析</a></li>
<li><a href="{:url('Admin/Tool/logs')}"><i class="fa fa-circle-o"></i> 错误日志</a></li>
<li class="treeview">
<li class="treeview{$curSubm['checkfile']}{$curSubm['checkdb']}">
<a href="#"><i class="fa fa-circle-o"></i> 校验
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu" style="display:none;">
<ul class="treeview-menu">
<li><a href="{:url('Admin/Tool/checkfile')}"><i class="fa fa-circle-o"></i> 文件</a></li>
<li><a href="{:url('Admin/Tool/checkdb')}"><i class="fa fa-circle-o"></i> 数据库</a></li>
</ul>
@ -179,10 +183,10 @@
</aside>
<div class="content-wrapper">
<section class="content-header">
<h1>{$GLOBALS['content_header']}</h1>
<h1>{$GLOBALS['_sc']['p_name']}</h1>
<ol class="breadcrumb">
<li><a href="{:url('Admin/Backstage/index')}"><i class="fa fa-dashboard"></i> {$Think.lang.admincp}</a></li>
{$GLOBALS['breadcrumb']}
{$GLOBALS['_sc']['p_nav']}
</ol>
</section>
<section class="content">

View File

@ -0,0 +1,46 @@
{$html}
<!-- 以下为蓝天采集器代码 -->
<link rel="stylesheet" href="__PUBLIC__/static/css/cpattern_browser.css?{$Think.config.html_v}">
<script type="text/javascript" src="__PUBLIC__/jquery/jquery.min.js?{$Think.config.html_v}"></script>
<script type="text/javascript" src="__PUBLIC__/static/js/admin/cpattern_browser.js?{$Think.config.html_v}"></script>
<script type="text/javascript">
$(document).ready(function() {
window.skycaijiCB.init({$config|json_encode});
});
</script>
<div id="skycaiji_wrapper" style="display:none;">
<div id="skycaiji_console" style="display:none;">
<em class="skycaiji-close" title="关闭">×</em>
<div class="skycaiji-block">
<span class="skycaiji-b-l">当前元素的xpath</span>
<div class="skycaiji-b-c"><input skycaiji-id="xpath" /></div>
<div class="skycaiji-b-r">
<a href="javascript:;" skycaiji-id="show-xpath">显示</a> /
<a href="javascript:;" title="当前元素的所有属性" skycaiji-id="obj-prop">属性</a> /
<a href="javascript:;" title="清理界面" skycaiji-id="obj-clear">清理</a> /
<a href="javascript:;" title="当前元素的父元素" skycaiji-id="obj-parent">父元素</a> /
<a href="javascript:;" title="当前元素的子元素" skycaiji-id="obj-child">子元素</a>
</div>
</div>
<div class="skycaiji-block">
<span class="skycaiji-b-l">同类型元素xpath</span>
<div class="skycaiji-b-c">
<div skycaiji-id="box-listXpath"><input skycaiji-id="listXpath" /></div>
<select skycaiji-id="listXpaths" style="display:none;">
<option value="">请选择</option>
</select>
</div>
<div class="skycaiji-b-r">
<a href="javascript:;" skycaiji-id="show-listXpath">显示</a>
</div>
</div>
</div>
<div id="skycaiji_sidebar">
</div>
<div id="skycaiji_tips" style="display:none;">
</div>
</div>

View File

@ -0,0 +1,34 @@
{extend name="common:main_clean" /}
{block name="cssjs"}
<link rel="stylesheet" href="__PUBLIC__/static/css/cpattern_browser.css?{$Think.config.html_v}">
<script type="text/javascript" src="__PUBLIC__/jquery/jquery.min.js?{$Think.config.html_v}"></script>
<script type="text/javascript" src="__PUBLIC__/static/js/admin/cpattern_browser.js?{$Think.config.html_v}"></script>
<style type="text/css">
#json_tree{width:100%;overflow:hidden;}
#json_tree ul{list-style:none;margin:0px;padding:0px;padding-left:20px;}
#json_tree li{padding:0;margin:0;}
#json_tree .tree{cursor:pointer;margin-left:-16px;margin-right:2px;}
#json_tree .node{color:#7F007F;}
#json_tree .val{}
</style>
<script src="__PUBLIC__/static/js/admin/json_tree.js?{$Think.config.html_v}"></script>
{/block}
{block name="content"}
<div class="form-group" style="padding-top:10px;">
<label>抓取到JSON字符串</label>
<textarea id="txt_json" rows="3" class="form-control">{$jsonHtml}</textarea>
</div>
<label>JSON解析</label>
<div id="json_tree"></div>
<script type="text/javascript">
'use strict';//严格模式
$(document).ready(function(){
jsonTree.treeId='#json_tree';
jsonTree.treeClass='.tree';
jsonTree.load($('#txt_json').val());
});
</script>
{/block}

View File

@ -0,0 +1,31 @@
{extend name="common:main_clean" /}
{block name="cssjs"}
<link rel="stylesheet" href="__PUBLIC__/static/css/cpattern_easy.css?{$Think.config.html_v}">
<link rel="stylesheet" href="__PUBLIC__/static/css/introjs.css?{$Think.config.html_v}">
<script type="text/javascript" src="__PUBLIC__/static/js/intro.js?{$Think.config.html_v}"></script>
<script type="text/javascript" src="__PUBLIC__/static/js/admin/cpattern_easy.js?{$Think.config.html_v}"></script>
{/block}
{block name="content"}
<div id="wrapper">
<iframe id="ifr_collector" src="{:url('Collector/set?easymode=1&task_id='.$taskId)}"></iframe>
<div id="box_guide">
<input type="hidden" id="coll_id" value="{$collId}" />
<div class="input-group">
<div class="input-group-btn">
<button type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">新手引导 <span class="caret"></span></button>
<ul class="dropdown-menu">
<li><a href="javascript:;" onclick="cpatternEasy.start_coll_guide()">开始引导</a></li>
<li><a href="javascript:;" onclick="cpatternEasy.coll_goto_step(0,true)">重新引导</a></li>
</ul>
</div>
<input type="text" id="browser_url" class="form-control" placeholder="请输入网址" />
<span class="input-group-btn">
<button class="btn btn-primary" type="button" id="btn_browser">分析网页</button>
</span>
</div>
<div id="ifr_browser_box">
<iframe id="ifr_browser" name="ifr_browser"></iframe>
</div>
</div>
</div>
{/block}

View File

@ -121,11 +121,11 @@
<textarea name="field[words]" class="form-control" rows="3">{$field['words']}</textarea>
</div>
<div class="c-p-field-module" module="num" style="display:none;">
<div class="input-group col-sm-8" style="margin:0 auto;">
<div class="input-group">
<div class="input-group-addon">范围</div>
<input type="number" name="field[num_start]" class="form-control" value="{$field['num_start']?intval($field['num_start']):1}" />
<div class="input-group-addon"></div>
<input type="number" name="field[num_end]" class="form-control" value="{$field['num_end']?intval($field['num_end']):100}" />
<input type="number" name="field[num_start]" class="form-control" value="{:isset($field['num_start'])?intval($field['num_start']):1}" />
<div class="input-group-addon" style="border-left:0;border-right:0;"></div>
<input type="number" name="field[num_end]" class="form-control" value="{:isset($field['num_end'])?intval($field['num_end']):100}" />
</div>
</div>
<div class="c-p-field-module" module="time" style="display:none;">
@ -140,7 +140,7 @@
<div class="input-group">
<div class="input-group-addon">范围随机</div>
<input type="text" name="field[time_start]" class="form-control" placeholder="默认当前时间" />
<div class="input-group-addon"></div>
<div class="input-group-addon" style="border-left:0;border-right:0;"></div>
<input type="text" name="field[time_end]" class="form-control" placeholder="默认当前时间" />
<div class="input-group-btn"><button type="button" class="btn btn-default" onclick="$(this).parent().siblings('input:text').val('');">清空</button></div>
</div>

View File

@ -13,6 +13,7 @@
<option value="translate">{$Think.lang.process_module_translate}</option>
<option value="tool">{$Think.lang.process_module_tool}</option>
<option value="func">{$Think.lang.process_module_func}</option>
<option value="api">{$Think.lang.process_module_api}</option>
</select>
<span class="input-group-btn">
<button class="btn btn-default process-add" type="button">添加</button>

View File

@ -38,7 +38,7 @@
</div>
</div>
</div>
<p>其它标签可直接输入,用空格或逗号分隔</p>
<p class="help-block">其它标签可直接输入,用空格或逗号分隔</p>
</section>
</div>
<div class="c-p-process-module" module="replace">
@ -52,6 +52,7 @@
<p style="margin:5px 0;">替换成</p>
<div class="form-group">
<textarea data-process="replace:replace_to" rows="3" class="form-control"></textarea>
<p class="help-block">可使用<b>$数字</b>调用正则捕获组(不包括通配符)的内容</p>
</div>
</div>
<div class="c-p-process-module" module="filter">
@ -98,13 +99,13 @@
<tbody>
<tr class="p-m-if-table-tpl" style="display:none;">
<td>
<select data-process="if:if_logic" data-is-array="1" class="form-control">
<select data-process="if:if_logic:" class="form-control">
<option value="and">并且</option>
<option value="or">或者</option>
</select>
</td>
<td>
<select data-process="if:if_cond" data-is-array="1" class="form-control">
<select data-process="if:if_cond:" class="form-control">
<option value="has">包含</option>
<option value="nhas">不包含</option>
<option value="eq">等于</option>
@ -123,9 +124,9 @@
</select>
</td>
<td>
<input type="text" data-process="if:if_val" data-is-array="1" class="form-control" />
<input type="text" data-process="if:if_val:" class="form-control" />
<div class="input-group-btn p-m-if-time" style="display:none;">
<select class="form-control">
<select class="form-control p-m-if-time-val">
<option value="now">当前时间</option>
<option value="today">今天</option>
<option value="today +1 day">明天</option>
@ -148,23 +149,33 @@
<option value="last day of today +1 month">下月最后一天</option>
</select>
</div>
<div class="input-group-btn p-m-if-func" style="display:none;">
<select class="form-control">
<option value="">--请选择--</option>
{foreach $Think.config.allow_process_if as $k=>$v}
<option value="{$k}">{$k}{$v}</option>
{/foreach}
{if is_array($Think.config.EXTEND_PROCESS_IF)}
{foreach $Think.config.EXTEND_PROCESS_IF as $k=>$v}
<option value="{$k}">{$k}{$v}</option>
{/foreach}
{/if}
<div class="input-group p-m-if-func" style="display:none;">
<select data-process="if:if_addon:func:" class="form-control">
<option value="">--选择函数--</option>
<optgroup label="系统函数">
{foreach $Think.config.allow_process_if as $k=>$v}
<option value="{$k}">{$k}{$v}</option>
{/foreach}
{if is_array($Think.config.EXTEND_PROCESS_IF)}
{foreach $Think.config.EXTEND_PROCESS_IF as $k=>$v}
<option value="{$k}">{$k}{$v}</option>
{/foreach}
{/if}
</optgroup>
</select>
<a href="javascript:;" class="form-control"><span class="glyphicon glyphicon-info-sign"></span></a>
<span style="display:none;">
直接输入函数名(函数名开头可以加!取反),默认会传入字段值,如需传入多个参数,一行一个参数值,用###表示字段值
<br>出于安全考虑,如需扩展函数,请在根目录/data/config.php中添加配置'EXTEND_PROCESS_IF'=&gt;array('PHP函数名'=&gt;'描述')
</span>
<div class="input-group-btn">
<select data-process="if:if_addon:turn:" class="form-control">
<option value="">正常</option>
<option value="1">取反</option>
</select>
</div>
<a href="javascript:;" class="input-group-addon p-m-if-func-info"><span class="glyphicon glyphicon-info-sign"></span></a>
<div class="p-m-if-func-tips" style="display:none;">
先选择函数(取反可获取函数结果的相反值),默认会传入当前字段值
<br>如需传入多个参数,一行一个值,用###表示当前字段值
<br>如需扩展系统函数,请在根目录/data/config.php中添加配置'EXTEND_PROCESS_IF'=&gt;array('PHP函数名'=&gt;'描述')
<br>如需扩展插件函数,可以创建<a href="{:url('Develop/func')}" target="_blank">函数插件</a>
</div>
</div>
</td>
<td>
@ -178,48 +189,34 @@
</section>
</div>
<div class="c-p-process-module" module="translate">
{if empty($transApiLangs)}
<a href="{:url('Setting/Translate')}" target="_blank">请先开启并配置翻译接口</a>
{else/}
<div class="form-group">
<div class="input-group">
<select data-process="translate:translate_from" class="form-control">
<option value="">--源语言--</option>
<option value="zh">中文</option>
<option value="en">英语</option>
<option value="fra">法语</option>
<option value="jp">日语</option>
<option value="kor">韩语</option>
<option value="de">德语</option>
<option value="ru">俄语</option>
<option value="spa">西班牙语</option>
<option value="pt">葡萄牙语</option>
<option value="it">意大利语</option>
<option value="ara">阿拉伯语</option>
<option value="cht">繁体中文</option>
{foreach $transApiLangs as $k=>$v}
<option value="{$k}">{$v}</option>
{/foreach}
</select>
<span class="input-group-addon">翻译为</span>
<span class="input-group-addon" style="border-left:0;border-right:0;">翻译为</span>
<select data-process="translate:translate_to" class="form-control">
<option value="">--目标语言--</option>
<option value="zh">中文</option>
<option value="en">英语</option>
<option value="fra">法语</option>
<option value="jp">日语</option>
<option value="kor">韩语</option>
<option value="de">德语</option>
<option value="ru">俄语</option>
<option value="spa">西班牙语</option>
<option value="pt">葡萄牙语</option>
<option value="it">意大利语</option>
<option value="ara">阿拉伯语</option>
<option value="cht">繁体中文</option>
{foreach $transApiLangs as $k=>$v}
<option value="{$k}">{$v}</option>
{/foreach}
</select>
</div>
<p class="help-block">不支持自动识别,请设置源语言和目标语言</p>
</div>
<p class="help-block">不支持自动识别,必须指定源语言和目标语言</p>
{/if}
</div>
<div class="c-p-process-module" module="tool">
<div class="checkbox">
<label><input type="checkbox" data-process="tool:tool_list" value="trim" />去除前后空格</label>
&nbsp; <label><input type="checkbox" data-process="tool:tool_list" value="format" />清除文本格式去除html元素所有样式id、class、style等</label>
&nbsp; <label><input type="checkbox" data-process="tool:tool_list" value="is_img" />内容是图片链接</label>
&nbsp; <label title="如果字段的值是完整的url链接标记为图片链接后可将其图片本地化"><input type="checkbox" data-process="tool:tool_list" value="is_img" />将文本链接标记为图片链接</label>
</div>
</div>
<div class="c-p-process-module" module="batch">
@ -240,31 +237,114 @@
</div>
</div>
<div class="c-p-process-module" module="func">
<section>
<div class="form-group">
<label>PHP函数名</label>
<select data-process="func:func_name" class="form-control">
<option value="">--请选择--</option>
{foreach $Think.config.allow_process_func as $k=>$v}
<option value="{$k}">{$k}{$v}</option>
{/foreach}
{if is_array($Think.config.EXTEND_PROCESS_FUNC)}
{foreach $Think.config.EXTEND_PROCESS_FUNC as $k=>$v}
<option value="{$k}">{$k}{$v}</option>
{/foreach}
{/if}
<optgroup label="系统函数">
{foreach $Think.config.allow_process_func as $k=>$v}
<option value="{$k}">{$k}{$v}</option>
{/foreach}
{if is_array($Think.config.EXTEND_PROCESS_FUNC)}
{foreach $Think.config.EXTEND_PROCESS_FUNC as $k=>$v}
<option value="{$k}">{$k}{$v}</option>
{/foreach}
{/if}
</optgroup>
</select>
</div>
<div class="form-group">
<label>传入参数</label>
<textarea data-process="func:func_param" rows="2" class="form-control" placeholder="默认###传入当前字段的值"></textarea>
<p class="help-block">
一行一个值,使用###表示当前字段的值,请按函数传参,否则运行出错!<a href="javascript:;" onclick="$(this).siblings('span').show();">扩展函数</a>
<textarea data-process="func:func_param" rows="2" class="form-control" placeholder="默认传入当前字段的值"></textarea>
<div class="help-block">
一行一个值,可输入任何内容或
<div class="dropdown p-m-func-fields" style="display:inline;">
<a class="dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
调用字段值
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="javascript:;" data-val="###">###表示当前字段</a></li>
</ul>
</div>
,请按函数传参,否则运行出错!<a href="javascript:;" onclick="$(this).siblings('span').show();">扩展函数</a>
<span style="display:none;">
<br>
出于安全考虑,如需扩展函数,请在根目录/data/config.php中添加配置
<br>如需扩展系统函数,请在根目录/data/config.php中添加配置
'EXTEND_PROCESS_FUNC'=&gt;array('PHP函数名'=&gt;'描述')
<br>如需扩展插件函数,可以创建<a href="{:url('Develop/func')}" target="_blank">函数插件</a>
</span>
</p>
</div>
</div>
</section>
</div>
<div class="c-p-process-module" module="api">
<section>
<div class="form-group">
<label>接口地址</label>
<input type="text" data-process="api:api_url" class="form-control" />
<p class="help-block">/开头自动补全为{:config('root_website')}/</p>
</div>
<div class="form-group">
<label>请求方式</label>
<select data-process="api:api_type" class="form-control">
<option value="">GET</option>
<option value="post">POST</option>
</select>
</div>
<div class="form-group">
<label>请求参数</label>
<a href="javascript:;" class="glyphicon glyphicon-plus p-m-api-add" title="添加"></a>
<div class="table-responsive">
<table class="table table-bordered table-hover p-m-api-table" style="margin-bottom:0;">
<thead>
<tr>
<th>名称</th>
<th></th>
<th style="width:50px;">删除</th>
</tr>
</thead>
<tbody>
<tr class="p-m-api-table-tpl" style="display:none;">
<td>
<input type="text" data-process="api:api_params:name:" class="form-control">
</td>
<td>
<div class="input-group">
<div class="input-group-btn">
<select data-process="api:api_params:val:" class="form-control" style="min-width:110px;">
<option value=""></option>
<option value="field">当前字段的值</option>
<option value="timestamp">当前时间戳</option>
<option value="time">当前日期</option>
<option value="custom">自定义</option>
</select>
</div>
<input type="text" data-process="api:api_params:addon:" class="form-control" style="display:none;margin-left:-1px;">
</div>
</td>
<td>
<a href="javascript:;" class="glyphicon glyphicon-remove p-m-api-del" style="margin-top:8px;"></a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="form-group">
<label>提取结果</label>
<input type="text" data-process="api:api_json" class="form-control" />
<p class="help-block">json规则 a.b.c 通配符 *</p>
</div>
<div class="form-group">
<label>结果是数组则转换为</label>
<select data-process="api:api_json_arr" class="form-control">
<option value="implode">字符串</option>
<option value="jsonencode">json编码</option>
<option value="serialize">序列化</option>
</select>
<textarea data-process="api:api_json_implode" class="form-control" rows="1" placeholder="输入分隔符" style="margin-top:5px;"></textarea>
</div>
</section>
</div>
</div>

View File

@ -5,10 +5,10 @@
<li><a href="#coll_pattern_field" data-toggle="tab">获取内容</a></li>
{if condition="!empty($collData)"}
<li class="dropdown nav-save2store">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">保存规则 <span class="caret"></span></a>
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">另存为 <span class="caret"></span></a>
<ul class="dropdown-menu dropdown-menu-right">
<li><a href="{:url('Collector/save2store?coll_id='.$collData['id'])}" title="云端存储,下载规则更方便!" onclick="windowModal('保存到云端',$(this).attr('href'));return false;">上传至云端</a></li>
<li><a href="{:url('Collector/export?coll_id='.$collData['id'])}" target="_blank">导出至本地</a></li>
<li><a href="{:url('Collector/export?coll_id='.$collData['id'])}" target="_blank">导出至本地</a></li>
<li><a href="{:url('Collector/save2store?coll_id='.$collData['id'])}" title="云端存储,保存规则更方便!" onclick="windowModal('保存到云端',$(this).attr('href'));return false;">上传至云端</a></li>
</ul>
</li>
{/if}
@ -62,7 +62,7 @@
<label class="radio-inline"><input type="radio" name="config[page_render]" value="1"> </label>
<label class="radio-inline"><input type="radio" name="config[page_render]" value="0"> </label>
</div>
<p class="help-block">需先配置<a href="{:url('Setting/page_render')}">页面渲染</a>可自动加载ajax内容</p>
<p class="help-block">需先配置<a href="{:url('Setting/page_render')}">页面渲染</a>可自动加载ajax内容注意渲染后的html源码与未渲染时的不相同原先的规则可能会失效</p>
</div>
</div>
</div>
@ -114,9 +114,9 @@
<label class="control-label">自定义</label>
<a href="javascript:;" class="glyphicon glyphicon-plus add-request-header" title="添加"></a>
</div>
<div class="form-group">
<div class="">
<div class="table-responsive">
<table class="table table-hover c-p-request-headers">
<table class="table table-bordered c-p-request-headers">
<thead>
<tr>
<th class="col-xs-4">名称</th>
@ -129,6 +129,14 @@
</table>
</div>
</div>
<div class="form-group">
<label class="control-label">下载图片使用请求头</label>
<div class="input-group">
<label class="radio-inline"><input type="radio" name="config[request_headers][download_img]" value="1"> </label>
<label class="radio-inline"><input type="radio" name="config[request_headers][download_img]" value="0"> </label>
</div>
<p class="help-block">下载图片时是否使用该请求头设置</p>
</div>
</div>
</div>
</div>
@ -139,7 +147,7 @@
<div class="panel-body">
<div class="form-group">
<label class="control-label">起始网址</label>
<a href="javascript:;" class="glyphicon glyphicon-plus" title="添加"></a>
<a href="javascript:;" class="glyphicon glyphicon-plus add-source-url" title="添加"></a>
<a href="javascript:;" class="glyphicon glyphicon-trash" title="清空"></a>
</div>
<div class="c-p-source-urls">
@ -177,7 +185,7 @@
<a href="javascript:;" class="glyphicon glyphicon-plus add-level-url" title="添加"></a>
</div>
<div class="table-responsive">
<table id="c_p_level_urls" class="table table-bordered table-hover">
<table id="c_p_level_urls" class="table table-hover">
<thead>
<tr>
<th>级别</th>
@ -363,7 +371,7 @@
<a href="javascript:;" class="glyphicon glyphicon-plus add-relation-url" title="添加"></a>
</div>
<div class="table-responsive">
<table id="c_p_relation_urls" class="table table-bordered table-hover">
<table id="c_p_relation_urls" class="table table-hover">
<thead>
<tr>
<th>名称</th>
@ -403,7 +411,7 @@
<a href="javascript:;" onclick="c_pattern.add_default_fields()" style="float:right;font-weight:normal;">添加默认</a>
</div>
<div class="table-responsive">
<table class="table table-bordered table-hover c-p-field-list" style="margin-bottom:10px;">
<table class="table table-hover c-p-field-list" style="margin-bottom:10px;">
<thead>
<tr>
<th>字段</th>
@ -570,6 +578,75 @@
{/if}
</div>
</div>
<div style="display:none;">
<table>
<tr id="coll_tpl_request_headers">
<td><input type="text" data-name="config[request_headers][custom_names][]" class="form-control" /></td>
<td><input type="text" data-name="config[request_headers][custom_vals][]" class="form-control" /></td>
<td><a href="javascript:;" class="glyphicon glyphicon-remove delete-request-header"></a></td>
</tr>
<tr id="coll_tpl_url_posts">
<td><input type="text" data-name="config[url_posts][names][]" class="form-control" /></td>
<td><input type="text" data-name="config[url_posts][vals][]" class="form-control" /></td>
<td><a href="javascript:;" class="glyphicon glyphicon-remove delete-url-post"></a></td>
</tr>
<tr id="coll_tpl_level_url">
<td><span class="level"></span></td>
<td><a href="javascript:;" class="name"></a></td>
<td>
<input type="hidden" data-name="config[level_urls][]" />
<a href="javascript:;" class="delete">删除</a>
<a href="javascript:;" class="glyphicon glyphicon-arrow-up" style="font-size:12px;"></a>
<a href="javascript:;" class="glyphicon glyphicon-arrow-down" style="font-size:12px;"></a>
</td>
</tr>
<tr id="coll_tpl_relation_url">
<td><a href="javascript:;" class="name"></a></td>
<td class="page"></td>
<td>
<input type="hidden" data-name="config[relation_urls][]" />
<a href="javascript:;" class="delete">删除</a>
<a href="javascript:;" class="glyphicon glyphicon-arrow-up" style="font-size:12px;"></a>
<a href="javascript:;" class="glyphicon glyphicon-arrow-down" style="font-size:12px;"></a>
</td>
</tr>
<tr id="coll_tpl_field">
<td class="field-name"></td>
<td class="field-source"></td>
<td class="field-module"></td>
<td>
<input type="hidden" data-name="config[field_list][]" />
<input type="hidden" data-name="config[field_process][]" />
<a href="javascript:;" class="field-process">数据处理</a>
<a href="javascript:;" class="glyphicon glyphicon-arrow-up" style="font-size:12px;"></a>
<a href="javascript:;" class="glyphicon glyphicon-arrow-down" style="font-size:12px;"></a>
<a href="javascript:;" class="glyphicon glyphicon-remove field-del" style="font-size:12px;"></a>
</td>
<td><label class="radio-inline"><input type="radio" data-name="config[field_title]">绑定</label></td>
</tr>
</table>
<div id="coll_tpl_process" class="panel panel-default">
<div class="panel-heading">
<div class="panel-title" style="font-size:14px;overflow:hidden;">
<a data-toggle="collapse" style="float:left;"></a>
<div class="panel-title-title" style="float:left;">
<a data-toggle="collapse" style="color:inherit;"></a>
<input type="text" style="display:none;border-radius:2px;border:1px solid #ccc;line-height:16px;margin-left:2px;padding:1px 1px 1px 2px;" />
</div>
<div style="float:right;">
<a href="javascript:;" class="glyphicon glyphicon-tags" title="标题"></a>&nbsp;
<a href="javascript:;" class="glyphicon glyphicon-arrow-up"></a>
<a href="javascript:;" class="glyphicon glyphicon-arrow-down"></a>
<a href="javascript:;" class="glyphicon glyphicon-remove" onclick="c_pattern.process_op('delete',{obj:this})"></a>
</div>
</div>
</div>
<div class="panel-collapse collapse">
<div class="panel-body">
</div>
</div>
</div>
</div>
<link href="__PUBLIC__/static/css/jquery.datetimepicker.css" rel="stylesheet">
<script type="text/javascript" src="__PUBLIC__/static/js/jquery.datetimepicker.js"></script>
<script type="text/javascript">
@ -579,5 +656,4 @@ c_pattern.init();
{if condition="!empty($collData['config'])"}
c_pattern.load({$collData['config']|json_encode});
{/if}
</script>

View File

@ -9,7 +9,7 @@
<input type="hidden" name="sub" value="1" />
<input type="hidden" name="source[type]" value="custom" />
<input type="hidden" name="source[uid]" value="{$source['uid']}" />
<ul class="nav nav-tabs">
<ul class="nav nav-tabs c-p-source-tab">
<li class="active"><a href="#tab_custom" data-toggle="tab" source-type="custom">手工指定</a></li>
<li class=""><a href="#tab_batch" data-toggle="tab" source-type="batch">批量生成</a></li>
<li class=""><a href="#tab_large" data-toggle="tab" source-type="large">大量网址</a></li>

View File

@ -16,13 +16,13 @@
<ul class="dropdown-menu">
<li><a href="javascript:;" data-test="get_fields">抓取字段</a></li>
<li><a href="javascript:;" data-test="get_html">抓取源码</a></li>
<li><a href="javascript:;" data-test="elements">分析元素</a></li>
<li><a href="javascript:;" data-test="elements">分析网页</a></li>
<li><a href="javascript:;" data-test="get_paging_urls">抓取分页</a></li>
<li><a href="javascript:;" data-test="get_relation_urls">抓取关联页</a></li>
</ul>
</div>
{if condition="!empty($url_post)"}
<div class="input-group-addon" style="color:green;">POST模式</div>
<div class="input-group-addon" style="color:green;border-right:0;">POST模式</div>
{/if}
<input type="text" class="form-control" name="url" value="{$cont_url}" placeholder="输入内容页网址" />
<div class="input-group-btn"><button type="button" class="btn btn-default test-sub">确定</button></div>
@ -83,11 +83,11 @@ function win_test_view(id){
$("#ifm_test_view").contents().find('body').html(html);
}
//分析元素
//分析网页
function test_elements(id){
var cont_url=$('#win_test_cont_url input[name="url"]').val();
var url="{:url('Cpattern/test?op=_op_&coll_id='.$collData['id'].'&cont_url=_url_')}";
url=url.replace('_op_','elements').replace('_url_',encodeURIComponent(cont_url));
var url="{:url('Cpattern/browser?coll_id='.$collData['id'].'&url=_url_')}";
url=url.replace('_url_',encodeURIComponent(cont_url));
window.open(url,'_blank');
}
//下拉选择
@ -147,7 +147,7 @@ $('#win_test_cont_url button.test-sub').bind('click',function(){
}else{
var eleId=generateUUID();
data=data.replace(/\</g,'&lt;').replace(/\>/g,'&gt;');//编码
var html='<label>源码:</label><a href="javascript:;" onclick="test_elements()">分析元素</a><textarea id="'
var html='<label>源码:</label><a href="javascript:;" onclick="test_elements()">分析网页</a><textarea id="'
+eleId+'" class="form-control" rows="20">'+data+'</textarea>';
$('#win_test_cont_url .vals').html(html);
}
@ -230,6 +230,15 @@ $('#win_test_cont_url button.test-sub').bind('click',function(){
}
}
});
//回车测试
$('#win_test_cont_url input[name="url"]').bind('keyup',function(event){
  if(event.keyCode=="13"){
$('#win_test_cont_url button').trigger("click");
  }
});
if($('#win_test_cont_url input[name="url"]').val().length>0){
//有网址自动触发
$('#win_test_cont_url button').trigger("click");

View File

@ -19,14 +19,14 @@
{foreach $urls as $url}
<li>
[<a href="javascript:;" class="cont_ceshi" url="{$url}">测试</a>]
[<a href="javascript:;" class="cont_element" url="{$url}">元素</a>]
[<a href="javascript:;" class="cont_element" url="{$url}">分析</a>]
{$url}
</li>
{/foreach}
{else /}
<li>
[<a href="javascript:;" class="cont_ceshi" url="{$urls}">测试</a>]
[<a href="javascript:;" class="cont_element" url="{$urls}">元素</a>]
[<a href="javascript:;" class="cont_element" url="{$urls}">分析</a>]
{$urls}
</li>
{/if}
@ -64,40 +64,46 @@ $(document).ready(function(){
get_cont_urls(source_url,$(this),0);
{/if}
{/if}
});
//测试
$('#test_source_urls').on('click','.cont_ceshi',function(){
var test_cont_url="{:url('Cpattern/test?op=cont_url&coll_id='.$collData['id'])}&cont_url=_url_";
test_cont_url=test_cont_url.replace('_url_',encodeURIComponent($(this).attr('url')));
var urls={};
$(this).parents('.source_url').each(function(){
var surl=$(this).attr('url');
if(surl){
if($(this).attr('level')){
//是级别
urls['level_'+$(this).attr('level')]=surl;
}else{
//是起始页
urls['source_url']=surl;
}
}
});
if(urls){
//加上多级和起始网址
for(var i in urls){
test_cont_url+='&'+i+'='+encodeURIComponent(urls[i]);
//测试
$('#test_source_urls').on('click','.cont_ceshi',function(){
var test_cont_url="{:url('Cpattern/test?op=cont_url&coll_id='.$collData['id'])}&cont_url=_url_";
test_cont_url=test_cont_url.replace('_url_',encodeURIComponent($(this).attr('url')));
var urls={};
$(this).parents('.source_url').each(function(){
var surl=$(this).attr('url');
if(surl){
if($(this).attr('level')){
//是级别
urls['level_'+$(this).attr('level')]=surl;
}else{
//是起始页
urls['source_url']=surl;
}
}
window.open(test_cont_url,'_test_cont');
});
//元素
$('#test_source_urls').on('click','.cont_element',function(){
var ele_cont_url="{:url('Cpattern/test?op=elements&coll_id='.$collData['id'])}&cont_url=_url_";
ele_cont_url=ele_cont_url.replace('_url_',encodeURIComponent($(this).attr('url')));
window.open(ele_cont_url,'_test_cont');
});
if(urls){
//加上多级和起始网址
for(var i in urls){
test_cont_url+='&'+i+'='+encodeURIComponent(urls[i]);
}
}
window.open(test_cont_url,'_blank');
});
//分析
$('#test_source_urls').on('click','.cont_element',function(){
if((/\beasymode\s*\=/i).test(window.self.location.href)&&window.top){
//简单模式
window.top.postMessage('browser_url:'+$(this).attr('url'),'*');
}else{
var ele_cont_url="{:url('Cpattern/browser?coll_id='.$collData['id'])}&url=_url_";
ele_cont_url=ele_cont_url.replace('_url_',encodeURIComponent($(this).attr('url')));
window.open(ele_cont_url,'_blank');
}
});
//展开收起
$('#test_source_urls').on('click','.cont_urls_num a',function(){
var status=$(this).attr('status');
@ -150,7 +156,7 @@ $(document).ready(function(){
//无级别,显示测试网址
for(var i in urls){
list+='<li>[<a href="javascript:;" class="cont_ceshi" url="'+urls[i]+'">测试</a>] '
+'[<a href="javascript:;" class="cont_element" url="'+urls[i]+'">元素</a>] '+urls[i]+'</li>';
+'[<a href="javascript:;" class="cont_element" url="'+urls[i]+'">分析</a>] '+urls[i]+'</li>';
}
list+='</ul>';

View File

@ -0,0 +1,83 @@
{extend name="common:main" /}
{block name="cssjs"}
<script type="text/javascript" src="__PUBLIC__/static/js/admin/develop.js?{$Think.config.html_v}"></script>
{/block}
{block name="content"}
<div class="box box-default">
<div class="box-body">
<form id="form_func" method="post" ajax-submit="true" action="{:url('Admin/Develop/func')}">
{if !empty($funcClass)}
<input type="hidden" name="edit" value="1" />
<input type="hidden" name="app" value="{$funcClass['app']}" />
<div class="alert alert-warning">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
请在 {$funcClass['filename']} 文件中编辑代码
</div>
{/if}
<div class="form-group">
<label>模块</label>
<select name="module" class="form-control">
<option value="">请选择</option>
{foreach $modules as $k=>$v}
<option value="{$k}">{$v['name']}{$v['loc']}</option>
{/foreach}
</select>
</div>
<div class="form-group">
<label>插件名称</label>
<input type="text" name="name" class="form-control">
<p class="help-block">精简描述该插件</p>
</div>
<div class="form-group">
<label>功能标识</label>
<input type="text" name="identifier" class="form-control">
<p class="help-block">表示该插件的作用,只能输入字母或数字</p>
</div>
<div class="form-group">
<label>作者版权</label>
<input type="text" name="copyright" class="form-control">
<p class="help-block">版权归属能有效区分他人开发的插件,只能输入字母或数字</p>
</div>
{if !empty($funcClass)}
<div class="form-group">
<label>类的方法(方法名:注释说明)</label>
<ul>
{foreach $funcClass['methods'] as $k=>$v}
<li>{$k}{$v['comment']}</li>
{/foreach}
</ul>
<p class="help-block">如需编辑方法请在插件文件中修改仅获取public方法注释必须在方法的前一行且以/**开头,/*//都获取不到注释</p>
</div>
{else /}
<div class="form-group">
<div class="h-title">
<label class="control-label">方法</label>
<a href="javascript:;" id="add_method" class="glyphicon glyphicon-plus" title="添加"></a>
</div>
<div class="table-responsive">
<table class="table table-hover method_list">
<thead>
<tr>
<th class="col-xs-4">方法名</th>
<th class="col-xs-6">描述</th>
<th class="col-xs-2">删除</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<p class="help-block">类的方法名必须符合php命名规范</p>
</div>
{/if}
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block">{$Think.lang.save}</button>
</div>
</form>
</div>
</div>
<script type="text/javascript">
developClass.func({$funcClass|json_encode});
</script>
{/block}

View File

@ -18,7 +18,7 @@
<input type="text" name="username" class="form-control" placeholder="{$Think.lang.find_pwd_username}" />
</div>
</div>
{if condition="$GLOBALS['config']['site']['verifycode']"}
{if condition="$GLOBALS['_sc']['c']['site']['verifycode']"}
<div class="form-group">
<div class="input-group">
<input type="text" name="verifycode" class="form-control" placeholder="{$Think.lang.verifycode}" />

View File

@ -26,7 +26,7 @@
<input type="password" name="password" class="form-control" placeholder="{$Think.lang.user_password}">
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
</div>
{if condition="$GLOBALS['config']['site']['verifycode']"}
{if condition="$GLOBALS['_sc']['c']['site']['verifycode']"}
<div class="form-group">
<div class="input-group">
<input type="text" name="verifycode" class="form-control" placeholder="{$Think.lang.verifycode}" />

View File

@ -17,7 +17,7 @@
操作
<span class="sep">|</span>
<div class="checkbox-inline">
<input type="checkbox" id="auto_check" {:empty($GLOBALS['config']['store_auto_check_app'])?'':'checked="checked"'} value="1" title="刷新页面时自动检测" style="margin-left:-17px;" />
<input type="checkbox" id="auto_check" {:empty($GLOBALS['_sc']['c']['store_auto_check_app'])?'':'checked="checked"'} value="1" title="刷新页面时自动检测" style="margin-left:-17px;" />
<a href="javascript:;" id="btn_check" style="color:#333;">检测更新</a>
</div>
</th>

View File

@ -0,0 +1,94 @@
{extend name="common:main" /}
{block name="cssjs"}
<script src="__PUBLIC__/static/js/admin/store.js?{$Think.config.html_v}"></script>
<script src="__PUBLIC__/static/js/admin/mystore.js?{$Think.config.html_v}"></script>
{/block}
{block name="content"}
{php}$orderClass=array($orderKey=>'_'.$sortBy);$orderSort=array($orderKey=>($sortBy=='asc'?'升序':'倒序'));{/php}
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li><a href="{:url('Mystore/rule')}">采集规则</a></li>
<li><a href="{:url('Mystore/releaseApp')}">发布插件</a></li>
<li class="active"><a href="{:url('Mystore/funcApp')}">函数插件</a></li>
<li class="nav-check-update">
<a href="javascript:;" onclick="check_funcapp_update()">检测更新</a>
<input type="checkbox" id="auto_check" {:empty($GLOBALS['_sc']['c']['store_auto_check_plugin'])?'':'checked="checked"'} value="1" title="刷新页面时自动检测" />
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active">
<div class="table-responsive">
<form id="form_list" method="post" ajax-submit="true" action="{:url('Mystore/funcAppOp')}">
<table id="list_table" class="table table-hover datatable">
<thead>
<tr>
<th class="chk">{$Think.lang.select}</th>
<th class="sorting{$orderClass['app']}" data-order="app" title="类名{$orderSort['app']}">类和方法</th>
<th class="sorting{$orderClass['name']}" data-order="name" title="名称{$orderSort['name']}">名称</th>
<th class="sorting{$orderClass['module']}" data-order="module" title="模块{$orderSort['module']}">模块</th>
<th class="sorting{$orderClass['addtime']}" data-order="addtime" title="添加时间{$orderSort['addtime']}">添加时间</th>
<th class="sorting{$orderClass['uptime']}" data-order="uptime" title="更新时间{$orderSort['uptime']}">更新时间</th>
<th>平台</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{foreach name="appList" item="app"}
<tr data-app-id="{$app['id']}">
<td class="chk"><input type="checkbox" name="ids[]" value="{$app['id']}" /></td>
<td class="dropdown methods">
<a href="javascript:;" class="dropdown-toggle" id="dm_{$app['app']}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">{$app['app']} <span class="caret"></span></a>
<ul class="dropdown-menu" aria-labelledby="dm_{$app['app']}">
</ul>
</td>
<td>{$app['name']}</td>
<td>{$modules[$app['module']]['name']}</td>
<td>{:date('Y-m-d H:i',$app['addtime'])}</td>
<td>{:date('Y-m-d H:i',$app['uptime'])}</td>
<td class="store-info">
<a href="{$app['store_url']}" data-is-store-url="1" class="store-detail">
{if empty($app['provider_id'])}
官方
{else /}
第三方
{/if}
</a>
</td>
<td>
<a href="javascript:;" class="enable" style="color:{$app['enable']?'green':'red'}">{$app['enable']?'已启用':'已禁用'}</a>
&nbsp;<a href="{:url('Develop/func?app='.$app['app'])}">开发</a>
&nbsp;<a href="javascript:;" class="delete">删除</a>
</td>
</tr>
{/foreach}
</tbody>
<tfoot>
<tr>
<td class="chk"><label><input type="checkbox" id="chkall" onclick="checkall(this,'ids[]')" />全部</label></td>
<td colspan="2">
<button type="button" class="btn btn btn-danger" id="deleteall">{$Think.lang.delete}</button>
&nbsp;<a href="{:url('Develop/func')}" class="btn btn btn-success">开发一个</a>
</td>
<td colspan="5" style="text-align:right;font-size:12px;">
{if !empty($appList)}
<p class="help-block"> “任务 &gt; 采集器设置 &gt; 获取内容 &gt; 数据处理 &gt; 使用函数或条件判断” 中使用</p>
{/if}
</td>
</tr>
{if condition="!empty($pagenav)"}
<tr>
<td colspan="8">{$pagenav}</td>
</tr>
{/if}
</tfoot>
</table>
</form>
</div>
</div>
</div>
</div>
<script type="text/javascript">
init_funcapp();
</script>
{/block}

View File

@ -7,18 +7,19 @@
{php}$orderClass=array($orderKey=>'_'.$sortBy);$orderSort=array($orderKey=>($sortBy=='asc'?'升序':'倒序'));{/php}
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li><a href="{:url('Mystore/Rule')}">采集规则</a></li>
<li class="active"><a href="{:url('Mystore/ReleaseApp')}">发布插件</a></li>
<li><a href="{:url('Mystore/rule')}">采集规则</a></li>
<li class="active"><a href="{:url('Mystore/releaseApp')}">发布插件</a></li>
<li><a href="{:url('Mystore/funcApp')}">函数插件</a></li>
<li class="nav-check-update">
<a href="javascript:;" onclick="check_releaseapp_update()">检测更新</a>
<input type="checkbox" id="auto_check" {:empty($GLOBALS['config']['store_auto_check_plugin'])?'':'checked="checked"'} value="1" title="刷新页面时自动检测" />
<input type="checkbox" id="auto_check" {:empty($GLOBALS['_sc']['c']['store_auto_check_plugin'])?'':'checked="checked"'} value="1" title="刷新页面时自动检测" />
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active">
<div class="table-responsive">
<form id="form_list" method="post" ajax-submit="true" action="{:url('Mystore/releaseAppOp')}">
<table id="list_table" class="table table-bordered table-hover datatable">
<table id="list_table" class="table table-hover datatable">
<thead>
<tr>
<th class="chk">{$Think.lang.select}</th>
@ -56,10 +57,15 @@
<tfoot>
<tr>
<td class="chk"><label><input type="checkbox" id="chkall" onclick="checkall(this,'ids[]')" />全部</label></td>
<td colspan="7">
<td colspan="2">
<button type="button" class="btn btn btn-danger" id="deleteall">{$Think.lang.delete}</button>
&nbsp;<a href="{:url('Develop/releaseCms')}" class="btn btn btn-success">开发一个</a>
</td>
<td colspan="5" style="text-align:right;font-size:12px;">
{if !empty($appList)}
<p class="help-block"> “任务 &gt; 发布设置 &gt; 本地CMS程序” 中使用</p>
{/if}
</td>
</tr>
{if condition="!empty($pagenav)"}
<tr>

View File

@ -7,18 +7,19 @@
{php}$orderClass=array($orderKey=>'_'.$sortBy);$orderSort=array($orderKey=>($sortBy=='asc'?'升序':'倒序'));{/php}
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li class="active"><a href="{:url('Mystore/Rule')}">采集规则</a></li>
<li><a href="{:url('Mystore/ReleaseApp')}">发布插件</a></li>
<li class="active"><a href="{:url('Mystore/rule')}">采集规则</a></li>
<li><a href="{:url('Mystore/releaseApp')}">发布插件</a></li>
<li><a href="{:url('Mystore/funcApp')}">函数插件</a></li>
<li class="nav-check-update">
<a href="javascript:;" onclick="check_rules_update()">检测更新</a>
<input type="checkbox" id="auto_check" {:empty($GLOBALS['config']['store_auto_check_rule'])?'':'checked="checked"'} value="1" title="刷新页面时自动检测" />
<input type="checkbox" id="auto_check" {:empty($GLOBALS['_sc']['c']['store_auto_check_rule'])?'':'checked="checked"'} value="1" title="刷新页面时自动检测" />
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active">
<div class="table-responsive">
<form id="form_list" method="post" ajax-submit="true" action="{:url('Mystore/ruleOp')}">
<table id="list_table" class="table table-bordered table-hover datatable">
<table id="list_table" class="table table-hover datatable">
<thead>
<tr>
<th class="chk">{$Think.lang.select}</th>
@ -54,8 +55,11 @@
<tfoot>
<tr>
<td class="chk"><label><input type="checkbox" id="chkall" onclick="checkall(this,'ids[]')" />全部</label></td>
<td colspan="6">
<button type="button" class="btn btn btn-danger" id="deleteall">{$Think.lang.delete}</button>
<td><button type="button" class="btn btn-danger" id="deleteall">{$Think.lang.delete}</button></td>
<td colspan="5" style="text-align:right;font-size:12px;">
{if !empty($ruleList)}
<p class="help-block"> “编辑任务 &gt; 导入规则 &gt; 已下载规则” 中使用</p>
{/if}
</td>
</tr>
{if condition="!empty($pagenav)"}

View File

@ -39,7 +39,7 @@
</tbody>
<tfoot>
<tr>
<td colspan="3">
<td colspan="5">
<button type="submit" class="btn btn-default" id="btn_save">保存</button>
<a href="javascript:;" class="btn btn-primary" id="btn_add">添加</a>
</td>

View File

@ -0,0 +1,37 @@
<form id="win_form_proxy_add" method="post" action="{:url('Admin/Proxy/add')}">
&nbsp;<a href="javascript:;" class="glyphicon glyphicon-plus add-proxy-ip">添加一行</a>
<div class="table-responsive">
<table class="table table-hover datatable proxy-ip-list">
<thead>
<tr>
<th>IP带端口</th>
<th>用户名(选填)</th>
<th>密码(选填)</th>
<th>类型</th>
<th>{$Think.lang.op}</th>
</tr>
</thead>
<tbody>
<tr class="tpl-proxy-ip">
<td class="p-ip"><input type="text" name="ip_list[]" class="form-control" /></td>
<td><input type="text" name="user_list[]" class="form-control" /></td>
<td><input type="text" name="pwd_list[]" class="form-control" /></td>
<td>
<select name="type_list[]" class="form-control" style="width:95px;">
{foreach $proxyTypes as $k=>$v}
<option value="{$v}">{$k}</option>
{/foreach}
</select>
</td>
<td class="p-top1"><a href="javascript:;" class="glyphicon glyphicon-remove op-delete"></a></td>
</tr>
</tbody>
</table>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block">提交</button>
</div>
</form>
<script type="text/javascript">
window.proxyClass.init_add();
</script>

View File

@ -0,0 +1,49 @@
<form id="win_form_proxy_batch" method="post" action="{:url('Admin/Proxy/batch')}">
<input type="hidden" name="is_test" />
<div class="form-group">
<label>代理IP一行一条</label>
<textarea rows="5" name="ips" class="form-control"></textarea>
</div>
<div class="form-group">
<label>匹配格式(对应上面每行的数据)</label>
<input type="text" name="format" value="[ip]:[端口]" class="form-control" />
<div style="margin:5px 0;" class="format">
<a href="javascript:;">[ip]</a>
&nbsp;<a href="javascript:;">[端口]</a>
&nbsp;<a href="javascript:;">[用户名]</a>
&nbsp;<a href="javascript:;">[密码]</a>
&nbsp;<a href="javascript:;" title="匹配任意字符">(*)</a>通配符
</div>
</div>
<div class="form-group">
<label>代理类型</label>
<select name="type" class="form-control">
{foreach $proxyTypes as $k=>$v}
<option value="{$v}">{$k}</option>
{/foreach}
</select>
</div>
<div class="form-group">
<label>默认设置</label>
<div class="input-group">
<span class="input-group-addon">默认用户名</span>
<input type="text" name="user" class="form-control" />
<span class="input-group-addon" style="border-left:0;border-right:0;">默认密码</span>
<input type="text" name="pwd" class="form-control" />
</div>
<p class="help-block">当未匹配到用户名时,使用默认设置</p>
</div>
<div class="form-group">
<div class="test-result" style="display:none;">
<label>IP:端口 - 类型 - 用户名:密码</label>
<textarea rows="5" class="form-control"></textarea>
</div>
<button type="button" class="btn btn-default btn-block btn-test">测试</button>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block">提交</button>
</div>
</form>
<script type="text/javascript">
window.proxyClass.init_batch();
</script>

View File

@ -0,0 +1,121 @@
{extend name="common:main_clean" /}
{block name="cssjs"}
<script type="text/javascript" src="__PUBLIC__/static/js/admin/proxy.js?{$Think.config.html_v}"></script>
{/block}
{block name="content"}
<div style="border-bottom:1px solid #ddd;padding:10px 0;">
<form id="form_search" method="post" action="{:url('Proxy/list')}" class="form-inline">
<div class="form-group form-group-sm">
<label>每页显示</label>
<select name="num" class="form-control">
<option value="100">100</option>
<option value="200">200</option>
<option value="500">500</option>
<option value="1000">1000</option>
</select>
</div>
<div class="form-group form-group-sm">
<input type="text" name="ip" class="form-control" placeholder="IP选填" />
</div>
<div class="form-group form-group-sm">
<input type="text" name="user" class="form-control" placeholder="用户名(选填)" />
</div>
<div class="form-group form-group-sm">
<input type="text" name="pwd" class="form-control" placeholder="密码(选填)" />
</div>
<div class="form-group form-group-sm">
<select name="type" class="form-control" style="width:95px;">
<option value="all">类型</option>
{foreach $proxyTypes as $k=>$v}
<option value="{$v}"{$curType[$v]}>{$k}</option>
{/foreach}
</select>
</div>
<div class="form-group form-group-sm">
<select name="invalid" class="form-control">
<option value="all">状态</option>
<option value="0">有效</option>
<option value="1">无效</option>
</select>
</div>
<button type="submit" class="btn btn-default btn-sm">{$Think.lang.search}</button>
</form>
</div>
<form id="form_list" method="post" ajax-submit="true" action="{:url('Proxy/op')}">
<input type="hidden" name="op" value="" />
<input type="hidden" name="url_params" value="{$urlParams}" />
<input type="hidden" name="ips" value="" />
<input type="hidden" name="ip_list" value="" />
<input type="hidden" name="user_list" value="" />
<input type="hidden" name="pwd_list" value="" />
<input type="hidden" name="type_list" value="" />
<div class="table-responsive proxy-ip-list">
<table id="list_table" class="table table-hover datatable">
<thead>
<tr>
<td class="chk"><label><input type="checkbox" class="check-all-ip" /> 全部</label></td>
<td>
<a href="javascript:;" class="label label-danger delete-all-ip">{$Think.lang.delete}</a>
<a href="javascript:;" class="label label-success update-all-ip">修改</a>
</td>
{if condition="!empty($pagenav)"}
<td colspan="6">{$pagenav}</td>
{/if}
</tr>
<tr>
<th width="60" class="chk">{$Think.lang.select}</th>
<th colspan="2">IP带端口</th>
<th>用户名(选填)</th>
<th>密码(选填)</th>
<th>类型</th>
<th>添加时间</th>
<th>{$Think.lang.op}</th>
</tr>
</thead>
<tbody>
{foreach name="dataList" item="item"}
<tr class="form-group-sm">
<td class="chk p-top"><input type="checkbox" data-name="ips[]" value="{$item['ip']}" /></td>
{if $item['invalid']>0||$item['failed']>0}
<td class="p-ip"><input type="text" data-name="ip_list[]" class="form-control" value="{$item['ip']}" /></td>
<td class="p-ip-info">
{if $item['invalid']>0}&nbsp;无效的{/if}
{if $item['failed']>0}&nbsp;失败{$item['failed']}{/if}
</td>
{else/}
<td class="p-ip" colspan="2"><input type="text" data-name="ip_list[]" class="form-control" value="{$item['ip']}" /></td>
{/if}
<td><input type="text" data-name="user_list[]" class="form-control" value="{$item['user']}" /></td>
<td><input type="text" data-name="pwd_list[]" class="form-control" value="{$item['pwd']}" /></td>
<td>
{php}$curType=array($item['type']=>' selected="true"');{/php}
<select data-name="type_list[]" class="form-control" style="width:95px;">
{foreach $proxyTypes as $k=>$v}
<option value="{$v}"{$curType[$v]}>{$k}</option>
{/foreach}
</select>
</td>
<td class="p-top">{:date('Y-m-d H:i',$item['addtime'])}</td>
<td class="p-top"><a href="javascript:;" class="glyphicon glyphicon-remove op-delete"></a></td>
</tr>
{/foreach}
</tbody>
<tfoot>
<tr>
<td class="chk"><label><input type="checkbox" class="check-all-ip" /> 全部</label></td>
<td>
<a href="javascript:;" class="label label-danger delete-all-ip">{$Think.lang.delete}</a>
<a href="javascript:;" class="label label-success update-all-ip">修改</a>
</td>
{if condition="!empty($pagenav)"}
<td colspan="6">{$pagenav}</td>
{/if}
</tr>
</tfoot>
</table>
</div>
</form>
<script type="text/javascript">
window.proxyClass.init_list({$search|json_encode});
</script>
{/block}

View File

@ -0,0 +1,4 @@
<div class="form-group">
<label>IP:端口 - 类型 - 用户名:密码</label>
<textarea rows="10" class="form-control" style="overflow:scroll;">{$ips}</textarea>
</div>

View File

@ -137,9 +137,9 @@
<div class="box-body">
<div class="form-group">
<label>文件存放目录</label>
<div class="input-group">
<div class="input-group mobile-input-group">
<div class="input-group-addon">{:config('root_path')}\data\</div>
<input type="text" class="form-control" name="file[path]" />
<input type="text" class="form-control" name="file[path]" placeholder="请输入目录名称" />
<div class="input-group-btn">
<button type="button" class="btn btn-default btn-file-rand-path">随机目录</button>
</div>
@ -190,9 +190,9 @@
<div class="box-body">
<div class="form-group">
<label>api地址</label>
<div class="input-group">
<div class="input-group mobile-input-group">
<div class="input-group-addon">{:config('root_website')}/api_task/{$releData['task_id']}/</div>
<input type="text" class="form-control" name="api[url]" />
<input type="text" class="form-control" name="api[url]" placeholder="请输入字符串" />
<div class="input-group-btn">
<button type="button" class="btn btn-default btn-api-rand-url">随机字符串</button>
</div>
@ -225,6 +225,97 @@
</div>
</div>
</div>
<div class="rele-module" id="rele_module_toapi" module="toapi" style="display:none;">
<div class="box box-default">
<div class="box-body">
<div class="form-group">
<label>接口地址</label>
<input type="text" name="toapi[url]" class="form-control" />
<p class="help-block">/开头自动补全为{:config('root_website')}/</p>
</div>
<div class="form-group">
<label>请求方式</label>
<select name="toapi[type]" class="form-control">
<option value="post">POST</option>
<option value="">GET</option>
</select>
</div>
<div class="form-group">
<label>请求参数</label>
<a href="javascript:;" class="glyphicon glyphicon-plus toapi-add-param" title="添加"></a>
<div class="table-responsive">
<table class="table table-bordered table-hover toapi-param-table" style="margin-bottom:0;">
<thead>
<tr>
<th>名称</th>
<th></th>
<th>删除</th>
</tr>
</thead>
<tbody>
<tr class="toapi-param-tpl" style="display:none;">
<td>
<input type="text" name="toapi[param_name][]" class="form-control">
</td>
<td>
<div class="input-group">
<div class="input-group-btn">
<select name="toapi[param_val][]" class="form-control" style="min-width:110px;">
<option value=""></option>
{if !empty($collFields)}
{foreach $collFields as $v}
<option value="field:{$v}">采集字段:{$v}</option>
{/foreach}
{/if}
<option value="custom">自定义</option>
</select>
</div>
<input type="text" name="toapi[param_addon][]" class="form-control" style="display:none;margin-left:-1px;">
</div>
</td>
<td>
<a href="javascript:;" class="glyphicon glyphicon-remove toapi-del-param" style="margin-top:8px;"></a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="form-group">
<div class="page-header">响应状态</div>
<p class="help-block">接口必须返回json格式的数组记录数据入库的状态否则会标记为失败</p>
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th style="width:150px;">名称</th>
<th>绑定响应的json数组健名</th>
</tr>
</thead>
<tbody>
<tr>
<td>id编号</td>
<td><input type="text" name="toapi[response][id]" class="form-control" placeholder="必填表示入库返回的自增id或入库状态" /></td>
</tr>
<tr>
<td>target位置</td>
<td><input type="text" name="toapi[response][target]" class="form-control" placeholder="记录入库的数据位置(发布的网址等)" /></td>
</tr>
<tr>
<td>desc描述</td>
<td><input type="text" name="toapi[response][desc]" class="form-control" placeholder="记录入库的数据位置附加信息" /></td>
</tr>
<tr>
<td>error错误</td>
<td><input type="text" name="toapi[response][error]" class="form-control" placeholder="记录入库失败的错误信息" /></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<div class="rele-module" id="rele_module_diy" module="diy" style="display:none;">
<input type="hidden" name="diy[type]" value="app">
<ul id="diy_tab" class="nav nav-tabs">

View File

@ -5,14 +5,33 @@
{block name="content"}
<form id="form_set" method="post" ajax-submit="true" role="form" action="{:url('Admin/Setting/caiji')}">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li class="active"><a href="{:url('Setting/Caiji')}">采集设置</a></li>
<li><a href="{:url('Setting/page_render')}">页面渲染设置</a></li>
<li><a href="{:url('Setting/Proxy')}">代理设置</a></li>
<li><a href="{:url('Setting/Translate')}">翻译设置</a></li>
</ul>
{include file="setting/caiji_nav" /}
<div class="tab-content">
<div class="tab-pane active" style="padding:0px 5px;">
<div class="form-group">
<label>遵守robots协议</label>
<div class="input-group">
<label class="radio-inline"><input type="radio" name="robots" value="1">{$Think.lang.yes}</label>
<label class="radio-inline"><input type="radio" name="robots" value="0">{$Think.lang.no}</label>
</div>
<p class="help-block">严格按照目标网站的robots.txt设置爬取数据避免采集到隐私、侵权等具有争议性的内容 <a href="https://www.baidu.com/s?wd=robots%E5%8D%8F%E8%AE%AE" target="_blank">了解robots协议</a></p>
</div>
<div class="form-group" id="set_caiji_server">
<label>采集运行模式</label>
<select name="server" class="form-control">
<option value="">web服务器默认</option>
<option value="cli">cli命令行推荐</option>
</select>
<p class="help-block server-">使用web服务器运行采集会受web服务器运行超时影响导致采集中断需修改web服务器的超时时间</p>
<div class="server-cli" style="display:none;">
<p class="help-block">使用php cli命令行模式运行采集自动采集、后台采集可以稳定运行需要web服务器拥有执行命令的权限 <a href="https://www.baidu.com/s?wd=php%E6%89%A7%E8%A1%8C%E5%91%BD%E4%BB%A4%E6%9D%83%E9%99%90" target="_blank">了解权限</a></p>
<div class="input-group">
<span class="input-group-addon">PHP可执行文件</span>
<input type="text" name="server_php" class="form-control" value="{$caijiConfig['server_php']}" {$phpExeFile?('placeholder="默认:'.$phpExeFile.'"'):''} />
</div>
<p class="help-block">PHP可执行文件在服务器中的绝对路径或者在系统中的环境变量名称</p>
</div>
</div>
<div class="form-group">
<label>{$Think.lang.set_caiji_auto}</label>
<div class="input-group">
@ -21,15 +40,6 @@
</div>
<p class="help-block">此设置为总控制开关,如设置“否”则任务中的自动采集设置不生效</p>
</div>
<div class="form-group" id="set_caiji_server">
<label>采集运行模式</label>
<div class="input-group">
<label class="radio-inline"><input type="radio" name="server" value="">web服务器默认</label>
<label class="radio-inline"><input type="radio" name="server" value="cli">cli命令行推荐</label>
</div>
<p class="help-block server-">使用web服务器运行采集会受web服务器运行超时影响导致采集中断需修改web服务器的超时时间</p>
<p class="help-block server-cli" style="display:none;">使用php cli命令行模式运行采集自动采集、后台采集可以稳定运行需要web服务器拥有执行命令的权限</p>
</div>
<div class="form-group" id="set_caiji_run" style="display:none;">
<label>{$Think.lang.set_caiji_run}</label>
<select name="run" class="form-control">
@ -74,62 +84,12 @@
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">图片本地化</h4>
</div>
<div class="panel-collapse collapse in">
<div class="panel-body" style="padding-bottom:0px;">
<div class="form-group">
<label>开启功能</label>
<div class="input-group">
<label class="radio-inline"><input type="radio" name="download_img" value="1"></label>
<label class="radio-inline"><input type="radio" name="download_img" value="0"></label>
</div>
<p class="help-block">将远程图片下载到本地服务器</p>
</div>
<div id="set_caiji_download_img" style="display:none;">
<div class="form-group">
<label>图片保存目录(绝对路径)</label>
<input type="text" name="img_path" class="form-control" placeholder="默认{:config('root_path')}\data\images" value="{$caijiConfig['img_path']}">
<p class="help-block">可设置为服务器中的任意文件夹必须开启读写权限如果保存到本程序中目录必须在data文件夹里</p>
</div>
<div class="form-group">
<label>图片链接地址(绝对地址)</label>
<input type="text" name="img_url" class="form-control" placeholder="默认{:config('root_website')}/data/images" value="{:htmlspecialchars($caijiConfig['img_url'],ENT_QUOTES)}">
<p class="help-block">网页中可访问的图片网址目录,请务必对应到图片保存目录,否则图片无法显示</p>
</div>
<div class="form-group">
<label>图片名称</label>
<select name="img_name" class="form-control">
<option value="">按时间生成(方便日期归类)</option>
<option value="url">按网址生成(防止重复下载)</option>
</select>
</div>
<div class="form-group">
<label>下载超时(秒)</label>
<input type="number" name="img_timeout" class="form-control" value="{$caijiConfig['img_timeout']}">
<p class="help-block">多少秒内未下载完跳过下载该图片留空或0表示不限制</p>
</div>
<div class="form-group">
<label>下载间隔(秒)</label>
<input type="number" name="img_interval" class="form-control" value="{$caijiConfig['img_interval']}">
<p class="help-block">可防止下载太快造成目标网站响应超时或宕机留空或0表示不限制</p>
</div>
<div class="form-group">
<label>限制大小MB</label>
<input type="number" name="img_max" class="form-control" value="{$caijiConfig['img_max']}">
<p class="help-block">超过兆数的图片不下载留空或0表示不限制</p>
</div>
</div>
</div>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block">{$Think.lang.save}</button>
</div>
</form>
<script type="text/javascript">
'use strict';//严格模式
$('#form_set [name="auto"]').bind('click',function(){
@ -145,25 +105,16 @@ $('#form_set [name="run"]').bind('change',function(){
$('#set_caiji_run .run-'+$(this).val()).show();
});
$('#form_set [name="server"]').bind('click',function(){
$('#set_caiji_server .help-block').hide();
$('#form_set [name="server"]').bind('change',function(){
$('#set_caiji_server .server-').hide();
$('#set_caiji_server .server-cli').hide();
$('#set_caiji_server .server-'+$(this).val()).show();
});
$('#form_set [name="download_img"]').bind('click',function(){
if($(this).val()>0){
$('#set_caiji_download_img').show();
}else{
$('#set_caiji_download_img').hide();
}
});
$('#form_set [name="robots"][value="{$caijiConfig["robots"]|intval}"]').prop('checked',true);
$('#form_set [name="auto"][value="{$caijiConfig["auto"]|intval}"]').trigger("click");
$('#form_set [name="run"]').val("{$caijiConfig['run']?$caijiConfig['run']:'backstage'}").trigger("change");
$('#form_set [name="server"][value="{$caijiConfig["server"]}"]').prop('checked',true).trigger("click");
$('#form_set [name="server"]').val("{$caijiConfig['server']}").trigger("change");
$('#form_set [name="real_time"][value="{$caijiConfig["real_time"]|intval}"]').prop('checked',true);
$('#form_set [name="download_img"][value="{$caijiConfig["download_img"]|intval}"]').trigger("click");
$('#form_set [name="img_name"]').val('{$caijiConfig["img_name"]}');
</script>
{/block}

View File

@ -0,0 +1,8 @@
{php}$curNav=request()->action();$curNav=array(strtolower($curNav)=>' class="active"');{/php}
<ul class="nav nav-tabs">
<li{$curNav['caiji']}><a href="{:url('Setting/caiji')}">采集设置</a></li>
<li{$curNav['download_img']}><a href="{:url('Setting/download_img')}">图片本地化</a></li>
<li{$curNav['page_render']}><a href="{:url('Setting/page_render')}">页面渲染</a></li>
<li{$curNav['proxy']}><a href="{:url('Setting/proxy')}">代理</a></li>
<li{$curNav['translate']}><a href="{:url('Setting/translate')}">翻译</a></li>
</ul>

View File

@ -0,0 +1,109 @@
{extend name="common:main" /}
{block name="cssjs"}
{/block}
{block name="content"}
<form id="form_set" method="post" ajax-submit="true" role="form" action="{:url('Admin/Setting/download_img')}">
<div class="nav-tabs-custom">
{include file="setting/caiji_nav" /}
<div class="tab-content">
<div class="tab-pane active" style="padding:0px 5px;">
<div class="form-group">
<label>开启功能</label>
<div class="input-group">
<label class="radio-inline"><input type="radio" name="download_img" value="1"></label>
<label class="radio-inline"><input type="radio" name="download_img" value="0"></label>
</div>
<p class="help-block">将远程图片下载到本地服务器</p>
</div>
<div id="set_download_img" style="display:none;">
<div class="form-group">
<label>图片保存目录(绝对路径)</label>
<input type="text" name="img_path" class="form-control" placeholder="默认{:config('root_path')}\data\images" value="{$imgConfig['img_path']}">
<p class="help-block">可设置为服务器中的任意文件夹必须开启读写权限如果保存到本程序中目录必须在data文件夹里</p>
</div>
<div class="form-group">
<label>图片链接地址(绝对地址)</label>
<input type="text" name="img_url" class="form-control" placeholder="默认{:config('root_website')}/data/images" value="{:htmlspecialchars($imgConfig['img_url'],ENT_QUOTES)}">
<p class="help-block">网页中可访问的图片网址目录,请务必对应到图片保存目录,否则图片无法显示</p>
</div>
<div class="form-group">
<label>图片名称</label>
<select name="img_name" class="form-control">
<option value="">按时间生成(方便日期归类)</option>
<option value="url">按网址生成(防止重复下载)</option>
<option value="custom">自定义</option>
</select>
<div id="img_name_custom" style="margin-top:5px;display:none;">
<div class="input-group">
<span class="input-group-addon">目录</span>
<input type="text" name="name_custom_path" class="form-control" value="{$imgConfig['name_custom_path']}" />
<span class="input-group-addon" style="border-left:0;border-right:0;">名称</span>
<select name="name_custom_name" class="form-control">
<option value="">图片网址MD5码</option>
</select>
</div>
<div class="help-block name-custom-path">
<a href="javascript:;">[]</a>&nbsp;
<a href="javascript:;">[]</a>&nbsp;
<a href="javascript:;">[]</a>&nbsp;
<a href="javascript:;">[]</a>&nbsp;
<a href="javascript:;" title="图片网址MD5码的前两位">[前两位]</a>&nbsp;
<a href="javascript:;" title="图片网址MD5码的后两位">[后两位]</a>&nbsp;
/分隔子目录
</div>
</div>
</div>
<div class="form-group">
<label>下载超时(秒)</label>
<input type="number" name="img_timeout" class="form-control" value="{$imgConfig['img_timeout']}">
<p class="help-block">多少秒内未下载完跳过下载该图片留空或0表示不限制</p>
</div>
<div class="form-group">
<label>下载间隔(秒)</label>
<input type="number" name="img_interval" class="form-control" value="{$imgConfig['img_interval']}">
<p class="help-block">可防止下载太快造成目标网站响应超时或宕机留空或0表示不限制</p>
</div>
<div class="form-group">
<label>限制大小MB</label>
<input type="number" name="img_max" class="form-control" value="{$imgConfig['img_max']}">
<p class="help-block">超过兆数的图片不下载留空或0表示不限制</p>
</div>
</div>
</div>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-block">{$Think.lang.save}</button>
</div>
</form>
<script type="text/javascript">
'use strict';//严格模式
$('#form_set [name="download_img"]').bind('click',function(){
if($(this).val()>0){
$('#set_download_img').show();
}else{
$('#set_download_img').hide();
}
});
$('#form_set [name="img_name"]').bind('change',function(){
if($(this).val()=='custom'){
$('#img_name_custom').show();
}else{
$('#img_name_custom').hide();
}
});
$('#form_set').on('click','.name-custom-path a',function(){
insertAtCaret($('[name="name_custom_path"]'),$(this).text());
});
$('#form_set [name="download_img"][value="{$imgConfig["download_img"]|intval}"]').trigger("click");
$('#form_set [name="img_name"]').val('{$imgConfig["img_name"]}').trigger('change');
$('#form_set [name="name_custom_name"]').val('{$imgConfig["name_custom_name"]}');
</script>
{/block}

View File

@ -3,12 +3,7 @@
{/block}
{block name="content"}
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li><a href="{:url('Setting/Caiji')}">采集设置</a></li>
<li class="active"><a href="{:url('Setting/page_render')}">页面渲染设置</a></li>
<li><a href="{:url('Setting/Proxy')}">代理设置</a></li>
<li><a href="{:url('Setting/Translate')}">翻译设置</a></li>
</ul>
{include file="setting/caiji_nav" /}
<div class="tab-content">
<div class="tab-pane active" style="padding:0px 5px;">
{if !empty($config['tool'])}

View File

@ -3,19 +3,16 @@
<script src="__PUBLIC__/static/js/admin/proxy.js?{$Think.config.html_v}"></script>
{/block}
{block name="content"}
<form id="form_set" method="post" ajax-submit="true" role="form" action="{:url('Admin/Setting/proxy')}">
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li><a href="{:url('Setting/Caiji')}">采集设置</a></li>
<li><a href="{:url('Setting/page_render')}">页面渲染设置</a></li>
<li class="active"><a href="{:url('Setting/Proxy')}">代理设置</a></li>
<li><a href="{:url('Setting/Translate')}">翻译设置</a></li>
</ul>
{include file="setting/caiji_nav" /}
<div class="tab-content">
<div class="tab-pane active" style="padding:0px 5px;">
<form id="form_set" method="post" ajax-submit="true" role="form" action="{:url('Admin/Setting/proxy')}">
<input type="hidden" name="ips" value="" />
<input type="hidden" name="ip_list" value="" />
<input type="hidden" name="user_list" value="" />
<input type="hidden" name="pwd_list" value="" />
<input type="hidden" name="type_list" value="" />
<div class="form-group">
<label>开启代理</label>
<div class="input-group">
@ -32,7 +29,7 @@
<div class="form-group">
<label>IP使用策略</label>
<div class="input-group">
<label class="radio-inline"><input type="radio" name="use" value="" checked="checked">无(默认循环使用)</label>
<label class="radio-inline"><input type="radio" name="use" value="" checked="checked">循环使用(默认</label>
<label class="radio-inline"><input type="radio" name="use" value="num">按次数使用</label>
<label class="radio-inline"><input type="radio" name="use" value="time">按时长使用</label>
</div>
@ -45,37 +42,125 @@
<label>每个IP使用多少分钟</label>
<input type="number" class="form-control" name="use_time" />
</div>
<div class="h-title">
<label class="control-label">代理IP</label>
&nbsp;<a href="javascript:;" id="add_proxy_ip" class="glyphicon glyphicon-plus" title="添加">添加</a>
&nbsp;<a href="javascript:;" id="batch_proxy_ip" class="glyphicon glyphicon-th" title="批量添加">批量</a>
&nbsp;<a href="javascript:;" id="clear_proxy_ip" class="glyphicon glyphicon-trash" title="清空">清空</a>
</div>
<div class="form-group">
<div class="table-responsive proxy-ip-list">
<table class="table table-hover" id="proxy_ip_table" style="margin-bottom:0;">
<thead>
<tr>
<th class="col-xs-5" colspan="2">IP可带端口</th>
<th class="col-xs-3">用户名(选填)</th>
<th class="col-xs-3">密码(选填)</th>
<th class="col-xs-1">删除</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
<div class="form-group">
<button type="submit" id="btn_sub" class="btn btn-primary btn-block">{$Think.lang.save}</button>
</div>
</form>
</div>
</div>
</div>
<div class="panel panel-default proxy-api-list" id="proxy_api" style="display:none;">
<div class="panel-heading">
<h4 class="panel-title"><a data-toggle="collapse" href="#panel_proxy_api">API动态获取IP</a></h4>
</div>
<div class="panel-collapse collapse in" id="panel_proxy_api">
<div class="panel-body">
<div class="form-group">
<label>开启功能</label>
<div class="input-group">
<label class="radio-inline"><input type="radio" name="api[open]" value="1"></label>
<label class="radio-inline"><input type="radio" name="api[open]" value="0"></label>
</div>
<p class="help-block">采集运行时自动从API接口中抓取代理IP并入库</p>
</div>
<div class="panel-group" id="proxy_api_box" style="display:none;">
<div class="form-group">
<label>IP入库时机</label>
<select name="api[insert]" class="form-control">
<option value="">数据库中无可用IP时(默认)</option>
<option value="end">数据库中IP循环到最后时</option>
</select>
</div>
<div class="form-group">
<div class="h-title">
<label class="control-label">API接口</label>
<a href="javascript:;" class="glyphicon glyphicon-plus p-api-add" title="添加"></a>
</div>
</div>
</div>
<div class="panel panel-default p-api-panel" id="proxy_api_tpl" style="display:none;">
<div class="panel-heading">
<div class="panel-title" style="width:auto;overflow:hidden;">
<a data-toggle="collapse" data-parent="#proxy_api_box" class="p-api-title">接口<small></small></a>
<div style="float:right;font-size:14px;">
<a href="javascript:;" class="glyphicon glyphicon-arrow-up p-api-up"></a>
<a href="javascript:;" class="glyphicon glyphicon-arrow-down p-api-down"></a>
<a href="javascript:;" class="glyphicon glyphicon-remove p-api-delete"></a>
</div>
</div>
</div>
<div class="panel-collapse collapse p-api-collapse">
<div class="panel-body">
<div class="form-group">
<label>接口地址</label>
<input type="text" data-name="api_url" class="form-control" />
<p class="help-block">请填写完整的API网址</p>
</div>
<div class="form-group">
<label>抓取间隔(分钟)</label>
<input type="number" data-name="api_interval" class="form-control" />
<p class="help-block">每隔多少分钟访问api防止频繁访问api造成资源浪费</p>
</div>
<div class="form-group">
<label>匹配格式</label>
<textarea data-name="api_format" class="form-control">[ip]:[端口]</textarea>
<div style="margin:10px 0;" class="p-api-format">
<a href="javascript:;">[ip]</a>
&nbsp;<a href="javascript:;">[端口]</a>
&nbsp;<a href="javascript:;">[用户名]</a>
&nbsp;<a href="javascript:;">[密码]</a>
&nbsp;<a href="javascript:;" title="匹配任意字符">(*)</a>通配符
</div>
<p class="help-block">从API返回的源码中匹配出相应格式的数据</p>
</div>
<div class="form-group">
<label>代理类型</label>
<select data-name="api_type" class="form-control">
{foreach $proxyTypes as $k=>$v}
<option value="{$v}">{$k}</option>
{/foreach}
</select>
</div>
<div class="form-group">
<label>默认设置</label>
<div class="input-group">
<span class="input-group-addon">默认用户名</span>
<input type="text" data-name="api_user" class="form-control" />
<span class="input-group-addon" style="border-left:0;border-right:0;">默认密码</span>
<input type="text" data-name="api_pwd" class="form-control" />
</div>
<p class="help-block">当未匹配到用户名时,使用默认设置</p>
</div>
<div class="form-group">
<button type="button" class="btn btn-default btn-api-test">测试抓取IP</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="form-group">
<button type="submit" id="btn_sub" class="btn btn-primary btn-block">保存以上配置</button>
</div>
<div class="panel panel-default" id="proxy_ip">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" href="#panel_proxy_ip">代理IP列表</a>
<small>
&nbsp;<a href="javascript:;" id="add_proxy_ip" class="glyphicon glyphicon-plus" title="添加">添加</a>
&nbsp;<a href="javascript:;" id="batch_proxy_ip" class="glyphicon glyphicon-th" title="批量添加">批量</a>
&nbsp;<a href="javascript:;" id="invalid_proxy_ip" class="glyphicon glyphicon glyphicon-erase" title="一键清理无效IP">清理无效IP</a>
</small>
</h4>
</div>
<div class="panel-collapse collapse in" id="panel_proxy_ip">
<div class="panel-body" style="padding:0;">
<div class="loading" style="margin:15px 10px;display:none;"></div>
<iframe src="{:url('Proxy/list')}" class="proxy-ip-iframe" id="proxy_ip_iframe" width="100%" frameborder="0" scrolling="yes"></iframe>
</div>
</div>
</div>
</form>
<script type="text/javascript">
proxyClass.init({$proxyConfig|json_encode});
window.proxyClass.init_setting({$proxyConfig|json_encode});
</script>
{/block}

View File

@ -27,13 +27,17 @@
<label class="radio-inline"><input type="radio" name="login[limit]" value="1">{$Think.lang.yes}</label>
<label class="radio-inline"><input type="radio" name="login[limit]" value="0">{$Think.lang.no}</label>
</div>
<div class="input-group" id="login_limit" style="margin-top:10px;display:none;">
<span class="input-group-addon">登录失败</span>
<input type="number" name="login[failed]" class="form-control" value="{$siteConfig['login']['failed']}">
<span class="input-group-addon">次,将被锁定</span>
<input type="number" name="login[time]" class="form-control" value="{$siteConfig['login']['time']}">
<span class="input-group-addon">小时</span>
<div id="login_limit" style="margin-top:10px;display:none;">
<div class="input-group" style="margin-bottom:5px;">
<span class="input-group-addon">登录失败</span>
<input type="number" name="login[failed]" class="form-control" value="{$siteConfig['login']['failed']}">
<span class="input-group-addon" style="border-left:0;"></span>
</div>
<div class="input-group">
<span class="input-group-addon">锁定登录</span>
<input type="number" name="login[time]" class="form-control" value="{$siteConfig['login']['time']}">
<span class="input-group-addon">小时</span>
</div>
</div>
</div>
<div class="form-group">

View File

@ -4,12 +4,7 @@
{/block}
{block name="content"}
<div class="nav-tabs-custom">
<ul class="nav nav-tabs">
<li><a href="{:url('Setting/Caiji')}">采集设置</a></li>
<li><a href="{:url('Setting/page_render')}">页面渲染设置</a></li>
<li><a href="{:url('Setting/Proxy')}">代理设置</a></li>
<li class="active"><a href="{:url('Setting/Translate')}">翻译设置</a></li>
</ul>
{include file="setting/caiji_nav" /}
<div class="tab-content">
<div class="tab-pane active" style="padding:0px 5px;">
<form id="form_set" method="post" ajax-submit="true" role="form" action="{:url('Admin/Setting/Translate')}">
@ -21,33 +16,47 @@
</div>
<p class="help-block">开启后采集器中的翻译功能才会生效</p>
</div>
<div class="form-group">
<label>翻译API接口</label>
<select name="api" class="form-control">
<option value="">--请选择--</option>
<option value="baidu">百度翻译</option>
<option value="youdao">有道翻译</option>
</select>
<p class="help-block">百度支持所有语种;有道支持:日文、英文、韩文、法文、俄文、葡萄牙文、西班牙文</p>
</div>
<div class="form-group" id="api_baidu" style="display:none;">
<label>百度翻译API &nbsp;<a href="https://www.baidu.com/s?wd=%E7%99%BE%E5%BA%A6%E7%BF%BB%E8%AF%91api" class="small" target="_blank">申请</a></label>
<div class="input-group">
<span class="input-group-addon">APPID</span>
<input type="text" name="baidu[appid]" class="form-control" value="{$transConfig['baidu']['appid']}">
<span class="input-group-addon">密钥</span>
<input type="text" name="baidu[key]" class="form-control" value="{$transConfig['baidu']['key']}">
<div id="translate_open" style="display:none;">
<div class="form-group">
<label>翻译API接口</label>
<select name="api" class="form-control">
<option value="">--请选择--</option>
<option value="baidu">百度翻译</option>
<option value="youdao">有道翻译</option>
<option value="qq">腾讯翻译</option>
</select>
</div>
<div class="form-group" id="api_baidu" style="display:none;">
<label>百度翻译API &nbsp;<a href="https://www.baidu.com/s?wd=%E7%99%BE%E5%BA%A6%E7%BF%BB%E8%AF%91api" class="small" target="_blank">申请</a></label>
<div class="input-group">
<span class="input-group-addon">APPID</span>
<input type="text" name="baidu[appid]" class="form-control" value="{$transConfig['baidu']['appid']}">
<span class="input-group-addon" style="border-left:0;border-right:0;">密钥</span>
<input type="text" name="baidu[key]" class="form-control" value="{$transConfig['baidu']['key']}">
</div>
<p class="help-block">支持语种:{$apiLangs['baidu']}</p>
</div>
</div>
<div class="form-group" id="api_youdao" style="display:none;">
<label>有道翻译API &nbsp;<a href="https://www.baidu.com/s?wd=%E6%9C%89%E9%81%93%E7%BF%BB%E8%AF%91api" class="small" target="_blank">申请</a></label>
<div class="input-group">
<span class="input-group-addon">应用ID</span>
<input type="text" name="youdao[appkey]" class="form-control" value="{$transConfig['youdao']['appkey']}">
<span class="input-group-addon">应用密钥</span>
<input type="text" name="youdao[key]" class="form-control" value="{$transConfig['youdao']['key']}">
<div class="form-group" id="api_youdao" style="display:none;">
<label>有道翻译API &nbsp;<a href="https://www.baidu.com/s?wd=%E6%9C%89%E9%81%93%E7%BF%BB%E8%AF%91api" class="small" target="_blank">申请</a></label>
<div class="input-group">
<span class="input-group-addon">应用ID</span>
<input type="text" name="youdao[appkey]" class="form-control" value="{$transConfig['youdao']['appkey']}">
<span class="input-group-addon" style="border-left:0;border-right:0;">应用密钥</span>
<input type="text" name="youdao[key]" class="form-control" value="{$transConfig['youdao']['key']}">
</div>
<p class="help-block">支持语种:{$apiLangs['youdao']}</p>
</div>
</div>
<div class="form-group" id="api_qq" style="display:none;">
<label>腾讯翻译API &nbsp;<a href="https://www.baidu.com/s?wd=%E8%85%BE%E8%AE%AF%E7%BF%BB%E8%AF%91api" class="small" target="_blank">申请</a></label>
<div class="input-group">
<span class="input-group-addon">SecretId</span>
<input type="text" name="qq[secretid]" class="form-control" value="{$transConfig['qq']['secretid']}">
<span class="input-group-addon" style="border-left:0;border-right:0;">SecretKey</span>
<input type="text" name="qq[secretkey]" class="form-control" value="{$transConfig['qq']['secretkey']}">
</div>
<p class="help-block">支持语种:{$apiLangs['qq']}</p>
</div>
</div>
<div class="form-group">
<button type="submit" id="btn_sub" class="btn btn-primary btn-block">{$Think.lang.save}</button>
</div>
@ -56,12 +65,21 @@
</div>
</div>
<script type="text/javascript">
'use strict';//严格模式
$('#form_set [name="open"]').bind('click',function(){
if($(this).val()==1){
$('#translate_open').show();
}else{
$('#translate_open').hide();
}
});
$('#form_set [name="api"]').bind('change',function(){
$('[id^="api_"]').hide();
$('#api_'+$(this).val()).show();
});
{if condition="!empty($transConfig)"}
$('#form_set [name="open"][value="{$transConfig["open"]|intval}"]').prop('checked',true);
$('#form_set [name="open"][value="{$transConfig["open"]|intval}"]').trigger('click');
$('#form_set [name="api"]').val("{$transConfig['api']}").trigger("change");
{/if}
</script>

View File

@ -5,6 +5,6 @@
{/block}
{block name="content"}
<div class="iframe-loading"><div class="loading">&nbsp;</div>页面加载中...</div>
<iframe src="{$url}" data-provider-url="{$provData['url']}" data-is-store-url="1" id="iframe_main" class="iframe-main" width="100%" height="100%" frameborder="0" scrolling="yes"></iframe>
<iframe data-store-url="{$url}" data-provider-url="{$provData['url']}" id="iframe_main" class="iframe-main" width="100%" height="100%" frameborder="0" scrolling="yes"></iframe>
<script type="text/javascript">storeClass.init_iframe();</script>
{/block}

View File

@ -10,7 +10,7 @@
<input type="hidden" name="show" value="list" />
<input type="hidden" name="op" value="saveall" />
<div class="table-responsive">
<table id="task_list" class="table table-bordered table-hover datatable">
<table id="task_list" class="table table-hover datatable">
<thead>
<tr>
<th width="80">{$Think.lang.sort}</th>
@ -24,6 +24,13 @@
</tr>
</thead>
<tbody>
{if empty($taskList)}
<tr>
<td colspan="8" style="text-align:center;">
<p class="help-block">没有任务,创建<a href="{:url('Task/add')}">新任务</a>或进入<a href="{:url('Store/index')}">云平台</a>下载规则</p>
</td>
</tr>
{else/}
{foreach name="taskList" item="item"}
<tr task-id="{$item['id']}">
<td class="sort"><input type="text" name="newsort[{$item['id']}]" class="form-control" value="{$item['sort']}" autocomplete="off" /></td>
@ -50,6 +57,7 @@
</td>
</tr>
{/foreach}
{/if}
</tbody>
<tfoot>
<tr>

View File

@ -5,7 +5,7 @@
<div class="box-body">
<form id="form_list" method="post" ajax-submit="true" action="{:url('Taskgroup/op')}">
<input type="hidden" name="op" value="saveall" />
<table id="list_table" class="table table-bordered table-hover datatable">
<table id="list_table" class="table table-hover datatable">
<thead>
<tr>
<th width="50" class="chk">{$Think.lang.select}</th>
@ -116,7 +116,7 @@ $(document).ready(function(){
//sort改变值后选中
$('input[name^="newsort"]').bind('change',function(){
$(this).parent().parent().find('input[name="ids[]"]').attr('checked',true);
$(this).parent().parent().find('input[name="ids[]"]').prop('checked',true);
});
//删除选中
$('#deleteall').bind('click',function(){

View File

@ -33,6 +33,7 @@ $(document).ready(function(){
var data=$('#txt_json').val();
if((/^\w+\:\/\//).test(data)){
$('#json_tree').html('<div class="loading"></div>');
//是网址
$.ajax({
type: 'POST',

View File

@ -31,7 +31,7 @@
<input type="text" name="email" class="form-control" value="{$user['email']}">
<p class="help-block">{$Think.lang.user_email_tips}</p>
</div>
{if condition="$GLOBALS['config']['site']['verifycode']"}
{if condition="$GLOBALS['_sc']['c']['site']['verifycode']"}
<div class="form-group">
<label>{$Think.lang.verifycode}</label>
<div class="input-group">

View File

@ -37,7 +37,7 @@
<label>{$Think.lang.user_repassword}</label>
<input type="password" name="repassword" class="form-control" value="">
</div>
{if condition="$GLOBALS['config']['site']['verifycode']"}
{if condition="$GLOBALS['_sc']['c']['site']['verifycode']"}
<div class="form-group">
<label>{$Think.lang.verifycode}</label>
<div class="input-group">

View File

@ -5,7 +5,7 @@
<div class="box">
<div class="box-body">
<div class="table-responsive">
<table id="list_table" class="table table-bordered table-hover datatable">
<table id="list_table" class="table table-hover datatable">
<thead>
<tr>
<th width="80">UID</th>

View File

@ -10,7 +10,7 @@
*/
define('SKYCAIJI_VERSION', '2.2');
define('SKYCAIJI_VERSION', '2.3');
define('NOW_TIME', time());
\think\Loader::addNamespace('plugin', realpath(ROOT_PATH.'plugin'));
\think\Loader::addNamespace('util',realpath(APP_PATH.'extend/util'));
@ -171,7 +171,14 @@ function clientinfo(){
);
return $info;
}
/*获取html代码*/
/**
* 获取html代码
* @param string $url
* @param string $headers 键值对形式
* @param array $options
* @param string $fromEncode
* @param array $post_data 通过isset判断是否是post模式
*/
function get_html($url,$headers=null,$options=array(),$fromEncode='auto',$post_data=null){
$headers=is_array($headers)?$headers:array();
$options=is_array($options)?$options:array();
@ -179,13 +186,20 @@ function get_html($url,$headers=null,$options=array(),$fromEncode='auto',$post_d
$options['useragent']='Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70 Safari/537.36';
}
$options['timeout']=$options['timeout']>0?$options['timeout']:30;
$options['verify']=false;
$curlHeaders=array();
foreach ($headers as $k=>$v){
$curlHeaders[]=$k.': '.$v;
}
$headers=$curlHeaders;
unset($curlHeaders);
if(!preg_match('/^\w+\:\/\//', $url)){
$url='http://'.$url;
}
$curl=null;
try {
if(!isset($post_data)){
@ -194,8 +208,8 @@ function get_html($url,$headers=null,$options=array(),$fromEncode='auto',$post_d
$max_bytes=intval($options['max_bytes']);
unset($options['max_bytes']);
$request=\Requests::head($url,$headers,$options);
if(preg_match('/\bContent-Length\s*:\s*(\d+)/i', $request->raw,$contLen)){
$curl=\util\Curl::head($url,$headers,$options);
if(preg_match('/\bContent-Length\s*:\s*(\d+)/i', $curl->header,$contLen)){
$contLen=intval($contLen[1]);
if($contLen>=$max_bytes){
@ -205,40 +219,43 @@ function get_html($url,$headers=null,$options=array(),$fromEncode='auto',$post_d
}
if($allow_get){
$request=\Requests::get($url,$headers,$options);
$curl=\util\Curl::get($url,$headers,$options);
}else{
$request=null;
$curl=null;
}
}else{
if(!is_array($post_data)){
if(preg_match_all('/([^\&]+)\=([^\&]*)/',$post_data,$m_post_data)){
$new_post_data=array();
foreach($m_post_data[1] as $k=>$v){
$new_post_data[$v]=rawurldecode($m_post_data[2][$k]);
}
$post_data=$new_post_data;
}else{
$post_data='';
}
}
$post_data=empty($post_data)?array():$post_data;
if(!empty($post_data)&&!empty($fromEncode)&&!in_array(strtolower($fromEncode), array('auto','utf-8','utf8'))){
if(!is_array($post_data)){
if(preg_match_all('/([^\&]+?)\=([^\&]*)/',$post_data,$m_post_data)){
$new_post_data=array();
foreach($m_post_data[1] as $k=>$v){
$new_post_data[$v]=rawurldecode($m_post_data[2][$k]);
}
$post_data=$new_post_data;
}else{
$post_data=array();
}
}
$post_data=is_array($post_data)?$post_data:array();
foreach ($post_data as $k=>$v){
$post_data[$k] = iconv ( 'utf-8', $fromEncode.'//IGNORE', $v );
}
}
$request=\Requests::post($url,$headers,$post_data,$options);
$curl=\util\Curl::post($url,$headers,$options,$post_data);
}
} catch (\Exception $e) {
$request=null;
$curl=null;
}
if(!empty($request)){
if(200==$request->status_code){
$html=null;
if(!empty($curl)){
if($curl->isOk){
$html=$request->body;
$html=$curl->body;
if ($fromEncode == 'auto') {
$htmlCharset='';
@ -251,7 +268,7 @@ function get_html($url,$headers=null,$options=array(),$fromEncode='auto',$post_d
$htmlCharset='';
}
$headerCharset='';
if(preg_match('/charset=(?P<charset>[\w\-]+)/i', $request->headers['content-type'],$headerCharset)){
if(preg_match('/\bContent-Type\s*:[^\r\n]*charset=(?P<charset>[\w\-]+)/i', $curl->header,$headerCharset)){
$headerCharset=strtolower(trim($headerCharset['charset']));
if('utf8'==$headerCharset){
$headerCharset='utf-8';
@ -306,7 +323,7 @@ function get_html($url,$headers=null,$options=array(),$fromEncode='auto',$post_d
}
}
}
return $html?$html:null;
return isset($html)?$html:false;
}
/*载入配置文件*/

View File

@ -15,7 +15,13 @@ use think\Request;
class Init{
public function run(){
session_start();
if(!isset($GLOBALS['_sc'])){
$GLOBALS['_sc']=array();
}
if(session_status()!==2){
session_start();
}
if(isset($_GET['m'])&&isset($_GET['c'])&&isset($_GET['a'])){
$tourl=config('root_website');
@ -41,7 +47,7 @@ class Init{
$browserIe = doubleval($browserIe[1]);
if($browserIe<9){
$GLOBALS['browser_is_old']=true;
$GLOBALS['_sc']['browser_is_old']=true;
}
}
if(stripos(Request::instance()->root(),'/index.php')!==false&&isset($_GET['s'])){

View File

@ -243,9 +243,9 @@ return [
/**********************************自定义配置*********************************************/
'cli_cache_config'=>array('view_replace_str','root_path','app_path','plugin_path','root_url','root_website'),//cli模式下需要缓存的配置否则会失效引起程序bug
'cli_cache_config'=>array('view_replace_str','root_path','app_path','apps_path','plugin_path','root_url','root_website'),//cli模式下需要缓存的配置否则会失效引起程序bug
'html_v'=>'20190601',//css和js版本
'html_v'=>'20190901',//css和js版本
'root_path'=>realpath(ROOT_PATH),//根目录
'app_path'=>realpath(APP_PATH),//skycaijiApp目录
@ -255,7 +255,7 @@ return [
'root_website'=>(Request::instance()->isSsl()?'https':'http').'://'.trim(Request::instance()->host(),'\/\\').rtrim(preg_replace('/\/index\.php.*/i','',Request::instance()->root()),'\/\\'),//带域名网站根目录去掉index.php结尾不带/
'allow_coll_modules'=>array('pattern'),//允许的采集器模块
'release_modules'=>array('cms','db','file','api','diy'),//发布模块
'release_modules'=>array('cms','db','file','toapi','api','diy'),//发布模块
'yzm_expire'=>1200, //邮箱验证码过期时间(秒)
'allow_process_func'=>array(

View File

@ -151,7 +151,7 @@ class ChromeSocket{
if(!is_array($postData)){
if(preg_match_all('/([^\&]+)\=([^\&]*)/', $postData,$m_post_data)){
if(preg_match_all('/([^\&]+?)\=([^\&]*)/', $postData,$m_post_data)){
$new_post_data=array();
foreach($m_post_data[1] as $k=>$v){
$new_post_data[$v]=rawurldecode($m_post_data[2][$k]);

View File

@ -0,0 +1,141 @@
<?php
/*
|--------------------------------------------------------------------------
| SkyCaiji (蓝天采集器)
|--------------------------------------------------------------------------
| Copyright (c) 2018 https://www.skycaiji.com All rights reserved.
|--------------------------------------------------------------------------
| 使用协议 https://www.skycaiji.com/licenses
|--------------------------------------------------------------------------
*/
/*curl*/
namespace util;
class Curl{
protected static $instance=null;
public $header=null;
public $isOk=null;
public $body=null;
/*实例*/
private static function init(){
if(!isset(self::$instance)){
self::$instance=new static;
}
self::$instance->header=null;
self::$instance->isOk=null;
self::$instance->body=null;
return self::$instance;
}
/**
* 请求
* @param string $url
* @param array $headers header格式必须为 “键: 值”
* @param array $options
* @param string $postData
* @return \util\Curl
*/
public static function request($url,$headers=array(),$options=array(),$postData=null){
$instance=self::init();
$headers=is_array($headers)?$headers:array();
$options=is_array($options)?$options:array();
$options['timeout']=intval($options['timeout']);
$options['timeout']=$options['timeout']>0?$options['timeout']:20;
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, $url );
curl_setopt ( $ch, CURLOPT_TIMEOUT, $options['timeout'] );
curl_setopt ( $ch, CURLOPT_CONNECTTIMEOUT , 10 );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, 1 );
curl_setopt ( $ch, CURLOPT_HEADER, 1 );
if($options['nobody']){
curl_setopt($ch, CURLOPT_NOBODY, true);
}
if($options['useragent']){
curl_setopt($ch, CURLOPT_USERAGENT, $options['useragent']);
}
curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, FALSE );
if(!empty($headers)&&count($headers)>0){
curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers );
}
if(isset($postData)){
curl_setopt ( $ch, CURLOPT_POST, 1 );
if(is_array($postData)){
$postData=http_build_query($postData);
}
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $postData );
}
if(!empty($options['proxy'])&&!empty($options['proxy']['ip'])){
$proxyType=null;
switch ($options['proxy']['type']){
case 'socks4':$proxyType=CURLPROXY_SOCKS4;break;
case 'socks5':$proxyType=CURLPROXY_SOCKS5;break;
default:$proxyType=CURLPROXY_HTTP;break;
}
curl_setopt($ch, CURLOPT_PROXYTYPE,$proxyType);
curl_setopt($ch, CURLOPT_PROXY, $options['proxy']['ip']);
curl_setopt($ch, CURLOPT_PROXYPORT, $options['proxy']['port']);
if(!empty($options['proxy']['user'])){
curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $options['proxy']['user'].':'.$options['proxy']['pwd']);
}
}
$body = curl_exec ( $ch );
$headerPos=strpos($body, "\r\n\r\n");
if($headerPos!==false){
$headerPos=intval($headerPos)+strlen("\r\n\r\n");
}
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headerSize=intval($headerSize);
if($headerSize<$headerPos){
$headerSize=$headerPos;
}
$instance->header = substr($body, 0, $headerSize);
$instance->body = substr($body, $headerSize);
$code=curl_getinfo($ch,CURLINFO_HTTP_CODE);
$code=intval($code);
if($code>=200&&$code<300){
$instance->isOk=true;
}else{
$instance->isOk=false;
}
curl_close ( $ch );
return $instance;
}
public static function head($url,$headers=array(),$options=array()){
$options=is_array($options)?$options:array();
$options['nobody']=1;
return self::request($url,$headers,$options);
}
public static function get($url,$headers=array(),$options=array()){
return self::request($url,$headers,$options);
}
public static function post($url,$headers=array(),$options=array(),$data=null){
return self::request($url,$headers,$options,$data?$data:'');
}
}
?>

View File

@ -19,7 +19,8 @@ class Log extends File{
'未定义','Undefined',
'A session had already been started','DOMDocument::loadHTML',
'MySQL server has gone away',"Error reading result set's header",
'The /e modifier is deprecated'
'The /e modifier is deprecated',
'Invalid argument supplied for foreach'
);
foreach ($log as $type => $val) {

View File

@ -12,48 +12,148 @@
/*翻译器*/
namespace util;
class Translator{
public static $youdao_langs=array('zh'=>'zh-CHS','jp'=>'ja','en'=>'EN','kor'=>'ko','fra'=>'fr','ru'=>'ru','pt'=>'pt','spa'=>'es');
public static $all_langs=array(
'zh'=>'中文',
'en'=>'英语',
'fra'=>'法语',
'jp'=>'日语',
'kor'=>'韩语',
'de'=>'德语',
'ru'=>'俄语',
'spa'=>'西班牙语',
'pt'=>'葡萄牙语',
'it'=>'意大利语',
'ara'=>'阿拉伯语',
'th'=>'泰语',
'el'=>'希腊语',
'nl'=>'荷兰语',
'pl'=>'波兰语',
'bul'=>'保加利亚语',
'est'=>'爱沙尼亚语',
'dan'=>'丹麦语',
'fin'=>'芬兰语',
'cs'=>'捷克语',
'rom'=>'罗马尼亚语',
'slo'=>'斯洛文尼亚语',
'swe'=>'瑞典语',
'hu'=>'匈牙利语',
'tr'=>'土耳其语',
'id'=>'印尼语',
'ms'=>'马来西亚语',
'vie'=>'越南语',
'yue'=>'粤语',
'wyw'=>'文言文',
'cht'=>'繁体中文'
);
public static $allow_langs = array (
'baidu' => array (
'zh'=>'zh',
'en'=>'en',
'fra'=>'fra',
'jp'=>'jp',
'kor'=>'kor',
'de'=>'de',
'ru'=>'ru',
'spa'=>'spa',
'pt'=>'pt',
'it'=>'it',
'ara'=>'ara',
'th'=>'th',
'el'=>'el',
'nl'=>'nl',
'pl'=>'pl',
'bul'=>'bul',
'est'=>'est',
'dan'=>'dan',
'fin'=>'fin',
'cs'=>'cs',
'rom'=>'rom',
'slo'=>'slo',
'swe'=>'swe',
'hu'=>'hu',
'vie'=>'vie',
'yue'=>'yue',
'wyw'=>'wyw',
'cht'=>'cht'
),
'youdao' => array (
'zh' => 'zh-CHS',
'en' => 'en',
'jp' => 'ja',
'kor' => 'ko',
'fra' => 'fr',
'spa' => 'es',
'pt' => 'pt',
'it' => 'it',
'ru' => 'ru',
'vie'=>'vi',
'de'=>'de',
'ara'=>'ar',
'id'=>'id',
'it'=>'it'
),
'qq' => array (
'zh' => 'zh',
'en' => 'en',
'jp' => 'jp',
'kor' => 'kr',
'de' => 'de',
'fra' => 'fr',
'spa' => 'es',
'it' => 'it',
'tr' => 'tr',
'ru' => 'ru',
'pt' => 'pt',
'vie' => 'vi',
'id' => 'id',
'ms' => 'ms',
'th' => 'th',
'cht' => 'zh-TW'
)
);
/*翻译入口*/
public static function translate($q,$from,$to){
$transConf=$GLOBALS['config']['translate'];
$transConf=$GLOBALS['_sc']['c']['translate'];
if(empty($from)||empty($to)){
return $q;
}
if(empty($transConf['api'])){
return $q;
}
$transConf['api']=strtolower($transConf['api']);
if(empty($transConf[$transConf['api']])){
$apiType=strtolower($transConf['api']);
if(empty($apiType)){
return $q;
}
if('baidu'==$transConf['api']){
$return=self::api_baidu($q, $from, $to);
return $return['success']?$return['data']:$q;
}elseif('youdao'==$transConf['api']){
$from=self::$youdao_langs[$from];
$to=self::$youdao_langs[$to];
if(empty($from)||empty($to)){
return $q;
}
$return=self::api_youdao($q, $from, $to);
return $return['success']?$return['data']:$q;
}else{
$allowLangs=self::$allow_langs[$apiType];
if(empty($allowLangs)){
return $q;
}
$from=$allowLangs[$from];
$to=$allowLangs[$to];
if(empty($from)||empty($to)){
return $q;
}
if($from==$to){
return $q;
}
if('baidu'==$apiType){
$return=self::api_baidu($q, $from, $to);
}elseif('youdao'==$apiType){
$return=self::api_youdao($q, $from, $to);
}elseif('qq'==$apiType){
$return=self::api_qq($q, $from, $to);
}
return $return['success']?$return['data']:$q;
}
/*百度翻译接口*/
public static function api_baidu($q,$from,$to){
$apiConf=$GLOBALS['config']['translate']['baidu'];
$apiConf=$GLOBALS['_sc']['c']['translate']['baidu'];
$salt = time ();
$sign = $apiConf['appid'] . $q . $salt . $apiConf['key'];
@ -80,7 +180,7 @@ class Translator{
}
/*有道翻译接口*/
public static function api_youdao($q,$from,$to){
$apiConf=$GLOBALS['config']['translate']['youdao'];
$apiConf=$GLOBALS['_sc']['c']['translate']['youdao'];
$salt = time ();
$sign = $apiConf['appkey'] . $q . $salt . $apiConf['key'];
@ -104,6 +204,76 @@ class Translator{
}
return $return;
}
/*腾讯翻译接口*/
public static function api_qq($q,$from,$to){
$apiConf=$GLOBALS['_sc']['c']['translate']['qq'];
$SecretId=$apiConf['secretid'];
$SecretKey=$apiConf['secretkey'];
$param=array();
$param["Nonce"] = rand();
$param["Timestamp"] = time();
$param["Region"] = "ap-shanghai";
$param["SecretId"] = $SecretId;
$param["Action"] = "TextTranslate";
$param["Version"] = "2018-03-21";
$param["SourceText"] = $q;
$param["Source"] = $from;
$param["Target"] = $to;
$param['ProjectId']='0';
ksort($param);
$signStr = "GETtmt.ap-shanghai.tencentcloudapi.com/?";
foreach ( $param as $key => $value ) {
$signStr = $signStr . $key . "=" . $value . "&";
}
$signStr = substr($signStr, 0, -1);
$param['Signature'] = base64_encode(hash_hmac("sha1", $signStr,$SecretKey, true));
$return=array('success'=>false);
ksort($param);
$url='';
foreach ( $param as $key => $value ) {
$url = $url . $key . "=" . urlencode($value) . "&";
}
$url=trim($url,'&');
$data = get_html ( 'https://tmt.'.$param["Region"].'.tencentcloudapi.com/?'.$url, null, null,'utf-8');
$data = json_decode ( $data,true );
if(!empty($data['Response']['TargetText'])){
$return['success']=true;
$return['data']=$data['Response']['TargetText'];
}
return $return;
}
public static function get_api_langs($api){
$allowLangs=self::$allow_langs[$api];
if(!empty($allowLangs)&&is_array($allowLangs)){
foreach($allowLangs as $k=>$v){
if(empty(self::$all_langs[$k])){
unset($allowLangs[$k]);
}else{
$allowLangs[$k]=self::$all_langs[$k];
}
}
}
return is_array($allowLangs)?$allowLangs:null;
}
}
?>

View File

@ -18,7 +18,9 @@ use think\Config;
class Index extends BaseController{
public function __construct(){
parent::__construct();
session_start();
if(session_status()!==2){
session_start();
}
if(file_exists(config('app_path').'/install/data/install.lock')){
$this->success('程序已安装','admin/Index/index');
@ -31,51 +33,12 @@ class Index extends BaseController{
/*环境检测*/
public function step1Action(){
$serverDataList=array(
'os'=>array('操作系统','不限制',php_uname('s').' '.php_uname('r'),true),
'php'=>array('PHP版本','5.4',phpversion())
);
/*判断最低配置*/
if(version_compare($serverDataList['php'][1],$serverDataList['php'][2])<=0){
$serverDataList['php'][3]=true;
}else{
$serverDataList['php'][3]=false;
}
/*php函数*/
$phpModuleList=array(
array('curl',extension_loaded('curl')),
array('mb_string',extension_loaded('mbstring')),
array('pdo_mysql',extension_loaded('pdo_mysql')),
array('gd',extension_loaded('gd')),
);
/*目录、文件*/
$pathFiles=array('./data','./data/config.php','./data/images','./data/app','./data/program/upgrade','./data/program/backup','./app','./plugin','./runtime');
$pathFileList=array();
foreach ($pathFiles as $pathFile){
$filename=config('root_path').'/'.$pathFile;
if(!file_exists($filename)){
if(preg_match('/\w+\.\w+/', $pathFile)){
write_dir_file($filename, null);
}else{
mkdir($filename,0777,true);
}
}
$pathFileList[]=array(
$pathFile,
is_writeable($filename),
is_readable($filename)
);
}
$this->assign('serverDataList',$serverDataList);
$this->assign('phpModuleList',$phpModuleList);
$this->assign('pathFileList',$pathFileList);
$LocSystem=new \skycaiji\install\event\LocSystem();
$setting=$LocSystem->environment();
$this->assign('serverDataList',$setting['server']);
$this->assign('phpModuleList',$setting['php']);
$this->assign('pathFileList',$setting['path']);
return $this->fetch();
}
/*数据安装表单*/

View File

@ -15,7 +15,9 @@ use skycaiji\install\event\UpgradeDb;
class Upgrade extends BaseController{
public function __construct(){
parent::__construct();
session_start();
if(session_status()!==2){
session_start();
}
$mconfig=model('admin/Config');
$dbVersion=$mconfig->getVersion();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -66,7 +66,7 @@ CREATE TABLE `skycaiji_config` (
/*Data for the table `skycaiji_config` */
insert into `skycaiji_config`(`cname`,`ctype`,`dateline`,`data`) values ('version',0,0,'2.2'),('caiji',2,0,'a:6:{s:4:\"auto\";i:0;s:3:\"run\";s:0:\"\";s:3:\"num\";i:10;s:8:\"interval\";i:60;s:7:\"timeout\";i:60;s:12:\"download_img\";i:0;}'),('site',2,0,'a:3:{s:10:"verifycode";i:1;s:8:"hidehome";i:0;s:5:"login";a:3:{s:5:"limit";i:1;s:6:"failed";i:20;s:4:"time";i:1;}}');
insert into `skycaiji_config`(`cname`,`ctype`,`dateline`,`data`) values ('version',0,0,'2.2'),('caiji',2,0,'a:6:{s:6:"robots";i:1;s:4:"auto";i:0;s:3:"run";s:9:"backstage";s:3:"num";i:10;s:8:"interval";i:30;s:7:"timeout";i:60;}'),('site',2,0,'a:3:{s:10:"verifycode";i:1;s:8:"hidehome";i:0;s:5:"login";a:3:{s:5:"limit";i:1;s:6:"failed";i:20;s:4:"time";i:1;}}');
/*Table structure for table `skycaiji_provider` */

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