Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 40
0.00% covered (danger)
0.00%
0 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
Swhid
0.00% covered (danger)
0.00%
0 / 40
0.00% covered (danger)
0.00%
0 / 10
342
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getWait
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getUrl
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSnapshot
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSnapshotDate
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 fetchOrSave
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
6
 fetchSnapshot
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
12
 getBody
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
42
 getStatus
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 saveCodeNow
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Extension\MathSearch\Swh;
4
5use MediaWiki\Http\HttpRequestFactory;
6use Throwable;
7
8class 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}