Move downloaded files to a permanent location
This commit is contained in:
parent
4307f85a04
commit
699d75552a
|
@ -4,6 +4,7 @@
|
|||
:path: '/var/www/telegabber/content' # webserver workdir
|
||||
:link: 'http://tlgrm.localhost/content' # webserver public address
|
||||
:upload: 'https:///xmppfiles.localhost' # xmpp http upload address
|
||||
:user: 'www-data' # owner of content files
|
||||
:tdlib_verbosity: 1
|
||||
:tdlib:
|
||||
:datadir: './sessions/'
|
||||
|
|
|
@ -38,6 +38,7 @@ type TelegramContentConfig struct {
|
|||
Path string `yaml:":path"`
|
||||
Link string `yaml:":link"`
|
||||
Upload string `yaml:":upload"`
|
||||
User string `yaml:":user"`
|
||||
}
|
||||
|
||||
// TelegramTdlibConfig is for :tdlib: subtree
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
},
|
||||
":upload": {
|
||||
"type": "string"
|
||||
},
|
||||
":user": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -2,8 +2,6 @@ package telegram
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -107,13 +105,6 @@ func (c *Client) updateHandler() {
|
|||
uhOh()
|
||||
}
|
||||
c.updateDeleteMessages(typedUpdate)
|
||||
case client.TypeUpdateFile:
|
||||
typedUpdate, ok := update.(*client.UpdateFile)
|
||||
if !ok {
|
||||
uhOh()
|
||||
}
|
||||
c.updateFile(typedUpdate)
|
||||
log.Debugf("%#v", typedUpdate.File)
|
||||
case client.TypeUpdateAuthorizationState:
|
||||
typedUpdate, ok := update.(*client.UpdateAuthorizationState)
|
||||
if !ok {
|
||||
|
@ -214,10 +205,10 @@ func (c *Client) updateNewMessage(update *client.UpdateNewMessage) {
|
|||
}
|
||||
} else {
|
||||
text = c.messageToText(update.Message, false)
|
||||
file, filename := c.contentToFilename(content)
|
||||
file := c.contentToFile(content)
|
||||
|
||||
// download file(s)
|
||||
if file != nil && !file.Local.IsDownloadingCompleted {
|
||||
// download file (if one)
|
||||
if file != nil {
|
||||
newFile, err := c.DownloadFile(file.Id, 1, true)
|
||||
if err == nil {
|
||||
file = newFile
|
||||
|
@ -226,7 +217,7 @@ func (c *Client) updateNewMessage(update *client.UpdateNewMessage) {
|
|||
// OTR support (I do not know why would you need it, seriously)
|
||||
if !(strings.HasPrefix(text, "?OTR") || c.Session.RawMessages) {
|
||||
var prefix strings.Builder
|
||||
prefix.WriteString(c.messageToPrefix(update.Message, c.formatContent(file, filename)))
|
||||
prefix.WriteString(c.messageToPrefix(update.Message, c.formatFile(file)))
|
||||
if text != "" {
|
||||
// \n if it is groupchat and message is not empty
|
||||
if chatId < 0 {
|
||||
|
@ -275,27 +266,6 @@ func (c *Client) updateDeleteMessages(update *client.UpdateDeleteMessages) {
|
|||
}
|
||||
}
|
||||
|
||||
// file downloaded
|
||||
func (c *Client) updateFile(update *client.UpdateFile) {
|
||||
// not really
|
||||
if !update.File.Local.IsDownloadingCompleted {
|
||||
return
|
||||
}
|
||||
|
||||
err := os.Symlink(
|
||||
update.File.Local.Path,
|
||||
c.formatFilePath(c.content.Path, update.File.Remote.UniqueId, filepath.Ext(update.File.Local.Path)),
|
||||
)
|
||||
if err != nil {
|
||||
linkErr := err.(*os.LinkError)
|
||||
if linkErr.Err.Error() == "file exists" {
|
||||
log.Warn(err.Error())
|
||||
} else {
|
||||
log.Errorf("Error creating symlink: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) updateAuthorizationState(update *client.UpdateAuthorizationState) {
|
||||
switch update.AuthorizationState.AuthorizationStateType() {
|
||||
case client.TypeAuthorizationStateClosing:
|
||||
|
|
|
@ -2,11 +2,11 @@ package telegram
|
|||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"io"
|
||||
"os"
|
||||
osUser "os/user"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
@ -355,21 +355,56 @@ func (c *Client) formatForward(fwd *client.MessageForwardInfo) string {
|
|||
return "Unknown forward type"
|
||||
}
|
||||
|
||||
func (c *Client) formatContent(file *client.File, filename string) string {
|
||||
if file == nil {
|
||||
func (c *Client) formatFile(file *client.File) string {
|
||||
if file == nil || file.Local == nil || file.Remote == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return fmt.Sprintf(
|
||||
"%s (%v kbytes) | %s",
|
||||
filename,
|
||||
file.Size/1024,
|
||||
c.formatFilePath(c.content.Link, file.Remote.UniqueId, filepath.Ext(file.Local.Path)),
|
||||
)
|
||||
}
|
||||
var link string
|
||||
var src string
|
||||
|
||||
func (c *Client) formatFilePath(basedir string, id string, ext string) string {
|
||||
return fmt.Sprintf("%s/%x%s", basedir, sha256.Sum256([]byte(id)), ext)
|
||||
if c.content.Path != "" && c.content.Link != "" {
|
||||
src = file.Local.Path // source path
|
||||
_, err := os.Stat(src)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
basename := file.Remote.UniqueId + filepath.Ext(src)
|
||||
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())
|
||||
} else {
|
||||
log.Errorf("File moving error: %v", err)
|
||||
return "<ERROR>"
|
||||
}
|
||||
}
|
||||
// chown
|
||||
if c.content.User != "" {
|
||||
user, err := osUser.Lookup(c.content.User)
|
||||
if err == nil {
|
||||
uid, err := strconv.ParseInt(user.Uid, 10, 0)
|
||||
if err == nil {
|
||||
err = os.Chown(dest, int(uid), -1)
|
||||
if err != nil {
|
||||
log.Errorf("Chown error: %v", err)
|
||||
}
|
||||
} else {
|
||||
log.Errorf("Broken uid: %v", err)
|
||||
}
|
||||
} else {
|
||||
log.Errorf("Wrong user name for chown: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s (%v kbytes) | %s", filepath.Base(src), file.Size/1024, link)
|
||||
}
|
||||
|
||||
func (c *Client) formatBantime(hours int64) int32 {
|
||||
|
@ -573,44 +608,44 @@ func (c *Client) messageToText(message *client.Message, preview bool) string {
|
|||
return fmt.Sprintf("unknown message (%s)", message.Content.MessageContentType())
|
||||
}
|
||||
|
||||
func (c *Client) contentToFilename(content client.MessageContent) (*client.File, string) {
|
||||
func (c *Client) contentToFile(content client.MessageContent) *client.File {
|
||||
if content == nil {
|
||||
return nil, ""
|
||||
return nil
|
||||
}
|
||||
|
||||
switch content.MessageContentType() {
|
||||
case client.TypeMessageSticker:
|
||||
sticker, _ := content.(*client.MessageSticker)
|
||||
return sticker.Sticker.Sticker, "sticker.webp"
|
||||
return sticker.Sticker.Sticker
|
||||
case client.TypeMessageVoiceNote:
|
||||
voice, _ := content.(*client.MessageVoiceNote)
|
||||
return voice.VoiceNote.Voice, fmt.Sprintf("voice note (%v s.).oga", voice.VoiceNote.Duration)
|
||||
return voice.VoiceNote.Voice
|
||||
case client.TypeMessageVideoNote:
|
||||
video, _ := content.(*client.MessageVideoNote)
|
||||
return video.VideoNote.Video, fmt.Sprintf("video note (%v s.).mp4", video.VideoNote.Duration)
|
||||
return video.VideoNote.Video
|
||||
case client.TypeMessageAnimation:
|
||||
animation, _ := content.(*client.MessageAnimation)
|
||||
return animation.Animation.Animation, "animation.mp4"
|
||||
return animation.Animation.Animation
|
||||
case client.TypeMessagePhoto:
|
||||
photo, _ := content.(*client.MessagePhoto)
|
||||
sizes := photo.Photo.Sizes
|
||||
if len(sizes) >= 1 {
|
||||
file := sizes[len(sizes)-1].Photo
|
||||
return file, strconv.FormatInt(int64(file.Id), 10) + ".jpg"
|
||||
return file
|
||||
}
|
||||
return nil, ""
|
||||
return nil
|
||||
case client.TypeMessageAudio:
|
||||
audio, _ := content.(*client.MessageAudio)
|
||||
return audio.Audio.Audio, filepath.Base(audio.Audio.Audio.Local.Path)
|
||||
return audio.Audio.Audio
|
||||
case client.TypeMessageVideo:
|
||||
video, _ := content.(*client.MessageVideo)
|
||||
return video.Video.Video, filepath.Base(video.Video.Video.Local.Path)
|
||||
return video.Video.Video
|
||||
case client.TypeMessageDocument:
|
||||
document, _ := content.(*client.MessageDocument)
|
||||
return document.Document.Document, filepath.Base(document.Document.Document.Local.Path)
|
||||
return document.Document.Document
|
||||
}
|
||||
|
||||
return nil, ""
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) messageToPrefix(message *client.Message, fileString string) string {
|
||||
|
|
|
@ -146,8 +146,8 @@ func TestFormatContent(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
content := c.formatContent(&file, "a.jpg")
|
||||
if content != "a.jpg (23 kbytes) | localhvost/b0896d9e9f1de7d2af59b080c3f0947b838c5c6c64f71c68a4b690a15de2ccf8.jpg" {
|
||||
content := c.formatFile(&file)
|
||||
if content != ". (23 kbytes) | " {
|
||||
t.Errorf("Wrong file label: %v", content)
|
||||
}
|
||||
}
|
||||
|
@ -351,142 +351,6 @@ func TestMessageUnknown(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestContentToFilenameSticker(t *testing.T) {
|
||||
sticker := client.MessageSticker{
|
||||
Sticker: &client.Sticker{},
|
||||
}
|
||||
_, filename := (&Client{}).contentToFilename(&sticker)
|
||||
if filename != "sticker.webp" {
|
||||
t.Errorf("Wrong sticker filename")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContentToFilenameVoice(t *testing.T) {
|
||||
voice := client.MessageVoiceNote{
|
||||
VoiceNote: &client.VoiceNote{
|
||||
Duration: 56,
|
||||
},
|
||||
}
|
||||
_, filename := (&Client{}).contentToFilename(&voice)
|
||||
if filename != "voice note (56 s.).oga" {
|
||||
t.Errorf("Wrong voice note filename")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContentToFilenameVideoNote(t *testing.T) {
|
||||
video := client.MessageVideoNote{
|
||||
VideoNote: &client.VideoNote{
|
||||
Duration: 56,
|
||||
},
|
||||
}
|
||||
_, filename := (&Client{}).contentToFilename(&video)
|
||||
if filename != "video note (56 s.).mp4" {
|
||||
t.Errorf("Wrong video note filename")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContentToFilenameAnimation(t *testing.T) {
|
||||
animation := client.MessageAnimation{
|
||||
Animation: &client.Animation{},
|
||||
}
|
||||
_, filename := (&Client{}).contentToFilename(&animation)
|
||||
if filename != "animation.mp4" {
|
||||
t.Errorf("Wrong animation filename")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContentToFilenamePhoto(t *testing.T) {
|
||||
photo := client.MessagePhoto{
|
||||
Photo: &client.Photo{
|
||||
Sizes: []*client.PhotoSize{
|
||||
&client.PhotoSize{
|
||||
Photo: &client.File{},
|
||||
},
|
||||
&client.PhotoSize{
|
||||
Photo: &client.File{
|
||||
Id: 56,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
_, filename := (&Client{}).contentToFilename(&photo)
|
||||
if filename != "56.jpg" {
|
||||
t.Errorf("Wrong photo filename")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContentToFilenamePhotoNoSizes(t *testing.T) {
|
||||
photo := client.MessagePhoto{
|
||||
Photo: &client.Photo{
|
||||
Sizes: []*client.PhotoSize{},
|
||||
},
|
||||
}
|
||||
_, filename := (&Client{}).contentToFilename(&photo)
|
||||
if filename != "" {
|
||||
t.Errorf("Wrong filename of sizeless photo")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContentToFilenameAudio(t *testing.T) {
|
||||
audio := client.MessageAudio{
|
||||
Audio: &client.Audio{
|
||||
FileName: "swine.mp3",
|
||||
Audio: &client.File{
|
||||
Local: &client.LocalFile{
|
||||
Path: "C:/WINNT/swine.mp3",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
_, filename := (&Client{}).contentToFilename(&audio)
|
||||
if filename != "swine.mp3" {
|
||||
t.Errorf("Not oinking, shame on you!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContentToFilenameVideo(t *testing.T) {
|
||||
video := client.MessageVideo{
|
||||
Video: &client.Video{
|
||||
FileName: "swine.3gp",
|
||||
Video: &client.File{
|
||||
Local: &client.LocalFile{
|
||||
Path: "C:/Document and Settings/Svinarchuk-PC/swine.3gp",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
_, filename := (&Client{}).contentToFilename(&video)
|
||||
if filename != "swine.3gp" {
|
||||
t.Errorf("Not pigdancing, shame on you!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContentToFilenameDocument(t *testing.T) {
|
||||
document := client.MessageDocument{
|
||||
Document: &client.Document{
|
||||
FileName: "swine.doc",
|
||||
Document: &client.File{
|
||||
Local: &client.LocalFile{
|
||||
Path: "D:/My Documents/swine.doc",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
_, filename := (&Client{}).contentToFilename(&document)
|
||||
if filename != "swine.doc" {
|
||||
t.Errorf("Not hoofstomping, shame on you!")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContentToFilenameUnknown(t *testing.T) {
|
||||
unknown := client.MessageExpiredPhoto{}
|
||||
_, filename := (&Client{}).contentToFilename(&unknown)
|
||||
if filename != "" {
|
||||
t.Errorf("Wrong filename of unknown content")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMessageToPrefix1(t *testing.T) {
|
||||
message := client.Message{
|
||||
Id: 42,
|
||||
|
|
Loading…
Reference in a new issue