-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapi.go
173 lines (147 loc) · 4.77 KB
/
api.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package twcapbot
import (
"embed"
"fmt"
"github.com/gusanmaz/capdec"
"github.com/gusanmaz/twigger"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
)
//go:embed hair.png
var embedFS embed.FS
type TweetCaptionBot struct {
JSCodes []string
OutDirPath string
TwiggerConn *twigger.Connection
HairPhotoPath string
InfoLog *log.Logger
ErrLog *log.Logger
}
const botLogPrefix = "Tweet Caption Bot: "
const DownloadRetries = 5
func init() {
//capdec.ChangeMaxBrowserDimensions(5500, 3200)
}
func New(creds twigger.Credentials, logFile *os.File, codes []string, outDirPath string) *TweetCaptionBot {
bot := TweetCaptionBot{}
bot.JSCodes = codes
bot.OutDirPath = outDirPath
finfo, err := os.Stat(outDirPath)
if err != nil || !finfo.IsDir() {
log.Panicf("%v is not a valid directory", outDirPath)
}
tConn, err := twigger.NewConnection(creds, logFile, os.Stdout, os.Stderr)
if err != nil {
log.Panicf("Cannot create a new connection for twigger. Error: %v", err)
}
bot.TwiggerConn = tConn
f, err := embedFS.Open("hair.png")
if err != nil {
log.Panicf("Cannot open hair.png. Error: %v", err)
}
tempF, err := ioutil.TempFile(os.TempDir(), "hair.*.png")
if err != nil {
log.Panicf("Cannot create temporary file for hair.png. Error: %v", err)
}
_, err = io.Copy(tempF, f)
if err != nil {
log.Panicf("Cannot copy hair.png into temporary directory. Error: %v", err)
}
infoW := tConn.InfoLog.Writer()
bot.InfoLog = log.New(infoW, botLogPrefix, log.LstdFlags)
errW := tConn.ErrLog.Writer()
bot.ErrLog = log.New(errW, botLogPrefix, log.LstdFlags)
bot.HairPhotoPath = filepath.Join(tempF.Name())
return &bot
}
func (b *TweetCaptionBot) CaptionTweet(id int64, rootPath string) error {
tw, err := b.TwiggerConn.GetSingleTweetFromID(id)
if err != nil {
return err
}
var quotedTweet *twigger.Tweet = nil
if tw.QuotedStatusID != 0 {
tw, err := b.TwiggerConn.GetSingleTweetFromID(tw.QuotedStatusID)
if err != nil {
return err
}
quotedTweet = &tw
}
fNameInfo := GenerateFileNamesForTweet(tw, quotedTweet)
userDirPath := filepath.Join(rootPath, fNameInfo[0].ShortDirName)
_, err = os.Stat(rootPath)
if err != nil {
err = os.Mkdir(rootPath, 0750)
if err != nil {
b.ErrLog.Printf("Cannot create directory: %v! Error message: %v", userDirPath, err)
panic("Exiting program...")
}
}
_, err = os.Stat(userDirPath)
if err != nil {
err = os.Mkdir(userDirPath, 0750)
if err != nil {
b.ErrLog.Printf("Cannot create directory: %v! Error message: %v", userDirPath, err)
panic("Exiting program...")
}
}
for _, v := range fNameInfo {
srcPath := filepath.Join(userDirPath, v.LongFileName)
destFilePath := filepath.Join(userDirPath, v.LongCaptionFileName)
b.InfoLog.Printf("Captioning of tweet with IDStr of %v has started", tw.Id)
if v.MediaTweet {
err := DownloadTo(v.MediaURL, srcPath)
if err != nil {
b.InfoLog.Printf("Download of media files of tweet with IDStr %v has failed!", tw.Id)
for i := 1; i <= DownloadRetries; i++ {
b.InfoLog.Printf("Attempt %v/%v to download media files of tweet (IDStr: %v)", i+1, DownloadRetries, tw.Id)
err = DownloadTo(v.MediaURL, srcPath)
if err == nil {
b.InfoLog.Printf("Media files for tweet (IDStr: %v) has succesfully downloaded", tw.Id)
break
}
}
if err != nil {
b.ErrLog.Printf("%v attempts to download media files for tweet with IDStr of %v has failed!", DownloadRetries)
return err
}
}
err = capdec.Caption(srcPath, GetCaptionsForTweet(tw, quotedTweet), destFilePath, b.JSCodes)
if err != nil {
b.ErrLog.Printf("Captioning of tweet with IDStr of %v is unsuccessful!", tw.Id)
b.ErrLog.Printf("Error message: %v", err)
panic("Exiting program...")
}
} else {
err := capdec.Caption(b.HairPhotoPath, GetCaptionsForTweet(tw, quotedTweet), destFilePath, b.JSCodes)
if err != nil {
b.ErrLog.Printf("Captioning of tweet with IDStr of %v is unsuccessful!", tw.Id)
b.ErrLog.Printf("Error message: %v", err)
panic("Exiting program...")
}
}
b.InfoLog.Printf("Captioning of tweet with IDStr of %v has completed successfully", tw.Id)
}
htmlFilePath := filepath.Join(userDirPath, fNameInfo[0].LongHTMLFileName)
htmFile, err := os.OpenFile(htmlFilePath, os.O_RDWR|os.O_CREATE, 0644)
defer htmFile.Close()
if err != nil {
b.ErrLog.Printf("Couldn't create %v", tw.Id)
}
templateStr := `<script> location.href = "{{}}" </script>`
text := strings.Replace(templateStr, "{{}}", GetTweetURL(tw), 1)
_, err = htmFile.WriteString(text)
if err != nil {
b.ErrLog.Printf("Couldn't write tweet (IDStr: %v) url into %v", tw.Id, htmlFilePath)
}
return nil
}
func GetTweetURL(tw twigger.Tweet) string {
sn := tw.User.ScreenName
url := fmt.Sprintf("https://www.twitter.com/%v/status/%v", sn, tw.Id)
return url
}