diff --git a/.idea/sqlDataSources.xml b/.idea/sqlDataSources.xml index ab5a5a0..0fd88c5 100644 --- a/.idea/sqlDataSources.xml +++ b/.idea/sqlDataSources.xml @@ -6,10 +6,11 @@ diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml index c3b0c41..996b98b 100644 --- a/.idea/sqldialects.xml +++ b/.idea/sqldialects.xml @@ -2,6 +2,7 @@ + diff --git a/data/schema.sql b/data/schema.sql index bd4f58c..45ced45 100644 --- a/data/schema.sql +++ b/data/schema.sql @@ -58,3 +58,14 @@ CREATE TABLE IF NOT EXISTS updateslog PRIMARY KEY (ID) ); + +CREATE TABLE IF NOT EXISTS projectlawful_downloadcounter +( + id int(11) NOT NULL AUTO_INCREMENT, + variant varchar(512) NOT NULL DEFAULT '0', + timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + ip varchar(128) NOT NULL, + useragent varchar(4096) NOT NULL, + + PRIMARY KEY (ID) +); diff --git a/www/data/css/styles.css b/www/data/css/styles.css index 2326daf..b3b5be8 100644 --- a/www/data/css/styles.css +++ b/www/data/css/styles.css @@ -1156,7 +1156,7 @@ html, body { background: transparent !important; } -.blogcontent_euler, .blogcontent_markdown, .blogcontent_plain { +.blogcontent_euler, .blogcontent_markdown, .blogcontent_plain, .blogcontent_aoclist, .blogcontent_html { width: 90%; } @@ -2612,5 +2612,100 @@ html, body { height: 150px; } } +.project-lawful-ebook-blogpost code { + background-color: rgba(0, 0, 0, 0.1); + border-radius: 2px; + padding-left: 2px; + padding-right: 2px; +} +.project-lawful-ebook-blogpost .variant { + display: grid; + grid-template-columns: repeat(6, auto) 1fr; + grid-template-rows: auto auto; + grid-column-gap: 1rem; +} +.project-lawful-ebook-blogpost .variant h3 { + grid-row: 1; + grid-column: 1/-1; + text-decoration: underline; +} +.project-lawful-ebook-blogpost .variant .dlbutton { + position: relative; + height: 100%; + padding: 0; + display: flex; + border: none; +} +.project-lawful-ebook-blogpost .variant .dlbutton img { + opacity: 0; + pointer-events: none; + user-select: none; +} +.project-lawful-ebook-blogpost .variant .dlbutton a { + display: grid; + grid-template-rows: 1fr auto auto; + grid-row-gap: 4px; + justify-content: center; + align-items: center; + justify-items: center; + padding: 0.5rem; + cursor: pointer; + text-decoration: none; + color: #DDDDDD; + background-color: #222222; + border-radius: 4px; + border: 1px solid black; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; +} +.project-lawful-ebook-blogpost .variant .dlbutton a:hover { + background-color: #555555; +} +.project-lawful-ebook-blogpost .variant .dlbutton a .span_dl { + font-weight: bold; + font-size: 1.33em; +} +.project-lawful-ebook-blogpost .variant .dlbutton a .span_mb { + font-size: 0.75em; +} +.project-lawful-ebook-blogpost .variant .dlbutton svg { + fill: #BBB; +} +.project-lawful-ebook-blogpost .variant img { + width: 100%; + border: 1px solid #555; +} + +.project-lawful-ebook-blogpost .variant.alt-variants { + display: flex; + flex-direction: column; + gap: 4px; +} +.project-lawful-ebook-blogpost .dlbtn_alt { + display: grid; + grid-template-columns: 24px auto 1fr auto; + grid-column-gap: 1rem; + color: #DDDDDD; + background-color: #222222; + border: 1px solid black; + border-radius: 4px; + text-decoration: none; + cursor: pointer; + padding: 6px; + align-items: center; +} +.project-lawful-ebook-blogpost .dlbtn_alt:hover { + background-color: #555555; +} +.project-lawful-ebook-blogpost .dlbtn_alt svg { + fill: #BBB; +} +.project-lawful-ebook-blogpost .dlbtn_alt .span_mb { + font-size: 0.75em; + grid-column: 4; +} /*# sourceMappingURL=styles.css.map */ diff --git a/www/data/css/styles.min.css b/www/data/css/styles.min.css index 9f02ded..7d4f036 100644 --- a/www/data/css/styles.min.css +++ b/www/data/css/styles.min.css @@ -217,7 +217,7 @@ html,body{margin:0;padding:0;height:100%} .mdtable_container{overflow-x:auto} .notable{width:unset !important;border:none !important} .notable th,.notable td,.notable tr{border:none !important;background:transparent !important} -.blogcontent_euler,.blogcontent_markdown,.blogcontent_plain{width:90%} +.blogcontent_euler,.blogcontent_markdown,.blogcontent_plain,.blogcontent_aoclist,.blogcontent_html{width:90%} #PEB_tableProblems .PEB_tablerowProblems:hover{background-color:#999} #PEB_tableProblems .PEB_TC_Value{font-family:Consolas,Monaco,"Courier New",Menlo,monospace} #PEB_tableProblems .PEB_TC_Value:not(:hover){color:transparent;-o-transition:.5s;-ms-transition:.5s;-moz-transition:.5s;-webkit-transition:.5s;transition:.5s} @@ -495,3 +495,19 @@ html,body{margin:0;padding:0;height:100%} .bce_code_out .bce_code_out_left{flex-grow:0;height:100px} .bce_code_out .bce_code_out_right{width:auto;height:150px} } +.project-lawful-ebook-blogpost code{background-color:rgba(0,0,0,0.1);border-radius:2px;padding-left:2px;padding-right:2px} +.project-lawful-ebook-blogpost .variant{display:grid;grid-template-columns:repeat(6,auto) 1fr;grid-template-rows:auto auto;grid-column-gap:1rem} +.project-lawful-ebook-blogpost .variant h3{grid-row:1;grid-column:1/-1;text-decoration:underline} +.project-lawful-ebook-blogpost .variant .dlbutton{position:relative;height:100%;padding:0;display:flex;border:0} +.project-lawful-ebook-blogpost .variant .dlbutton img{opacity:0;pointer-events:none;user-select:none} +.project-lawful-ebook-blogpost .variant .dlbutton a{display:grid;grid-template-rows:1fr auto auto;grid-row-gap:4px;justify-content:center;align-items:center;justify-items:center;padding:.5rem;cursor:pointer;text-decoration:none;color:#ddd;background-color:#222;border-radius:4px;border:1px solid black;position:absolute;left:0;right:0;top:0;bottom:0} +.project-lawful-ebook-blogpost .variant .dlbutton a:hover{background-color:#555} +.project-lawful-ebook-blogpost .variant .dlbutton a .span_dl{font-weight:bold;font-size:1.33em} +.project-lawful-ebook-blogpost .variant .dlbutton a .span_mb{font-size:.75em} +.project-lawful-ebook-blogpost .variant .dlbutton svg{fill:#BBB} +.project-lawful-ebook-blogpost .variant img{width:100%;border:1px solid #555} +.project-lawful-ebook-blogpost .variant.alt-variants{display:flex;flex-direction:column;gap:4px} +.project-lawful-ebook-blogpost .dlbtn_alt{display:grid;grid-template-columns:24px auto 1fr auto;grid-column-gap:1rem;color:#ddd;background-color:#222;border:1px solid black;border-radius:4px;text-decoration:none;cursor:pointer;padding:6px;align-items:center} +.project-lawful-ebook-blogpost .dlbtn_alt:hover{background-color:#555} +.project-lawful-ebook-blogpost .dlbtn_alt svg{fill:#BBB} +.project-lawful-ebook-blogpost .dlbtn_alt .span_mb{font-size:.75em;grid-column:4} diff --git a/www/data/css/styles.scss b/www/data/css/styles.scss index ab5aeb0..c1e7087 100644 --- a/www/data/css/styles.scss +++ b/www/data/css/styles.scss @@ -28,4 +28,6 @@ @import 'styles_bookspanel'; @import 'styles_bfjoustrunner'; -@import 'styles_befungerunner'; \ No newline at end of file +@import 'styles_befungerunner'; + +@import 'styles_projectlawfulebook.scss'; \ No newline at end of file diff --git a/www/data/css/styles_blogview.scss b/www/data/css/styles_blogview.scss index 61569fa..62e7e40 100644 --- a/www/data/css/styles_blogview.scss +++ b/www/data/css/styles_blogview.scss @@ -56,4 +56,4 @@ } } -.blogcontent_euler, .blogcontent_markdown, .blogcontent_plain { width: 90%;} +.blogcontent_euler, .blogcontent_markdown, .blogcontent_plain, .blogcontent_aoclist, .blogcontent_html { width: 90%;} diff --git a/www/data/css/styles_projectlawfulebook.scss b/www/data/css/styles_projectlawfulebook.scss new file mode 100644 index 0000000..1ee4527 --- /dev/null +++ b/www/data/css/styles_projectlawfulebook.scss @@ -0,0 +1,123 @@ +@import 'styles_config'; + +.project-lawful-ebook-blogpost +{ + code { + background-color: rgba(0, 0, 0, 0.1); + border-radius: 2px; + padding-left: 2px; + padding-right: 2px; + } + + .variant { + display: grid; + grid-template-columns: repeat(6, auto) 1fr; + grid-template-rows: auto auto; + grid-column-gap: 1rem; + } + + .variant h3 { grid-row: 1; grid-column: 1/-1; text-decoration: underline; } + + .variant .dlbutton { + position: relative; + height: 100%; + padding: 0; + display: flex; + border:none; + } + + .variant .dlbutton img { + opacity: 0; + pointer-events: none; + user-select: none; + } + + .variant .dlbutton a { + display: grid; + grid-template-rows: 1fr auto auto; + grid-row-gap: 4px; + justify-content: center; + align-items: center; + justify-items: center; + padding: 0.5rem; + cursor: pointer; + text-decoration: none; + + color: $COL_BUTTON_GENERIC_FG; + background-color: $COL_BUTTON_GENERIC_BG; + + border-radius: 4px; + + border: 1px solid black; + + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + } + + .variant .dlbutton a:hover { + background-color: $COL_BUTTON_GENERIC_HOVER; + } + + .variant .dlbutton a .span_dl { + font-weight: bold; + font-size: 1.33em; + } + + .variant .dlbutton a .span_mb { + font-size: 0.75em; + } + + .variant .dlbutton svg { + fill: #BBB; + } + + .variant img { + width: 100%; + border: 1px solid #555; + } +} + +.project-lawful-ebook-blogpost +{ + .variant.alt-variants { + display: flex; + flex-direction: column; + gap: 4px; + } + + .dlbtn_alt { + display: grid; + grid-template-columns: 24px auto 1fr auto; + grid-column-gap: 1rem; + + color: $COL_BUTTON_GENERIC_FG; + background-color: $COL_BUTTON_GENERIC_BG; + border: 1px solid black; + border-radius: 4px; + + text-decoration: none; + + cursor: pointer; + + padding: 6px; + + align-items: center; + } + + .dlbtn_alt:hover { + background-color: $COL_BUTTON_GENERIC_HOVER; + } + + .dlbtn_alt svg { + fill: #BBB; + + } + + .dlbtn_alt .span_mb { + font-size: 0.75em; + grid-column: 4; + } +} \ No newline at end of file diff --git a/www/data/images/blog/ple-scaled-avatars-01.jpeg b/www/data/images/blog/ple-scaled-avatars-01.jpeg new file mode 100644 index 0000000..2a8f85a Binary files /dev/null and b/www/data/images/blog/ple-scaled-avatars-01.jpeg differ diff --git a/www/data/images/blog/ple-scaled-avatars-02.jpeg b/www/data/images/blog/ple-scaled-avatars-02.jpeg new file mode 100644 index 0000000..a0ec312 Binary files /dev/null and b/www/data/images/blog/ple-scaled-avatars-02.jpeg differ diff --git a/www/data/images/blog/ple-scaled-avatars-03.jpeg b/www/data/images/blog/ple-scaled-avatars-03.jpeg new file mode 100644 index 0000000..c6c02b9 Binary files /dev/null and b/www/data/images/blog/ple-scaled-avatars-03.jpeg differ diff --git a/www/data/images/blog/ple-scaled-avatars-04.jpeg b/www/data/images/blog/ple-scaled-avatars-04.jpeg new file mode 100644 index 0000000..d870d76 Binary files /dev/null and b/www/data/images/blog/ple-scaled-avatars-04.jpeg differ diff --git a/www/data/images/blog/ple-scaled-avatars-05.jpeg b/www/data/images/blog/ple-scaled-avatars-05.jpeg new file mode 100644 index 0000000..b52f65b Binary files /dev/null and b/www/data/images/blog/ple-scaled-avatars-05.jpeg differ diff --git a/www/data/images/blog/ple-scaled-avatars-moreinfo-01.jpeg b/www/data/images/blog/ple-scaled-avatars-moreinfo-01.jpeg new file mode 100644 index 0000000..2a8f85a Binary files /dev/null and b/www/data/images/blog/ple-scaled-avatars-moreinfo-01.jpeg differ diff --git a/www/data/images/blog/ple-scaled-avatars-moreinfo-02.jpeg b/www/data/images/blog/ple-scaled-avatars-moreinfo-02.jpeg new file mode 100644 index 0000000..8bd4595 Binary files /dev/null and b/www/data/images/blog/ple-scaled-avatars-moreinfo-02.jpeg differ diff --git a/www/data/images/blog/ple-scaled-avatars-moreinfo-03.jpeg b/www/data/images/blog/ple-scaled-avatars-moreinfo-03.jpeg new file mode 100644 index 0000000..211e479 Binary files /dev/null and b/www/data/images/blog/ple-scaled-avatars-moreinfo-03.jpeg differ diff --git a/www/data/images/blog/ple-scaled-avatars-moreinfo-04.jpeg b/www/data/images/blog/ple-scaled-avatars-moreinfo-04.jpeg new file mode 100644 index 0000000..a45bf1a Binary files /dev/null and b/www/data/images/blog/ple-scaled-avatars-moreinfo-04.jpeg differ diff --git a/www/data/images/blog/ple-scaled-avatars-moreinfo-05.jpeg b/www/data/images/blog/ple-scaled-avatars-moreinfo-05.jpeg new file mode 100644 index 0000000..6e00710 Binary files /dev/null and b/www/data/images/blog/ple-scaled-avatars-moreinfo-05.jpeg differ diff --git a/www/data/images/blog/ple-scaled-biggerhtml-01.jpeg b/www/data/images/blog/ple-scaled-biggerhtml-01.jpeg new file mode 100644 index 0000000..2a8f85a Binary files /dev/null and b/www/data/images/blog/ple-scaled-biggerhtml-01.jpeg differ diff --git a/www/data/images/blog/ple-scaled-biggerhtml-02.jpeg b/www/data/images/blog/ple-scaled-biggerhtml-02.jpeg new file mode 100644 index 0000000..fb25312 Binary files /dev/null and b/www/data/images/blog/ple-scaled-biggerhtml-02.jpeg differ diff --git a/www/data/images/blog/ple-scaled-biggerhtml-03.jpeg b/www/data/images/blog/ple-scaled-biggerhtml-03.jpeg new file mode 100644 index 0000000..162ad98 Binary files /dev/null and b/www/data/images/blog/ple-scaled-biggerhtml-03.jpeg differ diff --git a/www/data/images/blog/ple-scaled-biggerhtml-04.jpeg b/www/data/images/blog/ple-scaled-biggerhtml-04.jpeg new file mode 100644 index 0000000..aa548a3 Binary files /dev/null and b/www/data/images/blog/ple-scaled-biggerhtml-04.jpeg differ diff --git a/www/data/images/blog/ple-scaled-biggerhtml-05.jpeg b/www/data/images/blog/ple-scaled-biggerhtml-05.jpeg new file mode 100644 index 0000000..3b9740f Binary files /dev/null and b/www/data/images/blog/ple-scaled-biggerhtml-05.jpeg differ diff --git a/www/data/images/blog/ple-scaled-inline-01.jpeg b/www/data/images/blog/ple-scaled-inline-01.jpeg new file mode 100644 index 0000000..81ada0a Binary files /dev/null and b/www/data/images/blog/ple-scaled-inline-01.jpeg differ diff --git a/www/data/images/blog/ple-scaled-inline-02.jpeg b/www/data/images/blog/ple-scaled-inline-02.jpeg new file mode 100644 index 0000000..d203b31 Binary files /dev/null and b/www/data/images/blog/ple-scaled-inline-02.jpeg differ diff --git a/www/data/images/blog/ple-scaled-inline-03.jpeg b/www/data/images/blog/ple-scaled-inline-03.jpeg new file mode 100644 index 0000000..34f7ade Binary files /dev/null and b/www/data/images/blog/ple-scaled-inline-03.jpeg differ diff --git a/www/data/images/blog/ple-scaled-inline-04.jpeg b/www/data/images/blog/ple-scaled-inline-04.jpeg new file mode 100644 index 0000000..4695232 Binary files /dev/null and b/www/data/images/blog/ple-scaled-inline-04.jpeg differ diff --git a/www/data/images/blog/ple-scaled-inline-05.jpeg b/www/data/images/blog/ple-scaled-inline-05.jpeg new file mode 100644 index 0000000..0d5073d Binary files /dev/null and b/www/data/images/blog/ple-scaled-inline-05.jpeg differ diff --git a/www/data/images/blog/ple-scaled-moreinfo-01.jpeg b/www/data/images/blog/ple-scaled-moreinfo-01.jpeg new file mode 100644 index 0000000..2a8f85a Binary files /dev/null and b/www/data/images/blog/ple-scaled-moreinfo-01.jpeg differ diff --git a/www/data/images/blog/ple-scaled-moreinfo-02.jpeg b/www/data/images/blog/ple-scaled-moreinfo-02.jpeg new file mode 100644 index 0000000..fb25312 Binary files /dev/null and b/www/data/images/blog/ple-scaled-moreinfo-02.jpeg differ diff --git a/www/data/images/blog/ple-scaled-moreinfo-03.jpeg b/www/data/images/blog/ple-scaled-moreinfo-03.jpeg new file mode 100644 index 0000000..162ad98 Binary files /dev/null and b/www/data/images/blog/ple-scaled-moreinfo-03.jpeg differ diff --git a/www/data/images/blog/ple-scaled-moreinfo-04.jpeg b/www/data/images/blog/ple-scaled-moreinfo-04.jpeg new file mode 100644 index 0000000..aa548a3 Binary files /dev/null and b/www/data/images/blog/ple-scaled-moreinfo-04.jpeg differ diff --git a/www/data/images/blog/ple-scaled-moreinfo-05.jpeg b/www/data/images/blog/ple-scaled-moreinfo-05.jpeg new file mode 100644 index 0000000..3b9740f Binary files /dev/null and b/www/data/images/blog/ple-scaled-moreinfo-05.jpeg differ diff --git a/www/data/projectlawful/.gitignore b/www/data/projectlawful/.gitignore new file mode 100644 index 0000000..181ed48 --- /dev/null +++ b/www/data/projectlawful/.gitignore @@ -0,0 +1,4 @@ +*.epub +*.mobi +*.zip +*.html \ No newline at end of file diff --git a/www/data/projectlawful/.gitkeep b/www/data/projectlawful/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/www/fragments/blogview_aoc_list.php b/www/fragments/blogview_aoc_list.php index e4d4a56..f6b80af 100644 --- a/www/fragments/blogview_aoc_list.php +++ b/www/fragments/blogview_aoc_list.php @@ -19,7 +19,7 @@ $FRAME_OPTIONS->alternative_url = "/adventofcode/$year"; ?> -
+
diff --git a/www/fragments/blogview_html.php b/www/fragments/blogview_html.php new file mode 100644 index 0000000..a52f085 --- /dev/null +++ b/www/fragments/blogview_html.php @@ -0,0 +1,35 @@ + + + + +
+ + + + + +
+ +
+ +
+ modules->Blog()->getPostFragment($post); ?> +
+ +
\ No newline at end of file diff --git a/www/index.php b/www/index.php index 585f5ca..7518d29 100644 --- a/www/index.php +++ b/www/index.php @@ -49,6 +49,8 @@ $URL_RULES = [ 'url' => ['admin'], 'target' => 'admin.php', 'options' => [ 'password' ], 'parameter' => [ ] ], + [ 'url' => ['blog','29','*','download','?{variant}'], 'target' => 'projectlawful_download.php', 'options' => [ ], 'parameter' => [ 'variant' => '%URL%' ], ], + [ 'url' => ['blog'], 'target' => 'blog_list.php', 'options' => [ ], 'parameter' => [ ], ], [ 'url' => ['log'], 'target' => 'blog_list.php', 'options' => [ ], 'parameter' => [ ], ], [ 'url' => ['blogpost', 'index'], 'target' => 'blog_list.php', 'options' => [ ], 'parameter' => [ ], ], @@ -66,7 +68,7 @@ $URL_RULES = [ 'url' => ['adventofcode', '?{year}'], 'target' => 'adventofcode_year.php', 'options' => [ ], 'parameter' => [ 'year' => '%URL%' ], ], [ 'url' => ['adventofcode', '?{year}', '?{day}'], 'target' => 'adventofcode_day.php', 'options' => [ ], 'parameter' => [ 'year' => '%URL%', 'day' => '%URL%' ], ], - [ 'url' => ['webapps'], 'target' => 'webapps_list.php', 'options' => [ ], 'parameter' => [ ], ], + [ 'url' => ['webapps'], 'target' => 'webapps_list.php', 'options' => [ ], 'parameter' => [ ], ], [ 'url' => ['highscores', 'list.php'], 'target' => 'highscores_listentries.php', 'options' => [ 'http' ], 'parameter' => [ 'gameid' => '%GET%' ], ], [ 'url' => ['highscores', 'list'], 'target' => 'highscores_listentries.php', 'options' => [ 'http' ], 'parameter' => [ 'gameid' => '%GET%' ], ], diff --git a/www/internals/fragments.php b/www/internals/fragments.php index bfda872..f8de7c4 100644 --- a/www/internals/fragments.php +++ b/www/internals/fragments.php @@ -75,6 +75,14 @@ class Fragments ]); } + public function BlogviewHTML(array $blogpost) + { + return $this->evalFragment('BlogviewHTML', 'blogview_html.php', + [ + 'blogpost' => $blogpost, + ]); + } + public function BlogviewEulerList(array $blogpost) { return $this->evalFragment('BlogviewEulerList', 'blogview_euler_list.php', diff --git a/www/internals/modules.php b/www/internals/modules.php index 38acd0e..865bbe9 100644 --- a/www/internals/modules.php +++ b/www/internals/modules.php @@ -1,5 +1,7 @@ highscores; } - public function SelfTest(): SelfTest - { - if ($this->selftest === null) { require_once 'modules/selftest.php'; $this->selftest = new SelfTest(); } - return $this->selftest; - } + public function SelfTest(): SelfTest + { + if ($this->selftest === null) { require_once 'modules/selftest.php'; $this->selftest = new SelfTest(); } + return $this->selftest; + } + + public function ProjectLawful(): ProjectLawful + { + if ($this->projectlawful === null) { require_once 'modules/projectlawful.php'; $this->projectlawful = new ProjectLawful($this->site); } + return $this->projectlawful; + } } \ No newline at end of file diff --git a/www/internals/modules/blog.php b/www/internals/modules/blog.php index a8cc759..208d0b4 100644 --- a/www/internals/modules/blog.php +++ b/www/internals/modules/blog.php @@ -118,9 +118,13 @@ class Blog implements IWebsiteModule if (!file_exists($post['file_fragment'])) return ['result'=>'err', 'message' => 'Fragment not found ' . $post['fragment']]; - } else if ($post['type'] === 'plain') { + } else if ($post['type'] === 'plain') { - if (!file_exists($post['file_fragment'])) return ['result'=>'err', 'message' => 'Fragment not found ' . $post['fragment']]; + if (!file_exists($post['file_fragment'])) return ['result'=>'err', 'message' => 'Fragment not found ' . $post['fragment']]; + + } else if ($post['type'] === 'html') { + + if (!file_exists($post['file_fragment'])) return ['result'=>'err', 'message' => 'Fragment not found ' . $post['fragment']]; } else if ($post['type'] === 'euler') { diff --git a/www/internals/modules/projectlawful.php b/www/internals/modules/projectlawful.php new file mode 100644 index 0000000..0235d24 --- /dev/null +++ b/www/internals/modules/projectlawful.php @@ -0,0 +1,76 @@ + 'project-lawful-avatars-moreinfo.epub', + 'avatars' => 'project-lawful-avatars.epub', + 'biggerhtml' => 'project-lawful-biggerhtml.epub', + 'inline' => 'project-lawful-inline.epub', + 'moreinfo' => 'project-lawful-moreinfo.epub', + 'onlymainstory-avatars-moreinfo' => 'project-lawful-onlymainstory-avatars-moreinfo.epub', + 'onlymainstory-avatars' => 'project-lawful-onlymainstory-avatars.epub', + 'onlymainstory-biggerhtml' => 'project-lawful-onlymainstory-biggerhtml.epub', + 'onlymainstory-inline' => 'project-lawful-onlymainstory-inline.epub', + 'onlymainstory-moreinfo' => 'project-lawful-onlymainstory-moreinfo.epub', + 'sfw-avatars-moreinfo' => 'project-lawful-sfw-avatars-moreinfo.epub', + 'sfw-avatars' => 'project-lawful-sfw-avatars.epub', + 'sfw-biggerhtml' => 'project-lawful-sfw-biggerhtml.epub', + 'sfw-inline' => 'project-lawful-sfw-inline.epub', + 'sfw-moreinfo' => 'project-lawful-sfw-moreinfo.epub', + ]; + + public function __construct(Website $site) + { + $this->site = $site; + } + + public function insertDownload($variant) + { + try + { + $this->site->modules->Database()->sql_query_assoc_prep('INSERT INTO projectlawful_downloadcounter (variant, ip, useragent) VALUES (:vr, :ip, :ua)', + [ + [':vr', $variant, PDO::PARAM_STR], + [':ip', get_client_ip(), PDO::PARAM_STR], + [':ua', $_SERVER['HTTP_USER_AGENT'] ?? '', PDO::PARAM_STR], + ]); + return true; + } + catch (Throwable $t) + { + return false; + } + } + + public function listDownloadCounts() + { + return $this->site->modules->Database()->sql_query_assoc('SELECT variant, COUNT(*) AS `count` FROM projectlawful_downloadcounter GROUP BY variant ORDER BY variant'); + } + + public function variantExists(string $variant) + { + return isset($this->variants[$variant]); + } + + public function checkConsistency() + { + foreach ($this->variants as $key => $val) { + $fn = __DIR__ . '/../../data/projectlawful/'.$val; + if (!file_exists($fn)) { + return ['result'=>'err', 'message' => 'File not found: ' . $fn]; + } + } + + return ['result' => 'ok', 'message' => '']; + } +} \ No newline at end of file diff --git a/www/internals/modules/selftest.php b/www/internals/modules/selftest.php index e175bdf..b141993 100644 --- a/www/internals/modules/selftest.php +++ b/www/internals/modules/selftest.php @@ -8,30 +8,31 @@ class SelfTest implements IWebsiteModule private const DISPLAY_NAMES = [ - 'web::main' => 'Website (http)', - 'web::programs' => 'Programs (http)', - 'web::programs-ext' => 'Programs (links)', - 'web::programs-dl' => 'Programs (download)', - 'web::books' => 'Books (http)', - 'web::blog' => 'Blog (http)', - 'web::webapps' => 'WebApps (http)', - 'web::euler' => 'Project Euler (http)', - 'web::aoc' => 'Advent of Code (http)', - 'api::default' => 'API', - 'api::highscore' => 'Highscores API', - 'modules::database' => 'Database', - 'modules::blog' => 'Blog (data)', - 'modules::euler' => 'Project Euler (data)', - 'modules::books' => 'Books (data)', - 'modules::extgitgraph' => 'ExtendedGitGraph (data)', - 'modules::programs' => 'Programs (data)', - 'modules::adventofcode' => 'Advent of Code (data)', - 'modules::anstatistics' => 'AlephNote Stats (data)', - 'modules::updateslog' => 'Program Updates (data)', - 'modules::webapps' => 'Webapps (data)', - 'modules::highscores' => 'Highscores (data)', - 'egg::db-check' => 'ExtendedGitGraph (db-check)', - 'backend::git' => 'Git Repository', + 'web::main' => 'Website (http)', + 'web::programs' => 'Programs (http)', + 'web::programs-ext' => 'Programs (links)', + 'web::programs-dl' => 'Programs (download)', + 'web::books' => 'Books (http)', + 'web::blog' => 'Blog (http)', + 'web::webapps' => 'WebApps (http)', + 'web::euler' => 'Project Euler (http)', + 'web::aoc' => 'Advent of Code (http)', + 'api::default' => 'API', + 'api::highscore' => 'Highscores API', + 'modules::database' => 'Database', + 'modules::blog' => 'Blog (data)', + 'modules::euler' => 'Project Euler (data)', + 'modules::books' => 'Books (data)', + 'modules::extgitgraph' => 'ExtendedGitGraph (data)', + 'modules::programs' => 'Programs (data)', + 'modules::adventofcode' => 'Advent of Code (data)', + 'modules::anstatistics' => 'AlephNote Stats (data)', + 'modules::updateslog' => 'Program Updates (data)', + 'modules::webapps' => 'Webapps (data)', + 'modules::highscores' => 'Highscores (data)', + 'modules::projectlawful' => 'ProjectLawful-ebook (files)', + 'egg::db-check' => 'ExtendedGitGraph (db-check)', + 'backend::git' => 'Git Repository', ]; private $methods = []; @@ -51,9 +52,9 @@ class SelfTest implements IWebsiteModule $this->addMethodPathStatus("web::main::about-2", 200, '/msmain/about'); $this->addMethodPathStatus("web::main::login-1", 200, '/login'); $this->addMethodPathStatus("web::main::404-1", 404, '/asdf'); - $this->addHTTPSRedirect( "web::main::redirect-1", ''); - $this->addHTTPSRedirect( "web::main::redirect-2", '/about'); - $this->addHTTPSRedirect( "web::main::redirect-3", '/about'); + $this->addHTTPSRedirect( "web::main::redirect-1", ''); + $this->addHTTPSRedirect( "web::main::redirect-2", '/about'); + $this->addHTTPSRedirect( "web::main::redirect-3", '/about'); $this->addMethodPathStatus( "web::programs::programs-list-1", 200, '/programs'); $this->addMethodPathStatus( "web::programs::programs-list-2", 200, '/programs/index'); @@ -106,18 +107,19 @@ class SelfTest implements IWebsiteModule $this->addMethodMultiPathStatus("web::aoc::aoc-redirect-1", 302, '{0}', function(){ return array_key_map(Website::inst()->modules->AdventOfCode()->listAllDays(), 'url-alternative'); }); $this->addMethodMultiPathStatus("web::aoc::aoc-redirect-1", 302, '/adventofcode/{0}', function(){ return Website::inst()->modules->AdventOfCode()->listYears(); }); - $this->addCheckConsistency("modules::database::database-check-consistency", function(){ return Website::inst()->modules->Database(); }); - $this->addCheckConsistency("modules::blog::blog-check-consistency", function(){ return Website::inst()->modules->Blog(); }); - $this->addCheckConsistency("modules::euler::euler-check-consistency", function(){ return Website::inst()->modules->Euler(); }); - $this->addCheckConsistency("modules::books::books-check-consistency", function(){ return Website::inst()->modules->Books(); }); - $this->addCheckConsistency("modules::extgitgraph::extgitgraph-check-consistency", function(){ return Website::inst()->modules->ExtendedGitGraph(); }); - $this->addCheckConsistency("modules::programs::programs-check-consistency", function(){ return Website::inst()->modules->Programs(); }); - $this->addCheckConsistency("modules::books::books-check-consistency", function(){ return Website::inst()->modules->Books(); }); - $this->addCheckConsistency("modules::adventofcode::adventofcode-check-consistency", function(){ return Website::inst()->modules->AdventOfCode(); }); - $this->addCheckConsistency("modules::anstatistics::anstatistics-check-consistency", function(){ return Website::inst()->modules->AlephNoteStatistics(); }); - $this->addCheckConsistency("modules::updateslog::updateslog-check-consistency", function(){ return Website::inst()->modules->UpdatesLog(); }); - $this->addCheckConsistency("modules::webapps::webapps-check-consistency", function(){ return Website::inst()->modules->WebApps(); }); - $this->addCheckConsistency("modules::highscores::highscores-check-consistency", function(){ return Website::inst()->modules->Highscores(); }); + $this->addCheckConsistency("modules::database::database-check-consistency", function(){ return Website::inst()->modules->Database(); }); + $this->addCheckConsistency("modules::blog::blog-check-consistency", function(){ return Website::inst()->modules->Blog(); }); + $this->addCheckConsistency("modules::euler::euler-check-consistency", function(){ return Website::inst()->modules->Euler(); }); + $this->addCheckConsistency("modules::books::books-check-consistency", function(){ return Website::inst()->modules->Books(); }); + $this->addCheckConsistency("modules::extgitgraph::extgitgraph-check-consistency", function(){ return Website::inst()->modules->ExtendedGitGraph(); }); + $this->addCheckConsistency("modules::programs::programs-check-consistency", function(){ return Website::inst()->modules->Programs(); }); + $this->addCheckConsistency("modules::books::books-check-consistency", function(){ return Website::inst()->modules->Books(); }); + $this->addCheckConsistency("modules::adventofcode::adventofcode-check-consistency", function(){ return Website::inst()->modules->AdventOfCode(); }); + $this->addCheckConsistency("modules::anstatistics::anstatistics-check-consistency", function(){ return Website::inst()->modules->AlephNoteStatistics(); }); + $this->addCheckConsistency("modules::updateslog::updateslog-check-consistency", function(){ return Website::inst()->modules->UpdatesLog(); }); + $this->addCheckConsistency("modules::webapps::webapps-check-consistency", function(){ return Website::inst()->modules->WebApps(); }); + $this->addCheckConsistency("modules::highscores::highscores-check-consistency", function(){ return Website::inst()->modules->Highscores(); }); + $this->addCheckConsistency("modules::projectlawful::projectlawful-check-consistency", function(){ return Website::inst()->modules->ProjectLawful(); }); $this->addLambdaStatus("egg::db-check::check-db-consistency", function(){ return Website::inst()->modules->ExtendedGitGraph()->checkDatabaseConsistency(); }); diff --git a/www/pages/admin.php b/www/pages/admin.php index 7e9d368..d508ffb 100644 --- a/www/pages/admin.php +++ b/www/pages/admin.php @@ -92,6 +92,18 @@ $connected = true; try { $SITE->modules->Database(); } catch (Exception $e) { $c +
+
Project Lawful ebook (download count)
+ +
+ modules->ProjectLawful()->listDownloadCounts() as $dlc): ?> +
:
+ +
+
+ + +
ExtendedGitGraph
diff --git a/www/pages/blog_view.php b/www/pages/blog_view.php index 814fafc..bd33bad 100644 --- a/www/pages/blog_view.php +++ b/www/pages/blog_view.php @@ -39,7 +39,11 @@ else { echo $SITE->fragments->BlogviewMarkdown($post); } - elseif ($post['type'] === 'euler') + elseif ($post['type'] === 'html') + { + echo $SITE->fragments->BlogviewHTML($post); + } + elseif ($post['type'] === 'euler') { if ($subview === '') echo $SITE->fragments->BlogviewEulerList($post); else echo $SITE->fragments->BlogviewEulerSingle($post, $subview); diff --git a/www/pages/programs_view.php b/www/pages/programs_view.php index b73cfa5..f5ff222 100644 --- a/www/pages/programs_view.php +++ b/www/pages/programs_view.php @@ -51,7 +51,7 @@ $FRAME_OPTIONS->activeHeader = 'programs'; { if ($xurl['alert'] === null) { - echo ''; + echo ''; echo ''; echo ''; echo ''; diff --git a/www/pages/projectlawful_download.php b/www/pages/projectlawful_download.php new file mode 100644 index 0000000..c4f23fd --- /dev/null +++ b/www/pages/projectlawful_download.php @@ -0,0 +1,18 @@ +parameter['variant']; + +if (!$SITE->modules->ProjectLawful()->variantExists($variant)) +{ + $FRAME_OPTIONS->setForced404('epub file not found'); + return; +} + +$SITE->modules->ProjectLawful()->insertDownload($variant); + +$FRAME_OPTIONS->setForcedRedirect('/data/projectlawful/project-lawful-' . $variant . '.epub'); diff --git a/www/statics/blog/__all.php b/www/statics/blog/__all.php index bff74d9..a6edcb8 100644 --- a/www/statics/blog/__all.php +++ b/www/statics/blog/__all.php @@ -2,32 +2,33 @@ return [ - [ 'id' => 5, 'date' => '2009-04-08', 'visible' => true, 'title' => 'Beginning the log', 'fragment' => 'initial.md', 'type' => 'markdown', 'cat' => 'log' ], - [ 'id' => 6, 'date' => '2009-05-01', 'visible' => false, 'title' => 'Mess with the best ...', 'fragment' => 'hack.md', 'type' => 'markdown', 'cat' => 'log' ], - [ 'id' => 4, 'date' => '2009-06-22', 'visible' => true, 'title' => 'New Layout!', 'fragment' => 'newlayout.txt', 'type' => 'plain', 'cat' => 'log' ], - [ 'id' => 10, 'date' => '2009-06-28', 'visible' => true, 'title' => '"FUN" update', 'fragment' => 'funupdate.md', 'type' => 'markdown', 'cat' => 'log' ], - [ 'id' => 11, 'date' => '2009-07-05', 'visible' => true, 'title' => 'New Download: LAN Control 2.0', 'fragment' => 'lancontrol.md', 'type' => 'markdown', 'cat' => 'log' ], - [ 'id' => 12, 'date' => '2009-09-07', 'visible' => false, 'title' => 'Airline BSOD', 'fragment' => 'bsod.md', 'type' => 'markdown', 'cat' => 'log' ], - [ 'id' => 13, 'date' => '2009-11-22', 'visible' => true, 'title' => 'Spammers gonna spam', 'fragment' => 'spammers.md', 'type' => 'markdown', 'cat' => 'log' ], - [ 'id' => 15, 'date' => '2012-04-14', 'visible' => true, 'title' => 'New Download: Infinity Tournament', 'fragment' => 'inftournament.md', 'type' => 'markdown', 'cat' => 'log' ], - [ 'id' => 16, 'date' => '2012-05-27', 'visible' => true, 'title' => 'New Download: Borderline Defense', 'fragment' => 'borderlinedef.md', 'type' => 'markdown', 'cat' => 'log' ], - [ 'id' => 17, 'date' => '2012-05-28', 'visible' => true, 'title' => 'Big clean up', 'fragment' => 'cleanup.md', 'type' => 'markdown', 'cat' => 'log' ], - [ 'id' => 18, 'date' => '2013-01-03', 'visible' => true, 'title' => 'New Download: Crystal Grid', 'fragment' => 'crystalgrid.md', 'type' => 'markdown', 'cat' => 'log' ], - [ 'id' => 2, 'date' => '2014-05-14', 'visible' => true, 'title' => 'Let\'s do Befunge-93', 'fragment' => 'befunge93.md', 'type' => 'markdown', 'cat' => 'blog' ], - [ 'id' => 14, 'date' => '2014-06-30', 'visible' => true, 'title' => 'Language changes', 'fragment' => 'language.txt', 'type' => 'plain', 'cat' => 'log' ], - [ 'id' => 1, 'date' => '2014-07-10', 'visible' => true, 'title' => 'Project Euler with Befunge', 'fragment' => '', 'type' => 'euler', 'cat' => 'blog' ], - [ 'id' => 3, 'date' => '2014-07-15', 'visible' => true, 'title' => '.Net format specifier Cheat Sheet', 'fragment' => 'net_format_spec.md', 'type' => 'markdown', 'cat' => 'blog' ], - [ 'id' => 19, 'date' => '2014-08-04', 'visible' => true, 'title' => 'I am Number Four', 'fragment' => 'v4.md', 'type' => 'markdown', 'cat' => 'log' ], - [ 'id' => 7, 'date' => '2014-09-28', 'visible' => true, 'title' => 'My BFJoust arena and battle-bot', 'fragment' => 'bfjoust.md', 'type' => 'markdown', 'cat' => 'blog' ], - [ 'id' => 8, 'date' => '2014-11-05', 'visible' => true, 'title' => 'Rapla Enhancement Script', 'fragment' => 'rapla_css.md', 'type' => 'markdown', 'cat' => 'blog' ], - [ 'id' => 20, 'date' => '2015-01-09', 'visible' => true, 'title' => 'More Befunge with Project Euler', 'fragment' => 'more_euler.md', 'type' => 'markdown', 'cat' => 'log' ], - [ 'id' => 9, 'date' => '2016-10-22', 'visible' => true, 'title' => 'A complete sudoku solver in Befunge-93', 'fragment' => 'sudoku_befunge.md', 'type' => 'markdown', 'cat' => 'blog' ], - [ 'id' => 21, 'date' => '2018-01-02', 'visible' => true, 'title' => 'A simple javascript befunge-93 runner', 'fragment' => 'js_befrunner.md', 'type' => 'markdown', 'cat' => 'blog' ], - [ 'id' => 22, 'date' => '2018-02-06', 'visible' => true, 'title' => 'Homepage iteration 5', 'fragment' => 'v5.md', 'type' => 'markdown', 'cat' => 'log' ], - [ 'id' => 23, 'date' => '2018-12-01', 'visible' => true, 'title' => 'Advent of Code 2018 - C#', 'fragment' => 'aoc2018.md', 'type' => 'aoc', 'cat' => 'blog', 'extras' => ['aoc:year' => '2018'] ], - [ 'id' => 24, 'date' => '2019-12-01', 'visible' => true, 'title' => 'Advent of Code 2019 - Typescript', 'fragment' => 'aoc2019.md', 'type' => 'aoc', 'cat' => 'blog', 'extras' => ['aoc:year' => '2019'] ], - [ 'id' => 25, 'date' => '2020-01-09', 'visible' => true, 'title' => 'Advent of Code 2017 - Python3', 'fragment' => 'aoc2017.md', 'type' => 'aoc', 'cat' => 'blog', 'extras' => ['aoc:year' => '2017'] ], - [ 'id' => 26, 'date' => '2020-12-01', 'visible' => true, 'title' => 'Advent of Code 2020 - Rust', 'fragment' => 'aoc2020.md', 'type' => 'aoc', 'cat' => 'blog', 'extras' => ['aoc:year' => '2020'] ], - [ 'id' => 27, 'date' => '2021-11-25', 'visible' => true, 'title' => 'Advent of Code 2021 - Go', 'fragment' => 'aoc2021.md', 'type' => 'aoc', 'cat' => 'blog', 'extras' => ['aoc:year' => '2021'] ], - [ 'id' => 28, 'date' => '2022-12-01', 'visible' => true, 'title' => 'Advent of Code 2022 - Nim', 'fragment' => 'aoc2022.md', 'type' => 'aoc', 'cat' => 'blog', 'extras' => ['aoc:year' => '2022'] ], + [ 'id' => 5, 'date' => '2009-04-08', 'visible' => true, 'title' => 'Beginning the log', 'fragment' => 'initial.md', 'type' => 'markdown', 'cat' => 'log' ], + [ 'id' => 6, 'date' => '2009-05-01', 'visible' => false, 'title' => 'Mess with the best ...', 'fragment' => 'hack.md', 'type' => 'markdown', 'cat' => 'log' ], + [ 'id' => 4, 'date' => '2009-06-22', 'visible' => true, 'title' => 'New Layout!', 'fragment' => 'newlayout.txt', 'type' => 'plain', 'cat' => 'log' ], + [ 'id' => 10, 'date' => '2009-06-28', 'visible' => true, 'title' => '"FUN" update', 'fragment' => 'funupdate.md', 'type' => 'markdown', 'cat' => 'log' ], + [ 'id' => 11, 'date' => '2009-07-05', 'visible' => true, 'title' => 'New Download: LAN Control 2.0', 'fragment' => 'lancontrol.md', 'type' => 'markdown', 'cat' => 'log' ], + [ 'id' => 12, 'date' => '2009-09-07', 'visible' => false, 'title' => 'Airline BSOD', 'fragment' => 'bsod.md', 'type' => 'markdown', 'cat' => 'log' ], + [ 'id' => 13, 'date' => '2009-11-22', 'visible' => true, 'title' => 'Spammers gonna spam', 'fragment' => 'spammers.md', 'type' => 'markdown', 'cat' => 'log' ], + [ 'id' => 15, 'date' => '2012-04-14', 'visible' => true, 'title' => 'New Download: Infinity Tournament', 'fragment' => 'inftournament.md', 'type' => 'markdown', 'cat' => 'log' ], + [ 'id' => 16, 'date' => '2012-05-27', 'visible' => true, 'title' => 'New Download: Borderline Defense', 'fragment' => 'borderlinedef.md', 'type' => 'markdown', 'cat' => 'log' ], + [ 'id' => 17, 'date' => '2012-05-28', 'visible' => true, 'title' => 'Big clean up', 'fragment' => 'cleanup.md', 'type' => 'markdown', 'cat' => 'log' ], + [ 'id' => 18, 'date' => '2013-01-03', 'visible' => true, 'title' => 'New Download: Crystal Grid', 'fragment' => 'crystalgrid.md', 'type' => 'markdown', 'cat' => 'log' ], + [ 'id' => 2, 'date' => '2014-05-14', 'visible' => true, 'title' => 'Let\'s do Befunge-93', 'fragment' => 'befunge93.md', 'type' => 'markdown', 'cat' => 'blog' ], + [ 'id' => 14, 'date' => '2014-06-30', 'visible' => true, 'title' => 'Language changes', 'fragment' => 'language.txt', 'type' => 'plain', 'cat' => 'log' ], + [ 'id' => 1, 'date' => '2014-07-10', 'visible' => true, 'title' => 'Project Euler with Befunge', 'fragment' => '', 'type' => 'euler', 'cat' => 'blog' ], + [ 'id' => 3, 'date' => '2014-07-15', 'visible' => true, 'title' => '.Net format specifier Cheat Sheet', 'fragment' => 'net_format_spec.md', 'type' => 'markdown', 'cat' => 'blog' ], + [ 'id' => 19, 'date' => '2014-08-04', 'visible' => true, 'title' => 'I am Number Four', 'fragment' => 'v4.md', 'type' => 'markdown', 'cat' => 'log' ], + [ 'id' => 7, 'date' => '2014-09-28', 'visible' => true, 'title' => 'My BFJoust arena and battle-bot', 'fragment' => 'bfjoust.md', 'type' => 'markdown', 'cat' => 'blog' ], + [ 'id' => 8, 'date' => '2014-11-05', 'visible' => true, 'title' => 'Rapla Enhancement Script', 'fragment' => 'rapla_css.md', 'type' => 'markdown', 'cat' => 'blog' ], + [ 'id' => 20, 'date' => '2015-01-09', 'visible' => true, 'title' => 'More Befunge with Project Euler', 'fragment' => 'more_euler.md', 'type' => 'markdown', 'cat' => 'log' ], + [ 'id' => 9, 'date' => '2016-10-22', 'visible' => true, 'title' => 'A complete sudoku solver in Befunge-93', 'fragment' => 'sudoku_befunge.md', 'type' => 'markdown', 'cat' => 'blog' ], + [ 'id' => 21, 'date' => '2018-01-02', 'visible' => true, 'title' => 'A simple javascript befunge-93 runner', 'fragment' => 'js_befrunner.md', 'type' => 'markdown', 'cat' => 'blog' ], + [ 'id' => 22, 'date' => '2018-02-06', 'visible' => true, 'title' => 'Homepage iteration 5', 'fragment' => 'v5.md', 'type' => 'markdown', 'cat' => 'log' ], + [ 'id' => 23, 'date' => '2018-12-01', 'visible' => true, 'title' => 'Advent of Code 2018 - C#', 'fragment' => 'aoc2018.md', 'type' => 'aoc', 'cat' => 'blog', 'extras' => ['aoc:year' => '2018'] ], + [ 'id' => 24, 'date' => '2019-12-01', 'visible' => true, 'title' => 'Advent of Code 2019 - Typescript', 'fragment' => 'aoc2019.md', 'type' => 'aoc', 'cat' => 'blog', 'extras' => ['aoc:year' => '2019'] ], + [ 'id' => 25, 'date' => '2020-01-09', 'visible' => true, 'title' => 'Advent of Code 2017 - Python3', 'fragment' => 'aoc2017.md', 'type' => 'aoc', 'cat' => 'blog', 'extras' => ['aoc:year' => '2017'] ], + [ 'id' => 26, 'date' => '2020-12-01', 'visible' => true, 'title' => 'Advent of Code 2020 - Rust', 'fragment' => 'aoc2020.md', 'type' => 'aoc', 'cat' => 'blog', 'extras' => ['aoc:year' => '2020'] ], + [ 'id' => 27, 'date' => '2021-11-25', 'visible' => true, 'title' => 'Advent of Code 2021 - Go', 'fragment' => 'aoc2021.md', 'type' => 'aoc', 'cat' => 'blog', 'extras' => ['aoc:year' => '2021'] ], + [ 'id' => 28, 'date' => '2022-12-01', 'visible' => true, 'title' => 'Advent of Code 2022 - Nim', 'fragment' => 'aoc2022.md', 'type' => 'aoc', 'cat' => 'blog', 'extras' => ['aoc:year' => '2022'] ], + [ 'id' => 29, 'date' => '2023-09-11', 'visible' => true, 'title' => 'Project Lawful ebook', 'fragment' => 'proj_lawful_ebook.html', 'type' => 'html', 'cat' => 'blog', 'extras' => ['gh_link' => 'https://github.com/Mikescher/ProjectLawfulEbook'] ], ]; \ No newline at end of file diff --git a/www/statics/blog/proj_lawful_ebook.html b/www/statics/blog/proj_lawful_ebook.html new file mode 100644 index 0000000..92c3baa --- /dev/null +++ b/www/statics/blog/proj_lawful_ebook.html @@ -0,0 +1,181 @@ + +
+ + This is my attempt at creating an ebook version of the project lawful story/glowfic. + +
    +
  • I used the cache file of glowpub as a basis, because I didn't want to write my own scraper (thanks to github.com/QuartzLibrary)
  • +
  • Then I hacked together a bit of C# code to generate epub files
  • +
  • All external images (and optionally avatars) are included in the epub
  • +
  • I went through all the avatar files and made them square images (simplified my css, and looked better - most were already squares or almost-squares)
  • +
  • Various properties of the final file/layout can be changed, I generated the variants I found useful, but if anyone wants something special it should be enough to close the repo, edit Program.cs and run make
  • +
+ +

# Variants

+ + I recommend either the project-lawful-inline.epub or the project-lawful-avatars.epub variants + (the *-avatars version contains the post profile-pictures, but is bigger and takes longer to open on older devices). + + There are 3 different versions of the actual **content** of the files: +
    +
  • the normal one includes all threads from projectlawful.com, including sandboxes and lectures. If there is a SFW version of a thread, it is not included (the inline/nsfw is included instead)
  • +
  • the *-sfw-* versions have the NSFW threads replaced wih their SFW counterparts
    (replaces threads 5310 with 5403, 5610 with 5618, 5638 with 5671)
  • +
  • the *-onlymainstory-* versions do not include the sandbox threads or the (optional) lecture threads
    (removes threads 5775, 5778, 5785, 5826, 5864, 5880, 6029, 6124)
  • +
+ + There are also 5 different layout options (that I code-built) for every version above: +
    +
  • the *-inline variant only includes the character-name of each post, and (if possible) the character-name is set inline with the first paragraph
  • +
  • the *-moreinfo variant also includes the alignment text of each post/character after the character-name.
  • +
  • the *-avatars variant show the character avatar beside each post. This forces us to include all 600-ish avatars in the epub file, which increases filesize and loading time
  • +
  • the *-avatars-moreinfo also includes the alignment text (additionally to the avatar). Here the avatar/character-name/alignment-text are also no longer inlined, but get their own paragraph at the start of every post.
  • +
  • the *-biggerhtml variant looks the same as *-inline, but internally every chapter is a single big file (instead of multiple split files), this makes the initial loading of the epub slower, but codevents a forced page-break after every 128th post.
  • +
+ + As said above, it should be possible to create epub's with other combination of options (see Program.cs and Options.cs) + +

# Tested on

+ +
    +
  • Kindle Paperwhite /w KOReader
  • +
  • Foliate
  • +
  • epub.js
  • +
  • Calibre Ebook viewer
  • +
+ +

# Download

+ +
+

project-lawful-inline.epub

+ + page preview + page preview + page preview + page preview + page preview +
+ +
+

project-lawful-avatars.epub

+ + page preview + page preview + page preview + page preview + page preview +
+ +
+

project-lawful-avatars-moreinfo.epub

+ + page preview + page preview + page preview + page preview + page preview +
+ +
+

project-lawful-moreinfo.epub

+ + page preview + page preview + page preview + page preview + page preview +
+ +
+

project-lawful-biggerhtml.epub

+ + page preview + page preview + page preview + page preview + page preview +
+ + + + + +
\ No newline at end of file