2
2
* Fix challenges launched as DEVELOP > CODE
3
3
*/
4
4
global . Promise = require ( 'bluebird' )
5
+ const uuid = require ( 'uuid/v4' )
5
6
const moment = require ( 'moment' )
6
7
const config = require ( 'config' )
8
+ const request = require ( 'superagent' )
9
+ const HashMap = require ( 'hashmap' )
7
10
const _ = require ( 'lodash' )
8
11
const logger = require ( '../../util/logger' )
9
12
const challengeService = require ( '../../services/challengeService' )
10
- const { getV4ESClient } = require ( '../../util/helper' )
13
+ const { getV4ESClient, getM2MToken } = require ( '../../util/helper' )
11
14
const translationService = require ( '../../services/translationService' )
12
- const resourceService = require ( '../../services/resourceService' )
15
+ // const resourceService = require('../../services/resourceService')
16
+
17
+ const memberHandleCache = new HashMap ( )
13
18
14
19
const migrationFunction = {
15
20
run : async ( ) => {
@@ -48,7 +53,7 @@ const migrationFunction = {
48
53
track : 'DATA_SCIENCE' ,
49
54
subTrack : c . subTrack ,
50
55
forumId : c . forumId ,
51
- // TODO :: directProjectId: challengeListing.projectId ,
56
+ directProjectId : config . MM_DIRECT_PROJECT_ID ,
52
57
reviewType : c . reviewType || 'COMMUNITY'
53
58
// screeningScorecardId: challengeListing.screeningScorecardId,
54
59
// reviewScorecardId: challengeListing.reviewScorecardId
@@ -61,19 +66,29 @@ const migrationFunction = {
61
66
name : c . challengeTitle ,
62
67
description : c . detailedRequirements || '' ,
63
68
descriptionFormat : 'HTML' ,
64
- // TODO :: projectId: connectProjectId ,
65
- // created: moment(challengeListing.createdAt).utc().format(),
66
- // createdBy: challengeInfoFromIfx ? challengeInfoFromIfx.created_by : 'v5migration ',
67
- // updated: moment(challengeListing.updatedAt).utc().format() || null,
68
- // updatedBy: challengeInfoFromIfx ? challengeInfoFromIfx.updated_by : 'v5migration ',
69
- // timelineTemplateId: await mapTimelineTemplateId(v5TrackProperties.trackId, v5TrackProperties.typeId), // TODO :: Hardcode marathon match timeline? or leave null?
69
+ projectId : config . MM_CONNECT_PROJECT_ID ,
70
+ created : null , // pull from phase info
71
+ createdBy : 'applications ',
72
+ updated : null , // pull from phase info
73
+ updatedBy : 'applications ',
74
+ timelineTemplateId : null ,
70
75
phases : [ ] , // TODO :: process phases
71
76
terms : [ ] , // leave empty
72
- // startDate: moment().utc().format(),
77
+ startDate : null , // pull from phase info
73
78
numOfSubmissions : _ . toNumber ( c . numberOfSubmissions ) ,
74
79
numOfRegistrants : _ . toNumber ( c . numberOfRegistrants )
75
80
}
76
81
82
+ // "registrationEndDate": "2012-03-29T17:00:00.000Z",
83
+ // "submissionEndDate": "2012-03-29T17:00:00.000Z",
84
+
85
+ const { phases, challengeStartDate, challengeEndDate } = convertPhases ( c . phases )
86
+
87
+ newChallenge . phases = phases
88
+ newChallenge . startDate = challengeStartDate
89
+ newChallenge . created = challengeStartDate
90
+ newChallenge . updated = challengeEndDate
91
+
77
92
const winners = _ . map ( c . winners , w => {
78
93
return {
79
94
handle : w . submitter
@@ -83,21 +98,42 @@ const migrationFunction = {
83
98
} )
84
99
newChallenge . winners = winners
85
100
86
- const savedChallenge = await challengeService . save ( newChallenge )
101
+ // const savedChallenge = await challengeService.save(newChallenge)
102
+ // logger.debug(`Challenge: ${JSON.stringify(newChallenge)}`)
103
+ const savedChallenge = { id : uuid ( ) }
104
+
105
+ let handlesToLookup = [ ]
87
106
for ( const registrant of c . registrants ) {
107
+ // build cache
108
+ if ( ! getMemberIdFromCache ( registrant . handle ) ) {
109
+ handlesToLookup . push ( registrant . handle )
110
+ }
111
+ if ( handlesToLookup . length >= 25 ) {
112
+ await cacheHandles ( handlesToLookup )
113
+ handlesToLookup = [ ]
114
+ }
115
+ }
116
+ await cacheHandles ( handlesToLookup )
117
+
118
+ logger . debug ( `Final Cache: ${ JSON . stringify ( memberHandleCache ) } ` )
119
+
120
+ for ( const registrant of c . registrants ) {
121
+ const memberId = await getMemberIdFromCache ( registrant . handle )
88
122
const newResource = {
89
123
// legacyId: resource.id,
90
124
created : moment ( registrant . registrationDate ) . utc ( ) . format ( ) ,
91
125
createdBy : registrant . handle ,
92
126
updated : moment ( registrant . registrationDate ) . utc ( ) . format ( ) ,
93
127
updatedBy : registrant . handle ,
94
- // memberId: _.toString(resource.member_id), //need to look this up
128
+ memberId : _ . toString ( memberId ) ,
95
129
memberHandle : registrant . handle ,
96
130
challengeId : savedChallenge . id ,
97
131
roleId : config . SUBMITTER_ROLE_ID
98
132
}
99
- await resourceService . save ( newResource )
133
+ // await resourceService.save(newResource)
134
+ logger . debug ( `Resource: ${ JSON . stringify ( newResource ) } ` )
100
135
}
136
+ return
101
137
}
102
138
} else {
103
139
logger . info ( 'Finished' )
@@ -110,6 +146,64 @@ const migrationFunction = {
110
146
}
111
147
}
112
148
149
+ function getMemberIdFromCache ( handle ) {
150
+ if ( memberHandleCache . get ( handle ) ) {
151
+ return memberHandleCache . get ( handle )
152
+ }
153
+ return false
154
+ }
155
+
156
+ function cacheMemberIdForHandle ( handle , memberId ) {
157
+ memberHandleCache . set ( handle , memberId )
158
+ }
159
+
160
+ async function cacheHandles ( handles ) {
161
+ logger . debug ( `Caching ${ handles . length } handles` )
162
+ // curl --location --request GET 'https://api.topcoder-dev.com/v3/members/_search/?fields=userId%2Chandle%2CfirstName%2Cemail%2ClastName&query=handleLower:upbeat%20OR%20handleLower:tonyj'
163
+ const ids = _ . map ( handles , h => `handleLower:${ h } ` )
164
+ const query = ids . join ( '%20OR%20' )
165
+ const token = await getM2MToken ( )
166
+ const url = `https://api.topcoder-dev.com/v3/members/_search?fields=userId%2Chandle&query=${ query } ` // TODO COnfig
167
+ const res = await request . get ( url ) . set ( { Authorization : `Bearer ${ token } ` } )
168
+ const handleArray = _ . get ( res . body , 'result.content' )
169
+ for ( const h of handleArray ) {
170
+ cacheMemberIdForHandle ( h . handle , h . userId )
171
+ }
172
+ }
173
+
174
+ function convertPhases ( v4PhasesArray ) {
175
+ let challengeEndDate = moment ( )
176
+ let challengeStartDate = null
177
+ const phases = _ . map ( v4PhasesArray , phase => {
178
+ const start = moment ( phase . actualStartTime )
179
+ const end = moment ( phase . actualEndTime )
180
+ const v5duration = start . diff ( end , 'seconds' )
181
+ if ( challengeStartDate === null ) {
182
+ challengeStartDate = moment ( phase . actualStartTime ) . utc ( ) . format ( )
183
+ }
184
+ // console.log('phase', phase)
185
+ const newPhase = {
186
+ id : uuid ( ) ,
187
+ name : phase . type ,
188
+ phaseId : _ . get ( _ . find ( config . get ( 'PHASE_NAME_MAPPINGS' ) , { name : phase . type } ) , 'phaseId' ) ,
189
+ duration : v5duration ,
190
+ scheduledStartDate : moment ( phase . scheduledStartTime ) . utc ( ) . format ( ) ,
191
+ scheduledEndDate : moment ( phase . scheduledEndTime ) . utc ( ) . format ( ) ,
192
+ actualStartDate : moment ( phase . actualStartTime ) . utc ( ) . format ( ) ,
193
+ actualEndDate : moment ( phase . actualEndTime ) . utc ( ) . format ( )
194
+ }
195
+
196
+ challengeEndDate = moment ( phase . scheduledEndTime ) . utc ( ) . format ( )
197
+ if ( phase . status === 'Open' ) {
198
+ newPhase . isOpen = true
199
+ } else {
200
+ newPhase . isOpen = false
201
+ }
202
+ return newPhase
203
+ } )
204
+
205
+ return { phases, challengeEndDate, challengeStartDate }
206
+ }
113
207
async function getMatchesFromES ( page = 0 , perPage = 10 ) {
114
208
const esQuery = {
115
209
index : 'mmatches' ,
0 commit comments