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