main.go (10332B)
1 package main 2 3 import ( 4 "flag" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "regexp" 10 "sort" 11 "strconv" 12 "strings" 13 "time" 14 ) 15 16 func main() { 17 src, consts, url, videoExt, photoExt, original, useRSS := InitialiseFlags() 18 Usage(src, consts) 19 DeleteStaticFiles(src, useRSS) 20 files := GetFilesList(src, photoExt, videoExt) 21 CreateFileByCopying("index.html", consts, "_header.html") 22 if useRSS { 23 CreateFileByCopying("rss.xml", consts, "_rss-header.xml") 24 } 25 for _, file := range files { 26 title := GetTitle(file) 27 if useRSS { 28 rssEntry := GetRSSEntry(title, url, file, photoExt, videoExt) 29 AppendContentToFile(rssEntry, "rss.xml") 30 } 31 var listItem string 32 if strings.HasSuffix(file, videoExt) { 33 listItem = ` 34 <li id="` + file + `"> 35 <video class="gallery" controls><source src="` + file + `"></video> 36 </li> 37 ` 38 } else if strings.HasSuffix(file, photoExt) { 39 highQualityFile := GetHQImg(file, original) 40 listItem = ` 41 <li id="` + file + `"> 42 <a 43 target="_blank" 44 rel="noopener noreferrer" 45 href="` + highQualityFile + `" 46 > 47 <img class="gallery" src="` + file + `"/> 48 </a> 49 </li> 50 ` 51 } else { 52 continue // don't write empty listItems to HTML 53 } 54 AppendContentToFile(listItem, "index.html") 55 } 56 CompleteFiles(consts, useRSS) 57 AddCopyrightToHtml() 58 AddDateToRSS(useRSS) 59 MoveFile("index.html", src) 60 if useRSS { 61 MoveFile("rss.xml", src) 62 } 63 CopyStaticFiles(consts, src) 64 os.Exit(0) 65 } 66 67 func GetHQImg(file string, original string) string { 68 extRegex := regexp.MustCompile(`\.[^.]*$`) 69 byteFile := []byte(file) 70 nothing := []byte("") 71 fileWithOutExt := string(extRegex.ReplaceAll(byteFile, nothing)) 72 hqFile := fileWithOutExt + original 73 return hqFile 74 } 75 76 func InitialiseFlags() (string, string, string, string, string, string, bool) { 77 var src string 78 var consts string 79 var url string 80 var videoExt string 81 var photoExt string 82 var original string 83 var useRSS bool 84 85 flag.StringVar(&src, "s", "src", "Specify the source directory containing images.") 86 flag.StringVar(&consts, "c", "consts", "Specify the consts directory containing static files.") 87 flag.StringVar(&url, "u", "___http://example.com/___", "Specify the URL of the website.") 88 flag.StringVar(&videoExt, "v", "mp4", "Specify which video file extension to use.") 89 flag.StringVar(&photoExt, "p", "jpg", "Specify which photo file extension to use.") 90 flag.StringVar(&original, "o", ".original.png", "Specify the suffix of the original high quality media.") 91 flag.BoolVar(&useRSS, "r", true, "Generate an RSS feed.") 92 93 flag.Usage = func() { 94 fmt.Println("Usage: ``./sgg-go -s src -c consts -u http://example.com -v mp4 -p jpg -o original.png [-r=false]''") 95 flag.PrintDefaults() 96 } 97 98 flag.Parse() 99 return src, consts, url, videoExt, photoExt, original, useRSS 100 } 101 102 func CheckDirExists(dir string) { 103 _, err := os.Stat(dir) 104 if os.IsNotExist(err) { 105 fmt.Fprintf(os.Stderr, "%s: No such directory", dir) 106 os.Exit(1) 107 } 108 } 109 110 func DeleteStaticFiles(src string, useRSS bool) { 111 files := []string{"avtaar.jpg", "index.html", "favicon.png", "style.css"} 112 for _, file := range files { 113 pathOfFile := filepath.Join(src, file) 114 DelFile(pathOfFile) 115 } 116 if useRSS { 117 pathOfFile := filepath.Join(src, "rss.xml") 118 DelFile(pathOfFile) 119 } 120 } 121 122 func DelFile(pathOfFile string) { 123 _, err := os.Stat(pathOfFile) 124 if err == nil { 125 os.Remove(pathOfFile) 126 } 127 } 128 129 func GetAllFiles(dir string) []string { 130 allFiles := []string{} 131 entries, err := ioutil.ReadDir(dir) 132 if err != nil { 133 fmt.Fprintf(os.Stderr, "%s", err) 134 os.Exit(1) 135 } 136 for _, elem := range entries { 137 name := elem.Name() 138 isDir := elem.IsDir() 139 if isDir == false { 140 fullName := filepath.Join(dir, name) 141 allFiles = append(allFiles, fullName) 142 } else { 143 recurredFiles := GetAllFiles(filepath.Join(dir, name)) 144 for j, _ := range recurredFiles { 145 allFiles = append(allFiles, recurredFiles[j]) 146 } 147 } 148 } 149 return allFiles 150 } 151 152 func TrimSrc(src string, filenames []string) []string { 153 trimedNames := []string{} 154 for _, file := range filenames { 155 reg := regexp.MustCompile("^" + src) 156 replacedName := string(reg.ReplaceAll([]byte(file), []byte(""))) 157 trimedNames = append(trimedNames, replacedName) 158 } 159 return trimedNames 160 } 161 162 func CreateFileByCopying(dstFileName string, srcDir string, srcFileName string) { 163 srcFilePath := filepath.Join(srcDir, srcFileName) 164 bytesRead := []byte("") 165 _, err := os.Stat(srcFilePath) 166 if !os.IsNotExist(err) { 167 bytesRead, err = ioutil.ReadFile(srcFilePath) 168 if err != nil { 169 fmt.Fprintf(os.Stderr, "%s", err) 170 os.Exit(1) 171 } 172 } 173 err = ioutil.WriteFile(dstFileName, bytesRead, 0644) 174 if err != nil { 175 fmt.Fprintf(os.Stderr, "%s", err) 176 os.Exit(1) 177 } 178 } 179 180 func MoveFile(filename string, dir string) { 181 newFilePath := filepath.Join(dir, filename) 182 err := os.Rename(filename, newFilePath) 183 if err != nil { 184 fmt.Fprintf(os.Stderr, "%s", err) 185 } 186 } 187 188 func CopyFile(from string, to string, filename string) { 189 srcFilePath := filepath.Join(from, filename) 190 dstFilePath := filepath.Join(to, filename) 191 _, err := os.Stat(srcFilePath) 192 if !os.IsNotExist(err) { 193 bytesRead, err := ioutil.ReadFile(srcFilePath) 194 if err != nil { 195 fmt.Fprintf(os.Stderr, "%s", err) 196 os.Exit(1) 197 } 198 err = ioutil.WriteFile(dstFilePath, bytesRead, 0644) 199 if err != nil { 200 fmt.Fprintf(os.Stderr, "%s", err) 201 os.Exit(1) 202 } 203 } 204 } 205 206 func GetTitle(fileName string) string { 207 bytedFileName := []byte(fileName) 208 empty := []byte("") 209 leadingSlashRegex := regexp.MustCompile(`^\/`) 210 firstReplace := leadingSlashRegex.ReplaceAll(bytedFileName, empty) 211 rmExtRegex := regexp.MustCompile(`\..*$`) 212 secondReplace := rmExtRegex.ReplaceAll(firstReplace, empty) 213 title := string(secondReplace) 214 return title 215 } 216 217 func ExtractDate(title string) string { 218 layoutISO := "2006/01/02" 219 220 ymd := title[0:10] 221 222 t, err := time.Parse(layoutISO, ymd) 223 if err != nil { 224 fmt.Fprintf(os.Stderr, "%s", err) 225 os.Exit(1) 226 } 227 formattedDate := t.Format(time.RFC1123) 228 return formattedDate 229 } 230 231 func GetRSSEntry(title string, url string, file string, photoExt string, videoExt string) string { 232 formattedDate := ExtractDate(title) 233 imgOrVideo := GetImgOrVideoForRSS(url, file, photoExt, videoExt) 234 rssEntry := ` 235 <item> 236 <title>` + title + `</title> 237 <description> 238 <![CDATA[ 239 <a href="` + url + "/#" + file + `">` + imgOrVideo + `</a> 240 <br/> 241 <h2>New media added on ` + formattedDate + `</h2> 242 <br/> 243 <small><a href="` + url + `">See more photos.</a></small> 244 <br/>]]> 245 </description> 246 <link>` + url + file + `</link> 247 <guid>` + url + file + `</guid> 248 <pubDate>` + formattedDate + `</pubDate> 249 </item> 250 ` 251 return rssEntry 252 } 253 254 func GetImgOrVideoForRSS(url string, file string, photoExt string, videoExt string) string { 255 var res string 256 if strings.HasSuffix(file, photoExt) { 257 res = `<img src="` + url + file + `">` 258 } else if strings.HasSuffix(file, videoExt) { 259 res = `<video class="gallery" controls><source src="` + url + file + `"></video>` 260 } 261 return res 262 } 263 264 func AppendContentToFile(content string, file string) { 265 fd, err := os.OpenFile(file, os.O_APPEND|os.O_WRONLY, 0644) 266 if err != nil { 267 fmt.Fprintf(os.Stderr, "%s", err) 268 os.Exit(1) 269 } 270 if _, err := fd.Write([]byte(content)); err != nil { 271 fmt.Fprintf(os.Stderr, "%s", err) 272 os.Exit(1) 273 } 274 defer fd.Close() 275 } 276 277 func Usage(src string, consts string) { 278 CheckDirExists(src) 279 CheckDirExists(consts) 280 } 281 282 func GetFilesList(src string, photoExt string, videoExt string) []string { 283 files := GetAllFiles("src") 284 trimedFiles := TrimSrc(src, files) 285 filteredFiles := []string{} 286 for _, file := range trimedFiles { 287 if strings.HasSuffix(file, photoExt) || strings.HasSuffix(file, videoExt) { 288 filteredFiles = append(filteredFiles, file) 289 } 290 } 291 sort.Strings(filteredFiles) 292 filesList := reverse(filteredFiles) 293 return filesList 294 } 295 296 func reverse(arr []string) []string { 297 for i, j := 0, len(arr)-1; i < j; i, j = i+1, j-1 { 298 arr[i], arr[j] = arr[j], arr[i] 299 } 300 return arr 301 } 302 303 func CopyStaticFiles(consts string, src string) { 304 CopyFile(consts, src, "avtaar.jpg") 305 CopyFile(consts, src, "favicon.png") 306 CopyFile(consts, src, "style.css") 307 } 308 309 func AppendFileToFile(from string, to string) { 310 _, err := os.Stat(from) 311 if os.IsNotExist(err) { 312 fmt.Fprintf(os.Stderr, "%s", err) 313 os.Exit(1) 314 } 315 bytesRead, err := ioutil.ReadFile(from) 316 if err != nil { 317 fmt.Fprintf(os.Stderr, "%s", err) 318 os.Exit(1) 319 } 320 fd, err := os.OpenFile(to, os.O_APPEND|os.O_WRONLY, 0644) 321 if err != nil { 322 fmt.Fprintf(os.Stderr, "%s", err) 323 os.Exit(1) 324 } 325 if _, err := fd.Write(bytesRead); err != nil { 326 fmt.Fprintf(os.Stderr, "%s", err) 327 os.Exit(1) 328 } 329 defer fd.Close() 330 } 331 332 func CompleteFiles(consts string, useRSS bool) { 333 htmlBottomPath := filepath.Join(consts, "_footer.html") 334 AppendFileToFile(htmlBottomPath, "index.html") 335 if useRSS { 336 rssBottomPath := filepath.Join(consts, "_rss-footer.xml") 337 AppendFileToFile(rssBottomPath, "rss.xml") 338 } 339 } 340 341 func AddCopyrightToHtml() { 342 year := strconv.Itoa(time.Now().Year()) 343 yearInBytes := []byte("© " + year + " ") 344 yearReg := `©` 345 AddRegexToFile("index.html", yearReg, yearInBytes) 346 } 347 348 func AddDateToRSS(useRSS bool) { 349 if useRSS { 350 AddCopyrightToRSS() 351 AddPubDateToRSS() 352 AddBuildDateToRSS() 353 } 354 } 355 356 func AddCopyrightToRSS() { 357 year := strconv.Itoa(time.Now().Year()) 358 yearInBytes := []byte("<copyright>" + year + " ___RSS-COPYRIGHT___</copyright>") 359 yearReg := `<copyright></copyright>` 360 AddRegexToFile("rss.xml", yearReg, yearInBytes) 361 } 362 363 func AddRegexToFile(filename string, regStr string, replacementStr []byte) { 364 bytesRead, err := ioutil.ReadFile(filename) 365 if err != nil { 366 fmt.Fprintf(os.Stderr, "%s", err) 367 os.Exit(1) 368 } 369 os.Remove(filename) 370 yearReg := regexp.MustCompile(regStr) 371 yearInserted := yearReg.ReplaceAll(bytesRead, replacementStr) 372 err = ioutil.WriteFile(filename, yearInserted, 0644) 373 if err != nil { 374 fmt.Fprintf(os.Stderr, "%s", err) 375 os.Exit(1) 376 } 377 } 378 379 func AddPubDateToRSS() { 380 reg := `<lastBuildDate></lastBuildDate>` 381 now := time.Now().Format(time.RFC1123) 382 replacement := []byte(`<lastBuildDate>` + now + `</lastBuildDate>`) 383 AddRegexToFile("rss.xml", reg, replacement) 384 } 385 386 func AddBuildDateToRSS() { 387 reg := `<pubDate></pubDate>` 388 now := time.Now().Format(time.RFC1123) 389 replacement := []byte(`<pubDate>` + now + `</pubDate>`) 390 AddRegexToFile("rss.xml", reg, replacement) 391 }