diff --git a/pom.xml b/pom.xml index 23eb06b..ebce38e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.boot spring-boot-starter-parent - 2.7.4 + 2.7.13 com.rymcu @@ -104,7 +104,7 @@ org.apache.tomcat.embed tomcat-embed-core - 9.0.68 + 9.0.73 org.springframework.boot @@ -328,7 +328,7 @@ com.theokanning.openai-gpt3-java client - 0.12.0 + 0.14.0 com.squareup.retrofit2 @@ -366,6 +366,10 @@ io.micrometer micrometer-registry-prometheus + + javax.validation + validation-api + diff --git a/src/main/java/com/rymcu/forest/core/constant/NotificationConstant.java b/src/main/java/com/rymcu/forest/core/constant/NotificationConstant.java index af131d5..3cd58a6 100644 --- a/src/main/java/com/rymcu/forest/core/constant/NotificationConstant.java +++ b/src/main/java/com/rymcu/forest/core/constant/NotificationConstant.java @@ -17,4 +17,6 @@ public class NotificationConstant { public static String UpdateArticle = "4"; + public static String UpdateArticleStatus = "5"; + } diff --git a/src/main/java/com/rymcu/forest/openai/OpenAiController.java b/src/main/java/com/rymcu/forest/openai/OpenAiController.java index f70c949..1aa635a 100644 --- a/src/main/java/com/rymcu/forest/openai/OpenAiController.java +++ b/src/main/java/com/rymcu/forest/openai/OpenAiController.java @@ -9,11 +9,8 @@ import com.rymcu.forest.openai.service.OpenAiService; import com.rymcu.forest.openai.service.SseService; import com.rymcu.forest.util.Html2TextUtil; import com.rymcu.forest.util.UserUtils; -import com.theokanning.openai.completion.chat.ChatCompletionChoice; -import com.theokanning.openai.completion.chat.ChatCompletionChunk; import com.theokanning.openai.completion.chat.ChatCompletionRequest; import com.theokanning.openai.completion.chat.ChatMessage; -import io.reactivex.Flowable; import org.apache.commons.lang.StringUtils; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Value; diff --git a/src/main/java/com/rymcu/forest/openai/service/OpenAiService.java b/src/main/java/com/rymcu/forest/openai/service/OpenAiService.java index b9d00fb..d917918 100644 --- a/src/main/java/com/rymcu/forest/openai/service/OpenAiService.java +++ b/src/main/java/com/rymcu/forest/openai/service/OpenAiService.java @@ -4,12 +4,14 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.rymcu.forest.util.SpringContextHolder; -import com.rymcu.forest.util.Utils; import com.theokanning.openai.DeleteResult; -import com.theokanning.openai.OpenAiApi; import com.theokanning.openai.OpenAiError; import com.theokanning.openai.OpenAiHttpException; +import com.theokanning.openai.audio.CreateTranscriptionRequest; +import com.theokanning.openai.audio.CreateTranslationRequest; +import com.theokanning.openai.audio.TranscriptionResult; +import com.theokanning.openai.audio.TranslationResult; +import com.theokanning.openai.client.OpenAiApi; import com.theokanning.openai.completion.CompletionChunk; import com.theokanning.openai.completion.CompletionRequest; import com.theokanning.openai.completion.CompletionResult; @@ -31,26 +33,26 @@ import com.theokanning.openai.image.ImageResult; import com.theokanning.openai.model.Model; import com.theokanning.openai.moderation.ModerationRequest; import com.theokanning.openai.moderation.ModerationResult; + import io.reactivex.BackpressureStrategy; import io.reactivex.Flowable; import io.reactivex.Single; import okhttp3.*; -import org.springframework.core.env.Environment; -import org.springframework.web.context.request.RequestContextHolder; -import org.springframework.web.context.request.ServletRequestAttributes; -import retrofit2.Call; import retrofit2.HttpException; import retrofit2.Retrofit; +import retrofit2.Call; import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; import retrofit2.converter.jackson.JacksonConverterFactory; -import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.time.Duration; import java.util.List; import java.util.Objects; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; +import com.rymcu.forest.util.SpringContextHolder; +import org.springframework.core.env.Environment; + public class OpenAiService { @@ -60,6 +62,7 @@ public class OpenAiService { private final OpenAiApi api; private final ExecutorService executorService; + private static final Environment env = SpringContextHolder.getBean(Environment.class); /** @@ -254,6 +257,61 @@ public class OpenAiService { return execute(api.createImageVariation(builder.build())); } + public TranscriptionResult createTranscription(CreateTranscriptionRequest request, String audioPath) { + java.io.File audio = new java.io.File(audioPath); + return createTranscription(request, audio); + } + + public TranscriptionResult createTranscription(CreateTranscriptionRequest request, java.io.File audio) { + RequestBody audioBody = RequestBody.create(MediaType.parse("audio"), audio); + + MultipartBody.Builder builder = new MultipartBody.Builder() + .setType(MediaType.get("multipart/form-data")) + .addFormDataPart("model", request.getModel()) + .addFormDataPart("file", audio.getName(), audioBody); + + if (request.getPrompt() != null) { + builder.addFormDataPart("prompt", request.getPrompt()); + } + if (request.getResponseFormat() != null) { + builder.addFormDataPart("response_format", request.getResponseFormat()); + } + if (request.getTemperature() != null) { + builder.addFormDataPart("temperature", request.getTemperature().toString()); + } + if (request.getLanguage() != null) { + builder.addFormDataPart("language", request.getLanguage()); + } + + return execute(api.createTranscription(builder.build())); + } + + public TranslationResult createTranslation(CreateTranslationRequest request, String audioPath) { + java.io.File audio = new java.io.File(audioPath); + return createTranslation(request, audio); + } + + public TranslationResult createTranslation(CreateTranslationRequest request, java.io.File audio) { + RequestBody audioBody = RequestBody.create(MediaType.parse("audio"), audio); + + MultipartBody.Builder builder = new MultipartBody.Builder() + .setType(MediaType.get("multipart/form-data")) + .addFormDataPart("model", request.getModel()) + .addFormDataPart("file", audio.getName(), audioBody); + + if (request.getPrompt() != null) { + builder.addFormDataPart("prompt", request.getPrompt()); + } + if (request.getResponseFormat() != null) { + builder.addFormDataPart("response_format", request.getResponseFormat()); + } + if (request.getTemperature() != null) { + builder.addFormDataPart("temperature", request.getTemperature().toString()); + } + + return execute(api.createTranslation(builder.build())); + } + public ModerationResult createModeration(ModerationRequest request) { return execute(api.createModeration(request)); } @@ -339,11 +397,8 @@ public class OpenAiService { } public static OkHttpClient defaultClient(String token, Duration timeout) { - HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); - String ip = Utils.getIpAddress(request); return new OkHttpClient.Builder() .addInterceptor(new AuthenticationInterceptor(token)) - .addInterceptor(new IpAddressInterceptor(ip)) .connectionPool(new ConnectionPool(5, 1, TimeUnit.SECONDS)) .readTimeout(timeout.toMillis(), TimeUnit.MILLISECONDS) .build();