找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 8138|回复: 10

[脚本] 求助ExpAuto的到期提醒的问题.

[复制链接]
发表于 2011-12-28 13:22:24 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

×
本帖最后由 kzyfl 于 2012-1-5 23:21 编辑

# 脚本名称: ExpAuto
# 脚本版本: 1.03
# 脚本作者: Mxso
# Email: mxsogm@gmail.com
# QQ/TM: 84046811
# 版本日期: 2011年1月3日
# 适用系统: (实例为 PPPoE到期 Web Proxy 错误页面通知,提前3天通知用户,到期停止用户,3.30测试通过,其他版本未测试)
# 脚本功能: 对PPP及Hotspot用户期限操作;此脚本的实例对用户状态(禁用/启用)进行设置及剔除到期在线用户,添加其他功能可参考下面例子
# 其他功能: 通过注释添加system scheduler星期制的禁用启用,注释格式:[7位布尔值]第一位是星期日,第二位是星期一,以此类推,E为启用,D为禁用
# 例:[EDDDDDE]代表只有周六日启用该scheduler,[DEEEEED]这个刚好相反,只有星期一至五启用该scheduler;
# 注意:被设置状态(启用/禁用)的scheduler运行时间不能调整到刚好00:00:00,因为00:00:00刚好在执行此脚本,未能00:00:00就设置好状态

# 添加用户注释日期格式:
# 例1:"张三[20100608]到期"(双引号里面为注释内容,[]里面为日期八位数字),
# 例2:"李四[+365]到期",[+365]指当前日期加365天,在下次调用脚本时注释将自动变为"李四[八位当前日期+365]到期",
# 假设当前日期为2010年4月4日立即调用脚本注释内容将变为"李四[20100404+365]到期",也就是2010年4月4日的365天后到期
# 例3:支持累加运算,假设[20090501+365]将近到期,用户续费可以在后面添加+X天,[20090501+365+180]这里加180天

#获取公元至今日( $Today 变量为公元至今已过的天数)
:local Date [/system clock get date];:local Year ([:pick $Date 7 11]-1)
:local Month ([:find jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec [:pick $Date 0 3]])
:local Day [:pick $Date 4 6];:if ([:pick $Date 4 5] = 0) do={:set Day [:pick $Date 5 6]};:set Day ($Day-1)
:local leapyear 0,31,59,90,120,151,181,212,243,273,304,334,0,31,60,91,121,152,182,213,244,274,305,335
:global Today ($Year*365+$Year/4);:if (($Year-$Year/4*4) != 3) do={:set Today ($Today+[:pick $leapyear $Month]+$Day)} else={:set Today ($Today+[:pick $leapyear ($Month+12)]+$Day)}
:local usname;:local uspfl;:local Ccomment;:local lc;:local rc;:local Exp;:local js;:local pcl;:local CYear;:local CMonth;:local CDay;:local CToday

#利用公元天数计算今天是星期几,0代表星期日
:global Week ($Today-$Today/7*7)
#:log info ("今天是星期" . $Week)

#scheduler处理开始
/system scheduler
:foreach i in=[find comment!="" name!="ExpAuto"] do={
:set Ccomment [get $i comment];:set lc [:find $Ccomment "["];:set rc [:find $Ccomment "]"]
:if ([:typeof $lc]="num" && [:typeof $rc]="num" && ($lc+1+$Week)<$rc) do={
:set Exp [:pick $Ccomment ($lc+1+$Week)]
:if ($Exp="e"||$Exp="E"||$Exp="1") do={:if ([get $i disabled ]) do={enable $i}}
:if ($Exp="d"||$Exp="D"||$Exp="0") do={:if (![get $i disabled ]) do={disable $i}}
}}
#scheduler处理结束


#PPP处理开始
/ppp secret
:foreach i in=[find comment!=""] do={
:set Ccomment [get $i comment];:set lc [:find $Ccomment "["];:set rc [:find $Ccomment "]"]
:if ([:typeof $lc]="num" && [:typeof $rc]="num" && $lc<$rc) do={
:set Exp [:pick $Ccomment ($lc+1) $rc];:set js 0;:set CToday 0
:if ([:pick $Exp 0 1]!="+" && [:len $Exp]>7 && [:typeof [:tonum [:pick $Exp 0 8]]]="num") do={
:set usname [get $i name];:set uspfl [get $i profile];:set CYear ([:pick $Exp 0 4]-1);:set CToday ($CYear*365+$CYear /4)
:set CMonth [:pick $Exp 4 6];:if ([:pick $Exp 4 5] = 0) do={ :set CMonth [:pick $Exp 5 6]};:set CMonth ($CMonth-1)
:set CDay [:pick $Exp 6 8];:if ([:pick $Exp 6 7] = 0) do={ :set CDay [:pick $Exp 7 8]};:set CDay ($CDay-1)
:if (($CYear-$CYear/4*4) != 3) do={:set CToday ($CToday+[:pick $leapyear $CMonth]+$CDay)} else={:set CToday ($CToday+[:pick $leapyear ($CMonth+12)]+$CDay)}}
:set pcl [:find $Exp "+"];:if ([:typeof $pcl]="num" && ($pcl>7 || $pcl=0) && ([:len $Exp]-1)>$pcl) do={
:if ($pcl = 0) do={:set CToday $Today;:set CYear ($Year+1);:set CMonth ($Month+1);:set CDay ($Day+1)
:if ([:len $CMonth]<2) do={:set CMonth ("0" . $CMonth)};:if ([:len $CDay]<2) do={:set CDay ("0" . $CDay)}
set $i comment=([:pick $Ccomment 0 $lc] . "[" .($CYear . $CMonth . $CDay) . [:pick $Exp $pcl [:len $Exp]] . "]" . [:pick $Ccomment ($rc+1) [:len $Ccomment]])}
:while ([:typeof [:find $Exp "+"]]="num") do={
:set Exp [:pick $Exp ($pcl+1) [:len $Exp]];:set pcl [:find $Exp "+"];:if ([:typeof $pcl]!="num") do={:set pcl [:len $Exp]}
:set js ($js+[:tonum [:pick $Exp 0 $pcl]])};:set CToday ($CToday+$js)}

#例子2:提前3天踢出到期用户并给予设置到期规则
:if (($CToday-3) < $Today) do={:if (![get $i disabled ] && [:pick $uspfl 0 8]!="ExpAuto_") do={
:if ([:len [..profile find name="ExpAuto_" . $uspfl]]=0) do={..profile add name=("ExpAuto_" . $uspfl) copy-from=$uspfl address-list=ExpAuto_expired}
set $i profile=("ExpAuto_" . $uspfl);/ppp active remove [find name=$usname]}} else={:if ([:pick $uspfl 0 8]="ExpAuto_") do={
:if ([:len [..profile find name=[:pick $uspfl 8 [:len $uspfl]]]]=0) do={..profile add name=[:pick $uspfl 8 [:len $uspfl]] copy-from=$uspfl address-list=""}
set $i profile=[:pick $uspfl 8 [:len $uspfl]];:foreach acus in=[/ppp active find name=$usname] do={:local tempipaddr [/ppp active get $acus address]
/ip firewall address-list remove [find list=ExpAuto_expired address=$tempipaddr];/ip firewall address-list remove [find list=ExpAuto_allow address=$tempipaddr]}}}
#例子1:禁用并剔出到期PPP用户
:if ($CToday <= $Today) do={:if (![get $i disabled ]) do={disable $i;/ppp active remove [find name=$usname]}} else={:if ([get $i disabled ]) do={enable $i}}
#根据需要可添加或替换对用户的操作例子,假设提前5天,则在条件:if (($CToday-5) < $Today) do={执行通知操作…}
#:if (($CToday-5) < $Today) do={执行通知操作…}

}}
#PPP处理结束



routeros
 楼主| 发表于 2011-12-28 13:23:17 | 显示全部楼层
没上过学,更没学过编程,没办法,只有求助大家了.先谢了.
routeros
回复

使用道具 举报

发表于 2012-1-5 01:14:45 | 显示全部楼层
同需,请问你解决了没有。
routeros
回复

使用道具 举报

发表于 2012-1-5 08:37:27 | 显示全部楼层
  1. :if (($CToday-3) < $Today && (![get $i disabled ] && $uspfl!="ting")) do={set $i profile="ting";/ppp active remove [find name=$usname]}
复制代码
但不能充值加天数自动返回原本的规则
routeros
回复

使用道具 举报

发表于 2012-1-5 08:40:17 | 显示全部楼层
同时须把这实例删除
#例子2:提前3天踢出到期用户并给予设置到期规则
……
……
……

#根据需要可添……
routeros
回复

使用道具 举报

 楼主| 发表于 2012-1-5 22:25:22 | 显示全部楼层

谢谢mxso 大师了,我修改了一下你的脚本,可以实现到期后"ting",麻烦你指教指教,修改部分如下.
#例子2:提前3天踢出到期用户并给予设置到期规则
:if (($CToday-5) < $Today && $CToday > $Today) do={:if (![get $i disabled ] && [:pick $uspfl 0 8]!="ExpAuto_") do={
:if ([:len [..profile find name="ExpAuto_" . $uspfl]]=0) do={..profile add name=("ExpAuto_" . $uspfl) copy-from=$uspfl address-list=ExpAuto_expired}
set $i profile=("ExpAuto_" . $uspfl);/ppp active remove [find name=$usname]}} else={:if ([:pick $uspfl 0 8]="ExpAuto_") do={
:if ([:len [..profile find name=[:pick $uspfl 8 [:len $uspfl]]]]=0) do={..profile add name=[:pick $uspfl 8 [:len $uspfl]] copy-from=$uspfl address-list=""}
set $i profile=[:pick $uspfl 8 [:len $uspfl]];:foreach acus in=[/ppp active find name=$usname] do={:local tempipaddr [/ppp active get $acus address]
/ip firewall address-list remove [find list=ExpAuto_expired address=$tempipaddr];/ip firewall address-list remove [find list=ExpAuto_allow address=$tempipaddr]}}}
#例子1:踢出到期用户并改为ting
:if ($CToday <= $Today) do={:if (![get $i disabled ]) do={;/ppp active remove [find name=$usname]
/ppp secret set [/ppp secret find name=$usname] profile="ting"}} else={:if ([get $i disabled ]) do={enable $i}}

我把例1与例2上下颠倒了一下(不颠倒有一点小瑕疵),例2时间上增加一个条件.这样可以实现到期ting.并且可以实现日期叠加.虽说这样改基本达到要求,但还是有一点小问题,如果ting后,续费的话,必须再手动指定正常的PPP模板才可以上网,如果不手动指定,就自动生成ExpAuto_ting模板.还是上不去网,如果能设定的增加日期后,不用动任何其它设置,就能上网,像WAYOS软路由那样那就完美了,不知道大师有没有更完美的解决办法.
routeros
回复

使用道具 举报

发表于 2012-1-5 22:49:14 | 显示全部楼层
XXX  =  原本模板
ExpAuto_XXX  =  根据原本模板生成的模板 (其中添加了地址列表选项)
这个ExpAuto_XXX就是自动根据原模板生成的,如果充值操作后不更改用户模板选项,在下次调用脚本时会自动将到期模板(ExpAuto_XXX)更改为原本模板(XXX)
routeros
回复

使用道具 举报

 楼主| 发表于 2012-1-5 22:55:30 | 显示全部楼层
mxso 发表于 2012-1-5 22:49
XXX  =  原本模板
ExpAuto_XXX  =  根据原本模板生成的模板 (其中添加了地址列表选项)
这个ExpAuto_XXX就 ...

呵呵,还没睡呀,mxso大师,看来只有用不是太完美的到期前通知,到期后提醒的解决方案了.
routeros
回复

使用道具 举报

 楼主| 发表于 2012-1-5 22:58:52 | 显示全部楼层
zbhdpx 发表于 2012-1-5 01:14
同需,请问你解决了没有。

基本解决,就是不是十分完美,脚本就在上边贴子里.
routeros
回复

使用道具 举报

发表于 2012-1-5 23:06:31 | 显示全部楼层
本帖最后由 mxso 于 2012-1-5 23:08 编辑

# 版本日期: 2011年1月3日
这个版本的算法有问题
原因是用户注释的日期处理里闰年的计算漏了加上当月的日
routeros
回复

使用道具 举报

 楼主| 发表于 2012-1-5 23:13:53 | 显示全部楼层
mxso 发表于 2012-1-5 23:06
# 版本日期: 2011年1月3日
这个版本的算法有问题
原因是用户注释的日期处理里闰年的计算漏了加上当月的日

贴子是早一个星期前发的,当时修正版还没出来,现在用的就是修正版的.# 版本日期: 2011年12月31日
routeros
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|Archiver|手机版|小黑屋|软路由 ( 渝ICP备15001194号-1|渝公网安备 50011602500124号 )

GMT+8, 2024-11-24 11:28 , Processed in 0.060434 second(s), 4 queries , Gzip On, Redis On.

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表