Thinkai's Blog

Autohotkey|Python|php|aardio|VOIP|IT 爱好者

# encoding: utf-8
#!/usr/bin/python

import os
import time
import MySQLdb
#设置目录
timearray = time.localtiime(time.time())
timedir = time.strftime("%Y/%m/%d/",timearray)
monitordir = "/var/spool/asterisk/monitor/"+timedir
vi conv.p
# 打开数据库连接
db = MySQLdb.connect("localhost","root","Elastixdb","asteriskcdrdb" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

sql = "SELECT recordingfile from cdr where recordingfile like '%.wav';"
try:
   # 执行SQL语句
   cursor.execute(sql)
   # 获取所有记录列表
   results = cursor.fetchall()
   for row in results:
      recordingfile = row[0]
      if os.path.exists(monitordir+recordingfile):
      	  print "转换:%s" % monitordir+recordingfile
      	  os.system("sox "+monitordir+recordingfile+" "+monitordir+recordingfile.replace('wav','gsm'))
      	  os.remove(monitordir+recordingfile.replace('gsm','wav'))
      	  sql = "update cdr set recordingfile=replace(recordingfile,'wav','gsm') where recordingfile='"+recordingfile+"';"
      	  cursor.execute(sql)
      	  db.commit()
      else:
      	  print "找不到文件:%s" % monitordir+recordingfile
except:
   print "Error: unable to fecth data"

# 关闭数据库连接
db.close()


Nano云文件外链(FTP上传) Autohotkey【已失效】 2603

作者为 发表

Autohotkey

#NoEnv
;首先你要在ftp创建upload文件夹
FileInstall, ftp_upload.exe, ftp_upload.exe
Gui, add, edit, x0 y0 w300 h20 vpath,
Gui, Add, Button, x300 y0 w100 h20 gsfile, 浏览
Gui, add, edit, x0 y20 w300 h20 vdpath,
Gui, Add, Button, x300 y20 w100 h20 gupload, 上传获取URL
gui, show, , Nano云文件外链(FTP上传)
;定义你的ftp用户名密码
result := FtpOpen("ftp.nanoyun.com",,"xxxxx/xxxxxcdn","xxxxxxxpass")
if result = 0
{
    MsgBox, 4112, 错误, 无法连接到服务器
    ExitApp
}
return

sfile:
FileSelectFile, path, , , 选择要上传的文件, (*jpg;*.png;*.gif;*.zip;*.rar;*.zip;*.7z;*.ahk;*.aau;*.exe) ;允许上传的文件类型
if path
{
	IfNotInString, path, %A_Space%
		GuiControl, , path, % path
	else
	{
		FileCopy, % path, % npath := RegExReplace(path," ","_")
		GuiControl, , path, % npath
	}
	GuiControl, , dpath,
}

return

upload:
Gui, Submit, NoHide
if path
{
FileDelete, result.txt
SplitPath, path, , , ext
md5 := FileMD5(path)
/* 外部工具方案
RunWait, % ComSpec " /c ftp_upload.exe ftp.nanoyun.com user pass " path " /upload/" md5 "." ext " >result.txt", , Hide
FileRead, result, result.txt
if result
	MsgBox, 64, 提示, % result
*/
result := FtpPutFile(path, "/upload/" md5 "." ext, 2)
if result = 0
{
    MsgBox, 4112, 错误, 上传遇到错误!
    return
}
MsgBox, 64, 提示, % result "`n已复制到剪切板!"
GuiControl, , dpath, % Clipboard := "http://cdn.ywwx.com.cn/upload/" md5 "." ext ;此处是你的外链网址 需要修改
}
return

GuiClose:
FtpClose()
ExitApp

;ftp函数集
FtpCreateDirectory(DirName) { ;创建目录
global ic_hInternet
r := DllCall("wininet\FtpCreateDirectoryA", "uint", ic_hInternet, "str", DirName)
If (ErrorLevel != 0 or r = 0)
return 0
else
return 1
}

FtpRemoveDirectory(DirName) { ;移除目录
global ic_hInternet
r := DllCall("wininet\FtpRemoveDirectoryA", "uint", ic_hInternet, "str", DirName)
If (ErrorLevel != 0 or r = 0)
return 0
else
return 1
}

FtpSetCurrentDirectory(DirName) { ;设置当前目录
global ic_hInternet
r := DllCall("wininet\FtpSetCurrentDirectoryA", "uint", ic_hInternet, "str", DirName)
If (ErrorLevel != 0 or r = 0)
return 0
else
return 1
}

FtpPutFile(LocalFile, NewRemoteFile="", Flags=0) { ;上传文件
;Flags:
;FTP_TRANSFER_TYPE_UNKNOWN = 0 (Defaults to FTP_TRANSFER_TYPE_BINARY)
;FTP_TRANSFER_TYPE_ASCII = 1 文本方式
;FTP_TRANSFER_TYPE_BINARY = 2 二进制方式
If NewRemoteFile=
NewRemoteFile := LocalFile
global ic_hInternet
r := DllCall("wininet\FtpPutFileA"
, "uint", ic_hInternet
, "str", LocalFile
, "str", NewRemoteFile
, "uint", Flags
, "uint", 0) ;dwContext
If (ErrorLevel != 0 or r = 0)
return 0
else
return 1
}

FtpGetFile(RemoteFile, NewFile="", Flags=0) { ;下载文件
;Flags:
;FTP_TRANSFER_TYPE_UNKNOWN = 0 (Defaults to FTP_TRANSFER_TYPE_BINARY)
;FTP_TRANSFER_TYPE_ASCII = 1
;FTP_TRANSFER_TYPE_BINARY = 2
If NewFile=
NewFile := RemoteFile
global ic_hInternet
r := DllCall("wininet\FtpGetFileA"
, "uint", ic_hInternet
, "str", RemoteFile
, "str", NewFile
, "int", 1 ;do not overwrite existing files
, "uint", 0 ;dwFlagsAndAttributes
, "uint", Flags
, "uint", 0) ;dwContext
If (ErrorLevel != 0 or r = 0)
return 0
else
return 1
}

FtpGetFileSize(FileName, Flags=0) { ;获取文件大小
;Flags:
;FTP_TRANSFER_TYPE_UNKNOWN = 0 (Defaults to FTP_TRANSFER_TYPE_BINARY)
;FTP_TRANSFER_TYPE_ASCII = 1
;FTP_TRANSFER_TYPE_BINARY = 2
global ic_hInternet
fof_hInternet := DllCall("wininet\FtpOpenFileA"
, "uint", ic_hInternet
, "str", FileName
, "uint", 0x80000000 ;dwAccess: GENERIC_READ
, "uint", Flags
, "uint", 0) ;dwContext
If (ErrorLevel != 0 or fof_hInternet = 0)
return -1

FileSize := DllCall("wininet\FtpGetFileSize", "uint", fof_hInternet, "uint", 0)
DllCall("wininet\InternetCloseHandle",  "UInt", fof_hInternet)
return, FileSize
}


FtpDeleteFile(FileName) { ;删除文件
global ic_hInternet
r :=  DllCall("wininet\FtpDeleteFileA", "uint", ic_hInternet, "str", FileName)
If (ErrorLevel != 0 or r = 0)
return 0
else
return 1
}

FtpRenameFile(Existing, New) { ;重命名文件
global ic_hInternet
r := DllCall("wininet\FtpRenameFileA", "uint", ic_hInternet, "str", Existing, "str", New)
If (ErrorLevel != 0 or r = 0)
return 0
else
return 1
}

FtpOpen(Server, Port=21, Username=0, Password=0 ,Proxy="", ProxyBypass="") { ;打开ftp连接
IfEqual, Username, 0, SetEnv, Username, anonymous
IfEqual, Password, 0, SetEnv, Password, anonymous

If (Proxy != "")
AccessType=3
Else
AccessType=1
;#define INTERNET_OPEN_TYPE_PRECONFIG                    0   // use registry configuration
;#define INTERNET_OPEN_TYPE_DIRECT                       1   // direct to net
;#define INTERNET_OPEN_TYPE_PROXY                        3   // via named proxy
;#define INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY  4   // prevent using java/script/INS

global ic_hInternet, io_hInternet, hModule
hModule := DllCall("LoadLibrary", "str", "wininet.dll")

io_hInternet := DllCall("wininet\InternetOpenA"
, "str", A_ScriptName ;lpszAgent
, "UInt", AccessType
, "str", Proxy
, "str", ProxyBypass
, "UInt", 0) ;dwFlags

If (ErrorLevel != 0 or io_hInternet = 0) {
FtpClose()
return 0
}

ic_hInternet := DllCall("wininet\InternetConnectA"
, "uint", io_hInternet
, "str", Server
, "uint", Port
, "str", Username
, "str", Password
, "uint" , 1 ;dwService (INTERNET_SERVICE_FTP = 1)
, "uint", 0 ;dwFlags
, "uint", 0) ;dwContext

If (ErrorLevel != 0 or ic_hInternet = 0)
return 0
else
return 1
}

FtpClose() { ;关闭ftp连接
global ic_hInternet, io_hInternet, hModule
DllCall("wininet\InternetCloseHandle",  "UInt", ic_hInternet)
DllCall("wininet\InternetCloseHandle",  "UInt", io_hInternet)
DllCall("FreeLibrary", "UInt", hModule)
}

FileMD5(filename) ;计算文件MD5值
{
    return CalcFileHash(filename, 0x8003, 64 * 1024)
}

CalcFileHash(filename, algid, continue = 0, byref hash = 0, byref hashlength = 0) ;计算文件hash
{
    fpos := ""
    if (!(f := FileOpen(filename, "r")))
    {
        return
    }
    f.pos := 0
    if (!continue && f.length > 0x7fffffff)
    {
        return
    }
    if (!continue)
    {
        VarSetCapacity(data, f.length, 0)
        f.rawRead(&data, f.length)
        f.pos := oldpos
        return CalcAddrHash(&data, f.length, algid, hash, hashlength)
    }
    hashlength := 0
    while (f.pos < f.length)
    {
        readlength := (f.length - fpos > continue) ? continue : f.length - f.pos
        VarSetCapacity(data, hashlength + readlength, 0)
        DllCall("RtlMoveMemory", "Ptr", &data, "Ptr", &hash, "Ptr", hashlength)
        f.rawRead(&data + hashlength, readlength)
        h := CalcAddrHash(&data, hashlength + readlength, algid, hash, hashlength)
    }
    return h
}

CalcAddrHash(addr, length, algid, byref hash = 0, byref hashlength = 0)
{
    static h := [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", "d", "e", "f"]
    static b := h.minIndex()
    hProv := hHash := o := ""
    if (DllCall("advapi32\CryptAcquireContext", "Ptr*", hProv, "Ptr", 0, "Ptr", 0, "UInt", 24, "UInt", 0xf0000000))
    {
        if (DllCall("advapi32\CryptCreateHash", "Ptr", hProv, "UInt", algid, "UInt", 0, "UInt", 0, "Ptr*", hHash))
        {
            if (DllCall("advapi32\CryptHashData", "Ptr", hHash, "Ptr", addr, "UInt", length, "UInt", 0))
            {
                if (DllCall("advapi32\CryptGetHashParam", "Ptr", hHash, "UInt", 2, "Ptr", 0, "UInt*", hashlength, "UInt", 0))
                {
                    VarSetCapacity(hash, hashlength, 0)
                    if (DllCall("advapi32\CryptGetHashParam", "Ptr", hHash, "UInt", 2, "Ptr", &hash, "UInt*", hashlength, "UInt", 0))
                    {
                        loop % hashlength
                        {
                            v := NumGet(hash, A_Index - 1, "UChar")
                            o .= h[(v >> 4) + b] h[(v & 0xf) + b]
                        }
                    }
                }
            }
            DllCall("advapi32\CryptDestroyHash", "Ptr", hHash)
        }
        DllCall("advapi32\CryptReleaseContext", "Ptr", hProv, "UInt", 0)
    }
    return o
}


简单的cmd ftp上传工具 AAuto 2445

作者为 发表

AAuto快手

import console;
import inet.ftp;
var p = string.split(_CMDLINE," ");
if(p[1]!=null and p[2]!=null and p[3]!=null and p[4]!=null and p[5]!=null){
ftp = inet.ftp(p[1],p[2],p[3]);
if(!ftp){
	console.log("请输入正确的服务器参数");
	return;
}
file = ftp.upload(p[4],p[5],2) 
ftp.close()
}else{
console.log('参数:服务器 用户名 密码 源文件 目标ftp路径\n所有参数不能包含空格');
}
console.close();


import console;
import mysql.client;

//本地数据库
console.log("正在连接本地数据库服务器...");
var localdb,err = mysql.client(
	server = "localhost";
	uid = "root";
	pwd = "123456";
);

if(!localdb){
	console.log("连接数据库失败",err)
	return;
}
localdb.selectDb("blog");
console.log("本地数据库连接成功");

//远端数据库
console.log("正在连接远端数据库服务器...");
var remotedb,err = mysql.client(
	server = "8.8.8.8"; 
	uid = "xxxxx";
	pwd = "xxxxx";
);

if(!remotedb){
	console.log("连接数据库失败",err)
	return;
}
remotedb.selectDb("blog");
console.log("远端数据库连接成功");

//同步本地日志到远端
console.log("同步本地日志到远端");
//查询最大ID
var result = remotedb.query("SELECT max(ID) as MAXID FROM wp_posts");
var remote_post_max_id = result.fetchObject()["MAXID"];
//console.log("远端最大ID:"++remote_post_max_id)
result.free();
//查询本地
var result = localdb.query("SELECT ID FROM wp_posts where ID>"++tostring(remote_post_max_id));
var local_post_sync_count = result.numRows();
console.log("需同步"++local_post_sync_count)
result.free();
//执行同步

if(local_post_sync_count>0){
//首先替换网址
localdb.exec("update wp_posts set post_content=replace(post_content,'thinkai.net','thinkai.net') where ID>"++tostring(remote_post_max_id));

var result = localdb.query("SELECT * FROM wp_posts where ID>"++tostring(remote_post_max_id));
for(i=1;local_post_sync_count){
var row = result.fetchObject();
	console.log(string.concat("同步ID:",row['ID']," 标题:",row['post_title']));
	remotedb.exec("insert into wp_posts values (@ID, @post_author, @post_date, @post_date_gmt, @post_content, @post_title, @post_excerpt, @post_status, @comment_status, @ping_status, @post_password, @post_name, @to_ping, @pinged, @post_modified, @post_modified_gmt, @post_content_filtered, @post_parent, @guid, @menu_order, @post_type, @post_mime_type, @comment_count)",row)
}
}

//同步本地日志分类到远端
console.log("同步本地日志分类到远端");
//查询最大ID
var result = remotedb.query("SELECT max(object_id) as MAXID FROM wp_term_relationships");
var remote_term_max_id = result.fetchObject()["MAXID"];
result.free();
//查询本地
var result = localdb.query("SELECT object_id FROM wp_term_relationships where object_id>"++tostring(remote_term_max_id));
var local_term_sync_count = result.numRows();
console.log("需同步"++local_term_sync_count)
result.free();
//执行同步

if(local_term_sync_count>0){
var result = localdb.query("SELECT * FROM wp_term_relationships where object_id>"++tostring(remote_term_max_id));
for(i=1;local_term_sync_count){
var row = result.fetchObject();
	console.log(string.concat("同步ID:",row['object_id']));
	remotedb.exec("insert into wp_term_relationships values (@object_id, @term_taxonomy_id, @term_order)",row)
}
}

//同步本地分类项目到远端
console.log("同步本地分类项目到远端");
//查询最大ID
var result = remotedb.query("SELECT max(term_taxonomy_id) as MAXID FROM wp_term_taxonomy");
var remote_termt_max_id = result.fetchObject()["MAXID"];
result.free();
//查询本地
var result = localdb.query("SELECT term_taxonomy_id FROM wp_term_taxonomy where term_taxonomy_id>"++tostring(remote_termt_max_id));
var local_termt_sync_count = result.numRows();
console.log("需同步"++local_termt_sync_count)
result.free();
//执行同步

if(local_termt_sync_count>0){
var result = localdb.query("SELECT * FROM wp_term_taxonomy where term_taxonomy_id>"++tostring(remote_termt_max_id));
for(i=1;local_termt_sync_count){
var row = result.fetchObject();
	console.log(string.concat("同步ID:",row['term_taxonomy_id']));
	remotedb.exec("insert into wp_term_taxonomy values (@term_taxonomy_id, @term_id, @taxonomy, @description, @parent, @count)",row)
}
}
//查询最大ID
var result = remotedb.query("SELECT max(term_id) as MAXID FROM wp_terms");
var remote_term_max_id = result.fetchObject()["MAXID"];
result.free();
//查询本地
var result = localdb.query("SELECT term_id FROM wp_terms where term_id>"++tostring(remote_term_max_id));
var local_term_sync_count = result.numRows();
console.log("需同步"++local_term_sync_count)
result.free();
//执行同步

if(local_term_sync_count>0){
var result = localdb.query("SELECT * FROM wp_terms where term_id>"++tostring(remote_term_max_id));
for(i=1;local_term_sync_count){
var row = result.fetchObject();
	console.log(string.concat("同步ID:",row['term_id']));
	remotedb.exec("insert into wp_terms values (@term_id, @name, @slug, @term_group)",row)
}
}
localdb.close();
remotedb.close();
console.pause();


Asterisk队列监控的简单实现 Autohotkey+php+cli 4061

作者为 发表

AutohotkeyVOIP

首先你得有个获取队列情况的接口。如果使用ami的话太麻烦,接收的数据控制不好断节,所以我用了php+shell的形式获取数据。由于是局域网内使用,所以没加验证,有需求的自己加一下。

vi /var/www/html/cli.php

按i进入插入模式,粘贴上如下代码:

<?php
if(isset($_GET["cmd"])){ //先判断是否是预期参数
$fp=popen("asterisk -x \"".$_GET["cmd"]."\"","r"); //asterisk -x单句命令执行
while(!feof($fp))
echo fgets($fp,4096);
pclose($fp);
}
?>

按Esc输入":wq"保存退出。好了这个接口就可以使用来执行Asterisk CLI命令了。


然后通过你自己的坐席数据库接口,结合ahk写一个客户端。

;数据库配置信息
host = 135.230.71.1
api = http://%host%/sqlapi.php
#MaxMem 1024
;检查连通性
if Not InStr(ping_info := ping(host),"正常")
	{
	MsgBox, 4112, 网络错误, % ping_info
	ExitApp
	}
;创建GUI
gui, add, edit, x0 y0 w800 h400 vshow,
gui, show, , 本地呼叫系统坐席队列监控
gui, +AlwaysOnTop +Resize
;循环监控坐席状态 3秒间隔
Loop
{
out =
Queue := QueueStatus() ;获取队列状态数组
tp := get_result_obj("select 队列,业务 from [我是口令呼叫系统数据库].[dbo].[呼叫系统业务分派] where 状态=1 and ((cast(getdate() as time) between 开始时间1 and 结束时间1) or (cast(getdate() as time) between 开始时间2 and 结束时间2));") ;这是一个获取当前正在执行的任务的语句
task := []
for k,v in tp
	task[v[1]] := v[2]
tp := get_result_obj("select 分机,工号,姓名 from [我是口令呼叫系统数据库].[dbo].[呼叫系统分机信息] where [工号] is not null") ;获取已经登记的坐席信息
user := []
for k,v in tp
	user[v[1]] := {"id":v[2],"name":v[3]}
;格式化输出
for group,gv in Queue
{
	out .= task[group] "(" group ") 策略:" gv["strategy"] " " gv["incall"] "个等待来电 平均摘机时间:" gv["holdtime"] "(秒)平均通话时长:" gv["talktime"] "(秒)`n"
	for exten,mv in gv["member"]
	{
		sp =
		loop % 20-strlen(user[exten]["name"])
			sp .= " "
		;很笨的一种汉化替换方法
		status := RegExReplace(mv["status"],"In use","通话中")
		status := RegExReplace(status,"Not in use","空闲")
		status := RegExReplace(status,"Ringing","振铃")
		status := RegExReplace(status,"Unavailable","不可用")
		status := RegExReplace(status,"On hold","保持")
		out .= "	坐席:" user[exten]["name"] "(" user[exten]["id"] " " exten ")" sp " 类型:" mv["kind"] " 状态:"  status " 本次签入后呼叫量:" mv["callcount"] " 最后一次摘机:" mv["lastcalltime"] "秒前`n"
	}
	for k,cv in gv["caller"]
		out .= "	来电:" k "." cv["phone"] " 等待时间:" cv["wait"] "秒`n"
	out .= "`n"

}
GuiControl, , show, % out
Sleep, 3000
}
Return

;界面调整尺寸
GuiSize:
GuiControl, move, show, % "w" A_GuiWidth "h" A_GuiHeight
Return

;获取状态函数
QueueStatus(){
src := URLDownloadToVar("http://135.230.71.2/cli.php?cmd=queue show") ;你的Asterisk的cli接口
queues := []
Loop, Parse, src, `n, `r
{
	line := A_LoopField
	if RegExMatch(line,"(\d+) has (\d+) calls \(max unlimited\) in '(\w+)' strategy \((\d+)s holdtime, (\d+)s talktime\), W:\d+, C:\d+, A:\d+, SL:[0-9\.]+% within \d+s",qtm) ;队列标题匹配
	{
		cqueue := qtm1
		queues[cqueue] := {"incall":qtm2,"strategy":qtm3,"holdtime":qtm4,"talktime":qtm5,member:{},caller:{}}
	}
	else if RegExMatch(line,"\s+sip/(\d+) with penalty 1 \(ringinuse disabled\) \((\w+)\) \((.+)\) has taken (\d+) calls \(last was (\d+) secs ago\)",mcm) ;坐席匹配1
		queues[cqueue]["member"][mcm1] := {"kind":mcm2,"status":mcm3,"callcount":mcm4,"lastcalltime":mcm5}
	else if RegExMatch(line,"\s+sip/(\d+) with penalty 1 \(ringinuse disabled\) \((\w+)\) \((.+)\) has taken no calls yet",mcm) ;坐席匹配2
		queues[cqueue]["member"][mcm1] := {"kind":mcm2,"status":mcm3,"callcount":0,"lastcalltime":"NULL"}
	else if RegExMatch(line,"\s+(\d+). DAHDI/i1/(\d+)-\w+ \(wait: 0:(\d+), prio: 0\)",ccm) ;来电匹配
		queues[cqueue]["caller"][ccm1] := {"phone":ccm2,"wait":ccm3}
}
Return queues
}

;返回csv带标题格式查询结果
get_result_with_colname(sql){
global api
result := URLDownloadToVar(api "?str=" urlencode(sql "我是口令") "&o=1","UTF-8")
return RegExReplace(result,"`n$","")
}

;返回csv查询结果
get_result(sql){
global api
result := URLDownloadToVar(api "?str=" urlencode(sql "我是口令"),"UTF-8")
return RegExReplace(result,"`n$","")
}

;返回查询数组
get_result_obj(sql){
global api
result := URLDownloadToVar(api "?str=" urlencode(sql "我是口令"),"UTF-8")
;return RegExReplace(result,"`n$","")
line := strsplit(result,"`n","`r")
for k,v in line
{
	if v
		line[k] := strsplit(v,",")
	Else
		line.remove(k)
}
return line
}

;返回1行数据
get_1_result(sql){
global api
result := URLDownloadToVar(api "?str=" urlencode(sql "我是口令"),"UTF-8")
return RegExReplace(result,"^([^\n]*)\n.*$","$1")
}

;返回执行影响结果
get_rowcount(sql){
global api
result := URLDownloadToVar(api "?str=" urlencode(sql "我是口令") "&o=2","UTF-8")
return RegExReplace(result,"^([^\n]*)\n.*$","$1")
}

URLDownloadToVar(url, Encoding = "",Method="GET",postData=""){ ;网址,编码,请求方式,post数据
	hObject:=ComObjCreate("WinHttp.WinHttpRequest.5.1")
	if Method = GET
	{
		Try
		{
			hObject.Open("GET",url)
			hObject.Send()
		}
		catch e
			return -1
	}
	else if Method = POST
	{
		Try
		{
			hObject.Open("POST",url,False)
			hObject.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
			hObject.Send(postData)
		}
		catch e
			return -1
	}

	if (Encoding && hObject.ResponseBody)
	{
		oADO := ComObjCreate("adodb.stream")
		oADO.Type := 1
		oADO.Mode := 3
		oADO.Open()
		oADO.Write(hObject.ResponseBody)
		oADO.Position := 0
		oADO.Type := 2
		oADO.Charset := Encoding
		return oADO.ReadText(), oADO.Close()
	}
	return hObject.ResponseText
}



Ansi2UTF8(sString)
{
   Ansi2Unicode(sString, wString, 0)
   Unicode2Ansi(wString, zString, 65001)
   Return zString
}
UTF82Ansi(zString)
{
   Ansi2Unicode(zString, wString, 65001)
   Unicode2Ansi(wString, sString, 0)
   Return sString
}
Ansi2Unicode(ByRef sString, ByRef wString, CP = 0)
{
     nSize := DllCall("MultiByteToWideChar"
      , "Uint", CP
      , "Uint", 0
      , "Uint", &sString
      , "int", -1
      , "Uint", 0
      , "int", 0)
   VarSetCapacity(wString, nSize * 2)
   DllCall("MultiByteToWideChar"
      , "Uint", CP
      , "Uint", 0
      , "Uint", &sString
      , "int", -1
      , "Uint", &wString
      , "int", nSize)
}
Unicode2Ansi(ByRef wString, ByRef sString, CP = 0)
{
     nSize := DllCall("WideCharToMultiByte"
      , "Uint", CP
      , "Uint", 0
      , "Uint", &wString
      , "int", -1
      , "Uint", 0
      , "int", 0
      , "Uint", 0
      , "Uint", 0)
   VarSetCapacity(sString, nSize)
   DllCall("WideCharToMultiByte"
      , "Uint", CP
      , "Uint", 0
      , "Uint", &wString
      , "int", -1
      , "str", sString
      , "int", nSize
      , "Uint", 0
      , "Uint", 0)
}

urlencode(string){
string := Ansi2UTF8(string)
StringLen, len, string
Loop % len
{
SetFormat, IntegerFast, hex
StringMid, out, string, %A_Index%, 1
hex := Asc(out)
hex2 := hex
StringReplace, hex, hex, 0x, , All
SetFormat, IntegerFast, d
hex2 := hex2
If (hex2==33 || (hex2>=39 && hex2 <=42) || hex2==45 || hex2 ==46 || (hex2>=48 && hex2<=57) || (hex2>=65 && hex2<=90) || hex2==95 || (hex2>=97 && hex2<=122) || hex2==126)
	content .= out
Else
	content .= "`%" hex
}
Return content
}


ping(ip){
FileEncoding,
RunWait, %ComSpec% /c ping -n 1 %ip% >%A_Temp%\ahk_ping.tmp, , Hide
FileRead, content, %A_Temp%\ahk_ping.tmp
StringReplace, content, content, `r, , All
StringSplit, var, content, `n
If content Contains 请求超时,Request timed out
	Return "请求超时"
If content Contains 找不到主机,could not find host
	Return "找不到主机 "
If content Contains 无法访问目标主机,Destination host unreachable
	Return "无法访问目标主机 "
Else
	{
	time := RegExReplace(var3, "(来自|Reply from) \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}[\s的回复|]*: (字节|bytes)=\d{1,3}\ (时间|time)[=<](\d{1,3})ms TTL=\d{1,3}","$4")
	Return "正常 time:" time "ms"
	}
FileEncoding, UTF-8
}

;调试用 输出数组
show_obj(obj,menu_name:=""){
static id
if menu_name =
    {
    main = 1
    id++
    menu_name := id
    }
Menu, % menu_name, add,
Menu, % menu_name, DeleteAll
for k,v in obj
{
if (IsObject(v))
	{
    id++
    submenu_name := id
    Menu, % submenu_name, add,
    Menu, % submenu_name, DeleteAll
	Menu, % menu_name, add, % k ? "【" k "】[obj]" : "", :%submenu_name%
    show_obj(v,submenu_name)
	}
Else
	{
	Menu, % menu_name, add, % k ? "【" k "】" v: "", MenuHandler
	}
}
if main = 1
    menu,% menu_name, show

MenuHandler:
return
}

GuiClose:
ExitApp

好了,看下效果:


Runas验证用户名密码 Autohotkey 2993

作者为 发表

Autohotkey

RunAs, Administrator, ;用户名 密码
try
	Run, %ComSpec% /c, , hide
catch error ;错误对象
	MsgBox, 4112, % error["Message"], % error["Extra"]
RunAs


酷Q Pro机器人Autohotkey API插件 3747

作者为 发表

Autohotkey易语言

本插件有以下三种功能(┆分隔):

一、获取好友信息

格式:

消息号[0] 好友┆QQ号┆昵称

消息号[0] 群┆群号┆QQ号┆昵称


二、推送接收到的消息到指定窗口(注意换行符转义成\n)

格式:

消息号[1] 好友┆QQ号┆消息 【返回0忽略消息 1拦截消息其他插件不再处理】

消息号[2] 群┆群号┆QQ号┆消息 【返回0忽略消息 1拦截消息其他插件不再处理】

消息号[3] 讨论组┆讨论组号┆QQ号┆消息 【返回0忽略消息 1拦截消息其他插件不再处理】

消息号[4] 陌生人┆类型【1/来自在线状态 2/来自群临时】┆群号┆QQ号┆消息 【返回0忽略消息 1拦截消息其他插件不再处理】

消息号[5] 群上传┆群号┆QQ号┆消息 【返回0忽略消息 1拦截消息其他插件不再处理】

消息号[6] 群管变动┆类型【1/被取消管理员 2/被设置管理员】┆群号┆被操作QQ号 【返回0忽略消息 1拦截消息其他插件不再处理】

消息号[7] 群员减少┆类型【1/群员离开 2/群员被踢 3/自己(即登录号)被踢】┆群号┆QQ号┆被操作QQ号 【返回0忽略消息 1拦截消息其他插件不再处理】

消息号[8] 群员增加┆类型【1/管理员已同意 2/管理员邀请】┆群号┆QQ号┆被操作QQ号 【返回0忽略消息 1拦截消息其他插件不再处理】

消息号[9] 加好友┆QQ号┆消息 【返回0不处理 1同意 2拒绝】

消息号[10] 加群┆群号┆QQ号┆消息 【返回1 同意 其他值不处理】

三、发送消息

格式:

群┆群号┆消息

好友┆QQ号┆消息

讨论组┆讨论组号┆消息

群临时┆群号┆QQ号┆消息

在线临时┆QQ号┆消息

赞┆QQ号

群员禁言┆群号┆QQ号|禁言秒数(0取消)


注意事项:

所有信息通过WM_COPYDATA发送接收

插件自动获取你的第一个Edit控件的内容进行发送

你的接收窗口标题AHK_Monitor





酷Q_Pro_Autohotkey_API.zip


;加载你的dll 注意像下面这种文件名里面有多个点的写全文件名
hModule := DllCall("LoadLibrary", "Str", "time.cqp.dll", "Ptr")
;无参数类型返回字符串
;Ptr1 := DllCall("time.cqp.dll\info") ;返回指针
;带参数类型返回字符串
;注意一定要用numput,不然指针飞了报0x0000005的错
;长度自己定好
VarSetCapacity(p1,3),VarSetCapacity(p2,3),VarSetCapacity(p3,3),VarSetCapacity(p4,3)
numput(0x313233,p1),numput(0x343536,p2),numput(0x373839,p3),numput(0x404142,p4)
;注意这里指针一定要用&变量的格式传入指针 参数记得写全 不然报错-4
Ptr2 := DllCall("time.cqp.dll\plugmain","Ptr",&p1,"Ptr",&p2,"Ptr",&p3,"Ptr",&p4,"Ptr",&p4)
Error := ErrorLevel ;保存错误值
Str = ;初始输出字符串变量
Loop
{
	UChar := NumGet(0+Ptr2,A_index-1,"UChar")
	if (UChar=0x0) ;以0结束
		break
	Str .= Chr(UChar)
}
MsgBox % Str "`n" Error

从AHK_L 46+开始增加了StrPut()和StrGet()来读取写入字符串到内存。

hModule := DllCall("LoadLibrary", "Str", "time.cqp.dll", "Ptr")
StrPutVar("你",p1),StrPutVar("是",p2),StrPutVar("谁",p3),StrPutVar("啊",p4),StrPutVar("?",p5)
Ptr2 := DllCall("time.cqp.dll\plugmain","Ptr",&p1,"Ptr",&p2,"Ptr",&p3,"Ptr",&p4,"Ptr",&p5)
Error := ErrorLevel ;保存错误值
MsgBox % StrGet(Ptr2) "`n" Error

StrPutVar(string, ByRef var, encoding:="")
{
    ; 确定容量.
    VarSetCapacity( var, StrPut(string, encoding)
        ; StrPut 返回字符数, 但 VarSetCapacity 需要字节数.
        * ((encoding="utf-16"||encoding="cp1200") ? 2 : 1) )
    ; 复制或转换字符串.
    return StrPut(string, &var, encoding)
}


Autohotkey+Web Short Message安卓短信接口 2308

作者为 发表

Autohotkey安卓应用

;Autohotkey+Web Short Message(com.wangtai.smstwoman)短信接口
;Thinkai@2015-01-05

;注意每次运行APP的管理网址都不一样
ManageUrl = http://192.168.1.106:1984/8119

;获取参数
RegExMatch(ManageUrl,"^(http://.*:\d*/)(\d{4})",parameter)
global parameter1
global parameter2



;运用实例

;发短信
if (SendMsg(10001,7)=1)
	MsgBox, 64, 提示, 短信发送成功

;接收回复
NewMessage := GetNewMsg()
From :=  NewMessage[1]["person"] ? NewMessage[1]["person"] "(" NewMessage[1]["address"] ")" : "未知(" NewMessage[1]["address"] ")"
MsgBox % "From:" From "`n" NewMessage[1]["body"]

;获取联系人
Contact := GetContacts()
for k,v in Contact
{
	MsgBox, 64, 提示, 第一个联系人是%v%`,号码是%k%
	Return
}

;获取新消息函数(调用后收到的)
GetNewMsg(){
;返回数组说明
;数组[1]:
;	_id:消息ID
;	address:号码
;	body:短信正文
;	date:收信Uinx时间戳
;	person:联系人
	Loop
	{
		res := URLDownloadToVar(parameter1 "get_new_msg/" parameter2 "/", "utf-8","POST") ;获取最新短信的JSON数据
		if (strlen(res)>2)
			Return json_toobj(res)
		Sleep, 100
	}
}

;获取联系人函数
GetContacts(){
obj := {} ;初始数组
res := URLDownloadToVar(parameter1 "get_contacts/" parameter2 "/", "utf-8","POST") ;获取联系人的JSON数据
;处理格式问题
StringTrimLeft, res, res, 1
StringTrimRight, res, res, 1
StringSplit, var, res, `,
loop % var0
{
	tmp_var := var%A_index%
	RegExMatch(tmp_var,"""(.*)"":""(.*)""",m)
	m1 := RegExReplace(m1,"\s","")
	m1 := RegExReplace(m1,"\+86","")
	obj["" m1] := m2 ;注意此处数组key的类型
}
Return obj ;返回数组  obj[电话号码] := 联系人姓名
}

;发短信函数
SendMsg(to,msg){ ;号码,消息
msg := urlencode(msg)
Return URLDownloadToVar(parameter1 "send/" parameter2 "/" to "/", "utf-8","POST","msg=" msg)
}



URLDownloadToVar(url, Encoding = "",Method="GET",postData=""){ ;网址,编码,请求方式,post数据
	hObject:=ComObjCreate("WinHttp.WinHttpRequest.5.1")
	if Method = GET
	{
		hObject.Open("GET",url)
		Try
			hObject.Send()
		catch e
			return -1
	}
	else if Method = POST
	{
		hObject.Open("POST",url,False)
		hObject.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
		Try
			hObject.Send(postData)
		catch e
			return -1
	}

	if Encoding
	{
		oADO := ComObjCreate("adodb.stream")
		oADO.Type := 1
		oADO.Mode := 3
		oADO.Open()
		oADO.Write(hObject.ResponseBody)
		oADO.Position := 0
		oADO.Type := 2
		oADO.Charset := Encoding
		return oADO.ReadText(), oADO.Close()
	}
	return hObject.ResponseText
}


urlencode(string){
string := Ansi2UTF8(string)
StringLen, len, string
Loop % len
{
SetFormat, IntegerFast, hex ;运算结果为HEX
StringMid, out, string, %A_Index%, 1
hex := Asc(out) ;获取单字节ascii值
hex2 := hex ;另存变量
StringReplace, hex, hex, 0x, , All
SetFormat, IntegerFast, d
hex2 := hex2 ;十进制化
;判断是否可见单字节字符 是则直接连接 否则编码
If (hex2==33 || (hex2>=39 && hex2 <=42) || hex2==45 || hex2 ==46 || (hex2>=48 && hex2<=57)    || (hex2>=65 && hex2<=90) || hex2==95 || (hex2>=97 && hex2<=122) || hex2==126)
	content .= out
Else
	content .= "`%" hex
}
Return content
}

Ansi2Oem(sString)
{
   Ansi2Unicode(sString, wString, 0)
   Unicode2Ansi(wString, zString, 1)
   Return zString
}
Oem2Ansi(zString)
{
   Ansi2Unicode(zString, wString, 1)
   Unicode2Ansi(wString, sString, 0)
   Return sString
}
Ansi2UTF8(sString)
{
   Ansi2Unicode(sString, wString, 0)
   Unicode2Ansi(wString, zString, 65001)
   Return zString
}
UTF82Ansi(zString)
{
   Ansi2Unicode(zString, wString, 65001)
   Unicode2Ansi(wString, sString, 0)
   Return sString
}
Ansi2Unicode(ByRef sString, ByRef wString, CP = 0)
{
     nSize := DllCall("MultiByteToWideChar"
      , "Uint", CP
      , "Uint", 0
      , "Uint", &sString
      , "int", -1
      , "Uint", 0
      , "int", 0)
   VarSetCapacity(wString, nSize * 2)
   DllCall("MultiByteToWideChar"
      , "Uint", CP
      , "Uint", 0
      , "Uint", &sString
      , "int", -1
      , "Uint", &wString
      , "int", nSize)
}
Unicode2Ansi(ByRef wString, ByRef sString, CP = 0)
{
     nSize := DllCall("WideCharToMultiByte"
      , "Uint", CP
      , "Uint", 0
      , "Uint", &wString
      , "int", -1
      , "Uint", 0
      , "int", 0
      , "Uint", 0
      , "Uint", 0)
   VarSetCapacity(sString, nSize)
   DllCall("WideCharToMultiByte"
      , "Uint", CP
      , "Uint", 0
      , "Uint", &wString
      , "int", -1
      , "str", sString
      , "int", nSize
      , "Uint", 0
      , "Uint", 0)
}

json_toobj(str){

	quot := """" ; firmcoded specifically for readability. Hardcode for (minor) performance gain
	ws := "`t`n`r " Chr(160) ; whitespace plus NBSP. This gets trimmed from the markup
	obj := {} ; dummy object
	objs := [] ; stack
	keys := [] ; stack
	isarrays := [] ; stack
	literals := [] ; queue
	y := nest := 0

; First pass swaps out literal strings so we can parse the markup easily
	StringGetPos, z, str, %quot% ; initial seek
	while !ErrorLevel
	{
		; Look for the non-literal quote that ends this string. Encode literal backslashes as '\u005C' because the
		; '\u..' entities are decoded last and that prevents literal backslashes from borking normal characters
		StringGetPos, x, str, %quot%,, % z + 1
		while !ErrorLevel
		{
			StringMid, key, str, z + 2, x - z - 1
			StringReplace, key, key, \\, \u005C, A
			If SubStr( key, 0 ) != "\"
				Break
			StringGetPos, x, str, %quot%,, % x + 1
		}
	;	StringReplace, str, str, %quot%%t%%quot%, %quot% ; this might corrupt the string
		str := ( z ? SubStr( str, 1, z ) : "" ) quot SubStr( str, x + 2 ) ; this won't

	; Decode entities
		StringReplace, key, key, \%quot%, %quot%, A
		StringReplace, key, key, \b, % Chr(08), A
		StringReplace, key, key, \t, % A_Tab, A
		StringReplace, key, key, \n, `n, A
		StringReplace, key, key, \f, % Chr(12), A
		StringReplace, key, key, \r, `r, A
		StringReplace, key, key, \/, /, A
		while y := InStr( key, "\u", 0, y + 1 )
			if ( A_IsUnicode || Abs( "0x" SubStr( key, y + 2, 4 ) ) < 0x100 )
				key := ( y = 1 ? "" : SubStr( key, 1, y - 1 ) ) Chr( "0x" SubStr( key, y + 2, 4 ) ) SubStr( key, y + 6 )

		literals.insert(key)

		StringGetPos, z, str, %quot%,, % z + 1 ; seek
	}

; Second pass parses the markup and builds the object iteratively, swapping placeholders as they are encountered
	key := isarray := 1

	; The outer loop splits the blob into paths at markers where nest level decreases
	Loop Parse, str, % "]}"
	{
		StringReplace, str, A_LoopField, [, [], A ; mark any array open-brackets

		; This inner loop splits the path into segments at markers that signal nest level increases
		Loop Parse, str, % "[{"
		{
			; The first segment might contain members that belong to the previous object
			; Otherwise, push the previous object and key to their stacks and start a new object
			if ( A_Index != 1 )
			{
				objs.insert( obj )
				isarrays.insert( isarray )
				keys.insert( key )
				obj := {}
				isarray := key := Asc( A_LoopField ) = 93
			}

			; arrrrays are made by pirates and they have index keys
			if ( isarray )
			{
				Loop Parse, A_LoopField, `,, % ws "]"
					if ( A_LoopField != "" )
						obj[key++] := A_LoopField = quot ? literals.remove(1) : A_LoopField
			}
			; otherwise, parse the segment as key/value pairs
			else
			{
				Loop Parse, A_LoopField, `,
					Loop Parse, A_LoopField, :, % ws
						if ( A_Index = 1 )
							key := A_LoopField = quot ? literals.remove(1) : A_LoopField
						else if ( A_Index = 2 && A_LoopField != "" )
							obj[key] := A_LoopField = quot ? literals.remove(1) : A_LoopField
			}
			nest += A_Index > 1
		} ; Loop Parse, str, % "[{"

		If !--nest
			Break

		; Insert the newly closed object into the one on top of the stack, then pop the stack
		pbj := obj
		obj := objs.remove()
		obj[key := keys.remove()] := pbj
		If ( isarray := isarrays.remove() )
			key++

	} ; Loop Parse, str, % "]}"

	Return obj
}

Autohotkey+Web Short Message安卓短信接口.zip

QQ截图20150409212038.jpg

Centos安装Denyhosts屏蔽恶意暴力破解root密码 2377

作者为 发表

Linux

#下载
wget http://fossies.org/unix/privat/DenyHosts-2.6.tar.gz
#解压
tar -zxvf DenyHosts-2.6.tar.gz
#为了方便改个名
mv DenyHosts-2.6 denyhost
#进入目录
cd denyhost
#安装python
yum install python -y
#安装denyhost,脚本
python setup.py install
#进入配置目录
cd /usr/share/denyhosts/
#为了方便改变配置文件名称
cp daemon-control-dist daemon-control
#修改服务文件名称
cp denyhosts.cfg-dist denyhosts.cfg
#提高安全级别,修改权限
chown root daemon-control
chmod 700 daemon-control
#创建启动服务连接
ln -s /usr/share/denyhosts/daemon-control /etc/init.d/denyhosts
#添加启动项
chkconfig --add denyhosts

#配置denyhosts.cfg
vi denyhosts.cfg

填充以下内容

SECURE_LOG = /var/log/secure 
#ssh日志文件
HOSTS_DENY = /etc/hosts.deny 
#将阻止IP写入到hosts.deny
PURGE_DENY = 5m 
#过多久后清除已经禁止的,其中w代表周,d代表天,h代表小时,s代表秒,m代表分钟
BLOCK_SERVICE = sshd 
#阻止服务名
DENY_THRESHOLD_INVALID = 5 
#允许无效用户(在/etc/passwd未列出)登录失败次数,允许无效用户登录失败的次数.
DENY_THRESHOLD_VALID = 5 
#允许普通用户登录失败的次数
DENY_THRESHOLD_ROOT = 5 
#允许root登录失败的次数
DENY_THRESHOLD_RESTRICTED = 1 
#设定 deny host 写入到该资料夹
WORK_DIR = /usr/share/denyhosts/data 
#将deny的host或ip纪录到Work_dir中 
SUSPICIOUS_LOGIN_REPORT_ALLOWED_HOSTS = YES
HOSTNAME_LOOKUP=YES 
#是否做域名反解
LOCK_FILE = /var/lock/subsys/denyhosts 
#将DenyHOts启动的pid纪录到LOCK_FILE中,已确保服务正确启动,防止同时启动多个服务。
ADMIN_EMAIL = denyhosts@163.com 
#设置管理员邮件地址 
SMTP_HOST = localhost 
SMTP_PORT = 25 
SMTP_FROM = DenyHosts 
SMTP_SUBJECT = DenyHosts Report
AGE_RESET_VALID=1d 
#有效用户登录失败计数归零的时间
AGE_RESET_ROOT=1d 
#root用户登录失败计数归零的时间
AGE_RESET_RESTRICTED=5d 
#用户的失败登录计数重置为0的时间(/usr/share/denyhosts/data/restricted-usernames)
AGE_RESET_INVALID=10d 
#无效用户登录失败计数归零的时间
DAEMON_LOG = /var/log/denyhosts 
#自己的日志文件
DAEMON_SLEEP = 30s
DAEMON_PURGE = 5m 
#该项与PURGE_DENY 设置成一样,也是清除hosts.deniedssh 用户的时间

如果想删除一个已经禁止的主机IP,并加入到允许主机例表,只在 /etc/hosts.deny 删除是没用的。需要进入 /var/lib/denyhosts 目录,进入以下操作:

1、停止DenyHosts服务:

service denyhosts stop

2、在 /etc/hosts.deny 中删除你想取消的主机IP

3、编辑 DenyHosts 工作目录的所有文件,通过 

grep 192.168.1.191 /usr/share/denyhosts/data/*

然后一个个删除文件中你想取消的主机IP所在的行: 

* /usr/share/denyhosts/data/hosts 

* /usr/share/denyhosts/data/hosts-restricted 

* /usr/share/denyhosts/data/hosts-root 

* /usr/share/denyhosts/data/hosts-valid 

* /usr/share/denyhosts/data/users-hosts 

4、添加你想允许的主机IP地址到/var/lib/denyhosts/allowed-hosts

vi /usr/share/denyhosts/data/allowed-hostsps

然后逐行输入你的IP

thinkai.net 
192.168.1.*

5、启动DenyHosts服务:

service denyhosts start

报错排查

#service denyhost start

starting DenyHosts: /usr/bin/env python /usr/bin/denyhosts.py –daemon

–config=/usr/share/denyhosts/denyhosts.cfg

python: can't open file '/usr/bin/denyhosts.py': [Errno 2] No such file or

directory

cd /usr/share/denyhosts/
vi daemon-control

DENYHOSTS_BIN = "/usr/bin/denyhosts.py"

改为

DENYHOSTS_BIN = "/usr/local/bin/denyhosts.py"

cd /usr/local/lib/python2.7/site-packages/
cp -rp DenyHosts /usr/lib/python2.4/site-packages/
/etc/init.d/denyhosts restart



友情链接:Autohotkey中文论坛Autohotkey中文帮助Autohotkey官网我的B站直播间Autohotkey中文网联系作者免GooglePlay APK下载

 主题设计 • skyfrit.com  Thinkai's Blog | 保留所有权利

43 queries in 1.064 seconds |