gyn

Win32下的Perl,无用的select,停滞的Tk,结束吧....

一段视频重录的代码

网站会录制一档每晚播出的电视节目,但是有时候录制会失败,于是需要在第二天重播的时候再次录制。为此,需要调整各个文件的参数,由于参数比较多而且涉及到FTP传输,对于不是很熟悉这一过程的网管,如果一不留神很可能会导致再次失败。所以写了一个带界面的设置工具,完成录制和传输过程。
chonglu.JPG
代码:
 1 use Win32::GUI;
 2 use strict;
 3 use Encode;
 4 use Net::FTP;
 5 use Time::Local;
 6 use Tk;
 7 use Tk::BrowseEntry;
 8 
 9 my $hw = Win32::GUI::GetPerlWindow();
10 Win32::GUI::Hide($hw);
11 
12 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst= localtime();
13 my @t = localtime(time() - 86400);
14 my $tm;
15 my $bt;
16 my $mw;
17 my $signal = 0;
18 my $sd = sprintf("%d", $t[5+ 1900).sprintf("%.2d", $t[4+ 1).sprintf("%.2d", $t[3]);
19 my $data = sprintf("%d", $t[5+ 1900).'-'.sprintf("%.2d", $t[4+ 1).'-'.sprintf("%.2d", $t[3]);
20 my $ta = sprintf("%d", $year + 1900).'-'.sprintf("%.2d", $mon + 1).'-'.sprintf("%.2d", $mday);
21 
22 sub hanzi { return decode('gb2312', shift); }
23 sub shezhi {
24     $tm = timelocal($sec,$min,$hour,$mday,$mon,$year);
25     $signal = 1;
26     open C, 'chonglu.rpjf';
27     open T, '>temp';
28     while (<C>) { 
29         chomp;
30         $_ =~ s/(.*)([0-9]{8})(.*)/$1$sd$3/;
31         $_ =~ s/(.*)([0-9]{4}\-[0-9]{2}\-[0-9]{2})(.*)/$1$data$3/;
32         print T "$_\n";
33     }
34     close C; close T;
35     system 'del chonglu.rpjf';
36     system 'rename temp chonglu.rpjf';
37     $bt->configure(-state => 'disable');
38 }
39 sub monitor {
40     if ($signal) { 
41         if (time() >= $tm) {
42             $signal = 0;
43             system 'producer -j "d:\shixian\chonglu.rpjf" -daw -lc "e,i"';
44         }
45         if (-"shixian$sd.rm") {
46             my $f = Net::FTP->new('media.zsgd.com') or print 'ftp failed';
47             $f->login('jh', '2020038');
48             $f->put("shixian$sd.rm");
49             $f->quit();
50             print "send complete\n";
51         }
52     }
53 }
54 
55 $mw = MainWindow->new(-title => hanzi('视线重录'));
56 $mw->Label(-text => $ta)->pack(-side => 'left', -expand => 1, -fill => 'x');
57 foreach ((['小时', \$hour, [0..23]], ['', \$min, [0..59]], ['', \$sec, [0..59]])) {
58     $mw->BrowseEntry(-label => hanzi($_->[0]), -variable => $_->[1], -choices => $_->[2])->pack(-side => 'left', -expand => 1, -fill => 'x');
59 }
60 $bt = $mw->Button(-text => hanzi('设置'), -command => \&shezhi)->pack(-side => 'bottom');
61 $mw->resizable(0, 0);
62 $mw->repeat(1000, \&monitor);
63 MainLoop();
64 

posted @ 2008-04-07 11:36 gyn_tadao 阅读(280) | 评论 (0)编辑 收藏

检索mp3的脚本

播出软件的音频解码单元无法处理一些特殊码率的mp3文件,为了保证播放的安全和流畅,需要将这些特殊码率的文件剔除掉。使用诸如千千静听和foobar等播放器都可以查看文件的码率,但是如果文件数量很多,这种人工查看的办法非常费时。所以用脚本来完成一项工作。
 1use strict;
 2use File::Find;
 3use MP3::Tag;
 4
 5my ($path, $delete= @ARGV;
 6
 7find(\&wanted, $path);
 8
 9sub wanted{
10    /\.mp3$/ && do {
11        my $mp3 = MP3::Tag->new("$_");
12        if (defined($mp3&& is_normal_bitrate($mp3->bitrate_kbps())){
13            remove($_);
14        }
15    };
16}
17
18sub is_normal_bitrate{
19    my $bitrate = shift;
20    for (64, 128, 192, 256){
21        if($bitrate == $_) {
22            return 1;
23        }
24    }
25    return 0;
26}
27
28sub remove{
29    my $filename = shift;
30    my @paths = split(/\//, $path);
31    my $recycled = $paths[0]."/$filename";
32    
33    open(FILE, $filename);
34    open(ANO, ">".$recycled) or die $!;
35    
36    binmode FILE;
37    binmode ANO;
38    
39    my $offset = 0;
40    my $buffer = undef;
41    my $number = 0;
42    while(($number = sysread(FILE, $buffer, 1024, $offset)) != 0){
43        syswrite(ANO, $buffer, $number, $offset);
44        $offset += $number;
45    }
46    
47    close FILE;
48    close ANO;
49    
50    if($delete eq "-d") {unlink $_;}
51}

posted @ 2008-04-05 16:57 gyn_tadao 阅读(309) | 评论 (0)编辑 收藏

ADT安装小记

Android很火,估计以后可以靠这个赚点小钱。就算不行,玩玩总是可以的。
具体的下载说明在这里:http://www.androidin.com/docs/intro/installing.html#developingwitheclipse
安装完SDK后,最好按一个eclipse。我平时一般用UE和GVIM比较多,不过eclipse是官方推荐的,连教程里也是用了这个。所以下载了一个就凑活用用。(学习一个新事物的最好办法就是亲手实践,而一个好的tutorial是十分重要的,对于建立继续学下去的信心至关重要,在此过程中亦步亦趋往往会有比较好的效果。)
之后,需要安装一个叫ADT的plugin。具体的安装方法,说明里也有。但是问题出现eclipse在搜索到ADT的一步。提示缺少“org.eclipse.wst.sse.ui”这个玩意儿。到google上搜索,比较值得可信的是http://blog.csdn.net/jiyucn/archive/2008/02/16/2099387.aspx里面说的。但是我从里面的链接里下载来各个plugin,解压,再全部复制到eclipse之后。按照他的说法,再装ADT就成了,但事实上还是提示不行。于是开始上网搜索“如何安装eclipse插件”,文章很多,但基本不靠谱。
终于,功夫不负有心人,在http://hi.baidu.com/iiyouxia/blog/item/3f13c245cba57c3c87947325.html中,发现了一句话“删掉configuration中除了config.ini以外的所有文件和文件夹,确保插件安装配置正确”。抱着死马当活马医的心情,删了它们。打开eclpise再试,成了!

posted @ 2008-03-17 16:52 gyn_tadao 阅读(4706) | 评论 (0)编辑 收藏

Big-endian和Little-endian(转自:http://blog.csdn.net/NeptuneX/)

简而言之:
Big endian machine: It thinks the first byte it reads is the biggest.
Little endian machine: It thinks the first byte it reads is the littlest.
举个例子,从内存地址0x0000开始有以下数据
 0x0000     0x12
 0x0001     0x34
 0x0002     0xab
 0x0003     0xcd
如果我们去读取一个地址为0x0000的四个字节变量,若字节序为big-endian,则读出
结果为0x1234abcd;若字节序位little-endian,则读出结果为0xcdab3412.
如果我们将0x1234abcd写入到以0x0000开始的内存中,则结果为
                big-endian     little-endian
0x0000     0x12              0xcd
0x0001     0x23              0xab
0x0002     0xab              0x34
0x0003     0xcd              0x12
x86系列CPU都是little-endian的字节序.

posted @ 2008-02-14 15:17 gyn_tadao 阅读(348) | 评论 (0)编辑 收藏

新年新学习-erlang

好久没有来了,不是因为没有在学习,相反的,因为一直在学习新的东西,并且还没有形成理论体系,所以没办法写下心得。前些日子,打算学习一下java,但是因为自己脚本习惯已深,所以先学习groovy,再慢慢过渡到java上去。建议打算学习groovy的朋友看mastering groovy in action,至于那本programming groovy就不要看了,出的时间太早,有一些版本上的冲突。
在以前用perl写脚本的日子里,一直被并行或者说进程间的通信问题所困扰。一些信号处理的办法或者Tk中解决通信的办法,在windows下无法很好实现,或多或少存在一些奇怪的问题。这也是为什么下定决心要精通另外一种语言的原因。java无疑是最好的选择。但是在一次浏览csdn的时候,发现了一篇介绍erlang的文章。erlang是天然用来解决并行的语言,因其高效稳定的运行,被用在电信等需要大量并行计算的通信行业中。爱立信和北电的一些产品正是应用了erlang。如此看来,erlang不正是我们这些学通信出身的人的好帮手吗?于是二话不说,下了本programming erlang开始看起来了。
相比较perl,c,java,erlang更接近与haskell,而更有意思的是,出于安全考虑,变量一旦赋值就无法更改。递归被频繁地使用。比如说一个快排算法。
qsort(_, []) -> [];
qsort([Pivat|T]) ->
    qsort([X || X <- T, X < Pivat])
    ++ [Pivat] ++
    qsort([X || X <- T, X >= Pivat]).
总而言之,与平常接触的一些编程语言习惯格格不入,完全从零开始。当然数据结构的一些概念和算法还是相通的,看来大学时好好学习是非常重要的。

posted @ 2008-02-11 12:59 gyn_tadao 阅读(604) | 评论 (2)编辑 收藏

基于串口心跳的双机热备Perl代码(下载)

(下载serial_heartbeat.rar)压缩包里有两个文件夹,一个用于主机,一个用于备机。串口参数修改在serial.conf中;检测参数在parameters.txt中一般不需要修改;网卡参数设置在inetrface开头的文件中,其中interface_null不需要修改。运行时,请确保已安装了perl 和Win32::SerialPort模块。由于上载空间有限,不提供exe文件下载。有需要可电邮我jh@zsgd.com

posted @ 2007-11-29 14:07 gyn_tadao 阅读(615) | 评论 (0)编辑 收藏

perl串口通信实例

使用串口通信,在备机端使用如下脚本检测来自主机的心跳信号,一旦未接受次数超过指定记数,备机认为主机DOWN机,自动设置为主机的网络参数,顶替主机提供服务。

# ! perl -w

use  strict;
use  Win32 :: SerialPort;

my   $port   =   ' COM2 ' #  serail port name registried in OS
my   $count   =   0 #  count number of heartbeat-receiving failture
my   $max_count   =   5 #  max fail count to be tolerated 
my   $interface   =   '

# ---------------------------------- 
# 接口 IP 配置         
# ---------------------------------- 
pushd interface ip


# "local" 的接口 IP  配置

set address name="local" source=static addr=192.168.6.185 mask=255.255.255.0
set address name="local" gateway=192.168.6.65 gwmetric=0
set dns name="local" source=static addr=192.168.6.112 register=PRIMARY
add dns name="local" addr=192.168.6.201 index=2
set wins name="local" source=static addr=none


popd
# 接口 IP 配置结束


' #  net inetrface config information

sub  errlog {
    
# log the failtrue occuring time
    
    
open  ERR ,   ' >>err.log ' ;
    
my   @time   =   localtime ();
    
my   $time   =   sprintf ( " %d " ,   $time [ 5 +   1900
                        
.   ' - '  
                        
.   sprintf ( " %d " ,   $time [ 4 +   1 )
                        
.   ' - '
                        
.   " $time[3] "
                        
.   '   '
                        
.   sprintf ( " %.2d " ,   $time [ 2 ])
                        
.   ' : '
                        
.   sprintf ( " %.2d " ,   $time [ 1 ])
                        
.   ' : '
                        
.   sprintf ( " %.2d " ,   $time [ 0 ]);
    
print  ERR  $time . " \n " ;
    
close  ERR;
}

sub  ipchange {
    
#  change ip addrress
    
    
open  TMP ,   ' >tmp ' ;
    
print  TMP  $interface ;
    
close  TMP;
    
    
eval  {
        
system   ' netsh -f tmp ' ;
        
unlink   ' tmp ' ;
    };
    
    
if  ($@) { return   0 ;}
    
return   1 ;
}

my   $ob   =  Win32 :: SerialPort -> new( $port ) or  die   " CANNOT OPEN $port " ;
#  open serial port 

eval  {
    
#  set serial port properties
    
    
$ob -> baudrate( 9600 );
    
$ob -> parity( ' none ' );
    
$ob -> databits( 8 );
    
$ob -> stopbits( 1 );
    
$ob -> handshake( ' none ' );
};
    
if  ($@) { die   ' SET FAILED ' ;}

$ob -> write_settings or  die   " CANNOT WRITE $port DRIVER " ;
#  write to port driver to make it active

while  ( 1 ) {
    
#  loop receiving heartbeat from remote machine
    # change ip address after designated count of failture 

    
    
my  ( $length ,   $result =   $ob -> read ( 10 );
    
    
if  ( $result ) { 
        
$count   =   0 ;
    } 
elsif  ( $count   ==   $max_count ) {
        errlog();
        
if  (not ipchange()) {  print   ' IP CHANGE FAILED ' ; }
        
last ;
    }    
else  { 
        
$count ++ ;
    }
    
    
sleep ( 1 );
}

undef   $ob ;

posted @ 2007-11-27 14:40 gyn_tadao 阅读(2085) | 评论 (0)编辑 收藏

给上一篇中的ftp服务增加了用户添加和删除的程序

最终放弃GUI 了,太麻烦。命令行好搞啊,呵呵。
 1import os, sys
 2import md5
 3from pysqlite2 import dbapi2 as sqlite
 4
 5def user_insert(username, password, homedir, perm, msg_login, msg_quit):
 6    if not username: username = 'anonymous'
 7    if not os.path.exists(homedir): homedir = r'D:\None'
 8    if not perm in ('''r;''r;w'): perm = 'r;'
 9    if not msg_login: msg_login = 'Login successful.'
10    if not msg_quit: msg_quit = 'Goodbye.'
11    dbpath = '%s\\users.db' % os.getcwd()
12    if not os.path.isfile(dbpath):
13        con = sqlite.connect(dbpath, isolation_level = None)
14        cur = con.cursor()
15        cur.execute("CREATE TABLE users(username test primary key, password text, homedir text, perm text, msg_login text, mag_quit text)")
16        cur.close()
17        con.close()
18    con = sqlite.connect(dbpath, isolation_level = None)
19    cur = con.cursor()
20    cur.execute("insert into users values(?, ?, ?, ?, ?, ?)"
21                (username, password, homedir, perm, msg_login, msg_quit))
22    cur.close()
23    con.close()
24
25try:
26    from msvcrt import getch
27except ImportError:
28    def getch():
29        import tty, termios
30        fd = sts.stdin.fileno()
31        old.settings = termios.tcgetattr(fd)
32        try:
33            tty.setraw(fd)
34            ch = sys.stdin.read(1)
35        finally:
36            termios.tcsetattr(fd, tremios.TCSADRAIN, old.settings)
37        return ch
38
39def asterisk_raw_input(label):
40    sys.stdout.write(label)
41    strAttr = []
42    while True:
43        tmp = getch()
44        if tmp != '\r':
45            strAttr.append(tmp)
46            sys.stdout.write('*')
47        else
48            sys.stdout.write('\n')
49            break
50    return ''.join(strAttr)
51    
52    
53user_info_list = []
54print "-*- pyftpdlib user information. -*-\n-*- Separated by ':' -*-\n"
55for eachLabel in ("Username""Password""Homedir""Perm""Msg_login""Msg_quit"):
56    if eachLabel == 'Password':
57        user_info = md5.new(asterisk_raw_input(eachLabel + ':  ')).hexdigest()
58    else:
59        user_info = raw_input(eachLabel + ':  ')
60    user_info_list.append(user_info)
61user_insert(*user_info_list)
62print "-*- Programme Quit. -*-"

user_add.py
 1import os
 2from pysqlite2 import dbapi2 as sqlite
 3
 4user_info = {}
 5dbpath = '%s\\users.db' % os.getcwd()
 6if not os.path.isfile(dbpath):
 7    print '-*- No user to delete. -*-'
 8else:
 9    con = sqlite.connect(dbpath, isolation_level = None)
10    cur = con.cursor()
11    cur.execute('select username from users')
12    result = cur.fetchall()
13    if not result: 
14        print '-*- No user to delete. -*-'
15    else:
16        result = [name[0] for name in result]
17        for index, name in zip(range(1, len(result)+1), result):
18            print '<%d> %s' % (index, name)
19            user_info[index] = name
20        print ''
21        user_index = int(raw_input("Enter the index of user to delete: "))
22        while not user_index in range(0, len(result)+1):
23            user_index = raw_input("Wrong index, re_enter: ")
24        if user_index:
25            cur.execute("delete from users where username = '%s'" % user_info[user_index])
26            print "-*- '%s' is deleted. -*-" % user_info[user_index]
27    cur.close()
28    con.close()
29    print "-*- Programme Quit. -*-"
user_del.py

posted @ 2007-11-11 15:37 gyn_tadao 阅读(354) | 评论 (0)编辑 收藏

利用pyftpdlib和pysqlite3建立可存储用户信息FTP服务

     摘要: 前一段时间因为版权的原因,停用了SERV-U服务。但是ftp的服务不能停止,所以不得不自己动手写一个。但是由于时间原因,无法完全认真去看协议,所以希望利用现有的模块。这类模块在perl和python中都有,不过我差不多有半年没碰perl了,自然选择了python。除了几个无关紧要的bug,这个模块基本能满足日常使用。只是用户信息的存储不是很保险,如果存到数据库中总能好一些。密码则参照范例中的md5...  阅读全文

posted @ 2007-11-10 11:15 gyn_tadao 阅读(1259) | 评论 (0)编辑 收藏

获取文件夹大小的python代码

可能是太简单的缘故,在google中查询不到,所以贴一下免得忘记了:
import os
from os.path import join, getsize

def getdirsize(dir):
   size 
= 0L
   
for root, dirs, files in os.walk(dir):
      size 
+= sum([getsize(join(root, name)) for name in files])
   
return size

if '__name__' == '__main__':
   filesize 
= getdirsize(r'c:\windows')
   
print 'There are %.3f' % (size/1024/1024), 'Mbytes in c:\\windows'

posted @ 2007-11-01 14:25 gyn_tadao 阅读(5128) | 评论 (0)编辑 收藏

仅列出标题
共11页: First 2 3 4 5 6 7 8 9 10 Last 
<2009年5月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

导航

统计

常用链接

留言簿(15)

随笔分类(126)

随笔档案(108)

相册

搜索

最新评论

阅读排行榜

评论排行榜