aboutsummaryrefslogtreecommitdiff
path: root/telegram/utils.go
diff options
context:
space:
mode:
authorBohdan Horbeshko <bodqhrohro@gmail.com>2023-06-01 23:37:38 +0300
committerBohdan Horbeshko <bodqhrohro@gmail.com>2023-06-01 23:37:38 +0300
commit8663a29e157aae6e68cc880a86b3a666da37bfc9 (patch)
tree8071a4381276bf743ca21a5a5b8da4930054fd5d /telegram/utils.go
parent75f0532193440294f4bbf7cd687174b5e9a16249 (diff)
Add /vcard command
Diffstat (limited to 'telegram/utils.go')
-rw-r--r--telegram/utils.go129
1 files changed, 108 insertions, 21 deletions
diff --git a/telegram/utils.go b/telegram/utils.go
index 9a247c4..851c6c1 100644
--- a/telegram/utils.go
+++ b/telegram/utils.go
@@ -24,6 +24,16 @@ import (
"github.com/zelenin/go-tdlib/client"
)
+type VCardInfo struct {
+ Fn string
+ Photo *client.File
+ Nickname string
+ Given string
+ Family string
+ Tel string
+ Info string
+}
+
var errOffline = errors.New("TDlib instance is offline")
var spaceRegex = regexp.MustCompile(`\s+`)
@@ -207,7 +217,7 @@ func (c *Client) ProcessStatusUpdate(chatID int64, status string, show string, o
var photo string
if chat != nil && chat.Photo != nil {
- file, path, err := c.OpenPhotoFile(chat.Photo.Small, 1)
+ file, path, err := c.ForceOpenFile(chat.Photo.Small, 1)
if err == nil {
defer file.Close()
@@ -408,6 +418,20 @@ func (c *Client) formatForward(fwd *client.MessageForwardInfo) string {
}
func (c *Client) formatFile(file *client.File, compact bool) (string, string) {
+ if file == nil {
+ return "", ""
+ }
+ src, link := c.PermastoreFile(file, false)
+
+ if compact {
+ return link, link
+ } else {
+ return fmt.Sprintf("%s (%v kbytes) | %s", filepath.Base(src), file.Size/1024, link), link
+ }
+}
+
+// PermastoreFile steals a file out of TDlib control into an independent shared directory
+func (c *Client) PermastoreFile(file *client.File, clone bool) (string, string) {
log.Debugf("file: %#v", file)
if file == nil || file.Local == nil || file.Remote == nil {
return "", ""
@@ -434,18 +458,57 @@ func (c *Client) formatFile(file *client.File, compact bool) (string, string) {
dest := c.content.Path + "/" + basename // destination path
link = c.content.Link + "/" + basename // download link
- // move
- err = os.Rename(src, dest)
- if err != nil {
- linkErr := err.(*os.LinkError)
- if linkErr.Err.Error() == "file exists" {
- log.Warn(err.Error())
+ if clone {
+ file, path, err := c.ForceOpenFile(file, 1)
+ if err == nil {
+ defer file.Close()
+
+ // mode
+ mode := os.FileMode(0644)
+ fi, err := os.Stat(path)
+ if err == nil {
+ mode = fi.Mode().Perm()
+ }
+
+ // create destination
+ tempFile, err := os.OpenFile(dest, os.O_CREATE|os.O_EXCL|os.O_WRONLY, mode)
+ if err != nil {
+ pathErr := err.(*os.PathError)
+ if pathErr.Err.Error() == "file exists" {
+ log.Warn(err.Error())
+ return src, link
+ } else {
+ log.Errorf("File creation error: %v", err)
+ return "<ERROR>", ""
+ }
+ }
+ defer tempFile.Close()
+ // copy
+ _, err = io.Copy(tempFile, file)
+ if err != nil {
+ log.Errorf("File copying error: %v", err)
+ return "<ERROR>", ""
+ }
+ } else if path != "" {
+ log.Errorf("Source file does not exist: %v", path)
+ return "<ERROR>", ""
} else {
- log.Errorf("File moving error: %v", err)
+ log.Errorf("PHOTO: %#v", err.Error())
return "<ERROR>", ""
}
+ } else {
+ // move
+ err = os.Rename(src, dest)
+ if err != nil {
+ linkErr := err.(*os.LinkError)
+ if linkErr.Err.Error() == "file exists" {
+ log.Warn(err.Error())
+ } else {
+ log.Errorf("File moving error: %v", err)
+ return "<ERROR>", ""
+ }
+ }
}
- gateway.CachedStorageSize += size64
// chown
if c.content.User != "" {
@@ -464,13 +527,12 @@ func (c *Client) formatFile(file *client.File, compact bool) (string, string) {
log.Errorf("Wrong user name for chown: %v", err)
}
}
- }
- if compact {
- return link, link
- } else {
- return fmt.Sprintf("%s (%v kbytes) | %s", filepath.Base(src), file.Size/1024, link), link
+ // copy or move should have succeeded at this point
+ gateway.CachedStorageSize += size64
}
+
+ return src, link
}
func (c *Client) formatBantime(hours int64) int32 {
@@ -1148,20 +1210,20 @@ func (c *Client) DownloadFile(id int32, priority int32, synchronous bool) (*clie
})
}
-// OpenPhotoFile reliably obtains a photo if possible
-func (c *Client) OpenPhotoFile(photoFile *client.File, priority int32) (*os.File, string, error) {
- if photoFile == nil {
- return nil, "", errors.New("Photo file not found")
+// ForceOpenFile reliably obtains a file if possible
+func (c *Client) ForceOpenFile(tgFile *client.File, priority int32) (*os.File, string, error) {
+ if tgFile == nil {
+ return nil, "", errors.New("File not found")
}
- path := photoFile.Local.Path
+ path := tgFile.Local.Path
file, err := os.Open(path)
if err == nil {
return file, path, nil
} else
// obtain the photo right now if still not downloaded
- if !photoFile.Local.IsDownloadingCompleted {
- tdFile, tdErr := c.DownloadFile(photoFile.Id, priority, true)
+ if !tgFile.Local.IsDownloadingCompleted {
+ tdFile, tdErr := c.DownloadFile(tgFile.Id, priority, true)
if tdErr == nil {
path = tdFile.Local.Path
file, err = os.Open(path)
@@ -1248,3 +1310,28 @@ func (c *Client) prepareDiskSpace(size uint64) {
}
}
}
+
+func (c *Client) GetVcardInfo(toID int64) (VCardInfo, error) {
+ var info VCardInfo
+ chat, user, err := c.GetContactByID(toID, nil)
+ if err != nil {
+ return info, err
+ }
+
+ if chat != nil {
+ info.Fn = chat.Title
+
+ if chat.Photo != nil {
+ info.Photo = chat.Photo.Small
+ }
+ info.Info = c.GetChatDescription(chat)
+ }
+ if user != nil {
+ info.Nickname = user.Username
+ info.Given = user.FirstName
+ info.Family = user.LastName
+ info.Tel = user.PhoneNumber
+ }
+
+ return info, nil
+}