diff options
author | Bohdan Horbeshko <bodqhrohro@gmail.com> | 2023-06-01 23:37:38 +0300 |
---|---|---|
committer | Bohdan Horbeshko <bodqhrohro@gmail.com> | 2023-06-01 23:37:38 +0300 |
commit | 8663a29e157aae6e68cc880a86b3a666da37bfc9 (patch) | |
tree | 8071a4381276bf743ca21a5a5b8da4930054fd5d /telegram/utils.go | |
parent | 75f0532193440294f4bbf7cd687174b5e9a16249 (diff) |
Add /vcard command
Diffstat (limited to 'telegram/utils.go')
-rw-r--r-- | telegram/utils.go | 129 |
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 +} |