Search in sources :

Example 1 with BadPkgScreenshotException

use of org.haiku.haikudepotserver.pkg.model.BadPkgScreenshotException in project haikudepotserver by haiku.

the class PkgScreenshotController method handleAdd.

/**
 * <p>This handler will take-up an HTTP POST that provides a new screenshot for the package.</p>
 */
@RequestMapping(value = "/{" + KEY_PKGNAME + "}/add", method = RequestMethod.POST)
public void handleAdd(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = KEY_FORMAT) String format, @PathVariable(value = KEY_PKGNAME) String pkgName) throws IOException {
    if (Strings.isNullOrEmpty(pkgName) || !Pkg.PATTERN_NAME.matcher(pkgName).matches()) {
        throw new MissingPkgName();
    }
    if (Strings.isNullOrEmpty(format) || !"png".equals(format)) {
        throw new MissingOrBadFormat();
    }
    ObjectContext context = serverRuntime.newContext();
    Pkg pkg = Pkg.tryGetByName(context, pkgName).orElseThrow(PkgNotFound::new);
    // check the authorization
    Optional<User> user = tryObtainAuthenticatedUser(context);
    if (!permissionEvaluator.hasPermission(SecurityContextHolder.getContext().getAuthentication(), pkg, Permission.PKG_EDITSCREENSHOT)) {
        LOGGER.warn("attempt to add a pkg screenshot, but there is no user present or that user is not able to edit the pkg");
        throw new PkgAuthorizationFailure();
    }
    String screenshotCode;
    try {
        screenshotCode = pkgScreenshotService.storePkgScreenshotImage(request.getInputStream(), context, pkg.getPkgSupplement(), null).getCode();
    } catch (SizeLimitReachedException sizeLimit) {
        LOGGER.warn("attempt to load in a screenshot larger than the size limit");
        throw new MissingOrBadFormat();
    } catch (BadPkgScreenshotException badIcon) {
        throw new MissingOrBadFormat();
    }
    context.commitChanges();
    // trigger optimization of the screenshot image.
    jobService.submit(new PkgScreenshotOptimizationJobSpecification(screenshotCode), JobSnapshot.COALESCE_STATUSES_QUEUED_STARTED);
    response.setHeader(HEADER_SCREENSHOTCODE, screenshotCode);
    response.setStatus(HttpServletResponse.SC_OK);
}
Also used : User(org.haiku.haikudepotserver.dataobjects.User) BadPkgScreenshotException(org.haiku.haikudepotserver.pkg.model.BadPkgScreenshotException) PkgScreenshotOptimizationJobSpecification(org.haiku.haikudepotserver.pkg.model.PkgScreenshotOptimizationJobSpecification) ObjectContext(org.apache.cayenne.ObjectContext) SizeLimitReachedException(org.haiku.haikudepotserver.pkg.model.SizeLimitReachedException) Pkg(org.haiku.haikudepotserver.dataobjects.Pkg)

Example 2 with BadPkgScreenshotException

use of org.haiku.haikudepotserver.pkg.model.BadPkgScreenshotException in project haikudepotserver by haiku.

the class PkgScreenshotOptimizationJobRunner method run.

@Override
public void run(JobService jobService, PkgScreenshotOptimizationJobSpecification specification) throws JobRunnerException {
    Preconditions.checkArgument(null != jobService);
    Preconditions.checkArgument(null != specification);
    long startMs = System.currentTimeMillis();
    LOGGER.info("will optimize {} screenshot images", specification.getPkgScreenshotCodes().size());
    for (String pkgScreenshotCode : specification.getPkgScreenshotCodes()) {
        ObjectContext context = serverRuntime.newContext();
        Optional<PkgScreenshot> pkgScreenshotOptional = PkgScreenshot.tryGetByCode(context, pkgScreenshotCode);
        if (pkgScreenshotOptional.isPresent()) {
            try {
                if (screenshotService.optimizeScreenshot(context, pkgScreenshotOptional.get())) {
                    context.commitChanges();
                }
            } catch (IOException ioe) {
                throw new UncheckedIOException(ioe);
            } catch (BadPkgScreenshotException bpse) {
                throw new JobRunnerException("unable to process a screenshot image", bpse);
            }
        }
        LOGGER.info("did optimize {} screenshot images in {}ms", specification.getPkgScreenshotCodes().size(), System.currentTimeMillis() - startMs);
    }
}
Also used : BadPkgScreenshotException(org.haiku.haikudepotserver.pkg.model.BadPkgScreenshotException) JobRunnerException(org.haiku.haikudepotserver.job.model.JobRunnerException) PkgScreenshot(org.haiku.haikudepotserver.dataobjects.PkgScreenshot) UncheckedIOException(java.io.UncheckedIOException) ObjectContext(org.apache.cayenne.ObjectContext) IOException(java.io.IOException) UncheckedIOException(java.io.UncheckedIOException)

Example 3 with BadPkgScreenshotException

use of org.haiku.haikudepotserver.pkg.model.BadPkgScreenshotException in project haikudepotserver by haiku.

the class PkgScreenshotServiceImpl method storePkgScreenshotImage.

/**
 * <p>Note that if the screenshot is already stored then this method will simply return that screenshot.</p>
 *
 * @param ordering can be NULL; in which case the screenshot will come at the end.
 */
@Override
public PkgScreenshot storePkgScreenshotImage(InputStream input, ObjectContext context, PkgSupplement pkgSupplement, Integer ordering) throws IOException, BadPkgScreenshotException {
    Preconditions.checkArgument(null != input, "the input must be provided");
    Preconditions.checkArgument(null != context, "the context must be provided");
    Preconditions.checkArgument(null != pkgSupplement, "the pkg supplement must be provided");
    byte[] pngData = ByteStreams.toByteArray(new BoundedInputStream(input, SCREENSHOT_SIZE_LIMIT));
    ImageHelper.Size size = imageHelper.derivePngSize(pngData);
    String hashSha256 = HASH_FUNCTION.hashBytes(pngData).toString();
    if (null == size) {
        LOGGER.warn("attempt to store a screenshot image that is not a png");
        throw new BadPkgScreenshotException();
    }
    if (size.height > SCREENSHOT_SIDE_LIMIT || size.width > SCREENSHOT_SIDE_LIMIT) {
        LOGGER.warn("attempt to store a screenshot image that is too large; " + size.toString());
        throw new BadPkgScreenshotException();
    }
    for (PkgScreenshot pkgScreenshot : pkgSupplement.getPkgScreenshots()) {
        if (pkgScreenshot.getHashSha256().equals(hashSha256)) {
            LOGGER.warn("attempt to store a screenshot image that is already stored for this package");
            return pkgScreenshot;
        }
    }
    MediaType png = MediaType.tryGetByCode(context, com.google.common.net.MediaType.PNG.toString()).get();
    // now we need to know the largest ordering so we can add this one at the end of the orderings
    // such that it is the next one in the list.
    int actualOrdering = null == ordering ? pkgSupplement.getHighestPkgScreenshotOrdering().orElse(0) + 1 : ordering;
    PkgScreenshot screenshot = context.newObject(PkgScreenshot.class);
    screenshot.setCode(UUID.randomUUID().toString());
    screenshot.setOrdering(actualOrdering);
    screenshot.setHeight(size.height);
    screenshot.setWidth(size.width);
    screenshot.setLength(pngData.length);
    screenshot.setHashSha256(hashSha256);
    pkgSupplement.addToManyTarget(PkgSupplement.PKG_SCREENSHOTS.getName(), screenshot, true);
    PkgScreenshotImage screenshotImage = context.newObject(PkgScreenshotImage.class);
    screenshotImage.setMediaType(png);
    screenshotImage.setData(pngData);
    screenshot.addToManyTarget(PkgScreenshot.PKG_SCREENSHOT_IMAGES.getName(), screenshotImage, true);
    pkgSupplement.setModifyTimestamp();
    LOGGER.info("a screenshot #{} has been added to package [{}] ({})", actualOrdering, pkgSupplement.getBasePkgName(), screenshot.getCode());
    return screenshot;
}
Also used : BadPkgScreenshotException(org.haiku.haikudepotserver.pkg.model.BadPkgScreenshotException) PkgScreenshotImage(org.haiku.haikudepotserver.dataobjects.PkgScreenshotImage) BoundedInputStream(org.apache.commons.compress.utils.BoundedInputStream) org.haiku.haikudepotserver.dataobjects.auto._PkgScreenshot(org.haiku.haikudepotserver.dataobjects.auto._PkgScreenshot) PkgScreenshot(org.haiku.haikudepotserver.dataobjects.PkgScreenshot) MediaType(org.haiku.haikudepotserver.dataobjects.MediaType) ImageHelper(org.haiku.haikudepotserver.graphics.ImageHelper)

Example 4 with BadPkgScreenshotException

use of org.haiku.haikudepotserver.pkg.model.BadPkgScreenshotException in project haikudepotserver by haiku.

the class PkgScreenshotImportArchiveJobRunner method importScreenshotsFromArchiveAndReport.

/**
 * <p>If this screenshot coming in from the archive does not exist persisted then load it in.</p>
 */
private void importScreenshotsFromArchiveAndReport(CSVWriter writer, ScreenshotImportMetadatas data, ArchiveInputStream archiveInputStream, ArchiveEntry archiveEntry, String pkgName, int order) {
    String[] row = { // path
    archiveEntry.getName(), // pkg
    pkgName, // action
    "", // message
    "", // code
    "" };
    if (data.isNotFound()) {
        row[CSV_COLUMN_ACTION] = Action.NOTFOUND.name();
    } else {
        FromArchiveScreenshotMetadata fromArchiveScreenshotMetadata = data.getFromArchiveScreenshots().stream().filter((as) -> as.getLength() == archiveEntry.getSize()).filter((as) -> as.getOrder() == order).findAny().orElseThrow(() -> new IllegalStateException("unable to find the from-archive screenshot metadata"));
        Optional<ExistingScreenshotMetadata> existingScreenshotMetadata = data.getExistingScreenshots().stream().filter((es) -> archiveEntry.getSize() == es.getLength()).filter((es) -> fromArchiveScreenshotMetadata.getDataHash().equals(es.getDataHash())).findAny();
        if (existingScreenshotMetadata.isPresent()) {
            row[CSV_COLUMN_ACTION] = Action.PRESENT.name();
            row[CSV_COLUMN_CODE] = existingScreenshotMetadata.get().getCode();
        } else {
            ObjectContext context = serverRuntime.newContext();
            try {
                PkgScreenshot screenshot = pkgScreenshotService.storePkgScreenshotImage(archiveInputStream, context, Pkg.getByName(context, pkgName).getPkgSupplement(), fromArchiveScreenshotMetadata.getDerivedOrder());
                row[CSV_COLUMN_CODE] = screenshot.getCode();
                row[CSV_COLUMN_ACTION] = Action.ADDED.name();
            } catch (IOException ioe) {
                throw new UncheckedIOException(ioe);
            } catch (BadPkgScreenshotException e) {
                row[CSV_COLUMN_ACTION] = Action.INVALID.name();
                row[CSV_COLUMN_MESSAGE] = e.getMessage();
            }
            context.commitChanges();
        }
    }
    writer.writeNext(row);
}
Also used : ObjectContext(org.apache.cayenne.ObjectContext) java.util(java.util) GZIPInputStream(java.util.zip.GZIPInputStream) ArchiveEntry(org.apache.commons.compress.archivers.ArchiveEntry) TarArchiveInputStream(org.apache.commons.compress.archivers.tar.TarArchiveInputStream) PkgScreenshotImage(org.haiku.haikudepotserver.dataobjects.PkgScreenshotImage) PkgScreenshotService(org.haiku.haikudepotserver.pkg.model.PkgScreenshotService) LoggerFactory(org.slf4j.LoggerFactory) Hashing(com.google.common.hash.Hashing) HashingInputStream(com.google.common.hash.HashingInputStream) BadPkgScreenshotException(org.haiku.haikudepotserver.pkg.model.BadPkgScreenshotException) Matcher(java.util.regex.Matcher) JobDataWithByteSource(org.haiku.haikudepotserver.job.model.JobDataWithByteSource) JobDataWithByteSink(org.haiku.haikudepotserver.job.model.JobDataWithByteSink) ArchiveInputStream(org.apache.commons.compress.archivers.ArchiveInputStream) JobService(org.haiku.haikudepotserver.job.model.JobService) ByteSource(com.google.common.io.ByteSource) MediaType(com.google.common.net.MediaType) Pkg(org.haiku.haikudepotserver.dataobjects.Pkg) Logger(org.slf4j.Logger) HashCode(com.google.common.hash.HashCode) AbstractJobRunner(org.haiku.haikudepotserver.job.AbstractJobRunner) CSVWriter(com.opencsv.CSVWriter) PkgScreenshotImportArchiveJobSpecification(org.haiku.haikudepotserver.pkg.model.PkgScreenshotImportArchiveJobSpecification) PkgScreenshot(org.haiku.haikudepotserver.dataobjects.PkgScreenshot) Consumer(java.util.function.Consumer) Component(org.springframework.stereotype.Component) java.io(java.io) ByteStreams(com.google.common.io.ByteStreams) Preconditions(com.google.common.base.Preconditions) Pattern(java.util.regex.Pattern) HashFunction(com.google.common.hash.HashFunction) JobRunnerException(org.haiku.haikudepotserver.job.model.JobRunnerException) ServerRuntime(org.apache.cayenne.configuration.server.ServerRuntime) BadPkgScreenshotException(org.haiku.haikudepotserver.pkg.model.BadPkgScreenshotException) PkgScreenshot(org.haiku.haikudepotserver.dataobjects.PkgScreenshot) ObjectContext(org.apache.cayenne.ObjectContext)

Aggregations

BadPkgScreenshotException (org.haiku.haikudepotserver.pkg.model.BadPkgScreenshotException)4 ObjectContext (org.apache.cayenne.ObjectContext)3 PkgScreenshot (org.haiku.haikudepotserver.dataobjects.PkgScreenshot)3 Pkg (org.haiku.haikudepotserver.dataobjects.Pkg)2 PkgScreenshotImage (org.haiku.haikudepotserver.dataobjects.PkgScreenshotImage)2 JobRunnerException (org.haiku.haikudepotserver.job.model.JobRunnerException)2 Preconditions (com.google.common.base.Preconditions)1 HashCode (com.google.common.hash.HashCode)1 HashFunction (com.google.common.hash.HashFunction)1 Hashing (com.google.common.hash.Hashing)1 HashingInputStream (com.google.common.hash.HashingInputStream)1 ByteSource (com.google.common.io.ByteSource)1 ByteStreams (com.google.common.io.ByteStreams)1 MediaType (com.google.common.net.MediaType)1 CSVWriter (com.opencsv.CSVWriter)1 java.io (java.io)1 IOException (java.io.IOException)1 UncheckedIOException (java.io.UncheckedIOException)1 java.util (java.util)1 Consumer (java.util.function.Consumer)1