InventoryUploadApi.java
/*
* discogs-java-client - A Java SDK to access the Discogs API
* Copyright © 2025 Andy Miles (andy.miles@amilesend.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.amilesend.discogs.api;
import com.amilesend.client.connection.RequestException;
import com.amilesend.client.connection.file.ProgressReportingRequestBody;
import com.amilesend.client.connection.file.TransferProgressCallback;
import com.amilesend.discogs.connection.DiscogsConnection;
import com.amilesend.discogs.model.Api;
import com.amilesend.discogs.model.AuthenticationRequired;
import com.amilesend.discogs.model.inventory.AddInventoryRequest;
import com.amilesend.discogs.model.inventory.AddInventoryResponse;
import com.amilesend.discogs.model.inventory.ChangeInventoryRequest;
import com.amilesend.discogs.model.inventory.ChangeInventoryResponse;
import com.amilesend.discogs.model.inventory.DeleteInventoryRequest;
import com.amilesend.discogs.model.inventory.DeleteInventoryResponse;
import com.amilesend.discogs.model.inventory.GetUploadRequest;
import com.amilesend.discogs.model.inventory.GetUploadResponse;
import com.amilesend.discogs.model.inventory.GetUploadsRequest;
import com.amilesend.discogs.model.inventory.GetUploadsResponse;
import com.amilesend.discogs.model.inventory.type.UploadInformation;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import okhttp3.HttpUrl;
import okhttp3.Request;
import java.io.IOException;
import java.nio.file.Path;
import static com.amilesend.client.connection.Connection.Headers.CONTENT_TYPE;
import static com.amilesend.client.connection.file.TransferFileUtil.fetchMimeTypeFromFile;
/**
* The Discogs Inventory Upload API.
* <br/>
* <a href="https://www.discogs.com/developers#page:inventory-upload">API Documentation</a>
*
* @see ApiBase
*/
@Api
@Slf4j
public class InventoryUploadApi extends ApiBase {
private static final String UPLOAD_FILE_FIELD_NAME = "upload";
private static final String INVENTORY_UPLOAD_SUB_PATH = "/inventory/upload";
/**
* Creates a new {@code InventoryUploadApi} object.
*
* @param connection the underlying client connection
*/
public InventoryUploadApi(final DiscogsConnection connection) {
super(connection);
}
/**
* Adds items from a CSV file to a user's inventory.
*
* @param request the request
* @return the response
* @see AddInventoryRequest
* @see AddInventoryResponse
*/
@AuthenticationRequired
public AddInventoryResponse addInventory(@NonNull final AddInventoryRequest request) {
final HttpUrl httpUrl = buildHttpUrl(INVENTORY_UPLOAD_SUB_PATH + "/add", request);
final UploadInformation uploadInfo =
uploadInternal(httpUrl, request.getInventoryCsvFile(), request.getTransferProgressCallback());
return AddInventoryResponse.builder()
.filename(uploadInfo.getFilename())
.location(uploadInfo.getLocation())
.build();
}
/**
* Change items from a CSV file within a user's inventory.
*
* @param request the request
* @return the response
* @see ChangeInventoryRequest
* @see ChangeInventoryResponse
*/
@AuthenticationRequired
public ChangeInventoryResponse changeInventory(@NonNull final ChangeInventoryRequest request) {
final HttpUrl httpUrl = buildHttpUrl(INVENTORY_UPLOAD_SUB_PATH + "/change", request);
final UploadInformation uploadInfo =
uploadInternal(httpUrl, request.getInventoryCsvFile(), request.getTransferProgressCallback());
return ChangeInventoryResponse.builder()
.filename(uploadInfo.getFilename())
.location(uploadInfo.getLocation())
.build();
}
/**
* Delete items from a user's inventory for the given CSV-formatted list of releases.
*
* @param request the request
* @return the response
* @see DeleteInventoryRequest
* @see DeleteInventoryResponse
*/
@AuthenticationRequired
public DeleteInventoryResponse deleteInventory(@NonNull final DeleteInventoryRequest request) {
final HttpUrl httpUrl = buildHttpUrl(INVENTORY_UPLOAD_SUB_PATH + "/delete", request);
final UploadInformation uploadInfo =
uploadInternal(httpUrl, request.getInventoryCsvFile(), request.getTransferProgressCallback());
return DeleteInventoryResponse.builder()
.filename(uploadInfo.getFilename())
.location(uploadInfo.getLocation())
.build();
}
private UploadInformation uploadInternal(
final HttpUrl httpUrl,
final Path filePath,
final TransferProgressCallback callback) {
try {
final ProgressReportingRequestBody requestBody = ProgressReportingRequestBody.multiPartBuilder()
.fieldName(UPLOAD_FILE_FIELD_NAME)
.contentType(fetchMimeTypeFromFile(filePath))
.callback(callback)
.file(filePath)
.build();
final DiscogsConnection connection = getConnection();
final Request httpRequest = connection.newRequestBuilder()
.url(httpUrl)
.addHeader(CONTENT_TYPE, requestBody.contentType().toString())
.post(requestBody)
.build();
final UploadInformation uploadInfo =
connection.upload(httpRequest, filePath.getFileName().toString());
return AddInventoryResponse.builder()
.filename(uploadInfo.getFilename())
.location(uploadInfo.getLocation())
.build();
} catch (final IOException ex) {
throw new RequestException("Error reading file to upload", ex);
}
}
/**
* Gets the paginated list of uploads. Note: authentication is required.
*
* @param request the request
* @return the response
* @see GetUploadsRequest
* @see GetUploadsResponse
*/
@AuthenticationRequired
public GetUploadsResponse getUploads(@NonNull final GetUploadsRequest request) {
return executeGet(INVENTORY_UPLOAD_SUB_PATH, request, GetUploadsResponse.class);
}
/**
* Gets information for a specific upload. Note: authentication is required.
*
* @param request the request
* @return the response
* @see GetUploadRequest
* @see GetUploadResponse
*/
@AuthenticationRequired
public GetUploadResponse getUpload(@NonNull final GetUploadRequest request) {
final String subPath = new StringBuilder(INVENTORY_UPLOAD_SUB_PATH)
.append("/")
.append(request.getUploadId())
.toString();
return executeGet(subPath, request, GetUploadResponse.class);
}
}