首页
AI导航
美图
服务
付费
树洞
留言
云主机
推荐
邻居
更多
我的书单
我的足迹
罗盘时钟
圈小猫
工作打分
本站统计
版本历史
推荐
txt阅读器
主机监控
M商城
网址导航
在线工具
证件照制作
Search
1
docker和docker-compose一键安装脚本
824 阅读
2
docker下运行grafana和grafana Image Renderer
664 阅读
3
grafana的Dashboard面板添加阈值报警
632 阅读
4
WooCommerce对接第三方支付插件开发
503 阅读
5
基于docker的部署fecmall开源电商系统
442 阅读
ChatGPT
虚拟化
数据库
运维
基础知识
监控预警
数据展示
运维工具
web安全
系统服务
开发
python
php
java
shell
go
html5
项目
博客
电商
工具
娱乐
影视
读书
读书笔记
综合
VPS报告
规范文档
知识总结
经验分享
关于本站
登录
Search
标签搜索
python
django
电商平台
运维工具
Joe主题
docker
zabbix
蓝鲸智云
运维
监控
typecho
grafana
wordpress
运维知识
mysql
php
elk
nginx
web安全
VPS测试
IT不难
累计撰写
245
篇文章
累计收到
209
条评论
首页
栏目
ChatGPT
虚拟化
数据库
运维
基础知识
监控预警
数据展示
运维工具
web安全
系统服务
开发
python
php
java
shell
go
html5
项目
博客
电商
工具
娱乐
影视
读书
读书笔记
综合
VPS报告
规范文档
知识总结
经验分享
关于本站
页面
美图
服务
留言
邻居
我的足迹
本站统计
版本历史
推荐
M商城
网址导航
搜索到
65
篇与
的结果
2023-03-16
直播推流管理系统prtmp的开发过程总结
前言去年通过docker部署rtmp服务并进行网络压力测试,今年我们的业务终于用到了直播流服务。自己写了一个小系统用来从上游拉取直播流并分发到阿里云或者腾讯的直播服务。然后供小程序调用。特此记录整个配置过程。{card-default label="直播流管理" width="75%"}{/card-default}直播服务{message type="success" content="一般需要准备2个子域名,一个用来拉流,一个用来推流。可以多准备一个子域名,给自己写的流管理系统使用。"/}阿里云{callout color="#f0ad4e"}刚开始,用户不多,流量也很小,可以使用按量计费模式。{/callout}{card-default label="直播" width="75%"}{/card-default}自建直播服务{message type="success" content="直接用docker启动"/}参考: centos7部署rtmp服务并进行压力测试直播流管理系统{message type="success" content="初始功能比较简单,用到了flask+js+celery,用docker方式启动。"/}{card-describe title="主要文件"}main.py 视图,接口等函数utils.py 辅助函数{/card-describe}主要接口{message type="success" content="查询接口,推流接口,推流播放链接生成"/}推流url生成def ali_push_url(appName, streamName): """ 阿里云直播服务推流url """ #推流 push_domain = 'push.mytest.com' push_key = 'ZtBxxxxxxxMEKW' #过期时间 expire_time = 86400 time_stamp = int(time.time()) + expire_time #推流url pstr = '/{}/{}-{}-0-0-{}'.format(appName, streamName, time_stamp, push_key) pmd5 = md5_sign(pstr) purl= 'rtmp://{}/{}/{}?auth_key={}-0-0-{}'.format(push_domain, appName, streamName, time_stamp, pmd5) return purl直播服务urldef ali_live_url(appName, streamName): """ 阿里云直播服务播放url """ resp = {} #播放 play_domain = 'live.mytest.com' play_key = 'ulwxxxxxxxxxOm' #过期时间 expire_time = 86400 time_stamp = int(time.time()) + expire_time #播流url rstr = '/{}/{}-{}-0-0-{}'.format(appName, streamName, time_stamp, play_key) fstr = '/{}/{}.flv-{}-0-0-{}'.format(appName, streamName, time_stamp, play_key) hstr = '/{}/{}.m3u8-{}-0-0-{}'.format(appName, streamName, time_stamp, play_key) rmd5 = md5_sign(rstr) fmd5 = md5_sign(fstr) hmd5 = md5_sign(hstr) resp['rtmp_url'] = 'rtmp://{}/{}/{}?auth_key={}-0-0-{}'.format(play_domain, appName, streamName, time_stamp, rmd5) resp['flv_url'] = 'http://{}/{}/{}.flv?auth_key={}-0-0-{}'.format(play_domain, appName, streamName, time_stamp, fmd5) resp['hls_url'] = 'http://{}/{}/{}.m3u8?auth_key={}-0-0-{}'.format(play_domain, appName, streamName, time_stamp, hmd5) return resp推流任务函数@celery.task def push_rtmp_task(sid, source, target): """ 推流任务函数 """ print(source) print(target) # 视频源输入参数 input_args = ['-i', source] # 推流输出参数 output_args = ['-vcodec', 'libx264', '-acodec', 'aac', '-f', 'flv', target] # 合并参数 command = ['ffmpeg'] + input_args + output_args # 执行命令 with subprocess.Popen(command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) as process: process.wait() # 更新推流信息 living_info = load_json('./data/living.json') if sid in living_info.keys(): living_info.pop(sid) save_living_info(living_info)前端功能{message type="success" content="通过js做数据交互"/}手动推流 //手动推流 function ManPushRtmp(dom) { var mymessage = confirm("确认手动推送此直播流到" + $(dom).attr("ptype") + "?" + $(dom).attr("url")); if (mymessage == true) { $('#myModal').modal('show'); $.ajax({ url : '/api/rtmppush?url=' + $(dom).attr("url") + '&utype=' + $(dom).attr("utype") + '&sid=' + $(dom).attr("sid") + '&mid=' + $(dom).attr("mid") + '&lid=' + $(dom).attr("lid") + '&ptype=' + $(dom).attr("ptype"), type : 'get', success : function(data) { $('#myModal').modal('hide'); if (data.code == 1000){ $("#child_table").bootstrapTable('refresh', data.data); alert(data.msg); } else { alert("推流失败! " + data.msg) } }, error : function(data){ $('#myModal').modal('hide'); alert("接口异常! " + data.msg) } }); } };停止推流 //停止推流 function ManStopPush(dom) { var mymessage = confirm("确认手动停止此直播流?" + $(dom).attr("stream_id")); if (mymessage == true) { $('#myModal').modal('show'); $.ajax({ url : '/api/stoppush?stream_id=' + $(dom).attr("stream_id"), type : 'get', success : function(data) { $('#myModal').modal('hide'); if (data.code == 1000){ alert(data.msg); location.reload(); } else { alert("失败! " + data.msg) } }, error : function(data){ $('#myModal').modal('hide'); alert("接口异常!" + data.msg) } }); } };异步任务{message type="success" content="通过celery实现异步任务执行"/}celery实例化from celery import Celery # celery配置 app.config['CELERY_BROKER_URL'] = 'redis://redis:6379/0' app.config['CELERY_RESULT_BACKEND'] = 'redis://redis:6379/0' #celery实例化 celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL']) celery.conf.update(app.config)caddy代理prmtp.mytest.com { tls admin@mytest.com encode gzip log { output file /opt/logs/access.log } header / { Strict-Transport-Security "max-age=31536000;includeSubdomains;preload" } #访问认证 #密码:123456 basicauth /* { admin $2a$14$DIjtbTxbUSZHfHJUrjuU9.45SlrcwICIXNVSwVxehsnHhTXBBN Nsi } ## HTTP 代理配置, 后端服务端口 reverse_proxy http://backend:5000 }启动#手动启动 python main.py celery -A main.celery worker -l info # 项目启动 docker-compose up -dFAQjs传递url参数需要转码{message type="success" content="使用encodeURIComponent函数"/}
2023年03月16日
4 阅读
0 评论
0 点赞
2023-03-01
聚合信达支付源码测试过程
说明 网上找的一份源码,几年之前的了。部署完之后功能挺全。记录一下部署过程。{card-default label="首页" width="80%"}{/card-default}源码地址第三第四方聚合信达支付源码修复版安装过程lnmp环境docker和docker-compose一键安装脚本nginx配置server { listen 80; server_name www.hnymwl.com; root /www/web/xdzf; add_header X-Frame-Options "SAMEORIGIN"; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options "nosniff"; access_log /www/web_logs/www_access.log wwwlogs; error_log /www/web_logs/www_error.log notice; charset utf-8; index index.html index.htm index.php; location / { try_files $uri $uri/ /index.php$uri?$query_string; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } error_page 404 /index.php; location ~ \.php(.*)$ { fastcgi_pass php:9000; fastcgi_index index.php; fastcgi_split_path_info ^((?U).+\.php)(/?.+)$; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; include fastcgi_params; } location ~ /\.(?!well-known).* { deny all; } }数据库配置编辑:vim app/Config.phpnamespace WY\app; class Config{ static function db(){ return array( 'server'=>'mariadb', 'port'=>'3306', 'user'=>'wpuser', 'pass'=>'wpuserxxx', 'name'=>'wp', 'prefix'=>'wy_', 'driver'=>'pdo', 'debug'=>true, 'path'=>'dy', //设置后台目录名称 ); }重置密码admin/admin update wy_admin set adminpass = 'd033e22ae348aeb5660fc2140aec35850c4da997' where id = 1;页面{card-default label="登录页" width="80%"}{/card-default}{card-default label="后台" width="80%"}{/card-default}
2023年03月01日
11 阅读
0 评论
0 点赞
2023-02-28
星益云收银台系统部署测试过程记录
说明 聚合收银台系统是一款聚合全网支付平台收款的系统,集合了多种支付方式、多个支付平台接口的聚合系统。系统完全免费开源。{card-default label="首页" width="80%"}{/card-default}项目地址(星益云)聚合收银台系统安装过程lnmp环境docker和docker-compose一键安装脚本 {cloud title="完整lnmp配置文件" type="bd" url="https://pan.baidu.com/s/1wIRd1KhFQpraIkjV-CQG6A" password="emjf"/}nginx配置server { listen 80; server_name www.mytest.cn; root /www/web/web/public; add_header X-Frame-Options "SAMEORIGIN"; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options "nosniff"; charset utf-8; index index.html index.htm index.php; location / { try_files $uri $uri/ /index.php$uri?$query_string; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } error_page 404 /index.php; location ~ \.php(.*)$ { fastcgi_pass php:9000; fastcgi_index index.php; fastcgi_split_path_info ^((?U).+\.php)(/?.+)$; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info; include fastcgi_params; } location ~ /\.(?!well-known).* { deny all; } }页面安装{card-default label="欢迎页" width="80%"}{/card-default}{card-default label="数据库配置" width="80%"}{/card-default}{card-default label="导入数据" width="80%"}{/card-default}{card-default label="安装成功" width="80%"}{/card-default}{card-default label="后台" width="80%"}{/card-default}
2023年02月28日
17 阅读
0 评论
0 点赞
2023-02-27
WooCommerce对接第三方支付(易支付)
前言WooCommerce是一款免费的WordPress电子商务插件,可帮助你在网上快速建立一个强大的商店。它可以帮助你控制收银、处理订单、支持付款和购物车、建立商品目录以及使用不同的运费和税率等等。此外,它还可以集成到各种支付系统,有助于将你的商店扩展到全球市场。{callout color="#f0ad4e"}本文分享对接国内易支付的代码关键点。具体流程可以参考以前的历史文章。易支付有两种方式一种是页面跳转方式,另一种是API接口方式。一些小的支付平台,也是采用易支付的系统源码搭建的。名字叫什么的都有,比如码支付。{/callout}{card-default label="支付页面" width="80%"}{/card-default}代码签名 //排序 ksort($Body); reset($Body); //待签名字符串拼接 $unsign_str = ""; foreach ($Body as $k => $v){ $unsign_str = $unsign_str . $k . '=' . $v . '&'; } $unsign_str = substr($unsign_str, 0, -1).$this -> mzfpay_paykey; #签名 $clientSign = md5($unsign_str);页面跳转方式 $fieldsString = http_build_query($Body); //挂载自定义js wc_enqueue_js(' setInterval(function(){ $.blockUI({ message: "' . esc_js(__('Thank you for your order. We are now redirecting you to rapay to make payment.', 'mzfpay-for-woocommerce')) . '", baseZ: 99999, overlayCSS: { background: "#fff", opacity: 0.6 }, css: { padding: "20px", zindex: "9999999", textAlign: "center", color: "#555", border: "3px solid #aaa", backgroundColor:"#fff", cursor: "wait", lineHeight: "24px", } }); var start = new Date().getTime(); while (new Date().getTime() < start + 1000); document.getElementById("submit_mzfpay_payment_button").click(); },1000); '); //返回值 return '<div>'."\n". '<a class="button alt" id="submit_mzfpay_payment_button" href="' . $this->mzfpay_api . '?' . $fieldsString .'">'.__('Pay Now', 'superxpay-rapay-for-woocommerce').'</a>'."\n". '<a class="button cancel" href="'.$order->get_cancel_order_url().'">'.__('Cancel', 'superxpay-rapay-for-woocommerce').'</a>'."\n". '</div>' ;api接口方式 //构建提交变量 $args = array( 'headers' => array( 'Content-Type' => 'application/json', 'charset' => 'utf-8' ), 'timeout' => 45, 'redirection' => 5, 'httpversion' => '1.0', 'blocking' => true, 'body' => json_encode($Body), ); $postRequest = wp_remote_post($this->yzfpay_api, $args); if ($postRequest['response']['code'] === 200) { $result = json_decode($postRequest['body'], true, 512, JSON_BIGINT_AS_STRING); } else { throw new Exception("Unable to reach Viva Payments (" . $postRequest['response']['message'] . ")"); } //打印返回值 //error_log(__METHOD__ . PHP_EOL .print_r($result, true)); if ($result['code'] === 1) { $TradeNo = $result['trade_no']; $PayUrl = $result['h5_qrurl']; } else { throw new Exception("Unable to create order code (" . $result['msg'] . ")"); } return '<span>Scan the QR code to complete the payment</span>'. '<div>'. '<img src="http://chart.apis.google.com/chart?chs=150x150&cht=qr&chld=L|0&chl='.rawurlencode($PayUrl).'" alt="QR code" widhtHeight="150" widhtHeight="150"/>'. '</div>'. '<div>'. '<a class="button alt" id="submit_uepay_payment_button" href="'.$return_url.'">'.__('Pay Completed', 'uepay-for-woocommerce').'</a>'. '<a class="button cancel" href="'.$order->get_cancel_order_url().'">'.__('Cancel', 'uepay-for-woocommerce').'</a>'. '</div>';完整项目代码woocommerce对接码支付插件源码历史文章WooCommerce对接第三方支付插件开发 WooCommerce对接第三方支付插件开发(二) WooCommerce对接第三方支付插件开发(三)
2023年02月27日
32 阅读
0 评论
0 点赞
2023-02-21
通过Django管理周期性任务-feapder爬虫
前言{callout color="#f0ad4e"}一开始感兴趣的信息比较少,直接用crontab启动就满足要求了。后台爬虫越来越多,有的爬虫早就失效了,也没发现。用了 feapder 作者的管理系统 feaplat 。系统功能很全面,但是随着功能的完善,价格也越来越贵。个人实在承担不起,只能花时间自己搞一个简易版的了。{/callout}{message type="success" content="我自己感兴趣的信息收集回来通过Django管理,把爬虫功能顺便集成到里面了。"/}{card-default label="项目" width="75%"}{/card-default}功能实现模型设计隐藏内容,请前往内页查看详情后台管理{message type="success" content="默认就能用,通过admin.py可以自定义需要显示的内容。"/}# Register your models here. class SpiderInfofAdmin(admin.ModelAdmin): #后台展示字段 list_display = ['id', 'sname', 'filepath', 'workpath', 'image', 'addtime', 'snote'] #搜索字段 search_fields = ['sname'] class SpiderTaskAdmin(admin.ModelAdmin): #后台展示字段 list_display = ['id', 'sname', 'snote', 'addtime', 'runtime_show', 'total', 'repeat', 'valid', 'status_colored', 'operate'] #过滤字段 list_filter = ["status"] #搜索字段 search_fields = ['sname'] #只读字段 readonly_fields = ['id', 'addtime', 'runtime', 'total', 'repeat', 'valid', 'status'] #自定义动作 actions = ['schedule_switch']{card-default label="任务界面" width="75%"}{/card-default}异步任务{message type="success" content="异步任务和周期性任务通过celery实现"/}项目主settings.py添加内容INSTALLED_APPS = [ # 略 'django_celery_beat', #略 ] # Celery配置 # BROKER和BACKEND配置,这里用了本地的redis,其中1和2表示分别用redis的第一个和第二个db CELERY_BROKER_URL = 'redis://172.17.0.10:6379/1' CELERY_RESULT_BACKEND = 'redis://172.17.0.10:6379/2' # CELERY 时间 CELERY_TIMEZONE = TIME_ZONE DJANGO_CELERY_BEAT_TZ_AWARE = False #指定任务接收的内容序列化类型 CELERY_ACCEPT_CONTENT = ['application/json'] #任务和任务结果序列化方式 CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json' #超过时间 CELERY_TASK_RESULT_EXPIRES = 12 * 30 #是否压缩 CELERY_MESSAGE_COMPRESSION = 'zlib' #并发数默 CELERYD_CONCURRENCY = 2 #celery worker 每次去redis取任务的数量认已CPU数量定 CELERYD_PREFETCH_MULTIPLIER = 2 #每个worker最多执行3个任务就摧毁,避免内存泄漏 CELERYD_MAX_TASKS_PER_CHILD = 3 #可以防止死锁 CELERYD_FORCE_EXECV = True #celery 关闭UTC时区 CELERY_ENABLE_UTC = False #celery 并发数设置,最多可以有20个任务同时运行 CELERYD_CONCURRENCY = 20 CELERYD_MAX_TASKS_PER_CHILD = 4 #celery开启数据库调度器,数据库修改后即时生效 CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler' #解决告警 DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'2.同目录下新增celery.pyimport os from celery import Celery,platforms from django.conf import settings # 设置环境变量 os.environ.setdefault('DJANGO_SETTINGS_MODULE','taskmon.settings') # 实例化 app = Celery('taskmon') # namespace='CELERY'作用是允许你在Django配置文件中对Celery进行配置 # 但所有Celery配置项必须以CELERY开头,防止冲突 app.config_from_object('django.conf:settings', namespace='CELERY') # 自动从Django的已注册app中发现任务 app.autodiscover_tasks() #允许root 用户运行celery platforms.C_FORCE_ROOT = True # 一个测试任务 @app.task(bind=True) def debug_task(self): print('Request: {0!r}'.format(self.request))3.项目目录下tasks.py#操作docker from celery import shared_task from .utils import process_start @shared_task def sync_start_process(sname): """ 异步执行任务 """ process_start(sname)4.celery启动#任务调度 celery multi start worker -A taskmon -l info --logfile=/logs/celery_worker.log celery -A taskmon beat -l info --logfile=/logs/celery_beat.log{card-default label="运行日志" width="75%"}{/card-default}添加周期任务隐藏内容,请前往内页查看详情删除周期任务def remove_celery_task(sid): """ 删除计划任务 sid : 爬虫任务ID """ cname = str(sid) + '-' + '周期任务' #添加计划任务 with transaction.atomic(): save_id = transaction.savepoint() try: _p = PeriodicTask.objects.get(name=cname) if _p: _p.delete() print('{}删除计划任务成功'.format(cname)) return True except Exception as e: transaction.savepoint_rollback(save_id) print('{}删除计划任务失败,错误原因:'.format(cname) + str(e)) return False任务启动函数def process_start(sname): """ 执行任务并处理返回结果 sname: 任务名 cinfo: 启动容器所需的信息 """ con_name = 'spider_{}_1'.format(sname) containers = get_containers({"name":con_name}) if containers: print('有相同任务运行中...|{}|{}'.format(con_name, datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S"))) return False #查询库 spider_task = SpiderTask.objects.get(sname=sname) #构建docker启动信息 cinfo = { "name": con_name, "command": spider_task.command, #宿主机目录 "volumes": ['/opt/project/taskmon/myapp/spider/{}:{}'.format(spider_task.sinfo.filepath, spider_task.sinfo.workpath),], "shm_size": spider_task.sinfo.shm, "image": spider_task.sinfo.image, "working_dir": spider_task.sinfo.workpath, "remove": False, } #启动容器 result = run_container(cinfo) if result: #日志文件 log_path='/logs/{}_{}.log'.format(con_name, datetime.datetime.now().strftime("%H-%M-%S-%Y-%m-%d")) #保存日志 with open(log_path, 'wb') as fw: fw.write(result) #采集结果 d_nums = process_result(result) #更新 spider_task.total = d_nums[0] spider_task.repeat = d_nums[1] spider_task.valid = d_nums[2] spider_task.logpath = log_path spider_task.save() print('任务执行...|{}|{}'.format(con_name, datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")))容器启动函数def run_container(ddict): """ 运行容器 """ #print(ddict) container = client.containers.run( image=ddict['image'], name=ddict['name'], shm_size=ddict['shm_size'], volumes=ddict['volumes'], working_dir=ddict['working_dir'], remove=ddict['remove'], detach=True, command=ddict['command'] ) container.wait() result = container.logs() container.remove() return result结果处理函数{message type="success" content="统计每次处理收到的结果"/}def process_result(result): """ 处理返回结果 """ a = 0 b = 0 c = 0 lines = str(result, encoding = "utf-8").split('\n') for line in lines: if '待入库数据' in line: tmp_s = line.split('|')[3] nums = tmp_s.split(' ') a += int(nums[2]) b += int(nums[5]) c += int(nums[7]) return (a, b, c){card-default label="效果" width="80%"}{/card-default}相关文章Django后台展示(一) Django后台展示(二)FAQ自动添加周期任务后,启动报错{card-default label="报错" width="85%"}{/card-default}{message type="success" content="解决办法: 写入数据库django_celery_beat_periodictask表的args字段需要双引号括起来。"/}
2023年02月21日
20 阅读
0 评论
0 点赞
2023-02-10
苹果CMS内容管理系统部署教程
前言发现好多视频网站的模板基于苹果cms,找到了苹果cms的 官网 下载了最新的源码,部署测试一下。本文记录部署过程。{card-default label="首页" width="80%"}{/card-default}代码lnmp环境docker和docker-compose一键安装脚本基于docker的lnmp项目文件 , 解压密码:3emx苹果cms源码本文项目源码配置nginx配置{message type="success" content="services/nginx/conf/conf.d/default.conf"/}# Appadmin server { listen 80; server_name cms.webzhan.xyz; #改成自己的域名 root /www/web/maccms_v10/; #项目目录,在app目录下 server_tokens off; #include none.conf; index index.php index.html index.htm; access_log /www/web_logs/wp_access.log wwwlogs; error_log /www/web_logs/wp_error.log notice; location ~ \.php$ { fastcgi_pass php:9000; fastcgi_index index.php; include fcgi.conf; } #需要注意伪静态的配置 if (!-e $request_filename) { rewrite ^/index.php(.*)$ /index.php?s=$1 last; rewrite ^/api.php(.*)$ /api.php?s=$1 last; rewrite ^/adm0.php(.*)$ /adm0.php?s=$1 last; rewrite ^(.*)$ /index.php?s=$1 last; break; } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; } location ~ .*\.(js|css)?$ { expires 12h; } }数据库建库授权CREATE DATABASE `cms` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin; create user 'wpuser'@'%' IDENTIFIED BY 'wpuserxxx'; grant all privileges on cms.* to 'wpuser'@'%'; flush privileges;导入导出# 导入分类数据 mysqldump -uroot -pmariadb@123 -h127.0.0.1 -t cms --tables mac_type > mac_type.sql # 导入 mysql -uroot -pmariadb@123 -h 127.0.0.1 cms < mac_type.sql安装http://cms.webzhan.xyz {callout color="#f0ad4e"}按照提示下一步即可安装完成后,修改admin.php名称,nginx的伪静态规则也要改{/callout}{card-default label="协议" width="80%"}{/card-default}{card-default label="环境检查" width="80%"}{/card-default}{card-default label="环境检查" width="80%"}{/card-default}{card-default label="完成" width="80%"}{/card-default}{card-default label="后台" width="80%"}{/card-default}采集资源推荐{message type="success" content="使用官方推荐网站测试"/}隐藏内容,请前往内页查看详情采集设置{message type="success" content="采集->自定义接口"/}{card-default label="设置" width="80%"}{/card-default}绑定分类先创建分类{message type="success" content="基础->分类管理"/}{card-default label="分类" width="80%"}{/card-default}采集数据后,绑定分类{card-default label="采集" width="80%"}{/card-default}模板{message type="success" content="苹果cms的模板比较多,很容易找到自己喜欢的模板。部署也比较简单"/}模板部署将模板上传到网站template目录通过后台设置{card-default label="模板设置" width="80%"}{/card-default}播放器{message type="success" content="如果采集的视频无法播放,将资源采集站带的播放器下载并导入"/}{card-default label="导入" width="80%"}{/card-default}
2023年02月10日
36 阅读
0 评论
0 点赞
2023-02-08
Joe主题侧边栏添加联系方式
前言好久没有折腾自己的博客了,最近遇到一个网友加我好友,说找了半天才找到我的联系方式。花了点时间,将自己的联系方式加到侧边栏比较明显的地方{card-default label="效果" width="75%"}{/card-default}参考博客的侧栏增加社交信息2.0实现PC端{message type="success" content="Joe/public/aside.php"/} <!-- PC侧栏社交信息 --> <?php if ($this->options->SocialInfo && (($this->options->SocialSwitch === 'on') || ($this->options->SocialSwitch === 'on2'))) : ?> <?php $SocialInfo = $this->options->SocialInfo; if ($SocialInfo) { $SocialInfo_arr = explode("\r\n", $SocialInfo); if (count($SocialInfo_arr) > 0) { for ($i = 0; $i < count($SocialInfo_arr); $i++) { $SocialTitle = explode("||", $SocialInfo_arr[$i])[0]; $SocialIco = explode("||", $SocialInfo_arr[$i])[1]; $SocialUrl = explode("||", $SocialInfo_arr[$i])[2]; $SocialInfos[] = array("SocialTitle" => trim($SocialTitle), "SocialIco" => trim($SocialIco), "SocialUrl" => trim($SocialUrl)); } } } ?> <section class="top-social"> <?php foreach ($SocialInfos as $item) : ?> <li class="<?php echo $item['SocialTitle']; ?>"> <a class="<?php echo $item['SocialTitle']; ?>A" href="<?php echo $item['SocialUrl']; ?>" target="_blank" title="<?php echo $item['SocialTitle']; ?>"> <img src="<?php echo $item['SocialIco']; ?>" /> </a> </li> <?php endforeach; ?> </section> <?php endif; ?>{card-default label="位置" width="75%"}{/card-default}H5手机端{message type="success" content="Joe/public/header.php"/} <!-- PE侧栏社交信息 --> <?php if ($this->options->SocialInfo && (($this->options->SocialSwitch === 'on') || ($this->options->SocialSwitch === 'on2'))) : ?> <?php $SocialInfo = $this->options->SocialInfo; if ($SocialInfo) { $SocialInfo_arr = explode("\r\n", $SocialInfo); if (count($SocialInfo_arr) > 0) { for ($i = 0; $i < count($SocialInfo_arr); $i++) { $SocialTitle = explode("||", $SocialInfo_arr[$i])[0]; $SocialIco = explode("||", $SocialInfo_arr[$i])[1]; $SocialUrl = explode("||", $SocialInfo_arr[$i])[2]; $SocialInfos[] = array("SocialTitle" => trim($SocialTitle), "SocialIco" => trim($SocialIco), "SocialUrl" => trim($SocialUrl)); } } } ?> <section class="top-social pe-social"> <?php foreach ($SocialInfos as $item) : ?> <li class="<?php echo $item['SocialTitle']; ?>"> <a class="<?php echo $item['SocialTitle']; ?>A" href="<?php echo $item['SocialUrl']; ?>" target="_blank" title="<?php echo $item['SocialTitle']; ?>"> <img src="<?php echo $item['SocialIco']; ?>" /> </a> </li> <?php endforeach; ?> </section> <?php endif; ?>{card-default label="位置" width="75%"}{/card-default}后台设置{message type="success" content=" Joe/functions.php"/} // 侧栏社交信息开关 $SocialSwitch = new Typecho_Widget_Helper_Form_Element_Select( 'SocialSwitch', array( 'off' => '关闭(默认)', 'on' => '开启PC社交信息', 'on1' => '开启PE社交信息', 'on2' => '同时开启PC与PE社交信息', ), 'off', '是否启用侧栏社交信息', '介绍:开启后,侧栏展示社交信息功能(必须填写下面的侧栏社交信息)' ); $SocialSwitch->setAttribute('class', 'joe_content joe_aside'); //没有custom.php就把joe_custom改成joe_other $form->addInput($SocialSwitch->multiMode()); //侧栏社交信息 $SocialInfo = new Typecho_Widget_Helper_Form_Element_Textarea( 'SocialInfo', NULL, NULL, '侧栏社交信息', '介绍:用于设置侧栏社交信息, 一行最多5个, 大于5个自动换行<br /> 格式:社交简称(微信必须固定格式WeChat) || 社交图标|| 跳转链接(微信写二维码链接)<br /> 微信: WeChat||https://fuuuy.cn/usr/uploads/image/wechat.png||https://www.itbunan.xyz/usr/uploads/image/gongzhonghao.png <br /> 其他:一行一个,代表一个社交信息' ); $SocialInfo->setAttribute('class', 'joe_content joe_aside'); //没有custom.php就把joe_custom改成joe_other $form->addInput($SocialInfo);{card-default label="效果" width="75%"}{/card-default}加载自定义css和js{message type="success" content="Joe/public/include.php"/}<!--自定义css --> <link rel="stylesheet" href="<?php $this->options->themeUrl('assets/css/custom.min.css'); ?>"> <!--自定义js --> <script src="<?php $this->options->themeUrl('assets/js/custom.min.js'); ?>"></script>
2023年02月08日
22 阅读
0 评论
0 点赞
2023-01-13
WooCommerce对接第三方支付插件开发(三)
前言以前对接过woocommerce的支付通道,优化了代码结构和新增插件管理页面直接跳转到插件设置页面的功能,记录一下。{card-default label="插件设置" width="80%"}{/card-default}代码/* Add custom action links ------------------------------------------------------------ */ add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'superxpay_action_links'); function superxpay_rapay_action_links($links) { $plugin_links = array( '<a href="' . admin_url('admin.php?page=wc-settings&tab=checkout§ion=superxpay') . '">' . __('Settings', 'superxpay') . '</a>', ); // Merge our new link with the default ones return array_merge($plugin_links, $links); }历史WooCommerce对接第三方支付插件开发(二)WooCommerce对接第三方支付插件开发
2023年01月13日
31 阅读
0 评论
0 点赞
2023-01-09
爬虫管理系统FEAPLAT部署与使用
前言去年用feapder写了几个小爬虫,定时收集自己感兴趣的数据,运行的挺稳定的。最近又添加了几个新的,同时发现原先写的有几个早就失效了,一直没有发现。于是花时间折腾一下官方的 feaplat爬虫管理系统,新版本好像可以免费20个采集任务,够自己用了。部署安装dockerdocker和docker-compose一键安装脚本# 配置 docker swarm docker swarm init ## 有多块网卡的话 docker swarm init --advertise-addr 172.17.0.10docker-compose.yaml{message type="success" content="我的服务器上已经安装了mysql和redis,改造一下docker-compose.yaml,直接使用自己的了。"/}version: "3.5" x-logging: &default-logging options: max-size: "100m" max-file: "1" driver: json-file services: feapder_front: container_name: feapder_front image: ${FRONT_IMAGE} restart: always environment: - BACKEND_URL=http://feapder_backend:${BACKEND_PORT} - FRONT_PORT=${FRONT_PORT} ports: - ${FRONT_PORT}:${FRONT_PORT} # 前端端口 (自定义端口:80) depends_on: - feapder_backend logging: *default-logging feapder_backend: container_name: feapder_backend image: ${BACKEND_IMAGE} restart: always command: /wait-for-it.sh 172.17.0.10:3306 -t 60 --strict -- uvicorn main:app --host 0.0.0.0 --workers ${BACKEND_WORKER} --port ${BACKEND_PORT} # workers 为后端服务的个数,爬虫多可改大点 ports: - ${BACKEND_PORT}:${BACKEND_PORT} # 后端端口 (自定义端口:8000) environment: - FEAPDER_BACKEND_URL=http://${BACKEND_HOST}:${BACKEND_PORT} - AUTHORIZATION_CODE=${AUTHORIZATION_CODE} # 授权码 - DB_URL=mysql+pymysql://fpuser:fpuserxxx@172.17.0.10:3306/feapder_platform?charset=utf8mb4 # 后端数据库配置 - REDIS_DB_URL=redis://:@172.17.0.10:6379/0 # redis数据库连接配置 redis://[[username]:[password]]@[host]:[port]/[db] - ACCESS_TOKEN_EXPIRE_MINUTES=1440 # 管理系统账号cookie过期时间 单位分钟 - SPIDER_IMAGE=${SPIDER_IMAGE} # 爬虫镜像 - SPIDER_AUTO_PULL_IMAGE=1 # 是否自动拉取镜像 否则需要在爬虫节点手动 docker pull 爬虫镜像,为了加快启动速度,可以设置0 - SPIDER_ENV={} # 爬虫环境变量 值为json类型 # 爬虫容器启动参数,支持的参数使用 docker service create --help 查看 - SPIDER_RUN_ARGS={"--network":"feaplat"} # git ssh 私有密钥,不填则使用默认的 - GIT_SSH_PRIVATE_KEY=${GIT_SSH_PRIVATE_KEY} # 监控配置 - INFLUXDB_HOST=${INFLUXDB_HOST} - INFLUXDB_DB=${INFLUXDB_DB} - INFLUXDB_ADMIN_USER=${INFLUXDB_ADMIN_USER} - INFLUXDB_ADMIN_PASSWORD=${INFLUXDB_ADMIN_PASSWORD} - INFLUXDB_PORT_TCP=8086 - INFLUXDB_PORT_UDP=8089 volumes: - "/var/run/docker.sock:/var/run/docker.sock" - "~/data/feapder/projects:/projects" # 上传的项目挂载, 本地目录:容器路径 depends_on: - influxdb logging: *default-logging feapder: container_name: feapder_worker image: ${SPIDER_IMAGE} influxdb: restart: always image: registry.cn-hangzhou.aliyuncs.com/feapderd/influxdb:1.8.6 container_name: feapder_influxdb volumes: - ~/data/feapder/influxdb:/var/lib/influxdb - ./conf/influxdb.conf:/etc/influxdb/influxdb.conf environment: - INFLUXDB_DB=${INFLUXDB_DB} - INFLUXDB_ADMIN_USER=${INFLUXDB_ADMIN_USER} - INFLUXDB_ADMIN_PASSWORD=${INFLUXDB_ADMIN_PASSWORD} - INFLUXDB_USER=influx - INFLUXDB_USER_PASSWORD=influx ports: - ${INFLUXDB_PORT_TCP}:8086 - ${INFLUXDB_PORT_UDP}:8089/udp logging: *default-logging networks: default: name: feaplat driver: overlay attachable: true.env{message type="error" content="可以自定义端口和镜象版本爬虫版本等"/}启动docker-compose up -d访问http://ip:804 {callout color="#f0ad4e"}默认账号密码:admin/admin{/callout}{card-default label="登录页面" width="75%"}{/card-default}其他数据表手动查询{message type="success" content="表结构挺简单的"/}# 查询所有任务 select * from feapder_task\G ## 修改任务自增id起始点,清理过期任务后 ALTER TABLE feapder_task AUTO_INCREMENT = 1; ## 修改任务id update feapder_task set id = 2 where id =23;{card-default label="任务信息" width="80%"}{/card-default}手动启动爬虫#启动 docker service create --name task_test --replicas 1 --workdir /task --mount type=bind,src=/opt/project/taskmonitor/myapp/spider/task,dst=/task registry.cn-hangzhou.aliyuncs.com/feapderd/feapder:2.3 tailf test.py #查看 docker service ps pzsutx0dhpkmngrs7roarsa6r #删除 docker service rm pzsutx0dhpkm
2023年01月09日
29 阅读
0 评论
0 点赞
2023-01-06
wordpress之woocommerce对接不知名第四方支付
前言最近接到一个新的需求,用wordpress的woocommerce做外贸独立站的人挺多的。总要对接一些小众的支付系统,只有开发文档。其实对接的多了,只有那简单的几步。组织参数,签名,提交然后接受返回结果。各种平台主要是签名方法和提交方式的差别。{card-describe title="签名要求"}1.支付、代付下单接口使用RSA加密(密钥长度1024位,密钥格式PKCS#8方式)加密2.使用工具类或者在线网址生成公钥和私钥,私钥自己保存,公钥上传至商户后台。使用私钥加密签名串3.Rsa最后做base64加密后需要进行URL编码(只对sign值做url编码){/card-describe}{card-describe title="提交方式"}POST: application/json{/card-describe}组织参数和签名{card-default label="构建参数" width="80%"}{/card-default}加密参数{card-default label="加密" width="75%"}{/card-default}订单提交{card-default label="订单提交" width="85%"}{/card-default}
2023年01月06日
61 阅读
0 评论
0 点赞
1
2
...
7