免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2741 | 回复: 4
打印 上一主题 下一主题

一个安装cpan模块的脚本 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-09-10 11:24 |只看该作者 |倒序浏览
本帖最后由 hp_truth 于 2010-09-10 14:26 编辑

CPAN命令好像是用Net::FTP来获取下载地址的,但是我的ftp端口被禁了,所以不能用cpan命令来安装了,不过http端口可以用,以前都是一个一个下载安装,最近觉得有必要自己写一个自动安装的脚本。 到目前为止还比较好使,大家感兴趣的可以试一下)

  1. #!/usr/local/bin/perl5

  2. use warnings;
  3. use strict;

  4. use WWW::Mechanize;
  5. use HTML::TreeBuilder;
  6. use HTML::Query 'query';
  7. use Cwd;
  8. use File::Basename;

  9. die "Usage: $0 module_name\n" unless @ARGV;
  10. my ($module) = @ARGV;

  11. my $prefix  = "~/perl5";
  12. my $tmp_dir = "~/test";
  13. my $http_proxy = "http://proxy.com:80";

  14. my $mech = WWW::Mechanize->new(autocheck=>1);
  15. $mech->stack_depth(0);
  16. $mech->proxy(['http'], $http_proxy) if (! $ENV{http_proxy});

  17. print "you want to install $module...\n";
  18. &install($module);

  19. ###########################
  20. sub get_url_from_cpan {
  21.     my $module = shift;
  22.     my $cpan_url = "http://search.cpan.org";
  23.     print "get search_page ...\nurl=$cpan_url\n";
  24.     # search the module in CPAN main page
  25.     $mech->get($cpan_url);
  26.     $mech->set_fields(query => $module);
  27.     $mech->submit();
  28.     my $search_page_content = $mech->content();

  29.     # parse the search page to find the url of this module
  30.     my $tree = HTML::TreeBuilder->new;
  31.     my $success = $tree->parse($search_page_content);
  32.     $success    = $tree->eof();
  33.     die "parse search_page_content failed: $!\n" unless $success;

  34.     my $h2s = $tree->query('h2.sr'); #<h2> with sr class
  35.     my $href;
  36.     for my $h2 (@$h2s) {
  37.         my $module_name = $h2->query('a[href]')->as_trimmed_text->[0];
  38.         print "module_name: $module_name, module: $module\n";
  39.         if ($module_name eq $module) {
  40.             $href = $h2->query('a[href]')->attr('href')->[0];
  41.             last;
  42.         }
  43.     }

  44.     # fetch the page of this module from CPAN
  45.     my $module_url = $cpan_url . $href;
  46.     print "get module_page ...\nurl=$module_url\n";
  47.     $mech->get($module_url);
  48.     my $module_page_content = $mech->content();
  49.     undef $tree;
  50.     $tree = HTML::TreeBuilder->new;
  51.     $success = $tree->parse($module_page_content);
  52.     $success = $tree->eof();
  53.     die "parse module_page_content failed: $!\n" unless $success;

  54.     # find the download url for this module
  55.     my $ps = $tree->query("p[style]");
  56.     for my $p (@$ps) {
  57.         if ($p->as_trimmed_text =~ m/Download:/) {
  58.             my $href = $p->query('a[href]')->attr('href')->[0];
  59.             print "Path = " . $cpan_url . $href . "\n";
  60.             return $cpan_url . $href;
  61.         }
  62.     }
  63.     return undef; # fail if reach here
  64. }

  65. sub install {
  66.     my $module = shift;
  67.     my @suffixlist = (".tar.gz", ".tgz");
  68.     my $suffix = ".tar.gz";
  69.     my $path;

  70.     my $cur_dir = getcwd;
  71.     chdir($tmp_dir);
  72.     print "cur_dir: $cur_dir, chidr to: " . getcwd . "\n";

  73.     # judge if file already exists.
  74.     # for example, file A-B.tar.gz for module A::B
  75.     my @files = grep {-f $_} <*>;
  76.     my $dir = $module;
  77.     $dir =~ s/::/-/g;
  78.     @files = grep /^$dir-(\d.)+/, @files;
  79.     print "files=@files\n";

  80.     # if module.tar.gz does not exists, we wget it from CPAN
  81.     # else use it directly
  82.     unless (@files) {
  83.         my $url = &get_url_from_cpan($module);
  84.         ($dir, $path, $suffix) = fileparse($url, @suffixlist);
  85.         system("wget $url 1>/dev/null 2>&1");
  86.     }
  87.     else {
  88.         ($dir, $path ,$suffix) = fileparse($files[0], @suffixlist);
  89.     }

  90.     # unpack the module.tar.gz file
  91.     # and chdir to the related dir
  92.     print "dir = $dir\n";
  93.     system("gunzip < $dir$suffix|tar -xf -");
  94.     chdir($dir);

  95.     # start to install this module
  96.     # 1. perl5 Makefile.PL prefix=$prefix
  97.     # 2. make
  98.     # 3. make install
  99.     # If there is dependency, we should install them first
  100.     # until all dependency are installed.
  101.     my $dependency = 1;
  102.     while ($dependency) {
  103.         my $mf_result = `perl5 Makefile.PL prefix=$prefix 2>&1`;
  104.         if ($mf_result =~ m/Warning: prerequisite (\S*) .* not found/) {
  105.             my ($new_module) = $1 ;
  106.             $new_module =~ s/-(\d.)+$//;
  107.             $new_module =~ s/-/::/g;
  108.             print ">" x 30 . "\n";
  109.             print "$new_module shoulde be installed first\n";
  110.             system("~/bin/cpan_install.pl",  $new_module);
  111.         }
  112.         else {
  113.             $dependency = 0;
  114.         }
  115.     }
  116.     system("make && make install");

  117.     chdir($cur_dir);
  118. }
复制代码

论坛徽章:
0
2 [报告]
发表于 2010-09-10 12:11 |只看该作者
呵呵··不错~~

论坛徽章:
0
3 [报告]
发表于 2010-09-10 12:20 |只看该作者
回复 2# wfnh


    谢谢, 就是觉得HTML:uery挺好用的,所以拿来当作练习了。 应该还有别的方法可以下载的。

论坛徽章:
0
4 [报告]
发表于 2010-09-10 13:03 |只看该作者
赞,我们内部网络也是不能CPAN,正好试试这个!

论坛徽章:
0
5 [报告]
发表于 2010-09-10 14:07 |只看该作者
cpan 有配置文件的,可以设置 ftp、http proxy的,看你设置了,我这边看到,经常都是 lwp 下载的嘛
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP