18 ) |
18 ) |
19 |
19 |
20 var accountUpdateFlags, accountMuteFlags, accountFollowFlags *flag.FlagSet |
20 var accountUpdateFlags, accountMuteFlags, accountFollowFlags *flag.FlagSet |
21 |
21 |
22 var accountsOpts struct { |
22 var accountsOpts struct { |
23 accountID int64 |
23 accountID madon.ActivityID |
24 accountUID string |
24 accountUID string |
25 unset bool // TODO remove eventually? |
25 unset bool // TODO remove eventually? |
26 limit, keep uint // Limit the results |
26 limit, keep uint // Limit the results |
27 sinceID, maxID int64 // Query boundaries |
27 sinceID, maxID madon.ActivityID // Query boundaries |
28 all bool // Try to fetch all results |
28 all bool // Try to fetch all results |
29 onlyMedia, onlyPinned bool // For acccount statuses |
29 onlyMedia, onlyPinned bool // For acccount statuses |
30 excludeReplies bool // For acccount statuses |
30 excludeReplies bool // For acccount statuses |
31 remoteUID string // For account follow |
31 remoteUID string // For account follow |
32 reblogs bool // For account follow |
32 reblogs bool // For account follow |
33 acceptFR, rejectFR bool // For account follow_requests |
33 acceptFR, rejectFR bool // For account follow_requests |
34 list bool // For account follow_requests/reports |
34 list bool // For account follow_requests/reports |
35 accountIDs string // For account relationships |
35 accountIDs string // For account relationships |
36 statusIDs string // For account reports |
36 statusIDs string // For account reports |
37 comment string // For account reports |
37 comment string // For account reports |
38 displayName, note string // For account update |
38 displayName, note string // For account update |
39 profileFields []string // For account update |
39 profileFields []string // For account update |
40 avatar, header string // For account update |
40 avatar, header string // For account update |
41 defaultLanguage string // For account update |
41 defaultLanguage string // For account update |
42 defaultPrivacy string // For account update |
42 defaultPrivacy string // For account update |
43 defaultSensitive bool // For account update |
43 defaultSensitive bool // For account update |
44 locked, bot bool // For account update |
44 locked, bot bool // For account update |
45 muteNotifications bool // For account mute |
45 muteNotifications bool // For account mute |
46 following bool // For account search |
46 following bool // For account search |
47 } |
47 } |
48 |
48 |
49 func init() { |
49 func init() { |
50 RootCmd.AddCommand(accountsCmd) |
50 RootCmd.AddCommand(accountsCmd) |
51 |
51 |
52 // Subcommands |
52 // Subcommands |
53 accountsCmd.AddCommand(accountSubcommands...) |
53 accountsCmd.AddCommand(accountSubcommands...) |
54 |
54 |
55 // Global flags |
55 // Global flags |
56 accountsCmd.PersistentFlags().Int64VarP(&accountsOpts.accountID, "account-id", "a", 0, "Account ID number") |
56 accountsCmd.PersistentFlags().StringVarP(&accountsOpts.accountID, "account-id", "a", "", "Account ID number") |
57 accountsCmd.PersistentFlags().StringVarP(&accountsOpts.accountUID, "user-id", "u", "", "Account user ID") |
57 accountsCmd.PersistentFlags().StringVarP(&accountsOpts.accountUID, "user-id", "u", "", "Account user ID") |
58 accountsCmd.PersistentFlags().UintVarP(&accountsOpts.limit, "limit", "l", 0, "Limit number of API results") |
58 accountsCmd.PersistentFlags().UintVarP(&accountsOpts.limit, "limit", "l", 0, "Limit number of API results") |
59 accountsCmd.PersistentFlags().UintVarP(&accountsOpts.keep, "keep", "k", 0, "Limit number of results") |
59 accountsCmd.PersistentFlags().UintVarP(&accountsOpts.keep, "keep", "k", 0, "Limit number of results") |
60 accountsCmd.PersistentFlags().Int64Var(&accountsOpts.sinceID, "since-id", 0, "Request IDs greater than a value") |
60 accountsCmd.PersistentFlags().StringVar(&accountsOpts.sinceID, "since-id", "", "Request IDs greater than a value") |
61 accountsCmd.PersistentFlags().Int64Var(&accountsOpts.maxID, "max-id", 0, "Request IDs less (or equal) than a value") |
61 accountsCmd.PersistentFlags().StringVar(&accountsOpts.maxID, "max-id", "", "Request IDs less (or equal) than a value") |
62 accountsCmd.PersistentFlags().BoolVar(&accountsOpts.all, "all", false, "Fetch all results") |
62 accountsCmd.PersistentFlags().BoolVar(&accountsOpts.all, "all", false, "Fetch all results") |
63 |
63 |
64 // Subcommand flags |
64 // Subcommand flags |
65 accountStatusesSubcommand.Flags().BoolVar(&accountsOpts.onlyPinned, "pinned", false, "Only statuses that have been pinned") |
65 accountStatusesSubcommand.Flags().BoolVar(&accountsOpts.onlyPinned, "pinned", false, "Only statuses that have been pinned") |
66 accountStatusesSubcommand.Flags().BoolVar(&accountsOpts.onlyMedia, "only-media", false, "Only statuses with media attachments") |
66 accountStatusesSubcommand.Flags().BoolVar(&accountsOpts.onlyMedia, "only-media", false, "Only statuses with media attachments") |
439 switch subcmd { |
439 switch subcmd { |
440 case "show", "search", "update": |
440 case "show", "search", "update": |
441 // These subcommands do not require an account ID |
441 // These subcommands do not require an account ID |
442 case "favourites", "blocks", "mutes", "pinned": |
442 case "favourites", "blocks", "mutes", "pinned": |
443 // Those subcommands can not use an account ID |
443 // Those subcommands can not use an account ID |
444 if opt.accountID > 0 { |
444 if opt.accountID != "" { |
445 return errors.New("useless account ID") |
445 return errors.New("useless account ID") |
446 } |
446 } |
447 case "follow", "unfollow": |
447 case "follow", "unfollow": |
448 // We need an account ID or a remote UID |
448 // We need an account ID or a remote UID |
449 if opt.accountID < 1 && opt.remoteUID == "" { |
449 if opt.accountID == "" && opt.remoteUID == "" { |
450 return errors.New("missing account ID or URI") |
450 return errors.New("missing account ID or URI") |
451 } |
451 } |
452 if opt.accountID > 0 && opt.remoteUID != "" { |
452 if opt.accountID != "" && opt.remoteUID != "" { |
453 return errors.New("cannot use both account ID and URI") |
453 return errors.New("cannot use both account ID and URI") |
454 } |
454 } |
455 if (opt.unset || subcmd == "unfollow") && opt.accountID < 1 { |
455 if (opt.unset || subcmd == "unfollow") && opt.accountID == "" { |
456 return errors.New("unfollowing requires an account ID") |
456 return errors.New("unfollowing requires an account ID") |
457 } |
457 } |
458 case "follow-requests": |
458 case "follow-requests": |
459 if opt.list { |
459 if opt.list { |
460 if opt.acceptFR || opt.rejectFR { |
460 if opt.acceptFR || opt.rejectFR { |
466 } |
466 } |
467 // This is a FR reply |
467 // This is a FR reply |
468 if opt.acceptFR && opt.rejectFR { |
468 if opt.acceptFR && opt.rejectFR { |
469 return errors.New("incompatible options") |
469 return errors.New("incompatible options") |
470 } |
470 } |
471 if opt.accountID < 1 { |
471 if opt.accountID == "" { |
472 return errors.New("missing account ID") |
472 return errors.New("missing account ID") |
473 } |
473 } |
474 } |
474 } |
475 case "relationships": |
475 case "relationships": |
476 if opt.accountID < 1 && len(opt.accountIDs) == 0 { |
476 if opt.accountID == "" && len(opt.accountIDs) == 0 { |
477 return errors.New("missing account IDs") |
477 return errors.New("missing account IDs") |
478 } |
478 } |
479 if opt.accountID > 0 && len(opt.accountIDs) > 0 { |
479 if opt.accountID != "" && len(opt.accountIDs) > 0 { |
480 return errors.New("incompatible options") |
480 return errors.New("incompatible options") |
481 } |
481 } |
482 case "reports": |
482 case "reports": |
483 if opt.list { |
483 if opt.list { |
484 break // No argument needed |
484 break // No argument needed |
485 } |
485 } |
486 if opt.accountID < 1 || len(opt.statusIDs) == 0 || opt.comment == "" { |
486 if opt.accountID == "" || len(opt.statusIDs) == 0 || opt.comment == "" { |
487 return errors.New("missing parameter") |
487 return errors.New("missing parameter") |
488 } |
488 } |
489 case "followers", "following", "statuses": |
489 case "followers", "following", "statuses": |
490 // If the user's account ID is missing, get it |
490 // If the user's account ID is missing, get it |
491 if opt.accountID < 1 { |
491 if opt.accountID == "" { |
492 // Sign in now to look the user id up |
492 // Sign in now to look the user id up |
493 if err := madonInit(true); err != nil { |
493 if err := madonInit(true); err != nil { |
494 return err |
494 return err |
495 } |
495 } |
496 account, err := gClient.GetCurrentAccount() |
496 account, err := gClient.GetCurrentAccount() |
502 errPrint("User account ID: %d", opt.accountID) |
502 errPrint("User account ID: %d", opt.accountID) |
503 } |
503 } |
504 } |
504 } |
505 default: |
505 default: |
506 // The other subcommands here require an account ID |
506 // The other subcommands here require an account ID |
507 if opt.accountID < 1 { |
507 if opt.accountID == "" { |
508 return errors.New("missing account ID") |
508 return errors.New("missing account ID") |
509 } |
509 } |
510 } |
510 } |
511 |
511 |
512 var limOpts *madon.LimitParams |
512 var limOpts *madon.LimitParams |
513 if opt.all || opt.limit > 0 || opt.sinceID > 0 || opt.maxID > 0 { |
513 if opt.all || opt.limit > 0 || opt.sinceID != "" || opt.maxID != "" { |
514 limOpts = new(madon.LimitParams) |
514 limOpts = new(madon.LimitParams) |
515 limOpts.All = opt.all |
515 limOpts.All = opt.all |
516 } |
516 } |
517 |
517 |
518 if opt.limit > 0 { |
518 if opt.limit > 0 { |
519 limOpts.Limit = int(opt.limit) |
519 limOpts.Limit = int(opt.limit) |
520 } |
520 } |
521 if opt.maxID > 0 { |
521 if opt.maxID != "" { |
522 limOpts.MaxID = opt.maxID |
522 limOpts.MaxID = opt.maxID |
523 } |
523 } |
524 if opt.sinceID > 0 { |
524 if opt.sinceID != "" { |
525 limOpts.SinceID = opt.sinceID |
525 limOpts.SinceID = opt.sinceID |
526 } |
526 } |
527 |
527 |
528 // All account subcommands need to have signed in |
528 // All account subcommands need to have signed in |
529 if err := madonInit(true); err != nil { |
529 if err := madonInit(true); err != nil { |
805 } |
805 } |
806 |
806 |
807 // accountLookupUser tries to find a (single) user matching 'user' |
807 // accountLookupUser tries to find a (single) user matching 'user' |
808 // If the user is an HTTP URL, it will use the search API, else |
808 // If the user is an HTTP URL, it will use the search API, else |
809 // it will use the accounts/search API. |
809 // it will use the accounts/search API. |
810 func accountLookupUser(user string) (int64, error) { |
810 func accountLookupUser(user string) (madon.ActivityID, error) { |
811 var accID int64 |
811 var accID madon.ActivityID |
812 |
812 |
813 if strings.HasPrefix(user, "https://") || strings.HasPrefix(user, "http://") { |
813 if strings.HasPrefix(user, "https://") || strings.HasPrefix(user, "http://") { |
814 res, err := gClient.Search(user, true) |
814 res, err := gClient.Search(user, true) |
815 if err != nil { |
815 if err != nil { |
816 return 0, err |
816 return "", err |
817 } |
817 } |
818 if res != nil { |
818 if res != nil { |
819 if len(res.Accounts) > 1 { |
819 if len(res.Accounts) > 1 { |
820 return 0, errors.New("several results") |
820 return "", errors.New("several results") |
821 } |
821 } |
822 if len(res.Accounts) == 1 { |
822 if len(res.Accounts) == 1 { |
823 accID = res.Accounts[0].ID |
823 accID = res.Accounts[0].ID |
824 } |
824 } |
825 } |
825 } |