Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 40 |
|
0.00% |
0 / 10 |
CRAP | |
0.00% |
0 / 1 |
Swhid | |
0.00% |
0 / 40 |
|
0.00% |
0 / 10 |
342 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
getWait | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getUrl | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getSnapshot | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getSnapshotDate | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
fetchOrSave | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
6 | |||
fetchSnapshot | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
12 | |||
getBody | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
42 | |||
getStatus | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
saveCodeNow | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\MathSearch\Swh; |
4 | |
5 | use MediaWiki\Http\HttpRequestFactory; |
6 | use Throwable; |
7 | |
8 | class Swhid { |
9 | private $url; |
10 | private $httpFactory; |
11 | |
12 | private ?string $snapshot = null; |
13 | |
14 | private $snapshotDate; |
15 | private int $status; |
16 | |
17 | private int $wait = 0; |
18 | |
19 | public function __construct( |
20 | HttpRequestFactory $httpFactory, string $url |
21 | ) { |
22 | $this->url = $url; |
23 | $this->httpFactory = $httpFactory; |
24 | } |
25 | |
26 | public function getWait(): int { |
27 | return $this->wait; |
28 | } |
29 | |
30 | /** |
31 | * @return string |
32 | */ |
33 | public function getUrl(): string { |
34 | return $this->url; |
35 | } |
36 | |
37 | /** |
38 | * @return string |
39 | */ |
40 | public function getSnapshot(): ?string { |
41 | return $this->snapshot; |
42 | } |
43 | |
44 | /** |
45 | * @return mixed |
46 | */ |
47 | public function getSnapshotDate() { |
48 | return $this->snapshotDate; |
49 | } |
50 | |
51 | public function fetchOrSave() { |
52 | return $this->fetchSnapshot() || $this->saveCodeNow(); |
53 | } |
54 | |
55 | public function fetchSnapshot() { |
56 | $destination = "https://archive.softwareheritage.org/api/1/origin/$this->url/visit/latest/"; |
57 | $body = $this->getBody( $destination, 'GET' ); |
58 | if ( $body !== null ) { |
59 | $content = json_decode( $body ); |
60 | if ( $content->status === 'full' ) { |
61 | $this->snapshot = 'swh:1:snp:' . $content->snapshot; |
62 | $this->snapshotDate = $content->date; |
63 | return true; |
64 | } |
65 | } else { |
66 | $this->snapshot = null; |
67 | $this->snapshotDate = null; |
68 | } |
69 | |
70 | return false; |
71 | } |
72 | |
73 | public function getBody( string $destination, string $method = 'GET' ): ?string { |
74 | global $wgMathSearchSwhToken; |
75 | $req = $this->httpFactory->create( $destination, [ |
76 | 'method' => $method, |
77 | ] ); |
78 | if ( $wgMathSearchSwhToken ) { |
79 | $req->setHeader( 'Authorization', 'Bearer ' . $wgMathSearchSwhToken ); |
80 | } |
81 | $res = $req->execute(); |
82 | $this->status = $req->getStatus(); |
83 | if ( $res->isOK() ) { |
84 | return $req->getContent(); |
85 | } |
86 | try { |
87 | if ( $this->status == 429 ) { |
88 | $json = json_decode( $req->getContent() ); |
89 | if ( preg_match( '/(?P<seconds>\d+)\s+[sS]/', $json->reason, $match ) ) { |
90 | $this->wait = $match['seconds']; |
91 | return null; |
92 | } |
93 | } |
94 | } catch ( Throwable $exception ) { |
95 | // empty |
96 | } |
97 | // wait for 1 hour |
98 | $this->wait = 3600; |
99 | return null; |
100 | } |
101 | |
102 | public function getStatus() { |
103 | return $this->status; |
104 | } |
105 | |
106 | public function saveCodeNow() { |
107 | $destination = "https://archive.softwareheritage.org/api/1/origin/save/git/url/$this->url/"; |
108 | $body = $this->getBody( $destination, 'POST' ); |
109 | |
110 | return $body !== null; |
111 | } |
112 | |
113 | } |