Bonjour.

je développe une petite app perso, qui me permet d'envoyer des fichiers à différents services web. (actuellement vers des sites d'hébergements d'images)

Dans le fichier principal de mon app, j'ai un premier dict :

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
 
        self.actions = {
 
			'services': {
				'config': {
					'jirafeau': {
						'days': {
							'default': 'month',
							'index': ['none', 'minute', 'hour', 'day',
										'week', 'month', 'year'],
							'day': {'active': True,
									'label': _('Un jour'), },
							'hour': {'active': True,
									'label': _('Une heure'), },
							'minute': {'active': True,
									'label': _(u'Une minute'), },
							'month': {'active': True,
									'label': _(u'Un mois'), },
							'none': {'active': True,
									'label': _(u'Illimité'), },
							'week': {'active': True,
									'label': _(u'Une semaine'), },
							'year': {'active': False,
									'label': _(u'Une année'), },
						},
						'input_key': '',    # to type password
						'member': False,
						'one_time_dl': 0,
					},
					'lufi': {
						'days': {
							'default': 30,
							'index': [1, 7, 30],
							1: {'active': True,
								'label': _(u'Un jour'), },
							7: {'active': True,
								'label': _(u'Une semaine'), },
							30: {'active': True,
								'label': _(u'Un mois'), },
						},
						'first_view': 0,
						'file_pwd': '',
						'zip-files': 0,
						'zipname': '',
					},
					'lutim': {
						'crypt': 1,
						'days': {
							'default': 7,
							'index': [0, 1, 7, 30, 90, 180, 365],
							0: {'active': False,
								'label': _(u'Illimité'), },
							1: {'active': True,
								'label': _(u'Un jour'), },
							7: {'active': True,
								'label': _(u'Une semaine'), },
							30: {'active': True,
								'label': _(u'Un mois'), },
							90: {'active': True,
								'label': _(u'Trois mois'), },
							180: {'active': True,
								'label': _(u'Six mois'), },
							365: {'active': True,
								'label': _(u'Un an'), },
						},
						'first_view': 0,
						'format_output': {
							'default': 'json',
							'index': ['json', 'web'],
							'json': {'active': True,
									'label': _(u'JSON'), },
							'web': {'active': True,
									'label': _(u'HTML'), },
						},
						'keep_exif': 0,
						'member': False,
						'retention': 0,
					},
					'pix': {
						'description': '',
						'img_infos': True,
						'member': True,
						'private': 0,
						'tags': '',
					},
				},
			},
 
			'sites': {
				'default': 'cybernux',                
			},
        }
Je récupère grâce au module 'from configparser import SafeConfigParser', je récupère des données d'un fichier de config .INI ; les voici :
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
 
[cybernux]
active = True
func = pix
label = Cyber-Nux
max_file_size = 20480000
url_member = https://pix.cyber-nux.fr/?action=login
url_upload = https://pix.cyber-nux.fr/?action=upload
 
[debianfacile]
active = True
days_default = none
func = jirafeau
label = Debian Facile
max_file_size = 2048
url_upload = https://debian-facile.org/images/
url_web = https://debian-facile.org/images/
 
[milkywan]
active = True
days_default = 365
func = lutim
label = MilkyWan
max_file_size = 
url_upload = https://pix.milkywan.fr
 
()
J'attire l'attention sur la déclaration 'func' qui a son utilité : elle permet de définir que tel site est de tel type de "services" (dont la configuration par défaut est rempli dans le dict self.actions['services']['config'][type_de_service]).

Ces données sont injectées dans un dictionnaire nommé self.actions['sites'].

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
 
{'index': ['arn', 'cybernux', 'debianfacile', 'framapic', 'jirafeau', 'milkywan', 'roflcopter', 'toilelibre'], 'arn': {'active': True, 'days': {'default': '30'}, 'func': 'lutim', 'label': 'ARN Sans-Nuage', 'max_file_size': 1000000000, 'only_image': False, 'url': {'upload': 'https://drop.sans-nuage.fr'}}, 'cybernux': {'active': True, 'func': 'pix', 'label': 'Cyber-Nux', 'max_file_size': 20480000, 'url': {'member': 'https://pix.cyber-nux.fr/?action=login', 'upload': 'https://pix.cyber-nux.fr/?action=upload'}}, 'debianfacile': {'active': True, 'days': {'default': 'none'}, 'func': 'jirafeau', 'label': 'Debian Facile', 'max_file_size': 2048, 'url': {'upload': 'https://debian-facile.org/images/', 'web': 'https://debian-facile.org/images/'}}, 'framapic': {'active': False, 'days': {'default': '180'}, 'func': 'lutim', 'label': 'Framapic', 'max_file_size': 1000000000, 'only_image': True, 'url': {'upload': 'https://framapic.org'}}, 'jirafeau': {'active': False, 'days': {'default': 'month'}, 'func': 'jirafeau', 'label': 'Jirafeau', 'max_file_size': 104857600, 'url': {'upload': 'https://demo.jirafeau.net/script.php', 'web': 'https://demo.jirafeau.net'}}, 'milkywan': {'active': True, 'days': {'default': '365'}, 'func': 'lutim', 'label': 'MilkyWan', 'max_file_size': '', 'only_image': True, 'urls_upload': 'https://pix.milkywan.fr'}, 'roflcopter': {'active': True, 'days': {'default': '30'}, 'func': 'lutim', 'label': 'RoflCopter', 'max_file_size': '', 'only_image': True, 'url': {'upload': 'https://wtf.roflcopter.fr/pics/'}}, 'toilelibre': {'active': False, 'func': 'pix', 'label': 'Toile Libre', 'max_file_size': 15360000, 'url': {'member': 'https://pix.toile-libre.org/?action=login', 'upload': 'https://pix.toile-libre.org/?action=upload'}}}
Ce que j'aimerais arrivé à faire est que les données du dictionnaire self.actions['services']['config'][type_de_service], qui sont elles aussi un dict, soient insérées dans le dict self.actions['sites'][namesite] selon la valeur de la variable 'func', sans réécrire les données récupérées depuis le fichier de config.

Pour cela, j'ai essayé l'utilisation de la fonction update() :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
for key, val in enumerate(self.actions['sites']['index']):
    # update self.actions sites with defaults services config
    func = self.actions['sites'][val]['func']            
    self.actions['sites'][val].update(
	self.actions['services']['config'][func])
ou :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
for key, val in enumerate(self.actions['sites']['index']):
    # update self.actions sites with defaults services config
    func = self.actions['sites'][val]['func']            
    self.actions['sites'][val].update(
	{k: v for k, v in self.actions['services']['config'][func].items() if v})
mais dans les deux cas, ça m'écrase les données… et ce n'est vraiment pas ce que je veux.

J'ai bien tenté l'utilisation de la fonction setdefault() - qui me semblait vraiment plus adéquate - :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
for key, val in enumerate(self.actions['sites']['index']):
    # update self.actions sites with defaults services config
    func = self.actions['sites'][val]['func']            
    self.actions['sites'][val].setdefault(
	self.actions['services']['config'][func])
Mais là, je bute avec le (fameux) message d'erreur suivant :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
 
Traceback (most recent call last):
  File "/home/user/Documents/Programmation/YUP.py/yup.py", line 637, in <module>
    yup = App()
          ^^^^^
  File "/home/user/Documents/Programmation/YUP.py/yup.py", line 546, in __init__
    self.rebuild_dict()
  File "/home/user/Documents/Programmation/YUP.py/yup.py", line 603, in rebuild_dict
    self.actions['sites'][val].setdefault(
TypeError: unhashable type: 'dict'
Je pense comprendre le propos, mais ne sait pas comment le résoudre !

Voilà. (en espérant être clair)