Viva la File, my boys, viva la File!

pull/108/head
Ian Byrd 7 years ago
parent b6938a118c
commit 7316e92265
No known key found for this signature in database
GPG Key ID: 598F598CA3B8055F

@ -100,11 +100,11 @@ func (b *Bot) sendObject(f *File, what string, params map[string]string) (*Messa
var respJSON []byte var respJSON []byte
var err error var err error
if f.Exists() { if f.InCloud() {
params[what] = f.FileID params[what] = f.FileID
respJSON, err = b.sendCommand(sendWhat, params) respJSON, err = b.sendCommand(sendWhat, params)
} else { } else {
respJSON, err = b.sendFile(sendWhat, what, f.filename, params) respJSON, err = b.sendFile(sendWhat, what, f.FileLocal, params)
} }
if err != nil { if err != nil {

@ -1,7 +1,7 @@
package telebot package telebot
import ( import (
"fmt" "net/url"
"os" "os"
) )
@ -9,32 +9,61 @@ import (
type File struct { type File struct {
FileID string `json:"file_id"` FileID string `json:"file_id"`
FileSize int `json:"file_size"` FileSize int `json:"file_size"`
// file on telegram server https://core.telegram.org/bots/api#file
FilePath string `json:"file_path"` FilePath string `json:"file_path"`
// Local absolute path to file on local file system. // file on local file system.
filename string FileLocal string
// file on the internet
FileURL *url.URL
}
// FromDisk constructs a new local (on-disk) file object.
//
// Note, it returns File, not *File for a very good reason:
// in telebot, File is pretty much an embeddable struct,
// so upon uploading media you'll need to set embedded File
// with something. NewFile() returning File makes it a one-liner.
//
// photo := &tb.Photo{File: tb.FromDisk("chicken.jpg")}
//
func FromDisk(filename string) File {
return File{FileLocal: filename}
} }
// NewFile attempts to create a File object, leading to a real // FromURL constructs a new file on provided HTTPS URL.
// file on the file system, that could be uploaded later.
// //
// Notice that NewFile doesn't upload file, but only creates // Note, it returns File, not *File for a very good reason:
// a descriptor for it. // in telebot, File is pretty much an embeddable struct,
func NewFile(path string) (File, error) { // so upon uploading media you'll need to set embedded File
if _, err := os.Stat(path); os.IsNotExist(err) { // with something. NewFile() returning File makes it a one-liner.
return File{}, fmt.Errorf("telebot: '%s' does not exist", path) //
// photo := &tb.Photo{File: tb.FromURL("https://site.com/picture.jpg")}
//
func FromURL(u *url.URL) File {
return File{FileURL: u}
}
func (f *File) importLocal(g *File) {
if !g.OnDisk() {
return
} }
return File{filename: path}, nil f.FileLocal = g.FileLocal
} }
// Exists says whether the file presents on Telegram servers or not. // InCloud tells whether the file is present on Telegram servers.
func (f File) Exists() bool { func (f *File) InCloud() bool {
return f.FileID != "" return f.FileID != ""
} }
// Local returns location of file on local file system, if it's // OnDisk will return true if file is present on disk.
// actually there, otherwise returns empty string. func (f *File) OnDisk() bool {
func (f File) Local() string { if _, err := os.Stat(f.FileLocal); err != nil {
return f.filename return false
}
return true
} }

@ -1,6 +1,21 @@
package telebot package telebot
// Photo object represents a photo (with or without caption). import (
"encoding/json"
"fmt"
)
type photoSize struct {
File
Width int `json:"width"`
Height int `json:"height"`
// (Optional)
Caption string `json:"caption,omitempty"`
}
// Photo object represents a single photo file.
type Photo struct { type Photo struct {
File File
@ -11,6 +26,31 @@ type Photo struct {
Caption string `json:"caption,omitempty"` Caption string `json:"caption,omitempty"`
} }
func (p *Photo) UnmarshalJSON(jsonStr []byte) error {
fmt.Println(string(jsonStr))
var hq photoSize
if jsonStr[0] == '{' {
if err := json.Unmarshal(jsonStr, &hq); err != nil {
return err
}
} else {
var sizes []photoSize
if err := json.Unmarshal(jsonStr, &sizes); err != nil {
return err
}
hq = sizes[len(sizes)-1]
}
p.File = hq.File
p.Width = hq.Width
p.Height = hq.Height
return nil
}
// Audio object represents an audio file. // Audio object represents an audio file.
type Audio struct { type Audio struct {
File File

@ -60,8 +60,8 @@ type Message struct {
// For a general file, information about it. // For a general file, information about it.
Document *Document `json:"document"` Document *Document `json:"document"`
// For a photo, all available sizes (thumnails). // For a photo, all available sizes (thumbnails).
Photo []Photo `json:"photo"` Photo *Photo `json:"photo"`
// For a sticker, information about it. // For a sticker, information about it.
Sticker *Sticker `json:"sticker"` Sticker *Sticker `json:"sticker"`

@ -31,10 +31,8 @@ func (p *Photo) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error) {
return nil, err return nil, err
} }
thumbnails := msg.Photo msg.Photo.File.importLocal(&p.File)
fname := p.filename *p = *msg.Photo
p.File = thumbnails[len(thumbnails)-1].File
p.filename = fname
return msg, nil return msg, nil
} }
@ -51,9 +49,8 @@ func (a *Audio) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error) {
return nil, err return nil, err
} }
fname := a.filename msg.Audio.File.importLocal(&a.File)
*a = *msg.Audio *a = *msg.Audio
a.filename = fname
return msg, nil return msg, nil
} }
@ -70,9 +67,8 @@ func (d *Document) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error
return nil, err return nil, err
} }
fname := d.filename msg.Document.File.importLocal(&d.File)
*d = *msg.Document *d = *msg.Document
d.filename = fname
return msg, nil return msg, nil
} }
@ -88,9 +84,8 @@ func (s *Sticker) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error)
return nil, err return nil, err
} }
fname := s.filename msg.Sticker.File.importLocal(&s.File)
*s = *msg.Sticker *s = *msg.Sticker
s.filename = fname
return msg, nil return msg, nil
} }
@ -107,9 +102,8 @@ func (v *Video) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error) {
return nil, err return nil, err
} }
fname := v.filename msg.Video.File.importLocal(&v.File)
*v = *msg.Video *v = *msg.Video
v.filename = fname
return msg, nil return msg, nil
} }
@ -125,9 +119,8 @@ func (v *Voice) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, error) {
return nil, err return nil, err
} }
fname := v.filename msg.Voice.File.importLocal(&v.File)
*v = *msg.Voice *v = *msg.Voice
v.filename = fname
return msg, nil return msg, nil
} }
@ -143,9 +136,8 @@ func (v *VideoNote) Send(b *Bot, to Recipient, opt *SendOptions) (*Message, erro
return nil, err return nil, err
} }
fname := v.filename msg.VideoNote.File.importLocal(&v.File)
*v = *msg.VideoNote *v = *msg.VideoNote
v.filename = fname
return msg, nil return msg, nil
} }

Loading…
Cancel
Save