barcodeserver.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. package main
  2. import (
  3. "bufio"
  4. "crypto/sha1"
  5. "encoding/hex"
  6. "fmt"
  7. "github.com/boombuler/barcode"
  8. "github.com/boombuler/barcode/codabar"
  9. "github.com/boombuler/barcode/code128"
  10. "github.com/boombuler/barcode/code39"
  11. "github.com/boombuler/barcode/datamatrix"
  12. "github.com/boombuler/barcode/ean"
  13. "github.com/boombuler/barcode/qr"
  14. "github.com/boombuler/barcode/twooffive"
  15. "github.com/julienschmidt/httprouter"
  16. "image/png"
  17. "log"
  18. "net/http"
  19. "os"
  20. "strconv"
  21. )
  22. func IdToPath(id string) string {
  23. hasher := sha1.New()
  24. hasher.Write([]byte(id))
  25. hash := hex.EncodeToString(hasher.Sum(nil))
  26. path := fmt.Sprintf("%s/%s/%s.png", hash[0:2], hash[2:4], hash)
  27. os.MkdirAll(fmt.Sprintf("public/%s/%s", hash[0:2], hash[2:4]), 0755)
  28. return path
  29. }
  30. func Get(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
  31. bartype := p.ByName("type")
  32. content := r.URL.Query().Get("content")
  33. swidth := r.URL.Query().Get("width")
  34. sheight := r.URL.Query().Get("height")
  35. if swidth == "" {
  36. swidth = "0"
  37. }
  38. if sheight == "" {
  39. sheight = "0"
  40. }
  41. width, werr := strconv.Atoi(swidth)
  42. if werr != nil {
  43. log.Println(werr)
  44. w.WriteHeader(http.StatusBadRequest)
  45. fmt.Fprintf(w, "Error: %s", werr)
  46. return
  47. }
  48. height, herr := strconv.Atoi(sheight)
  49. if herr != nil {
  50. log.Println(herr)
  51. w.WriteHeader(http.StatusBadRequest)
  52. fmt.Fprintf(w, "Error: %s", herr)
  53. return
  54. }
  55. id := fmt.Sprintf("%s:%s:%d:%d", bartype, content, width, height)
  56. path := IdToPath(id)
  57. realPath := fmt.Sprintf("public/%s", path)
  58. if _, err := os.Stat(realPath); err == nil {
  59. http.Redirect(w, r, fmt.Sprintf("/%s", path), 307)
  60. return
  61. }
  62. var err error
  63. var initialBarcode barcode.Barcode
  64. switch bartype {
  65. case "datamatrix":
  66. initialBarcode, err = datamatrix.Encode(content)
  67. if width == 0 {
  68. width = 256
  69. }
  70. if height == 0 {
  71. height = 256
  72. }
  73. case "qr":
  74. initialBarcode, err = qr.Encode(content, qr.Q, qr.Auto)
  75. if width == 0 {
  76. width = 256
  77. }
  78. if height == 0 {
  79. height = 256
  80. }
  81. case "codabar":
  82. initialBarcode, err = codabar.Encode(content)
  83. if width == 0 {
  84. width = 256
  85. }
  86. if height == 0 {
  87. height = 50
  88. }
  89. case "code128":
  90. initialBarcode, err = code128.Encode(content)
  91. if width == 0 {
  92. width = 256
  93. }
  94. if height == 0 {
  95. height = 25
  96. }
  97. case "code39":
  98. initialBarcode, err = code39.Encode(content, true, true)
  99. if width == 0 {
  100. width = 256
  101. }
  102. if height == 0 {
  103. height = 25
  104. }
  105. case "ean":
  106. initialBarcode, err = ean.Encode(content)
  107. if width == 0 {
  108. width = 256
  109. }
  110. if height == 0 {
  111. height = 25
  112. }
  113. case "2of5":
  114. initialBarcode, err = twooffive.Encode(content, true)
  115. if width == 0 {
  116. width = 256
  117. }
  118. if height == 0 {
  119. height = 25
  120. }
  121. case "twooffive":
  122. initialBarcode, err = twooffive.Encode(content, true)
  123. if width == 0 {
  124. width = 256
  125. }
  126. if height == 0 {
  127. height = 25
  128. }
  129. }
  130. if err != nil {
  131. log.Println(err)
  132. w.WriteHeader(http.StatusInternalServerError)
  133. fmt.Fprintf(w, "Error: %s", err)
  134. return
  135. } else if bartype == "" || initialBarcode == nil {
  136. log.Println("Bad type")
  137. w.WriteHeader(http.StatusBadRequest)
  138. fmt.Fprintf(w, "Error: %s", "Bad bar type")
  139. return
  140. } else {
  141. var serr error
  142. var finalBarcode barcode.Barcode
  143. if width != 0 && height != 0 {
  144. finalBarcode, serr = barcode.Scale(initialBarcode, width, height)
  145. } else {
  146. finalBarcode = initialBarcode
  147. }
  148. if serr != nil {
  149. log.Println(serr)
  150. w.WriteHeader(http.StatusInternalServerError)
  151. fmt.Fprintf(w, "Error: %s", serr)
  152. return
  153. }
  154. file, ferr := os.Create(realPath)
  155. if ferr != nil {
  156. log.Println(ferr)
  157. w.WriteHeader(http.StatusInternalServerError)
  158. fmt.Fprintf(w, "Error: %s", ferr)
  159. return
  160. }
  161. defer file.Close()
  162. writer := bufio.NewWriter(file)
  163. perr := png.Encode(writer, finalBarcode)
  164. if perr != nil {
  165. log.Println(perr)
  166. w.WriteHeader(http.StatusInternalServerError)
  167. fmt.Fprintf(w, "Error: %s", perr)
  168. return
  169. }
  170. writer.Flush()
  171. http.Redirect(w, r, fmt.Sprintf("/%s", path), 307)
  172. }
  173. }
  174. func main() {
  175. sport := os.Getenv("PORT")
  176. var port string
  177. if len(sport) > 2 {
  178. port = sport
  179. } else {
  180. port = "8080"
  181. }
  182. log.Printf("Binding at 0.0.0.0:%s", port)
  183. router := httprouter.New()
  184. router.NotFound = http.FileServer(http.Dir("public"))
  185. router.GET("/", Get)
  186. router.GET("/:type", Get)
  187. log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), router))
  188. }