add detailed jpg quality opts & thumbnail pass
Docker server image / build-and-push (push) Successful in 3m48s
Docker server image / build-and-push (push) Successful in 3m48s
This commit is contained in:
@@ -107,7 +107,11 @@ Create a conversion request:
|
|||||||
```bash
|
```bash
|
||||||
curl \
|
curl \
|
||||||
--header "Content-Type: application/json" \
|
--header "Content-Type: application/json" \
|
||||||
--data '{"sourceFilename":"example.pptx","resolution":"CONVERSION_RESOLUTION_FHD"}' \
|
--data '{
|
||||||
|
"sourceFilename":"example.pptx",
|
||||||
|
"full":{"resolution":"CONVERSION_RESOLUTION_FHD","jpeg":{"quality":85}},
|
||||||
|
"thumbnail":{"resolution":"CONVERSION_RESOLUTION_SD","jpeg":{"quality":75}}
|
||||||
|
}' \
|
||||||
http://localhost:8080/officeconvertapi.v1.ConversionService/CreateConversion
|
http://localhost:8080/officeconvertapi.v1.ConversionService/CreateConversion
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -139,8 +143,10 @@ Use `.env.example` as your baseline env configuration.
|
|||||||
|
|
||||||
If conversion fails on larger decks, tune these environment variables:
|
If conversion fails on larger decks, tune these environment variables:
|
||||||
|
|
||||||
- `CreateConversionRequest.resolution` controls output dimensions via presets: `SD`, `HD`, `FHD`, `QHD`, `UHD`.
|
- `CreateConversionRequest.full.resolution` controls full-size output dimensions via presets: `SD`, `HD`, `FHD`, `QHD`, `UHD`.
|
||||||
- Omitting `resolution` (or sending `CONVERSION_RESOLUTION_UNSPECIFIED`) defaults to `FHD`.
|
- `CreateConversionRequest.thumbnail.resolution` controls thumbnail output dimensions with the same presets.
|
||||||
- Rasterization DPI is inferred automatically from source slide size and selected output dimensions.
|
- Omitting full/thumbnail resolution (or sending `CONVERSION_RESOLUTION_UNSPECIFIED`) defaults to `FHD` for full and `SD` for thumbnail.
|
||||||
|
- Output is JPEG-only for now; set `CreateConversionRequest.full.jpeg.quality` and `CreateConversionRequest.thumbnail.jpeg.quality` to `1..100` (`0` or omitted uses server defaults: full `85`, thumbnail `75`).
|
||||||
|
- Rasterization DPI is inferred automatically from source slide size and selected full/thumbnail output dimensions.
|
||||||
- `CONVERSION_PPTX_TO_PDF_TIMEOUT_SECONDS` (default `180`): timeout for LibreOffice export.
|
- `CONVERSION_PPTX_TO_PDF_TIMEOUT_SECONDS` (default `180`): timeout for LibreOffice export.
|
||||||
- `CONVERSION_PDF_TO_IMAGES_TIMEOUT_SECONDS` (default `1800`): timeout for Poppler rasterization.
|
- `CONVERSION_PDF_TO_IMAGES_TIMEOUT_SECONDS` (default `1800`): timeout for Poppler rasterization.
|
||||||
|
|||||||
@@ -8,13 +8,25 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"connectrpc.com/connect"
|
"connectrpc.com/connect"
|
||||||
"github.com/segmentio/ksuid"
|
|
||||||
officeconvertapiv1 "gitea.auvem.com/end-internal/officeconvert/gen/go/officeconvertapi/v1"
|
officeconvertapiv1 "gitea.auvem.com/end-internal/officeconvert/gen/go/officeconvertapi/v1"
|
||||||
"gitea.auvem.com/end-internal/officeconvert/gen/go/officeconvertapi/v1/officeconvertapiv1connect"
|
"gitea.auvem.com/end-internal/officeconvert/gen/go/officeconvertapi/v1/officeconvertapiv1connect"
|
||||||
|
"github.com/segmentio/ksuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultPollInterval = 2 * time.Second
|
const defaultPollInterval = 2 * time.Second
|
||||||
|
|
||||||
|
// RasterTierOptions defines per-tier raster settings for conversion output.
|
||||||
|
type RasterTierOptions struct {
|
||||||
|
Resolution officeconvertapiv1.ConversionResolution
|
||||||
|
JPEGQuality int32
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateConversionOptions configures optional full and thumbnail raster tiers.
|
||||||
|
type CreateConversionOptions struct {
|
||||||
|
Full *RasterTierOptions
|
||||||
|
Thumbnail *RasterTierOptions
|
||||||
|
}
|
||||||
|
|
||||||
// Client wraps the generated Connect client with orchestration-focused helpers.
|
// Client wraps the generated Connect client with orchestration-focused helpers.
|
||||||
type Client struct {
|
type Client struct {
|
||||||
rpc officeconvertapiv1connect.ConversionServiceClient
|
rpc officeconvertapiv1connect.ConversionServiceClient
|
||||||
@@ -47,12 +59,16 @@ func (c *Client) SetPollInterval(interval time.Duration) {
|
|||||||
func (c *Client) CreateConversion(
|
func (c *Client) CreateConversion(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
sourceFilename string,
|
sourceFilename string,
|
||||||
resolution officeconvertapiv1.ConversionResolution,
|
options *CreateConversionOptions,
|
||||||
) (*CreateConversionResponse, error) {
|
) (*CreateConversionResponse, error) {
|
||||||
req := connect.NewRequest(&officeconvertapiv1.CreateConversionRequest{
|
message := &officeconvertapiv1.CreateConversionRequest{
|
||||||
SourceFilename: sourceFilename,
|
SourceFilename: sourceFilename,
|
||||||
Resolution: resolution,
|
}
|
||||||
})
|
if options != nil {
|
||||||
|
message.Full = toProtoSlideRasterOptions(options.Full)
|
||||||
|
message.Thumbnail = toProtoSlideRasterOptions(options.Thumbnail)
|
||||||
|
}
|
||||||
|
req := connect.NewRequest(message)
|
||||||
res, err := c.rpc.CreateConversion(ctx, req)
|
res, err := c.rpc.CreateConversion(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -60,6 +76,25 @@ func (c *Client) CreateConversion(
|
|||||||
return augmentCreateConversionResponse(res.Msg)
|
return augmentCreateConversionResponse(res.Msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func toProtoSlideRasterOptions(
|
||||||
|
options *RasterTierOptions,
|
||||||
|
) *officeconvertapiv1.SlideRasterOptions {
|
||||||
|
if options == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
proto := &officeconvertapiv1.SlideRasterOptions{
|
||||||
|
Resolution: options.Resolution,
|
||||||
|
}
|
||||||
|
if options.JPEGQuality != 0 {
|
||||||
|
proto.Format = &officeconvertapiv1.SlideRasterOptions_Jpeg{
|
||||||
|
Jpeg: &officeconvertapiv1.JpegOutputOptions{
|
||||||
|
Quality: options.JPEGQuality,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return proto
|
||||||
|
}
|
||||||
|
|
||||||
// StartConversion signals that upload is complete and conversion can begin.
|
// StartConversion signals that upload is complete and conversion can begin.
|
||||||
func (c *Client) StartConversion(
|
func (c *Client) StartConversion(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ func (c *Client) ConvertPPTXFile(ctx context.Context, localPPTXPath string) (*Co
|
|||||||
createRes, err := c.CreateConversion(
|
createRes, err := c.CreateConversion(
|
||||||
ctx,
|
ctx,
|
||||||
filepath.Base(localPPTXPath),
|
filepath.Base(localPPTXPath),
|
||||||
officeconvertapiv1.ConversionResolution_CONVERSION_RESOLUTION_UNSPECIFIED,
|
nil,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("create conversion: %w", err)
|
return nil, fmt.Errorf("create conversion: %w", err)
|
||||||
|
|||||||
@@ -196,19 +196,144 @@ func (ConversionResolution) EnumDescriptor() ([]byte, []int) {
|
|||||||
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{2}
|
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{2}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slide contains extracted notes and the rendered image URL for one slide.
|
// JpegOutputOptions configures JPEG-specific encoding controls.
|
||||||
type Slide struct {
|
type JpegOutputOptions struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
Index int32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"`
|
// JPEG quality from 1..100. 0 means server default.
|
||||||
NotesPlain string `protobuf:"bytes,2,opt,name=notes_plain,json=notesPlain,proto3" json:"notes_plain,omitempty"`
|
Quality int32 `protobuf:"varint,1,opt,name=quality,proto3" json:"quality,omitempty"`
|
||||||
ImageUrl string `protobuf:"bytes,3,opt,name=image_url,json=imageUrl,proto3" json:"image_url,omitempty"`
|
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *JpegOutputOptions) Reset() {
|
||||||
|
*x = JpegOutputOptions{}
|
||||||
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[0]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *JpegOutputOptions) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*JpegOutputOptions) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *JpegOutputOptions) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[0]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use JpegOutputOptions.ProtoReflect.Descriptor instead.
|
||||||
|
func (*JpegOutputOptions) Descriptor() ([]byte, []int) {
|
||||||
|
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{0}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *JpegOutputOptions) GetQuality() int32 {
|
||||||
|
if x != nil {
|
||||||
|
return x.Quality
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// SlideRasterOptions defines rendering settings for a raster output tier.
|
||||||
|
type SlideRasterOptions struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
// Output resolution preset. UNSPECIFIED means server default for the tier.
|
||||||
|
Resolution ConversionResolution `protobuf:"varint,1,opt,name=resolution,proto3,enum=officeconvertapi.v1.ConversionResolution" json:"resolution,omitempty"`
|
||||||
|
// Types that are valid to be assigned to Format:
|
||||||
|
//
|
||||||
|
// *SlideRasterOptions_Jpeg
|
||||||
|
Format isSlideRasterOptions_Format `protobuf_oneof:"format"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SlideRasterOptions) Reset() {
|
||||||
|
*x = SlideRasterOptions{}
|
||||||
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[1]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SlideRasterOptions) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*SlideRasterOptions) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *SlideRasterOptions) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[1]
|
||||||
|
if x != nil {
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
if ms.LoadMessageInfo() == nil {
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
return ms
|
||||||
|
}
|
||||||
|
return mi.MessageOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use SlideRasterOptions.ProtoReflect.Descriptor instead.
|
||||||
|
func (*SlideRasterOptions) Descriptor() ([]byte, []int) {
|
||||||
|
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{1}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SlideRasterOptions) GetResolution() ConversionResolution {
|
||||||
|
if x != nil {
|
||||||
|
return x.Resolution
|
||||||
|
}
|
||||||
|
return ConversionResolution_CONVERSION_RESOLUTION_UNSPECIFIED
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SlideRasterOptions) GetFormat() isSlideRasterOptions_Format {
|
||||||
|
if x != nil {
|
||||||
|
return x.Format
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SlideRasterOptions) GetJpeg() *JpegOutputOptions {
|
||||||
|
if x != nil {
|
||||||
|
if x, ok := x.Format.(*SlideRasterOptions_Jpeg); ok {
|
||||||
|
return x.Jpeg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type isSlideRasterOptions_Format interface {
|
||||||
|
isSlideRasterOptions_Format()
|
||||||
|
}
|
||||||
|
|
||||||
|
type SlideRasterOptions_Jpeg struct {
|
||||||
|
Jpeg *JpegOutputOptions `protobuf:"bytes,2,opt,name=jpeg,proto3,oneof"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*SlideRasterOptions_Jpeg) isSlideRasterOptions_Format() {}
|
||||||
|
|
||||||
|
// Slide contains extracted notes and the rendered image URL for one slide.
|
||||||
|
type Slide struct {
|
||||||
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
|
Index int32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"`
|
||||||
|
NotesPlain string `protobuf:"bytes,2,opt,name=notes_plain,json=notesPlain,proto3" json:"notes_plain,omitempty"`
|
||||||
|
// Full-size rendered image URL.
|
||||||
|
ImageUrl string `protobuf:"bytes,3,opt,name=image_url,json=imageUrl,proto3" json:"image_url,omitempty"`
|
||||||
|
// Thumbnail rendered image URL.
|
||||||
|
ThumbnailImageUrl string `protobuf:"bytes,4,opt,name=thumbnail_image_url,json=thumbnailImageUrl,proto3" json:"thumbnail_image_url,omitempty"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
}
|
||||||
|
|
||||||
func (x *Slide) Reset() {
|
func (x *Slide) Reset() {
|
||||||
*x = Slide{}
|
*x = Slide{}
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[0]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[2]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -220,7 +345,7 @@ func (x *Slide) String() string {
|
|||||||
func (*Slide) ProtoMessage() {}
|
func (*Slide) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *Slide) ProtoReflect() protoreflect.Message {
|
func (x *Slide) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[0]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[2]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -233,7 +358,7 @@ func (x *Slide) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use Slide.ProtoReflect.Descriptor instead.
|
// Deprecated: Use Slide.ProtoReflect.Descriptor instead.
|
||||||
func (*Slide) Descriptor() ([]byte, []int) {
|
func (*Slide) Descriptor() ([]byte, []int) {
|
||||||
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{0}
|
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{2}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *Slide) GetIndex() int32 {
|
func (x *Slide) GetIndex() int32 {
|
||||||
@@ -257,6 +382,13 @@ func (x *Slide) GetImageUrl() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *Slide) GetThumbnailImageUrl() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.ThumbnailImageUrl
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
// SlideDeck is the final structured conversion artifact.
|
// SlideDeck is the final structured conversion artifact.
|
||||||
type SlideDeck struct {
|
type SlideDeck struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
@@ -265,15 +397,21 @@ type SlideDeck struct {
|
|||||||
SourceFilename string `protobuf:"bytes,2,opt,name=source_filename,json=sourceFilename,proto3" json:"source_filename,omitempty"`
|
SourceFilename string `protobuf:"bytes,2,opt,name=source_filename,json=sourceFilename,proto3" json:"source_filename,omitempty"`
|
||||||
Slides []*Slide `protobuf:"bytes,3,rep,name=slides,proto3" json:"slides,omitempty"`
|
Slides []*Slide `protobuf:"bytes,3,rep,name=slides,proto3" json:"slides,omitempty"`
|
||||||
CreatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
CreatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||||
Width int32 `protobuf:"varint,5,opt,name=width,proto3" json:"width,omitempty"`
|
// Full-size raster width in pixels.
|
||||||
Height int32 `protobuf:"varint,6,opt,name=height,proto3" json:"height,omitempty"`
|
Width int32 `protobuf:"varint,5,opt,name=width,proto3" json:"width,omitempty"`
|
||||||
unknownFields protoimpl.UnknownFields
|
// Full-size raster height in pixels.
|
||||||
sizeCache protoimpl.SizeCache
|
Height int32 `protobuf:"varint,6,opt,name=height,proto3" json:"height,omitempty"`
|
||||||
|
// Thumbnail raster width in pixels.
|
||||||
|
ThumbnailWidth int32 `protobuf:"varint,7,opt,name=thumbnail_width,json=thumbnailWidth,proto3" json:"thumbnail_width,omitempty"`
|
||||||
|
// Thumbnail raster height in pixels.
|
||||||
|
ThumbnailHeight int32 `protobuf:"varint,8,opt,name=thumbnail_height,json=thumbnailHeight,proto3" json:"thumbnail_height,omitempty"`
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *SlideDeck) Reset() {
|
func (x *SlideDeck) Reset() {
|
||||||
*x = SlideDeck{}
|
*x = SlideDeck{}
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[1]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[3]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -285,7 +423,7 @@ func (x *SlideDeck) String() string {
|
|||||||
func (*SlideDeck) ProtoMessage() {}
|
func (*SlideDeck) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *SlideDeck) ProtoReflect() protoreflect.Message {
|
func (x *SlideDeck) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[1]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[3]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -298,7 +436,7 @@ func (x *SlideDeck) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use SlideDeck.ProtoReflect.Descriptor instead.
|
// Deprecated: Use SlideDeck.ProtoReflect.Descriptor instead.
|
||||||
func (*SlideDeck) Descriptor() ([]byte, []int) {
|
func (*SlideDeck) Descriptor() ([]byte, []int) {
|
||||||
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{1}
|
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{3}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *SlideDeck) GetConversionId() string {
|
func (x *SlideDeck) GetConversionId() string {
|
||||||
@@ -343,18 +481,33 @@ func (x *SlideDeck) GetHeight() int32 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *SlideDeck) GetThumbnailWidth() int32 {
|
||||||
|
if x != nil {
|
||||||
|
return x.ThumbnailWidth
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SlideDeck) GetThumbnailHeight() int32 {
|
||||||
|
if x != nil {
|
||||||
|
return x.ThumbnailHeight
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
// CreateConversionRequest starts a conversion session.
|
// CreateConversionRequest starts a conversion session.
|
||||||
type CreateConversionRequest struct {
|
type CreateConversionRequest struct {
|
||||||
state protoimpl.MessageState `protogen:"open.v1"`
|
state protoimpl.MessageState `protogen:"open.v1"`
|
||||||
SourceFilename string `protobuf:"bytes,1,opt,name=source_filename,json=sourceFilename,proto3" json:"source_filename,omitempty"`
|
SourceFilename string `protobuf:"bytes,1,opt,name=source_filename,json=sourceFilename,proto3" json:"source_filename,omitempty"`
|
||||||
Resolution ConversionResolution `protobuf:"varint,2,opt,name=resolution,proto3,enum=officeconvertapi.v1.ConversionResolution" json:"resolution,omitempty"`
|
Full *SlideRasterOptions `protobuf:"bytes,2,opt,name=full,proto3" json:"full,omitempty"`
|
||||||
|
Thumbnail *SlideRasterOptions `protobuf:"bytes,3,opt,name=thumbnail,proto3" json:"thumbnail,omitempty"`
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *CreateConversionRequest) Reset() {
|
func (x *CreateConversionRequest) Reset() {
|
||||||
*x = CreateConversionRequest{}
|
*x = CreateConversionRequest{}
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[2]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[4]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -366,7 +519,7 @@ func (x *CreateConversionRequest) String() string {
|
|||||||
func (*CreateConversionRequest) ProtoMessage() {}
|
func (*CreateConversionRequest) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *CreateConversionRequest) ProtoReflect() protoreflect.Message {
|
func (x *CreateConversionRequest) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[2]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[4]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -379,7 +532,7 @@ func (x *CreateConversionRequest) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use CreateConversionRequest.ProtoReflect.Descriptor instead.
|
// Deprecated: Use CreateConversionRequest.ProtoReflect.Descriptor instead.
|
||||||
func (*CreateConversionRequest) Descriptor() ([]byte, []int) {
|
func (*CreateConversionRequest) Descriptor() ([]byte, []int) {
|
||||||
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{2}
|
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{4}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *CreateConversionRequest) GetSourceFilename() string {
|
func (x *CreateConversionRequest) GetSourceFilename() string {
|
||||||
@@ -389,11 +542,18 @@ func (x *CreateConversionRequest) GetSourceFilename() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *CreateConversionRequest) GetResolution() ConversionResolution {
|
func (x *CreateConversionRequest) GetFull() *SlideRasterOptions {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.Resolution
|
return x.Full
|
||||||
}
|
}
|
||||||
return ConversionResolution_CONVERSION_RESOLUTION_UNSPECIFIED
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *CreateConversionRequest) GetThumbnail() *SlideRasterOptions {
|
||||||
|
if x != nil {
|
||||||
|
return x.Thumbnail
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateConversionResponse returns upload details for the session.
|
// CreateConversionResponse returns upload details for the session.
|
||||||
@@ -411,7 +571,7 @@ type CreateConversionResponse struct {
|
|||||||
|
|
||||||
func (x *CreateConversionResponse) Reset() {
|
func (x *CreateConversionResponse) Reset() {
|
||||||
*x = CreateConversionResponse{}
|
*x = CreateConversionResponse{}
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[3]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[5]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -423,7 +583,7 @@ func (x *CreateConversionResponse) String() string {
|
|||||||
func (*CreateConversionResponse) ProtoMessage() {}
|
func (*CreateConversionResponse) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *CreateConversionResponse) ProtoReflect() protoreflect.Message {
|
func (x *CreateConversionResponse) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[3]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[5]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -436,7 +596,7 @@ func (x *CreateConversionResponse) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use CreateConversionResponse.ProtoReflect.Descriptor instead.
|
// Deprecated: Use CreateConversionResponse.ProtoReflect.Descriptor instead.
|
||||||
func (*CreateConversionResponse) Descriptor() ([]byte, []int) {
|
func (*CreateConversionResponse) Descriptor() ([]byte, []int) {
|
||||||
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{3}
|
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{5}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *CreateConversionResponse) GetConversionId() string {
|
func (x *CreateConversionResponse) GetConversionId() string {
|
||||||
@@ -485,7 +645,7 @@ type StartConversionRequest struct {
|
|||||||
|
|
||||||
func (x *StartConversionRequest) Reset() {
|
func (x *StartConversionRequest) Reset() {
|
||||||
*x = StartConversionRequest{}
|
*x = StartConversionRequest{}
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[4]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[6]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -497,7 +657,7 @@ func (x *StartConversionRequest) String() string {
|
|||||||
func (*StartConversionRequest) ProtoMessage() {}
|
func (*StartConversionRequest) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *StartConversionRequest) ProtoReflect() protoreflect.Message {
|
func (x *StartConversionRequest) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[4]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[6]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -510,7 +670,7 @@ func (x *StartConversionRequest) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use StartConversionRequest.ProtoReflect.Descriptor instead.
|
// Deprecated: Use StartConversionRequest.ProtoReflect.Descriptor instead.
|
||||||
func (*StartConversionRequest) Descriptor() ([]byte, []int) {
|
func (*StartConversionRequest) Descriptor() ([]byte, []int) {
|
||||||
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{4}
|
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{6}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *StartConversionRequest) GetConversionId() string {
|
func (x *StartConversionRequest) GetConversionId() string {
|
||||||
@@ -532,7 +692,7 @@ type StartConversionResponse struct {
|
|||||||
|
|
||||||
func (x *StartConversionResponse) Reset() {
|
func (x *StartConversionResponse) Reset() {
|
||||||
*x = StartConversionResponse{}
|
*x = StartConversionResponse{}
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[5]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[7]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -544,7 +704,7 @@ func (x *StartConversionResponse) String() string {
|
|||||||
func (*StartConversionResponse) ProtoMessage() {}
|
func (*StartConversionResponse) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *StartConversionResponse) ProtoReflect() protoreflect.Message {
|
func (x *StartConversionResponse) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[5]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[7]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -557,7 +717,7 @@ func (x *StartConversionResponse) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use StartConversionResponse.ProtoReflect.Descriptor instead.
|
// Deprecated: Use StartConversionResponse.ProtoReflect.Descriptor instead.
|
||||||
func (*StartConversionResponse) Descriptor() ([]byte, []int) {
|
func (*StartConversionResponse) Descriptor() ([]byte, []int) {
|
||||||
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{5}
|
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{7}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *StartConversionResponse) GetConversionId() string {
|
func (x *StartConversionResponse) GetConversionId() string {
|
||||||
@@ -585,7 +745,7 @@ type GetConversionStatusRequest struct {
|
|||||||
|
|
||||||
func (x *GetConversionStatusRequest) Reset() {
|
func (x *GetConversionStatusRequest) Reset() {
|
||||||
*x = GetConversionStatusRequest{}
|
*x = GetConversionStatusRequest{}
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[6]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[8]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -597,7 +757,7 @@ func (x *GetConversionStatusRequest) String() string {
|
|||||||
func (*GetConversionStatusRequest) ProtoMessage() {}
|
func (*GetConversionStatusRequest) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *GetConversionStatusRequest) ProtoReflect() protoreflect.Message {
|
func (x *GetConversionStatusRequest) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[6]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[8]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -610,7 +770,7 @@ func (x *GetConversionStatusRequest) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use GetConversionStatusRequest.ProtoReflect.Descriptor instead.
|
// Deprecated: Use GetConversionStatusRequest.ProtoReflect.Descriptor instead.
|
||||||
func (*GetConversionStatusRequest) Descriptor() ([]byte, []int) {
|
func (*GetConversionStatusRequest) Descriptor() ([]byte, []int) {
|
||||||
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{6}
|
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{8}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *GetConversionStatusRequest) GetConversionId() string {
|
func (x *GetConversionStatusRequest) GetConversionId() string {
|
||||||
@@ -637,7 +797,7 @@ type GetConversionStatusResponse struct {
|
|||||||
|
|
||||||
func (x *GetConversionStatusResponse) Reset() {
|
func (x *GetConversionStatusResponse) Reset() {
|
||||||
*x = GetConversionStatusResponse{}
|
*x = GetConversionStatusResponse{}
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[7]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[9]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -649,7 +809,7 @@ func (x *GetConversionStatusResponse) String() string {
|
|||||||
func (*GetConversionStatusResponse) ProtoMessage() {}
|
func (*GetConversionStatusResponse) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *GetConversionStatusResponse) ProtoReflect() protoreflect.Message {
|
func (x *GetConversionStatusResponse) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[7]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[9]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -662,7 +822,7 @@ func (x *GetConversionStatusResponse) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use GetConversionStatusResponse.ProtoReflect.Descriptor instead.
|
// Deprecated: Use GetConversionStatusResponse.ProtoReflect.Descriptor instead.
|
||||||
func (*GetConversionStatusResponse) Descriptor() ([]byte, []int) {
|
func (*GetConversionStatusResponse) Descriptor() ([]byte, []int) {
|
||||||
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{7}
|
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{9}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *GetConversionStatusResponse) GetConversionId() string {
|
func (x *GetConversionStatusResponse) GetConversionId() string {
|
||||||
@@ -725,7 +885,7 @@ type GetSlideDeckRequest struct {
|
|||||||
|
|
||||||
func (x *GetSlideDeckRequest) Reset() {
|
func (x *GetSlideDeckRequest) Reset() {
|
||||||
*x = GetSlideDeckRequest{}
|
*x = GetSlideDeckRequest{}
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[8]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[10]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -737,7 +897,7 @@ func (x *GetSlideDeckRequest) String() string {
|
|||||||
func (*GetSlideDeckRequest) ProtoMessage() {}
|
func (*GetSlideDeckRequest) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *GetSlideDeckRequest) ProtoReflect() protoreflect.Message {
|
func (x *GetSlideDeckRequest) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[8]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[10]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -750,7 +910,7 @@ func (x *GetSlideDeckRequest) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use GetSlideDeckRequest.ProtoReflect.Descriptor instead.
|
// Deprecated: Use GetSlideDeckRequest.ProtoReflect.Descriptor instead.
|
||||||
func (*GetSlideDeckRequest) Descriptor() ([]byte, []int) {
|
func (*GetSlideDeckRequest) Descriptor() ([]byte, []int) {
|
||||||
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{8}
|
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{10}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *GetSlideDeckRequest) GetConversionId() string {
|
func (x *GetSlideDeckRequest) GetConversionId() string {
|
||||||
@@ -770,7 +930,7 @@ type GetSlideDeckResponse struct {
|
|||||||
|
|
||||||
func (x *GetSlideDeckResponse) Reset() {
|
func (x *GetSlideDeckResponse) Reset() {
|
||||||
*x = GetSlideDeckResponse{}
|
*x = GetSlideDeckResponse{}
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[9]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[11]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -782,7 +942,7 @@ func (x *GetSlideDeckResponse) String() string {
|
|||||||
func (*GetSlideDeckResponse) ProtoMessage() {}
|
func (*GetSlideDeckResponse) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *GetSlideDeckResponse) ProtoReflect() protoreflect.Message {
|
func (x *GetSlideDeckResponse) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[9]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[11]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -795,7 +955,7 @@ func (x *GetSlideDeckResponse) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use GetSlideDeckResponse.ProtoReflect.Descriptor instead.
|
// Deprecated: Use GetSlideDeckResponse.ProtoReflect.Descriptor instead.
|
||||||
func (*GetSlideDeckResponse) Descriptor() ([]byte, []int) {
|
func (*GetSlideDeckResponse) Descriptor() ([]byte, []int) {
|
||||||
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{9}
|
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{11}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *GetSlideDeckResponse) GetSlideDeck() *SlideDeck {
|
func (x *GetSlideDeckResponse) GetSlideDeck() *SlideDeck {
|
||||||
@@ -816,7 +976,7 @@ type DeleteConversionRequest struct {
|
|||||||
|
|
||||||
func (x *DeleteConversionRequest) Reset() {
|
func (x *DeleteConversionRequest) Reset() {
|
||||||
*x = DeleteConversionRequest{}
|
*x = DeleteConversionRequest{}
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[10]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[12]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -828,7 +988,7 @@ func (x *DeleteConversionRequest) String() string {
|
|||||||
func (*DeleteConversionRequest) ProtoMessage() {}
|
func (*DeleteConversionRequest) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *DeleteConversionRequest) ProtoReflect() protoreflect.Message {
|
func (x *DeleteConversionRequest) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[10]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[12]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -841,7 +1001,7 @@ func (x *DeleteConversionRequest) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use DeleteConversionRequest.ProtoReflect.Descriptor instead.
|
// Deprecated: Use DeleteConversionRequest.ProtoReflect.Descriptor instead.
|
||||||
func (*DeleteConversionRequest) Descriptor() ([]byte, []int) {
|
func (*DeleteConversionRequest) Descriptor() ([]byte, []int) {
|
||||||
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{10}
|
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{12}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *DeleteConversionRequest) GetConversionId() string {
|
func (x *DeleteConversionRequest) GetConversionId() string {
|
||||||
@@ -863,7 +1023,7 @@ type DeleteConversionResponse struct {
|
|||||||
|
|
||||||
func (x *DeleteConversionResponse) Reset() {
|
func (x *DeleteConversionResponse) Reset() {
|
||||||
*x = DeleteConversionResponse{}
|
*x = DeleteConversionResponse{}
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[11]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[13]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -875,7 +1035,7 @@ func (x *DeleteConversionResponse) String() string {
|
|||||||
func (*DeleteConversionResponse) ProtoMessage() {}
|
func (*DeleteConversionResponse) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *DeleteConversionResponse) ProtoReflect() protoreflect.Message {
|
func (x *DeleteConversionResponse) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[11]
|
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[13]
|
||||||
if x != nil {
|
if x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -888,7 +1048,7 @@ func (x *DeleteConversionResponse) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use DeleteConversionResponse.ProtoReflect.Descriptor instead.
|
// Deprecated: Use DeleteConversionResponse.ProtoReflect.Descriptor instead.
|
||||||
func (*DeleteConversionResponse) Descriptor() ([]byte, []int) {
|
func (*DeleteConversionResponse) Descriptor() ([]byte, []int) {
|
||||||
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{11}
|
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{13}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *DeleteConversionResponse) GetConversionId() string {
|
func (x *DeleteConversionResponse) GetConversionId() string {
|
||||||
@@ -909,12 +1069,21 @@ var File_officeconvertapi_v1_conversion_proto protoreflect.FileDescriptor
|
|||||||
|
|
||||||
const file_officeconvertapi_v1_conversion_proto_rawDesc = "" +
|
const file_officeconvertapi_v1_conversion_proto_rawDesc = "" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"$officeconvertapi/v1/conversion.proto\x12\x13officeconvertapi.v1\x1a\x1fgoogle/protobuf/timestamp.proto\"[\n" +
|
"$officeconvertapi/v1/conversion.proto\x12\x13officeconvertapi.v1\x1a\x1fgoogle/protobuf/timestamp.proto\"-\n" +
|
||||||
|
"\x11JpegOutputOptions\x12\x18\n" +
|
||||||
|
"\aquality\x18\x01 \x01(\x05R\aquality\"\xa7\x01\n" +
|
||||||
|
"\x12SlideRasterOptions\x12I\n" +
|
||||||
|
"\n" +
|
||||||
|
"resolution\x18\x01 \x01(\x0e2).officeconvertapi.v1.ConversionResolutionR\n" +
|
||||||
|
"resolution\x12<\n" +
|
||||||
|
"\x04jpeg\x18\x02 \x01(\v2&.officeconvertapi.v1.JpegOutputOptionsH\x00R\x04jpegB\b\n" +
|
||||||
|
"\x06format\"\x8b\x01\n" +
|
||||||
"\x05Slide\x12\x14\n" +
|
"\x05Slide\x12\x14\n" +
|
||||||
"\x05index\x18\x01 \x01(\x05R\x05index\x12\x1f\n" +
|
"\x05index\x18\x01 \x01(\x05R\x05index\x12\x1f\n" +
|
||||||
"\vnotes_plain\x18\x02 \x01(\tR\n" +
|
"\vnotes_plain\x18\x02 \x01(\tR\n" +
|
||||||
"notesPlain\x12\x1b\n" +
|
"notesPlain\x12\x1b\n" +
|
||||||
"\timage_url\x18\x03 \x01(\tR\bimageUrl\"\xf6\x01\n" +
|
"\timage_url\x18\x03 \x01(\tR\bimageUrl\x12.\n" +
|
||||||
|
"\x13thumbnail_image_url\x18\x04 \x01(\tR\x11thumbnailImageUrl\"\xca\x02\n" +
|
||||||
"\tSlideDeck\x12#\n" +
|
"\tSlideDeck\x12#\n" +
|
||||||
"\rconversion_id\x18\x01 \x01(\tR\fconversionId\x12'\n" +
|
"\rconversion_id\x18\x01 \x01(\tR\fconversionId\x12'\n" +
|
||||||
"\x0fsource_filename\x18\x02 \x01(\tR\x0esourceFilename\x122\n" +
|
"\x0fsource_filename\x18\x02 \x01(\tR\x0esourceFilename\x122\n" +
|
||||||
@@ -922,12 +1091,13 @@ const file_officeconvertapi_v1_conversion_proto_rawDesc = "" +
|
|||||||
"\n" +
|
"\n" +
|
||||||
"created_at\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x12\x14\n" +
|
"created_at\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x12\x14\n" +
|
||||||
"\x05width\x18\x05 \x01(\x05R\x05width\x12\x16\n" +
|
"\x05width\x18\x05 \x01(\x05R\x05width\x12\x16\n" +
|
||||||
"\x06height\x18\x06 \x01(\x05R\x06height\"\x8d\x01\n" +
|
"\x06height\x18\x06 \x01(\x05R\x06height\x12'\n" +
|
||||||
|
"\x0fthumbnail_width\x18\a \x01(\x05R\x0ethumbnailWidth\x12)\n" +
|
||||||
|
"\x10thumbnail_height\x18\b \x01(\x05R\x0fthumbnailHeight\"\xc6\x01\n" +
|
||||||
"\x17CreateConversionRequest\x12'\n" +
|
"\x17CreateConversionRequest\x12'\n" +
|
||||||
"\x0fsource_filename\x18\x01 \x01(\tR\x0esourceFilename\x12I\n" +
|
"\x0fsource_filename\x18\x01 \x01(\tR\x0esourceFilename\x12;\n" +
|
||||||
"\n" +
|
"\x04full\x18\x02 \x01(\v2'.officeconvertapi.v1.SlideRasterOptionsR\x04full\x12E\n" +
|
||||||
"resolution\x18\x02 \x01(\x0e2).officeconvertapi.v1.ConversionResolutionR\n" +
|
"\tthumbnail\x18\x03 \x01(\v2'.officeconvertapi.v1.SlideRasterOptionsR\tthumbnail\"\xea\x01\n" +
|
||||||
"resolution\"\xea\x01\n" +
|
|
||||||
"\x18CreateConversionResponse\x12#\n" +
|
"\x18CreateConversionResponse\x12#\n" +
|
||||||
"\rconversion_id\x18\x01 \x01(\tR\fconversionId\x12#\n" +
|
"\rconversion_id\x18\x01 \x01(\tR\fconversionId\x12#\n" +
|
||||||
"\rupload_bucket\x18\x02 \x01(\tR\fuploadBucket\x12*\n" +
|
"\rupload_bucket\x18\x02 \x01(\tR\fuploadBucket\x12*\n" +
|
||||||
@@ -1002,50 +1172,55 @@ func file_officeconvertapi_v1_conversion_proto_rawDescGZIP() []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var file_officeconvertapi_v1_conversion_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
|
var file_officeconvertapi_v1_conversion_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
|
||||||
var file_officeconvertapi_v1_conversion_proto_msgTypes = make([]protoimpl.MessageInfo, 12)
|
var file_officeconvertapi_v1_conversion_proto_msgTypes = make([]protoimpl.MessageInfo, 14)
|
||||||
var file_officeconvertapi_v1_conversion_proto_goTypes = []any{
|
var file_officeconvertapi_v1_conversion_proto_goTypes = []any{
|
||||||
(ConversionStatus)(0), // 0: officeconvertapi.v1.ConversionStatus
|
(ConversionStatus)(0), // 0: officeconvertapi.v1.ConversionStatus
|
||||||
(ConversionPhase)(0), // 1: officeconvertapi.v1.ConversionPhase
|
(ConversionPhase)(0), // 1: officeconvertapi.v1.ConversionPhase
|
||||||
(ConversionResolution)(0), // 2: officeconvertapi.v1.ConversionResolution
|
(ConversionResolution)(0), // 2: officeconvertapi.v1.ConversionResolution
|
||||||
(*Slide)(nil), // 3: officeconvertapi.v1.Slide
|
(*JpegOutputOptions)(nil), // 3: officeconvertapi.v1.JpegOutputOptions
|
||||||
(*SlideDeck)(nil), // 4: officeconvertapi.v1.SlideDeck
|
(*SlideRasterOptions)(nil), // 4: officeconvertapi.v1.SlideRasterOptions
|
||||||
(*CreateConversionRequest)(nil), // 5: officeconvertapi.v1.CreateConversionRequest
|
(*Slide)(nil), // 5: officeconvertapi.v1.Slide
|
||||||
(*CreateConversionResponse)(nil), // 6: officeconvertapi.v1.CreateConversionResponse
|
(*SlideDeck)(nil), // 6: officeconvertapi.v1.SlideDeck
|
||||||
(*StartConversionRequest)(nil), // 7: officeconvertapi.v1.StartConversionRequest
|
(*CreateConversionRequest)(nil), // 7: officeconvertapi.v1.CreateConversionRequest
|
||||||
(*StartConversionResponse)(nil), // 8: officeconvertapi.v1.StartConversionResponse
|
(*CreateConversionResponse)(nil), // 8: officeconvertapi.v1.CreateConversionResponse
|
||||||
(*GetConversionStatusRequest)(nil), // 9: officeconvertapi.v1.GetConversionStatusRequest
|
(*StartConversionRequest)(nil), // 9: officeconvertapi.v1.StartConversionRequest
|
||||||
(*GetConversionStatusResponse)(nil), // 10: officeconvertapi.v1.GetConversionStatusResponse
|
(*StartConversionResponse)(nil), // 10: officeconvertapi.v1.StartConversionResponse
|
||||||
(*GetSlideDeckRequest)(nil), // 11: officeconvertapi.v1.GetSlideDeckRequest
|
(*GetConversionStatusRequest)(nil), // 11: officeconvertapi.v1.GetConversionStatusRequest
|
||||||
(*GetSlideDeckResponse)(nil), // 12: officeconvertapi.v1.GetSlideDeckResponse
|
(*GetConversionStatusResponse)(nil), // 12: officeconvertapi.v1.GetConversionStatusResponse
|
||||||
(*DeleteConversionRequest)(nil), // 13: officeconvertapi.v1.DeleteConversionRequest
|
(*GetSlideDeckRequest)(nil), // 13: officeconvertapi.v1.GetSlideDeckRequest
|
||||||
(*DeleteConversionResponse)(nil), // 14: officeconvertapi.v1.DeleteConversionResponse
|
(*GetSlideDeckResponse)(nil), // 14: officeconvertapi.v1.GetSlideDeckResponse
|
||||||
(*timestamppb.Timestamp)(nil), // 15: google.protobuf.Timestamp
|
(*DeleteConversionRequest)(nil), // 15: officeconvertapi.v1.DeleteConversionRequest
|
||||||
|
(*DeleteConversionResponse)(nil), // 16: officeconvertapi.v1.DeleteConversionResponse
|
||||||
|
(*timestamppb.Timestamp)(nil), // 17: google.protobuf.Timestamp
|
||||||
}
|
}
|
||||||
var file_officeconvertapi_v1_conversion_proto_depIdxs = []int32{
|
var file_officeconvertapi_v1_conversion_proto_depIdxs = []int32{
|
||||||
3, // 0: officeconvertapi.v1.SlideDeck.slides:type_name -> officeconvertapi.v1.Slide
|
2, // 0: officeconvertapi.v1.SlideRasterOptions.resolution:type_name -> officeconvertapi.v1.ConversionResolution
|
||||||
15, // 1: officeconvertapi.v1.SlideDeck.created_at:type_name -> google.protobuf.Timestamp
|
3, // 1: officeconvertapi.v1.SlideRasterOptions.jpeg:type_name -> officeconvertapi.v1.JpegOutputOptions
|
||||||
2, // 2: officeconvertapi.v1.CreateConversionRequest.resolution:type_name -> officeconvertapi.v1.ConversionResolution
|
5, // 2: officeconvertapi.v1.SlideDeck.slides:type_name -> officeconvertapi.v1.Slide
|
||||||
15, // 3: officeconvertapi.v1.CreateConversionResponse.expires_at:type_name -> google.protobuf.Timestamp
|
17, // 3: officeconvertapi.v1.SlideDeck.created_at:type_name -> google.protobuf.Timestamp
|
||||||
0, // 4: officeconvertapi.v1.StartConversionResponse.status:type_name -> officeconvertapi.v1.ConversionStatus
|
4, // 4: officeconvertapi.v1.CreateConversionRequest.full:type_name -> officeconvertapi.v1.SlideRasterOptions
|
||||||
0, // 5: officeconvertapi.v1.GetConversionStatusResponse.status:type_name -> officeconvertapi.v1.ConversionStatus
|
4, // 5: officeconvertapi.v1.CreateConversionRequest.thumbnail:type_name -> officeconvertapi.v1.SlideRasterOptions
|
||||||
15, // 6: officeconvertapi.v1.GetConversionStatusResponse.updated_at:type_name -> google.protobuf.Timestamp
|
17, // 6: officeconvertapi.v1.CreateConversionResponse.expires_at:type_name -> google.protobuf.Timestamp
|
||||||
1, // 7: officeconvertapi.v1.GetConversionStatusResponse.phase:type_name -> officeconvertapi.v1.ConversionPhase
|
0, // 7: officeconvertapi.v1.StartConversionResponse.status:type_name -> officeconvertapi.v1.ConversionStatus
|
||||||
4, // 8: officeconvertapi.v1.GetSlideDeckResponse.slide_deck:type_name -> officeconvertapi.v1.SlideDeck
|
0, // 8: officeconvertapi.v1.GetConversionStatusResponse.status:type_name -> officeconvertapi.v1.ConversionStatus
|
||||||
5, // 9: officeconvertapi.v1.ConversionService.CreateConversion:input_type -> officeconvertapi.v1.CreateConversionRequest
|
17, // 9: officeconvertapi.v1.GetConversionStatusResponse.updated_at:type_name -> google.protobuf.Timestamp
|
||||||
7, // 10: officeconvertapi.v1.ConversionService.StartConversion:input_type -> officeconvertapi.v1.StartConversionRequest
|
1, // 10: officeconvertapi.v1.GetConversionStatusResponse.phase:type_name -> officeconvertapi.v1.ConversionPhase
|
||||||
9, // 11: officeconvertapi.v1.ConversionService.GetConversionStatus:input_type -> officeconvertapi.v1.GetConversionStatusRequest
|
6, // 11: officeconvertapi.v1.GetSlideDeckResponse.slide_deck:type_name -> officeconvertapi.v1.SlideDeck
|
||||||
11, // 12: officeconvertapi.v1.ConversionService.GetSlideDeck:input_type -> officeconvertapi.v1.GetSlideDeckRequest
|
7, // 12: officeconvertapi.v1.ConversionService.CreateConversion:input_type -> officeconvertapi.v1.CreateConversionRequest
|
||||||
13, // 13: officeconvertapi.v1.ConversionService.DeleteConversion:input_type -> officeconvertapi.v1.DeleteConversionRequest
|
9, // 13: officeconvertapi.v1.ConversionService.StartConversion:input_type -> officeconvertapi.v1.StartConversionRequest
|
||||||
6, // 14: officeconvertapi.v1.ConversionService.CreateConversion:output_type -> officeconvertapi.v1.CreateConversionResponse
|
11, // 14: officeconvertapi.v1.ConversionService.GetConversionStatus:input_type -> officeconvertapi.v1.GetConversionStatusRequest
|
||||||
8, // 15: officeconvertapi.v1.ConversionService.StartConversion:output_type -> officeconvertapi.v1.StartConversionResponse
|
13, // 15: officeconvertapi.v1.ConversionService.GetSlideDeck:input_type -> officeconvertapi.v1.GetSlideDeckRequest
|
||||||
10, // 16: officeconvertapi.v1.ConversionService.GetConversionStatus:output_type -> officeconvertapi.v1.GetConversionStatusResponse
|
15, // 16: officeconvertapi.v1.ConversionService.DeleteConversion:input_type -> officeconvertapi.v1.DeleteConversionRequest
|
||||||
12, // 17: officeconvertapi.v1.ConversionService.GetSlideDeck:output_type -> officeconvertapi.v1.GetSlideDeckResponse
|
8, // 17: officeconvertapi.v1.ConversionService.CreateConversion:output_type -> officeconvertapi.v1.CreateConversionResponse
|
||||||
14, // 18: officeconvertapi.v1.ConversionService.DeleteConversion:output_type -> officeconvertapi.v1.DeleteConversionResponse
|
10, // 18: officeconvertapi.v1.ConversionService.StartConversion:output_type -> officeconvertapi.v1.StartConversionResponse
|
||||||
14, // [14:19] is the sub-list for method output_type
|
12, // 19: officeconvertapi.v1.ConversionService.GetConversionStatus:output_type -> officeconvertapi.v1.GetConversionStatusResponse
|
||||||
9, // [9:14] is the sub-list for method input_type
|
14, // 20: officeconvertapi.v1.ConversionService.GetSlideDeck:output_type -> officeconvertapi.v1.GetSlideDeckResponse
|
||||||
9, // [9:9] is the sub-list for extension type_name
|
16, // 21: officeconvertapi.v1.ConversionService.DeleteConversion:output_type -> officeconvertapi.v1.DeleteConversionResponse
|
||||||
9, // [9:9] is the sub-list for extension extendee
|
17, // [17:22] is the sub-list for method output_type
|
||||||
0, // [0:9] is the sub-list for field type_name
|
12, // [12:17] is the sub-list for method input_type
|
||||||
|
12, // [12:12] is the sub-list for extension type_name
|
||||||
|
12, // [12:12] is the sub-list for extension extendee
|
||||||
|
0, // [0:12] is the sub-list for field type_name
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() { file_officeconvertapi_v1_conversion_proto_init() }
|
func init() { file_officeconvertapi_v1_conversion_proto_init() }
|
||||||
@@ -1053,13 +1228,16 @@ func file_officeconvertapi_v1_conversion_proto_init() {
|
|||||||
if File_officeconvertapi_v1_conversion_proto != nil {
|
if File_officeconvertapi_v1_conversion_proto != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
file_officeconvertapi_v1_conversion_proto_msgTypes[1].OneofWrappers = []any{
|
||||||
|
(*SlideRasterOptions_Jpeg)(nil),
|
||||||
|
}
|
||||||
type x struct{}
|
type x struct{}
|
||||||
out := protoimpl.TypeBuilder{
|
out := protoimpl.TypeBuilder{
|
||||||
File: protoimpl.DescBuilder{
|
File: protoimpl.DescBuilder{
|
||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_officeconvertapi_v1_conversion_proto_rawDesc), len(file_officeconvertapi_v1_conversion_proto_rawDesc)),
|
RawDescriptor: unsafe.Slice(unsafe.StringData(file_officeconvertapi_v1_conversion_proto_rawDesc), len(file_officeconvertapi_v1_conversion_proto_rawDesc)),
|
||||||
NumEnums: 3,
|
NumEnums: 3,
|
||||||
NumMessages: 12,
|
NumMessages: 14,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 1,
|
NumServices: 1,
|
||||||
},
|
},
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -53,39 +53,61 @@ CONVERSION_RESOLUTION_FHD: ConversionResolution
|
|||||||
CONVERSION_RESOLUTION_QHD: ConversionResolution
|
CONVERSION_RESOLUTION_QHD: ConversionResolution
|
||||||
CONVERSION_RESOLUTION_UHD: ConversionResolution
|
CONVERSION_RESOLUTION_UHD: ConversionResolution
|
||||||
|
|
||||||
|
class JpegOutputOptions(_message.Message):
|
||||||
|
__slots__ = ("quality",)
|
||||||
|
QUALITY_FIELD_NUMBER: _ClassVar[int]
|
||||||
|
quality: int
|
||||||
|
def __init__(self, quality: _Optional[int] = ...) -> None: ...
|
||||||
|
|
||||||
|
class SlideRasterOptions(_message.Message):
|
||||||
|
__slots__ = ("resolution", "jpeg")
|
||||||
|
RESOLUTION_FIELD_NUMBER: _ClassVar[int]
|
||||||
|
JPEG_FIELD_NUMBER: _ClassVar[int]
|
||||||
|
resolution: ConversionResolution
|
||||||
|
jpeg: JpegOutputOptions
|
||||||
|
def __init__(self, resolution: _Optional[_Union[ConversionResolution, str]] = ..., jpeg: _Optional[_Union[JpegOutputOptions, _Mapping]] = ...) -> None: ...
|
||||||
|
|
||||||
class Slide(_message.Message):
|
class Slide(_message.Message):
|
||||||
__slots__ = ("index", "notes_plain", "image_url")
|
__slots__ = ("index", "notes_plain", "image_url", "thumbnail_image_url")
|
||||||
INDEX_FIELD_NUMBER: _ClassVar[int]
|
INDEX_FIELD_NUMBER: _ClassVar[int]
|
||||||
NOTES_PLAIN_FIELD_NUMBER: _ClassVar[int]
|
NOTES_PLAIN_FIELD_NUMBER: _ClassVar[int]
|
||||||
IMAGE_URL_FIELD_NUMBER: _ClassVar[int]
|
IMAGE_URL_FIELD_NUMBER: _ClassVar[int]
|
||||||
|
THUMBNAIL_IMAGE_URL_FIELD_NUMBER: _ClassVar[int]
|
||||||
index: int
|
index: int
|
||||||
notes_plain: str
|
notes_plain: str
|
||||||
image_url: str
|
image_url: str
|
||||||
def __init__(self, index: _Optional[int] = ..., notes_plain: _Optional[str] = ..., image_url: _Optional[str] = ...) -> None: ...
|
thumbnail_image_url: str
|
||||||
|
def __init__(self, index: _Optional[int] = ..., notes_plain: _Optional[str] = ..., image_url: _Optional[str] = ..., thumbnail_image_url: _Optional[str] = ...) -> None: ...
|
||||||
|
|
||||||
class SlideDeck(_message.Message):
|
class SlideDeck(_message.Message):
|
||||||
__slots__ = ("conversion_id", "source_filename", "slides", "created_at", "width", "height")
|
__slots__ = ("conversion_id", "source_filename", "slides", "created_at", "width", "height", "thumbnail_width", "thumbnail_height")
|
||||||
CONVERSION_ID_FIELD_NUMBER: _ClassVar[int]
|
CONVERSION_ID_FIELD_NUMBER: _ClassVar[int]
|
||||||
SOURCE_FILENAME_FIELD_NUMBER: _ClassVar[int]
|
SOURCE_FILENAME_FIELD_NUMBER: _ClassVar[int]
|
||||||
SLIDES_FIELD_NUMBER: _ClassVar[int]
|
SLIDES_FIELD_NUMBER: _ClassVar[int]
|
||||||
CREATED_AT_FIELD_NUMBER: _ClassVar[int]
|
CREATED_AT_FIELD_NUMBER: _ClassVar[int]
|
||||||
WIDTH_FIELD_NUMBER: _ClassVar[int]
|
WIDTH_FIELD_NUMBER: _ClassVar[int]
|
||||||
HEIGHT_FIELD_NUMBER: _ClassVar[int]
|
HEIGHT_FIELD_NUMBER: _ClassVar[int]
|
||||||
|
THUMBNAIL_WIDTH_FIELD_NUMBER: _ClassVar[int]
|
||||||
|
THUMBNAIL_HEIGHT_FIELD_NUMBER: _ClassVar[int]
|
||||||
conversion_id: str
|
conversion_id: str
|
||||||
source_filename: str
|
source_filename: str
|
||||||
slides: _containers.RepeatedCompositeFieldContainer[Slide]
|
slides: _containers.RepeatedCompositeFieldContainer[Slide]
|
||||||
created_at: _timestamp_pb2.Timestamp
|
created_at: _timestamp_pb2.Timestamp
|
||||||
width: int
|
width: int
|
||||||
height: int
|
height: int
|
||||||
def __init__(self, conversion_id: _Optional[str] = ..., source_filename: _Optional[str] = ..., slides: _Optional[_Iterable[_Union[Slide, _Mapping]]] = ..., created_at: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ..., width: _Optional[int] = ..., height: _Optional[int] = ...) -> None: ...
|
thumbnail_width: int
|
||||||
|
thumbnail_height: int
|
||||||
|
def __init__(self, conversion_id: _Optional[str] = ..., source_filename: _Optional[str] = ..., slides: _Optional[_Iterable[_Union[Slide, _Mapping]]] = ..., created_at: _Optional[_Union[datetime.datetime, _timestamp_pb2.Timestamp, _Mapping]] = ..., width: _Optional[int] = ..., height: _Optional[int] = ..., thumbnail_width: _Optional[int] = ..., thumbnail_height: _Optional[int] = ...) -> None: ...
|
||||||
|
|
||||||
class CreateConversionRequest(_message.Message):
|
class CreateConversionRequest(_message.Message):
|
||||||
__slots__ = ("source_filename", "resolution")
|
__slots__ = ("source_filename", "full", "thumbnail")
|
||||||
SOURCE_FILENAME_FIELD_NUMBER: _ClassVar[int]
|
SOURCE_FILENAME_FIELD_NUMBER: _ClassVar[int]
|
||||||
RESOLUTION_FIELD_NUMBER: _ClassVar[int]
|
FULL_FIELD_NUMBER: _ClassVar[int]
|
||||||
|
THUMBNAIL_FIELD_NUMBER: _ClassVar[int]
|
||||||
source_filename: str
|
source_filename: str
|
||||||
resolution: ConversionResolution
|
full: SlideRasterOptions
|
||||||
def __init__(self, source_filename: _Optional[str] = ..., resolution: _Optional[_Union[ConversionResolution, str]] = ...) -> None: ...
|
thumbnail: SlideRasterOptions
|
||||||
|
def __init__(self, source_filename: _Optional[str] = ..., full: _Optional[_Union[SlideRasterOptions, _Mapping]] = ..., thumbnail: _Optional[_Union[SlideRasterOptions, _Mapping]] = ...) -> None: ...
|
||||||
|
|
||||||
class CreateConversionResponse(_message.Message):
|
class CreateConversionResponse(_message.Message):
|
||||||
__slots__ = ("conversion_id", "upload_bucket", "upload_object_key", "upload_url", "expires_at")
|
__slots__ = ("conversion_id", "upload_bucket", "upload_object_key", "upload_url", "expires_at")
|
||||||
|
|||||||
@@ -53,11 +53,29 @@ enum ConversionResolution {
|
|||||||
CONVERSION_RESOLUTION_UHD = 5;
|
CONVERSION_RESOLUTION_UHD = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JpegOutputOptions configures JPEG-specific encoding controls.
|
||||||
|
message JpegOutputOptions {
|
||||||
|
// JPEG quality from 1..100. 0 means server default.
|
||||||
|
int32 quality = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SlideRasterOptions defines rendering settings for a raster output tier.
|
||||||
|
message SlideRasterOptions {
|
||||||
|
// Output resolution preset. UNSPECIFIED means server default for the tier.
|
||||||
|
ConversionResolution resolution = 1;
|
||||||
|
oneof format {
|
||||||
|
JpegOutputOptions jpeg = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Slide contains extracted notes and the rendered image URL for one slide.
|
// Slide contains extracted notes and the rendered image URL for one slide.
|
||||||
message Slide {
|
message Slide {
|
||||||
int32 index = 1;
|
int32 index = 1;
|
||||||
string notes_plain = 2;
|
string notes_plain = 2;
|
||||||
|
// Full-size rendered image URL.
|
||||||
string image_url = 3;
|
string image_url = 3;
|
||||||
|
// Thumbnail rendered image URL.
|
||||||
|
string thumbnail_image_url = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SlideDeck is the final structured conversion artifact.
|
// SlideDeck is the final structured conversion artifact.
|
||||||
@@ -67,14 +85,21 @@ message SlideDeck {
|
|||||||
string source_filename = 2;
|
string source_filename = 2;
|
||||||
repeated Slide slides = 3;
|
repeated Slide slides = 3;
|
||||||
google.protobuf.Timestamp created_at = 4;
|
google.protobuf.Timestamp created_at = 4;
|
||||||
|
// Full-size raster width in pixels.
|
||||||
int32 width = 5;
|
int32 width = 5;
|
||||||
|
// Full-size raster height in pixels.
|
||||||
int32 height = 6;
|
int32 height = 6;
|
||||||
|
// Thumbnail raster width in pixels.
|
||||||
|
int32 thumbnail_width = 7;
|
||||||
|
// Thumbnail raster height in pixels.
|
||||||
|
int32 thumbnail_height = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateConversionRequest starts a conversion session.
|
// CreateConversionRequest starts a conversion session.
|
||||||
message CreateConversionRequest {
|
message CreateConversionRequest {
|
||||||
string source_filename = 1;
|
string source_filename = 1;
|
||||||
ConversionResolution resolution = 2;
|
SlideRasterOptions full = 2;
|
||||||
|
SlideRasterOptions thumbnail = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateConversionResponse returns upload details for the session.
|
// CreateConversionResponse returns upload details for the session.
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ class SlideArtifact:
|
|||||||
|
|
||||||
index: int
|
index: int
|
||||||
image_path: Path
|
image_path: Path
|
||||||
|
thumbnail_path: Path
|
||||||
notes_plain: str
|
notes_plain: str
|
||||||
|
|
||||||
|
|
||||||
@@ -30,6 +31,8 @@ class SlideDeckResult:
|
|||||||
slides: list[SlideArtifact]
|
slides: list[SlideArtifact]
|
||||||
width: int
|
width: int
|
||||||
height: int
|
height: int
|
||||||
|
thumbnail_width: int
|
||||||
|
thumbnail_height: int
|
||||||
inferred_dpi: int
|
inferred_dpi: int
|
||||||
pptx_to_pdf_timeout_s: int
|
pptx_to_pdf_timeout_s: int
|
||||||
pdf_to_images_timeout_s: int
|
pdf_to_images_timeout_s: int
|
||||||
@@ -133,6 +136,7 @@ def render_pdf_to_images(
|
|||||||
target_width: int | None = None,
|
target_width: int | None = None,
|
||||||
target_height: int | None = None,
|
target_height: int | None = None,
|
||||||
image_format: str = "png",
|
image_format: str = "png",
|
||||||
|
jpeg_quality: int | None = None,
|
||||||
timeout_s: int = 120,
|
timeout_s: int = 120,
|
||||||
total_pages: int | None = None,
|
total_pages: int | None = None,
|
||||||
operation_timeout_s: int | None = None,
|
operation_timeout_s: int | None = None,
|
||||||
@@ -162,6 +166,15 @@ def render_pdf_to_images(
|
|||||||
raise ValueError("target_width must be greater than zero")
|
raise ValueError("target_width must be greater than zero")
|
||||||
if target_height is not None and target_height <= 0:
|
if target_height is not None and target_height <= 0:
|
||||||
raise ValueError("target_height must be greater than zero")
|
raise ValueError("target_height must be greater than zero")
|
||||||
|
normalized_image_format = _normalize_image_format(image_format)
|
||||||
|
output_suffix = _image_output_suffix(normalized_image_format)
|
||||||
|
normalized_jpeg_quality = _normalize_jpeg_quality(jpeg_quality)
|
||||||
|
jpeg_options_args: list[str] = []
|
||||||
|
if normalized_jpeg_quality is not None and normalized_image_format in {
|
||||||
|
"jpeg",
|
||||||
|
"jpegcmyk",
|
||||||
|
}:
|
||||||
|
jpeg_options_args = ["-jpegopt", f"quality={normalized_jpeg_quality}"]
|
||||||
|
|
||||||
out_dir.mkdir(parents=True, exist_ok=True)
|
out_dir.mkdir(parents=True, exist_ok=True)
|
||||||
scale_args: list[str] = []
|
scale_args: list[str] = []
|
||||||
@@ -174,7 +187,8 @@ def render_pdf_to_images(
|
|||||||
"-r",
|
"-r",
|
||||||
str(dpi),
|
str(dpi),
|
||||||
*scale_args,
|
*scale_args,
|
||||||
f"-{image_format}",
|
*jpeg_options_args,
|
||||||
|
f"-{normalized_image_format}",
|
||||||
str(pdf_path.resolve()),
|
str(pdf_path.resolve()),
|
||||||
str(prefix_path),
|
str(prefix_path),
|
||||||
]
|
]
|
||||||
@@ -198,7 +212,7 @@ def render_pdf_to_images(
|
|||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
f"Poppler rasterization failed: {completed.stderr.strip() or completed.stdout.strip()}"
|
f"Poppler rasterization failed: {completed.stderr.strip() or completed.stdout.strip()}"
|
||||||
)
|
)
|
||||||
images = sorted(out_dir.glob(f"slide-*.{image_format}"))
|
images = sorted(out_dir.glob(f"slide-*.{output_suffix}"))
|
||||||
else:
|
else:
|
||||||
if total_pages < 0:
|
if total_pages < 0:
|
||||||
raise ValueError("total_pages must be zero or greater")
|
raise ValueError("total_pages must be zero or greater")
|
||||||
@@ -210,7 +224,8 @@ def render_pdf_to_images(
|
|||||||
"-r",
|
"-r",
|
||||||
str(dpi),
|
str(dpi),
|
||||||
*scale_args,
|
*scale_args,
|
||||||
f"-{image_format}",
|
*jpeg_options_args,
|
||||||
|
f"-{normalized_image_format}",
|
||||||
"-f",
|
"-f",
|
||||||
str(page_index),
|
str(page_index),
|
||||||
"-l",
|
"-l",
|
||||||
@@ -246,7 +261,7 @@ def render_pdf_to_images(
|
|||||||
"Poppler rasterization failed on page "
|
"Poppler rasterization failed on page "
|
||||||
f"{page_index}: {completed.stderr.strip() or completed.stdout.strip()}"
|
f"{page_index}: {completed.stderr.strip() or completed.stdout.strip()}"
|
||||||
)
|
)
|
||||||
image_path = page_prefix.with_suffix(f".{image_format}")
|
image_path = page_prefix.with_suffix(f".{output_suffix}")
|
||||||
if not image_path.exists():
|
if not image_path.exists():
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
f"Poppler did not create expected page image: {image_path}"
|
f"Poppler did not create expected page image: {image_path}"
|
||||||
@@ -289,8 +304,10 @@ def convert_pptx_to_slidedeck(
|
|||||||
pptx_path: Path,
|
pptx_path: Path,
|
||||||
work_dir: Path,
|
work_dir: Path,
|
||||||
*,
|
*,
|
||||||
resolution: str = RESOLUTION_FHD,
|
full_resolution: str = RESOLUTION_FHD,
|
||||||
image_format: str = "png",
|
thumbnail_resolution: str = RESOLUTION_SD,
|
||||||
|
full_jpeg_quality: int | None = None,
|
||||||
|
thumbnail_jpeg_quality: int | None = None,
|
||||||
pptx_to_pdf_timeout_s: int = 180,
|
pptx_to_pdf_timeout_s: int = 180,
|
||||||
pdf_to_images_timeout_s: int = 1800,
|
pdf_to_images_timeout_s: int = 1800,
|
||||||
pptx_to_pdf_base_timeout_s: int = 45,
|
pptx_to_pdf_base_timeout_s: int = 45,
|
||||||
@@ -308,8 +325,10 @@ def convert_pptx_to_slidedeck(
|
|||||||
Args:
|
Args:
|
||||||
pptx_path: Source `.pptx` path.
|
pptx_path: Source `.pptx` path.
|
||||||
work_dir: Scratch directory for generated outputs.
|
work_dir: Scratch directory for generated outputs.
|
||||||
resolution: Output resolution preset (`sd`, `hd`, `fhd`, `qhd`, `uhd`).
|
full_resolution: Full-size output resolution preset (`sd`, `hd`, `fhd`, `qhd`, `uhd`).
|
||||||
image_format: Output image format accepted by `pdftoppm`.
|
thumbnail_resolution: Thumbnail output resolution preset (`sd`, `hd`, `fhd`, `qhd`, `uhd`).
|
||||||
|
full_jpeg_quality: Full-size JPEG quality (`1..100`); `None`/`0` means default.
|
||||||
|
thumbnail_jpeg_quality: Thumbnail JPEG quality (`1..100`); `None`/`0` means default.
|
||||||
pptx_to_pdf_timeout_s: Timeout in seconds for the LibreOffice subprocess.
|
pptx_to_pdf_timeout_s: Timeout in seconds for the LibreOffice subprocess.
|
||||||
pdf_to_images_timeout_s: Timeout in seconds for the Poppler subprocess.
|
pdf_to_images_timeout_s: Timeout in seconds for the Poppler subprocess.
|
||||||
|
|
||||||
@@ -322,7 +341,8 @@ def convert_pptx_to_slidedeck(
|
|||||||
work_dir = work_dir.resolve()
|
work_dir = work_dir.resolve()
|
||||||
work_dir.mkdir(parents=True, exist_ok=True)
|
work_dir.mkdir(parents=True, exist_ok=True)
|
||||||
pdf_path = work_dir / f"{pptx_path.stem}.pdf"
|
pdf_path = work_dir / f"{pptx_path.stem}.pdf"
|
||||||
image_dir = work_dir / "slides"
|
full_image_dir = work_dir / "slides_full"
|
||||||
|
thumbnail_image_dir = work_dir / "slides_thumb"
|
||||||
|
|
||||||
_emit_progress(progress_callback, PHASE_EXTRACTING_NOTES, 0, 1)
|
_emit_progress(progress_callback, PHASE_EXTRACTING_NOTES, 0, 1)
|
||||||
notes = extract_slide_notes(pptx_path)
|
notes = extract_slide_notes(pptx_path)
|
||||||
@@ -331,7 +351,12 @@ def convert_pptx_to_slidedeck(
|
|||||||
output_width, output_height = _infer_output_dimensions_from_slide_size(
|
output_width, output_height = _infer_output_dimensions_from_slide_size(
|
||||||
slide_width=slide_width,
|
slide_width=slide_width,
|
||||||
slide_height=slide_height,
|
slide_height=slide_height,
|
||||||
resolution=resolution,
|
resolution=full_resolution,
|
||||||
|
)
|
||||||
|
thumbnail_width, thumbnail_height = _infer_output_dimensions_from_slide_size(
|
||||||
|
slide_width=slide_width,
|
||||||
|
slide_height=slide_height,
|
||||||
|
resolution=thumbnail_resolution,
|
||||||
)
|
)
|
||||||
inferred_dpi = infer_minimum_raster_dpi(
|
inferred_dpi = infer_minimum_raster_dpi(
|
||||||
slide_width_emu=slide_width,
|
slide_width_emu=slide_width,
|
||||||
@@ -339,6 +364,12 @@ def convert_pptx_to_slidedeck(
|
|||||||
output_width_px=output_width,
|
output_width_px=output_width,
|
||||||
output_height_px=output_height,
|
output_height_px=output_height,
|
||||||
)
|
)
|
||||||
|
thumbnail_inferred_dpi = infer_minimum_raster_dpi(
|
||||||
|
slide_width_emu=slide_width,
|
||||||
|
slide_height_emu=slide_height,
|
||||||
|
output_width_px=thumbnail_width,
|
||||||
|
output_height_px=thumbnail_height,
|
||||||
|
)
|
||||||
slide_count = len(notes)
|
slide_count = len(notes)
|
||||||
pptx_to_pdf_timeout = _compute_adaptive_timeout(
|
pptx_to_pdf_timeout = _compute_adaptive_timeout(
|
||||||
slide_count=slide_count,
|
slide_count=slide_count,
|
||||||
@@ -347,7 +378,7 @@ def convert_pptx_to_slidedeck(
|
|||||||
per_slide_timeout_s=pptx_to_pdf_per_slide_timeout_s,
|
per_slide_timeout_s=pptx_to_pdf_per_slide_timeout_s,
|
||||||
)
|
)
|
||||||
pdf_to_images_timeout = _compute_adaptive_timeout(
|
pdf_to_images_timeout = _compute_adaptive_timeout(
|
||||||
slide_count=slide_count,
|
slide_count=slide_count * 2,
|
||||||
timeout_cap_s=pdf_to_images_timeout_s,
|
timeout_cap_s=pdf_to_images_timeout_s,
|
||||||
base_timeout_s=pdf_to_images_base_timeout_s,
|
base_timeout_s=pdf_to_images_base_timeout_s,
|
||||||
per_slide_timeout_s=pdf_to_images_per_slide_timeout_s,
|
per_slide_timeout_s=pdf_to_images_per_slide_timeout_s,
|
||||||
@@ -357,34 +388,43 @@ def convert_pptx_to_slidedeck(
|
|||||||
convert_pptx_to_pdf(pptx_path, pdf_path, timeout_s=pptx_to_pdf_timeout)
|
convert_pptx_to_pdf(pptx_path, pdf_path, timeout_s=pptx_to_pdf_timeout)
|
||||||
_emit_progress(progress_callback, PHASE_PPTX_TO_PDF, 1, 1)
|
_emit_progress(progress_callback, PHASE_PPTX_TO_PDF, 1, 1)
|
||||||
|
|
||||||
_emit_progress(progress_callback, PHASE_PDF_TO_IMAGES, 0, slide_count)
|
raster_steps = slide_count * 2
|
||||||
|
_emit_progress(progress_callback, PHASE_PDF_TO_IMAGES, 0, raster_steps)
|
||||||
pdf_to_images_page_timeout = _compute_page_timeout(
|
pdf_to_images_page_timeout = _compute_page_timeout(
|
||||||
total_timeout_s=pdf_to_images_timeout,
|
total_timeout_s=pdf_to_images_timeout,
|
||||||
page_count=slide_count,
|
page_count=raster_steps,
|
||||||
base_timeout_s=pdf_to_images_base_timeout_s,
|
base_timeout_s=pdf_to_images_base_timeout_s,
|
||||||
)
|
)
|
||||||
logger.info(
|
logger.info(
|
||||||
"Conversion plan source=%s slides=%d inferred_dpi=%d image_format=%s "
|
"Conversion plan source=%s slides=%d image_format=%s "
|
||||||
"resolution=%s output_size=%dx%d "
|
"full[resolution=%s size=%dx%d dpi=%d jpeg_quality=%s] "
|
||||||
|
"thumbnail[resolution=%s size=%dx%d dpi=%d jpeg_quality=%s] "
|
||||||
"computed_timeouts_s[pptx_to_pdf_total=%d,pdf_to_images_total=%d,pdf_to_images_per_page=%d]",
|
"computed_timeouts_s[pptx_to_pdf_total=%d,pdf_to_images_total=%d,pdf_to_images_per_page=%d]",
|
||||||
pptx_path.name,
|
pptx_path.name,
|
||||||
slide_count,
|
slide_count,
|
||||||
inferred_dpi,
|
"jpeg",
|
||||||
image_format,
|
full_resolution,
|
||||||
resolution,
|
|
||||||
output_width,
|
output_width,
|
||||||
output_height,
|
output_height,
|
||||||
|
inferred_dpi,
|
||||||
|
str(full_jpeg_quality if full_jpeg_quality is not None else "default"),
|
||||||
|
thumbnail_resolution,
|
||||||
|
thumbnail_width,
|
||||||
|
thumbnail_height,
|
||||||
|
thumbnail_inferred_dpi,
|
||||||
|
str(thumbnail_jpeg_quality if thumbnail_jpeg_quality is not None else "default"),
|
||||||
pptx_to_pdf_timeout,
|
pptx_to_pdf_timeout,
|
||||||
pdf_to_images_timeout,
|
pdf_to_images_timeout,
|
||||||
pdf_to_images_page_timeout,
|
pdf_to_images_page_timeout,
|
||||||
)
|
)
|
||||||
image_paths = render_pdf_to_images(
|
full_image_paths = render_pdf_to_images(
|
||||||
pdf_path,
|
pdf_path,
|
||||||
image_dir,
|
full_image_dir,
|
||||||
dpi=inferred_dpi,
|
dpi=inferred_dpi,
|
||||||
target_width=output_width,
|
target_width=output_width,
|
||||||
target_height=output_height,
|
target_height=output_height,
|
||||||
image_format=image_format,
|
image_format="jpeg",
|
||||||
|
jpeg_quality=full_jpeg_quality,
|
||||||
timeout_s=pdf_to_images_page_timeout,
|
timeout_s=pdf_to_images_page_timeout,
|
||||||
total_pages=slide_count,
|
total_pages=slide_count,
|
||||||
operation_timeout_s=pdf_to_images_timeout,
|
operation_timeout_s=pdf_to_images_timeout,
|
||||||
@@ -395,22 +435,55 @@ def convert_pptx_to_slidedeck(
|
|||||||
max_pages,
|
max_pages,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
thumbnail_image_paths = render_pdf_to_images(
|
||||||
|
pdf_path,
|
||||||
|
thumbnail_image_dir,
|
||||||
|
dpi=thumbnail_inferred_dpi,
|
||||||
|
target_width=thumbnail_width,
|
||||||
|
target_height=thumbnail_height,
|
||||||
|
image_format="jpeg",
|
||||||
|
jpeg_quality=thumbnail_jpeg_quality,
|
||||||
|
timeout_s=pdf_to_images_page_timeout,
|
||||||
|
total_pages=slide_count,
|
||||||
|
operation_timeout_s=pdf_to_images_timeout,
|
||||||
|
page_progress_callback=lambda current, max_pages: _emit_progress(
|
||||||
|
progress_callback,
|
||||||
|
PHASE_PDF_TO_IMAGES,
|
||||||
|
slide_count + current,
|
||||||
|
slide_count + max_pages,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
if len(image_paths) != len(notes):
|
if len(full_image_paths) != len(notes):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"rendered slide count does not match note count: "
|
"rendered full-size slide count does not match note count: "
|
||||||
f"{len(image_paths)} image(s) vs {len(notes)} note entries"
|
f"{len(full_image_paths)} image(s) vs {len(notes)} note entries"
|
||||||
|
)
|
||||||
|
if len(thumbnail_image_paths) != len(notes):
|
||||||
|
raise ValueError(
|
||||||
|
"rendered thumbnail slide count does not match note count: "
|
||||||
|
f"{len(thumbnail_image_paths)} image(s) vs {len(notes)} note entries"
|
||||||
)
|
)
|
||||||
|
|
||||||
slides = [
|
slides = [
|
||||||
SlideArtifact(index=index, image_path=image_path, notes_plain=note)
|
SlideArtifact(
|
||||||
for index, (image_path, note) in enumerate(zip(image_paths, notes), start=1)
|
index=index,
|
||||||
|
image_path=image_path,
|
||||||
|
thumbnail_path=thumbnail_path,
|
||||||
|
notes_plain=note,
|
||||||
|
)
|
||||||
|
for index, (image_path, thumbnail_path, note) in enumerate(
|
||||||
|
zip(full_image_paths, thumbnail_image_paths, notes),
|
||||||
|
start=1,
|
||||||
|
)
|
||||||
]
|
]
|
||||||
return SlideDeckResult(
|
return SlideDeckResult(
|
||||||
source_filename=pptx_path.name,
|
source_filename=pptx_path.name,
|
||||||
slides=slides,
|
slides=slides,
|
||||||
width=output_width,
|
width=output_width,
|
||||||
height=output_height,
|
height=output_height,
|
||||||
|
thumbnail_width=thumbnail_width,
|
||||||
|
thumbnail_height=thumbnail_height,
|
||||||
inferred_dpi=inferred_dpi,
|
inferred_dpi=inferred_dpi,
|
||||||
pptx_to_pdf_timeout_s=pptx_to_pdf_timeout,
|
pptx_to_pdf_timeout_s=pptx_to_pdf_timeout,
|
||||||
pdf_to_images_timeout_s=pdf_to_images_timeout,
|
pdf_to_images_timeout_s=pdf_to_images_timeout,
|
||||||
@@ -511,6 +584,30 @@ def _compute_page_timeout(
|
|||||||
return max(base_timeout_s, timeout)
|
return max(base_timeout_s, timeout)
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_image_format(image_format: str) -> str:
|
||||||
|
"""Normalize image format aliases accepted by Poppler."""
|
||||||
|
normalized = image_format.strip().lower()
|
||||||
|
if normalized == "jpg":
|
||||||
|
return "jpeg"
|
||||||
|
return normalized
|
||||||
|
|
||||||
|
|
||||||
|
def _image_output_suffix(image_format: str) -> str:
|
||||||
|
"""Return output filename suffix for a normalized Poppler image format."""
|
||||||
|
if image_format in {"jpeg", "jpegcmyk"}:
|
||||||
|
return "jpg"
|
||||||
|
return image_format
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_jpeg_quality(jpeg_quality: int | None) -> int | None:
|
||||||
|
"""Normalize optional JPEG quality; 0 means server/default quality."""
|
||||||
|
if jpeg_quality is None or jpeg_quality == 0:
|
||||||
|
return None
|
||||||
|
if 1 <= jpeg_quality <= 100:
|
||||||
|
return jpeg_quality
|
||||||
|
raise ValueError("jpeg_quality must be 0 or between 1 and 100")
|
||||||
|
|
||||||
|
|
||||||
def _emit_progress(
|
def _emit_progress(
|
||||||
progress_callback: ProgressCallback | None,
|
progress_callback: ProgressCallback | None,
|
||||||
phase: str,
|
phase: str,
|
||||||
|
|||||||
@@ -19,7 +19,10 @@ class ConversionSession:
|
|||||||
|
|
||||||
conversion_id: str
|
conversion_id: str
|
||||||
source_filename: str
|
source_filename: str
|
||||||
resolution: conversion_pb2.ConversionResolution
|
full_resolution: conversion_pb2.ConversionResolution
|
||||||
|
thumbnail_resolution: conversion_pb2.ConversionResolution
|
||||||
|
full_jpeg_quality: int
|
||||||
|
thumbnail_jpeg_quality: int
|
||||||
bucket_name: str
|
bucket_name: str
|
||||||
upload_object_key: str
|
upload_object_key: str
|
||||||
status: conversion_pb2.ConversionStatus
|
status: conversion_pb2.ConversionStatus
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ _RESOLUTION_PRESET_BY_PROTO = {
|
|||||||
conversion_pb2.CONVERSION_RESOLUTION_QHD: RESOLUTION_QHD,
|
conversion_pb2.CONVERSION_RESOLUTION_QHD: RESOLUTION_QHD,
|
||||||
conversion_pb2.CONVERSION_RESOLUTION_UHD: RESOLUTION_UHD,
|
conversion_pb2.CONVERSION_RESOLUTION_UHD: RESOLUTION_UHD,
|
||||||
}
|
}
|
||||||
|
_DEFAULT_FULL_RESOLUTION = conversion_pb2.CONVERSION_RESOLUTION_FHD
|
||||||
|
_DEFAULT_THUMBNAIL_RESOLUTION = conversion_pb2.CONVERSION_RESOLUTION_SD
|
||||||
|
_DEFAULT_FULL_JPEG_QUALITY = 85
|
||||||
|
_DEFAULT_THUMBNAIL_JPEG_QUALITY = 75
|
||||||
|
|
||||||
|
|
||||||
class ConversionServiceImpl(conversion_connect.ConversionService):
|
class ConversionServiceImpl(conversion_connect.ConversionService):
|
||||||
@@ -69,11 +73,18 @@ class ConversionServiceImpl(conversion_connect.ConversionService):
|
|||||||
raise ConnectError(Code.INVALID_ARGUMENT, "source_filename is required")
|
raise ConnectError(Code.INVALID_ARGUMENT, "source_filename is required")
|
||||||
if not source_filename.lower().endswith(".pptx"):
|
if not source_filename.lower().endswith(".pptx"):
|
||||||
raise ConnectError(Code.INVALID_ARGUMENT, "only .pptx input is supported")
|
raise ConnectError(Code.INVALID_ARGUMENT, "only .pptx input is supported")
|
||||||
resolution = request.resolution
|
full_resolution, full_jpeg_quality = self._resolve_raster_options(
|
||||||
if resolution == conversion_pb2.CONVERSION_RESOLUTION_UNSPECIFIED:
|
request.full,
|
||||||
resolution = conversion_pb2.CONVERSION_RESOLUTION_FHD
|
default_resolution=_DEFAULT_FULL_RESOLUTION,
|
||||||
if resolution not in _RESOLUTION_PRESET_BY_PROTO:
|
default_jpeg_quality=_DEFAULT_FULL_JPEG_QUALITY,
|
||||||
raise ConnectError(Code.INVALID_ARGUMENT, "resolution is invalid")
|
field_name="full",
|
||||||
|
)
|
||||||
|
thumbnail_resolution, thumbnail_jpeg_quality = self._resolve_raster_options(
|
||||||
|
request.thumbnail,
|
||||||
|
default_resolution=_DEFAULT_THUMBNAIL_RESOLUTION,
|
||||||
|
default_jpeg_quality=_DEFAULT_THUMBNAIL_JPEG_QUALITY,
|
||||||
|
field_name="thumbnail",
|
||||||
|
)
|
||||||
|
|
||||||
ksuid = Ksuid()
|
ksuid = Ksuid()
|
||||||
conversion_id = str(ksuid)
|
conversion_id = str(ksuid)
|
||||||
@@ -109,7 +120,10 @@ class ConversionServiceImpl(conversion_connect.ConversionService):
|
|||||||
session = ConversionSession(
|
session = ConversionSession(
|
||||||
conversion_id=conversion_id,
|
conversion_id=conversion_id,
|
||||||
source_filename=source_filename,
|
source_filename=source_filename,
|
||||||
resolution=resolution,
|
full_resolution=full_resolution,
|
||||||
|
thumbnail_resolution=thumbnail_resolution,
|
||||||
|
full_jpeg_quality=full_jpeg_quality,
|
||||||
|
thumbnail_jpeg_quality=thumbnail_jpeg_quality,
|
||||||
bucket_name=bucket_name,
|
bucket_name=bucket_name,
|
||||||
upload_object_key=upload_key,
|
upload_object_key=upload_key,
|
||||||
status=conversion_pb2.CONVERSION_STATUS_PENDING,
|
status=conversion_pb2.CONVERSION_STATUS_PENDING,
|
||||||
@@ -226,11 +240,15 @@ class ConversionServiceImpl(conversion_connect.ConversionService):
|
|||||||
"""Execute conversion flow and persist terminal state in memory."""
|
"""Execute conversion flow and persist terminal state in memory."""
|
||||||
started_at = time.monotonic()
|
started_at = time.monotonic()
|
||||||
logger.info(
|
logger.info(
|
||||||
"Starting conversion conversion_id=%s source_filename=%s resolution=%s "
|
"Starting conversion conversion_id=%s source_filename=%s "
|
||||||
|
"full[resolution=%s,jpeg_quality=%d] thumbnail[resolution=%s,jpeg_quality=%d] "
|
||||||
"timeout_caps_s[pptx_to_pdf_total=%d,pdf_to_images_total=%d]",
|
"timeout_caps_s[pptx_to_pdf_total=%d,pdf_to_images_total=%d]",
|
||||||
session.conversion_id,
|
session.conversion_id,
|
||||||
session.source_filename,
|
session.source_filename,
|
||||||
conversion_pb2.ConversionResolution.Name(session.resolution),
|
conversion_pb2.ConversionResolution.Name(session.full_resolution),
|
||||||
|
session.full_jpeg_quality,
|
||||||
|
conversion_pb2.ConversionResolution.Name(session.thumbnail_resolution),
|
||||||
|
session.thumbnail_jpeg_quality,
|
||||||
self._config.conversion_pptx_to_pdf_timeout_seconds,
|
self._config.conversion_pptx_to_pdf_timeout_seconds,
|
||||||
self._config.conversion_pdf_to_images_timeout_seconds,
|
self._config.conversion_pdf_to_images_timeout_seconds,
|
||||||
)
|
)
|
||||||
@@ -250,7 +268,12 @@ class ConversionServiceImpl(conversion_connect.ConversionService):
|
|||||||
convert_pptx_to_slidedeck,
|
convert_pptx_to_slidedeck,
|
||||||
source_path,
|
source_path,
|
||||||
work_dir,
|
work_dir,
|
||||||
resolution=_RESOLUTION_PRESET_BY_PROTO[session.resolution],
|
full_resolution=_RESOLUTION_PRESET_BY_PROTO[session.full_resolution],
|
||||||
|
thumbnail_resolution=_RESOLUTION_PRESET_BY_PROTO[
|
||||||
|
session.thumbnail_resolution
|
||||||
|
],
|
||||||
|
full_jpeg_quality=session.full_jpeg_quality,
|
||||||
|
thumbnail_jpeg_quality=session.thumbnail_jpeg_quality,
|
||||||
pptx_to_pdf_timeout_s=self._config.conversion_pptx_to_pdf_timeout_seconds,
|
pptx_to_pdf_timeout_s=self._config.conversion_pptx_to_pdf_timeout_seconds,
|
||||||
pdf_to_images_timeout_s=self._config.conversion_pdf_to_images_timeout_seconds,
|
pdf_to_images_timeout_s=self._config.conversion_pdf_to_images_timeout_seconds,
|
||||||
pptx_to_pdf_base_timeout_s=self._config.conversion_pptx_to_pdf_base_timeout_seconds,
|
pptx_to_pdf_base_timeout_s=self._config.conversion_pptx_to_pdf_base_timeout_seconds,
|
||||||
@@ -266,14 +289,21 @@ class ConversionServiceImpl(conversion_connect.ConversionService):
|
|||||||
)
|
)
|
||||||
logger.info(
|
logger.info(
|
||||||
"Resolved conversion plan conversion_id=%s source_filename=%s "
|
"Resolved conversion plan conversion_id=%s source_filename=%s "
|
||||||
"resolution=%s inferred_dpi=%d output_size=%dx%d "
|
"full[resolution=%s,size=%dx%d,jpeg_quality=%d] "
|
||||||
|
"thumbnail[resolution=%s,size=%dx%d,jpeg_quality=%d] "
|
||||||
|
"inferred_dpi=%d "
|
||||||
"computed_timeouts_s[pptx_to_pdf_total=%d,pdf_to_images_total=%d,pdf_to_images_per_page=%d]",
|
"computed_timeouts_s[pptx_to_pdf_total=%d,pdf_to_images_total=%d,pdf_to_images_per_page=%d]",
|
||||||
session.conversion_id,
|
session.conversion_id,
|
||||||
session.source_filename,
|
session.source_filename,
|
||||||
conversion_pb2.ConversionResolution.Name(session.resolution),
|
conversion_pb2.ConversionResolution.Name(session.full_resolution),
|
||||||
result.inferred_dpi,
|
|
||||||
result.width,
|
result.width,
|
||||||
result.height,
|
result.height,
|
||||||
|
session.full_jpeg_quality,
|
||||||
|
conversion_pb2.ConversionResolution.Name(session.thumbnail_resolution),
|
||||||
|
result.thumbnail_width,
|
||||||
|
result.thumbnail_height,
|
||||||
|
session.thumbnail_jpeg_quality,
|
||||||
|
result.inferred_dpi,
|
||||||
result.pptx_to_pdf_timeout_s,
|
result.pptx_to_pdf_timeout_s,
|
||||||
result.pdf_to_images_timeout_s,
|
result.pdf_to_images_timeout_s,
|
||||||
result.pdf_to_images_page_timeout_s,
|
result.pdf_to_images_page_timeout_s,
|
||||||
@@ -282,7 +312,7 @@ class ConversionServiceImpl(conversion_connect.ConversionService):
|
|||||||
session,
|
session,
|
||||||
phase=conversion_pb2.CONVERSION_PHASE_UPLOADING_RESULTS,
|
phase=conversion_pb2.CONVERSION_PHASE_UPLOADING_RESULTS,
|
||||||
current_progress=0,
|
current_progress=0,
|
||||||
max_progress=len(result.slides),
|
max_progress=len(result.slides) * 2,
|
||||||
)
|
)
|
||||||
session.slide_deck = await asyncio.to_thread(
|
session.slide_deck = await asyncio.to_thread(
|
||||||
self._upload_and_build_slide_deck,
|
self._upload_and_build_slide_deck,
|
||||||
@@ -291,6 +321,8 @@ class ConversionServiceImpl(conversion_connect.ConversionService):
|
|||||||
result.source_filename,
|
result.source_filename,
|
||||||
result.width,
|
result.width,
|
||||||
result.height,
|
result.height,
|
||||||
|
result.thumbnail_width,
|
||||||
|
result.thumbnail_height,
|
||||||
lambda current, max_value: self._set_session_progress(
|
lambda current, max_value: self._set_session_progress(
|
||||||
session,
|
session,
|
||||||
phase=conversion_pb2.CONVERSION_PHASE_UPLOADING_RESULTS,
|
phase=conversion_pb2.CONVERSION_PHASE_UPLOADING_RESULTS,
|
||||||
@@ -358,12 +390,16 @@ class ConversionServiceImpl(conversion_connect.ConversionService):
|
|||||||
source_filename: str,
|
source_filename: str,
|
||||||
width: int,
|
width: int,
|
||||||
height: int,
|
height: int,
|
||||||
|
thumbnail_width: int,
|
||||||
|
thumbnail_height: int,
|
||||||
progress_callback: Callable[[int, int], None] | None = None,
|
progress_callback: Callable[[int, int], None] | None = None,
|
||||||
) -> conversion_pb2.SlideDeck:
|
) -> conversion_pb2.SlideDeck:
|
||||||
"""Upload generated slide images and construct API response payload."""
|
"""Upload generated slide images and construct API response payload."""
|
||||||
response_slides: list[conversion_pb2.Slide] = []
|
response_slides: list[conversion_pb2.Slide] = []
|
||||||
slide_total = len(slides)
|
slide_total = len(slides)
|
||||||
for slide_index, slide in enumerate(slides, start=1):
|
upload_total = slide_total * 2
|
||||||
|
upload_index = 0
|
||||||
|
for slide in slides:
|
||||||
object_key = f"output/slide-{slide.index:04d}{slide.image_path.suffix}"
|
object_key = f"output/slide-{slide.index:04d}{slide.image_path.suffix}"
|
||||||
self._store.fput_object(session.bucket_name, object_key, slide.image_path)
|
self._store.fput_object(session.bucket_name, object_key, slide.image_path)
|
||||||
image_url = self._store.presigned_get_url(
|
image_url = self._store.presigned_get_url(
|
||||||
@@ -371,15 +407,33 @@ class ConversionServiceImpl(conversion_connect.ConversionService):
|
|||||||
object_key,
|
object_key,
|
||||||
ttl_seconds=self._config.s3_session_ttl_seconds,
|
ttl_seconds=self._config.s3_session_ttl_seconds,
|
||||||
)
|
)
|
||||||
|
upload_index += 1
|
||||||
|
if progress_callback is not None:
|
||||||
|
progress_callback(upload_index, upload_total)
|
||||||
|
thumbnail_object_key = (
|
||||||
|
f"output/thumb/slide-{slide.index:04d}{slide.thumbnail_path.suffix}"
|
||||||
|
)
|
||||||
|
self._store.fput_object(
|
||||||
|
session.bucket_name,
|
||||||
|
thumbnail_object_key,
|
||||||
|
slide.thumbnail_path,
|
||||||
|
)
|
||||||
|
thumbnail_image_url = self._store.presigned_get_url(
|
||||||
|
session.bucket_name,
|
||||||
|
thumbnail_object_key,
|
||||||
|
ttl_seconds=self._config.s3_session_ttl_seconds,
|
||||||
|
)
|
||||||
|
upload_index += 1
|
||||||
response_slides.append(
|
response_slides.append(
|
||||||
conversion_pb2.Slide(
|
conversion_pb2.Slide(
|
||||||
index=slide.index,
|
index=slide.index,
|
||||||
notes_plain=slide.notes_plain,
|
notes_plain=slide.notes_plain,
|
||||||
image_url=image_url,
|
image_url=image_url,
|
||||||
|
thumbnail_image_url=thumbnail_image_url,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if progress_callback is not None:
|
if progress_callback is not None:
|
||||||
progress_callback(slide_index, slide_total)
|
progress_callback(upload_index, upload_total)
|
||||||
|
|
||||||
return conversion_pb2.SlideDeck(
|
return conversion_pb2.SlideDeck(
|
||||||
conversion_id=session.conversion_id,
|
conversion_id=session.conversion_id,
|
||||||
@@ -388,8 +442,38 @@ class ConversionServiceImpl(conversion_connect.ConversionService):
|
|||||||
created_at=_to_timestamp(utc_now()),
|
created_at=_to_timestamp(utc_now()),
|
||||||
width=width,
|
width=width,
|
||||||
height=height,
|
height=height,
|
||||||
|
thumbnail_width=thumbnail_width,
|
||||||
|
thumbnail_height=thumbnail_height,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _resolve_raster_options(
|
||||||
|
self,
|
||||||
|
options: conversion_pb2.SlideRasterOptions,
|
||||||
|
*,
|
||||||
|
default_resolution: conversion_pb2.ConversionResolution,
|
||||||
|
default_jpeg_quality: int,
|
||||||
|
field_name: str,
|
||||||
|
) -> tuple[conversion_pb2.ConversionResolution, int]:
|
||||||
|
"""Resolve per-tier raster options with defaults and validation."""
|
||||||
|
resolution = options.resolution
|
||||||
|
if resolution == conversion_pb2.CONVERSION_RESOLUTION_UNSPECIFIED:
|
||||||
|
resolution = default_resolution
|
||||||
|
if resolution not in _RESOLUTION_PRESET_BY_PROTO:
|
||||||
|
raise ConnectError(Code.INVALID_ARGUMENT, f"{field_name}.resolution is invalid")
|
||||||
|
jpeg_quality = default_jpeg_quality
|
||||||
|
if options.HasField("jpeg"):
|
||||||
|
quality = options.jpeg.quality
|
||||||
|
if quality == 0:
|
||||||
|
jpeg_quality = default_jpeg_quality
|
||||||
|
elif 1 <= quality <= 100:
|
||||||
|
jpeg_quality = quality
|
||||||
|
else:
|
||||||
|
raise ConnectError(
|
||||||
|
Code.INVALID_ARGUMENT,
|
||||||
|
f"{field_name}.jpeg.quality must be 0 or between 1 and 100",
|
||||||
|
)
|
||||||
|
return resolution, jpeg_quality
|
||||||
|
|
||||||
async def _delayed_cleanup(self, session: ConversionSession) -> None:
|
async def _delayed_cleanup(self, session: ConversionSession) -> None:
|
||||||
"""Delete storage resources after the configured session retention period."""
|
"""Delete storage resources after the configured session retention period."""
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user