line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Catmandu::WoS::SearchBase; |
2
|
|
|
|
|
|
|
|
3
|
5
|
|
|
5
|
|
2716
|
use Catmandu::Sane; |
|
5
|
|
|
|
|
45
|
|
|
5
|
|
|
|
|
38
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
our $VERSION = '0.0302'; |
6
|
|
|
|
|
|
|
|
7
|
5
|
|
|
5
|
|
1030
|
use Moo::Role; |
|
5
|
|
|
|
|
8
|
|
|
5
|
|
|
|
|
32
|
|
8
|
5
|
|
|
5
|
|
3876
|
use URI::Escape qw(uri_escape); |
|
5
|
|
|
|
|
6234
|
|
|
5
|
|
|
|
|
259
|
|
9
|
5
|
|
|
5
|
|
589
|
use XML::LibXML; |
|
5
|
|
|
|
|
38816
|
|
|
5
|
|
|
|
|
29
|
|
10
|
5
|
|
|
5
|
|
663
|
use XML::LibXML::XPathContext; |
|
5
|
|
|
|
|
9
|
|
|
5
|
|
|
|
|
91
|
|
11
|
5
|
|
|
5
|
|
31
|
use namespace::clean; |
|
5
|
|
|
|
|
9
|
|
|
5
|
|
|
|
|
24
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
with 'Catmandu::Importer'; |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
has username => (is => 'ro'); |
16
|
|
|
|
|
|
|
has password => (is => 'ro'); |
17
|
|
|
|
|
|
|
has session_id => (is => 'lazy'); |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
requires '_search_content'; |
20
|
|
|
|
|
|
|
requires '_retrieve_content'; |
21
|
|
|
|
|
|
|
requires '_search_response_type'; |
22
|
|
|
|
|
|
|
requires '_retrieve_response_type'; |
23
|
|
|
|
|
|
|
requires '_find_records'; |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
sub _auth_url { |
26
|
0
|
|
|
0
|
|
|
my ($self) = @_; |
27
|
|
|
|
|
|
|
|
28
|
0
|
|
|
|
|
|
'http://' |
29
|
|
|
|
|
|
|
. uri_escape($self->username) . ':' |
30
|
|
|
|
|
|
|
. uri_escape($self->password) |
31
|
|
|
|
|
|
|
. '@search.webofknowledge.com/esti/wokmws/ws/WOKMWSAuthenticate'; |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
sub _auth_ns { |
35
|
0
|
|
|
0
|
|
|
state $ns = { |
36
|
|
|
|
|
|
|
'soap' => 'http://schemas.xmlsoap.org/soap/envelope/', |
37
|
|
|
|
|
|
|
'ns2' => 'http://auth.cxf.wokmws.thomsonreuters.com', |
38
|
|
|
|
|
|
|
}; |
39
|
|
|
|
|
|
|
} |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
sub _auth_content { |
42
|
0
|
|
|
0
|
|
|
state $content = <<EOF; |
43
|
|
|
|
|
|
|
<soapenv:Envelope |
44
|
|
|
|
|
|
|
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" |
45
|
|
|
|
|
|
|
xmlns:auth="http://auth.cxf.wokmws.thomsonreuters.com"> |
46
|
|
|
|
|
|
|
<soapenv:Header/> |
47
|
|
|
|
|
|
|
<soapenv:Body> |
48
|
|
|
|
|
|
|
<auth:authenticate/> |
49
|
|
|
|
|
|
|
</soapenv:Body> |
50
|
|
|
|
|
|
|
</soapenv:Envelope> |
51
|
|
|
|
|
|
|
EOF |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
sub _search_url { |
55
|
0
|
|
|
0
|
|
|
state $url = 'http://search.webofknowledge.com/esti/wokmws/ws/WokSearch'; |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
sub _search_ns { |
59
|
0
|
|
|
0
|
|
|
state $ns = { |
60
|
|
|
|
|
|
|
'soap' => 'http://schemas.xmlsoap.org/soap/envelope/', |
61
|
|
|
|
|
|
|
'ns2' => 'http://woksearch.v3.wokmws.thomsonreuters.com', |
62
|
|
|
|
|
|
|
}; |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
sub _soap_request { |
66
|
0
|
|
|
0
|
|
|
my ($self, $url, $ns, $content, $session_id) = @_; |
67
|
|
|
|
|
|
|
|
68
|
0
|
|
|
|
|
|
my $headers = ['Content-Type' => "text/xml; charset=UTF-8"]; |
69
|
|
|
|
|
|
|
|
70
|
0
|
0
|
|
|
|
|
if ($session_id) { |
71
|
0
|
|
|
|
|
|
push @$headers, 'Cookie', qq|SID="$session_id"|; |
72
|
|
|
|
|
|
|
} |
73
|
|
|
|
|
|
|
|
74
|
0
|
|
|
|
|
|
my $res_content = $self->_http_request('POST', $url, $headers, $content, |
75
|
|
|
|
|
|
|
$self->_http_timing_tries,); |
76
|
|
|
|
|
|
|
|
77
|
0
|
|
|
|
|
|
my $doc = XML::LibXML->new(huge => 1)->load_xml(string => $res_content); |
78
|
0
|
|
|
|
|
|
my $xpc = XML::LibXML::XPathContext->new($doc); |
79
|
0
|
|
|
|
|
|
$xpc->registerNs($_ => $ns->{$_}) for keys %$ns; |
80
|
0
|
|
|
|
|
|
$xpc; |
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
sub _build_session_id { |
84
|
0
|
|
|
0
|
|
|
my ($self) = @_; |
85
|
|
|
|
|
|
|
|
86
|
0
|
|
|
|
|
|
my $xpc = $self->_soap_request($self->_auth_url, $self->_auth_ns, |
87
|
|
|
|
|
|
|
$self->_auth_content,); |
88
|
|
|
|
|
|
|
|
89
|
0
|
|
|
|
|
|
my $session_id = $xpc->findvalue( |
90
|
|
|
|
|
|
|
'/soap:Envelope/soap:Body/ns2:authenticateResponse/return'); |
91
|
|
|
|
|
|
|
|
92
|
0
|
|
|
|
|
|
return $session_id; |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
sub _search { |
96
|
0
|
|
|
0
|
|
|
my ($self, $start, $limit) = @_; |
97
|
|
|
|
|
|
|
|
98
|
0
|
|
|
|
|
|
my $response_type = $self->_search_response_type; |
99
|
|
|
|
|
|
|
|
100
|
0
|
|
|
|
|
|
my $xpc |
101
|
|
|
|
|
|
|
= $self->_soap_request($self->_search_url, $self->_search_ns, |
102
|
|
|
|
|
|
|
$self->_search_content($start, $limit), |
103
|
|
|
|
|
|
|
$self->session_id); |
104
|
|
|
|
|
|
|
|
105
|
0
|
|
|
|
|
|
my $recs = $self->_find_records($xpc, $response_type); |
106
|
0
|
|
|
|
|
|
my $total = $xpc->findvalue( |
107
|
|
|
|
|
|
|
"/soap:Envelope/soap:Body/ns2:$response_type/return/recordsFound"); |
108
|
0
|
|
|
|
|
|
my $query_id = $xpc->findvalue( |
109
|
|
|
|
|
|
|
"/soap:Envelope/soap:Body/ns2:$response_type/return/queryId"); |
110
|
|
|
|
|
|
|
|
111
|
0
|
|
|
|
|
|
return $recs, $total, $query_id; |
112
|
|
|
|
|
|
|
} |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
sub _retrieve { |
115
|
0
|
|
|
0
|
|
|
my ($self, $query_id, $start, $limit) = @_; |
116
|
|
|
|
|
|
|
|
117
|
0
|
|
|
|
|
|
my $xpc |
118
|
|
|
|
|
|
|
= $self->_soap_request($self->_search_url, $self->_search_ns, |
119
|
|
|
|
|
|
|
$self->_retrieve_content($query_id, $start, $limit), |
120
|
|
|
|
|
|
|
$self->session_id); |
121
|
|
|
|
|
|
|
|
122
|
0
|
|
|
|
|
|
$self->_find_records($xpc, $self->_retrieve_response_type); |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
sub generator { |
126
|
0
|
|
|
0
|
0
|
|
my ($self) = @_; |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
sub { |
129
|
0
|
|
|
0
|
|
|
state $recs = []; |
130
|
0
|
|
|
|
|
|
state $query_id; |
131
|
0
|
|
|
|
|
|
state $start = 1; |
132
|
0
|
|
|
|
|
|
state $limit = 100; |
133
|
0
|
|
|
|
|
|
state $total; |
134
|
|
|
|
|
|
|
|
135
|
0
|
0
|
|
|
|
|
unless (@$recs) { |
136
|
0
|
0
|
0
|
|
|
|
return if defined $total && $start > $total; |
137
|
|
|
|
|
|
|
|
138
|
0
|
0
|
|
|
|
|
if (defined $query_id) { |
139
|
0
|
|
|
|
|
|
$recs = $self->_retrieve($query_id, $start, $limit); |
140
|
|
|
|
|
|
|
} |
141
|
|
|
|
|
|
|
else { |
142
|
0
|
|
|
|
|
|
($recs, $total, $query_id) = $self->_search($start, $limit); |
143
|
0
|
0
|
|
|
|
|
$total || return; |
144
|
|
|
|
|
|
|
} |
145
|
|
|
|
|
|
|
|
146
|
0
|
|
|
|
|
|
$start += $limit; |
147
|
|
|
|
|
|
|
} |
148
|
|
|
|
|
|
|
|
149
|
0
|
|
|
|
|
|
shift @$recs; |
150
|
0
|
|
|
|
|
|
}; |
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
1; |