adding initial tbl code

master
Steve Ayerhart 2023-09-06 12:40:23 -04:00
parent 0179a4ce08
commit 7ddfae364c
Signed by: steve
GPG Key ID: BB368A0698AE49B7
9 changed files with 512 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -0,0 +1,138 @@
USING: urls pcre sequences accessors kernel assocs parser quotations combinators.short-circuit regexp arrays unicode ;
FROM: regexp => matches? ;
USING: xml.syntax xml.writer ;
USING: io io.streams.string ;
USING: math.parser math.text.english ;
USING: calendar calendar.english calendar.format ;
USING: html.parser html.parser.analyzer ;
USING: http.client ;
USING: triangle-beer-league.entities ;
IN: triangle-beer-league.daysmart
CONSTANT: daysmart-base-url URL" https://apps.daysmartrecreation.com/dash/index.php?company=dreamsports"
CONSTANT: datetime-regex "^(?<month>\\w{3}) (?<day>\\d{0,2}).{7}(?<hour>\\d{0,2}):(?<minute>\\d{0,2}) (?<ampm>[ap]m)$"
: tbl-team-name? ( name -- ? )
R/ (maroon|white|blue|teal|green|yellow|light blue|red|orange|black)$/i matches? ;
: normalize-team-name ( name -- name' )
>lower R/ \s*team$/i "" re-replace ;
! turns something like "Aug 23rd Wed 8:20 pm" into a timestamp
: parse-daysmart-schedule-time ( string -- timestamp )
datetime-regex findall
first
[
[ now year>> swap "month" of month-abbreviation-index ]
[ "day" of string>number ] bi <date>
]
[
[ "hour" of string>number ]
[ "minute" of string>number ]
[ "ampm" of ] tri
] bi
[ 0 set-time dup hour>> ] dip
parse-word 1quotation call( ts h -- ts' ) ;
! TODO team schedules
! dup [ "event__date" html-class? ] find-between-all [ trim-text [ { [ name>> text = ] [ text>> empty? not ] } 1&& ] filter 2 swap remove-nth " " join ] map
: parse-team-schedule-response ( vector -- schedules )
[ "event__date" html-class? ] find-between-all
[ trim-text [ { [ name>> text = ] [ text>> empty? not ] } 1&& ] filter
2 swap remove-nth [ text>> ] map " " join ] map ;
: parse-schedule-response ( vector -- schedules )
[ "list-group-item" html-class? ] find-between-all
[
remove-blank-text trim-text
[ name>> text = ] filter
[ text>> ] map
[ first R/ \s*Game$/ "" re-replace ]
[ second ] [ fourth ] tri [ normalize-team-name ] bi@ schedule boa
] { } map-as
[ home>> tbl-team-name? ] filter ;
: <daysmart-url> ( action -- url )
daysmart-base-url swap "Action" set-query-param ;
: <daysmart-team-url> ( team-id -- url )
"team/index" <daysmart-url> swap "teamid" set-query-param ;
: <daysmart-schedule-url> ( -- url )
"Schedule/location" <daysmart-url> ;
: <daysmart-schedule-form-data> ( datetime -- assoc )
[ { MM "/" DD "/" YYYY } formatted ] with-string-writer dup
'{
{ "startDate" _ }
{ "endDate" _ }
{ "facilityId" "1" } ! apex
{ "eventType" "g" } ! game types
{ "run" "true" } ! no idea
} ;
: <daysmart-schedule-request> ( datetime -- vector )
<daysmart-schedule-form-data> <daysmart-schedule-url> <post-request>
http-request nip parse-html ;
: <daysmart-request> ( url -- response )
<get-request> http-request nip parse-html ;
: <daysmart-team-request> ( team-id -- response )
<daysmart-team-url> scrape-html nip ;
: tbl-games ( -- assoc )
now [ wednesday ] [ thursday ] bi 2array dup
[ <daysmart-schedule-request> parse-schedule-response ] map
zip ;
: render-day-header ( timestamp -- xml )
[ day-of-week day-name ]
[ month>> month-name ]
[ day>> dup number>string swap ordinal-suffix append ] tri
[XML
<h1 class="day-header">
<span class="day-name"><-></span>
<span class="month"><-></span>
<span class="day"><-></span>
</h1>
XML] ;
: render-team-times ( schedule -- xml )
[ away>> [ "team " prepend ] keep ]
[ home>> [ "team " prepend ] keep ]
[ start>> ] tri
[XML
<div class="team-times">
<span class="at">@</span>
<div class="teams">
<span class=<->><-></span>
<span class=<->><-></span>
</div>
<div class="time"><-></div>
</div>
XML] ;
: render-no-games ( -- xml )
[XML
<div class="team-times"><div class="none">No Scheduled TBL games</div></div>
XML] ;
: render-day-schedule ( assoc -- xml )
[ first render-day-header ]
[ second
dup empty?
[ drop render-no-games ]
[ [ render-team-times ] map ] if
] bi
[XML
<section class="game">
<->
<->
</section>
XML] ;
: render-schedule ( -- )
tbl-games [ render-day-schedule pprint-xml ] each ;

View File

@ -0,0 +1,24 @@
IN: triangle-beer-league.entities
TUPLE: team
id color ;
TUPLE: team-schedule
start home away ;
TUPLE: schedule
start away home ;
CONSTANT: teams
{
T{ team f 25475 "maroon" }
T{ team f 25476 "white" }
T{ team f 25469 "blue" }
T{ team f 25475 "teal" }
T{ team f 25471 "green" }
T{ team f 25472 "yellow" }
T{ team f 25473 "light-blue" }
T{ team f 25470 "red" }
T{ team f 25477 "orange" }
T{ team f 25474 "black" }
}

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Alegreya+Sans+SC:wght@900"/>
<link rel="stylesheet" href="tbl.css"/>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@500&display=swap" rel="stylesheet">
<title>Triangle Beer League</title>
</head>
<body>
<header>
<a id="header-logo splash" href="index.html"></a>
<nav role="navigation">
<menu>
<li><a href="schedule.html">schedule</a></li>
<li><a href="standings.html">standings</a></li>
<li><a href="#">roster</a></li>
</menu>
</nav>
</header>

View File

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Alegreya+Sans+SC:wght@900"/>
<link rel="stylesheet" href="/tbl.css"/>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@500&display=swap" rel="stylesheet">
<title>Triangle Beer League</title>
</head>
<body>
<header>
<a id="header-logo splash" href="index.html"></a>
<nav role="navigation">
<menu>
<li><a href="/schedule">schedule</a></li>
<li><a href="#">standings</a></li>
<li><a href="#">roster</a></li>
</menu>
</nav>
</header>
<main>
<div id="triangle"></div>
</main>
<footer>
</footer>
</body>
</html>

View File

@ -0,0 +1,34 @@
<%
USING: triangle-beer-league triangle-beer-league.daysmart
sequences html.elements html.streams accessors ;
%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Alegreya+Sans+SC:wght@900"/>
<link rel="stylesheet" href="/tbl.css"/>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto+Slab:wght@500&display=swap" rel="stylesheet">
<title>Triangle Beer League</title>
</head>
<body>
<header>
<a id="header-logo" href="/"></a>
<nav role="navigation">
<menu>
<li><a href="/schedule" class="current">schedule</a></li>
<li><a href="#">standings</a></li>
<li><a href="#">roster</a></li>
</menu>
</nav>
</header>
<main class="schedule">
<% render-schedule %>
</main>
<footer>
</footer>
</body>
</html>

View File

@ -0,0 +1,209 @@
* {
margin: 0;
padding: 0; }
*, *::before, *::after {
box-sizing: border-box; }
@keyframes rotate {
100% {
transform: rotate(1turn); } }
body {
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
align-items: center;
background-color: #0f2240; }
header {
color: #f4f7f6;
font-weight: bold;
width: 100%; }
header #header-logo {
display: block;
min-width: 150px;
min-height: 150px;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
background-image: url("/cropped-TBL-Logo-2.jpg");
object-fit: cover; }
header #header-logo.splash {
display: none; }
header nav menu {
display: flex;
justify-content: center;
flex-wrap: wrap; }
header nav menu li {
list-style: none;
padding: 1em;
font-weight: 500;
font-size: 1.5em;
font-family: "Roboto Slab";
text-transform: uppercase; }
header nav menu li a {
text-decoration: none;
color: #f4f7f6;
position: relative;
padding: .25em; }
header nav menu li a.current::before {
transform: scaleX(1);
transform-origin: left; }
header nav menu li a::before {
background: #a4151a;
content: "";
inset: 0;
position: absolute;
transform: scaleX(0);
transform-origin: right;
transition: transform 0.5s ease-in-out;
z-index: -1; }
header nav menu li a:hover::before {
transform: scaleX(1);
transform-origin: left; }
main {
padding: 1em;
max-width: 1020px; }
main .splash {
height: 100%;
display: flex;
align-items: center; }
main table {
color: #f4f7f6;
border-spacing: .5em 1em;
padding: 1em;
display: block;
line-height: 1.5;
font-size: 1em; }
main table a {
color: #f4f7f6;
text-decoration: none; }
main table tr.header {
font-family: "DM Sans"; }
main table tr td {
font-family: "Inconsolata";
font-size: 1.25em; }
main table tr td.team {
font-weight: 500;
font-size: 1.25em;
font-family: "Roboto Slab";
text-align: right; }
main table tr td.team.maroon {
border-right: .25em solid maroon; }
main table tr td.team.yellow {
border-right: .25em solid yellow; }
main table tr td.team.black {
border-right: .25em solid black; }
main table tr td.team.white {
border-right: .25em solid white; }
main table tr td.team.red {
border-right: .25em solid red; }
main table tr td.team.blue {
border-right: .25em solid blue; }
main table tr td.team.light-blue {
border-right: .25em solid lightblue; }
main table tr td.team.orange {
border-right: .25em solid orange; }
main table tr td.team.teal {
border-right: .25em solid teal; }
main table tr td.team.green {
border-right: .25em solid green; }
main table.standings td {
padding: .75rem; }
main.schedule {
width: 100%;
display: flex;
justify-content: space-around;
flex-wrap: wrap; }
main.schedule .game {
padding-bottom: 1em;
min-width: 40%; }
main.schedule .game .day-header {
font-size: 1.5em;
color: #f4f7f6;
font-family: "DM Sans";
border-top: 2px solid red;
border-bottom: 2px solid red;
padding: .25em 0; }
main.schedule .game .day-header .day-name {
weight: 500; }
main.schedule .game .team-times {
padding: .5em 0;
font-size: 1.25em;
display: flex;
align-items: center; }
main.schedule .game .team-times .at {
font-family: "Roboto Slab";
font-size: .75em;
color: #f4f7f6; }
main.schedule .game .team-times .time {
color: #f4f7f6;
text-align: right;
flex: 1; }
main.schedule .game .team-times .teams {
font-family: "Roboto Slab";
text-transform: uppercase;
display: flex;
flex-direction: column; }
main.schedule .game .team-times .teams .team.maroon {
color: maroon; }
main.schedule .game .team-times .teams .team.yellow {
color: yellow; }
main.schedule .game .team-times .teams .team.black {
color: black; }
main.schedule .game .team-times .teams .team.white {
color: white; }
main.schedule .game .team-times .teams .team.red {
color: red; }
main.schedule .game .team-times .teams .team.blue {
color: blue; }
main.schedule .game .team-times .teams .team.light-blue {
color: lightblue; }
main.schedule .game .team-times .teams .team.orange {
color: orange; }
main.schedule .game .team-times .teams .team.teal {
color: teal; }
main.schedule .game .team-times .teams .team.green {
color: green; }
#triangle {
height: 50vw;
width: 50vw;
max-width: 540px;
max-height: 540px;
clip-path: polygon(100% 0, 0 0, 50% 100%);
position: relative;
z-index: 0;
overflow: hidden;
padding: 2rem; }
#triangle::before {
content: '';
position: absolute;
z-index: -2;
left: -50%;
top: -50%;
width: 200%;
height: 200%;
background-repeat: no-repeat;
background-size: 50% 50%, 50% 50%;
background-position: 0 0, 100% 0, 100% 100%, 0 100%;
background-image: linear-gradient(#eb1f26, #eb1f26), linear-gradient(#d31b22, #d31b22), linear-gradient(#bc181e, #bc181e), linear-gradient(#a4151a, #a4151a);
animation: rotate 4s linear infinite; }
#triangle::after {
background-image: url("/cropped-TBL-Logo-2.jpg");
background-color: #0f2240;
background-size: 50%;
background-repeat: no-repeat;
background-position: center 10%;
content: '';
position: absolute;
z-index: -1;
left: 12px;
top: 8px;
width: calc(100% - 24px);
height: calc(100% - 24px);
clip-path: inherit; }
/*# sourceMappingURL=tbl.css.map */

View File

@ -0,0 +1,7 @@
{
"version": 3,
"mappings": "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",
"sources": ["../../../ayerhart-design/tbl/tbl.scss"],
"names": [],
"file": "tbl.css"
}

View File

@ -0,0 +1,49 @@
USING: accessors namespaces ;
USING: io.sockets.secure io.servers ;
USING: furnace.actions furnace.boilerplate ;
USING: http.server http.server.dispatchers http.server.static ;
IN: triangle-beer-league
SYMBOLS: key-password key-file dh-file ;
TUPLE: tbl < dispatcher ;
: <splash-action> ( -- action )
<page-action>
{ tbl "tbl" } >>template ;
: <schedule-action> ( -- action )
<page-action>
{ tbl "schedule" } >>template ;
: <tbl-website> ( -- responder )
tbl new-dispatcher
! "resource:work/triangle-beer-league/schedule" <static> enable-fhtml >>default
"resource:work/triangle-beer-league" <static> enable-fhtml >>default ;
! <splash-action> "" add-responder
! <schedule-action> "schedule" add-responder
! "resource:work/triangle-beer-league" <static> >>default
! <boilerplate> { tbl "tbl-common" } >>template ;
: init-testing ( -- )
"vocab:openssl/test-1.2/dh2048.pem" dh-file set-global
"vocab:openssl/test-1.2/server.pem" key-file set-global
"password" key-password set-global
<tbl-website>
main-responder set-global ;
: <tbl-secure-config> ( -- config )
<secure-config>
key-file get >>key-file
dh-file get >>dh-file
key-password get >>password ;
: <tbl-website-server> ( -- threaded-server )
<http-server>
<tbl-secure-config> >>secure-config
8080 >>insecure
8431 >>secure ;
: start-tbl-site ( -- server )
<tbl-website-server> start-server ;