diff --git a/citesphere/pom.xml b/citesphere/pom.xml index 34fa7b238..ade3c00c6 100644 --- a/citesphere/pom.xml +++ b/citesphere/pom.xml @@ -24,7 +24,7 @@ 6.2.3 2.2.6.RELEASE 0.13 - 0.4 + 0.6 1.24 $2a$04$oQo44vqcDIFRoYKiAXoNheurzkwX9dcNmowvTX/hsWuBMwijqn44i diff --git a/citesphere/src/main/java/edu/asu/diging/citesphere/api/v1/user/JobInfoController.java b/citesphere/src/main/java/edu/asu/diging/citesphere/api/v1/user/JobInfoController.java index cab48f00c..e705b12cb 100644 --- a/citesphere/src/main/java/edu/asu/diging/citesphere/api/v1/user/JobInfoController.java +++ b/citesphere/src/main/java/edu/asu/diging/citesphere/api/v1/user/JobInfoController.java @@ -19,8 +19,10 @@ import edu.asu.diging.citesphere.core.model.jobs.IUploadJob; import edu.asu.diging.citesphere.core.service.jobs.IUploadJobManager; import edu.asu.diging.citesphere.core.service.jwt.IJobApiTokenContents; +import edu.asu.diging.citesphere.core.service.oauth.InternalTokenManager; import edu.asu.diging.citesphere.core.user.IUserManager; import edu.asu.diging.citesphere.core.zotero.impl.ZoteroTokenManager; +import edu.asu.diging.citesphere.user.IUser; @Controller public class JobInfoController extends BaseJobInfoController { @@ -37,6 +39,8 @@ public class JobInfoController extends BaseJobInfoController { @Autowired private IExportTaskManager exportTaskManager; + @Autowired + private InternalTokenManager internalTokenManager; @RequestMapping(value="/job/info") public ResponseEntity getProfile(@RequestHeader HttpHeaders headers) { @@ -62,6 +66,9 @@ public ResponseEntity getProfile(@RequestHeader HttpHeaders headers) { // FIXME: ugly, needs better solution if (job instanceof IUploadJob) { node.put("groupId", ((IUploadJob)job).getCitationGroup()); + node.put("collectionId", ((IUploadJob)job).getCitationCollection()); + IUser user = userManager.findByUsername(job.getUsername()); + node.put("giles", internalTokenManager.getAccessToken(user).getValue()); } if (job instanceof IExportJob) { IExportTask exportTask = exportTaskManager.get(((IExportJob)job).getTaskId()); diff --git a/citesphere/src/main/java/edu/asu/diging/citesphere/core/model/jobs/IUploadJob.java b/citesphere/src/main/java/edu/asu/diging/citesphere/core/model/jobs/IUploadJob.java index caf90a7c5..44b391197 100644 --- a/citesphere/src/main/java/edu/asu/diging/citesphere/core/model/jobs/IUploadJob.java +++ b/citesphere/src/main/java/edu/asu/diging/citesphere/core/model/jobs/IUploadJob.java @@ -30,6 +30,10 @@ public interface IUploadJob extends IJob { void setCitationGroup(String citationGroup); String getCitationGroup(); + + String getCitationCollection(); + + void setCitationCollection(String citationCollection); ICitationGroup getCitationGroupDetail(); diff --git a/citesphere/src/main/java/edu/asu/diging/citesphere/core/model/jobs/impl/UploadJob.java b/citesphere/src/main/java/edu/asu/diging/citesphere/core/model/jobs/impl/UploadJob.java index c1e776b85..bbddcff16 100644 --- a/citesphere/src/main/java/edu/asu/diging/citesphere/core/model/jobs/impl/UploadJob.java +++ b/citesphere/src/main/java/edu/asu/diging/citesphere/core/model/jobs/impl/UploadJob.java @@ -14,6 +14,7 @@ public class UploadJob extends Job implements IUploadJob { private long fileSize; private String contentType; private String citationGroup; + private String citationCollection; @Transient private ICitationGroup citationGroupDetail; @@ -57,6 +58,14 @@ public void setCitationGroup(String citationGroup) { this.citationGroup = citationGroup; } @Override + public String getCitationCollection() { + return citationCollection; + } + @Override + public void setCitationCollection(String citationCollection) { + this.citationCollection = citationCollection; + } + @Override public ICitationGroup getCitationGroupDetail() { return citationGroupDetail; } diff --git a/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/ICitationCollectionManager.java b/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/ICitationCollectionManager.java index b5fc7f03c..501b61947 100644 --- a/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/ICitationCollectionManager.java +++ b/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/ICitationCollectionManager.java @@ -2,7 +2,10 @@ import java.util.List; +import org.springframework.social.zotero.exception.ZoteroConnectionException; + import edu.asu.diging.citesphere.core.exceptions.GroupDoesNotExistException; +import edu.asu.diging.citesphere.core.exceptions.ZoteroItemCreationFailedException; import edu.asu.diging.citesphere.model.bib.ICitationCollection; import edu.asu.diging.citesphere.model.bib.impl.CitationCollectionResult; import edu.asu.diging.citesphere.user.IUser; @@ -20,5 +23,8 @@ List getAllCollections(IUser user, String groupId, String p throws GroupDoesNotExistException; void deleteLocalGroupCollections(String groupId); + + ICitationCollection createCollection(IUser user, String groupId, String collectionName, String parentCollection) + throws GroupDoesNotExistException, ZoteroItemCreationFailedException, ZoteroConnectionException; } \ No newline at end of file diff --git a/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/impl/CitationCollectionManager.java b/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/impl/CitationCollectionManager.java index 45ce1bd39..3bd00d163 100644 --- a/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/impl/CitationCollectionManager.java +++ b/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/impl/CitationCollectionManager.java @@ -7,9 +7,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.PropertySource; +import org.springframework.social.zotero.exception.ZoteroConnectionException; import org.springframework.stereotype.Service; import edu.asu.diging.citesphere.core.exceptions.GroupDoesNotExistException; +import edu.asu.diging.citesphere.core.exceptions.ZoteroItemCreationFailedException; import edu.asu.diging.citesphere.core.service.ICitationCollectionManager; import edu.asu.diging.citesphere.core.zotero.IZoteroManager; import edu.asu.diging.citesphere.data.bib.CitationCollectionRepository; @@ -17,6 +19,7 @@ import edu.asu.diging.citesphere.data.bib.ICollectionMongoDao; import edu.asu.diging.citesphere.model.bib.ICitationCollection; import edu.asu.diging.citesphere.model.bib.ICitationGroup; +import edu.asu.diging.citesphere.model.bib.impl.CitationCollection; import edu.asu.diging.citesphere.model.bib.impl.CitationCollectionResult; import edu.asu.diging.citesphere.user.IUser; @@ -107,4 +110,22 @@ public ICitationCollection getCollection(IUser user, String groupId, String coll public void deleteLocalGroupCollections(String groupId) { collectionRepository.deleteByGroupId(groupId); } + + @Override + public ICitationCollection createCollection(IUser user, String groupId, String collectionName, String parentCollection) + throws GroupDoesNotExistException, ZoteroItemCreationFailedException, ZoteroConnectionException { + Optional groupOptional = groupRepository.findFirstByGroupId(new Long(groupId)); + if (!groupOptional.isPresent()) { + throw new GroupDoesNotExistException("Group with id " + groupId + " does not exist."); + } + if(parentCollection != null) { + Optional collectionOptional = collectionRepository.findByKey(parentCollection); + if (!collectionOptional.isPresent()) { + throw new GroupDoesNotExistException("Collection with id " + parentCollection + " does not exist."); + } + } + + ICitationCollection newCollection = zoteroManager.createCitationCollection(user, groupId, collectionName, parentCollection); + return collectionRepository.save((CitationCollection)newCollection); + } } diff --git a/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/jobs/IUploadCollectionJobManager.java b/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/jobs/IUploadCollectionJobManager.java new file mode 100644 index 000000000..a66667af6 --- /dev/null +++ b/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/jobs/IUploadCollectionJobManager.java @@ -0,0 +1,16 @@ +package edu.asu.diging.citesphere.core.service.jobs; + +import java.util.List; + +import org.springframework.web.multipart.MultipartFile; + +import edu.asu.diging.citesphere.core.exceptions.GroupDoesNotExistException; +import edu.asu.diging.citesphere.core.model.jobs.IUploadJob; +import edu.asu.diging.citesphere.user.IUser; + +public interface IUploadCollectionJobManager { + + List createUploadJob(IUser user, MultipartFile[] files, List fileBytes, String groupId, String collectionId) throws GroupDoesNotExistException; + + +} diff --git a/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/jobs/impl/UploadCollectionJobManager.java b/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/jobs/impl/UploadCollectionJobManager.java new file mode 100644 index 000000000..3842f1d25 --- /dev/null +++ b/citesphere/src/main/java/edu/asu/diging/citesphere/core/service/jobs/impl/UploadCollectionJobManager.java @@ -0,0 +1,140 @@ +package edu.asu.diging.citesphere.core.service.jobs.impl; + +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.List; + +import javax.transaction.Transactional; + +import org.apache.tika.Tika; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.PropertySource; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import edu.asu.diging.citesphere.core.exceptions.FileStorageException; +import edu.asu.diging.citesphere.core.exceptions.GroupDoesNotExistException; +import edu.asu.diging.citesphere.core.exceptions.MessageCreationException; +import edu.asu.diging.citesphere.core.kafka.IKafkaRequestProducer; +import edu.asu.diging.citesphere.core.model.jobs.IUploadJob; +import edu.asu.diging.citesphere.core.model.jobs.JobStatus; +import edu.asu.diging.citesphere.core.model.jobs.impl.JobPhase; +import edu.asu.diging.citesphere.core.model.jobs.impl.UploadJob; +import edu.asu.diging.citesphere.core.repository.jobs.UploadJobRepository; +import edu.asu.diging.citesphere.core.service.IGroupManager; +import edu.asu.diging.citesphere.core.service.jobs.IUploadCollectionJobManager; +import edu.asu.diging.citesphere.core.service.jwt.IJwtTokenService; +import edu.asu.diging.citesphere.core.service.upload.IFileStorageManager; +import edu.asu.diging.citesphere.messages.KafkaTopics; +import edu.asu.diging.citesphere.messages.model.KafkaJobMessage; +import edu.asu.diging.citesphere.model.bib.ICitationGroup; +import edu.asu.diging.citesphere.user.IUser; + +@Service +@Transactional +@PropertySource("classpath:/config.properties") +public class UploadCollectionJobManager implements IUploadCollectionJobManager { + + private final Logger logger = LoggerFactory.getLogger(getClass()); + + @Value("${_job_page_size}") + private int jobPageSize; + + @Autowired + private UploadJobRepository uploadJobRepository; + + @Autowired + private IFileStorageManager fileManager; + + @Autowired + private IKafkaRequestProducer kafkaProducer; + + @Autowired + private IJwtTokenService tokenService; + + @Autowired + private IGroupManager groupManager; + + @Override + public List createUploadJob(IUser user, MultipartFile[] files, List fileBytes, + String groupId, String collectionId) throws GroupDoesNotExistException { + ICitationGroup group = groupManager.getGroup(user, groupId); + if (group == null) { + throw new GroupDoesNotExistException(); + } + + List jobs = new ArrayList<>(); + int i = 0; + for (MultipartFile f : files) { + String filename = f.getOriginalFilename(); + + byte[] bytes = null; + UploadJob job = new UploadJob(); + jobs.add(job); + job.setFilename(filename); + job.setCreatedOn(OffsetDateTime.now()); + job.setUsername(user.getUsername()); + job.setCitationGroup(groupId); + job.setCitationCollection(collectionId); + job.setPhases(new ArrayList<>()); + try { + if (fileBytes != null && fileBytes.size() == files.length) { + bytes = fileBytes.get(i); + } else { + job.setStatus(JobStatus.FAILURE); + job.getPhases().add(new JobPhase(JobStatus.FAILURE, + "There is a mismatch between file metadata and file contents.")); + continue; + } + + if (bytes == null) { + job.setStatus(JobStatus.FAILURE); + job.getPhases().add(new JobPhase(JobStatus.FAILURE, "There is not file content.")); + continue; + } + job = uploadJobRepository.save(job); + fileManager.saveFile(user.getUsername(), job.getId(), filename, bytes); + + job.setStatus(JobStatus.PREPARED); + } catch (FileStorageException e) { + logger.error("Could not store file.", e); + job.setStatus(JobStatus.FAILURE); + job.getPhases().add(new JobPhase(JobStatus.FAILURE, e.getMessage())); + continue; + } finally { + i++; + uploadJobRepository.save(job); + } + + String contentType = null; + + if (bytes != null) { + Tika tika = new Tika(); + contentType = tika.detect(bytes); + } + + if (contentType == null) { + contentType = f.getContentType(); + } + + job.setContentType(contentType); + job.setFileSize(f.getSize()); + uploadJobRepository.save(job); + String token = tokenService.generateJobApiToken(job); + try { + kafkaProducer.sendRequest(new KafkaJobMessage(token), KafkaTopics.COLLECTION_IMPORT_TOPIC); + } catch (MessageCreationException e) { + logger.error("Could not send Kafka message.", e); + job.setStatus(JobStatus.FAILURE); + job.getPhases().add(new JobPhase(JobStatus.FAILURE, e.getMessage())); + uploadJobRepository.save(job); + } + } + + return jobs; + } + +} diff --git a/citesphere/src/main/java/edu/asu/diging/citesphere/core/zotero/IZoteroConnector.java b/citesphere/src/main/java/edu/asu/diging/citesphere/core/zotero/IZoteroConnector.java index c552896cb..e5c26ec93 100644 --- a/citesphere/src/main/java/edu/asu/diging/citesphere/core/zotero/IZoteroConnector.java +++ b/citesphere/src/main/java/edu/asu/diging/citesphere/core/zotero/IZoteroConnector.java @@ -85,4 +85,6 @@ void clearCollectionItemsCache(IUser user, String groupId, String collectionId, Map> deleteMultipleItems(IUser user, String groupId, List citationKeys, Long citationVersion) throws ZoteroConnectionException, ZoteroHttpStatusException; + Collection createCitationCollection(IUser user, String groupId, String collectionName, + String parentCollection) throws ZoteroItemCreationFailedException, ZoteroConnectionException; } \ No newline at end of file diff --git a/citesphere/src/main/java/edu/asu/diging/citesphere/core/zotero/IZoteroManager.java b/citesphere/src/main/java/edu/asu/diging/citesphere/core/zotero/IZoteroManager.java index 806ba0a67..3f7f42bbe 100644 --- a/citesphere/src/main/java/edu/asu/diging/citesphere/core/zotero/IZoteroManager.java +++ b/citesphere/src/main/java/edu/asu/diging/citesphere/core/zotero/IZoteroManager.java @@ -81,4 +81,7 @@ CitationResults getCollectionItems(IUser user, String groupId, String collection long getLatestGroupVersion(IUser user, String groupId); Map> deleteMultipleItems(IUser user, String groupId, List citationKeys, Long citationVersion) throws ZoteroConnectionException, ZoteroHttpStatusException; + + ICitationCollection createCitationCollection(IUser user, String groupId, String collectionName, String parentCollection) throws ZoteroItemCreationFailedException, ZoteroConnectionException; + } \ No newline at end of file diff --git a/citesphere/src/main/java/edu/asu/diging/citesphere/core/zotero/impl/ZoteroConnector.java b/citesphere/src/main/java/edu/asu/diging/citesphere/core/zotero/impl/ZoteroConnector.java index 9a865db9d..25180501c 100644 --- a/citesphere/src/main/java/edu/asu/diging/citesphere/core/zotero/impl/ZoteroConnector.java +++ b/citesphere/src/main/java/edu/asu/diging/citesphere/core/zotero/impl/ZoteroConnector.java @@ -369,4 +369,29 @@ public Map> deleteMultipleItems(IUser user, S Zotero zotero = getApi(user); return zotero.getGroupsOperations().deleteMultipleItems(groupId, citationKeys, citationVersion); } + + @Override + public Collection createCitationCollection(IUser user, String groupId, String collectionName, + String parentCollection) throws ZoteroItemCreationFailedException, ZoteroConnectionException { + Zotero zotero = getApi(user); + + ItemCreationResponse response = zotero.getGroupCollectionsOperations().createCollection(groupId, collectionName, parentCollection); + + // let's give Zotero a minute to process + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + logger.error("Could not sleep.", e); + // well if something goes wrong here, let's just ignore it + } + + Map success = response.getSuccess(); + if (success.isEmpty()) { + logger.error("Could not create collection: " + response.getFailed().get("0")); + throw new ZoteroItemCreationFailedException(response); + } + + // since we only submitted one item, there should only be one in the map + return getCitationCollection(user, groupId, success.values().iterator().next()); + } } diff --git a/citesphere/src/main/java/edu/asu/diging/citesphere/core/zotero/impl/ZoteroManager.java b/citesphere/src/main/java/edu/asu/diging/citesphere/core/zotero/impl/ZoteroManager.java index cf2236382..8b311f053 100644 --- a/citesphere/src/main/java/edu/asu/diging/citesphere/core/zotero/impl/ZoteroManager.java +++ b/citesphere/src/main/java/edu/asu/diging/citesphere/core/zotero/impl/ZoteroManager.java @@ -538,4 +538,11 @@ public Map> deleteMultipleItems(IUser user, S throws ZoteroConnectionException, ZoteroHttpStatusException { return zoteroConnector.deleteMultipleItems(user, groupId, citationKeys, citationVersion); } + + @Override + public ICitationCollection createCitationCollection(IUser user, String groupId, String collectionName, + String parentCollection) throws ZoteroItemCreationFailedException, ZoteroConnectionException { + Collection collection = zoteroConnector.createCitationCollection(user, groupId, collectionName, parentCollection); + return collectionFactory.createCitationCollection(collection); + } } diff --git a/citesphere/src/main/java/edu/asu/diging/citesphere/web/user/jobs/ImportCollectionsController.java b/citesphere/src/main/java/edu/asu/diging/citesphere/web/user/jobs/ImportCollectionsController.java new file mode 100644 index 000000000..feb6c837d --- /dev/null +++ b/citesphere/src/main/java/edu/asu/diging/citesphere/web/user/jobs/ImportCollectionsController.java @@ -0,0 +1,149 @@ +package edu.asu.diging.citesphere.web.user.jobs; + +import java.io.IOException; +import java.security.Principal; +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.social.zotero.exception.ZoteroConnectionException; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.multipart.MultipartFile; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import edu.asu.diging.citesphere.api.v1.model.impl.Collections; +import edu.asu.diging.citesphere.api.v1.user.JsonUtil; +import edu.asu.diging.citesphere.core.exceptions.GroupDoesNotExistException; +import edu.asu.diging.citesphere.core.exceptions.ZoteroItemCreationFailedException; +import edu.asu.diging.citesphere.core.model.jobs.IUploadJob; +import edu.asu.diging.citesphere.core.service.ICitationCollectionManager; +import edu.asu.diging.citesphere.core.service.ICitationManager; +import edu.asu.diging.citesphere.core.service.IGroupManager; +import edu.asu.diging.citesphere.core.service.jobs.IUploadCollectionJobManager; +import edu.asu.diging.citesphere.model.bib.ICitationCollection; +import edu.asu.diging.citesphere.model.bib.ICitationGroup; +import edu.asu.diging.citesphere.user.IUser; +import edu.asu.diging.citesphere.user.impl.User; + +@Controller +public class ImportCollectionsController { + private final Logger logger = LoggerFactory.getLogger(getClass()); + + @Autowired + private IUploadCollectionJobManager jobManager; + + @Autowired + private ICitationManager citationManager; + + @Autowired + private ICitationCollectionManager collectionManager; + + @Autowired + private IGroupManager groupManager; + + @Autowired + private JsonUtil jsonUtil; + + @RequestMapping(value = "/auth/import/collection", method = RequestMethod.GET) + public String show(Model model, Authentication authentication) { + model.addAttribute("groups", citationManager.getGroups((IUser)authentication.getPrincipal())); + return "auth/import/collection"; + } + + @RequestMapping(value = "/auth/import/collection/getgroupcollections", method = RequestMethod.GET) + public ResponseEntity getCollections( @RequestParam("groupId") String groupId, Authentication authentication) { + IUser user = (IUser)authentication.getPrincipal(); + + ICitationGroup group = groupManager.getGroup(user, groupId); + if (group == null) { + return new ResponseEntity(HttpStatus.NOT_FOUND); + } + + Collections collectionResponse = new Collections(); + collectionResponse.setGroup(jsonUtil.createGroup(group)); + try { + collectionResponse.setCollections( + collectionManager.getAllCollections(user, groupId, null, "title", 20)); + } catch (GroupDoesNotExistException e) { + logger.error("Could not create job because group does not exist.", e); + return new ResponseEntity(HttpStatus.BAD_REQUEST); + } + return new ResponseEntity(collectionResponse, HttpStatus.OK); + } + + @RequestMapping(value = "/auth/import/collection", method = RequestMethod.POST) + public ResponseEntity uploadCollection(Principal principal, @RequestParam("group") String group, + @RequestParam("collectionId") String collectionId, @RequestParam("files") MultipartFile[] files) { + + User user = null; + if (principal instanceof UsernamePasswordAuthenticationToken) { + user = (User) ((UsernamePasswordAuthenticationToken) principal) + .getPrincipal(); + } + + if (user == null) { + return new ResponseEntity(HttpStatus.UNAUTHORIZED); + } + + List fileBytes = new ArrayList<>(); + for (MultipartFile file : files) { + try { + fileBytes.add(file.getBytes()); + } catch (IOException e) { + logger.error("Could not get file content from request.", e); + return new ResponseEntity("Could not get file content from request.", HttpStatus.BAD_REQUEST); + } + } + + if (collectionId.equals("new")) { + try { + ICitationCollection collection = collectionManager.createCollection(user, group, files[0].getName(), null); + collectionId = collection.getKey(); + } catch (GroupDoesNotExistException e) { + logger.error("Could not create job because group does not exist.", e); + return new ResponseEntity("Could not create job because group does not exist", HttpStatus.BAD_REQUEST); + } catch (ZoteroItemCreationFailedException e) { + logger.error("Zotero new collection creation failed.", e); + return new ResponseEntity("Zotero new collection creation failed.", HttpStatus.INTERNAL_SERVER_ERROR); + } catch (ZoteroConnectionException e) { + logger.error("Zotero connection failed.", e); + return new ResponseEntity("Zotero connection failed.", HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + List jobs; + try { + jobs = jobManager.createUploadJob(user, files, fileBytes, group, collectionId); + } catch (GroupDoesNotExistException e) { + logger.error("Could not create job because group does not exist.", e); + return new ResponseEntity(HttpStatus.BAD_REQUEST); + } + + ObjectMapper mapper = new ObjectMapper(); + ObjectNode root = mapper.createObjectNode(); + ArrayNode filesNode = root.putArray("jobs"); + for (IUploadJob job : jobs) { + ObjectNode jobNode = mapper.createObjectNode(); + jobNode.put("jobId", job.getId()); + jobNode.put("filename", job.getFilename()); + jobNode.put("status", job.getStatus().name()); + filesNode.add(jobNode); + } + return new ResponseEntity(root.toString(), HttpStatus.OK); + } + + +} diff --git a/citesphere/src/main/webapp/WEB-INF/tiles-defs.xml b/citesphere/src/main/webapp/WEB-INF/tiles-defs.xml index 82ad578d2..c2ad5b473 100644 --- a/citesphere/src/main/webapp/WEB-INF/tiles-defs.xml +++ b/citesphere/src/main/webapp/WEB-INF/tiles-defs.xml @@ -88,6 +88,9 @@ + + + diff --git a/citesphere/src/main/webapp/WEB-INF/views/auth/import/collection.html b/citesphere/src/main/webapp/WEB-INF/views/auth/import/collection.html new file mode 100644 index 000000000..6772618d4 --- /dev/null +++ b/citesphere/src/main/webapp/WEB-INF/views/auth/import/collection.html @@ -0,0 +1,199 @@ + + + + + + + + +
+
+
+
+ Upload Collection +
+
+ + + + + +

Select files from your computer

+
+
+ +
+ +
+ +
+ +
+
+ +
+ +
+
+ + +

Or drag and drop files below

+
Just drag and + drop files here
+ + +
+

Processed files

+
+
+
+
+
+ +
+ + \ No newline at end of file diff --git a/citesphere/src/main/webapp/WEB-INF/views/layouts/main.html b/citesphere/src/main/webapp/WEB-INF/views/layouts/main.html index db0d1104e..bda2bff20 100644 --- a/citesphere/src/main/webapp/WEB-INF/views/layouts/main.html +++ b/citesphere/src/main/webapp/WEB-INF/views/layouts/main.html @@ -90,6 +90,7 @@