6
6
import requests
7
7
import pystray
8
8
import winreg
9
+ import psutil
9
10
import time
10
11
import json
11
12
import sys
12
13
import os
13
14
14
-
15
15
def readConfig (configFilePath ):
16
16
config = configparser .ConfigParser ()
17
17
@@ -27,7 +27,6 @@ def readConfig(configFilePath):
27
27
}
28
28
return config
29
29
30
-
31
30
def updateConfig ():
32
31
def displayRecords (records ):
33
32
newWindow = Toplevel (root )
@@ -118,17 +117,9 @@ def checkEntries(*args):
118
117
119
118
root .mainloop ()
120
119
121
-
122
120
def updateDns (target , port , apiToken , zoneId , recordId ):
123
121
with contextlib .suppress (Exception ):
124
122
response = requests .patch (f"https://api.cloudflare.com/client/v4/zones/{ zoneId } /dns_records/{ recordId } " , json = {"data" : {"port" : port , "target" : target }}, headers = {"Authorization" : f"Bearer { apiToken } " })
125
- if response .status_code != 200 :
126
- errorData = json .loads (response .content )
127
- errorMessages = [error ['message' ] for error in errorData .get ('errors' , [])]
128
- errorMessageStr = "\n " .join (errorMessages )
129
- messagebox .showerror ("Error" , f"An error occurred while updating DNS:\n { errorMessageStr } \n \n Make sure your API token has the right privileges." )
130
- stop ()
131
-
132
123
133
124
def checkForUpdates ():
134
125
response = requests .get ("https://api.github.com/repos/voidlesity/ngrok-dynamic-dns/releases/latest" ).json ()
@@ -146,6 +137,13 @@ def checkForUpdates():
146
137
subprocess .run (["NgrokDynamicDNS-installer.exe" ])
147
138
stop ()
148
139
140
+ def checkForMultipleInstances ():
141
+ process_count = 0
142
+ for process in psutil .process_iter (['name' ]):
143
+ if process .info ['name' ] == "NgrokDynamicDNS.exe" :
144
+ process_count += 1
145
+ if process_count > 2 :
146
+ stop ()
149
147
150
148
def toggleAutostart ():
151
149
config .set ('DEFAULT' , 'autostart' , f"{ not config .getboolean ('DEFAULT' , 'autostart' )} " )
@@ -164,38 +162,29 @@ def autostart():
164
162
else :
165
163
winreg .DeleteValue (registry_key , "Ngrok Dynamic DNS" )
166
164
167
-
168
165
def stop ():
169
166
icon .stop ()
170
167
os ._exit (0 )
171
168
172
-
173
169
def main ():
174
170
prevTarget = None
175
171
prevPort = None
176
-
177
172
while True :
178
- try :
173
+ with contextlib . suppress ( Exception ) :
179
174
response = requests .get (ngrokApiUrl )
180
175
response .raise_for_status ()
181
-
182
176
if response .status_code == 200 :
183
177
ngrokData = response .json ()['tunnels' ][0 ]['public_url' ].strip ("tcp://" ).split (":" )
184
178
target = ngrokData [0 ]
185
179
port = ngrokData [1 ]
186
-
187
180
if target != prevTarget or port != prevPort :
188
181
updateDns (target , port , apiToken , zoneId , recordId )
189
182
prevTarget = target
190
183
prevPort = port
191
-
192
184
time .sleep (30 )
193
- except Exception as e :
194
- messagebox .showerror ("Error" , f"An error occurred while trying to fetch tunnel info:\n { e } \n \n Make sure the Ngrok URL is set correctly." )
195
- stop ()
196
185
197
186
if __name__ == "__main__" :
198
- currentVersion = "v1.1.0 "
187
+ currentVersion = "v1.1.1 "
199
188
allVars = ['api_token' , 'zone_id' , 'record_id' , 'ngrok_api_url' ]
200
189
201
190
configFilePath = os .path .join (os .path .expanduser ("~" ), ".config" , "voidlesity" , "NgrokDynamicDNS.config" )
@@ -220,6 +209,7 @@ def main():
220
209
icon = pystray .Icon ("NgrokDynamicDNS" , iconImage , title = "NgrokDynamicDNS" , menu = menu )
221
210
icon .run_detached ()
222
211
212
+ checkForMultipleInstances ()
223
213
checkForUpdates ()
224
214
autostart ()
225
215
main ()
0 commit comments