aboutsummaryrefslogtreecommitdiffhomepage
path: root/backend/account/icon.go
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2024-08-17 21:11:07 +0900
committernsfisis <nsfisis@gmail.com>2024-08-17 21:11:07 +0900
commit01d3120fd7129f573d88f7aa7c227b3ef93fe368 (patch)
treeeea4f5ac0f025c7bdbff71d2ee83b4dce99355ef /backend/account/icon.go
parentf926ef682de637b717d3b0cc0eaee43c59e83c95 (diff)
parentb923a9d6534820d33f42bc65c47ae22889bde922 (diff)
downloadphperkaigi-2025-albatross-01d3120fd7129f573d88f7aa7c227b3ef93fe368.tar.gz
phperkaigi-2025-albatross-01d3120fd7129f573d88f7aa7c227b3ef93fe368.tar.zst
phperkaigi-2025-albatross-01d3120fd7129f573d88f7aa7c227b3ef93fe368.zip
Merge branch 'feat/icon'
Diffstat (limited to 'backend/account/icon.go')
-rw-r--r--backend/account/icon.go85
1 files changed, 85 insertions, 0 deletions
diff --git a/backend/account/icon.go b/backend/account/icon.go
new file mode 100644
index 0000000..40632c6
--- /dev/null
+++ b/backend/account/icon.go
@@ -0,0 +1,85 @@
+package account
+
+import (
+ "context"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "os"
+ "path"
+ "path/filepath"
+ "time"
+
+ "github.com/nsfisis/iosdc-japan-2024-albatross/backend/db"
+ "github.com/nsfisis/iosdc-japan-2024-albatross/backend/fortee"
+)
+
+func FetchIcon(
+ ctx context.Context,
+ q *db.Queries,
+ userID int,
+) error {
+ ctx, cancel := context.WithTimeout(ctx, 15*time.Second)
+ defer cancel()
+
+ // Fetch user.
+ user, err := q.GetUserByID(ctx, int32(userID))
+ if err != nil {
+ return fmt.Errorf("failed to fetch user icon (uid=%d): %w", userID, err)
+ }
+ // Fetch user icon URL.
+ avatarURL, err := fortee.GetUserAvatarURL(ctx, user.Username)
+ if err != nil {
+ return fmt.Errorf("failed to fetch user icon (uid=%d): %w", userID, err)
+ }
+ // Download user icon file.
+ filePath := fmt.Sprintf("/files/%s/icon%s", url.PathEscape(user.Username), path.Ext(avatarURL))
+ if err := downloadFile(ctx, fortee.Endpoint+avatarURL, "/data"+filePath); err != nil {
+ return fmt.Errorf("failed to fetch user icon (uid=%d): %w", userID, err)
+ }
+ // Save user icon path.
+ if err := q.UpdateUserIconPath(ctx, db.UpdateUserIconPathParams{
+ UserID: int32(userID),
+ IconPath: &filePath,
+ }); err != nil {
+ return fmt.Errorf("failed to fetch user icon (uid=%d): %w", userID, err)
+ }
+ return nil
+}
+
+func downloadFile(ctx context.Context, url string, filePath string) error {
+ req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
+ if err != nil {
+ return fmt.Errorf("failed to download file (%s): %w", url, err)
+ }
+
+ client := &http.Client{}
+ res, err := client.Do(req)
+ if err != nil {
+ return fmt.Errorf("failed to download file (%s): %w", url, err)
+ }
+ defer res.Body.Close()
+
+ if res.StatusCode != http.StatusOK {
+ return fmt.Errorf("failed to download file (%s): status %d", url, res.StatusCode)
+ }
+
+ fileDir := filepath.Dir(filePath)
+ if err := os.MkdirAll(fileDir, 0755); err != nil {
+ return fmt.Errorf("failed to create directory (%s): %w", fileDir, err)
+ }
+
+ file, err := os.Create(filePath)
+ if err != nil {
+ return fmt.Errorf("failed to open file (%s): %w", filePath, err)
+ }
+ defer file.Close()
+
+ _, err = io.Copy(file, res.Body)
+ if err != nil {
+ return fmt.Errorf("failed to save file (%s): %w", filePath, err)
+ }
+
+ return nil
+}