add rich output support for slide notes
Docker server image / build-and-push (push) Successful in 3m2s

This commit is contained in:
2026-05-07 10:35:37 -07:00
parent 500b767d58
commit 06d4122e4e
11 changed files with 831 additions and 140 deletions
+42
View File
@@ -21,10 +21,28 @@ type RasterTierOptions struct {
JPEGQuality int32 JPEGQuality int32
} }
// HtmlFormattingPolicy configures which formatting features are ignored in HTML notes mode.
type HtmlFormattingPolicy struct {
IgnoreBold bool
IgnoreItalic bool
IgnoreUnderline bool
IgnoreStrikethrough bool
IgnoreFontSize bool
IgnoreColor bool
}
// NotesOptions controls speaker-notes extraction/output.
type NotesOptions struct {
Format officeconvertapiv1.NotesFormat
HTMLUseParagraphTags *bool
HTMLPolicy *HtmlFormattingPolicy
}
// CreateConversionOptions configures optional full and thumbnail raster tiers. // CreateConversionOptions configures optional full and thumbnail raster tiers.
type CreateConversionOptions struct { type CreateConversionOptions struct {
Full *RasterTierOptions Full *RasterTierOptions
Thumbnail *RasterTierOptions Thumbnail *RasterTierOptions
Notes *NotesOptions
} }
// Client wraps the generated Connect client with orchestration-focused helpers. // Client wraps the generated Connect client with orchestration-focused helpers.
@@ -67,6 +85,7 @@ func (c *Client) CreateConversion(
if options != nil { if options != nil {
message.Full = toProtoSlideRasterOptions(options.Full) message.Full = toProtoSlideRasterOptions(options.Full)
message.Thumbnail = toProtoSlideRasterOptions(options.Thumbnail) message.Thumbnail = toProtoSlideRasterOptions(options.Thumbnail)
message.Notes = toProtoNotesOptions(options.Notes)
} }
req := connect.NewRequest(message) req := connect.NewRequest(message)
res, err := c.rpc.CreateConversion(ctx, req) res, err := c.rpc.CreateConversion(ctx, req)
@@ -95,6 +114,29 @@ func toProtoSlideRasterOptions(
return proto return proto
} }
func toProtoNotesOptions(options *NotesOptions) *officeconvertapiv1.NotesOptions {
if options == nil {
return nil
}
proto := &officeconvertapiv1.NotesOptions{
Format: options.Format,
}
if options.HTMLUseParagraphTags != nil {
proto.HtmlUseParagraphTags = options.HTMLUseParagraphTags
}
if options.HTMLPolicy != nil {
proto.HtmlPolicy = &officeconvertapiv1.HtmlFormattingPolicy{
IgnoreBold: options.HTMLPolicy.IgnoreBold,
IgnoreItalic: options.HTMLPolicy.IgnoreItalic,
IgnoreUnderline: options.HTMLPolicy.IgnoreUnderline,
IgnoreStrikethrough: options.HTMLPolicy.IgnoreStrikethrough,
IgnoreFontSize: options.HTMLPolicy.IgnoreFontSize,
IgnoreColor: options.HTMLPolicy.IgnoreColor,
}
}
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,
+332 -88
View File
@@ -196,6 +196,56 @@ func (ConversionResolution) EnumDescriptor() ([]byte, []int) {
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{2} return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{2}
} }
// NotesFormat controls what note representation the server should compute.
type NotesFormat int32
const (
NotesFormat_NOTES_FORMAT_UNSPECIFIED NotesFormat = 0
NotesFormat_NOTES_FORMAT_PLAIN NotesFormat = 1
NotesFormat_NOTES_FORMAT_HTML NotesFormat = 2
)
// Enum value maps for NotesFormat.
var (
NotesFormat_name = map[int32]string{
0: "NOTES_FORMAT_UNSPECIFIED",
1: "NOTES_FORMAT_PLAIN",
2: "NOTES_FORMAT_HTML",
}
NotesFormat_value = map[string]int32{
"NOTES_FORMAT_UNSPECIFIED": 0,
"NOTES_FORMAT_PLAIN": 1,
"NOTES_FORMAT_HTML": 2,
}
)
func (x NotesFormat) Enum() *NotesFormat {
p := new(NotesFormat)
*p = x
return p
}
func (x NotesFormat) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (NotesFormat) Descriptor() protoreflect.EnumDescriptor {
return file_officeconvertapi_v1_conversion_proto_enumTypes[3].Descriptor()
}
func (NotesFormat) Type() protoreflect.EnumType {
return &file_officeconvertapi_v1_conversion_proto_enumTypes[3]
}
func (x NotesFormat) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use NotesFormat.Descriptor instead.
func (NotesFormat) EnumDescriptor() ([]byte, []int) {
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{3}
}
// JpegOutputOptions configures JPEG-specific encoding controls. // JpegOutputOptions configures JPEG-specific encoding controls.
type JpegOutputOptions struct { type JpegOutputOptions struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
@@ -318,6 +368,155 @@ type SlideRasterOptions_Jpeg struct {
func (*SlideRasterOptions_Jpeg) isSlideRasterOptions_Format() {} func (*SlideRasterOptions_Jpeg) isSlideRasterOptions_Format() {}
// HtmlFormattingPolicy configures which formatting features are ignored in HTML mode.
type HtmlFormattingPolicy struct {
state protoimpl.MessageState `protogen:"open.v1"`
IgnoreBold bool `protobuf:"varint,1,opt,name=ignore_bold,json=ignoreBold,proto3" json:"ignore_bold,omitempty"`
IgnoreItalic bool `protobuf:"varint,2,opt,name=ignore_italic,json=ignoreItalic,proto3" json:"ignore_italic,omitempty"`
IgnoreUnderline bool `protobuf:"varint,3,opt,name=ignore_underline,json=ignoreUnderline,proto3" json:"ignore_underline,omitempty"`
IgnoreStrikethrough bool `protobuf:"varint,4,opt,name=ignore_strikethrough,json=ignoreStrikethrough,proto3" json:"ignore_strikethrough,omitempty"`
IgnoreFontSize bool `protobuf:"varint,5,opt,name=ignore_font_size,json=ignoreFontSize,proto3" json:"ignore_font_size,omitempty"`
IgnoreColor bool `protobuf:"varint,6,opt,name=ignore_color,json=ignoreColor,proto3" json:"ignore_color,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *HtmlFormattingPolicy) Reset() {
*x = HtmlFormattingPolicy{}
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *HtmlFormattingPolicy) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*HtmlFormattingPolicy) ProtoMessage() {}
func (x *HtmlFormattingPolicy) ProtoReflect() protoreflect.Message {
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[2]
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 HtmlFormattingPolicy.ProtoReflect.Descriptor instead.
func (*HtmlFormattingPolicy) Descriptor() ([]byte, []int) {
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{2}
}
func (x *HtmlFormattingPolicy) GetIgnoreBold() bool {
if x != nil {
return x.IgnoreBold
}
return false
}
func (x *HtmlFormattingPolicy) GetIgnoreItalic() bool {
if x != nil {
return x.IgnoreItalic
}
return false
}
func (x *HtmlFormattingPolicy) GetIgnoreUnderline() bool {
if x != nil {
return x.IgnoreUnderline
}
return false
}
func (x *HtmlFormattingPolicy) GetIgnoreStrikethrough() bool {
if x != nil {
return x.IgnoreStrikethrough
}
return false
}
func (x *HtmlFormattingPolicy) GetIgnoreFontSize() bool {
if x != nil {
return x.IgnoreFontSize
}
return false
}
func (x *HtmlFormattingPolicy) GetIgnoreColor() bool {
if x != nil {
return x.IgnoreColor
}
return false
}
// NotesOptions configures note extraction behavior.
type NotesOptions struct {
state protoimpl.MessageState `protogen:"open.v1"`
// Output format for extracted notes.
Format NotesFormat `protobuf:"varint,1,opt,name=format,proto3,enum=officeconvertapi.v1.NotesFormat" json:"format,omitempty"`
// If true, wrap PPTX paragraphs as <p> blocks in HTML mode. If false, emit <br/> only.
HtmlUseParagraphTags *bool `protobuf:"varint,2,opt,name=html_use_paragraph_tags,json=htmlUseParagraphTags,proto3,oneof" json:"html_use_paragraph_tags,omitempty"`
// Formatting policy for HTML mode.
HtmlPolicy *HtmlFormattingPolicy `protobuf:"bytes,3,opt,name=html_policy,json=htmlPolicy,proto3" json:"html_policy,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *NotesOptions) Reset() {
*x = NotesOptions{}
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *NotesOptions) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*NotesOptions) ProtoMessage() {}
func (x *NotesOptions) ProtoReflect() protoreflect.Message {
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[3]
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 NotesOptions.ProtoReflect.Descriptor instead.
func (*NotesOptions) Descriptor() ([]byte, []int) {
return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{3}
}
func (x *NotesOptions) GetFormat() NotesFormat {
if x != nil {
return x.Format
}
return NotesFormat_NOTES_FORMAT_UNSPECIFIED
}
func (x *NotesOptions) GetHtmlUseParagraphTags() bool {
if x != nil && x.HtmlUseParagraphTags != nil {
return *x.HtmlUseParagraphTags
}
return false
}
func (x *NotesOptions) GetHtmlPolicy() *HtmlFormattingPolicy {
if x != nil {
return x.HtmlPolicy
}
return nil
}
// Slide contains extracted notes and the rendered image URL for one slide. // Slide contains extracted notes and the rendered image URL for one slide.
type Slide struct { type Slide struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
@@ -327,13 +526,15 @@ type Slide struct {
ImageUrl string `protobuf:"bytes,3,opt,name=image_url,json=imageUrl,proto3" json:"image_url,omitempty"` ImageUrl string `protobuf:"bytes,3,opt,name=image_url,json=imageUrl,proto3" json:"image_url,omitempty"`
// Thumbnail rendered image URL. // Thumbnail rendered image URL.
ThumbnailImageUrl string `protobuf:"bytes,4,opt,name=thumbnail_image_url,json=thumbnailImageUrl,proto3" json:"thumbnail_image_url,omitempty"` ThumbnailImageUrl string `protobuf:"bytes,4,opt,name=thumbnail_image_url,json=thumbnailImageUrl,proto3" json:"thumbnail_image_url,omitempty"`
unknownFields protoimpl.UnknownFields // Optional, sanitized HTML version of notes when requested.
sizeCache protoimpl.SizeCache NotesHtml string `protobuf:"bytes,5,opt,name=notes_html,json=notesHtml,proto3" json:"notes_html,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[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)
} }
@@ -345,7 +546,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[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 {
@@ -358,7 +559,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{2} return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{4}
} }
func (x *Slide) GetIndex() int32 { func (x *Slide) GetIndex() int32 {
@@ -389,6 +590,13 @@ func (x *Slide) GetThumbnailImageUrl() string {
return "" return ""
} }
func (x *Slide) GetNotesHtml() string {
if x != nil {
return x.NotesHtml
}
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"`
@@ -411,7 +619,7 @@ type SlideDeck struct {
func (x *SlideDeck) Reset() { func (x *SlideDeck) Reset() {
*x = SlideDeck{} *x = SlideDeck{}
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 +631,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[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 +644,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{3} return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{5}
} }
func (x *SlideDeck) GetConversionId() string { func (x *SlideDeck) GetConversionId() string {
@@ -501,13 +709,14 @@ type CreateConversionRequest struct {
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"`
Full *SlideRasterOptions `protobuf:"bytes,2,opt,name=full,proto3" json:"full,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"` Thumbnail *SlideRasterOptions `protobuf:"bytes,3,opt,name=thumbnail,proto3" json:"thumbnail,omitempty"`
Notes *NotesOptions `protobuf:"bytes,4,opt,name=notes,proto3" json:"notes,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[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)
} }
@@ -519,7 +728,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[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 {
@@ -532,7 +741,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{4} return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{6}
} }
func (x *CreateConversionRequest) GetSourceFilename() string { func (x *CreateConversionRequest) GetSourceFilename() string {
@@ -556,6 +765,13 @@ func (x *CreateConversionRequest) GetThumbnail() *SlideRasterOptions {
return nil return nil
} }
func (x *CreateConversionRequest) GetNotes() *NotesOptions {
if x != nil {
return x.Notes
}
return nil
}
// CreateConversionResponse returns upload details for the session. // CreateConversionResponse returns upload details for the session.
type CreateConversionResponse struct { type CreateConversionResponse struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
@@ -571,7 +787,7 @@ type CreateConversionResponse struct {
func (x *CreateConversionResponse) Reset() { func (x *CreateConversionResponse) Reset() {
*x = CreateConversionResponse{} *x = CreateConversionResponse{}
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)
} }
@@ -583,7 +799,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[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 {
@@ -596,7 +812,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{5} return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{7}
} }
func (x *CreateConversionResponse) GetConversionId() string { func (x *CreateConversionResponse) GetConversionId() string {
@@ -645,7 +861,7 @@ type StartConversionRequest struct {
func (x *StartConversionRequest) Reset() { func (x *StartConversionRequest) Reset() {
*x = StartConversionRequest{} *x = StartConversionRequest{}
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)
} }
@@ -657,7 +873,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[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 {
@@ -670,7 +886,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{6} return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{8}
} }
func (x *StartConversionRequest) GetConversionId() string { func (x *StartConversionRequest) GetConversionId() string {
@@ -692,7 +908,7 @@ type StartConversionResponse struct {
func (x *StartConversionResponse) Reset() { func (x *StartConversionResponse) Reset() {
*x = StartConversionResponse{} *x = StartConversionResponse{}
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)
} }
@@ -704,7 +920,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[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 {
@@ -717,7 +933,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{7} return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{9}
} }
func (x *StartConversionResponse) GetConversionId() string { func (x *StartConversionResponse) GetConversionId() string {
@@ -745,7 +961,7 @@ type GetConversionStatusRequest struct {
func (x *GetConversionStatusRequest) Reset() { func (x *GetConversionStatusRequest) Reset() {
*x = GetConversionStatusRequest{} *x = GetConversionStatusRequest{}
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)
} }
@@ -757,7 +973,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[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 {
@@ -770,7 +986,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{8} return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{10}
} }
func (x *GetConversionStatusRequest) GetConversionId() string { func (x *GetConversionStatusRequest) GetConversionId() string {
@@ -797,7 +1013,7 @@ type GetConversionStatusResponse struct {
func (x *GetConversionStatusResponse) Reset() { func (x *GetConversionStatusResponse) Reset() {
*x = GetConversionStatusResponse{} *x = GetConversionStatusResponse{}
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)
} }
@@ -809,7 +1025,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[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 {
@@ -822,7 +1038,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{9} return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{11}
} }
func (x *GetConversionStatusResponse) GetConversionId() string { func (x *GetConversionStatusResponse) GetConversionId() string {
@@ -885,7 +1101,7 @@ type GetSlideDeckRequest struct {
func (x *GetSlideDeckRequest) Reset() { func (x *GetSlideDeckRequest) Reset() {
*x = GetSlideDeckRequest{} *x = GetSlideDeckRequest{}
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)
} }
@@ -897,7 +1113,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[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 {
@@ -910,7 +1126,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{10} return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{12}
} }
func (x *GetSlideDeckRequest) GetConversionId() string { func (x *GetSlideDeckRequest) GetConversionId() string {
@@ -930,7 +1146,7 @@ type GetSlideDeckResponse struct {
func (x *GetSlideDeckResponse) Reset() { func (x *GetSlideDeckResponse) Reset() {
*x = GetSlideDeckResponse{} *x = GetSlideDeckResponse{}
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)
} }
@@ -942,7 +1158,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[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 {
@@ -955,7 +1171,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{11} return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{13}
} }
func (x *GetSlideDeckResponse) GetSlideDeck() *SlideDeck { func (x *GetSlideDeckResponse) GetSlideDeck() *SlideDeck {
@@ -976,7 +1192,7 @@ type DeleteConversionRequest struct {
func (x *DeleteConversionRequest) Reset() { func (x *DeleteConversionRequest) Reset() {
*x = DeleteConversionRequest{} *x = DeleteConversionRequest{}
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[12] mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -988,7 +1204,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[12] mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[14]
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 {
@@ -1001,7 +1217,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{12} return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{14}
} }
func (x *DeleteConversionRequest) GetConversionId() string { func (x *DeleteConversionRequest) GetConversionId() string {
@@ -1023,7 +1239,7 @@ type DeleteConversionResponse struct {
func (x *DeleteConversionResponse) Reset() { func (x *DeleteConversionResponse) Reset() {
*x = DeleteConversionResponse{} *x = DeleteConversionResponse{}
mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[13] mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -1035,7 +1251,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[13] mi := &file_officeconvertapi_v1_conversion_proto_msgTypes[15]
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 {
@@ -1048,7 +1264,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{13} return file_officeconvertapi_v1_conversion_proto_rawDescGZIP(), []int{15}
} }
func (x *DeleteConversionResponse) GetConversionId() string { func (x *DeleteConversionResponse) GetConversionId() string {
@@ -1077,13 +1293,29 @@ const file_officeconvertapi_v1_conversion_proto_rawDesc = "" +
"resolution\x18\x01 \x01(\x0e2).officeconvertapi.v1.ConversionResolutionR\n" + "resolution\x18\x01 \x01(\x0e2).officeconvertapi.v1.ConversionResolutionR\n" +
"resolution\x12<\n" + "resolution\x12<\n" +
"\x04jpeg\x18\x02 \x01(\v2&.officeconvertapi.v1.JpegOutputOptionsH\x00R\x04jpegB\b\n" + "\x04jpeg\x18\x02 \x01(\v2&.officeconvertapi.v1.JpegOutputOptionsH\x00R\x04jpegB\b\n" +
"\x06format\"\x8b\x01\n" + "\x06format\"\x87\x02\n" +
"\x14HtmlFormattingPolicy\x12\x1f\n" +
"\vignore_bold\x18\x01 \x01(\bR\n" +
"ignoreBold\x12#\n" +
"\rignore_italic\x18\x02 \x01(\bR\fignoreItalic\x12)\n" +
"\x10ignore_underline\x18\x03 \x01(\bR\x0fignoreUnderline\x121\n" +
"\x14ignore_strikethrough\x18\x04 \x01(\bR\x13ignoreStrikethrough\x12(\n" +
"\x10ignore_font_size\x18\x05 \x01(\bR\x0eignoreFontSize\x12!\n" +
"\fignore_color\x18\x06 \x01(\bR\vignoreColor\"\xec\x01\n" +
"\fNotesOptions\x128\n" +
"\x06format\x18\x01 \x01(\x0e2 .officeconvertapi.v1.NotesFormatR\x06format\x12:\n" +
"\x17html_use_paragraph_tags\x18\x02 \x01(\bH\x00R\x14htmlUseParagraphTags\x88\x01\x01\x12J\n" +
"\vhtml_policy\x18\x03 \x01(\v2).officeconvertapi.v1.HtmlFormattingPolicyR\n" +
"htmlPolicyB\x1a\n" +
"\x18_html_use_paragraph_tags\"\xaa\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\x12.\n" + "\timage_url\x18\x03 \x01(\tR\bimageUrl\x12.\n" +
"\x13thumbnail_image_url\x18\x04 \x01(\tR\x11thumbnailImageUrl\"\xca\x02\n" + "\x13thumbnail_image_url\x18\x04 \x01(\tR\x11thumbnailImageUrl\x12\x1d\n" +
"\n" +
"notes_html\x18\x05 \x01(\tR\tnotesHtml\"\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" +
@@ -1093,11 +1325,12 @@ const file_officeconvertapi_v1_conversion_proto_rawDesc = "" +
"\x05width\x18\x05 \x01(\x05R\x05width\x12\x16\n" + "\x05width\x18\x05 \x01(\x05R\x05width\x12\x16\n" +
"\x06height\x18\x06 \x01(\x05R\x06height\x12'\n" + "\x06height\x18\x06 \x01(\x05R\x06height\x12'\n" +
"\x0fthumbnail_width\x18\a \x01(\x05R\x0ethumbnailWidth\x12)\n" + "\x0fthumbnail_width\x18\a \x01(\x05R\x0ethumbnailWidth\x12)\n" +
"\x10thumbnail_height\x18\b \x01(\x05R\x0fthumbnailHeight\"\xc6\x01\n" + "\x10thumbnail_height\x18\b \x01(\x05R\x0fthumbnailHeight\"\xff\x01\n" +
"\x17CreateConversionRequest\x12'\n" + "\x17CreateConversionRequest\x12'\n" +
"\x0fsource_filename\x18\x01 \x01(\tR\x0esourceFilename\x12;\n" + "\x0fsource_filename\x18\x01 \x01(\tR\x0esourceFilename\x12;\n" +
"\x04full\x18\x02 \x01(\v2'.officeconvertapi.v1.SlideRasterOptionsR\x04full\x12E\n" + "\x04full\x18\x02 \x01(\v2'.officeconvertapi.v1.SlideRasterOptionsR\x04full\x12E\n" +
"\tthumbnail\x18\x03 \x01(\v2'.officeconvertapi.v1.SlideRasterOptionsR\tthumbnail\"\xea\x01\n" + "\tthumbnail\x18\x03 \x01(\v2'.officeconvertapi.v1.SlideRasterOptionsR\tthumbnail\x127\n" +
"\x05notes\x18\x04 \x01(\v2!.officeconvertapi.v1.NotesOptionsR\x05notes\"\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" +
@@ -1151,7 +1384,11 @@ const file_officeconvertapi_v1_conversion_proto_rawDesc = "" +
"\x18CONVERSION_RESOLUTION_HD\x10\x02\x12\x1d\n" + "\x18CONVERSION_RESOLUTION_HD\x10\x02\x12\x1d\n" +
"\x19CONVERSION_RESOLUTION_FHD\x10\x03\x12\x1d\n" + "\x19CONVERSION_RESOLUTION_FHD\x10\x03\x12\x1d\n" +
"\x19CONVERSION_RESOLUTION_QHD\x10\x04\x12\x1d\n" + "\x19CONVERSION_RESOLUTION_QHD\x10\x04\x12\x1d\n" +
"\x19CONVERSION_RESOLUTION_UHD\x10\x052\xcc\x04\n" + "\x19CONVERSION_RESOLUTION_UHD\x10\x05*Z\n" +
"\vNotesFormat\x12\x1c\n" +
"\x18NOTES_FORMAT_UNSPECIFIED\x10\x00\x12\x16\n" +
"\x12NOTES_FORMAT_PLAIN\x10\x01\x12\x15\n" +
"\x11NOTES_FORMAT_HTML\x10\x022\xcc\x04\n" +
"\x11ConversionService\x12q\n" + "\x11ConversionService\x12q\n" +
"\x10CreateConversion\x12,.officeconvertapi.v1.CreateConversionRequest\x1a-.officeconvertapi.v1.CreateConversionResponse\"\x00\x12n\n" + "\x10CreateConversion\x12,.officeconvertapi.v1.CreateConversionRequest\x1a-.officeconvertapi.v1.CreateConversionResponse\"\x00\x12n\n" +
"\x0fStartConversion\x12+.officeconvertapi.v1.StartConversionRequest\x1a,.officeconvertapi.v1.StartConversionResponse\"\x00\x12z\n" + "\x0fStartConversion\x12+.officeconvertapi.v1.StartConversionRequest\x1a,.officeconvertapi.v1.StartConversionResponse\"\x00\x12z\n" +
@@ -1171,56 +1408,62 @@ func file_officeconvertapi_v1_conversion_proto_rawDescGZIP() []byte {
return file_officeconvertapi_v1_conversion_proto_rawDescData return file_officeconvertapi_v1_conversion_proto_rawDescData
} }
var file_officeconvertapi_v1_conversion_proto_enumTypes = make([]protoimpl.EnumInfo, 3) var file_officeconvertapi_v1_conversion_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
var file_officeconvertapi_v1_conversion_proto_msgTypes = make([]protoimpl.MessageInfo, 14) var file_officeconvertapi_v1_conversion_proto_msgTypes = make([]protoimpl.MessageInfo, 16)
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
(*JpegOutputOptions)(nil), // 3: officeconvertapi.v1.JpegOutputOptions (NotesFormat)(0), // 3: officeconvertapi.v1.NotesFormat
(*SlideRasterOptions)(nil), // 4: officeconvertapi.v1.SlideRasterOptions (*JpegOutputOptions)(nil), // 4: officeconvertapi.v1.JpegOutputOptions
(*Slide)(nil), // 5: officeconvertapi.v1.Slide (*SlideRasterOptions)(nil), // 5: officeconvertapi.v1.SlideRasterOptions
(*SlideDeck)(nil), // 6: officeconvertapi.v1.SlideDeck (*HtmlFormattingPolicy)(nil), // 6: officeconvertapi.v1.HtmlFormattingPolicy
(*CreateConversionRequest)(nil), // 7: officeconvertapi.v1.CreateConversionRequest (*NotesOptions)(nil), // 7: officeconvertapi.v1.NotesOptions
(*CreateConversionResponse)(nil), // 8: officeconvertapi.v1.CreateConversionResponse (*Slide)(nil), // 8: officeconvertapi.v1.Slide
(*StartConversionRequest)(nil), // 9: officeconvertapi.v1.StartConversionRequest (*SlideDeck)(nil), // 9: officeconvertapi.v1.SlideDeck
(*StartConversionResponse)(nil), // 10: officeconvertapi.v1.StartConversionResponse (*CreateConversionRequest)(nil), // 10: officeconvertapi.v1.CreateConversionRequest
(*GetConversionStatusRequest)(nil), // 11: officeconvertapi.v1.GetConversionStatusRequest (*CreateConversionResponse)(nil), // 11: officeconvertapi.v1.CreateConversionResponse
(*GetConversionStatusResponse)(nil), // 12: officeconvertapi.v1.GetConversionStatusResponse (*StartConversionRequest)(nil), // 12: officeconvertapi.v1.StartConversionRequest
(*GetSlideDeckRequest)(nil), // 13: officeconvertapi.v1.GetSlideDeckRequest (*StartConversionResponse)(nil), // 13: officeconvertapi.v1.StartConversionResponse
(*GetSlideDeckResponse)(nil), // 14: officeconvertapi.v1.GetSlideDeckResponse (*GetConversionStatusRequest)(nil), // 14: officeconvertapi.v1.GetConversionStatusRequest
(*DeleteConversionRequest)(nil), // 15: officeconvertapi.v1.DeleteConversionRequest (*GetConversionStatusResponse)(nil), // 15: officeconvertapi.v1.GetConversionStatusResponse
(*DeleteConversionResponse)(nil), // 16: officeconvertapi.v1.DeleteConversionResponse (*GetSlideDeckRequest)(nil), // 16: officeconvertapi.v1.GetSlideDeckRequest
(*timestamppb.Timestamp)(nil), // 17: google.protobuf.Timestamp (*GetSlideDeckResponse)(nil), // 17: officeconvertapi.v1.GetSlideDeckResponse
(*DeleteConversionRequest)(nil), // 18: officeconvertapi.v1.DeleteConversionRequest
(*DeleteConversionResponse)(nil), // 19: officeconvertapi.v1.DeleteConversionResponse
(*timestamppb.Timestamp)(nil), // 20: google.protobuf.Timestamp
} }
var file_officeconvertapi_v1_conversion_proto_depIdxs = []int32{ var file_officeconvertapi_v1_conversion_proto_depIdxs = []int32{
2, // 0: officeconvertapi.v1.SlideRasterOptions.resolution:type_name -> officeconvertapi.v1.ConversionResolution 2, // 0: officeconvertapi.v1.SlideRasterOptions.resolution:type_name -> officeconvertapi.v1.ConversionResolution
3, // 1: officeconvertapi.v1.SlideRasterOptions.jpeg:type_name -> officeconvertapi.v1.JpegOutputOptions 4, // 1: officeconvertapi.v1.SlideRasterOptions.jpeg:type_name -> officeconvertapi.v1.JpegOutputOptions
5, // 2: officeconvertapi.v1.SlideDeck.slides:type_name -> officeconvertapi.v1.Slide 3, // 2: officeconvertapi.v1.NotesOptions.format:type_name -> officeconvertapi.v1.NotesFormat
17, // 3: officeconvertapi.v1.SlideDeck.created_at:type_name -> google.protobuf.Timestamp 6, // 3: officeconvertapi.v1.NotesOptions.html_policy:type_name -> officeconvertapi.v1.HtmlFormattingPolicy
4, // 4: officeconvertapi.v1.CreateConversionRequest.full:type_name -> officeconvertapi.v1.SlideRasterOptions 8, // 4: officeconvertapi.v1.SlideDeck.slides:type_name -> officeconvertapi.v1.Slide
4, // 5: officeconvertapi.v1.CreateConversionRequest.thumbnail:type_name -> officeconvertapi.v1.SlideRasterOptions 20, // 5: officeconvertapi.v1.SlideDeck.created_at:type_name -> google.protobuf.Timestamp
17, // 6: officeconvertapi.v1.CreateConversionResponse.expires_at:type_name -> google.protobuf.Timestamp 5, // 6: officeconvertapi.v1.CreateConversionRequest.full:type_name -> officeconvertapi.v1.SlideRasterOptions
0, // 7: officeconvertapi.v1.StartConversionResponse.status:type_name -> officeconvertapi.v1.ConversionStatus 5, // 7: officeconvertapi.v1.CreateConversionRequest.thumbnail:type_name -> officeconvertapi.v1.SlideRasterOptions
0, // 8: officeconvertapi.v1.GetConversionStatusResponse.status:type_name -> officeconvertapi.v1.ConversionStatus 7, // 8: officeconvertapi.v1.CreateConversionRequest.notes:type_name -> officeconvertapi.v1.NotesOptions
17, // 9: officeconvertapi.v1.GetConversionStatusResponse.updated_at:type_name -> google.protobuf.Timestamp 20, // 9: officeconvertapi.v1.CreateConversionResponse.expires_at:type_name -> google.protobuf.Timestamp
1, // 10: officeconvertapi.v1.GetConversionStatusResponse.phase:type_name -> officeconvertapi.v1.ConversionPhase 0, // 10: officeconvertapi.v1.StartConversionResponse.status:type_name -> officeconvertapi.v1.ConversionStatus
6, // 11: officeconvertapi.v1.GetSlideDeckResponse.slide_deck:type_name -> officeconvertapi.v1.SlideDeck 0, // 11: officeconvertapi.v1.GetConversionStatusResponse.status:type_name -> officeconvertapi.v1.ConversionStatus
7, // 12: officeconvertapi.v1.ConversionService.CreateConversion:input_type -> officeconvertapi.v1.CreateConversionRequest 20, // 12: officeconvertapi.v1.GetConversionStatusResponse.updated_at:type_name -> google.protobuf.Timestamp
9, // 13: officeconvertapi.v1.ConversionService.StartConversion:input_type -> officeconvertapi.v1.StartConversionRequest 1, // 13: officeconvertapi.v1.GetConversionStatusResponse.phase:type_name -> officeconvertapi.v1.ConversionPhase
11, // 14: officeconvertapi.v1.ConversionService.GetConversionStatus:input_type -> officeconvertapi.v1.GetConversionStatusRequest 9, // 14: officeconvertapi.v1.GetSlideDeckResponse.slide_deck:type_name -> officeconvertapi.v1.SlideDeck
13, // 15: officeconvertapi.v1.ConversionService.GetSlideDeck:input_type -> officeconvertapi.v1.GetSlideDeckRequest 10, // 15: officeconvertapi.v1.ConversionService.CreateConversion:input_type -> officeconvertapi.v1.CreateConversionRequest
15, // 16: officeconvertapi.v1.ConversionService.DeleteConversion:input_type -> officeconvertapi.v1.DeleteConversionRequest 12, // 16: officeconvertapi.v1.ConversionService.StartConversion:input_type -> officeconvertapi.v1.StartConversionRequest
8, // 17: officeconvertapi.v1.ConversionService.CreateConversion:output_type -> officeconvertapi.v1.CreateConversionResponse 14, // 17: officeconvertapi.v1.ConversionService.GetConversionStatus:input_type -> officeconvertapi.v1.GetConversionStatusRequest
10, // 18: officeconvertapi.v1.ConversionService.StartConversion:output_type -> officeconvertapi.v1.StartConversionResponse 16, // 18: officeconvertapi.v1.ConversionService.GetSlideDeck:input_type -> officeconvertapi.v1.GetSlideDeckRequest
12, // 19: officeconvertapi.v1.ConversionService.GetConversionStatus:output_type -> officeconvertapi.v1.GetConversionStatusResponse 18, // 19: officeconvertapi.v1.ConversionService.DeleteConversion:input_type -> officeconvertapi.v1.DeleteConversionRequest
14, // 20: officeconvertapi.v1.ConversionService.GetSlideDeck:output_type -> officeconvertapi.v1.GetSlideDeckResponse 11, // 20: officeconvertapi.v1.ConversionService.CreateConversion:output_type -> officeconvertapi.v1.CreateConversionResponse
16, // 21: officeconvertapi.v1.ConversionService.DeleteConversion:output_type -> officeconvertapi.v1.DeleteConversionResponse 13, // 21: officeconvertapi.v1.ConversionService.StartConversion:output_type -> officeconvertapi.v1.StartConversionResponse
17, // [17:22] is the sub-list for method output_type 15, // 22: officeconvertapi.v1.ConversionService.GetConversionStatus:output_type -> officeconvertapi.v1.GetConversionStatusResponse
12, // [12:17] is the sub-list for method input_type 17, // 23: officeconvertapi.v1.ConversionService.GetSlideDeck:output_type -> officeconvertapi.v1.GetSlideDeckResponse
12, // [12:12] is the sub-list for extension type_name 19, // 24: officeconvertapi.v1.ConversionService.DeleteConversion:output_type -> officeconvertapi.v1.DeleteConversionResponse
12, // [12:12] is the sub-list for extension extendee 20, // [20:25] is the sub-list for method output_type
0, // [0:12] is the sub-list for field type_name 15, // [15:20] is the sub-list for method input_type
15, // [15:15] is the sub-list for extension type_name
15, // [15:15] is the sub-list for extension extendee
0, // [0:15] is the sub-list for field type_name
} }
func init() { file_officeconvertapi_v1_conversion_proto_init() } func init() { file_officeconvertapi_v1_conversion_proto_init() }
@@ -1231,13 +1474,14 @@ func file_officeconvertapi_v1_conversion_proto_init() {
file_officeconvertapi_v1_conversion_proto_msgTypes[1].OneofWrappers = []any{ file_officeconvertapi_v1_conversion_proto_msgTypes[1].OneofWrappers = []any{
(*SlideRasterOptions_Jpeg)(nil), (*SlideRasterOptions_Jpeg)(nil),
} }
file_officeconvertapi_v1_conversion_proto_msgTypes[3].OneofWrappers = []any{}
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: 4,
NumMessages: 14, NumMessages: 16,
NumExtensions: 0, NumExtensions: 0,
NumServices: 1, NumServices: 1,
}, },
@@ -7,6 +7,7 @@ from typing import Protocol
from connectrpc.client import ConnectClient, ConnectClientSync from connectrpc.client import ConnectClient, ConnectClientSync
from connectrpc.code import Code from connectrpc.code import Code
from connectrpc.codec import Codec
from connectrpc.compression import Compression from connectrpc.compression import Compression
from connectrpc.errors import ConnectError from connectrpc.errors import ConnectError
from connectrpc.interceptor import Interceptor, InterceptorSync from connectrpc.interceptor import Interceptor, InterceptorSync
@@ -34,7 +35,7 @@ class ConversionService(Protocol):
class ConversionServiceASGIApplication(ConnectASGIApplication[ConversionService]): class ConversionServiceASGIApplication(ConnectASGIApplication[ConversionService]):
def __init__(self, service: ConversionService | AsyncGenerator[ConversionService], *, interceptors: Iterable[Interceptor]=(), read_max_bytes: int | None = None, compressions: Iterable[Compression] | None = None) -> None: def __init__(self, service: ConversionService | AsyncGenerator[ConversionService], *, interceptors: Iterable[Interceptor]=(), read_max_bytes: int | None = None, compressions: Iterable[Compression] | None = None, codecs: Iterable[Codec] | None = None) -> None:
super().__init__( super().__init__(
service=service, service=service,
endpoints=lambda svc: { endpoints=lambda svc: {
@@ -92,6 +93,7 @@ class ConversionServiceASGIApplication(ConnectASGIApplication[ConversionService]
interceptors=interceptors, interceptors=interceptors,
read_max_bytes=read_max_bytes, read_max_bytes=read_max_bytes,
compressions=compressions, compressions=compressions,
codecs=codecs,
) )
@property @property
@@ -202,6 +204,9 @@ class ConversionServiceClient(ConnectClient):
) )
class ConversionServiceSync(Protocol): class ConversionServiceSync(Protocol):
def create_conversion(self, request: officeconvertapi_dot_v1_dot_conversion__pb2.CreateConversionRequest, ctx: RequestContext) -> officeconvertapi_dot_v1_dot_conversion__pb2.CreateConversionResponse: def create_conversion(self, request: officeconvertapi_dot_v1_dot_conversion__pb2.CreateConversionRequest, ctx: RequestContext) -> officeconvertapi_dot_v1_dot_conversion__pb2.CreateConversionResponse:
raise ConnectError(Code.UNIMPLEMENTED, "Not implemented") raise ConnectError(Code.UNIMPLEMENTED, "Not implemented")
@@ -216,7 +221,7 @@ class ConversionServiceSync(Protocol):
class ConversionServiceWSGIApplication(ConnectWSGIApplication): class ConversionServiceWSGIApplication(ConnectWSGIApplication):
def __init__(self, service: ConversionServiceSync, interceptors: Iterable[InterceptorSync]=(), read_max_bytes: int | None = None, compressions: Iterable[Compression] | None = None) -> None: def __init__(self, service: ConversionServiceSync, interceptors: Iterable[InterceptorSync]=(), read_max_bytes: int | None = None, compressions: Iterable[Compression] | None = None, codecs: Iterable[Codec] | None = None) -> None:
super().__init__( super().__init__(
endpoints={ endpoints={
"/officeconvertapi.v1.ConversionService/CreateConversion": EndpointSync.unary( "/officeconvertapi.v1.ConversionService/CreateConversion": EndpointSync.unary(
@@ -273,6 +278,7 @@ class ConversionServiceWSGIApplication(ConnectWSGIApplication):
interceptors=interceptors, interceptors=interceptors,
read_max_bytes=read_max_bytes, read_max_bytes=read_max_bytes,
compressions=compressions, compressions=compressions,
codecs=codecs,
) )
@property @property
@@ -381,3 +387,5 @@ class ConversionServiceClientSync(ConnectClientSync):
headers=headers, headers=headers,
timeout_ms=timeout_ms, timeout_ms=timeout_ms,
) )
File diff suppressed because one or more lines are too long
@@ -35,6 +35,12 @@ class ConversionResolution(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
CONVERSION_RESOLUTION_FHD: _ClassVar[ConversionResolution] CONVERSION_RESOLUTION_FHD: _ClassVar[ConversionResolution]
CONVERSION_RESOLUTION_QHD: _ClassVar[ConversionResolution] CONVERSION_RESOLUTION_QHD: _ClassVar[ConversionResolution]
CONVERSION_RESOLUTION_UHD: _ClassVar[ConversionResolution] CONVERSION_RESOLUTION_UHD: _ClassVar[ConversionResolution]
class NotesFormat(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
__slots__ = ()
NOTES_FORMAT_UNSPECIFIED: _ClassVar[NotesFormat]
NOTES_FORMAT_PLAIN: _ClassVar[NotesFormat]
NOTES_FORMAT_HTML: _ClassVar[NotesFormat]
CONVERSION_STATUS_UNSPECIFIED: ConversionStatus CONVERSION_STATUS_UNSPECIFIED: ConversionStatus
CONVERSION_STATUS_PENDING: ConversionStatus CONVERSION_STATUS_PENDING: ConversionStatus
CONVERSION_STATUS_RUNNING: ConversionStatus CONVERSION_STATUS_RUNNING: ConversionStatus
@@ -52,6 +58,9 @@ CONVERSION_RESOLUTION_HD: ConversionResolution
CONVERSION_RESOLUTION_FHD: ConversionResolution CONVERSION_RESOLUTION_FHD: ConversionResolution
CONVERSION_RESOLUTION_QHD: ConversionResolution CONVERSION_RESOLUTION_QHD: ConversionResolution
CONVERSION_RESOLUTION_UHD: ConversionResolution CONVERSION_RESOLUTION_UHD: ConversionResolution
NOTES_FORMAT_UNSPECIFIED: NotesFormat
NOTES_FORMAT_PLAIN: NotesFormat
NOTES_FORMAT_HTML: NotesFormat
class JpegOutputOptions(_message.Message): class JpegOutputOptions(_message.Message):
__slots__ = ("quality",) __slots__ = ("quality",)
@@ -67,17 +76,45 @@ class SlideRasterOptions(_message.Message):
jpeg: JpegOutputOptions jpeg: JpegOutputOptions
def __init__(self, resolution: _Optional[_Union[ConversionResolution, str]] = ..., jpeg: _Optional[_Union[JpegOutputOptions, _Mapping]] = ...) -> None: ... def __init__(self, resolution: _Optional[_Union[ConversionResolution, str]] = ..., jpeg: _Optional[_Union[JpegOutputOptions, _Mapping]] = ...) -> None: ...
class HtmlFormattingPolicy(_message.Message):
__slots__ = ("ignore_bold", "ignore_italic", "ignore_underline", "ignore_strikethrough", "ignore_font_size", "ignore_color")
IGNORE_BOLD_FIELD_NUMBER: _ClassVar[int]
IGNORE_ITALIC_FIELD_NUMBER: _ClassVar[int]
IGNORE_UNDERLINE_FIELD_NUMBER: _ClassVar[int]
IGNORE_STRIKETHROUGH_FIELD_NUMBER: _ClassVar[int]
IGNORE_FONT_SIZE_FIELD_NUMBER: _ClassVar[int]
IGNORE_COLOR_FIELD_NUMBER: _ClassVar[int]
ignore_bold: bool
ignore_italic: bool
ignore_underline: bool
ignore_strikethrough: bool
ignore_font_size: bool
ignore_color: bool
def __init__(self, ignore_bold: _Optional[bool] = ..., ignore_italic: _Optional[bool] = ..., ignore_underline: _Optional[bool] = ..., ignore_strikethrough: _Optional[bool] = ..., ignore_font_size: _Optional[bool] = ..., ignore_color: _Optional[bool] = ...) -> None: ...
class NotesOptions(_message.Message):
__slots__ = ("format", "html_use_paragraph_tags", "html_policy")
FORMAT_FIELD_NUMBER: _ClassVar[int]
HTML_USE_PARAGRAPH_TAGS_FIELD_NUMBER: _ClassVar[int]
HTML_POLICY_FIELD_NUMBER: _ClassVar[int]
format: NotesFormat
html_use_paragraph_tags: bool
html_policy: HtmlFormattingPolicy
def __init__(self, format: _Optional[_Union[NotesFormat, str]] = ..., html_use_paragraph_tags: _Optional[bool] = ..., html_policy: _Optional[_Union[HtmlFormattingPolicy, _Mapping]] = ...) -> None: ...
class Slide(_message.Message): class Slide(_message.Message):
__slots__ = ("index", "notes_plain", "image_url", "thumbnail_image_url") __slots__ = ("index", "notes_plain", "image_url", "thumbnail_image_url", "notes_html")
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] THUMBNAIL_IMAGE_URL_FIELD_NUMBER: _ClassVar[int]
NOTES_HTML_FIELD_NUMBER: _ClassVar[int]
index: int index: int
notes_plain: str notes_plain: str
image_url: str image_url: str
thumbnail_image_url: str thumbnail_image_url: str
def __init__(self, index: _Optional[int] = ..., notes_plain: _Optional[str] = ..., image_url: _Optional[str] = ..., thumbnail_image_url: _Optional[str] = ...) -> None: ... notes_html: str
def __init__(self, index: _Optional[int] = ..., notes_plain: _Optional[str] = ..., image_url: _Optional[str] = ..., thumbnail_image_url: _Optional[str] = ..., notes_html: _Optional[str] = ...) -> None: ...
class SlideDeck(_message.Message): class SlideDeck(_message.Message):
__slots__ = ("conversion_id", "source_filename", "slides", "created_at", "width", "height", "thumbnail_width", "thumbnail_height") __slots__ = ("conversion_id", "source_filename", "slides", "created_at", "width", "height", "thumbnail_width", "thumbnail_height")
@@ -100,14 +137,16 @@ class SlideDeck(_message.Message):
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: ... 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", "full", "thumbnail") __slots__ = ("source_filename", "full", "thumbnail", "notes")
SOURCE_FILENAME_FIELD_NUMBER: _ClassVar[int] SOURCE_FILENAME_FIELD_NUMBER: _ClassVar[int]
FULL_FIELD_NUMBER: _ClassVar[int] FULL_FIELD_NUMBER: _ClassVar[int]
THUMBNAIL_FIELD_NUMBER: _ClassVar[int] THUMBNAIL_FIELD_NUMBER: _ClassVar[int]
NOTES_FIELD_NUMBER: _ClassVar[int]
source_filename: str source_filename: str
full: SlideRasterOptions full: SlideRasterOptions
thumbnail: SlideRasterOptions thumbnail: SlideRasterOptions
def __init__(self, source_filename: _Optional[str] = ..., full: _Optional[_Union[SlideRasterOptions, _Mapping]] = ..., thumbnail: _Optional[_Union[SlideRasterOptions, _Mapping]] = ...) -> None: ... notes: NotesOptions
def __init__(self, source_filename: _Optional[str] = ..., full: _Optional[_Union[SlideRasterOptions, _Mapping]] = ..., thumbnail: _Optional[_Union[SlideRasterOptions, _Mapping]] = ..., notes: _Optional[_Union[NotesOptions, _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")
@@ -68,6 +68,33 @@ message SlideRasterOptions {
} }
} }
// NotesFormat controls what note representation the server should compute.
enum NotesFormat {
NOTES_FORMAT_UNSPECIFIED = 0;
NOTES_FORMAT_PLAIN = 1;
NOTES_FORMAT_HTML = 2;
}
// HtmlFormattingPolicy configures which formatting features are ignored in HTML mode.
message HtmlFormattingPolicy {
bool ignore_bold = 1;
bool ignore_italic = 2;
bool ignore_underline = 3;
bool ignore_strikethrough = 4;
bool ignore_font_size = 5;
bool ignore_color = 6;
}
// NotesOptions configures note extraction behavior.
message NotesOptions {
// Output format for extracted notes.
NotesFormat format = 1;
// If true, wrap PPTX paragraphs as <p> blocks in HTML mode. If false, emit <br/> only.
optional bool html_use_paragraph_tags = 2;
// Formatting policy for HTML mode.
HtmlFormattingPolicy html_policy = 3;
}
// 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;
@@ -76,6 +103,8 @@ message Slide {
string image_url = 3; string image_url = 3;
// Thumbnail rendered image URL. // Thumbnail rendered image URL.
string thumbnail_image_url = 4; string thumbnail_image_url = 4;
// Optional, sanitized HTML version of notes when requested.
string notes_html = 5;
} }
// SlideDeck is the final structured conversion artifact. // SlideDeck is the final structured conversion artifact.
@@ -100,6 +129,7 @@ message CreateConversionRequest {
string source_filename = 1; string source_filename = 1;
SlideRasterOptions full = 2; SlideRasterOptions full = 2;
SlideRasterOptions thumbnail = 3; SlideRasterOptions thumbnail = 3;
NotesOptions notes = 4;
} }
// CreateConversionResponse returns upload details for the session. // CreateConversionResponse returns upload details for the session.
@@ -1,19 +1,27 @@
"""Public conversion APIs for the officeconvert Python library.""" """Public conversion APIs for the officeconvert Python library."""
from officeconvert.conversion import ( from officeconvert.conversion import (
HtmlFormattingPolicy,
NotesFormat,
NotesOptions,
SlideArtifact, SlideArtifact,
SlideDeckResult, SlideDeckResult,
convert_pptx_to_pdf, convert_pptx_to_pdf,
convert_pptx_to_slidedeck, convert_pptx_to_slidedeck,
extract_slide_notes, extract_slide_notes,
extract_slide_notes_html,
render_pdf_to_images, render_pdf_to_images,
) )
__all__ = [ __all__ = [
"HtmlFormattingPolicy",
"NotesFormat",
"NotesOptions",
"SlideArtifact", "SlideArtifact",
"SlideDeckResult", "SlideDeckResult",
"convert_pptx_to_pdf", "convert_pptx_to_pdf",
"convert_pptx_to_slidedeck", "convert_pptx_to_slidedeck",
"extract_slide_notes", "extract_slide_notes",
"extract_slide_notes_html",
"render_pdf_to_images", "render_pdf_to_images",
] ]
@@ -4,6 +4,8 @@ from __future__ import annotations
from collections.abc import Callable from collections.abc import Callable
from dataclasses import dataclass from dataclasses import dataclass
from enum import Enum
import html
import logging import logging
import math import math
from pathlib import Path from pathlib import Path
@@ -13,6 +15,28 @@ from typing import Iterable
from pptx import Presentation from pptx import Presentation
class NotesFormat(str, Enum):
PLAIN = "plain"
HTML = "html"
@dataclass(frozen=True, slots=True)
class HtmlFormattingPolicy:
ignore_bold: bool = False
ignore_italic: bool = False
ignore_underline: bool = False
ignore_strikethrough: bool = False
ignore_font_size: bool = False
ignore_color: bool = False
@dataclass(frozen=True, slots=True)
class NotesOptions:
format: NotesFormat = NotesFormat.PLAIN
html_use_paragraph_tags: bool = True
html_policy: HtmlFormattingPolicy = HtmlFormattingPolicy()
@dataclass(frozen=True, slots=True) @dataclass(frozen=True, slots=True)
class SlideArtifact: class SlideArtifact:
"""Represents one converted slide image and its extracted notes.""" """Represents one converted slide image and its extracted notes."""
@@ -21,6 +45,7 @@ class SlideArtifact:
image_path: Path image_path: Path
thumbnail_path: Path thumbnail_path: Path
notes_plain: str notes_plain: str
notes_html: str = ""
@dataclass(frozen=True, slots=True) @dataclass(frozen=True, slots=True)
@@ -290,14 +315,52 @@ def extract_slide_notes(pptx_path: Path) -> list[str]:
if not pptx_path.exists(): if not pptx_path.exists():
raise FileNotFoundError(f"source PPTX does not exist: {pptx_path}") raise FileNotFoundError(f"source PPTX does not exist: {pptx_path}")
plain, _html = _extract_slide_notes(pptx_path, options=NotesOptions(format=NotesFormat.PLAIN))
return plain
def extract_slide_notes_html(
pptx_path: Path,
*,
options: NotesOptions | None = None,
) -> list[str]:
"""Extract sanitized HTML notes for each slide in slide index order.
The returned HTML is sanitized-by-construction:
- text content is always escaped
- only a small allowlist of tags is emitted: p, br, strong, em, u, s, span
- only `style` attributes generated by this function are emitted on span tags
"""
if not pptx_path.exists():
raise FileNotFoundError(f"source PPTX does not exist: {pptx_path}")
resolved = options or NotesOptions(format=NotesFormat.HTML)
if resolved.format != NotesFormat.HTML:
raise ValueError("extract_slide_notes_html requires NotesOptions.format=NotesFormat.HTML")
_plain, html_notes = _extract_slide_notes(pptx_path, options=resolved)
return html_notes
def _extract_slide_notes(
pptx_path: Path,
*,
options: NotesOptions,
) -> tuple[list[str], list[str]]:
presentation = Presentation(str(pptx_path.resolve())) presentation = Presentation(str(pptx_path.resolve()))
notes: list[str] = [] want_html = options.format == NotesFormat.HTML
plain_notes: list[str] = []
html_notes: list[str] = []
for slide in presentation.slides: for slide in presentation.slides:
if not slide.has_notes_slide: if not slide.has_notes_slide:
notes.append("") plain_notes.append("")
html_notes.append("")
continue continue
notes.append(_extract_notes_text(slide.notes_slide.shapes)) plain = _extract_notes_text(slide.notes_slide.shapes)
return notes plain_notes.append(plain)
html_notes.append(_extract_notes_html(slide.notes_slide.shapes, options=options) if want_html else "")
return plain_notes, html_notes
def convert_pptx_to_slidedeck( def convert_pptx_to_slidedeck(
@@ -314,6 +377,7 @@ def convert_pptx_to_slidedeck(
pptx_to_pdf_per_slide_timeout_s: int = 3, pptx_to_pdf_per_slide_timeout_s: int = 3,
pdf_to_images_base_timeout_s: int = 30, pdf_to_images_base_timeout_s: int = 30,
pdf_to_images_per_slide_timeout_s: int = 8, pdf_to_images_per_slide_timeout_s: int = 8,
notes_options: NotesOptions | None = None,
progress_callback: ProgressCallback | None = None, progress_callback: ProgressCallback | None = None,
) -> SlideDeckResult: ) -> SlideDeckResult:
"""Convert a PPTX into rendered images and extracted notes. """Convert a PPTX into rendered images and extracted notes.
@@ -344,8 +408,9 @@ def convert_pptx_to_slidedeck(
full_image_dir = work_dir / "slides_full" full_image_dir = work_dir / "slides_full"
thumbnail_image_dir = work_dir / "slides_thumb" thumbnail_image_dir = work_dir / "slides_thumb"
resolved_notes_options = notes_options or NotesOptions(format=NotesFormat.PLAIN)
_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_plain, notes_html = _extract_slide_notes(pptx_path, options=resolved_notes_options)
_emit_progress(progress_callback, PHASE_EXTRACTING_NOTES, 1, 1) _emit_progress(progress_callback, PHASE_EXTRACTING_NOTES, 1, 1)
slide_width, slide_height = _read_slide_size_emu(pptx_path) slide_width, slide_height = _read_slide_size_emu(pptx_path)
output_width, output_height = _infer_output_dimensions_from_slide_size( output_width, output_height = _infer_output_dimensions_from_slide_size(
@@ -370,7 +435,7 @@ def convert_pptx_to_slidedeck(
output_width_px=thumbnail_width, output_width_px=thumbnail_width,
output_height_px=thumbnail_height, output_height_px=thumbnail_height,
) )
slide_count = len(notes) slide_count = len(notes_plain)
pptx_to_pdf_timeout = _compute_adaptive_timeout( pptx_to_pdf_timeout = _compute_adaptive_timeout(
slide_count=slide_count, slide_count=slide_count,
timeout_cap_s=pptx_to_pdf_timeout_s, timeout_cap_s=pptx_to_pdf_timeout_s,
@@ -454,15 +519,15 @@ def convert_pptx_to_slidedeck(
), ),
) )
if len(full_image_paths) != len(notes): if len(full_image_paths) != len(notes_plain):
raise ValueError( raise ValueError(
"rendered full-size slide count does not match note count: " "rendered full-size slide count does not match note count: "
f"{len(full_image_paths)} image(s) vs {len(notes)} note entries" f"{len(full_image_paths)} image(s) vs {len(notes_plain)} note entries"
) )
if len(thumbnail_image_paths) != len(notes): if len(thumbnail_image_paths) != len(notes_plain):
raise ValueError( raise ValueError(
"rendered thumbnail slide count does not match note count: " "rendered thumbnail slide count does not match note count: "
f"{len(thumbnail_image_paths)} image(s) vs {len(notes)} note entries" f"{len(thumbnail_image_paths)} image(s) vs {len(notes_plain)} note entries"
) )
slides = [ slides = [
@@ -470,10 +535,11 @@ def convert_pptx_to_slidedeck(
index=index, index=index,
image_path=image_path, image_path=image_path,
thumbnail_path=thumbnail_path, thumbnail_path=thumbnail_path,
notes_plain=note, notes_plain=plain,
notes_html=html,
) )
for index, (image_path, thumbnail_path, note) in enumerate( for index, (image_path, thumbnail_path, plain, html) in enumerate(
zip(full_image_paths, thumbnail_image_paths, notes), zip(full_image_paths, thumbnail_image_paths, notes_plain, notes_html),
start=1, start=1,
) )
] ]
@@ -632,3 +698,102 @@ def _extract_notes_text(shapes: Iterable[object]) -> str:
if text: if text:
segments.append(text) segments.append(text)
return "\n\n".join(segments).strip() return "\n\n".join(segments).strip()
def _extract_notes_html(shapes: Iterable[object], *, options: NotesOptions) -> str:
"""Extract sanitized HTML from note shapes while preserving paragraph boundaries."""
paragraphs_html: list[str] = []
for shape in shapes:
text_frame = getattr(shape, "text_frame", None)
if text_frame is None:
continue
for paragraph in getattr(text_frame, "paragraphs", []) or []:
paragraph_html = _paragraph_to_html(paragraph, options=options)
if paragraph_html:
paragraphs_html.append(paragraph_html)
if not paragraphs_html:
return ""
if options.html_use_paragraph_tags:
return "".join(paragraphs_html)
# Flatten paragraph boundaries into <br/> separators (double-break between paragraphs).
return "<br/><br/>".join(
p.removeprefix("<p>").removesuffix("</p>") if p.startswith("<p>") else p
for p in paragraphs_html
)
def _paragraph_to_html(paragraph: object, *, options: NotesOptions) -> str:
policy = options.html_policy
parts: list[str] = []
for run in getattr(paragraph, "runs", []) or []:
text = getattr(run, "text", "") or ""
if not text:
continue
# Escape first, then re-introduce only allowlisted tags.
escaped = html.escape(text, quote=False)
escaped = escaped.replace("\n", "<br/>")
font = getattr(run, "font", None)
style = ""
if font is not None:
if not policy.ignore_color:
rgb_obj = getattr(getattr(font, "color", None), "rgb", None)
if rgb_obj is not None:
rgb = str(rgb_obj)
if isinstance(rgb, str) and len(rgb) == 6:
style += f"color: #{rgb};"
if not policy.ignore_font_size:
size = getattr(font, "size", None)
pt = getattr(size, "pt", None)
if isinstance(pt, (int, float)):
# Clamp to a sane range to avoid pathological CSS.
if 0.5 <= pt <= 512:
pt_str = str(int(pt)) if float(pt).is_integer() else str(round(float(pt), 2))
style += f"font-size: {pt_str}pt;"
content = escaped
if style:
content = f"<span style=\"{style}\">{content}</span>"
if font is not None:
if not policy.ignore_bold and getattr(font, "bold", None) is True:
content = f"<strong>{content}</strong>"
if not policy.ignore_italic and getattr(font, "italic", None) is True:
content = f"<em>{content}</em>"
if not policy.ignore_underline and _truthy_underline(getattr(font, "underline", None)):
content = f"<u>{content}</u>"
if not policy.ignore_strikethrough and _truthy_strikethrough(run):
content = f"<s>{content}</s>"
parts.append(content)
inner = "".join(parts).strip()
if not inner:
return ""
if options.html_use_paragraph_tags:
return f"<p>{inner}</p>"
return inner
def _truthy_underline(value: object) -> bool:
# python-pptx may represent underline as True/False/None or an enum value.
if value is True:
return True
if value in (None, False):
return False
# Any non-falsey, non-None value implies underline style.
return True
def _truthy_strikethrough(run: object) -> bool:
# python-pptx doesn't currently expose a first-class Font.strike property; detect via XML.
xml_run = getattr(run, "_r", None)
rpr = getattr(xml_run, "rPr", None)
if rpr is None:
return False
strike_val = rpr.get("strike")
if strike_val in (None, "noStrike", "false", "0"):
return False
return True
@@ -0,0 +1,111 @@
import tempfile
import unittest
from pathlib import Path
from pptx import Presentation
from pptx.dml.color import RGBColor
from pptx.util import Pt
from officeconvert.conversion import HtmlFormattingPolicy, NotesFormat, NotesOptions, extract_slide_notes_html
def _build_pptx_with_formatted_notes(tmp_path: Path) -> Path:
prs = Presentation()
slide = prs.slides.add_slide(prs.slide_layouts[5]) # blank
notes = slide.notes_slide
tf = notes.notes_text_frame
# First paragraph: mixed runs with formatting.
p1 = tf.paragraphs[0]
p1.text = ""
r1 = p1.add_run()
r1.text = "BoldRed24 "
r1.font.bold = True
r1.font.color.rgb = RGBColor(0xFF, 0x00, 0x00)
r1.font.size = Pt(24)
r2 = p1.add_run()
r2.text = "UnderStrike"
r2.font.underline = True
# python-pptx does not currently expose a first-class API for strikethrough,
# but the underlying DrawingML uses a:rPr@strike="sngStrike" or "dblStrike".
r2._r.rPr.set("strike", "sngStrike")
# Second paragraph: ensure escaping is applied.
p2 = tf.add_paragraph()
r3 = p2.add_run()
r3.text = "<script>alert(1)</script>"
r3.font.italic = True
out = tmp_path / "notes.pptx"
prs.save(out)
return out
class NotesHtmlExtractionTests(unittest.TestCase):
def test_extracts_basic_rich_text_and_escapes(self) -> None:
with tempfile.TemporaryDirectory() as d:
pptx_path = _build_pptx_with_formatted_notes(Path(d))
html_notes = extract_slide_notes_html(
pptx_path,
options=NotesOptions(format=NotesFormat.HTML, html_use_paragraph_tags=True),
)
self.assertEqual(len(html_notes), 1)
html_out = html_notes[0]
# Paragraphs are wrapped in <p>.
self.assertIn("<p>", html_out)
self.assertIn("</p>", html_out)
# Formatting tags.
self.assertIn("<strong>", html_out)
self.assertIn("<em>", html_out)
self.assertIn("<u>", html_out)
self.assertIn("<s>", html_out)
# Style tags for RGB and font size.
self.assertIn('style="color: #FF0000;font-size: 24pt;"', html_out)
# Escaping: no raw <script> tag survives.
self.assertNotIn("<script>", html_out)
self.assertIn("&lt;script&gt;alert(1)&lt;/script&gt;", html_out)
def test_ignore_policy_prunes_styles_and_tags(self) -> None:
with tempfile.TemporaryDirectory() as d:
pptx_path = _build_pptx_with_formatted_notes(Path(d))
html_notes = extract_slide_notes_html(
pptx_path,
options=NotesOptions(
format=NotesFormat.HTML,
html_use_paragraph_tags=True,
html_policy=HtmlFormattingPolicy(
ignore_bold=True,
ignore_color=True,
ignore_font_size=True,
),
),
)
html_out = html_notes[0]
self.assertNotIn("<strong>", html_out)
self.assertNotIn("color:", html_out)
self.assertNotIn("font-size:", html_out)
def test_br_mode_uses_double_break_between_paragraphs(self) -> None:
with tempfile.TemporaryDirectory() as d:
pptx_path = _build_pptx_with_formatted_notes(Path(d))
html_notes = extract_slide_notes_html(
pptx_path,
options=NotesOptions(format=NotesFormat.HTML, html_use_paragraph_tags=False),
)
html_out = html_notes[0]
self.assertNotIn("<p>", html_out)
self.assertIn("<br/><br/>", html_out)
if __name__ == "__main__":
unittest.main()
@@ -23,6 +23,7 @@ class ConversionSession:
thumbnail_resolution: conversion_pb2.ConversionResolution thumbnail_resolution: conversion_pb2.ConversionResolution
full_jpeg_quality: int full_jpeg_quality: int
thumbnail_jpeg_quality: int thumbnail_jpeg_quality: int
notes: conversion_pb2.NotesOptions | None = None
bucket_name: str bucket_name: str
upload_object_key: str upload_object_key: str
status: conversion_pb2.ConversionStatus status: conversion_pb2.ConversionStatus
@@ -18,6 +18,9 @@ from google.protobuf.timestamp_pb2 import Timestamp
from officeconvert import SlideArtifact, convert_pptx_to_slidedeck from officeconvert import SlideArtifact, convert_pptx_to_slidedeck
from officeconvert.conversion import ( from officeconvert.conversion import (
ConversionTimeoutError, ConversionTimeoutError,
HtmlFormattingPolicy,
NotesFormat,
NotesOptions,
PHASE_EXTRACTING_NOTES, PHASE_EXTRACTING_NOTES,
PHASE_PDF_TO_IMAGES, PHASE_PDF_TO_IMAGES,
PHASE_PPTX_TO_PDF, PHASE_PPTX_TO_PDF,
@@ -49,6 +52,37 @@ _DEFAULT_FULL_RESOLUTION = conversion_pb2.CONVERSION_RESOLUTION_FHD
_DEFAULT_THUMBNAIL_RESOLUTION = conversion_pb2.CONVERSION_RESOLUTION_SD _DEFAULT_THUMBNAIL_RESOLUTION = conversion_pb2.CONVERSION_RESOLUTION_SD
_DEFAULT_FULL_JPEG_QUALITY = 85 _DEFAULT_FULL_JPEG_QUALITY = 85
_DEFAULT_THUMBNAIL_JPEG_QUALITY = 75 _DEFAULT_THUMBNAIL_JPEG_QUALITY = 75
_DEFAULT_NOTES_FORMAT = conversion_pb2.NOTES_FORMAT_PLAIN
_DEFAULT_HTML_USE_PARAGRAPH_TAGS = True
def _to_library_notes_options(
notes: conversion_pb2.NotesOptions | None,
) -> NotesOptions | None:
if notes is None:
return None
fmt = notes.format or _DEFAULT_NOTES_FORMAT
library_format = NotesFormat.HTML if fmt == conversion_pb2.NOTES_FORMAT_HTML else NotesFormat.PLAIN
html_use_paragraph_tags = _DEFAULT_HTML_USE_PARAGRAPH_TAGS
if notes.HasField("html_use_paragraph_tags"):
html_use_paragraph_tags = bool(notes.html_use_paragraph_tags)
policy_proto = notes.html_policy
policy = HtmlFormattingPolicy(
ignore_bold=bool(policy_proto.ignore_bold),
ignore_italic=bool(policy_proto.ignore_italic),
ignore_underline=bool(policy_proto.ignore_underline),
ignore_strikethrough=bool(policy_proto.ignore_strikethrough),
ignore_font_size=bool(policy_proto.ignore_font_size),
ignore_color=bool(policy_proto.ignore_color),
)
return NotesOptions(
format=library_format,
html_use_paragraph_tags=html_use_paragraph_tags,
html_policy=policy,
)
class ConversionServiceImpl(conversion_connect.ConversionService): class ConversionServiceImpl(conversion_connect.ConversionService):
@@ -124,6 +158,7 @@ class ConversionServiceImpl(conversion_connect.ConversionService):
thumbnail_resolution=thumbnail_resolution, thumbnail_resolution=thumbnail_resolution,
full_jpeg_quality=full_jpeg_quality, full_jpeg_quality=full_jpeg_quality,
thumbnail_jpeg_quality=thumbnail_jpeg_quality, thumbnail_jpeg_quality=thumbnail_jpeg_quality,
notes=request.notes if request.HasField("notes") else None,
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,
@@ -280,6 +315,7 @@ class ConversionServiceImpl(conversion_connect.ConversionService):
pptx_to_pdf_per_slide_timeout_s=self._config.conversion_pptx_to_pdf_per_slide_timeout_seconds, pptx_to_pdf_per_slide_timeout_s=self._config.conversion_pptx_to_pdf_per_slide_timeout_seconds,
pdf_to_images_base_timeout_s=self._config.conversion_pdf_to_images_base_timeout_seconds, pdf_to_images_base_timeout_s=self._config.conversion_pdf_to_images_base_timeout_seconds,
pdf_to_images_per_slide_timeout_s=self._config.conversion_pdf_to_images_per_slide_timeout_seconds, pdf_to_images_per_slide_timeout_s=self._config.conversion_pdf_to_images_per_slide_timeout_seconds,
notes_options=_to_library_notes_options(session.notes),
progress_callback=lambda phase_name, current, max_value: self._set_session_progress_from_name( progress_callback=lambda phase_name, current, max_value: self._set_session_progress_from_name(
session, session,
phase_name=phase_name, phase_name=phase_name,
@@ -428,6 +464,7 @@ class ConversionServiceImpl(conversion_connect.ConversionService):
conversion_pb2.Slide( conversion_pb2.Slide(
index=slide.index, index=slide.index,
notes_plain=slide.notes_plain, notes_plain=slide.notes_plain,
notes_html=slide.notes_html,
image_url=image_url, image_url=image_url,
thumbnail_image_url=thumbnail_image_url, thumbnail_image_url=thumbnail_image_url,
) )