sina: package tracking via orangeconnex

Signed-off-by: Christine Dodrill <me@christine.website>
This commit is contained in:
Cadey Ratio 2020-12-30 23:23:12 -05:00
parent 3521b125cf
commit 97d5e9e9c2
11 changed files with 261 additions and 17 deletions

View File

@ -22,6 +22,21 @@ pub fn track(conn: MainDatabase, tn: StringBody, tok: paseto::Token) -> Result<S
Ok(format!("now tracking package {}", tn))
}
#[get("/packages/orangeconnex")]
#[instrument(skip(conn), err)]
pub fn list(
conn: MainDatabase,
tok: paseto::Token,
) -> Result<Json<Vec<models::OrangeConnexPackage>>> {
use schema::orangeconnex_packages;
Ok(Json(
orangeconnex_packages::table
.load::<models::OrangeConnexPackage>(&*conn)
.map_err(Error::Database)?,
))
}
#[get("/packages/orangeconnex/status?<tn>")]
#[instrument(skip(conn), err)]
pub fn status(
@ -29,10 +44,11 @@ pub fn status(
tn: String,
tok: paseto::Token,
) -> Result<Json<Vec<models::OrangeConnexTrace>>> {
use schema::orangeconnex_traces;
use schema::orangeconnex_traces::dsl::*;
Ok(Json(
orangeconnex_traces::table
orangeconnex_traces
.filter(tracking_number.eq(tn))
.load::<models::OrangeConnexTrace>(&*conn)
.map_err(Error::Database)?,
))

View File

@ -70,9 +70,10 @@ fn main() -> Result<()> {
.mount(
"/api",
routes![
api::package_tracking::orangeconnex::track,
api::package_tracking::orangeconnex::status,
api::package_tracking::orangeconnex::list,
api::package_tracking::orangeconnex::recieved,
api::package_tracking::orangeconnex::status,
api::package_tracking::orangeconnex::track,
api::posse::notify,
api::posse::refresh_blog,
api::switch::current_front,

View File

@ -73,7 +73,7 @@ pub struct Blogpost {
pub title: String,
}
#[derive(Queryable, Associations, Insertable, AsChangeset)]
#[derive(Queryable, Associations, Insertable, AsChangeset, Serialize)]
#[table_name = "orangeconnex_packages"]
pub struct OrangeConnexPackage {
pub tracking_number: String,
@ -104,7 +104,7 @@ impl OrangeConnexTrace {
country: t.opr_country,
time_recorded: t.opr_time,
time_zone: t.opr_time_zone,
ts: t.opr_timestamp,
ts: t.opr_timestamp.try_into().unwrap_or(1337),
}
}
}

View File

@ -66,7 +66,7 @@ pub struct Trace {
pub opr_country: String,
pub opr_time: String,
pub opr_time_zone: String,
pub opr_timestamp: i32,
pub opr_timestamp: i64,
}
#[derive(Deserialize, Serialize, Clone, Debug)]

View File

@ -38,9 +38,10 @@ template title body =
, a [ href "/posse" ] [ text "POSSE" ]
, text " - "
, a [ href "/switches" ] [ text "Switches" ]
--, text " - "
--, a [ href "/webmentions" ] [ text "WebMentions" ]
, text " - "
, a [ href "/packages" ] [ text "Packages" ]
, text " - "
, a [ href "/webmentions" ] [ text "WebMentions" ]
]
, h1 [] [ text title ]
]

View File

@ -9,11 +9,14 @@ import Http
import Json.Decode
import Layout
import Mi
import Mi.PackageTracking.OrangeConnex
import Mi.Switch
import Mi.WebMention
import Model exposing (Model, Msg(..), get, init)
import Page.Index
import Page.Login
import Page.OrangeConnex
import Page.Packages
import Page.SwitchInfo
import Page.Switches
import Route exposing (Route(..), routeParser)
@ -73,6 +76,20 @@ update msg model =
Json.Decode.list Mi.Switch.decoder
)
FetchOCPackages ->
( model
, get model Mi.PackageTracking.OrangeConnex.packageListURL <|
Mi.expectJson ValidateOCPackages <|
Json.Decode.list Mi.PackageTracking.OrangeConnex.decodePackage
)
FetchOCTraces trackingID ->
( { model | ocTrackingID = Just trackingID }
, get model (Mi.PackageTracking.OrangeConnex.packageStatusURL trackingID) <|
Mi.expectJson ValidateOCTraces <|
Json.Decode.list Mi.PackageTracking.OrangeConnex.decodeTrace
)
ValidateSwitchByID result ->
if_okay result <|
\data ->
@ -95,6 +112,16 @@ update msg model =
, Nav.pushUrl model.navKey "/"
)
ValidateOCPackages result ->
if_okay result <|
\data ->
( { model | ocPackages = Just data }, Cmd.none )
ValidateOCTraces result ->
if_okay result <|
\data ->
( { model | ocTraces = Just data }, Cmd.none )
ClickLink urlRequest ->
case urlRequest of
Internal url ->
@ -124,6 +151,15 @@ view model =
SwitchID _ ->
Page.SwitchInfo.view model
Packages ->
Page.Packages.view
OCPackages ->
Page.OrangeConnex.viewList model
OCPackage packageID ->
Page.OrangeConnex.viewPackage { model | ocTrackingID = Just packageID }
_ ->
Layout.template "Oh noes" [ p [] [ text "todo: implement this 404 page" ] ]

View File

@ -0,0 +1,64 @@
module Mi.PackageTracking.OrangeConnex exposing (..)
import Json.Decode as D
import Json.Encode as E
import Url.Builder as UB
type alias Package =
{ tracking_number : String
, recieved : Bool
}
decodePackage : D.Decoder Package
decodePackage =
D.map2 Package
(D.field "tracking_number" D.string)
(D.field "recieved" D.bool)
type alias Trace =
{ id : String
, tracking_number : String
, description : String
, city : Maybe String
, country : String
, time_recorded : String
, time_zone : String
, ts : Int
}
decodeTrace : D.Decoder Trace
decodeTrace =
D.map8 Trace
(D.field "id" D.string)
(D.field "tracking_number" D.string)
(D.field "description" D.string)
(D.field "city" (D.nullable D.string))
(D.field "country" D.string)
(D.field "time_recorded" D.string)
(D.field "time_zone" D.string)
(D.field "ts" D.int)
packageListURL : String
packageListURL =
UB.absolute
[ "api", "packages", "orangeconnex" ]
[]
packageStatusURL : String -> String
packageStatusURL trackingNumber =
UB.absolute
[ "api", "packages", "orangeconnex", "status" ]
[ UB.string "tn" trackingNumber ]
markRecievedURL : String -> String
markRecievedURL trackingNumber =
UB.absolute
[ "api", "packages", "orangeconnex", "delivered" ]
[ UB.string "tn" trackingNumber ]

View File

@ -5,6 +5,7 @@ import Browser.Navigation as Nav
import Http
import Mi
import Mi.POSSE
import Mi.PackageTracking.OrangeConnex as OrangeConnex
import Mi.Switch exposing (Switch)
import Mi.WebMention exposing (WebMention)
import Route exposing (Route, routeParser)
@ -26,6 +27,9 @@ type alias Model =
, switchByID : Maybe Switch
, webMentionByID : Maybe WebMention
, post : Mi.POSSE.Post
, ocTrackingID : Maybe String
, ocPackages : Maybe (List OrangeConnex.Package)
, ocTraces : Maybe (List OrangeConnex.Trace)
}
@ -47,10 +51,14 @@ type Msg
| FetchSwitch String
| NextSwitchesPage
| PrevSwitchesPage
| FetchOCPackages
| FetchOCTraces String
| ValidateToken (Result Http.Error Mi.TokenData)
| ValidateSwitchByID (Result Http.Error Switch)
| ValidateFront (Result Http.Error Switch)
| ValidateSwitches (Result Http.Error (List Switch))
| ValidateOCPackages (Result Http.Error (List OrangeConnex.Package))
| ValidateOCTraces (Result Http.Error (List OrangeConnex.Trace))
| ClearError
@ -69,6 +77,9 @@ init _ url key =
, switchByID = Nothing
, webMentionByID = Nothing
, post = Mi.POSSE.init
, ocTrackingID = Nothing
, ocPackages = Nothing
, ocTraces = Nothing
}
, Nav.pushUrl key "/login"
)

View File

@ -0,0 +1,92 @@
module Page.OrangeConnex exposing (viewList, viewPackage)
import Browser exposing (Document)
import Html exposing (a, br, button, h2, img, p, span, table, td, text, th, tr)
import Html.Attributes exposing (height, href, src, style, width)
import Html.Events exposing (onClick)
import Iso8601
import Layout exposing (template)
import Mi.PackageTracking.OrangeConnex exposing (Package, Trace)
import Model exposing (Msg(..))
type alias Model a =
{ a
| ocTrackingID : Maybe String
, ocPackages : Maybe (List Package)
, ocTraces : Maybe (List Trace)
}
viewList : Model a -> Document Msg
viewList { ocPackages } =
case ocPackages of
Nothing ->
Layout.template "Loading" [ text "please wait..." ]
Just packages ->
let
heading =
tr
[]
[ th [] [ text "ID" ]
, th [] [ text "recieved" ]
]
stringFromBool value =
if value then
"True"
else
"False"
rowify data =
tr
[]
[ td
[]
[ a
[ href <| "/packages/orangeconnex/" ++ data.tracking_number, onClick <| FetchOCTraces data.tracking_number ]
[ text data.tracking_number ]
]
, td [] [ text <| stringFromBool data.recieved ]
]
contents =
List.map rowify packages
in
Layout.template "OrangeConnex Packages"
[ table [] <| [ heading ] ++ contents ]
viewPackage : Model a -> Document Msg
viewPackage { ocTraces, ocTrackingID } =
case ocTraces of
Nothing ->
Layout.template "Loading..." [ span [] [] ]
Just traces ->
let
heading =
tr
[]
[ th [] [ text "Message" ]
, th [] [ text "City" ]
, th [] [ text "Country" ]
]
rowify data =
tr
[]
[ td [] [ text data.description ]
, td [] [ text <| Maybe.withDefault "" data.city ]
, td [] [ text data.country ]
]
contents =
List.map rowify traces
title =
"Info on package " ++ Maybe.withDefault "" ocTrackingID
in
Layout.template title [ table [] <| [ heading ] ++ contents ]

View File

@ -0,0 +1,17 @@
module Page.Packages exposing (view)
import Browser exposing (Document)
import Html exposing (a, text)
import Html.Attributes exposing (href)
import Html.Events exposing (onClick)
import Iso8601
import Layout exposing (basic, template)
import Mi
import Model exposing (Msg(..))
view : Document Msg
view =
template
"Package Deliveries"
[ a [ href "/packages/orangeconnex", onClick FetchOCPackages ] [ text "OrangeConnex" ] ]

View File

@ -12,16 +12,22 @@ type Route
| MakeSwitch
| WebMentionLog
| WebMentionID String
| Packages
| OCPackages
| OCPackage String
routeParser : Parser (Route -> a) a
routeParser =
oneOf
[ map Index (s "")
, map Login (s "login")
, map SwitchLog (s "switches")
, map SwitchID (s "switches" </> string)
, map MakeSwitch (s "switches" </> s "log")
, map WebMentionLog (s "webmentions")
, map WebMentionID (s "webmentions" </> string)
[ map Index <| s ""
, map Login <| s "login"
, map SwitchLog <| s "switches"
, map SwitchID <| s "switches" </> string
, map MakeSwitch <| s "switches" </> s "log"
, map WebMentionLog <| s "webmentions"
, map WebMentionID <| s "webmentions" </> string
, map Packages <| s "packages"
, map OCPackages <| s "packages" </> s "orangeconnex"
, map OCPackage <| s "packages" </> s "orangeconnex" </> string
]