diff --git a/config/config.go b/config/config.go index 17fceca..c463c91 100644 --- a/config/config.go +++ b/config/config.go @@ -6,6 +6,7 @@ import ( "io" "os" "strings" + "web/model" ) type config struct { @@ -17,6 +18,7 @@ type config struct { TemplatesGlobPattern string DatabasePath string CustomCSS string + PostFormats []model.PostFormat Logfile string } @@ -43,7 +45,13 @@ func getDefaultConfig() *config { TemplatesGlobPattern: "templates/*", DatabasePath: "database.db", CustomCSS: "", - Logfile: "", + PostFormats: []model.PostFormat{ + model.PostFormat{"Plain Text", "text/plain"}, + model.PostFormat{"HTML", "text/html"}, + model.PostFormat{"Markdown", "text/markdown"}, + model.PostFormat{"BBCode", "text/bbcode"}, + }, + Logfile: "", } } @@ -87,6 +95,25 @@ func Parse(r io.Reader) (c *config, err error) { c.DatabasePath = val case "custom_css": c.CustomCSS = val + case "post_formats": + vals := strings.Split(val, ",") + var formats []model.PostFormat + for _, v := range vals { + pair := strings.Split(v, ":") + if len(pair) != 2 { + return nil, errors.New("invalid config key " + key) + } + n := strings.TrimSpace(pair[0]) + t := strings.TrimSpace(pair[1]) + if len(n) < 1 || len(t) < 1 { + return nil, errors.New("invalid config key " + key) + } + formats = append(formats, model.PostFormat{ + Name: n, + Type: t, + }) + } + c.PostFormats = formats case "logfile": c.Logfile = val default: diff --git a/default.conf b/default.conf index eede82b..81ed26a 100644 --- a/default.conf +++ b/default.conf @@ -5,4 +5,5 @@ client_website=http://localhost:8080 static_directory=static templates_glob_pattern=templates/* #custom_css=custom.css +#post_formats=PlainText:text/plain,HTML:text/html,Markdown:text/markdown,BBCode:text/bbcode database_path=database diff --git a/main.go b/main.go index f9fdc8f..e29f53a 100644 --- a/main.go +++ b/main.go @@ -71,7 +71,8 @@ func main() { logger = log.New(lf, "", log.LstdFlags) } - s := service.NewService(config.ClientName, config.ClientScope, config.ClientWebsite, customCSS, renderer, sessionRepo, appRepo) + s := service.NewService(config.ClientName, config.ClientScope, config.ClientWebsite, + customCSS, config.PostFormats, renderer, sessionRepo, appRepo) s = service.NewAuthService(sessionRepo, appRepo, s) s = service.NewLoggingService(logger, s) handler := service.NewHandler(s, config.StaticDirectory) diff --git a/mastodon/mastodon.go b/mastodon/mastodon.go index 22f5a53..8a8af6a 100644 --- a/mastodon/mastodon.go +++ b/mastodon/mastodon.go @@ -273,6 +273,7 @@ type Toot struct { Sensitive bool `json:"sensitive"` SpoilerText string `json:"spoiler_text"` Visibility string `json:"visibility"` + ContentType string `json:"content_type"` } // Mention hold information for mention. diff --git a/mastodon/status.go b/mastodon/status.go index c36b6cb..edd88e9 100644 --- a/mastodon/status.go +++ b/mastodon/status.go @@ -266,6 +266,9 @@ func (c *Client) PostStatus(ctx context.Context, toot *Toot) (*Status, error) { if toot.SpoilerText != "" { params.Set("spoiler_text", toot.SpoilerText) } + if toot.ContentType != "" { + params.Set("content_type", toot.ContentType) + } var status Status err := c.doAPI(ctx, http.MethodPost, "/api/v1/statuses", params, &status, nil) diff --git a/model/postContext.go b/model/postContext.go index 90e5771..3098437 100644 --- a/model/postContext.go +++ b/model/postContext.go @@ -1,8 +1,14 @@ package model +type PostFormat struct { + Name string + Type string +} + type PostContext struct { DefaultVisibility string ReplyContext *ReplyContext + Formats []PostFormat } type ReplyContext struct { diff --git a/service/auth.go b/service/auth.go index c408672..0c2e7f6 100644 --- a/service/auth.go +++ b/service/auth.go @@ -181,12 +181,12 @@ func (s *authService) UnRetweet(ctx context.Context, client io.Writer, c *model. return s.Service.UnRetweet(ctx, client, c, id) } -func (s *authService) PostTweet(ctx context.Context, client io.Writer, c *model.Client, content string, replyToID string, visibility string, isNSFW bool, files []*multipart.FileHeader) (id string, err error) { +func (s *authService) PostTweet(ctx context.Context, client io.Writer, c *model.Client, content string, replyToID string, format string, visibility string, isNSFW bool, files []*multipart.FileHeader) (id string, err error) { c, err = s.getClient(ctx) if err != nil { return } - return s.Service.PostTweet(ctx, client, c, content, replyToID, visibility, isNSFW, files) + return s.Service.PostTweet(ctx, client, c, content, replyToID, format, visibility, isNSFW, files) } func (s *authService) Follow(ctx context.Context, client io.Writer, c *model.Client, id string) (err error) { diff --git a/service/logging.go b/service/logging.go index fbc6371..f5e6d66 100644 --- a/service/logging.go +++ b/service/logging.go @@ -157,12 +157,12 @@ func (s *loggingService) UnRetweet(ctx context.Context, client io.Writer, c *mod return s.Service.UnRetweet(ctx, client, c, id) } -func (s *loggingService) PostTweet(ctx context.Context, client io.Writer, c *model.Client, content string, replyToID string, visibility string, isNSFW bool, files []*multipart.FileHeader) (id string, err error) { +func (s *loggingService) PostTweet(ctx context.Context, client io.Writer, c *model.Client, content string, replyToID string, format string, visibility string, isNSFW bool, files []*multipart.FileHeader) (id string, err error) { defer func(begin time.Time) { - s.logger.Printf("method=%v, content=%v, reply_to_id=%v, visibility=%v, is_nsfw=%v, took=%v, err=%v\n", - "PostTweet", content, replyToID, visibility, isNSFW, time.Since(begin), err) + s.logger.Printf("method=%v, content=%v, reply_to_id=%v, format=%v, visibility=%v, is_nsfw=%v, took=%v, err=%v\n", + "PostTweet", content, replyToID, format, visibility, isNSFW, time.Since(begin), err) }(time.Now()) - return s.Service.PostTweet(ctx, client, c, content, replyToID, visibility, isNSFW, files) + return s.Service.PostTweet(ctx, client, c, content, replyToID, format, visibility, isNSFW, files) } func (s *loggingService) Follow(ctx context.Context, client io.Writer, c *model.Client, id string) (err error) { diff --git a/service/service.go b/service/service.go index 7dc784f..2787079 100644 --- a/service/service.go +++ b/service/service.go @@ -43,7 +43,7 @@ type Service interface { UnLike(ctx context.Context, client io.Writer, c *model.Client, id string) (err error) Retweet(ctx context.Context, client io.Writer, c *model.Client, id string) (err error) UnRetweet(ctx context.Context, client io.Writer, c *model.Client, id string) (err error) - PostTweet(ctx context.Context, client io.Writer, c *model.Client, content string, replyToID string, visibility string, isNSFW bool, files []*multipart.FileHeader) (id string, err error) + PostTweet(ctx context.Context, client io.Writer, c *model.Client, content string, replyToID string, format string, visibility string, isNSFW bool, files []*multipart.FileHeader) (id string, err error) Follow(ctx context.Context, client io.Writer, c *model.Client, id string) (err error) UnFollow(ctx context.Context, client io.Writer, c *model.Client, id string) (err error) } @@ -53,19 +53,21 @@ type service struct { clientScope string clientWebsite string customCSS string + postFormats []model.PostFormat renderer renderer.Renderer sessionRepo model.SessionRepository appRepo model.AppRepository } func NewService(clientName string, clientScope string, clientWebsite string, - customCSS string, renderer renderer.Renderer, sessionRepo model.SessionRepository, - appRepo model.AppRepository) Service { + customCSS string, postFormats []model.PostFormat, renderer renderer.Renderer, + sessionRepo model.SessionRepository, appRepo model.AppRepository) Service { return &service{ clientName: clientName, clientScope: clientScope, clientWebsite: clientWebsite, customCSS: customCSS, + postFormats: postFormats, renderer: renderer, sessionRepo: sessionRepo, appRepo: appRepo, @@ -297,6 +299,7 @@ func (svc *service) ServeTimelinePage(ctx context.Context, client io.Writer, postContext := model.PostContext{ DefaultVisibility: c.Session.Settings.DefaultVisibility, + Formats: svc.postFormats, } commonData, err := svc.getCommonData(ctx, client, c) @@ -353,6 +356,7 @@ func (svc *service) ServeThreadPage(ctx context.Context, client io.Writer, c *mo postContext = model.PostContext{ DefaultVisibility: s.Visibility, + Formats: svc.postFormats, ReplyContext: &model.ReplyContext{ InReplyToID: id, InReplyToName: status.Account.Acct, @@ -647,7 +651,7 @@ func (svc *service) UnRetweet(ctx context.Context, client io.Writer, c *model.Cl return } -func (svc *service) PostTweet(ctx context.Context, client io.Writer, c *model.Client, content string, replyToID string, visibility string, isNSFW bool, files []*multipart.FileHeader) (id string, err error) { +func (svc *service) PostTweet(ctx context.Context, client io.Writer, c *model.Client, content string, replyToID string, format string, visibility string, isNSFW bool, files []*multipart.FileHeader) (id string, err error) { var mediaIds []string for _, f := range files { a, err := c.UploadMediaFromMultipartFileHeader(ctx, f) @@ -667,6 +671,7 @@ func (svc *service) PostTweet(ctx context.Context, client io.Writer, c *model.Cl Status: content, InReplyToID: replyToID, MediaIDs: mediaIds, + ContentType: format, Visibility: visibility, Sensitive: isNSFW, } diff --git a/service/transport.go b/service/transport.go index d4011db..6541772 100644 --- a/service/transport.go +++ b/service/transport.go @@ -183,12 +183,13 @@ func NewHandler(s Service, staticDir string) http.Handler { content := getMultipartFormValue(req.MultipartForm, "content") replyToID := getMultipartFormValue(req.MultipartForm, "reply_to_id") + format := getMultipartFormValue(req.MultipartForm, "format") visibility := getMultipartFormValue(req.MultipartForm, "visibility") isNSFW := "on" == getMultipartFormValue(req.MultipartForm, "is_nsfw") files := req.MultipartForm.File["attachments"] - id, err := s.PostTweet(ctx, w, nil, content, replyToID, visibility, isNSFW, files) + id, err := s.PostTweet(ctx, w, nil, content, replyToID, format, visibility, isNSFW, files) if err != nil { s.ServeErrorPage(ctx, w, err) return diff --git a/templates/postform.tmpl b/templates/postform.tmpl index 54024f0..0e104b4 100644 --- a/templates/postform.tmpl +++ b/templates/postform.tmpl @@ -12,6 +12,14 @@