main.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package main
  2. import (
  3. "errors"
  4. "fmt"
  5. "image"
  6. "image/jpeg"
  7. "log"
  8. "net/http"
  9. "os"
  10. "path"
  11. "plugin"
  12. "time"
  13. "golang.org/x/net/websocket"
  14. )
  15. type Transformer struct {
  16. name string
  17. t func(image.Image) image.Image
  18. priority int // priority can be 0 or 1
  19. }
  20. func loadPlugin(path string) (*Transformer, error) {
  21. fmt.Println("Loading", path)
  22. p, err := plugin.Open(path)
  23. if err != nil {
  24. return nil, err
  25. }
  26. transformSymbol, err := p.Lookup("Transform")
  27. if err != nil {
  28. return nil, err
  29. }
  30. transform, ok := transformSymbol.(func(image.Image) image.Image)
  31. if !ok {
  32. return nil, errors.New(fmt.Sprintf("%s: Transform not a func(image.Image) image.Image", path))
  33. }
  34. var priority int
  35. prioritySymbol, err := p.Lookup("Priority")
  36. if err != nil {
  37. fmt.Println("Error looking up Priority:", err)
  38. } else {
  39. var ok bool
  40. priority, ok = prioritySymbol.(int)
  41. if !ok {
  42. fmt.Println("Error casting Priority to int")
  43. }
  44. }
  45. return &Transformer{path, transform, priority}, nil
  46. }
  47. func getPlugins(pluginDir string) (map[int][]*Transformer, error) {
  48. pDir, err := os.Open(pluginDir)
  49. if err != nil {
  50. return nil, err
  51. }
  52. pFiles, err := pDir.Readdir(0)
  53. if err != nil {
  54. return nil, err
  55. }
  56. ret := make(map[int][]*Transformer)
  57. for _, pFile := range pFiles {
  58. if pFile.IsDir() {
  59. continue
  60. }
  61. p, err := loadPlugin(path.Join(pluginDir, pFile.Name()))
  62. if err != nil {
  63. log.Printf("Failed to load pluging %s", p)
  64. } else {
  65. ret[p.priority] = append(ret[p.priority], p)
  66. }
  67. }
  68. return ret, nil
  69. }
  70. func handler(w http.ResponseWriter, r *http.Request) {
  71. fi, _ := os.Open("lca.jpg")
  72. i, _ := jpeg.Decode(fi)
  73. plugins, err := getPlugins(pluginDir)
  74. if err != nil {
  75. panic(err)
  76. }
  77. for _, p := range plugins[1] {
  78. fmt.Println("Apply", p.name)
  79. i = p.t(i)
  80. }
  81. for _, p := range plugins[0] {
  82. fmt.Println("Apply", p.name)
  83. i = p.t(i)
  84. }
  85. jpeg.Encode(w, i, nil)
  86. }
  87. func wsHandler(ws *websocket.Conn) {
  88. for true {
  89. fmt.Fprintf(ws, "echp")
  90. time.Sleep(200 * time.Millisecond)
  91. }
  92. }
  93. var pluginDir string
  94. func main() {
  95. pluginDir = os.Args[1]
  96. http.HandleFunc("/a.jpg", handler)
  97. http.Handle("/ws", websocket.Handler(wsHandler))
  98. http.ListenAndServe(":8080", nil)
  99. }