printer/plain.go
changeset 0 5abace724584
child 18 7a4b57b3e66a
equal deleted inserted replaced
-1:000000000000 0:5abace724584
       
     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)
       
   190 	return nil
       
   191 }
       
   192 
       
   193 func (p *PlainPrinter) plainPrintNotification(n *madon.Notification, w io.Writer, indent string) error {
       
   194 	indentedPrint(w, indent, true, false, "Notification ID", "%d", n.ID)
       
   195 	indentedPrint(w, indent, false, false, "Type", "%s", n.Type)
       
   196 	indentedPrint(w, indent, false, false, "Timestamp", "%v", n.CreatedAt.Local())
       
   197 	if n.Account != nil {
       
   198 		indentedPrint(w, indent+p.Indent, true, false, "Account", "(%d) @%s - %s",
       
   199 			n.Account.ID, n.Account.Acct, n.Account.DisplayName)
       
   200 	}
       
   201 	if n.Status != nil {
       
   202 		p.plainPrintStatus(n.Status, w, indent+p.Indent)
       
   203 	}
       
   204 	return nil
       
   205 }
       
   206 
       
   207 func (p *PlainPrinter) plainPrintRelationship(r *madon.Relationship, w io.Writer, indent string) error {
       
   208 	indentedPrint(w, indent, true, false, "ID", "%d", r.ID)
       
   209 	indentedPrint(w, indent, false, false, "Following", "%v", r.Following)
       
   210 	indentedPrint(w, indent, false, false, "Followed-by", "%v", r.FollowedBy)
       
   211 	indentedPrint(w, indent, false, false, "Blocking", "%v", r.Blocking)
       
   212 	indentedPrint(w, indent, false, false, "Muting", "%v", r.Muting)
       
   213 	indentedPrint(w, indent, false, false, "Requested", "%v", r.Requested)
       
   214 	return nil
       
   215 }
       
   216 
       
   217 func (p *PlainPrinter) plainPrintReport(r *madon.Report, w io.Writer, indent string) error {
       
   218 	indentedPrint(w, indent, true, false, "Report ID", "%d", r.ID)
       
   219 	indentedPrint(w, indent, false, false, "Action taken", "%s", r.ActionTaken)
       
   220 	return nil
       
   221 }
       
   222 
       
   223 func (p *PlainPrinter) plainPrintResults(r *madon.Results, w io.Writer, indent string) error {
       
   224 	indentedPrint(w, indent, true, false, "Results", "%d account(s), %d status(es), %d hashtag(s)",
       
   225 		len(r.Accounts), len(r.Statuses), len(r.Hashtags))
       
   226 	if len(r.Accounts) > 0 {
       
   227 		indentedPrint(w, indent, false, false, "Accounts", "")
       
   228 		p.PrintObj(r.Accounts, w, indent+p.Indent)
       
   229 	}
       
   230 	if len(r.Statuses) > 0 {
       
   231 		indentedPrint(w, indent, false, false, "Statuses", "")
       
   232 		p.PrintObj(r.Statuses, w, indent+p.Indent)
       
   233 	}
       
   234 	if len(r.Hashtags) > 0 {
       
   235 		indentedPrint(w, indent, false, false, "Hashtags", "")
       
   236 		for _, tag := range r.Hashtags {
       
   237 			indentedPrint(w, indent+p.Indent, true, false, "Tag", "%s", tag)
       
   238 		}
       
   239 	}
       
   240 	return nil
       
   241 }
       
   242 
       
   243 func (p *PlainPrinter) plainPrintStatus(s *madon.Status, w io.Writer, indent string) error {
       
   244 	indentedPrint(w, indent, true, false, "Status ID", "%d", s.ID)
       
   245 	indentedPrint(w, indent, false, false, "From", "%s", s.Account.Acct)
       
   246 	indentedPrint(w, indent, false, false, "Timestamp", "%v", s.CreatedAt.Local())
       
   247 
       
   248 	if s.Reblog != nil {
       
   249 		indentedPrint(w, indent, false, false, "Reblogged from", "%s", s.Reblog.Account.Username)
       
   250 		return p.plainPrintStatus(s.Reblog, w, indent+p.Indent)
       
   251 	}
       
   252 
       
   253 	indentedPrint(w, indent, false, false, "Contents", "%s", html2string(s.Content))
       
   254 	if s.InReplyToID > 0 {
       
   255 		indentedPrint(w, indent, false, false, "In-Reply-To", "%d", s.InReplyToID)
       
   256 	}
       
   257 	if s.Reblogged {
       
   258 		indentedPrint(w, indent, false, false, "Reblogged", "%v", s.Reblogged)
       
   259 	}
       
   260 	indentedPrint(w, indent, false, false, "URL", "%s", s.URL)
       
   261 	return nil
       
   262 }
       
   263 
       
   264 func (p *PlainPrinter) plainPrintUserToken(s *madon.UserToken, w io.Writer, indent string) error {
       
   265 	indentedPrint(w, indent, true, false, "User token", "%s", s.AccessToken)
       
   266 	indentedPrint(w, indent, false, true, "Type", "%s", s.TokenType)
       
   267 	if s.CreatedAt != 0 {
       
   268 		indentedPrint(w, indent, false, true, "Timestamp", "%v", time.Unix(int64(s.CreatedAt), 0))
       
   269 	}
       
   270 	indentedPrint(w, indent, false, true, "Scope", "%s", s.Scope)
       
   271 	return nil
       
   272 }