sina: package tracking via orangeconnex
Signed-off-by: Christine Dodrill <me@christine.website>
This commit is contained in:
parent
3521b125cf
commit
97d5e9e9c2
|
@ -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)?,
|
||||
))
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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 ]
|
||||
]
|
||||
|
|
|
@ -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" ] ]
|
||||
|
||||
|
|
|
@ -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 ]
|
|
@ -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"
|
||||
)
|
||||
|
|
|
@ -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 ]
|
|
@ -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" ] ]
|
|
@ -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
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue