4 // Please see the LICENSE file is this directory. |
4 // Please see the LICENSE file is this directory. |
5 |
5 |
6 package cmd |
6 package cmd |
7 |
7 |
8 import ( |
8 import ( |
|
9 "strings" |
|
10 |
9 "github.com/pkg/errors" |
11 "github.com/pkg/errors" |
10 "github.com/spf13/cobra" |
12 "github.com/spf13/cobra" |
11 "github.com/spf13/viper" |
13 "github.com/spf13/viper" |
12 |
14 |
13 "github.com/McKael/madon" |
15 "github.com/McKael/madon" |
24 tootAliasCmd.Flags().StringVar(&statusOpts.mediaIDs, "media-ids", "", "Comma-separated list of media IDs") |
26 tootAliasCmd.Flags().StringVar(&statusOpts.mediaIDs, "media-ids", "", "Comma-separated list of media IDs") |
25 tootAliasCmd.Flags().StringVarP(&statusOpts.mediaFilePath, "file", "f", "", "Media attachment file name") |
27 tootAliasCmd.Flags().StringVarP(&statusOpts.mediaFilePath, "file", "f", "", "Media attachment file name") |
26 tootAliasCmd.Flags().StringVar(&statusOpts.textFilePath, "text-file", "", "Text file name (message content)") |
28 tootAliasCmd.Flags().StringVar(&statusOpts.textFilePath, "text-file", "", "Text file name (message content)") |
27 tootAliasCmd.Flags().Int64VarP(&statusOpts.inReplyToID, "in-reply-to", "r", 0, "Status ID to reply to") |
29 tootAliasCmd.Flags().Int64VarP(&statusOpts.inReplyToID, "in-reply-to", "r", 0, "Status ID to reply to") |
28 tootAliasCmd.Flags().BoolVar(&statusOpts.stdin, "stdin", false, "Read message content from standard input") |
30 tootAliasCmd.Flags().BoolVar(&statusOpts.stdin, "stdin", false, "Read message content from standard input") |
|
31 tootAliasCmd.Flags().BoolVar(&statusOpts.addMentions, "add-mentions", false, "Add mentions when replying") |
29 |
32 |
30 // Flag completion |
33 // Flag completion |
31 annotation := make(map[string][]string) |
34 annotation := make(map[string][]string) |
32 annotation[cobra.BashCompCustom] = []string{"__madonctl_visibility"} |
35 annotation[cobra.BashCompCustom] = []string{"__madonctl_visibility"} |
33 |
36 |
41 Example: ` madonctl toot message |
44 Example: ` madonctl toot message |
42 madonctl toot --spoiler Warning "Hello, World" |
45 madonctl toot --spoiler Warning "Hello, World" |
43 madonctl status post --media-ids ID1,ID2 "Here are the photos" |
46 madonctl status post --media-ids ID1,ID2 "Here are the photos" |
44 madonctl post --sensitive --file image.jpg Image |
47 madonctl post --sensitive --file image.jpg Image |
45 madonctl toot --text-file message.txt |
48 madonctl toot --text-file message.txt |
|
49 madonctl toot --in-reply-to STATUSID "@user response" |
|
50 madonctl toot --in-reply-to STATUSID --add-mentions "response" |
46 echo "Hello from #madonctl" | madonctl toot --visibility unlisted --stdin |
51 echo "Hello from #madonctl" | madonctl toot --visibility unlisted --stdin |
47 |
52 |
48 The default visibility can be set in the configuration file with the option |
53 The default visibility can be set in the configuration file with the option |
49 'default_visibility' (or with an environmnent variable).`, |
54 'default_visibility' (or with an environmnent variable).`, |
50 RunE: func(cmd *cobra.Command, args []string) error { |
55 RunE: func(cmd *cobra.Command, args []string) error { |
79 ids, err := splitIDs(opt.mediaIDs) |
84 ids, err := splitIDs(opt.mediaIDs) |
80 if err != nil { |
85 if err != nil { |
81 return nil, errors.New("cannot parse media IDs") |
86 return nil, errors.New("cannot parse media IDs") |
82 } |
87 } |
83 |
88 |
|
89 if tootText == "" && len(ids) == 0 && opt.spoiler == "" && opt.mediaFilePath == "" { |
|
90 return nil, errors.New("toot is empty") |
|
91 } |
|
92 |
|
93 if opt.addMentions && opt.inReplyToID > 0 { |
|
94 mentions, err := mentionsList(opt.inReplyToID) |
|
95 if err != nil { |
|
96 return nil, err |
|
97 } |
|
98 tootText = mentions + tootText |
|
99 } |
|
100 |
|
101 // Uploading media file last |
84 if opt.mediaFilePath != "" { |
102 if opt.mediaFilePath != "" { |
85 if len(ids) > 3 { |
103 if len(ids) > 3 { |
86 return nil, errors.New("too many media attachments") |
104 return nil, errors.New("too many media attachments") |
87 } |
105 } |
88 |
106 |
93 if fileMediaID > 0 { |
111 if fileMediaID > 0 { |
94 ids = append(ids, fileMediaID) |
112 ids = append(ids, fileMediaID) |
95 } |
113 } |
96 } |
114 } |
97 |
115 |
98 if tootText == "" && len(ids) == 0 && opt.spoiler == "" { |
116 return gClient.PostStatus(tootText, opt.inReplyToID, ids, opt.sensitive, opt.spoiler, opt.visibility) |
99 return nil, errors.New("toot is empty") |
117 } |
|
118 |
|
119 func mentionsList(statusID int64) (string, error) { |
|
120 a, err := gClient.GetCurrentAccount() |
|
121 if err != nil { |
|
122 return "", errors.Wrap(err, "cannot check account details") |
100 } |
123 } |
101 |
124 |
102 return gClient.PostStatus(tootText, opt.inReplyToID, ids, opt.sensitive, opt.spoiler, opt.visibility) |
125 s, err := gClient.GetStatus(statusID) |
|
126 if err != nil { |
|
127 return "", errors.Wrap(err, "cannot get mentions") |
|
128 } |
|
129 |
|
130 var mentions []string |
|
131 // Add the sender if she is not the connected user |
|
132 if s.Account.Acct != a.Acct { |
|
133 mentions = append(mentions, "@"+s.Account.Acct) |
|
134 } |
|
135 for _, m := range s.Mentions { |
|
136 if m.Acct != a.Acct { |
|
137 mentions = append(mentions, "@"+m.Acct) |
|
138 } |
|
139 } |
|
140 mentionsStr := strings.Join(mentions, " ") |
|
141 if len(mentionsStr) > 0 { |
|
142 return mentionsStr + " ", nil |
|
143 } |
|
144 return "", nil |
103 } |
145 } |