This commit is contained in:
Cadey Ratio 2020-01-18 17:28:10 -05:00
parent 2ac8f81c9f
commit 52812abba2
9 changed files with 266 additions and 28 deletions

View File

@ -160,6 +160,12 @@ func main() {
mi.RegisterPusher(mi.PushTwitter)
go mi.StreamMastodonToTwitter(ctx)
go mi.BlogPOSSE(ctx)
} else {
mi.RegisterPusher(func(ctx context.Context, p Post) error {
ln.Log(ctx, p)
fmt.Println(p.Format())
return nil
})
}
h := &http.Server{

View File

@ -27,4 +27,5 @@ func (mi *Mi) RegisterPusher(p Pusher) {
func (mi *Mi) RegisterRoutes() {
mi.mux.HandleFunc("/blog/refresh", mi.RefreshBlog)
mi.mux.HandleFunc("/.within/botinfo", botInfoPage)
mi.mux.HandleFunc("/posse/post", mi.PostPOSSE)
}

View File

@ -2,7 +2,9 @@ package main
import (
"context"
"encoding/json"
"fmt"
"net/http"
"strings"
"github.com/hashicorp/go-multierror"
@ -12,21 +14,32 @@ import (
type Pusher func(context.Context, Post) error
type Post struct {
Title string
URL string
Tags []string
Title string `json:"title"`
URL string `json:"url"`
Body string `json:"body"`
Tags []string `json:"tags"`
}
func (p Post) Format() string {
var sb strings.Builder
fmt.Fprintf(&sb, "New post: %s\n\n%s\n\n", p.Title, p.URL)
if p.Title != "" {
fmt.Fprintf(&sb, "%s\n\n", p.Title)
}
if p.URL != "" {
fmt.Fprintf(&sb, "%s\n\n", p.URL)
}
if p.Body != "" {
fmt.Fprintf(&sb, "%s\n\n", p.Body)
}
for _, tg := range p.Tags {
tg = strings.ReplaceAll(tg, "-", "")
fmt.Fprintf(&sb, "#%s ", tg)
}
return sb.String()
return strings.TrimSpace(sb.String())
}
func (p Post) F() ln.F {
@ -34,6 +47,7 @@ func (p Post) F() ln.F {
"post_title": p.Title,
"post_url": p.URL,
"post_tags": p.Tags,
"post_body": p.Body,
}
}
@ -49,3 +63,15 @@ func (mi *Mi) Push(ctx context.Context, p Post) error {
return result
}
func (mi *Mi) PostPOSSE(w http.ResponseWriter, r *http.Request) {
var data Post
err := json.NewDecoder(r.Body).Decode(&data)
if err != nil {
http.Error(w, "bad data", http.StatusBadRequest)
ln.Error(r.Context(), err)
return
}
mi.Push(r.Context(), data)
}

View File

@ -44,6 +44,7 @@ viewHeader currentRoute =
]
[ viewLink currentRoute ( "Mi", routes.top )
, viewLink currentRoute ( "Switch Data", routes.switch )
, viewLink currentRoute ( "POSSE", routes.pOSSE )
]

View File

@ -1,6 +1,6 @@
module Mi exposing (TokenData, expectJson, request, tokenDecoder)
module Mi exposing (TokenData, errorToString, expectJson, request, tokenDecoder)
import Http
import Http exposing (Error(..))
import Json.Decode as D
@ -55,3 +55,22 @@ expectJson toMsg decoder =
Err err ->
Err (Http.BadBody (D.errorToString err))
errorToString : Http.Error -> String
errorToString err =
case err of
Timeout ->
"Timeout exceeded"
NetworkError ->
"Network error"
BadStatus st ->
"Bad status code: " ++ String.fromInt st
BadBody text ->
"Unexpected response from api: " ++ text
BadUrl url ->
"Malformed url: " ++ url

31
frontend/src/Mi/POSSE.elm Normal file
View File

@ -0,0 +1,31 @@
module Mi.POSSE exposing (..)
import Json.Decode as D
import Json.Encode as E
type alias Post =
{ title : String
, body : String
, url : String
, tags : List String
}
encoder : Post -> E.Value
encoder post =
E.object
[ ( "title", E.string post.title )
, ( "body", E.string post.body )
, ( "url", E.string post.url )
, ( "tags", E.list E.string post.tags )
]
decoder : D.Decoder Post
decoder =
D.map4 Post
(D.field "title" D.string)
(D.field "body" D.string)
(D.field "url" D.string)
(D.field "tags" (D.list D.string))

View File

@ -0,0 +1,169 @@
module Pages.POSSE exposing (Model, Msg, page)
import Element exposing (..)
import Element.Background as Background
import Element.Font as Font
import Element.Input as Input
import Generated.Params as Params
import Global
import Http
import Mi
import Mi.POSSE as POSSE
import Spa.Page
import Utils.Spa exposing (Page, PageContext)
page : Page Params.POSSE Model Msg model msg appMsg
page =
Spa.Page.component
{ title = always "POSSE"
, init = always init
, update = update
, subscriptions = always subscriptions
, view = always view
}
type alias Model =
{ title : String
, url : String
, body : String
, tags : String
, status : String
}
init : Params.POSSE -> ( Model, Cmd Msg, Cmd Global.Msg )
init _ =
( { title = ""
, url = ""
, body = ""
, tags = ""
, status = ""
}
, Cmd.none
, Cmd.none
)
type Msg
= UpdateTitle String
| UpdateBody String
| UpdateURL String
| UpdateTags String
| Send
| GotResponse (Result Http.Error String)
update : PageContext -> Msg -> Model -> ( Model, Cmd Msg, Cmd Global.Msg )
update { global } msg model =
case msg of
UpdateBody body ->
( { model | body = body }
, Cmd.none
, Cmd.none
)
UpdateURL url ->
( { model | url = url }
, Cmd.none
, Cmd.none
)
UpdateTags tags ->
( { model | tags = tags }
, Cmd.none
, Cmd.none
)
UpdateTitle title ->
( { model | title = title }
, Cmd.none
, Cmd.none
)
Send ->
let
post =
{ title = model.title
, body = model.body
, url = model.url
, tags = String.words model.tags
}
postJson =
POSSE.encoder post
in
( model
, Mi.request
"POST"
(Maybe.withDefault "" global.token)
"/posse/post"
(Http.jsonBody postJson)
(Http.expectString GotResponse)
, Cmd.none
)
GotResponse resp ->
case resp of
Ok _ ->
( { model | status = "Posted!" }
, Cmd.none
, Cmd.none
)
Err data ->
( { model | status = "Error when posting! " ++ Mi.errorToString data }
, Cmd.none
, Cmd.none
)
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
view : Model -> Element Msg
view model =
let
statusMsg =
case model.status of
"" ->
none
_ ->
row [] [ text "Status", text model.status ]
makeInput : String -> (String -> Msg) -> String -> Element Msg
makeInput label msg text =
Input.spellChecked [ padding 10, Font.size 14 ]
{ label = Input.labelAbove [] (Element.text label)
, onChange = msg
, text = text
, placeholder = Nothing
}
in
column []
[ statusMsg
, row [ padding 10 ]
[ makeInput "Title" UpdateTitle model.title
, makeInput "URL" UpdateURL model.url
, makeInput "Tags" UpdateTags model.tags
]
, Input.multiline [ Font.size 14 ]
{ label =
Input.labelAbove
[ Input.focusedOnLoad ]
(text "Body")
, onChange = UpdateBody
, spellcheck = True
, placeholder = Nothing
, text = model.body
}
, Input.button
[]
{ onPress = Just Send
, label = text "Send"
}
]

View File

@ -129,11 +129,12 @@ view model =
Nothing ->
Element.column []
[ Input.text []
[ Input.currentPassword [ Input.focusedOnLoad ]
{ label = Input.labelAbove [] (text "API Token")
, onChange = UpdateToken
, text = model.token
, placeholder = Just (Input.placeholder [] (text ""))
, show = False
}
, Input.button [] { onPress = Just SignIn, label = text "Login" }
]

View File

@ -27,10 +27,6 @@ page =
}
-- INIT
type alias Model =
{ currentFront : Maybe Mi.SwitchData.Switch
, frontData : Maybe (List Mi.SwitchData.Switch)
@ -76,10 +72,6 @@ init { global } _ =
)
-- UPDATE
type Msg
= ValidateCurrentFront (Result Http.Error Mi.SwitchData.Switch)
| ValidateFrontData (Result Http.Error (List Mi.SwitchData.Switch))
@ -126,8 +118,8 @@ update { global } msg model =
, Cmd.none
)
Err _ ->
( { model | error = Just "can't fetch current front" }
Err err ->
( { model | error = Just ("can't fetch current front: " ++ Mi.errorToString err) }
, Cmd.none
, Cmd.none
)
@ -140,26 +132,18 @@ update { global } msg model =
, Cmd.none
)
Err _ ->
( { model | error = Just "can't fetch historical front data" }
Err err ->
( { model | error = Just ("can't fetch historical front data: " ++ Mi.errorToString err) }
, Cmd.none
, Cmd.none
)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view : Model -> Element Msg
view model =
let