File Coverage

blib/lib/VK.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2            
3             ###################################################
4             ## ##
5             ## VKontakte serverside manager ##
6             ## ##
7             ## Marat Shaymardanov, LeonMedia LLC, 2013 ##
8             ## info@leonmedia.ru http://leonmedia.ru ##
9             ## ##
10             ## http://vk.com/do.more ##
11             ## ##
12             ###################################################
13            
14             package VK;
15            
16             require Exporter;
17            
18             @ISA = qw(Exporter);
19             @EXPORT = qw();
20            
21 1     1   23764 use WWW::Mechanize::GZip;
  0            
  0            
22             use URI::Escape;
23            
24             our $VERSION = '0.09';
25            
26             sub new
27             {
28             my ($class, $login, $pass, $wallurl, $security_code) = @_;
29             my $self = {};
30            
31             bless $self, $class;
32            
33             my $mech = WWW::Mechanize::GZip->new(
34             agent => 'Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13',
35             timeout => 30,
36             onerror => sub {print "error\n"}
37             );
38            
39             $mech->cookie_jar(HTTP::Cookies->new());
40             $self->{mech} = $mech;
41            
42             if ($login){
43             if (!$self->login($login, $pass, $wallurl, $security_code)){
44             return undef;
45             }
46             }
47            
48             return $self;
49             }
50            
51             sub login
52             {
53             my ($self, $login, $pass, $wallurl, $security_code) = @_;
54             my $mech = $self->{mech};
55            
56             $self->{security_code} = $security_code;
57             $self->get("http://vk.com/login");
58            
59             # correct language
60             $mech->content =~ m/hash: '([^']+)'/s;
61             $mech->post("http://vk.com/al_index.php",{
62             'act' => 'change_lang',
63             'lang_id' => 0, # russian
64             'hash' => $1
65             });
66            
67             $mech->form_number(1);
68             $mech->field("email" => $login);
69             $mech->field("pass" => $pass);
70            
71             my $r = $mech->submit();
72             my $c = $r->content;
73             my $wallid = undef;
74            
75             if ($c =~ m/parent\.onLoginDone\('([^']+)'\)/is){
76             $self->{home} = $1;
77            
78             # wall hash
79             if ($wallurl && ($wallurl ne $self->{home})){
80             $self->get($wallurl);
81             $c = $mech->content;
82            
83             # wall hash
84             $c =~ m/"post_hash":"([^"]+)"/s;
85             $self->{wall_hash} = $1;
86            
87             # wall oid
88             $c =~ m/"wall_oid":([^,]+),/s;
89             $wallid = $1;
90             }
91            
92             # user hash
93             $self->get($self->{home});
94             $c = $mech->content;
95            
96             # get post hash
97             $c =~ m/\"post_hash\":\"([^\"]+)"/s;
98             $self->{hash} = $1;
99            
100             # get user id
101             $c =~ m/id: (\d+)/s;
102             $self->{id} = $1;
103            
104             $self->{wallurl} = $wallurl || $self->{home};
105             $self->{wallid} = $wallid || $self->{id};
106            
107             return 1;
108             }
109             #print $c;
110             return 0;
111             }
112            
113             sub createAlbum
114             {
115             my ($self, $title, $desc, $permission, $commentable) = @_;
116             my $mech = $self->{mech};
117            
118             $self->get('http://m.vk.com/photos?act=select_album');
119            
120             # get hash
121             if ($mech->content =~ m/photos\?act=new_album&hash=([\d\w]+)/){
122             my $hash = $1;
123            
124             $mech->post(
125             'http://m.vk.com/photos?act=new_album&hash='.$hash,{
126             'title' => $title,
127             'desc' => $desc,
128             'view' => int($permission),
129             'comm' => int($commentable)
130             });
131            
132             return ($mech->content =~ m/Альбом успешно создан\.<\/div>/)?1:0;
133             }
134            
135             return 0;
136             }
137            
138             sub get
139             {
140             my $self = shift @_;
141             my $mech = $self->{mech};
142             from_security:
143             my $r = $mech->get(@_);
144            
145             if ($mech->content =~ m/"loc":"\?act=security_check/s){
146             $mech->content =~ m/{act: 'security_check', code: [^,]+, to: '([^']+)', al_page: '(\d+)', hash: '([^']+)'}/s;
147             $mech->post("http://vk.com/login.php", {
148             'act' => 'security_check',
149             'code' => $self->{security_code},
150             'to' => $1,
151             'hash' => $3,
152             'al_page' => $2
153             });
154             #print $mech->content."\n\n\n";
155             goto from_security;
156             }
157            
158             return $r;
159             }
160            
161             sub logout
162             {
163             my ($self) = @_;
164             my $mech = $self->{mech};
165             $self->get("http://m.vk.com");
166             my $link = $mech->find_link( text_regex => qr/Выход/i );
167             sleep(1);
168             my $r = $self->get($link->url());
169             return $r->is_success;
170             }
171            
172             sub addPhoto
173             {
174             my ($self, $filePath, $albumName, $albumDesc, $permission, $commentable) = @_;
175             my $mech = $self->{mech};
176            
177             $albumName = '#shared' if (!$albumName);
178            
179             do_again:
180             $self->get("http://m.vk.com");
181             sleep(2);
182            
183             print "my photos\n";
184             my $link = $mech->find_link( text_regex => qr/Мои Фотографии/is );
185             my $r = $self->get($link->url());
186             sleep(2);
187            
188             print "add new photos\n";
189             $link = $mech->find_link( text_regex => qr/Добавить новые фотографии/is );
190            
191             sleep(2);
192             $r = $self->get($link->url());
193             my $c = $r->content;
194            
195             print "create album if required $albumName\n";
196             # check if album exists
197             unless ($c =~ m/
$albumName<\/div>/s){
198             print $self->createAlbum($albumName, $albumDesc, $permission, $commentable)?"ok\n":"failed\n";
199             goto do_again;
200             }
201            
202             print "upload\n";
203             if ($c =~ m/]+|)>\s+
]+>\s+]+>\s+<\/div>\s+
$albumName<\/div>/s){
204             print "submitting file $1\n";
205            
206             $r = $self->get($1);
207             =no
208             if ($mech->content =~ m/
В этом альбоме уже находится более 500 фотографий/){
209             if ($albumName =~ m/\-(\d+)$/){
210             my $next = int($1) + 1;
211             $albumName =~ s/\-\d+$/($next)/;
212             } else {
213             $albumName .= "-2";
214             }
215             print "rename album to $albumName\n";
216             goto do_again;
217             }
218             =cut
219             $mech->form_number(1);
220             $mech->field("file1" => $filePath);
221            
222             sleep(2);
223             $r = $mech->submit();
224            
225             print $r->is_success()." - submit result\n";
226            
227             $c = $r->content;
228             if ($c =~ m/Загрузка завершена\.<\/div>/is){
229             print "Uploaded $1\n" and return $1 if ($c =~ m/\"\/photo(\d+_\d+)/is);
230             }
231             }
232             print "not uploaded\n";
233            
234             return undef;
235             }
236            
237             sub wallPost
238             {
239             my ($self, %params) = @_;
240             my $mech = $self->{mech};
241             my $photoid = undef;
242            
243             if ($params{'photo'}){
244             $photoid = $self->addPhoto(
245             $params{'photo'},
246             $params{'album'}, $params{'album_desc'},
247             $params{'album_view'}, $params{'album_comments'}
248             );
249            
250             return 0 if (!$params{'post_anyway'} && !$photoid);
251             }
252            
253             my $to_id = $params{'to_id'} || $self->{wallid};
254            
255             my $r = $self->get('http://vk.com'.(($to_id>0)?"/id$to_id":$self->{wallurl}));
256             $mech->content =~ m/"post_hash":"([^"]+)"/s;
257            
258             my $post_hash = $1;
259            
260             my $h = {
261             'act' => 'post',
262             'al' => 1,
263             'hash' => $post_hash,
264             'message' => $params{'message'},
265             'note_title' => $params{'note_title'},
266             'official' => $params{'official'},
267             'status_export' => '',
268             'signed' => $params{'signed'}?1:0,
269             'to_id' => $to_id,
270             'type' => ($to_id > 0)?'all':'own',
271             };
272            
273             my $n = 0;
274            
275             if ($photoid){
276             $n++;
277             $h->{"attach$n\_type"} = 'photo';
278             $h->{"attach$n"} = $photoid;
279             }
280            
281             if ($params{'link'}){
282             $n++;
283             $h->{"attach$n\_type"} = 'share';
284             $h->{"title"} = $params{'link_title'},
285             $h->{"description"} = $params{'link_desc'},
286             $h->{"url"} = $params{'link'},
287             }
288            
289             #foreach $key (sort(keys %{$h})){ print "$key=$h->{$key}&"; }
290             sleep(2);
291             print "posting message\n";
292             my $r = $mech->post("http://vk.com/al_wall.php", $h);
293             my @codes = split(/<\!>/, $r->content);
294            
295             return ($codes[4] eq '0')?1:0;
296             }
297            
298             1;
299             __END__