Salut,
Bon je suis en train de faire un petit outil pour me faire gagner du temps... (enfin c'est surtout pour pratiquer python)
L'idée est la suivante : Avoir une liste de sites/matériels de ce genre :
1 : http://192.168.1.1:8081
2 : https://202.202.202:2002
...
Donc l'idée est de "pinger" l'adresse au choix en tapant "1" pour le site 1, "2" etc., et si il y a réponse au ping, ouvrir le navigateur avec l'adresse correspondante (ou ne pas l'ouvrir d'ailleurs, au choix).
J'ai une premier version qui fonctionne très bien, le problème est que je tente de rendre le bouzin plus propre (...bon, moins sale).
Et je bloque sur une partie particulière à savoir stocker une liste de fonctions dans un dictionnaire, et lancer ces fonctions selon le bon vouloir de l'utilisateur (je met le code en entier et je désignerai la partie problématique ensuite en précisant).
Bon attention les yeux sensibles hein, je suis loin d'être un expert...
Donc, la partie problématique se situe au niveau de user_input_received().
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243 # -*- coding: utf-8 *-* ############################################################################### # ping-and-open v0.4 # Auteur : Mathieu B. # # Description : * # # Module ping : http://www.g-loaded.eu/2009/10/30/python-ping/ # # Todo: # H - vérifier compatibilité linux # H - terminer la nouvelle version de user_input_received() # H - faire create_default_config() (récupérer et tester de la V02 tout caca) # M - Refaire/terminer toute la partie navigateur (webbrowser) # M - Refaire manuel_input() # L - gestion de imacro... ou pas # L - Vérifier read_conf si pas mieux... ############################################################################### try: import sys import msvcrt import platform #vérifier l'os import webbrowser #ouverture du navigateur import ConfigParser #lecture du fichier de conf import ping #module ping import os import time import socket #utilisé par ping.py except ImportError as exc: sys.stderr.write("[CRITIQUE]: Un module n'a pas ete trouve ({})".format(exc)) sys.exit("\nArret du programme") #------------------------------------------ class conf_parser: "charge et lit le fichier de conf" def __init__(self): self.config = ConfigParser.ConfigParser() def read_conf(self): "ouvrir et lire le fichier de conf" self.config.read('config.cfg') # lecture du fichier "config.cfg" self.hardware_list_tmp = [] # liste tampon pour les sections sites/matériels print "[INFO] Lecture du fichier de conf..." for section in self.config._sections: # construction dict sites/matériel (nom, ip, port) try: self.hardware_list_tmp.append({"Sect_name":section, "ip": self.config._sections[section]["ip"], "port":self.config._sections[section]["port"], "protocol":self.config._sections[section]["protocol"]}) except: if section != "General": print "[Alerte] Omission de la section '%s'\n > verifiez si il n'y a pas une erreur\n" % (section) # enfin on envoit toutes les infos de config vers les différentes variables de ping_and_open.__init__ return self.config.getint('General', 'timer'), self.config.get('General', 'browser_path'), self.config.get('General', 'open_browser'), self.config.getint('General', 'ping_limit'), self.hardware_list_tmp def create_default_config(self): "Création d'un fichier de config avec les valeurs par défaut" self.config.add_section('General') # Section générale self.config.set('General', "#", "ATTENTION pour les booléens : si l'option doit être desactivee, laisser vide (= ne pas mettre False)") self.config.set('General', 'timer', 5) self.config.set('General', 'browser_path', "") self.config.set('General', 'open_browser', "") self.config.set('General', 'ping_limit', 99) self.config.add_section('Manuel') self.config.set('Manuel', "#", "Ne pas supprimer cette section") self.config.set('Manuel', "ip", "a saisir manuellement") self.config.set('Manuel', "port", 80) self.config.set('Manuel',"protocol","http://") self.config.write(open('config.cfg','w')) self.config.add_section('Exemple') self.config.set('Exemple', "#","Exemple") self.config.set('Exemple', "ip", "192.168.1.1") self.config.set('Exemple', "port", 80) self.config.set('Exemple',"protocol","http://") self.config.write(open('config.cfg','w')) class ping_and_open(object): "Petit utilitaire pour pinger, accéder à l'interface web \nde différents sites - matériels\nCréé à l'occasion pour gagner du temps au boulot... ou pas" def __init__(self, key_config): self.timer = key_config[0] # écart entre les pings en secondes self.browser_path = key_config[1] # chemin complet vers le navigateur self.open_option = key_config[2] # Option "ouvrir le navigateur" après un ping réussi #print self.open_option # DEBUG #print type(self.open_option) # DEBUG #if self.open_option : # DEBUG #print "True" # DEBUG #else : # DEBUG #print "False" # DEBUG self.ping_request_limit = key_config[3] # limite du nombre de requetes self.hardware_list = key_config[4] # liste des sections matériel (ip, ports spécifiques, protocol) def do_ping_repeat(self, dest_ip, port, protocol): "Effectue un ping" self.requetes = 0 self.statut_ping_loop = True while (self.requetes < self.ping_request_limit) and (self.statut_ping_loop == True) : self.os_clear_screen() # on nettoie l'écran à chaque ping - voir si meilleur solution self.requetes += 1 print "[INFO] ctrl+c pour stopper a tout moment\n" print "%i requetes effectuees sur %i" % (self.requetes, self.ping_request_limit) try: # c'est pas très propre :/ print "\nAdresse MAC : %s" % (self.do_arp_search(dest_ip)[1]) # affiche la mac adress du matériel except: #si self.arp_search() ne trouve rien (genre ping échoué) : print "\nRecherche de l'adresse MAC..." try: if ping.Ping(dest_ip).do(): #si le ping recoit une réponse print "[UP]\n" if self.open_option : # si l'option d'ouverture du navigateur est True self.statut_ping_loop = False # on casse la boucle self.do_open_browser(dest_ip, port, protocol) # on lance le navigateur else: pass # sinon continuer de pinger(c'pas très propre ça encore...) else: print "[DOWN]\n" #si pas de réponse, time.sleep(int(self.timer)) #on marque une pause et la boucle continue except KeyboardInterrupt: # si ctrl-c, on affiche le message d'arrêt' self.statut_ping_loop = False # on casse la boucle print "\n[INFO] Operation stoppee par l'utilisateur" def do_arp_search(self, ip): "Renvoit l'adresse MAC" #print platform.system() # DEBUG self.arp_table = os.popen("arp -a") #on récupère la table arp for mac in self.arp_table: #on cherche dans la table l'ip qui nous intéresse if ip in mac: return mac.split() #on renvoit la ligne intéressant (mac seule extraite dans do_ping_repeat() ) break def do_open_browser(self, ip, port, protocol): "ouvrir le navigateur" print "[INFO] Lancement du navigateur...5s" time.sleep(5) # 5s d'attente', au cas où if self.browser_path == "none": try: webbrowser.open(protocol+ip+":"+port) except: #mmmh à refaire print "Outch ! Modifiez le fichier config.cfg puis \ncopier le chemin d'accès vers votre navigateur préféré" else: pass print "..." # mmmh, un temps trop long après cette fonction, chercher d'ou ça vient def do_print_menu(self): "Affiche la liste du matériel/sites" for i in self.hardware_list: print "%2i - %30s %s%s:%s" % (self.hardware_list.index(i), i["Sect_name"].ljust(30,"."),i["protocol"], i["ip"], i["port"]) def effect_typewriter(self, string, type_timer): "Petit effet : inscrit une phrase lettre par lettre, trop kikoo kowa" for letter in string: sys.stdout.write(letter) sys.stdout.flush() time.sleep(type_timer) def os_clear_screen(self): "Effacer l'écran" #print platform.system() # DEBUG if platform.system() == "Linux": #linux os.system('clear') else : #windows os.system('cls') def do_user_input(self): "Prompt" self.statut = True print "#-------------------------------------------------------#\n" self.effect_typewriter("..................-{ PING AND OPEN }-....................", 0.04) print "\nv0.4" print "#-------------------------------------------------------#" print "[INFO] Tapez 'help' pour obtenir de l'aide'" time.sleep(1) while self.statut: # boucle principale #self.os_clear_screen() print "\n" self.do_print_menu() self.user_input_received(raw_input()) def manuel_input(self): "Pinger manuel, cad laisser le choix ip, port protocol" self.usr_prompt = {"Quel est le protocol ? [http]" : "http", "Quelle est l'ip a pinger ? [192.168.1.1]" : "192.168.1.1", "Quel est le port ? [80]" : "80"} for q, v in self.usr_prompt.iteritems(): print q self.user_input_tmp = raw_input() if (self.user_input_tmp != ""): self.usr_prompt[q] = str(self.user_input_tmp) return self.usr_prompt["Quelle est l'ip a pinger ? [192.168.1.1]"], self.usr_prompt["Quel est le port ? [80]"], self.usr_prompt["Quel est le protocol ? [http]"] def user_input_received(self, user_input): self.commandes = {"q" : self.com_quit, # Quitter "t": self.com_timer, # timer "o": self.com_open_nav, # ouvrir nav "l": self.com_plimit, # ping limit "help": self.com_help} self.os_clear_screen() # on nettoie l'écran try: #print self.commandes[user_input] # DEBUG self.commandes[user_input]() except : "[ALERTE] Erreur de saisie. Tapez 'help' pour plus d'info" def com_quit(self): #quitter self.statut = False print "fin du programme" def com_timer(self): #timer change print "[INFO] Timer est actuellement de (en seconde) : %i\nEntrez la nouvelle valeur" % (self.timer) self.timer = int(raw_input()) #DEBUG ah ! le coquinou ! toi être un integer !!! def com_open_nav(self): #ouvrir le navigateur if self.open_option : print "[INFO] Option ouvrir navigateur : Desactivee" self.open_option = False else : print "[INFO] Option ouvrir navigateur : Activee" self.open_option = True def com_plimit(self): #limiter nombre de ping print "[INFO] Ping limite est actuellement de : %i \nEntrez la nouvelle valeur" % (self.ping_request_limit) self.ping_request_limit = int(raw_input()) def com_help(self): # affiche les les options modifiables print "#----------------------------------HELP----------------------------#" print "Tapez l'une des lettre suivantes pour effectuer l'action correspondante\n" print "[q] : Quitter le programme\n[t] : Modifier le Temps entre chaque ping\n[o] : Au premier ping reussi, Ouvre le navigateur (on/off)\n[l] : Modifier la Limite max de ping a effectuer" print "\nPour modifier durablement ces options, modifiez le fichier de \nconfiguration 'config.cfg' se trouvant dans le repertoire du script.\n\nDans ce meme fichier, vous pouvez ajouter de nouveaux sites/materiels" print "#----------------------------------FIN-----------------------------#" def com_ping(self, user_input): self.do_ping_repeat(self.hardware_list[int(user_input)]["ip"],self.hardware_list[int(user_input)]["port"], self.hardware_list[int(user_input)]["protocol"]) #here we gooooo ! if __name__ == '__main__': initialisation = conf_parser() initialisation.create_default_config() # DEBUG créer le fichier de conf start = ping_and_open(initialisation.read_conf()) #start.do_arp_search("192.168.1.1") DEBUG start.do_user_input()
Je résume le fonctionnement.
L'utilisateur est invité à taper quelque chose : do_user_input()
Ce qui a été tapé est traité : user_input_received() (... oui sans rien tester)
Puis on lance les fonctions stockées dans self.commandes{} selon ce qu'a tapé l'utilisateur...et c'est le drame.
Parce que taper "help" ou une commande stockée fonctionne parfaitement, mais comment faire pour lancer com_ping() avec une des clés du dictionnaire contenant la liste des sites/matériels, pour lancer le ping...
Je ne sais pas si c'est très clair... :/
Je vous met une version qui fonctionne ici, histoire que vous puissiez voir comme fonctionne ce petit programme :
Auriez-vous une piste pour me sortir de ce cul-de-sac ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240 # -*- coding: utf-8 *-* ############################################################################### # ping-and-open v0.4 # Auteur : Mathieu B. # # Description : * # # Module ping : http://www.g-loaded.eu/2009/10/30/python-ping/ # # Todo: # H - vérifier compatibilité linux # H - terminer la nouvelle version de user_input_received() # H - faire create_default_config() (récupérer et tester de la V02 tout caca) # M - Refaire/terminer toute la partie navigateur (webbrowser) # M - Refaire manuel_input() # L - gestion de imacro... ou pas # L - Vérifier read_conf si pas mieux... ############################################################################### try: import sys import msvcrt import platform #vérifier l'os import webbrowser #ouverture du navigateur import ConfigParser #lecture du fichier de conf import ping #module ping import os import time import socket #utilisé par ping.py except ImportError as exc: sys.stderr.write("[CRITIQUE]: Un module n'a pas ete trouve ({})".format(exc)) sys.exit("\nArret du programme") #------------------------------------------ class conf_parser: "charge et lit le fichier de conf" def __init__(self): self.config = ConfigParser.ConfigParser() def read_conf(self): "ouvrir et lire le fichier de conf" self.config.read('config.cfg') # lecture du fichier "config.cfg" self.hardware_list_tmp = [] # liste tampon pour les sections sites/matériels print "[INFO] Lecture du fichier de conf..." for section in self.config._sections: # construction dict sites/matériel (nom, ip, port) try: self.hardware_list_tmp.append({"Sect_name":section, "ip": self.config._sections[section]["ip"], "port":self.config._sections[section]["port"], "protocol":self.config._sections[section]["protocol"]}) except: if section != "General": print "[Alerte] Omission de la section '%s'\n > verifiez si il n'y a pas une erreur\n" % (section) # enfin on envoit toutes les infos de config vers les différentes variables de ping_and_open.__init__ return self.config.getint('General', 'timer'), self.config.get('General', 'browser_path'), self.config.get('General', 'open_browser'), self.config.getint('General', 'ping_limit'), self.hardware_list_tmp def create_default_config(self): "Création d'un fichier de config avec les valeurs par défaut" self.config.add_section('General') # Section générale self.config.set('General', "#", "ATTENTION pour les booléens : si l'option doit être desactivee, laisser vide (= ne pas mettre False)") self.config.set('General', 'timer', 5) self.config.set('General', 'browser_path', "") self.config.set('General', 'open_browser', "") self.config.set('General', 'ping_limit', 99) self.config.add_section('Manuel') self.config.set('Manuel', "#", "Ne pas supprimer cette section") self.config.set('Manuel', "ip", "a saisir manuellement") self.config.set('Manuel', "port", 80) self.config.set('Manuel',"protocol","http://") self.config.write(open('config.cfg','w')) self.config.add_section('Exemple') self.config.set('Exemple', "#","Exemple") self.config.set('Exemple', "ip", "192.168.1.1") self.config.set('Exemple', "port", 80) self.config.set('Exemple',"protocol","http://") self.config.write(open('config.cfg','w')) class ping_and_open(object): "Petit utilitaire pour pinger, accéder à l'interface web \nde différents sites - matériels\nCréé à l'occasion pour gagner du temps au boulot... ou pas" def __init__(self, key_config): self.timer = key_config[0] # écart entre les pings en secondes self.browser_path = key_config[1] # chemin complet vers le navigateur self.open_option = key_config[2] # Option "ouvrir le navigateur" après un ping réussi #print self.open_option # DEBUG #print type(self.open_option) # DEBUG #if self.open_option : # DEBUG #print "True" # DEBUG #else : # DEBUG #print "False" # DEBUG self.ping_request_limit = key_config[3] # limite du nombre de requetes self.hardware_list = key_config[4] # liste des sections matériel (ip, ports spécifiques, protocol) def do_ping_repeat(self, dest_ip, port, protocol): "Effectue un ping" self.requetes = 0 self.statut_ping_loop = True while (self.requetes < self.ping_request_limit) and (self.statut_ping_loop == True) : self.os_clear_screen() # on nettoie l'écran à chaque ping - voir si meilleur solution self.requetes += 1 print "[INFO] ctrl+c pour stopper a tout moment\n" print "%i requetes effectuees sur %i" % (self.requetes, self.ping_request_limit) try: # c'est pas très propre :/ print "\nAdresse MAC : %s" % (self.do_arp_search(dest_ip)[1]) # affiche la mac adress du matériel except: #si self.arp_search() ne trouve rien (genre ping échoué) : print "\nRecherche de l'adresse MAC..." try: if ping.Ping(dest_ip).do(): #si le ping recoit une réponse print "[UP]\n" if self.open_option : # si l'option d'ouverture du navigateur est True self.statut_ping_loop = False # on casse la boucle self.do_open_browser(dest_ip, port, protocol) # on lance le navigateur else: pass # sinon continuer de pinger(c'pas très propre ça encore...) else: print "[DOWN]\n" #si pas de réponse, time.sleep(int(self.timer)) #on marque une pause et la boucle continue except KeyboardInterrupt: # si ctrl-c, on affiche le message d'arrêt' self.statut_ping_loop = False # on casse la boucle print "\n[INFO] Operation stoppee par l'utilisateur" def do_arp_search(self, ip): "Renvoit l'adresse MAC" #print platform.system() # DEBUG self.arp_table = os.popen("arp -a") #on récupère la table arp for mac in self.arp_table: #on cherche dans la table l'ip qui nous intéresse if ip in mac: return mac.split() #on renvoit la ligne intéressant (mac seule extraite dans do_ping_repeat() ) break def do_open_browser(self, ip, port, protocol): "ouvrir le navigateur" print "[INFO] Lancement du navigateur...5s" time.sleep(5) # 5s d'attente', au cas où if self.browser_path == "none": try: webbrowser.open(protocol+ip+":"+port) except: #mmmh à refaire print "Outch ! Modifiez le fichier config.cfg puis \ncopier le chemin d'accès vers votre navigateur préféré" else: pass print "..." # mmmh, un temps trop long après cette fonction, chercher d'ou ça vient def do_print_menu(self): "Affiche la liste du matériel/sites" for i in self.hardware_list: print "%2i - %30s %s%s:%s" % (self.hardware_list.index(i), i["Sect_name"].ljust(30,"."),i["protocol"], i["ip"], i["port"]) def effect_typewriter(self, string, type_timer): "Petit effet : inscrit une phrase lettre par lettre, trop kikoo kowa" for letter in string: sys.stdout.write(letter) sys.stdout.flush() time.sleep(type_timer) def os_clear_screen(self): "Effacer l'écran" #print platform.system() # DEBUG if platform.system() == "Linux": #linux os.system('clear') else : #windows os.system('cls') def do_user_input(self): "Prompt" self.statut = True print "#-------------------------------------------------------#\n" self.effect_typewriter("..................-{ PING AND OPEN }-....................", 0.04) print "\nv0.4" print "#-------------------------------------------------------#" print "[INFO] Tapez 'help' pour obtenir de l'aide'" time.sleep(1) while self.statut: # boucle principale #self.os_clear_screen() print "\n" self.do_print_menu() self.user_input_received(raw_input()) def manuel_input(self): "Pinger manuel, cad laisser le choix ip, port protocol" self.usr_prompt = {"Quel est le protocol ? [http]" : "http", "Quelle est l'ip a pinger ? [192.168.1.1]" : "192.168.1.1", "Quel est le port ? [80]" : "80"} for q, v in self.usr_prompt.iteritems(): print q self.user_input_tmp = raw_input() if (self.user_input_tmp != ""): self.usr_prompt[q] = str(self.user_input_tmp) return self.usr_prompt["Quelle est l'ip a pinger ? [192.168.1.1]"], self.usr_prompt["Quel est le port ? [80]"], self.usr_prompt["Quel est le protocol ? [http]"] # version à l'arrache... def user_input_received(self, user_input): "Traite le choix de l'utilisateur'" # pas super, mais bon, ça fonctionne self.os_clear_screen() # on nettoie l'écran if user_input == "q": #quitter self.statut = False print "fin du programme" elif user_input == "t": #timer change print "[INFO] Timer est actuellement de (en seconde) : %i\nEntrez la nouvelle valeur" % (self.timer) self.timer = int(raw_input()) #DEBUG ah ! le coquinou ! integer !!! elif user_input == "o": #ouvrir le navigateur if self.open_option : print "[INFO] Option ouvrir navigateur : Desactivee" self.open_option = False else : print "[INFO] Option ouvrir navigateur : Activee" self.open_option = True elif user_input == "help": # affiche les les options modifiables print "#----------------------------------HELP----------------------------#" print "Tapez l'une des lettre suivantes pour effectuer l'action correspondante\n" print "[q] : Quitter le programme\n[t] : Modifier le Temps entre chaque ping\n[o] : Au premier ping reussi, Ouvre le navigateur (on/off)\n[l] : Modifier la Limite max de ping a effectuer" print "\nPour modifier durablement ces options, modifiez le fichier de \nconfiguration 'config.cfg' se trouvant dans le repertoire du script.\n\nDans ce meme fichier, vous pouvez ajouter de nouveaux sites/materiels" print "#----------------------------------FIN-----------------------------#" elif user_input == "l": #limiter nombre de ping print "[INFO] Ping limite est actuellement de : %i \nEntrez la nouvelle valeur" % (self.ping_request_limit) self.ping_request_limit = int(raw_input()) elif user_input == "0": #Manuel self.do_ping_repeat(*self.manuel_input()) #wooooow, l'asterisk!!! else : #mmmh tout ça à vérifier, parait ultra crade et pas logique try: # requete ping if self.ping_request_limit != 99: # si la limite de ping est paramétrée, lancer x ping self.do_ping_repeat(self.hardware_list[int(user_input)]["ip"],self.hardware_list[int(user_input)]["port"], self.hardware_list[int(user_input)]["protocol"]) else: self.do_ping_repeat(self.hardware_list[int(user_input)]["ip"],self.hardware_list[int(user_input)]["port"], self.hardware_list[int(user_input)]["protocol"]) except: print "[ALERTE] Erreur de saisie. Tapez 'help' pour plus d'info" #here we gooooo ! if __name__ == '__main__': initialisation = conf_parser() initialisation.create_default_config() # DEBUG créer le fichier de conf start = ping_and_open(initialisation.read_conf()) #start.do_arp_search("192.168.1.1") DEBUG start.do_user_input()![]()
Partager