Projet

Général

Profil

Paste
Télécharger (5,94 ko) Statistiques
| Branche: | Révision:

root / scripts_divers / migrer_taches_vers_redmine / goto_redmine.py @ 65ce03da

1 8a509595 jenselme
"""
2
Pandoc est requis pour convertir le html en textile !
3
"""
4
5
import url_parser  #permet de connaître les id des taches
6 a2a6f2e9 jenselme
import urllib.request #permet de récupérer une page web
7
import httplib2 #pour faire des requêtes http
8 565596d9 jenselme
import json
9 a2a6f2e9 jenselme
import re #pour les expressions régulières
10
import os #pour pouvoir faire appel à pandoc (commande system)
11 565596d9 jenselme
12 a2a6f2e9 jenselme
######## NB : cid : comment id, nid : node id, urls : urls des tâches
13
14
#Dictionnaire des gens dont on a la clé API
15
#id: clé
16 b1cefa06 jenselme
SUBMITERS = {'jenselme': '464c7c05b9bb53fb136092f1b9807ad91ec51321'}
17 a2a6f2e9 jenselme
18
#les entêtes des requêtes POST et PUT
19 565596d9 jenselme
Headers = {'content-type': 'application/json', 'X-Redmine-API-Key': ''}
20 a2a6f2e9 jenselme
21
#là où on poste les tâches
22 b1cefa06 jenselme
URL = 'https://forge.centrale-marseille.fr/issues'
23 a2a6f2e9 jenselme
24
#là où sont les tâches
25 8a509595 jenselme
LIST_TODO = 'http://localhost/portail/liste-tache'
26 a2a6f2e9 jenselme
27
#url de base de l’emplacement du contenu
28 8a509595 jenselme
BASE_URL = 'http://localhost/portail'
29 b1cefa06 jenselme
PROJECT_ID = 30
30 8a509595 jenselme
TRACKER_ID = 2
31 a2a6f2e9 jenselme
32
33
########## dictionnaires de correspondance
34 3a9aefa9 jenselme
DONE_RATIO = {'En pause': 50, 'À commencer': 0, 'Entamée': 20, 'Bien avancée': 80, 'Terminée (success)': 100, 'Fermée (won\'t fix)': 100}
35 8a509595 jenselme
PRIORITY = {'5 - Très basse': 3, '4 - Basse': 3, '3 - Moyenne': 4, '2 - Haute': 5, '1 - Très haute': 6,\
36 3a9aefa9 jenselme
        'Très basse': 3, 'Basse': 3, 'Moyenne': 4, 'Haute': 5, 'Très haute':6,\
37
        '0': 3, '1': 3, '2': 4, '3': 5, '4': 6}
38 8a509595 jenselme
STATUS = {'En cours': 2, 'Fermée': 5, 'Rejetée': 6, 'En pause': 7}
39 a2a6f2e9 jenselme
#NB sur le portail, on a les équivalences suivantes
40
#pour le champ version de drupal : 17 : drupal6, 18 : drupal7
41 b1cefa06 jenselme
DRUPAL_VERSION = {'17': 2, '18': 1}
42 565596d9 jenselme
43
def give_api_key(submiter):
44 a2a6f2e9 jenselme
    "Donne la clé API de submiter ou celle de jenselme si c’est la seule"
45 565596d9 jenselme
    if submiter in SUBMITERS:
46
        return SUBMITERS[submiter]
47
    else:
48
        return  SUBMITERS['jenselme']
49
50 8a509595 jenselme
51
def give_comments_ids(nid):
52 a2a6f2e9 jenselme
    "permet de récupérer les id des commentaires de la tâche nid"
53 3a9aefa9 jenselme
    page = urllib.request.urlopen(BASE_URL + '/entity_json/node/' + nid).read()
54
    page_json = json.loads(page.decode('utf-8'))
55
    comments_json = page_json['comments']
56
    #S’il n’y a pas de commentaire, comments_json est une liste vide et pas un dictionnaire
57
    if comments_json:
58
        comments = list(comments_json.keys())
59
        comments.sort() #ce sont les clés d’un dictionnaire. Pas d’ordre à priori
60
        return comments
61
    else:
62
        return list()
63 8a509595 jenselme
64
65
def give_comments(cids):
66 a2a6f2e9 jenselme
    "Donne la liste du texte des commentaires pour chaque cid in cids"
67 8a509595 jenselme
    comments = list()
68
    for cid in cids:
69
        comment = urllib.request.urlopen(BASE_URL + '/comment/' + cid + '.json').read()
70 3a9aefa9 jenselme
        comments.append(json.loads(comment.decode('utf-8')))
71 8a509595 jenselme
    return comments
72
73
74
def format(txt):
75 a2a6f2e9 jenselme
    "prend le texte en html et le renvoie en textile"
76 8a509595 jenselme
    txt.replace('\n', '')
77
    txt.replace('\t', '')
78
    with open('tmp.html', 'w') as f:
79
        f.write(txt)
80
    os.system('pandoc -f html tmp.html -t textile -o tmp.textile')
81
    with open('tmp.textile', 'r') as f:
82
        txt = f.read()
83
    return txt
84
85
86
def give_redmine_status_id(tache):
87
    drupal_status = ''
88
    for elt in tache['field_avancement']:
89
        if "Terminée" in elt:
90
            drupal_status = 'Fermée'
91
            break
92
        elif "Fermée" in elt:
93
            drupal_status = 'Rejetée'
94
            break
95
        elif "pause" in elt:
96
            drupal_status = 'En pause'
97
            del elt
98
            break
99 3a9aefa9 jenselme
    if not drupal_status:
100
        drupal_status = 'En cours'
101 8a509595 jenselme
    return STATUS[drupal_status]
102
103
104
def give_redmine_issue(tache):
105
    issue = dict()
106
    issue['project_id'] = PROJECT_ID
107
    issue['tracker_id'] = TRACKER_ID
108
    issue['subject'] = tache['title']
109
    issue['description'] = format(tache['body']['value'])
110 3a9aefa9 jenselme
    #de temps en temps, le champ priorité est vide. On met 'Normale' dans ce cas
111
    if tache['field_prioritaecute']:
112
        issue['priority_id'] = PRIORITY[tache['field_prioritaecute']]
113
    else:
114
        issue['priority_id'] = PRIORITY['3 - Moyenne']
115
    if tache['field_avancement']:
116
        issue['done_ratio'] = DONE_RATIO[tache['field_avancement'][0]]
117
    else:
118
        issue['done_ratio'] = DONE_RATIO['À commencer']
119 8a509595 jenselme
    issue['status_id'] = give_redmine_status_id(tache)
120 3a9aefa9 jenselme
    issue['fixed_version_id'] = DRUPAL_VERSION[tache['taxonomy_vocabulary_8']['id']]
121
    return issue
122 8a509595 jenselme
123
124 a2a6f2e9 jenselme
######### Main
125
126 8a509595 jenselme
nids, urls = url_parser.give_json_urls(LIST_TODO, BASE_URL)
127 565596d9 jenselme
128
h = httplib2.Http()
129
130 35c29fad jenselme
for post_url in urls:
131
    nid = nids[urls.index(post_url)]
132 3a9aefa9 jenselme
    print(nid)
133 8a509595 jenselme
    tache_json = urllib.request.urlopen(post_url)
134 3a9aefa9 jenselme
    tache_drupal = json.loads(tache_json.read().decode('utf-8'))
135 565596d9 jenselme
136 8a509595 jenselme
    cids = give_comments_ids(nid)
137
    comments_drupal = give_comments(cids)
138 565596d9 jenselme
139
    issue = {}
140 8a509595 jenselme
    issue['issue'] = give_redmine_issue(tache_drupal)
141 565596d9 jenselme
    data = json.dumps(issue)
142
143 8a509595 jenselme
    Headers['X-Redmine-API-Key'] = SUBMITERS['jenselme']
144 565596d9 jenselme
145
    resp, content = h.request(URL + '.json', 'POST', body=data, headers=Headers)
146
147 8a509595 jenselme
    #on récupère l’issue id pour savoir où poster les commentaires
148 565596d9 jenselme
    iid = re.findall(r',"id":([0-9]*),', content.decode('utf-8'))[0]
149
150 35c29fad jenselme
    #on a besoin de l’url à laquelle on met les commentaires, pour changer le status
151 3a9aefa9 jenselme
    put_url = URL + '/' + iid + '.json'
152 8a509595 jenselme
    for index, comment in enumerate(comments_drupal):
153
        submiter = comment['name']  #le premier est celui qui a soumis le node
154 35c29fad jenselme
        Headers['X-Redmine-API-Key'] = give_api_key(submiter)
155
        #si la personne n’a pas sa clé, on modifie le commentaire
156 8a509595 jenselme
        comment_body = format(comment['comment_body']['value'])
157 35c29fad jenselme
        if not submiter in SUBMITERS:
158 3a9aefa9 jenselme
            comment_body = "_{}_ a dit que :\n\n{}".format(submiter, comment_body)
159 35c29fad jenselme
        update = {}
160 8a509595 jenselme
        update['issue'] = {'notes': comment_body}
161 35c29fad jenselme
        data = json.dumps(update)
162
        h.request(put_url, 'PUT', body=data, headers=Headers)
163 565596d9 jenselme
164
    #Les taches sont crées avec le status nouveau peu importe ce qu’il y a dans le json
165
    #on modifie le status après coup
166 8a509595 jenselme
    update_status = {'issue': {'status_id': issue['issue']['status_id']}}
167 35c29fad jenselme
    data = json.dumps(update_status)
168 8a509595 jenselme
    h.request(put_url, 'PUT', body=data, headers=Headers)