Search in sources :

Example 1 with TransferStatus

use of com.tesshu.jpsonic.domain.TransferStatus in project jpsonic by tesshucom.

the class StatusService method getAllStreamStatuses.

public List<TransferStatus> getAllStreamStatuses() {
    synchronized (STREAM_LOCK) {
        List<TransferStatus> result = new ArrayList<>(streamStatuses);
        // Add inactive status for those players that have no active status.
        Set<Integer> activePlayers = new HashSet<>();
        for (TransferStatus status : streamStatuses) {
            activePlayers.add(status.getPlayer().getId());
        }
        for (Map.Entry<Integer, TransferStatus> entry : inactiveStreamStatuses.entrySet()) {
            if (!activePlayers.contains(entry.getKey())) {
                result.add(entry.getValue());
            }
        }
        return unmodifiableList(result);
    }
}
Also used : TransferStatus(com.tesshu.jpsonic.domain.TransferStatus) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) HashSet(java.util.HashSet)

Example 2 with TransferStatus

use of com.tesshu.jpsonic.domain.TransferStatus in project jpsonic by tesshucom.

the class UploadController method handleRequestInternal.

@PostMapping
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) {
    TransferStatus status = null;
    UnzipResult result = null;
    Map<String, Object> model = LegacyMap.of();
    try {
        status = statusService.createUploadStatus(playerService.getPlayer(request, response, false, false));
        status.setBytesTotal(request.getContentLength());
        request.getSession().setAttribute(Attributes.Session.UPLOAD_STATUS.value(), status);
        // Check that we have a file upload request
        if (!ServletFileUpload.isMultipartContent(request)) {
            throw new ExecutionException(new IOException("Illegal request."));
        }
        List<FileItem> items = getUploadItems(request, status);
        File dir = getDir(items);
        if (dir == null) {
            throw new IOException("Missing 'dir' parameter.");
        }
        boolean unzip = isUnzip(items);
        result = doUnzip(items, dir, unzip);
    } catch (IOException | FileUploadException e) {
        if (LOG.isWarnEnabled()) {
            LOG.warn("Uploading failed.", e);
        }
        model.put("exception", e);
    } catch (ExecutionException e) {
        ConcurrentUtils.handleCauseUnchecked(e);
        if (LOG.isWarnEnabled()) {
            LOG.warn("Uploading failed.", e);
        }
        model.put("exception", e);
    } finally {
        afterUpload(request, status);
    }
    if (result != null) {
        model.put("uploadedFiles", result.getUploadedFiles());
        model.put("unzippedFiles", result.getUnzippedFiles());
    }
    return new ModelAndView("upload", "model", model);
}
Also used : ModelAndView(org.springframework.web.servlet.ModelAndView) IOException(java.io.IOException) FileItem(org.apache.commons.fileupload.FileItem) TransferStatus(com.tesshu.jpsonic.domain.TransferStatus) ExecutionException(java.util.concurrent.ExecutionException) ZipFile(java.util.zip.ZipFile) File(java.io.File) FileUploadException(org.apache.commons.fileupload.FileUploadException) PostMapping(org.springframework.web.bind.annotation.PostMapping)

Example 3 with TransferStatus

use of com.tesshu.jpsonic.domain.TransferStatus in project jpsonic by tesshucom.

the class StatusController method handleRequestInternal.

// (TransferStatusHolder) Not reusable
@SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
@GetMapping
protected ModelAndView handleRequestInternal(HttpServletRequest request) {
    List<TransferStatus> streamStatuses = statusService.getAllStreamStatuses();
    List<TransferStatus> downloadStatuses = statusService.getAllDownloadStatuses();
    List<TransferStatus> uploadStatuses = statusService.getAllUploadStatuses();
    Locale locale = RequestContextUtils.getLocale(request);
    List<TransferStatusHolder> transferStatuses = new ArrayList<>();
    for (int i = 0; i < streamStatuses.size(); i++) {
        long minutesAgo = streamStatuses.get(i).getMillisSinceLastUpdate() / 1000L / 60L;
        if (minutesAgo < LIMIT_OF_HISTORY_TO_BE_PRESENTED) {
            transferStatuses.add(new TransferStatusHolder(streamStatuses.get(i), true, false, false, i, locale));
        }
    }
    for (int i = 0; i < downloadStatuses.size(); i++) {
        transferStatuses.add(new TransferStatusHolder(downloadStatuses.get(i), false, true, false, i, locale));
    }
    for (int i = 0; i < uploadStatuses.size(); i++) {
        transferStatuses.add(new TransferStatusHolder(uploadStatuses.get(i), false, false, true, i, locale));
    }
    return new ModelAndView("status", "model", LegacyMap.of("brand", SettingsService.getBrand(), "admin", securityService.isAdmin(securityService.getCurrentUser(request).getUsername()), "showStatus", settingsService.isShowStatus(), "transferStatuses", transferStatuses, "chartWidth", StatusChartController.IMAGE_WIDTH, "chartHeight", StatusChartController.IMAGE_HEIGHT));
}
Also used : Locale(java.util.Locale) TransferStatus(com.tesshu.jpsonic.domain.TransferStatus) ArrayList(java.util.ArrayList) ModelAndView(org.springframework.web.servlet.ModelAndView) GetMapping(org.springframework.web.bind.annotation.GetMapping)

Example 4 with TransferStatus

use of com.tesshu.jpsonic.domain.TransferStatus in project jpsonic by tesshucom.

the class StreamController method handleRequest.

/**
 * @param req
 * @param res
 * @param isRest
 *            True if the call is from SubsonicRESTController
 *
 * @throws ServletRequestBindingException
 */
@GetMapping
public void handleRequest(HttpServletRequest req, HttpServletResponse res, Boolean isRest) throws ServletRequestBindingException {
    final Player player = playerService.getPlayer(req, res, false, true);
    final User user = securityService.getUserByName(player.getUsername());
    final Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    if (!(auth instanceof JWTAuthenticationToken) && !user.isStreamRole()) {
        sendForbidden(res, "Streaming is forbidden for user " + user.getUsername());
        return;
    }
    // Processing for all responses
    res.setHeader("Access-Control-Allow-Origin", "*");
    String contentType = getMimeType(req.getParameter(Attributes.Request.SUFFIX.value()));
    res.setContentType(contentType);
    // Processing for Podcast response only
    Integer playlistId = getIntParameter(req, Attributes.Request.PLAYLIST.value());
    final boolean isPodcast = playlistId != null;
    if (isPodcast) {
        streamService.setUpPlayQueue(req, res, player, playlistId);
    }
    MediaFile file = streamService.getSingleFile(req);
    boolean isSingleFile = file != null;
    String format = streamService.getFormat(req, player, isRest);
    Integer maxBitRate = getMaxBitRate(req);
    // Processing for a single file
    PrepareResponseResult result = null;
    if (isSingleFile) {
        result = prepareResponse(req, res, auth, user, player, file, format, maxBitRate);
    }
    // If Header request or folder access not allowed, end here.
    boolean isHeaderRequest = HttpMethod.HEAD.name().equals(req.getMethod());
    if (result == null || result.isFolderAccessNotAllowed() || isHeaderRequest) {
        writeVerboseLog(settingsService.isVerboseLogPlaying(), isHeaderRequest, file);
        return;
    }
    writeVerboseLog(settingsService.isVerboseLogPlaying(), res, file);
    streamService.closeAllStreamFor(player, isPodcast, isSingleFile);
    TransferStatus status = statusService.createStreamStatus(player);
    try (InputStream in = streamService.createInputStream(player, status, maxBitRate, format, result.getVideoTranscodingSettings());
        OutputStream out = RangeOutputStream.wrap(res.getOutputStream(), result.getRange())) {
        writeStream(player, in, out, result.getFileLengthExpected(), isPodcast, isSingleFile);
    } catch (IOException e) {
        writeErrorLog(e, req);
    } finally {
        streamService.removeStreamStatus(user, status);
    }
}
Also used : MediaFile(com.tesshu.jpsonic.domain.MediaFile) Player(com.tesshu.jpsonic.domain.Player) User(com.tesshu.jpsonic.domain.User) InputStream(java.io.InputStream) RangeOutputStream(com.tesshu.jpsonic.io.RangeOutputStream) OutputStream(java.io.OutputStream) IOException(java.io.IOException) Authentication(org.springframework.security.core.Authentication) TransferStatus(com.tesshu.jpsonic.domain.TransferStatus) JWTAuthenticationToken(com.tesshu.jpsonic.security.JWTAuthenticationToken) GetMapping(org.springframework.web.bind.annotation.GetMapping)

Example 5 with TransferStatus

use of com.tesshu.jpsonic.domain.TransferStatus in project jpsonic by tesshucom.

the class StreamControllerTest method initMocks.

private void initMocks(Player player, TranscodingService ts, StreamService ss) {
    this.transcodingService = ts;
    this.streamService = ss;
    settingsService = mock(SettingsService.class);
    securityService = mock(SecurityService.class);
    User user = new User(player.getUsername(), player.getUsername(), "");
    Mockito.when(securityService.getUserByName(player.getUsername())).thenReturn(user);
    playerService = mock(PlayerService.class);
    Mockito.when(playerService.getPlayer(Mockito.any(), Mockito.any(), Mockito.anyBoolean(), Mockito.anyBoolean())).thenReturn(player);
    statusService = mock(StatusService.class);
    TransferStatus transferStatus = mock(TransferStatus.class);
    Mockito.when(transferStatus.getPlayer()).thenReturn(player);
    Mockito.when(transferStatus.isTerminated()).thenReturn(true);
    Mockito.when(transferStatus.isActive()).thenReturn(true);
    Mockito.when(statusService.createStreamStatus(Mockito.nullable(Player.class))).thenReturn(transferStatus);
    Mockito.when(statusService.getStreamStatusesForPlayer(Mockito.nullable(Player.class))).thenReturn(Arrays.asList(transferStatus));
    streamController = new StreamController(settingsService, securityService, playerService, ts, statusService, ss);
    JWTAuthenticationToken token = new JWTAuthenticationToken(Collections.emptyList(), ServiceMockUtils.ADMIN_NAME, null);
    SecurityContextHolder.getContext().setAuthentication(token);
    this.mockMvc = MockMvcBuilders.standaloneSetup(streamController).build();
}
Also used : PlayerService(com.tesshu.jpsonic.service.PlayerService) StatusService(com.tesshu.jpsonic.service.StatusService) Player(com.tesshu.jpsonic.domain.Player) User(com.tesshu.jpsonic.domain.User) SecurityService(com.tesshu.jpsonic.service.SecurityService) TransferStatus(com.tesshu.jpsonic.domain.TransferStatus) JWTAuthenticationToken(com.tesshu.jpsonic.security.JWTAuthenticationToken) SettingsService(com.tesshu.jpsonic.service.SettingsService)

Aggregations

TransferStatus (com.tesshu.jpsonic.domain.TransferStatus)14 Player (com.tesshu.jpsonic.domain.Player)6 GetMapping (org.springframework.web.bind.annotation.GetMapping)5 MediaFile (com.tesshu.jpsonic.domain.MediaFile)4 User (com.tesshu.jpsonic.domain.User)4 Test (org.junit.jupiter.api.Test)4 ArrayList (java.util.ArrayList)3 ModelAndView (org.springframework.web.servlet.ModelAndView)3 JWTAuthenticationToken (com.tesshu.jpsonic.security.JWTAuthenticationToken)2 File (java.io.File)2 IOException (java.io.IOException)2 Date (java.util.Date)2 LinkedHashMap (java.util.LinkedHashMap)2 Order (org.junit.jupiter.api.Order)2 TestMethodOrder (org.junit.jupiter.api.TestMethodOrder)2 SpringBootTest (org.springframework.boot.test.context.SpringBootTest)2 PlayQueue (com.tesshu.jpsonic.domain.PlayQueue)1 PlayStatus (com.tesshu.jpsonic.domain.PlayStatus)1 Playlist (com.tesshu.jpsonic.domain.Playlist)1 RangeOutputStream (com.tesshu.jpsonic.io.RangeOutputStream)1