summaryrefslogtreecommitdiffstats
path: root/modules/avatar
diff options
context:
space:
mode:
authorskyblue <ssx205@gmail.com>2014-03-23 12:24:09 +0800
committerskyblue <ssx205@gmail.com>2014-03-23 12:24:09 +0800
commit8e47ae21024bc35a82215e16f1e586f94ae622c9 (patch)
tree8f82573b400f8833f06bc23bc70d6f3883c99f86 /modules/avatar
parent17da2fd2e30e85909394bc58069ecab14d8d8577 (diff)
downloadgitea-8e47ae21024bc35a82215e16f1e586f94ae622c9.tar.gz
gitea-8e47ae21024bc35a82215e16f1e586f94ae622c9.zip
add avatar inorder to view code on github
Diffstat (limited to 'modules/avatar')
-rw-r--r--modules/avatar/avatar.go136
-rw-r--r--modules/avatar/avatar_test.go35
2 files changed, 171 insertions, 0 deletions
diff --git a/modules/avatar/avatar.go b/modules/avatar/avatar.go
new file mode 100644
index 0000000000..93f842eaef
--- /dev/null
+++ b/modules/avatar/avatar.go
@@ -0,0 +1,136 @@
+package avatar
+
+import (
+ "crypto/md5"
+ "encoding/hex"
+ "fmt"
+ "io"
+ "log"
+ "net/http"
+ "net/url"
+ "os"
+ "path/filepath"
+ "strings"
+ "sync"
+ "time"
+)
+
+var gravatar = "http://www.gravatar.com/avatar"
+
+// hash email to md5 string
+func HashEmail(email string) string {
+ h := md5.New()
+ h.Write([]byte(strings.ToLower(email)))
+ return hex.EncodeToString(h.Sum(nil))
+}
+
+type Avatar struct {
+ Hash string
+ cacheDir string // image save dir
+ reqParams string
+ imagePath string
+}
+
+func New(hash string, cacheDir string) *Avatar {
+ return &Avatar{
+ Hash: hash,
+ cacheDir: cacheDir,
+ reqParams: url.Values{
+ "d": {"retro"},
+ "size": {"200"},
+ "r": {"pg"}}.Encode(),
+ imagePath: filepath.Join(cacheDir, hash+".jpg"),
+ }
+}
+
+// get image from gravatar.com
+func (this *Avatar) Update() {
+ thunder.Fetch(gravatar+"/"+this.Hash+"?"+this.reqParams,
+ this.Hash+".jpg")
+}
+
+func (this *Avatar) UpdateTimeout(timeout time.Duration) {
+ select {
+ case <-time.After(timeout):
+ log.Println("timeout")
+ case <-thunder.GoFetch(gravatar+"/"+this.Hash+"?"+this.reqParams,
+ this.Hash+".jpg"):
+ }
+}
+
+var thunder = &Thunder{QueueSize: 10}
+
+type Thunder struct {
+ QueueSize int // download queue size
+ q chan *thunderTask
+ once sync.Once
+}
+
+func (t *Thunder) init() {
+ if t.QueueSize < 1 {
+ t.QueueSize = 1
+ }
+ t.q = make(chan *thunderTask, t.QueueSize)
+ for i := 0; i < t.QueueSize; i++ {
+ go func() {
+ for {
+ task := <-t.q
+ task.Fetch()
+ }
+ }()
+ }
+}
+
+func (t *Thunder) Fetch(url string, saveFile string) error {
+ t.once.Do(t.init)
+ task := &thunderTask{
+ Url: url,
+ SaveFile: saveFile,
+ }
+ task.Add(1)
+ t.q <- task
+ task.Wait()
+ return task.err
+}
+
+func (t *Thunder) GoFetch(url, saveFile string) chan error {
+ c := make(chan error)
+ go func() {
+ c <- t.Fetch(url, saveFile)
+ }()
+ return c
+}
+
+// thunder download
+type thunderTask struct {
+ Url string
+ SaveFile string
+ sync.WaitGroup
+ err error
+}
+
+func (this *thunderTask) Fetch() {
+ this.err = this.fetch()
+ this.Done()
+}
+
+func (this *thunderTask) fetch() error {
+ resp, err := http.Get(this.Url)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode != 200 {
+ return fmt.Errorf("status code: %d", resp.StatusCode)
+ }
+ fd, err := os.Create(this.SaveFile)
+ if err != nil {
+ return err
+ }
+ defer fd.Close()
+ _, err = io.Copy(fd, resp.Body)
+ if err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/modules/avatar/avatar_test.go b/modules/avatar/avatar_test.go
new file mode 100644
index 0000000000..49f8f91f35
--- /dev/null
+++ b/modules/avatar/avatar_test.go
@@ -0,0 +1,35 @@
+package avatar
+
+import (
+ "log"
+ "strconv"
+ "testing"
+ "time"
+)
+
+func TestFetch(t *testing.T) {
+ hash := HashEmail("ssx205@gmail.com")
+ avatar := New(hash, "./")
+ //avatar.Update()
+ avatar.UpdateTimeout(time.Millisecond * 200)
+ time.Sleep(5 * time.Second)
+}
+
+func TestFetchMany(t *testing.T) {
+ log.Println("start")
+ var n = 50
+ ch := make(chan bool, n)
+ for i := 0; i < n; i++ {
+ go func(i int) {
+ hash := HashEmail(strconv.Itoa(i) + "ssx205@gmail.com")
+ avatar := New(hash, "./")
+ avatar.Update()
+ log.Println("finish", hash)
+ ch <- true
+ }(i)
+ }
+ for i := 0; i < n; i++ {
+ <-ch
+ }
+ log.Println("end")
+}