11
22from PyQt5 .QtNetwork import QNetworkAccessManager , QNetworkRequest , QNetworkReply
3- from PyQt5 .QtCore import QUrl ,QObject ,pyqtSignal ,QEventLoop ,QCoreApplication
3+ from PyQt5 .QtCore import QUrl ,QObject ,pyqtSignal ,QEventLoop ,QCoreApplication , QThread , QElapsedTimer
44import json
55import re
66import os
77import tempfile
8+ import subprocess
89
10+
11+ class PingThread (QThread ):
12+ pingSignal = pyqtSignal (str ,float )
13+ def __init__ (self , name : str ,url : str ,parent : QObject | None = None ) -> None :
14+ super ().__init__ (parent )
15+ self .reSet (name ,url )
16+
17+ def reSet (self ,name : str ,url : str ):
18+ self .name = name
19+ self .url = url
20+ self .host = self .url .split ("/" )
21+
22+
23+ def ping (self ):
24+ timer = QElapsedTimer ()
25+ timer .start ()
26+ try :
27+ nam = QNetworkAccessManager (self )
28+ request = QNetworkRequest (QUrl (self .url ))
29+
30+ reply = nam .get (request )
31+ loop = QEventLoop ()
32+ reply .finished .connect (loop .quit )
33+ loop .exec_ ()
34+
35+ except Exception as e :
36+ return float ('inf' )
37+ time = timer .elapsed ()
38+ return time
39+
40+ def run (self ):
41+ responseTime = self .ping ()
42+ self .pingSignal .emit (self .name , responseTime )
43+
44+
45+ class SourceManager (QObject ):
46+ quickSource = pyqtSignal (str ,float )
47+ def __init__ (self ,sources :dict ,parent = None ):
48+ super ().__init__ ()
49+ if not isinstance (sources ,dict ):
50+ raise TypeError
51+ if not sources :
52+ raise ValueError
53+ self .sources = sources
54+ # 第一个的key
55+ self .currentSource = list (sources .keys ())[0 ]
56+ self .speedData = {}
57+ self .threads = []
58+
59+
60+ @property
61+ def sources (self ):
62+ return self .__sources
63+
64+ @sources .setter
65+ def sources (self ,sources :dict ):
66+ if not isinstance (sources ,dict ):
67+ raise TypeError
68+ if not sources :
69+ raise ValueError
70+ for key in sources :
71+ sources [key ] = sources [key ].strip ('/' )
72+ self .__sources = sources
73+ self .currentSource = list (sources .keys ())[0 ]
74+
75+ @property
76+ def currentSource (self ):
77+ return self .__currentSource
78+
79+ @currentSource .setter
80+ def currentSource (self ,currentSource :str ):
81+ if currentSource not in self .sources :
82+ raise ValueError
83+ self .__currentSource = currentSource
84+
85+ @property
86+ def currentSourceUrl (self ):
87+ return self .sources [self .currentSource ]
88+
89+ def checkSourceSpeed (self ):
90+ self .threads .clear ()
91+ self .speedData = {}
92+ for source in self .sources :
93+ thread = PingThread (source , self .sources [source ])
94+ thread .pingSignal .connect (self .pingSignal )
95+ self .threads .append (thread )
96+ thread .start ()
97+
98+ def pingSignal (self ,url : str , responseTime : float ):
99+ self .speedData [url ] = responseTime
100+ if len (self .speedData ) == len (self .sources ):
101+ quickTime = float ('inf' )
102+ quickKey = ''
103+ for key ,value in self .speedData .items ():
104+ if value < quickTime :
105+ quickTime = value
106+ quickKey = key
107+ self .quickSource .emit (quickKey ,quickTime )
108+
9109class Release :
10110 def __init__ (self ,dict ):
11111 self .tag_name = dict ['tag_name' ]
@@ -26,21 +126,21 @@ class GitHub(QObject):
26126 downloadReleaseAsyncProgressSignal = pyqtSignal (int ,int )
27127 downloadReleaseAsyncFinishSignal = pyqtSignal (str )
28128 errorSignal = pyqtSignal (str )
29- def __init__ (self ,source : str ,owner :str ,repo :str ,version :str ,versionReStr :str ,parent = None ):
129+ def __init__ (self ,sourcemanager : SourceManager ,owner :str ,repo :str ,version :str ,versionReStr :str ,parent = None ):
30130 super ().__init__ (parent )
31- self .__source = source . strip ( '/' )
131+ self .__sourcemanager = sourcemanager
32132 self .__owner = owner
33133 self .__repo = repo
34134 self .__version = version
35135 self .__versionReStr = versionReStr
36136
37137 @property
38- def source (self ):
39- return self .__source
138+ def sourceManager (self ):
139+ return self .__sourcemanager
40140
41- @source .setter
42- def source (self ,source : str ):
43- self .__source = source
141+ @sourceManager .setter
142+ def sourceManager (self ,sourcemanager : SourceManager ):
143+ self .__sourcemanager = sourcemanager
44144
45145 @property
46146 def owner (self ):
@@ -75,10 +175,10 @@ def versionReStr(self,versionReStr:str):
75175 self .__versionReStr = versionReStr
76176 @property
77177 def latestReleaseUrl (self ) -> str :
78- return f'{ self .__source } /{ self .__owner } /{ self .__repo } /releases/latest'
178+ return f'{ self .sourceManager . currentSourceUrl } /{ self .__owner } /{ self .__repo } /releases/latest'
79179 @property
80180 def releasesUrl (self ) -> str :
81- return f'{ self .__source } /{ self .__owner } /{ self .__repo } /releases'
181+ return f'{ self .sourceManager . currentSourceUrl } /{ self .__owner } /{ self .__repo } /releases'
82182 @property
83183 def header (self ) -> dict :
84184 return {
@@ -228,8 +328,15 @@ def error(self,errorStr:str):
228328
229329if __name__ == '__main__' :
230330 app = QCoreApplication ([])
231- github = GitHub ("https://api.github.com/repos/" ,"eee555" ,"Solvable-Minesweeper" ,"3.1.9" ,"(\d+\.\d+\.\d+)" )
331+ data = {
332+ "Github" : "https://api.github.com/repos/" ,
333+ "fff666" : "https://fff666.top/" ,
334+ }
335+ github = GitHub (SourceManager (data ),"eee555" ,"Solvable-Minesweeper" ,"3.1.9" ,"(\d+\.\d+\.\d+)" )
232336 github .releasesAsyncSignal .connect (lambda x :print (x ))
233337 github .releases ()
338+ # manager = SourceManager(data)
339+ # manager.quickSource.connect(lambda x,y:print(x,y))
340+ # manager.checkSourceSpeed()
234341 app .exec_ ()
235342
0 commit comments