Skip to content
This repository was archived by the owner on Jan 23, 2025. It is now read-only.

Commit d0d6b87

Browse files
committed
Fixed download URL challenge
1 parent c071c4e commit d0d6b87

File tree

16 files changed

+361
-69
lines changed

16 files changed

+361
-69
lines changed

build.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@
359359
<include name="phase_templates/**/*.xml" />
360360
<include name="xml_phase_template.xsd" />
361361
<include name="AwsCredentials.properties" />
362+
<include name="AwsS3Credentials.properties" />
362363
<include name="contest_creation_sns_message.txt" />
363364
<include name="contest_update_sns_message.txt" />
364365
</fileset>

components/deliverable_management/src/java/main/com/topcoder/management/deliverable/Upload.java

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2006,2010 TopCoder Inc., All Rights Reserved.
2+
* Copyright (C) 2006 - 2018 TopCoder Inc., All Rights Reserved.
33
*/
44
package com.topcoder.management.deliverable;
55

@@ -19,9 +19,13 @@
1919
* This class is highly mutable. All fields can be changed.
2020
* </p>
2121
*
22+
* <p>
23+
* Version 1.3 - Topcoder - Change Download URL in Direct Application
24+
* - Add url property
25+
* </p>
2226
* @author aubergineanode, singlewood
2327
* @author TCSDESIGNER, TCSDEVELOPER
24-
* @version 1.2
28+
* @version 1.3
2529
*/
2630
public class Upload extends AuditedDeliverableStructure {
2731
/**
@@ -93,6 +97,12 @@ public class Upload extends AuditedDeliverableStructure {
9397
*/
9498
private String description;
9599

100+
/**
101+
* Represent the s3 url
102+
*
103+
*/
104+
private String url;
105+
96106
/**
97107
* Creates a new Upload.
98108
*/
@@ -267,4 +277,22 @@ public boolean isValidToPersist() {
267277
&& (parameter != null)
268278
&& (super.isValidToPersist()));
269279
}
280+
281+
/**
282+
* Get url
283+
*
284+
* @return url
285+
*/
286+
public String getUrl() {
287+
return url;
288+
}
289+
290+
/**
291+
* Set url
292+
*
293+
* @param url url
294+
*/
295+
public void setUrl(String url) {
296+
this.url = url;
297+
}
270298
}

components/deliverable_management/src/java/main/com/topcoder/management/deliverable/persistence/sql/SqlUploadPersistence.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2006-2012 TopCoder Inc., All Rights Reserved.
2+
* Copyright (C) 2006-2018 TopCoder Inc., All Rights Reserved.
33
*/
44
package com.topcoder.management.deliverable.persistence.sql;
55

@@ -193,7 +193,14 @@
193193
* <li>Update {@link #loadUpload(CustomResultSet)} to load the project phase id.</li>
194194
* </ol>
195195
* </p>
196-
*
196+
*
197+
* <p>
198+
* Version 1.6 - Topcoder - Change Download URL in Direct Application
199+
* <ol>
200+
* <li>Update {@link #loadUpload(CustomResultSet)} to load url.</li>
201+
* </ol>
202+
* </p>
203+
*
197204
* <strong>Thread Safety:</strong> This class is immutable and thread-safe in the sense that multiple threads can not
198205
* corrupt its internal data structures. However, the results if used from multiple threads can be unpredictable as the
199206
* database is changed from different threads. This can equally well occur when the component is used on multiple
@@ -202,7 +209,7 @@
202209
*
203210
* @author aubergineanode, saarixx, urtks, George1
204211
* @author TCSDESIGNER, TCSDEVELOPER
205-
* @version 1.5
212+
* @version 1.6
206213
*/
207214
public class SqlUploadPersistence implements UploadPersistence {
208215

@@ -2525,6 +2532,7 @@ private Upload loadUpload(CustomResultSet resultSet) throws UploadPersistenceExc
25252532
upload.setCreationTimestamp(resultSet.getDate("upload_create_date"));
25262533
upload.setModificationUser(resultSet.getString("upload_modify_user"));
25272534
upload.setModificationTimestamp(resultSet.getDate("upload_modify_date"));
2535+
upload.setUrl(resultSet.getString("upload_url"));
25282536

25292537
upload.setProject(resultSet.getLong("project_id"));
25302538
if (resultSet.getObject("project_phase_id") != null) {

conf/components/com/topcoder/util/config/ConfigManager.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ com.cronos.onlinereview.services.uploads.impl.DefaultManagersProvider = onlineRe
1010
com.cronos.onlinereview.services.uploads.impl.DefaultUploadServices = onlineReviewUpload_config.xml
1111
com.cronos.onlinereview.services.uploads.impl.DefaultUploadExternalServices = onlineReviewUpload_config.xml
1212
com.topcoder.servlet.request.LocalFileUpload = onlineReviewUpload_config.xml
13+
com.topcoder.servlet.request.LocalStudioFileUpload = onlineReviewUpload_config.xml
1314

1415
com.topcoder.project.service.ProjectServicesFactory = projectServices_config.xml
1516
com.topcoder.project.service.impl.ProjectServicesImpl = projectServices_config.xml

conf/objectFactory_config.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,7 @@
10101010
upload.resource_id AS resource_id,
10111011
upload.project_phase_id AS project_phase_id,
10121012
upload.parameter AS upload_parameter,
1013+
upload.url AS upload_url,
10131014
upload_type_lu.upload_type_id AS upload_type_id,
10141015
upload_type_lu.create_user AS upload_type_create_user,
10151016
upload_type_lu.create_date AS upload_type_create_date,

conf/onlineReviewUpload_config.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,24 @@
6464
<Value>false</Value>
6565
</Property>
6666
</Config>
67+
<!--
68+
=============== Configuration for File Upload component ===============
69+
-->
70+
<Config name="com.topcoder.servlet.request.LocalStudioFileUpload">
71+
<Property name="single_file_limit">
72+
<Value>-1</Value>
73+
</Property>
74+
<Property name="total_file_limit">
75+
<Value>-1</Value>
76+
</Property>
77+
<Property name="default_dir">
78+
<Value>@studio_file_storage_location@</Value>
79+
</Property>
80+
<Property name="allowed_dirs">
81+
<Value>@studio_file_storage_location@</Value>
82+
</Property>
83+
<Property name="overwrite">
84+
<Value>false</Value>
85+
</Property>
86+
</Config>
6787
</CMConfig>

conf/web/WEB-INF/applicationContext.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,12 @@
174174
</constructor-arg>
175175
</bean>
176176

177+
<bean id="studioFileUpload" class="com.topcoder.servlet.request.LocalFileUpload">
178+
<constructor-arg index="0">
179+
<value>com.topcoder.servlet.request.LocalStudioFileUpload</value>
180+
</constructor-arg>
181+
</bean>
182+
177183
<bean id="userPreferenceHome" class="org.springframework.jndi.JndiObjectFactoryBean">
178184
<property name="jndiName" value="com.topcoder.web.ejb.user.UserPreferenceHome"/>
179185
<property name="cache" value="true"/>
@@ -943,21 +949,27 @@
943949
class="com.topcoder.direct.services.view.action.contest.DownloadAllSoftwareSubmissionsAction"
944950
scope="prototype" parent="baseDirectStrutsAction">
945951
<property name="fileUpload" ref="fileUpload"/>
952+
<property name="studioFileUpload" ref="studioFileUpload"/>
946953
<property name="roundType" value="CHECKPOINT" />
954+
<property name="s3Bucket" value="@aws_s3_bucket@"/>
947955
</bean>
948956

949957
<bean id="downloadAllSoftwareFinalSubmissions"
950958
class="com.topcoder.direct.services.view.action.contest.DownloadAllSoftwareSubmissionsAction"
951959
scope="prototype" parent="baseDirectStrutsAction">
952960
<property name="fileUpload" ref="fileUpload"/>
961+
<property name="studioFileUpload" ref="studioFileUpload"/>
953962
<property name="roundType" value="FINAL" />
963+
<property name="s3Bucket" value="@aws_s3_bucket@"/>
954964
</bean>
955965

956966
<bean id="downloadAllCopilotPostingSubmissions"
957967
class="com.topcoder.direct.services.view.action.contest.DownloadAllSoftwareSubmissionsAction"
958968
scope="prototype" parent="baseDirectStrutsAction">
959969
<property name="fileUpload" ref="fileUpload"/>
970+
<property name="studioFileUpload" ref="studioFileUpload"/>
960971
<property name="roundType" value="FINAL" />
972+
<property name="s3Bucket" value="@aws_s3_bucket@"/>
961973
</bean>
962974

963975
<bean id="saveSoftwareCheckpointReviewAction"
@@ -976,6 +988,8 @@
976988
class="com.topcoder.direct.services.view.action.contest.DownloadSoftwareSubmissionAction"
977989
scope="prototype" parent="baseDirectStrutsAction">
978990
<property name="fileUpload" ref="fileUpload"/>
991+
<property name="studioFileUpload" ref="studioFileUpload"/>
992+
<property name="s3Bucket" value="@aws_s3_bucket@"/>
979993
</bean>
980994

981995
<bean id="downloadFinalFix"

src/java/main/com/topcoder/direct/services/view/action/contest/DownloadAllSoftwareSubmissionsAction.java

Lines changed: 100 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
/*
2-
* Copyright (C) 2012 - 2013 TopCoder Inc., All Rights Reserved.
2+
* Copyright (C) 2012 - 2018 TopCoder Inc., All Rights Reserved.
33
*/
44
package com.topcoder.direct.services.view.action.contest;
55

6+
import com.amazonaws.services.s3.model.GetObjectRequest;
7+
import com.amazonaws.services.s3.model.S3Object;
68
import com.topcoder.direct.services.view.action.contest.launch.ContestAction;
79
import com.topcoder.direct.services.view.dto.contest.ContestRoundType;
810
import com.topcoder.direct.services.view.dto.contest.ContestType;
911
import com.topcoder.direct.services.view.util.DirectUtils;
1012
import com.topcoder.management.deliverable.Submission;
1113
import com.topcoder.management.deliverable.Upload;
14+
import com.topcoder.management.resource.Resource;
1215
import com.topcoder.service.project.SoftwareCompetition;
1316
import com.topcoder.servlet.request.FileUpload;
1417
import com.topcoder.servlet.request.UploadedFile;
@@ -50,9 +53,15 @@
5053
* </li>
5154
* </ul>
5255
* </p>
53-
*
56+
*
57+
* <p>
58+
* Version 1.3 - Topcoder - Change Download URL in Direct Application
59+
* - Add support download from S3
60+
* - Add support for download studio
61+
* </p>
62+
*
5463
* @author TCSASSEMBLER
55-
* @version 1.2
64+
* @version 1.3
5665
*/
5766
public class DownloadAllSoftwareSubmissionsAction extends ContestAction {
5867

@@ -126,6 +135,11 @@ public class DownloadAllSoftwareSubmissionsAction extends ContestAction {
126135
*/
127136
private static final String ALL_SUBMISSIONS = "All_Submissions.zip";
128137

138+
/**
139+
* Resource property for "Handle"
140+
*/
141+
private static final String RESOURCE_PROPERTY_HANDLE = "Handle";
142+
129143
/**
130144
* Represents the upload parameters which are used to retrieve the uploaded files.
131145
*/
@@ -136,6 +150,10 @@ public class DownloadAllSoftwareSubmissionsAction extends ContestAction {
136150
*/
137151
private FileUpload fileUpload;
138152

153+
/**
154+
* Represents the <code>FileUpload</code> service for studio. It will be injected by Spring.
155+
*/
156+
private FileUpload studioFileUpload;
139157

140158
/**
141159
* The round type of the software contest.
@@ -165,6 +183,11 @@ public class DownloadAllSoftwareSubmissionsAction extends ContestAction {
165183
*/
166184
private SoftwareCompetition contest;
167185

186+
/**
187+
* S3 bucket
188+
*/
189+
private String s3Bucket;
190+
168191
/**
169192
* <p>
170193
* Creates a <code>DownloadAllSoftwareSubmissionsAction</code> instance.
@@ -259,34 +282,55 @@ public InputStream getInputStream() throws Exception {
259282
PipedInputStream in = new PipedInputStream();
260283
PipedOutputStream out = new PipedOutputStream(in);
261284
final ZipOutputStream zos = new ZipOutputStream(out);
262-
new Thread(new Runnable(){
285+
new Thread(new Runnable() {
263286
public void run() {
264287
byte[] buffer = new byte[8192];
265288
int read;
266289
InputStream is = null;
267290
try {
268291
for (Submission sub : submissionsToDownload) {
269-
UploadedFile file = fileUpload.getUploadedFile(sub.getUpload().getParameter());
270-
is = file.getInputStream();
271292
String submissionFileZipName;
272-
273-
if(isCopilotPosting) {
274-
// special handling for the copilot posting submission, prefix the submitter's handle
275-
final String copilotHandle = getUserService().getUserHandle(Long.parseLong(sub.getUpload().getCreationUser()));
276-
String ext = FilenameUtils.getExtension(file.getRemoteFileName());
277-
if(ext != null && ext.trim().length() > 0) {
278-
ext = "." + ext;
293+
// url != null is s3
294+
if (sub.getUpload().getUrl() != null) {
295+
S3Object s3Object = DirectUtils.getS3Client().getObject(new GetObjectRequest(s3Bucket,
296+
DirectUtils.getS3FileKey(sub.getUpload().getUrl())));
297+
is = s3Object.getObjectContent();
298+
submissionFileZipName = DirectUtils.getS3FileKey(sub.getUpload().getUrl());
299+
} else {
300+
UploadedFile file;
301+
if (DirectUtils.isStudio(contest)) {
302+
Long userId = null;
303+
String handle = null;
304+
for (Resource r : contest.getResources()) {
305+
if (r.getId() == sub.getUpload().getOwner()) {
306+
userId = r.getUserId();
307+
handle = r.getProperty(RESOURCE_PROPERTY_HANDLE);
308+
}
309+
}
310+
file = studioFileUpload.getUploadedFile(DirectUtils.createStudioLocalFilePath(contest.getId(), userId, handle,
311+
sub.getUpload().getParameter()));
279312
} else {
280-
ext = "";
313+
file = fileUpload.getUploadedFile(sub.getUpload().getParameter());
314+
}
315+
is = file.getInputStream();
316+
317+
if (isCopilotPosting) {
318+
// special handling for the copilot posting submission, prefix the submitter's handle
319+
final String copilotHandle = getUserService().getUserHandle(Long.parseLong(sub.getUpload().getCreationUser()));
320+
String ext = FilenameUtils.getExtension(file.getRemoteFileName());
321+
if (ext != null && ext.trim().length() > 0) {
322+
ext = "." + ext;
323+
} else {
324+
ext = "";
325+
}
326+
submissionFileZipName = copilotHandle + COPILOT_POSTING_SUBMISSION
327+
+ ext;
328+
329+
is = DirectUtils.appendStringToFilesInZip(file, copilotHandle);
330+
} else {
331+
submissionFileZipName = "Submission-" + sub.getId() + "-" + file.getRemoteFileName();
281332
}
282-
submissionFileZipName = copilotHandle + COPILOT_POSTING_SUBMISSION
283-
+ ext;
284-
285-
is = DirectUtils.appendStringToFilesInZip(file, copilotHandle);
286-
} else {
287-
submissionFileZipName = "Submission-" + sub.getId() + "-" + file.getRemoteFileName();
288333
}
289-
290334
// create an entry for each file
291335
ZipEntry outputEntry = new ZipEntry(submissionFileZipName);
292336

@@ -375,4 +419,39 @@ public void setFileUpload(FileUpload fileUpload) {
375419
public void setRoundType(ContestRoundType roundType) {
376420
this.roundType = roundType;
377421
}
422+
423+
/**
424+
* Get S3 bucket
425+
*
426+
* @return s3 bucket name
427+
*/
428+
public String getS3Bucket() {
429+
return s3Bucket;
430+
}
431+
432+
/**
433+
* Set S3 bucket
434+
* @param s3Bucket S3 bucket name
435+
*/
436+
public void setS3Bucket(String s3Bucket) {
437+
this.s3Bucket = s3Bucket;
438+
}
439+
440+
/**
441+
* Get FileUpload instance for studio
442+
*
443+
* @return FileUpload instance
444+
*/
445+
public FileUpload getStudioFileUpload() {
446+
return studioFileUpload;
447+
}
448+
449+
/**
450+
* Set FileUpload for studio
451+
*
452+
* @param studioFileUpload FileUpload instance
453+
*/
454+
public void setStudioFileUpload(FileUpload studioFileUpload) {
455+
this.studioFileUpload = studioFileUpload;
456+
}
378457
}

0 commit comments

Comments
 (0)