author | Mikael Berthe <mikael@lilotux.net> |
Fri, 28 Apr 2017 15:53:09 +0200 | |
changeset 21 | 9e94836dc081 |
parent 18 | 7a4b57b3e66a |
child 37 | 9bc03db114c3 |
permissions | -rw-r--r-- |
0 | 1 |
// Copyright © 2017 Mikael Berthe <mikael@lilotux.net> |
2 |
// |
|
3 |
// Licensed under the MIT license. |
|
4 |
// Please see the LICENSE file is this directory. |
|
5 |
||
6 |
package printer |
|
7 |
||
8 |
import ( |
|
9 |
"fmt" |
|
10 |
"io" |
|
11 |
"os" |
|
12 |
"reflect" |
|
13 |
"time" |
|
14 |
||
15 |
"github.com/jaytaylor/html2text" |
|
16 |
||
17 |
"github.com/McKael/madon" |
|
18 |
) |
|
19 |
||
20 |
// PlainPrinter is the default "plain text" printer |
|
21 |
type PlainPrinter struct { |
|
22 |
Indent string |
|
23 |
NoSubtitles bool |
|
24 |
} |
|
25 |
||
26 |
// NewPrinterPlain returns a plaintext ResourcePrinter |
|
27 |
// For PlainPrinter, the option parameter contains the indent prefix. |
|
28 |
func NewPrinterPlain(option string) (*PlainPrinter, error) { |
|
29 |
indentInc := " " |
|
30 |
if option != "" { |
|
31 |
indentInc = option |
|
32 |
} |
|
33 |
return &PlainPrinter{Indent: indentInc}, nil |
|
34 |
} |
|
35 |
||
36 |
// PrintObj sends the object as text to the writer |
|
37 |
// If the writer w is nil, standard output will be used. |
|
38 |
// For PlainPrinter, the option parameter contains the initial indent. |
|
39 |
func (p *PlainPrinter) PrintObj(obj interface{}, w io.Writer, initialIndent string) error { |
|
40 |
if w == nil { |
|
41 |
w = os.Stdout |
|
42 |
} |
|
43 |
switch o := obj.(type) { |
|
44 |
case []madon.Account, []madon.Attachment, []madon.Card, []madon.Context, |
|
45 |
[]madon.Instance, []madon.Mention, []madon.Notification, |
|
46 |
[]madon.Relationship, []madon.Report, []madon.Results, |
|
47 |
[]madon.Status, []madon.StreamEvent, []madon.Tag: |
|
48 |
return p.plainForeach(o, w, initialIndent) |
|
49 |
case *madon.Account: |
|
50 |
return p.plainPrintAccount(o, w, initialIndent) |
|
51 |
case madon.Account: |
|
52 |
return p.plainPrintAccount(&o, w, initialIndent) |
|
53 |
case *madon.Attachment: |
|
54 |
return p.plainPrintAttachment(o, w, initialIndent) |
|
55 |
case madon.Attachment: |
|
56 |
return p.plainPrintAttachment(&o, w, initialIndent) |
|
57 |
case *madon.Card: |
|
58 |
return p.plainPrintCard(o, w, initialIndent) |
|
59 |
case madon.Card: |
|
60 |
return p.plainPrintCard(&o, w, initialIndent) |
|
61 |
case *madon.Context: |
|
62 |
return p.plainPrintContext(o, w, initialIndent) |
|
63 |
case madon.Context: |
|
64 |
return p.plainPrintContext(&o, w, initialIndent) |
|
65 |
case *madon.Instance: |
|
66 |
return p.plainPrintInstance(o, w, initialIndent) |
|
67 |
case madon.Instance: |
|
68 |
return p.plainPrintInstance(&o, w, initialIndent) |
|
69 |
case *madon.Notification: |
|
70 |
return p.plainPrintNotification(o, w, initialIndent) |
|
71 |
case madon.Notification: |
|
72 |
return p.plainPrintNotification(&o, w, initialIndent) |
|
73 |
case *madon.Relationship: |
|
74 |
return p.plainPrintRelationship(o, w, initialIndent) |
|
75 |
case madon.Relationship: |
|
76 |
return p.plainPrintRelationship(&o, w, initialIndent) |
|
77 |
case *madon.Report: |
|
78 |
return p.plainPrintReport(o, w, initialIndent) |
|
79 |
case madon.Report: |
|
80 |
return p.plainPrintReport(&o, w, initialIndent) |
|
81 |
case *madon.Results: |
|
82 |
return p.plainPrintResults(o, w, initialIndent) |
|
83 |
case madon.Results: |
|
84 |
return p.plainPrintResults(&o, w, initialIndent) |
|
85 |
case *madon.Status: |
|
86 |
return p.plainPrintStatus(o, w, initialIndent) |
|
87 |
case madon.Status: |
|
88 |
return p.plainPrintStatus(&o, w, initialIndent) |
|
89 |
case *madon.UserToken: |
|
90 |
return p.plainPrintUserToken(o, w, initialIndent) |
|
91 |
case madon.UserToken: |
|
92 |
return p.plainPrintUserToken(&o, w, initialIndent) |
|
93 |
} |
|
94 |
// TODO: Mention |
|
95 |
// TODO: StreamEvent |
|
96 |
// TODO: Tag |
|
97 |
||
98 |
return fmt.Errorf("PlainPrinter not yet implemented for %T (try json or yaml...)", obj) |
|
99 |
} |
|
100 |
||
101 |
func (p *PlainPrinter) plainForeach(ol interface{}, w io.Writer, ii string) error { |
|
102 |
switch reflect.TypeOf(ol).Kind() { |
|
103 |
case reflect.Slice: |
|
104 |
s := reflect.ValueOf(ol) |
|
105 |
||
106 |
for i := 0; i < s.Len(); i++ { |
|
107 |
o := s.Index(i).Interface() |
|
108 |
if err := p.PrintObj(o, w, ii); err != nil { |
|
109 |
return err |
|
110 |
} |
|
111 |
} |
|
112 |
} |
|
113 |
return nil |
|
114 |
} |
|
115 |
||
116 |
func html2string(h string) string { |
|
117 |
t, err := html2text.FromString(h) |
|
118 |
if err == nil { |
|
119 |
return t |
|
120 |
} |
|
121 |
return h // Failed: return initial string |
|
122 |
} |
|
123 |
||
124 |
func indentedPrint(w io.Writer, indent string, title, skipIfEmpty bool, label string, format string, args ...interface{}) { |
|
125 |
prefix := indent |
|
126 |
if title { |
|
127 |
prefix += "- " |
|
128 |
} else { |
|
129 |
prefix += " " |
|
130 |
} |
|
131 |
value := fmt.Sprintf(format, args...) |
|
132 |
if !title && skipIfEmpty && len(value) == 0 { |
|
133 |
return |
|
134 |
} |
|
135 |
fmt.Fprintf(w, "%s%s: %s\n", prefix, label, value) |
|
136 |
} |
|
137 |
||
138 |
func (p *PlainPrinter) plainPrintAccount(a *madon.Account, w io.Writer, indent string) error { |
|
139 |
indentedPrint(w, indent, true, false, "Account ID", "%d (%s)", a.ID, a.Username) |
|
140 |
indentedPrint(w, indent, false, false, "User ID", "%s", a.Acct) |
|
141 |
indentedPrint(w, indent, false, false, "Display name", "%s", a.DisplayName) |
|
142 |
indentedPrint(w, indent, false, false, "Creation date", "%v", a.CreatedAt.Local()) |
|
143 |
indentedPrint(w, indent, false, false, "URL", "%s", a.URL) |
|
144 |
indentedPrint(w, indent, false, false, "Statuses count", "%d", a.StatusesCount) |
|
145 |
indentedPrint(w, indent, false, false, "Followers count", "%d", a.FollowersCount) |
|
146 |
indentedPrint(w, indent, false, false, "Following count", "%d", a.FollowingCount) |
|
147 |
if a.Locked { |
|
148 |
indentedPrint(w, indent, false, false, "Locked", "%v", a.Locked) |
|
149 |
} |
|
150 |
indentedPrint(w, indent, false, true, "User note", "%s", html2string(a.Note)) // XXX too long? |
|
151 |
return nil |
|
152 |
} |
|
153 |
||
154 |
func (p *PlainPrinter) plainPrintAttachment(a *madon.Attachment, w io.Writer, indent string) error { |
|
155 |
indentedPrint(w, indent, true, false, "Attachment ID", "%d", a.ID) |
|
156 |
indentedPrint(w, indent, false, false, "Type", "%s", a.Type) |
|
157 |
indentedPrint(w, indent, false, false, "Local URL", "%s", a.URL) |
|
158 |
indentedPrint(w, indent, false, true, "Remote URL", "%s", a.RemoteURL) |
|
159 |
indentedPrint(w, indent, false, true, "Preview URL", "%s", a.PreviewURL) |
|
160 |
indentedPrint(w, indent, false, true, "Text URL", "%s", a.PreviewURL) |
|
161 |
return nil |
|
162 |
} |
|
163 |
||
164 |
func (p *PlainPrinter) plainPrintCard(c *madon.Card, w io.Writer, indent string) error { |
|
165 |
indentedPrint(w, indent, true, false, "Card title", "%s", c.Title) |
|
166 |
indentedPrint(w, indent, false, true, "Description", "%s", c.Description) |
|
167 |
indentedPrint(w, indent, false, true, "URL", "%s", c.URL) |
|
168 |
indentedPrint(w, indent, false, true, "Image", "%s", c.Image) |
|
169 |
return nil |
|
170 |
} |
|
171 |
||
172 |
func (p *PlainPrinter) plainPrintContext(c *madon.Context, w io.Writer, indent string) error { |
|
173 |
indentedPrint(w, indent, true, false, "Context", "%d relative(s)", len(c.Ancestors)+len(c.Descendents)) |
|
174 |
if len(c.Ancestors) > 0 { |
|
175 |
indentedPrint(w, indent, false, false, "Ancestors", "") |
|
176 |
p.PrintObj(c.Ancestors, w, indent+p.Indent) |
|
177 |
} |
|
178 |
if len(c.Descendents) > 0 { |
|
179 |
indentedPrint(w, indent, false, false, "Descendents", "") |
|
180 |
p.PrintObj(c.Descendents, w, indent+p.Indent) |
|
181 |
} |
|
182 |
return nil |
|
183 |
} |
|
184 |
||
185 |
func (p *PlainPrinter) plainPrintInstance(i *madon.Instance, w io.Writer, indent string) error { |
|
186 |
indentedPrint(w, indent, true, false, "Instance title", "%s", i.Title) |
|
187 |
indentedPrint(w, indent, false, true, "Description", "%s", html2string(i.Description)) |
|
188 |
indentedPrint(w, indent, false, true, "URL", "%s", i.URI) |
|
189 |
indentedPrint(w, indent, false, true, "Email", "%s", i.Email) |
|
18
7a4b57b3e66a
Display instance version, if field is set
Mikael Berthe <mikael@lilotux.net>
parents:
0
diff
changeset
|
190 |
indentedPrint(w, indent, false, true, "Version", "%s", i.Version) |
0 | 191 |
return nil |
192 |
} |
|
193 |
||
194 |
func (p *PlainPrinter) plainPrintNotification(n *madon.Notification, w io.Writer, indent string) error { |
|
195 |
indentedPrint(w, indent, true, false, "Notification ID", "%d", n.ID) |
|
196 |
indentedPrint(w, indent, false, false, "Type", "%s", n.Type) |
|
197 |
indentedPrint(w, indent, false, false, "Timestamp", "%v", n.CreatedAt.Local()) |
|
198 |
if n.Account != nil { |
|
199 |
indentedPrint(w, indent+p.Indent, true, false, "Account", "(%d) @%s - %s", |
|
200 |
n.Account.ID, n.Account.Acct, n.Account.DisplayName) |
|
201 |
} |
|
202 |
if n.Status != nil { |
|
203 |
p.plainPrintStatus(n.Status, w, indent+p.Indent) |
|
204 |
} |
|
205 |
return nil |
|
206 |
} |
|
207 |
||
208 |
func (p *PlainPrinter) plainPrintRelationship(r *madon.Relationship, w io.Writer, indent string) error { |
|
209 |
indentedPrint(w, indent, true, false, "ID", "%d", r.ID) |
|
210 |
indentedPrint(w, indent, false, false, "Following", "%v", r.Following) |
|
211 |
indentedPrint(w, indent, false, false, "Followed-by", "%v", r.FollowedBy) |
|
212 |
indentedPrint(w, indent, false, false, "Blocking", "%v", r.Blocking) |
|
213 |
indentedPrint(w, indent, false, false, "Muting", "%v", r.Muting) |
|
214 |
indentedPrint(w, indent, false, false, "Requested", "%v", r.Requested) |
|
215 |
return nil |
|
216 |
} |
|
217 |
||
218 |
func (p *PlainPrinter) plainPrintReport(r *madon.Report, w io.Writer, indent string) error { |
|
219 |
indentedPrint(w, indent, true, false, "Report ID", "%d", r.ID) |
|
220 |
indentedPrint(w, indent, false, false, "Action taken", "%s", r.ActionTaken) |
|
221 |
return nil |
|
222 |
} |
|
223 |
||
224 |
func (p *PlainPrinter) plainPrintResults(r *madon.Results, w io.Writer, indent string) error { |
|
225 |
indentedPrint(w, indent, true, false, "Results", "%d account(s), %d status(es), %d hashtag(s)", |
|
226 |
len(r.Accounts), len(r.Statuses), len(r.Hashtags)) |
|
227 |
if len(r.Accounts) > 0 { |
|
228 |
indentedPrint(w, indent, false, false, "Accounts", "") |
|
229 |
p.PrintObj(r.Accounts, w, indent+p.Indent) |
|
230 |
} |
|
231 |
if len(r.Statuses) > 0 { |
|
232 |
indentedPrint(w, indent, false, false, "Statuses", "") |
|
233 |
p.PrintObj(r.Statuses, w, indent+p.Indent) |
|
234 |
} |
|
235 |
if len(r.Hashtags) > 0 { |
|
236 |
indentedPrint(w, indent, false, false, "Hashtags", "") |
|
237 |
for _, tag := range r.Hashtags { |
|
238 |
indentedPrint(w, indent+p.Indent, true, false, "Tag", "%s", tag) |
|
239 |
} |
|
240 |
} |
|
241 |
return nil |
|
242 |
} |
|
243 |
||
244 |
func (p *PlainPrinter) plainPrintStatus(s *madon.Status, w io.Writer, indent string) error { |
|
245 |
indentedPrint(w, indent, true, false, "Status ID", "%d", s.ID) |
|
246 |
indentedPrint(w, indent, false, false, "From", "%s", s.Account.Acct) |
|
247 |
indentedPrint(w, indent, false, false, "Timestamp", "%v", s.CreatedAt.Local()) |
|
248 |
||
249 |
if s.Reblog != nil { |
|
250 |
indentedPrint(w, indent, false, false, "Reblogged from", "%s", s.Reblog.Account.Username) |
|
251 |
return p.plainPrintStatus(s.Reblog, w, indent+p.Indent) |
|
252 |
} |
|
253 |
||
254 |
indentedPrint(w, indent, false, false, "Contents", "%s", html2string(s.Content)) |
|
255 |
if s.InReplyToID > 0 { |
|
256 |
indentedPrint(w, indent, false, false, "In-Reply-To", "%d", s.InReplyToID) |
|
257 |
} |
|
258 |
if s.Reblogged { |
|
259 |
indentedPrint(w, indent, false, false, "Reblogged", "%v", s.Reblogged) |
|
260 |
} |
|
261 |
indentedPrint(w, indent, false, false, "URL", "%s", s.URL) |
|
262 |
return nil |
|
263 |
} |
|
264 |
||
265 |
func (p *PlainPrinter) plainPrintUserToken(s *madon.UserToken, w io.Writer, indent string) error { |
|
266 |
indentedPrint(w, indent, true, false, "User token", "%s", s.AccessToken) |
|
267 |
indentedPrint(w, indent, false, true, "Type", "%s", s.TokenType) |
|
268 |
if s.CreatedAt != 0 { |
|
269 |
indentedPrint(w, indent, false, true, "Timestamp", "%v", time.Unix(int64(s.CreatedAt), 0)) |
|
270 |
} |
|
271 |
indentedPrint(w, indent, false, true, "Scope", "%s", s.Scope) |
|
272 |
return nil |
|
273 |
} |