Bauke/tildes-issue-log
Bauke
/
tildes-issue-log
Archived
1
Fork 0

Compare commits

..

No commits in common. "f1edf363cc17532819e769cd674d772d74652210" and "bcaecf8cb7a31873959c15e7f281466ed4630dbc" have entirely different histories.

14 changed files with 1028 additions and 2079 deletions

View File

@ -1,129 +0,0 @@
# Development Guide
Welcome to the Tildes Issue Log development guide, this will be very concise.
## Setup
1. Clone the repository.
1. Create a `config.json` file from the sample `config.sample.json` file. The `gitlabToken` should be [a Personal Access Token](https://gitlab.com/profile/personal_access_tokens) with the `api` scope available.
## Project Overview
The Tildes Issue Log is set up with 7 scripts, 6 of which can be run on their own.
If you want to run any of these on their own, use `yarn ts-node 'source/scripts/<script>.ts'`.
These 7 are the following:
### `assets.ts`
Extracts the fonts and favicons `.tar` files located in `source/pages/assets/` and outputs them in `public/`.
### `download.ts`
Downloads all the commit, issue and merge request data with the GitLab API and saves it to `temp/data/`. If any of these already exist for today (meaning you have downloaded them previously) it won't try to redownload them and will use the existing ones instead.
### `feeds.ts`
*This is the script that can't be run on its own.*
Generates the Atom, JSON and RSS feeds from the post list that is created by `html.ts`. The feeds are output to `public/feed.{atom,json,rss}`.
### `html.ts`
Takes in all the generated data by `download.ts`, `official-topics.ts` and `statistics.ts`, and the Markdown posts in `source/pages/posts/` and generates all the HTML for the site.
The HTML is generated using Nunjucks templates, all of which can be found in `source/pages/templates/`.
The HTML generation also linkifies Tildes-style `@user` mentions and ~group mentions.
This script also writes a Markdown file to `temp/email.md` to be used for [the mailing list](https://lists.sr.ht/~bauke/tildes-issue-log). If you plan on sending the email, don't forget to change the header so instead of it being something like this:
```
<h2 id="may-2020">
May 2020
<span id="authors">by @Bauke</span>
</h2>
```
It looks something like this:
```
# Tildes Issue Log
## May 2020 by @Bauke
```
### `official-topics.ts`
Scrapes [~tildes.official](https://tildes.net/~tildes.official) and extracts all the official topics that were posted after the latest one we have saved in `source/pages/data/official-topics.json`.
### `redirects.ts`
Creates HTML files for the posts [before the 2.0.0 redesign](https://gitlab.com/Bauke/tildes-issue-log/-/commit/959c68125e8ac810d79f9a8cc8d2d7072300b320) that contain a `<meta http-equiv="refresh">` tag that redirects to the new wanted location after 5 seconds.
The old URL scheme was `https://til.bauke.xyz/posts/<month>-<year>.html`.
The current URL scheme is `https://til.bauke.xyz/<year>/<month>.html`.
An example: https://til.bauke.xyz/posts/january-2020.html
### `statistics.ts`
Generates various statistics from the downloaded data `download.ts` creates.
## Writing Posts
To start writing a new post, create the Markdown file as `source/pages/posts/<year>/<month>.md`. Every post should contain the same header similar to this one:
```
<h2 id="may-2020">
May 2020
<span id="authors">by @Bauke</span>
</h2>
```
The `@user` mentions are automatically linkified, so it's simple to add multiple authors.
After that it's all up to you. As mentioned in the `html.ts` section, `@user` mentions and ~group mentions are automatically linkified.
If you write and intend to publish a completely new post, don't forget to update the latest post link in the ReadMe.
## Building
To test and build the entire site, you can run this command:
```
yarn test && yarn download && yarn statistics && yarn official-topics && yarn build
```
This will run all the scripts in the desired sequence. It's not necessary to run it like this, once you have successfully ran `yarn download && yarn statistics && yarn official-topics` once you can run `yarn build` by itself after, but this way everything is generated and ready for the post.
`yarn build` runs all the `build:...` commands inside `package.json`. Some of these commands are do not run scripts, so if you want to build the entire site use `yarn build` to include everything.
## Testing/Linting
The JavaScript and TypeScript is linted by XO. If XO ever complains, you can usually fix it quickly with `xo --fix`. If not it will usually tell you what exactly to fix.
The SCSS is linted by Stylelint with an XO-like config.
If you only want to lint JS/TS, use `yarn xo`.
If you only want to lint SCSS, use `yarn stylelint 'source/pages/scss/**'`. Stylelint might try to lint the compiled CSS in `public/` without the specified path and blow up with errors, so don't forget to include it.
You can run both of these linters at the same time with `yarn test`.
## Committing
If you have written a new post, there's a few things you should do before you commit.
* Proofread the new post.
* Build the site, copy the entire contents of the post from the site. (`CTRL+A` and then `CTRL+C`). Then paste this into LibreOffice Writer or equivalent program and do a spellcheck. Ignore any false positives it might mark like `@user` mentions or unknown but correct words.
* Make sure there are new statistics for this month in `source/pages/data/statistics.json`. Even if they are all 0, they should be included.
* If any official topics were posted, make they are added correctly in `source/pages/data/official-topics.json`.
## Deploying
Deployment is completely and automatically handled via the GitLab CI/CD and hosted with GitLab Pages.
The CI/CD will first run `yarn test` to make sure everything is good. And then it will run `yarn build`. If successful it will save the generated `public/` directory as artifacts and upload it to be used on the live site. If either of these steps failed nothing will be uploaded.

View File

@ -1,13 +1,9 @@
# Tildes Issue Log
[Latest Post: **June 2020**](https://til.bauke.xyz/2020/june.html).
[Latest Post: **February 2020**](https://til.bauke.xyz/2020/february.html).
[Click here to view all posts](https://til.bauke.xyz/posts.html).
## Development
If you're interested in developing the site or writing a new post, see [the Development document](Development.md).
## License
Licensed under [AGPL-3.0-or-later](License).

View File

@ -5,7 +5,6 @@
"version": "2.0.0",
"license": "AGPL-3.0-or-later",
"scripts": {
"serve": "serve 'public/'",
"build": "mkdir 'public/images/' 'public/fonts/' -p && yarn build:assets && yarn build:html && yarn build:images && yarn build:js && yarn build:redirects && yarn build:sass",
"build:assets": "TZ=UTC ts-node 'source/scripts/assets.ts'",
"build:html": "TZ=UTC ts-node 'source/scripts/html.ts'",
@ -22,31 +21,30 @@
"modern-normalize": "^0.6.0"
},
"devDependencies": {
"@types/cheerio": "^0.22.18",
"@types/got": "^9.6.11",
"@types/marked": "^1.1.0",
"@types/cheerio": "^0.22.16",
"@types/got": "^9.6.9",
"@types/marked": "^0.7.2",
"@types/nunjucks": "^3.1.3",
"@types/tar": "^4.0.3",
"@types/wordwrap": "^1.0.0",
"cheerio": "^1.0.0-rc.3",
"cpy-cli": "^3.1.1",
"fecha": "^4.2.0",
"feed": "^4.2.0",
"cpy-cli": "^3.1.0",
"fecha": "^4.1.0",
"feed": "^4.1.0",
"gitlab": "^14.2.2",
"got": "^11.3.0",
"got": "^10.6.0",
"htmlclean": "^3.0.8",
"marked": "^1.1.0",
"nunjucks": "^3.2.1",
"sass": "^1.26.9",
"serve": "^11.3.2",
"stylelint": "^13.6.1",
"marked": "^0.8.0",
"nunjucks": "^3.2.0",
"sass": "^1.26.1",
"stylelint": "^13.2.0",
"stylelint-config-xo-scss": "^0.12.0",
"stylelint-config-xo-space": "^0.14.0",
"tar": "^6.0.2",
"ts-node": "^8.10.2",
"typescript": "^3.9.5",
"tar": "^6.0.1",
"ts-node": "^8.6.2",
"typescript": "^3.8.2",
"wordwrap": "^1.0.0",
"xo": "^0.32.0"
"xo": "^0.27.2"
},
"stylelint": {
"extends": [

View File

@ -405,7 +405,7 @@
"commits": 30
},
"issues": {
"closed": 8,
"closed": 9,
"opened": 9
},
"lines": {
@ -498,45 +498,5 @@
},
"month": 4,
"year": 2020
},
{
"contributions": {
"authors": 2,
"commits": 11
},
"issues": {
"closed": 4,
"opened": 13
},
"lines": {
"added": 243,
"removed": 41
},
"mergeRequests": {
"closed": 1,
"opened": 1
},
"month": 5,
"year": 2020
},
{
"contributions": {
"authors": 1,
"commits": 7
},
"issues": {
"closed": 1,
"opened": 10
},
"lines": {
"added": 197,
"removed": 283
},
"mergeRequests": {
"closed": 0,
"opened": 0
},
"month": 6,
"year": 2020
}
]

View File

@ -8,7 +8,7 @@ window.addEventListener('load', () => {
}
// When the theme button is clicked, switch the theme to the other one.
themeToggleButton.addEventListener('click', (event) => {
themeToggleButton.addEventListener('click', event => {
event.preventDefault();
if (document.body.getAttribute('id') === 'dark-theme') {

View File

@ -1,12 +0,0 @@
<h2 id="june-2020">
June 2020
<span id="authors">by @Bauke</span>
</h2>
### Another Very Short One
Just like last month, this month's also a shorter one. Nonetheless, some things still happened:
* Comments that are removed by a site admin and then deleted by the comment author will now show that it was removed. Previously it would show as deleted but the reason it was deleted is often because it was removed.
* The specialized coronavirus views that were introduced [in March](https://til.bauke.xyz/2020/march.html#covid-19) and were visible at the top of the home page have been removed.
* A [new feature was introduced](https://tildes.net/~tildes/pt7/you_cant_reply_to_this_user_yet_please_wait_29_minutes#comment-57nh) that added a hard delay when 2 people were replying to each other too quickly. It was removed a few days after the delay was being triggered more than @Deimos liked, but it will likely come back in the future in an improved form.

View File

@ -1,10 +0,0 @@
<h2 id="may-2020">
May 2020
<span id="authors">by @Bauke</span>
</h2>
### A Very Short One
* A bug with tag autocompletion has been fixed, [thanks ASZH](https://gitlab.com/tildes/tildes/-/merge_requests/104)!
* When logging in, if you enter the wrong username or password, Tildes will now specifically tell you which one was wrong.
* A bug was fixed that caused an internal server error when voting on ignored topics.

View File

@ -17,5 +17,5 @@ async function entry(): Promise<void> {
}
if (require.main === module) {
void entry();
entry();
}

View File

@ -19,10 +19,10 @@ async function setupGitLabAPI(): Promise<GitLab> {
return api;
}
async function setupTemporaryDirectory(): Promise<string> {
const temporaryDirectory: string = join(__dirname, '../../temp/');
await fsp.mkdir(temporaryDirectory + 'data/', {recursive: true});
return temporaryDirectory;
async function setupTempDirectory(): Promise<string> {
const tempDirectory: string = join(__dirname, '../../temp/');
await fsp.mkdir(tempDirectory + 'data/', {recursive: true});
return tempDirectory;
}
async function getConfig(): Promise<Config> {
@ -33,13 +33,13 @@ async function getConfig(): Promise<Config> {
}
export async function getCommits(): Promise<any[]> {
const temporaryDirectory: string = await setupTemporaryDirectory();
const tempDirectory: string = await setupTempDirectory();
const api: GitLab = await setupGitLabAPI();
const project: gitlab.ProjectSchema = await api.Projects.show(
'tildes/tildes'
);
const commitsPath: string = join(
temporaryDirectory,
tempDirectory,
`data/commits (${fecha.format(new Date(), 'YYYY-MM-DD')}).json`
);
let commits: any[];
@ -59,13 +59,13 @@ export async function getCommits(): Promise<any[]> {
}
export async function getIssues(): Promise<any[]> {
const temporaryDirectory: string = await setupTemporaryDirectory();
const tempDirectory: string = await setupTempDirectory();
const api: GitLab = await setupGitLabAPI();
const project: gitlab.ProjectSchema = await api.Projects.show(
'tildes/tildes'
);
const issuesPath: string = join(
temporaryDirectory,
tempDirectory,
`data/issues (${fecha.format(new Date(), 'YYYY-MM-DD')}).json`
);
let issues: any[];
@ -83,13 +83,13 @@ export async function getIssues(): Promise<any[]> {
}
export async function getMergeRequests(): Promise<any[]> {
const temporaryDirectory: string = await setupTemporaryDirectory();
const tempDirectory: string = await setupTempDirectory();
const api: GitLab = await setupGitLabAPI();
const project: gitlab.ProjectSchema = await api.Projects.show(
'tildes/tildes'
);
const mergeRequestsPath: string = join(
temporaryDirectory,
tempDirectory,
`data/merge requests (${fecha.format(new Date(), 'YYYY-MM-DD')}).json`
);
let mergeRequests: any[];
@ -114,5 +114,5 @@ export async function getMergeRequests(): Promise<any[]> {
}
if (require.main === module) {
void entry();
entry();
}

View File

@ -1,7 +1,7 @@
import {promises as fsp} from 'fs';
import {basename, join} from 'path';
import fecha from 'fecha';
// @ts-expect-error
// @ts-ignore
import htmlclean from 'htmlclean';
import marked from 'marked';
import nunjucks from 'nunjucks';
@ -99,7 +99,7 @@ async function entry(): Promise<void> {
// Get the statistics for that month.
const statistic: Statistics = statistics.find(
(value) => value.year === Number(year) && value.month === monthNumber
val => val.year === Number(year) && val.month === monthNumber
)!;
const topics: OfficialTopic[] = await getTopicsFromMonth(
@ -184,7 +184,7 @@ async function entry(): Promise<void> {
export async function renderTemplate(
template: string,
location: string,
context: Record<string, unknown> = {}
context: object = {}
): Promise<void> {
const html: string = htmlclean(nunjucks.render(template, context));
await fsp.writeFile(location, html);
@ -211,5 +211,5 @@ export function pluralize(
}
if (require.main === module) {
void entry();
entry();
}

View File

@ -58,8 +58,8 @@ async function entry(): Promise<void> {
// If all pagination buttons are "previous" buttons, stop the loop.
if (
paginationButtons.every((value) =>
value.firstChild.data?.toLowerCase().includes('prev')
paginationButtons.every(val =>
val.firstChild.data?.toLowerCase().includes('prev')
)
) {
hasNextButton = false;
@ -76,7 +76,7 @@ async function entry(): Promise<void> {
}
export async function wait(timeout: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, timeout));
return new Promise(resolve => setTimeout(resolve, timeout));
}
export async function getTopicsFromMonth(
@ -100,5 +100,5 @@ export async function getTopicsFromMonth(
}
if (require.main === module) {
void entry();
entry();
}

View File

@ -33,5 +33,5 @@ async function entry(): Promise<void> {
}
if (require.main === module) {
void entry();
entry();
}

View File

@ -288,7 +288,7 @@ export async function findData<T extends Result>(
}
// Find the monthly that applies to this datapoint.
const monthly: T | undefined = monthlies.find((result) =>
const monthly: T | undefined = monthlies.find(result =>
findFn(result, point)
);
@ -311,11 +311,11 @@ async function getResultCount(
month: number
): Promise<number> {
const result: MonthlyResult | undefined = results.find(
(value) => value.year === year && value.month === month
val => val.year === year && val.month === month
);
return result === undefined ? 0 : result.count;
}
if (require.main === module) {
void entry();
entry();
}

2826
yarn.lock

File diff suppressed because it is too large Load Diff