gitlink-cli/shortcuts/user/user.go

771 lines
20 KiB
Go

package user
import (
"encoding/json"
"fmt"
"net/url"
"github.com/gitlink-org/gitlink-cli/shortcuts/common"
)
func Shortcuts() []*common.Shortcut {
return []*common.Shortcut{
{
Name: "me",
Description: "Show current authenticated user",
Run: func(ctx *common.RuntimeContext) error {
env, err := ctx.CallAPI("GET", "/users/me", nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "info",
Description: "Show user profile",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("GET", fmt.Sprintf("/users/%s", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// --- Message management ---
{
Name: "messages",
Description: "List user messages",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "page", Usage: "Page number", Default: "1"},
{Name: "limit", Usage: "Items per page", Default: "20"},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
page := ctx.Arg("page")
if page == "" {
page = "1"
}
limit := ctx.Arg("limit")
if limit == "" {
limit = "20"
}
query := url.Values{}
query.Set("page", page)
query.Set("limit", limit)
env, err := ctx.CallAPIWithQuery("GET", fmt.Sprintf("/users/%s/messages", login), query)
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "delete-message",
Description: "Delete a message",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "id", Usage: "Message ID", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
id, err := ctx.RequireArg("id")
if err != nil {
return err
}
query := url.Values{}
query.Set("id", id)
env, err := ctx.CallAPIWithQuery("DELETE", fmt.Sprintf("/users/%s/messages", login), query)
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "create-message",
Description: "Create a message",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "content", Usage: "Message content", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
content, err := ctx.RequireArg("content")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/users/%s/messages", login), map[string]interface{}{
"content": content,
})
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "read-message",
Description: "Mark a message as read",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "id", Usage: "Message ID", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
id, err := ctx.RequireArg("id")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/users/%s/messages/read", login), map[string]interface{}{
"id": id,
})
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "msg-settings",
Description: "Get message notification settings",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("GET", fmt.Sprintf("/users/%s/template_message_settings", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "update-msg-settings",
Description: "Update message notification settings",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "settings", Usage: "Settings JSON array", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
settingsStr, err := ctx.RequireArg("settings")
if err != nil {
return err
}
var settings []interface{}
if err := json.Unmarshal([]byte(settingsStr), &settings); err != nil {
return fmt.Errorf("invalid settings JSON: %w", err)
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/users/%s/template_message_settings/update_setting", login), map[string]interface{}{
"setting": settings,
})
if err != nil {
return err
}
return ctx.Output(env)
},
},
// --- Pinned projects ---
{
Name: "pinned-projects",
Description: "List pinned projects",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("GET", fmt.Sprintf("/users/%s/is_pinned_projects", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "pin-project",
Description: "Pin a project",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "id", Usage: "Project ID", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
id, err := ctx.RequireArg("id")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/users/%s/is_pinned_projects/pin", login), map[string]interface{}{
"id": id,
})
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "reorder-pinned",
Description: "Reorder a pinned project",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "id", Usage: "Pinned project ID", Required: true},
{Name: "position", Usage: "New position", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
id, err := ctx.RequireArg("id")
if err != nil {
return err
}
position, err := ctx.RequireArg("position")
if err != nil {
return err
}
env, err := ctx.CallAPI("PUT", fmt.Sprintf("/users/%s/is_pinned_projects/%s", login, id), map[string]interface{}{
"position": position,
})
if err != nil {
return err
}
return ctx.Output(env)
},
},
// --- Statistics ---
{
Name: "activity",
Description: "Get user activity statistics",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("GET", fmt.Sprintf("/users/%s/statistics/activity", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "headmap",
Description: "Get user heatmap data",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("GET", fmt.Sprintf("/users/%s/headmaps", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "develop-stats",
Description: "Get user development statistics",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("GET", fmt.Sprintf("/users/%s/statistics/develop", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "role-stats",
Description: "Get user role statistics",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("GET", fmt.Sprintf("/users/%s/statistics/role", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "major-stats",
Description: "Get user major statistics",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("GET", fmt.Sprintf("/users/%s/statistics/major", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// --- Transfer / Apply ---
{
Name: "applied-transfers",
Description: "List applied transfer projects",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("GET", fmt.Sprintf("/users/%s/applied_transfer_projects", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "accept-transfer",
Description: "Accept a project transfer",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "id", Usage: "Transfer ID", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
id, err := ctx.RequireArg("id")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/users/%s/applied_transfer_projects/%s/accept", login, id), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "refuse-transfer",
Description: "Refuse a project transfer",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "id", Usage: "Transfer ID", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
id, err := ctx.RequireArg("id")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/users/%s/applied_transfer_projects/%s/refuse", login, id), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "applied-projects",
Description: "List applied projects (join requests)",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("GET", fmt.Sprintf("/users/%s/applied_projects", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "accept-join",
Description: "Accept a project join request",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "id", Usage: "Application ID", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
id, err := ctx.RequireArg("id")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/users/%s/applied_projects/%s/accept", login, id), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "refuse-join",
Description: "Refuse a project join request",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "id", Usage: "Application ID", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
id, err := ctx.RequireArg("id")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/users/%s/applied_projects/%s/refuse", login, id), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// --- Feedback / Update ---
{
Name: "feedback",
Description: "Submit feedback",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "content", Usage: "Feedback content", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
content, err := ctx.RequireArg("content")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/v1/%s/feedbacks", login), map[string]interface{}{
"content": content,
})
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "update",
Description: "Update user profile",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "nickname", Usage: "New nickname"},
{Name: "description", Usage: "New description"},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
body := map[string]interface{}{}
if v := ctx.Arg("nickname"); v != "" {
body["nickname"] = v
}
if v := ctx.Arg("description"); v != "" {
body["description"] = v
}
env, err := ctx.CallAPI("PUT", fmt.Sprintf("/users/%s", login), body)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// --- Account settings ---
{
Name: "change-password",
Description: "Change password",
Flags: []common.Flag{
{Name: "old-password", Usage: "Current password", Required: true},
{Name: "new-password", Usage: "New password", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
oldPwd, err := ctx.RequireArg("old-password")
if err != nil {
return err
}
newPwd, err := ctx.RequireArg("new-password")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", "/accounts/change_password", map[string]interface{}{
"old_password": oldPwd,
"new_password": newPwd,
})
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "update-email",
Description: "Update email address",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "email", Usage: "New email address", Required: true},
{Name: "code", Usage: "Verification code"},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
email, err := ctx.RequireArg("email")
if err != nil {
return err
}
body := map[string]interface{}{
"email": email,
}
if v := ctx.Arg("code"); v != "" {
body["code"] = v
}
env, err := ctx.CallAPI("PATCH", fmt.Sprintf("/v1/%s/update_email", login), body)
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "update-phone",
Description: "Update phone number",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "phone", Usage: "New phone number", Required: true},
{Name: "code", Usage: "Verification code"},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
phone, err := ctx.RequireArg("phone")
if err != nil {
return err
}
body := map[string]interface{}{
"phone": phone,
}
if v := ctx.Arg("code"); v != "" {
body["code"] = v
}
env, err := ctx.CallAPI("PATCH", fmt.Sprintf("/v1/%s/update_phone", login), body)
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "send-verify",
Description: "Send email verification code",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "email", Usage: "Email address"},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
query := url.Values{}
if v := ctx.Arg("email"); v != "" {
query.Set("email", v)
}
env, err := ctx.CallAPIWithQuery("GET", fmt.Sprintf("/v1/%s/send_email_vefify_code", login), query)
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "check-verify",
Description: "Check email verification code",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "code", Usage: "Verification code", Required: true},
{Name: "email", Usage: "Email address"},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
code, err := ctx.RequireArg("code")
if err != nil {
return err
}
body := map[string]interface{}{
"code": code,
}
if v := ctx.Arg("email"); v != "" {
body["email"] = v
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/v1/%s/check_email_verify_code", login), body)
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "check-password",
Description: "Verify password",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "password", Usage: "Password to verify", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
password, err := ctx.RequireArg("password")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/v1/%s/check_password", login), map[string]interface{}{
"password": password,
})
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "check-email",
Description: "Verify email",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "email", Usage: "Email to verify", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
email, err := ctx.RequireArg("email")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/v1/%s/check_email", login), map[string]interface{}{
"email": email,
})
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "can-delete",
Description: "Check if user account can be deleted",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/v1/%s/check_user_can_delete", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
{
Name: "delete",
Description: "Delete (deactivate) user account",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("DELETE", fmt.Sprintf("/v1/%s", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
}
}