93 Commits

Author SHA1 Message Date
c6b4f01102 build(version): bump version 1.0.0rc0 → 1.0.0rc1 2022-01-29 06:36:04 +00:00
Jon
9592dc58b1 Merge branch 'test-internal-hyperlink' into 'development'
test(unit_test): internal hyperlink validation

See merge request nofusscomputing/infrastructure/website!5
2022-01-29 06:31:07 +00:00
Jon
a6bcfa6b3f refactor: update article requirements
MR !5
2022-01-29 06:24:55 +00:00
ce3a2c2e1e feat(merge_requests): added article MR template
MR !5
2022-01-29 15:15:01 +09:30
c9f9d0b504 build(gitlab_release): add cz config file for verion bumping.
MR !5
2022-01-29 15:02:02 +09:30
cc7a411613 feat(vscode)!: fix junit path to use workspace folder
MR !5
2022-01-29 15:00:19 +09:30
2e534c5dd0 refactor(article): include meta.description
MR !5
2022-01-29 14:26:29 +09:30
286caa1696 feat(blog_list): layout not to include post content
removed the page.content from the list as the tags are included with
the wrong relative path to the tags page.

Now the meta.description will be shown in lieu of half the page.content.

MR !5
2022-01-29 14:19:43 +09:30
08bdf09d30 feat(blog_post): remove meta.description from page
the meta.description is not required on the article.

MR !5
2022-01-29 14:16:31 +09:30
88b80c412d test: build URLs dont require the build path in the name
MR !5
2022-01-29 14:04:41 +09:30
3dd7b452a4 test(test_hyperlink_internal_alive_check): added test
This test checks all internal (to the site) links to ensure they
are valid and the page exists.

MR !5
2022-01-29 13:21:45 +09:30
7bd7abd0e4 feat(theme): removed post content from 'blog_list'
This had to be removed as the tag plugin builds a relative link
to the tags.html page. the blog list is generated by copying
the page content of the article. due to this the tag hyperlinks
were wrong. so disabled.

MR !5
2022-01-29 13:16:38 +09:30
ddc871acca fix(mkdocs-plugin-tags): ensure trailing '/' added to tag hyperlink
since the tag file is in path '/tags/index.html' a '/' is
required to be appended to the path.

MR !5
2022-01-29 13:13:56 +09:30
Jon
217f159c5c ci: amend to last commit
MR !4
2022-01-29 08:43:27 +09:30
Jon
88af5fedab ci(integration_test): disable job until developed
MR !4
2022-01-29 08:43:27 +09:30
Jon
ec46764d72 ci(unit_test): copy report to right location
MR !4
2022-01-29 08:43:27 +09:30
Jon
c6f44892e7 ci(pytest): fix to collect junit report
MR !4
2022-01-29 08:43:27 +09:30
fee71df75e test: named test to refelect its function.
MR !4
2022-01-29 08:43:27 +09:30
006a36ac0c feat(sitemap): git_revision_date for page change
Now the last mode data is set by the 'git_revision_date_localized' plugin.
adjusted the change freq to be weekly

MR !4
2022-01-29 08:43:27 +09:30
b4fdcb6183 fix(vscode): use correct params for tests
MR !4
2022-01-29 08:43:27 +09:30
247f85c319 feat(vscode): added pytest settings
MR !4
2022-01-29 08:43:27 +09:30
40a92b975f feat(vscode): added build task
MR !4
2022-01-29 08:43:27 +09:30
3fb954faac build(requirements): added wheel for module build
required for the custom plugin module

MR !4
2022-01-29 08:43:27 +09:30
a73362abe7 ci: command only required for unit test
MR !4
2022-01-29 08:43:27 +09:30
c3f1ccc8dd ci: ensure placeholder test runs and passes
MR !4
2022-01-29 08:43:27 +09:30
8b041133dc ci(static_pages): dont run build if MD lint fails
The Static pages job requires valid markdown for it to function
correctly.  Do not start the job if linting fails.

MR !4
2022-01-29 08:43:27 +09:30
13b829d0b5 ci(tests): rijigged the job order
pages to deploy to gitlab pages so it can be used in tests.

added a pytest template for all tests that will use pytest.

added a placeholder job for integration testing.

MR !4
2022-01-29 08:43:27 +09:30
c50e9a0a6e ci(stages): deploy job to occur after build
Moved so that gitlab pages deployment could be used in the tests.

MR !4
2022-01-29 08:43:27 +09:30
15cf04ff32 test(ssl_hyperlinks_only): Test added
Added a test to ensure that all hyperlinks are to 'https' sites only.

MR !4
2022-01-29 08:43:27 +09:30
c4dd5b4a24 ci(unit_test): include requests in test pipfile
this module is required for test 'test_hyperlink_alive_check'

MR !4 fixes #7
2022-01-29 08:43:27 +09:30
f811a7acef ci(unit_test): capture stdout in JUnit Report
for debugging purposes, the test data for each test will output the
parameters to stdout for inclusion in the JUnit report

MR !4
2022-01-29 08:43:27 +09:30
3dcca53b09 test(dead_link_check): test for dead hyperlinks
This test fetches all hyperlinks and ensures they are valid and alive.

MR !4
2022-01-29 08:43:27 +09:30
3a2968b56a test(privacy): print the test data to stdout
This will enable visibility within the test report.

MR !4
2022-01-29 08:43:27 +09:30
cfe5de7ed7 test(privacy): clear the class data
MR !4
2022-01-29 08:43:27 +09:30
e1d3a33418 test(unit_test_data): web driver to be class obj
Set back to be a class object so that if an exception occurs  the object
can still be removed and cleared.

MR !4
2022-01-29 08:43:27 +09:30
f77363beea test(unit_test_data): include the url in url dict
MR !4
2022-01-29 08:43:27 +09:30
e094f84b15 test(unit_test_data): chrome driver should not be a class object.
removed the chrome driver from bing a class object as it'st only
required for collecting the data.

MR !4
2022-01-29 08:43:27 +09:30
7c9c3fcbf0 test(data): add fetching of all hyperlinks
This logic fetches all of the hyperlinks on every page and presents it
as a dictionary for testing.

MR !4
2022-01-29 08:43:27 +09:30
45cb623758 test(data): created a function to parse url to dict
This function creates a dict of the components of a url.

MR !4
2022-01-29 08:43:27 +09:30
Jon
8292b0a6cf feat(minify): disable minifying website until site ready to deploy
may need to move the minify to a task in the pages deploy job. this would allow the tests to show line numbers.

MR !2
2022-01-29 08:43:27 +09:30
Jon
17f97f85bf chore(typo): fix minify plugin.
MR !2
2022-01-29 08:43:27 +09:30
Jon
f73011d29d refactor(mkdocs.yml): fix tabbing of plugin
MR !2
2022-01-29 08:43:27 +09:30
Jon
e4999a4462 feat(minify): minify the mkdocs static html build files
MR !2
2022-01-29 08:43:27 +09:30
Jon
0e65f0465b feat(mkdocs): minify plugin added to pipfile for usage with build
MR !2
2022-01-29 08:43:27 +09:30
94ced08565 refactor(privacy_test): rename test 'test_page_external_requests' -> 'test_page_load_external_requests'
MR !2
2022-01-29 08:43:27 +09:30
65726fda02 ci(unit_test): ensure only unit test jobs run for the 'unit test' job.
previous was to run all tests. no filtered to 'test/unit'

MR !2
2022-01-29 08:43:27 +09:30
0c7c36d7e1 feat(emoji): removed emoji support until a solution can be found to self-host.
the emoji index collects from an external provider.

This feature will be disabled until a solution is provided to self-host.

MR !2
2022-01-29 08:43:27 +09:30
7e99d55bda ci(pytest): Added pytest job to run tests against build.
This CI job runs all tests in the tests/ directory.

MR !2
2022-01-29 08:43:27 +09:30
0d51c8d10b test(privacy): Created a test to check external requests during page load
This test checks if the external request is within the apporved list.
This test will prevent the adding of external urls within the page load.

MR !2
2022-01-29 08:43:27 +09:30
d67a264ef0 refactor(syntax): updated tags and added title metadata
MR !2
2022-01-29 08:43:27 +09:30
452fbe1225 feat(blog_post): change location of updated date to be in the social metadata.
Requires the git_revision_date_localized plugin for it to function.

MR !2
2022-01-29 08:43:27 +09:30
a9237c5950 fix(blog_metadata): set the date to be in a format that is normal
MR !2
2022-01-29 08:43:27 +09:30
98d0acf0ac refactor(choose_internet_service): removed extra tags and moved archive notice to bottom of page
MR !2
2022-01-29 08:43:27 +09:30
85c5d475bb build(pages): Updated the path for the mkdocs gitlab-ci job
MR !2
2022-01-29 08:43:27 +09:30
78c8db9466 build(gitlab-ci): upated to v0.6.1rc0 due to bug in mkdocs not working
Previous HEAD position was 46cc1fb build(version): bump version 0.5.0 → 0.6.0
HEAD is now at ce1cc01 build(version): bump version 0.6.0 → 0.6.1rc0

MR !2
2022-01-29 08:43:27 +09:30
34ff1e34df ci(gitlab-ci): use gitlab-ci markdown linting job
MR !2
2022-01-29 08:43:27 +09:30
b79196335d ci(mkdocs): use gitlab-ci mkdocs job
MR !2
2022-01-29 08:43:27 +09:30
95f20fee73 ci(gitlab-ci): updated to v0.6.0
Previous HEAD position was 1ef6c41 build(version): bump version 0.4.0 → 0.5.0
HEAD is now at 46cc1fb build(version): bump version 0.5.0 → 0.6.0

MR !2
2022-01-29 08:43:27 +09:30
0e09b249dc feat(gitlab): added a default issue templete for reporting issues with the website.
MR !2 task from #5
2022-01-29 08:43:27 +09:30
5d75c663a1 feat(blog_list): change articles page to be a preview list of articles.
MR !2
2022-01-29 08:43:27 +09:30
Jon
61f3331db0 feat(blog_post): include git revision date plugin
MR !1
2022-01-29 08:43:27 +09:30
9b6b3eb291 build: use the blogging capabilities added
MR !1 #3
2022-01-29 08:43:27 +09:30
9d9f9c73c8 feat(blog): added blog capability to posts
Github source:
  url:      https://github.com/4kelly/material-mkdocs-blog
  commit:   a34df0d7c70fd9b327de4b3b8f0ffcd213aa6afa
  branches: (HEAD -> main, origin/main, origin/HEAD)

issue #3 MR !1
2022-01-29 08:43:27 +09:30
54b75f38b4 fix(mkdocs-plugin-tags): fix markdown generation so it passes linting
MR !1
2022-01-29 08:43:27 +09:30
d6524ac9cf feat(markdownlint): specifiy the allowed inline html elements
MR !1
2022-01-29 08:43:27 +09:30
72ed1cb440 refactor: change hover for content tags to yellow text.
MR !1
2022-01-29 08:43:27 +09:30
93ceceb396 refactor(navigation): rename tags -> 'Content Tags'
MR !1
2022-01-29 08:43:27 +09:30
10a81f0bed fix(mkdocs-plugin-tags): ensure heading reference in a url is in lower case.
issue #3 !1
2022-01-29 08:43:27 +09:30
f2969de739 refactor(markdown_lint): correct linting errors
MR !1
2022-01-29 08:43:27 +09:30
1a1b77769d feat(mkdocs): use custom plugin from custom-plugins/mkdocs-plugin-tags
this is a custom theme modified so it works correctly

issue #3 !1
2022-01-29 08:43:27 +09:30
5dfeeb81b1 refactor(mkdocs-plugin-tags): rebranded plugin to be from nfc
changed so that it could be deliniated as custom

MR !1 #3
2022-01-29 08:43:27 +09:30
653c535b2c fix(mkdocs-plugin-tags): the template not using the specified css class for the tag
the template was hardcoded to the tag class. this prevented the end user
from specifying the css_name in mkdcos.yml

 Changes to be committed:
    modified:   custom-plugins/mkdocs-plugin-tags/tags/plugin.py
    modified:   custom-plugins/mkdocs-plugin-tags/tags/templates/tags.md.template

issue #3 MR !1
2022-01-29 08:43:27 +09:30
7267f8f2ad fix(mkdocs-plugin-tags): Build a relative link for the url to the tag page
The url was hardcoded to the root dir which prevented docs ran in a
sub-folder from having a tags.html url that was correct.

Changes to be committed:
       modified:   custom-plugins/mkdocs-plugin-tags/tags/plugin.py

issue #3 MR !
2022-01-29 08:43:27 +09:30
f77b36a138 feat(plugin): cloned plugin tags repo so it can be customized and used
cloned from: https://github.com/ginsburgnm/mkdocs-plugin-tags.git

module version 1.0.2 from pypi

git details:
    commit: fb2be9ac09889c9baf88358a216a13ed8b4a04a2
    branch details: (grafted, HEAD -> master, tag: 1.0.2, origin/master, origin/HEAD)

issue #3
2022-01-29 08:43:27 +09:30
Jon
2a16ca065c refactor: md linting error, ul must be indent four spaces
MR !1
2022-01-29 08:43:27 +09:30
Jon
b0c91fa68b ci(markdown_lint): set unordered list indentation to four.
MR !1
2022-01-29 08:43:27 +09:30
449ec4a9fc refactor: linting error. removed trailing empty line in choosing an internet service.
MR !1
2022-01-29 08:43:27 +09:30
c2d3a178a5 refactor(article): fixing lists in choosing an internet service
MR !1
2022-01-29 08:43:27 +09:30
830371c691 feat(mkdocs): add lists and task lists to markdown
MR !1
2022-01-29 08:43:27 +09:30
3a08f14d74 refactor(markdown_lint): clean up linting errors.
MR !1
2022-01-29 08:43:27 +09:30
893d3dfd5c ci(markdown_lint): disable line length for markdown files
MR !1
2022-01-29 08:43:27 +09:30
59c2593c68 feat(sitemap): remove sitemap as the changed dates for files is wrong.
needs to be investigated why the dates for file changes are wrong.

issue #3 !1
2022-01-29 08:43:27 +09:30
c6de8bc960 feat(operations): Added markdown syntax page.
Page Changes:
	new file:      pages/operations/syntax.md
	modified:      pages/robots.txt
        old wiki page: wiki/syntax.txt

Also added a robots.txt redirect to new location

issue #3 !1
2022-01-29 08:43:27 +09:30
6667f4f076 feat(article): migrated choosing an internet service from old wiki
Pages:
	new file:   pages/articles/2015/choose_internet_service.md
	modified:   pages/articles/index.md
	modified:   pages/robots.txt
	deleted:    wiki/current/info/150225_choose_internet_service.txt

Also added a redirect to the robots.txt file

issue #3 !1
2022-01-29 08:43:27 +09:30
268e076e9a feat(contact): updated the page content to include how to fix an issue with a page.
issue #3 !1
2022-01-29 08:43:27 +09:30
47bfd4e5cc feat(markdown): added ability to colour by brand name.
Brands supported
    - docker
    - facebook
    - github
    - gitlab

example for icon: ':fontawesome-brands-docker:{ .docker }'

issue #3 !1
2022-01-29 08:43:27 +09:30
f6d6bd627b feat(markdown): Support admonations in markdown.
issue #3 !1
2022-01-29 08:43:27 +09:30
c0aa5cbe12 feat(footer): Add colour to the social icons within the page footer
issue #3 !1
2022-01-29 08:43:27 +09:30
2460b4c70c feat(mkdocs): add document creation and last edited date.
Git clone depth must be the complete repo as the pip module
requires access to the full hostory to obtain the dates for the documents.

issue #3 !1
2022-01-29 08:43:27 +09:30
dde0939e1b build(mkdocs): changed the site theme to material and setup.
issue #3 !1
2022-01-29 08:43:27 +09:30
a02d2c3bb5 ci(pages): ensure the static site artifacts are available for gitlab pages
issue #3 !1
2022-01-29 08:43:27 +09:30
696138c317 ci(build): Added config to build and publish to gitlab pages
issue #3 !1
2022-01-29 08:43:27 +09:30
8fbb9d95ac feat(mkdocs): Add the default config and the site layout directory
issue #3 !1
2022-01-29 08:43:27 +09:30
53 changed files with 2312 additions and 156 deletions

7
.cz.yaml Normal file
View File

@ -0,0 +1,7 @@
commitizen:
bump_message: "build(version): bump version $current_version \u2192 $new_version"
changelog_incremental: false
name: cz_conventional_commits
tag_format: v$major.$minor.$patch$prerelease
update_changelog_on_bump: true
version: 1.0.0rc1

13
.gitignore vendored Normal file
View File

@ -0,0 +1,13 @@
# Ignore build Directory
build/
aux/
# ignore dev env
dev_env
__pycache__
# ignore junit
*.junit.xml
# ignore log files
*.log

View File

@ -1,9 +1,11 @@
stages:
- validation
- build
- deploy
- test
- release
- publish
variables:
GIT_SUBMODULE_STRATEGY: recursive
MY_PROJECT_ID: "13001358"
@ -11,56 +13,87 @@ variables:
include:
- project: nofusscomputing/projects/gitlab-ci
ref: 1ef6c41818c40183f8019ea5cde48b4278e4d694
ref: ce1cc017e26ff7f6cee586cc7d98e4d292275672
file:
- conventional_commits/.gitlab-ci.yml
- mkdocs/.gitlab-ci.yml
- validation/.gitlab-ci.yml
- gitlab_release/.gitlab-ci.yml
markdown lint:
image: node:alpine3.14
stage: validation
before_script:
- npm install markdownlint-cli2 --global
- npm install markdownlint-cli2-formatter-junit --global
- mkdir -p "$CI_PROJECT_DIR/artifacts/$CI_JOB_STAGE/$CI_JOB_NAME"
- mkdir -p "$CI_PROJECT_DIR/artifacts/$CI_JOB_STAGE/tests"
Lint Markdown:
extends: .Lint_Markdown
Static Pages:
extends: .MKDocs_Build
needs: [ 'Lint Markdown' ]
pages:
stage: deploy
variables:
GIT_STRATEGY: none
script:
- markdownlint-cli2 "**/*.md" "!gitlab-ci" 1>&1 || EXITCODE=$?
- echo DEBUG EXITCODE[$EXITCODE]
- mv markdown.junit.xml $CI_PROJECT_DIR/artifacts/$CI_JOB_STAGE/tests/markdown.junit.xml
- mv "$CI_PROJECT_DIR/artifacts/build/Static Pages/build" public
needs: [ 'Static Pages' ]
environment:
name: staging
url: $CI_PAGES_URL
artifacts:
expire_in: 3 days
when: always
paths:
- "$CI_PROJECT_DIR/artifacts/*"
reports:
junit:
- "$CI_PROJECT_DIR/artifacts/$CI_JOB_STAGE/tests/*.junit.xml"
- public
rules:
- if: '$CI_COMMIT_BRANCH == "master"'
when: never
- if: '$CI_COMMIT_BRANCH'
exists:
- "**.md"
- if: '$CI_COMMIT_BRANCH && $CI_COMMIT_BRANCH != "master"'
when: always
- when: never
.Pytest_template:
stage: test
image: ubuntu:18.04
before_script:
- mkdir -p "$CI_PROJECT_DIR/artifacts/$CI_JOB_STAGE/$CI_JOB_NAME"
- mkdir -p "$CI_PROJECT_DIR/artifacts/$CI_JOB_STAGE/tests"
- apt update
- apt install -y python3 python3-pip ca-certificates
- apt install --no-install-recommends -y chromium-chromedriver
- pip3 install --upgrade pip
- pip3 install -r test/requirements.txt
artifacts:
expire_in: 24 hrs
when: always
paths:
- "$CI_PROJECT_DIR/artifacts/$CI_JOB_STAGE/$CI_JOB_NAME/*"
reports:
junit:
- "*.junit.xml"
rules:
- if: '$CI_COMMIT_BRANCH'
when: always
- when: never
Unit Tests:
extends: .Pytest_template
needs: [ 'Static Pages' ]
script:
- mv "$CI_PROJECT_DIR/artifacts/build/Static Pages/build" build
- pytest --verbose --junitxml=unit_test.junit.xml --tb=line test/unit
- cp *.junit.xml "$CI_PROJECT_DIR/artifacts/$CI_JOB_STAGE/$CI_JOB_NAME/"
- echo "[DEBUG] python_exit[$python_exit]"
#Integration Tests:
# extends: .Pytest_template
# needs:
# - pages
# - 'Unit Tests'
# script:
# - echo "placeholder job for integration tests" > "$CI_PROJECT_DIR/artifacts/$CI_JOB_STAGE/$CI_JOB_NAME/DETEMEME.txt"
Gitlab Release:
extends:
- .gitlab_release
pages:
stage: publish
script:
- echo publish page
artifacts:
paths:
- public
only:
- master

View File

@ -0,0 +1,5 @@
What is the Page URL? <!-- Place the url after this text -->
### :books: Summary
<!-- Please put a detailed summary of what you wish to report under this heading. including any suggestions you would like to make. -->

View File

@ -0,0 +1,27 @@
### :memo: Summary
### :link: Links / References
- LinksOrReferencesListed
#### :construction_worker: Tasks
- Required Metadata
- [ ] meta.title
- [ ] meta.description
- [ ] meta.date _format YYYY-MM-DD_
- [ ] meta.tags
``` yaml
tags:
- tagname1
- tagname2
```
/target_branch development

View File

@ -1,5 +0,0 @@
{
"outputFormatters": [
[ "markdownlint-cli2-formatter-junit", { "name": "markdown.junit.xml" } ]
]
}

9
.markdownlint.json Normal file
View File

@ -0,0 +1,9 @@
{
"line-length": false,
"MD007": {
"indent": 4
},
"MD033": {
"allowed_elements": [ "div", "s", "span", "u" ]
}
}

8
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,8 @@
{
"python.pythonPath": "dev_env/bin/python",
"python.testing.pytestArgs": [
"--verbose", "--junit-xml=${workspaceFolder}/unit_test.junit.xml", "--tb=line", "test"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true
}

22
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,22 @@
{
"version": "2.0.0",
"command": "bash",
"showOutput": "always",
"args": [
"-c"
],
"tasks": [
{
"suppressTaskName": true,
"args": [
"cd ${workspaceFolder}; . dev_env/bin/activate; pip install -r gitlab-ci/mkdocs/requirements.txt; pip install -r requirements.txt; mkdocs build --clean --strict"
],
"problemMatcher": [],
"label": "MKDocs Build Static Site",
"group": {
"kind": "build",
"isDefault": true
}
}
]
}

86
CHANGELOG.md Normal file
View File

@ -0,0 +1,86 @@
## v1.0.0rc1 (2022-01-29)
### Bug Fixes
- **mkdocs-plugin-tags**: [ddc871ac](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/ddc871accabbbdafe28576265ee66755a5ffe17c) - ensure trailing '/' added to tag hyperlink [ [!5](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/5) ]
- **vscode**: [b4fdcb61](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/b4fdcb61834a6d9d1536b2a93aefd855fbe25006) - use correct params for tests [ [!4](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/4) ]
- **blog_metadata**: [a9237c59](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/a9237c59508979f673faa565f086ce0d2782e53d) - set the date to be in a format that is normal [ [!2](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/2) ]
- **mkdocs-plugin-tags**: [54b75f38](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/54b75f38b432050836f1f0f41eb6a9f9235ca88d) - fix markdown generation so it passes linting [ [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **mkdocs-plugin-tags**: [10a81f0b](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/10a81f0bed073ef865e8c98013ae186d7c70a467) - ensure heading reference in a url is in lower case. [ [#3](https://gitlab.com/nofusscomputing/infrastructure/website/-/issues/3) [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **mkdocs-plugin-tags**: [653c535b](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/653c535b2cfae1a54e45f27fd5c23950ddbe64ed) - the template not using the specified css class for the tag [ [#3](https://gitlab.com/nofusscomputing/infrastructure/website/-/issues/3) [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **mkdocs-plugin-tags**: [7267f8f2](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/7267f8f2ad287fafcbae0fc88f3ceb7dadd19035) - Build a relative link for the url to the tag page [ [#3](https://gitlab.com/nofusscomputing/infrastructure/website/-/issues/3) ]
### Code Refactor
- [a6bcfa6b](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/a6bcfa6b3f877489891905adb120f3fa4228e7fd) - update article requirements
- **article**: [2e534c5d](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/2e534c5dd01b046f8fb520b9a2c607d432d2c309) - include meta.description [ [!5](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/5) ]
- **mkdocs.yml**: [f73011d2](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/f73011d29dbedd3617f37648c2a2fac5501a7a0d) - fix tabbing of plugin
- **privacy_test**: [94ced085](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/94ced08565dac3b26c23e66e9f61e929a8f07ddd) - rename test 'test_page_external_requests' -> 'test_page_load_external_requests' [ [!2](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/2) ]
- **syntax**: [d67a264e](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/d67a264ef010b3a182147d6e40407310e37fb099) - updated tags and added title metadata [ [!2](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/2) ]
- **choose_internet_service**: [98d0acf0](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/98d0acf0aca74c904236bc686f72e669009a8363) - removed extra tags and moved archive notice to bottom of page [ [!2](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/2) ]
- [72ed1cb4](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/72ed1cb4408fcddf202e819cf73c3ce9d9cb2169) - change hover for content tags to yellow text. [ [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **navigation**: [93ceceb3](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/93ceceb3965f93ae4b0d0d3ffa86c0002927ee4b) - rename tags -> 'Content Tags' [ [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **markdown_lint**: [f2969de7](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/f2969de739230bc8c5d44c15a65c61bfdfc74027) - correct linting errors [ [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **mkdocs-plugin-tags**: [5dfeeb81](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/5dfeeb81b10a7e86c30b90dc360a06c3ad429adf) - rebranded plugin to be from nfc [ [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) [#3](https://gitlab.com/nofusscomputing/infrastructure/website/-/issues/3) ]
- [2a16ca06](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/2a16ca065c08759b31ee24f53d1e0ac67a406a9d) - md linting error, ul must be indent four spaces
- [449ec4a9](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/449ec4a9fc5d8421eea4cb79477d2124fc0a308c) - linting error. removed trailing empty line in choosing an internet service. [ [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **article**: [c2d3a178](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/c2d3a178a5ab335bd769a19e9a88839f17021bca) - fixing lists in choosing an internet service [ [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **markdown_lint**: [3a08f14d](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/3a08f14d74899d2f2200503db3ca1bd96ffa859f) - clean up linting errors. [ [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
### Continious Integration
- [217f159c](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/217f159c5c6593c33f27f6c36f0b54735fe3703b) - amend to last commit
- **integration_test**: [88af5fed](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/88af5fedab608986855ae7f1a29ccadd7a53d0f0) - disable job until developed
- **unit_test**: [ec46764d](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/ec46764d72db8de1fc25f8cfb73f56107007932f) - copy report to right location
- **pytest**: [c6f44892](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/c6f44892e7300f9e33b79a12df66bea866bfcd86) - fix to collect junit report
- [a73362ab](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/a73362abe74f9498c200bb76ac4b744ddf762462) - command only required for unit test [ [!4](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/4) ]
- [c3f1ccc8](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/c3f1ccc8dd31c0bce3b3f709c54b3c39c1698b3c) - ensure placeholder test runs and passes [ [!4](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/4) ]
- **static_pages**: [8b041133](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/8b041133dce19647310b24a09161338029765a28) - dont run build if MD lint fails [ [!4](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/4) ]
- **tests**: [13b829d0](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/13b829d0b54d06540ea68b801e59139bedf176ea) - rijigged the job order [ [!4](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/4) ]
- **stages**: [c50e9a0a](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/c50e9a0a6ec438aa1211215202eb66363ef22de0) - deploy job to occur after build [ [!4](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/4) ]
- **unit_test**: [c4dd5b4a](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/c4dd5b4a24a383c84bb6759e3c482b8b11784859) - include requests in test pipfile [ [!4](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/4) [#7](https://gitlab.com/nofusscomputing/infrastructure/website/-/issues/7) ]
- **unit_test**: [f811a7ac](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/f811a7aceffbfdea77c4ff429d0edf386023f07f) - capture stdout in JUnit Report [ [!4](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/4) ]
- **unit_test**: [65726fda](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/65726fda02b7001c7b5315f787136a86d7549566) - ensure only unit test jobs run for the 'unit test' job. [ [!2](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/2) ]
- **pytest**: [7e99d55b](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/7e99d55bdab2263b224aa8297e43e5b156e2bc6b) - Added pytest job to run tests against build. [ [!2](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/2) ]
- **gitlab-ci**: [34ff1e34](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/34ff1e34df74437edf5dbb1a05c2ed41215da056) - use gitlab-ci markdown linting job [ [!2](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/2) ]
- **mkdocs**: [b7919633](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/b79196335d8d471ebffd071cc61276e964fd2482) - use gitlab-ci mkdocs job [ [!2](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/2) ]
- **gitlab-ci**: [95f20fee](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/95f20fee7391674730ff5bbe3e4decdfc57de350) - updated to v0.6.0 [ [!2](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/2) ]
- **markdown_lint**: [b0c91fa6](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/b0c91fa68bda0fac2c4492a6fb227d0970a8f1d0) - set unordered list indentation to four.
- **markdown_lint**: [893d3dfd](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/893d3dfd5c393131f69fddd7d5e80d3f025b48bb) - disable line length for markdown files [ [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **pages**: [a02d2c3b](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/a02d2c3bb5fd0e933b42edce96b624ea355dcb69) - ensure the static site artifacts are available for gitlab pages [ [#3](https://gitlab.com/nofusscomputing/infrastructure/website/-/issues/3) [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **build**: [696138c3](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/696138c317e0f898188b1ba9f0a3e287933f5249) - Added config to build and publish to gitlab pages [ [#3](https://gitlab.com/nofusscomputing/infrastructure/website/-/issues/3) [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
### Features
- **merge_requests**: [ce3a2c2e](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/ce3a2c2e1e434d4910979fee482d071cc050c2b4) - added article MR template [ [!5](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/5) ]
- **vscode**: [cc7a4116](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/cc7a411613c02649fac2e5519079a1cc1b109677) - fix junit path to use workspace folder [ [!5](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/5) ]
- **blog_list**: [286caa16](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/286caa1696692216a09d4fe9dbfc3d4126c7dfd7) - layout not to include post content [ [!5](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/5) ]
- **blog_post**: [08bdf09d](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/08bdf09d30d7f8bbd1f6728d46835d0401f490c0) - remove meta.description from page [ [!5](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/5) ]
- **theme**: [7bd7abd0](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/7bd7abd0e40e56ccb2321a21dd974e8a5ef3de61) - removed post content from 'blog_list' [ [!5](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/5) ]
- **sitemap**: [006a36ac](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/006a36ac0cee8450ce0523add551081b87a235c2) - git_revision_date for page change [ [!4](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/4) ]
- **vscode**: [247f85c3](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/247f85c319e7456e5cb256b1e4fc15bff743424d) - added pytest settings [ [!4](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/4) ]
- **vscode**: [40a92b97](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/40a92b975fc706fdef584d40212d5403646f012a) - added build task [ [!4](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/4) ]
- **minify**: [8292b0a6](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/8292b0a6cfdfd8812a55775809947a0f4fc9501a) - disable minifying website until site ready to deploy [ [!2](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/2) ]
- **minify**: [e4999a44](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/e4999a446267c134d24bae252e363797fb188c95) - minify the mkdocs static html build files
- **mkdocs**: [0e65f046](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/0e65f0465b47f2d58774c44e028b6d6395f7a69c) - minify plugin added to pipfile for usage with build
- **emoji**: [0c7c36d7](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/0c7c36d7e1fd46925a805ad3a98fb682614d510f) - removed emoji support until a solution can be found to self-host. [ [!2](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/2) ]
- **blog_post**: [452fbe12](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/452fbe1225d8f0d22f3976b2c90aef9217a2ecd2) - change location of updated date to be in the social metadata. [ [!2](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/2) ]
- **gitlab**: [0e09b249](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/0e09b249dc72292b36e45449aaaf264a41e74140) - added a default issue templete for reporting issues with the website. [ [!2](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/2) [#5](https://gitlab.com/nofusscomputing/infrastructure/website/-/issues/5) ]
- **blog_list**: [5d75c663](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/5d75c663a1c8472462d53a7bf758a91914ecfbfe) - change articles page to be a preview list of articles. [ [!2](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/2) ]
- **blog_post**: [61f3331d](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/61f3331db0602241b8a4b68952f38707e2b1043a) - include git revision date plugin
- **blog**: [9d9f9c73](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/9d9f9c73c8261cb6a4529acb7c59f4085fd2df27) - added blog capability to posts [ [#3](https://gitlab.com/nofusscomputing/infrastructure/website/-/issues/3) [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **markdownlint**: [d6524ac9](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/d6524ac9cf2e305218ec5d3862b85d12b341ba48) - specifiy the allowed inline html elements [ [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **mkdocs**: [1a1b7776](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/1a1b77769d7f924fc018fb303e6f656826c578a1) - use custom plugin from custom-plugins/mkdocs-plugin-tags [ [#3](https://gitlab.com/nofusscomputing/infrastructure/website/-/issues/3) [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **plugin**: [f77b36a1](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/f77b36a138809b50389dce016557497fbaaf5adb) - cloned plugin tags repo so it can be customized and used [ [#3](https://gitlab.com/nofusscomputing/infrastructure/website/-/issues/3) ]
- **mkdocs**: [830371c6](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/830371c691e283418e373da881f13727ef63ec17) - add lists and task lists to markdown [ [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **sitemap**: [59c2593c](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/59c2593c68fbc3f5b5d9e553e328586ce0811859) - remove sitemap as the changed dates for files is wrong. [ [#3](https://gitlab.com/nofusscomputing/infrastructure/website/-/issues/3) [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **operations**: [c6de8bc9](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/c6de8bc9600a9c740660b8523f2efdd33a879b9e) - Added markdown syntax page. [ [#3](https://gitlab.com/nofusscomputing/infrastructure/website/-/issues/3) [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **article**: [6667f4f0](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/6667f4f0761dcba22a1825c9514963931618140e) - migrated choosing an internet service from old wiki [ [#3](https://gitlab.com/nofusscomputing/infrastructure/website/-/issues/3) [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **contact**: [268e076e](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/268e076e9a04fb071490f4d532aa3cdb53c4ee06) - updated the page content to include how to fix an issue with a page. [ [#3](https://gitlab.com/nofusscomputing/infrastructure/website/-/issues/3) [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **markdown**: [47bfd4e5](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/47bfd4e5cc9c19da8c82e37eb7513f1b75d68f45) - added ability to colour by brand name. [ [#3](https://gitlab.com/nofusscomputing/infrastructure/website/-/issues/3) [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **markdown**: [f6d6bd62](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/f6d6bd627b755cafe9e45f9edd17f7436a323b4a) - Support admonations in markdown. [ [#3](https://gitlab.com/nofusscomputing/infrastructure/website/-/issues/3) [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **footer**: [c0aa5cbe](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/c0aa5cbe12f92cea496a902f68ce4f7114f36d1a) - Add colour to the social icons within the page footer [ [#3](https://gitlab.com/nofusscomputing/infrastructure/website/-/issues/3) [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **mkdocs**: [2460b4c7](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/2460b4c70cf3a7ccf11da60c8b356fad2fad352d) - add document creation and last edited date. [ [#3](https://gitlab.com/nofusscomputing/infrastructure/website/-/issues/3) [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
- **mkdocs**: [8fbb9d95](https://gitlab.com/nofusscomputing/infrastructure/website/-/commit/8fbb9d95ac452b550c65cff32a88f7b6c23437d3) - Add the default config and the site layout directory [ [#3](https://gitlab.com/nofusscomputing/infrastructure/website/-/issues/3) [!1](https://gitlab.com/nofusscomputing/infrastructure/website/-/merge_requests/1) ]
## v1.0.0rc0 (2022-01-29)

View File

@ -0,0 +1,125 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
# docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/

View File

@ -0,0 +1,7 @@
# License
Copyright (C) 2021 No Fuss Computing
All Rights Reserved.
Not yet suitable for public release.

View File

@ -0,0 +1,2 @@
include versioneer.py
include tags/_version.py

View File

@ -0,0 +1,128 @@
# No Fuss Computing's Tags Plugin for MKDocs
Modified version from: [github.com/ginsburgnm/mkdocs-plugin-tags](https://github.com/ginsburgnm/mkdocs-plugin-tags)
## Previous Readme below - tags
Support for tags in the yaml-metadata in the header of markdown files.
Extracts this metadata and creates a "Tags" page which lists all tags
and all pages for each tag.
## Quick Demo
Install this plugin (it will also install mkdocs if required)
```bash
pip install mkdocs-plugin-tags
```
Create a new documentation folder:
```bash
mkdocs new demo
```
Edit the `.md` files to add initial metadata. Currently, the metadata has to be
enclosed in `---` lines, and must include a `title:` property
(otherwise the page will appear as "untitled" in the tags page). So, for example:
```bash
cd demo
cd docs
cat > index.md
---
title: Welcome
tags:
- testing
- unimportant
---
# Welcome to MkDocs
For full documentation visit [mkdocs.org](https://mkdocs.org).
^D
```
Edit `mkdocs.yml` to include this plugin:
```yaml
plugins:
- tags:
```
Run the server:
```bash
mkdocs serve --livereload
```
Visit the URL `/tags` (it should appear in the nav panel).
This is an auto-generated page which contains the tags as level 2 headers,
and under each tag, a listing of the pages which declare that tag in the
metadata section.
![example screenshot](doc/imgs/screenshot.png)
## How it works
On each build (even with `--livereload`), all the `.md` files composing the
site are scanned, their "triple-dash-delimted" yaml header is extracted and
parsed, and the list of tags is collected.
After that, a new temporal file is created (by default in `aux/tags.md`, but
this is customizable) which contains the generated tags page, in markdown
format. This file is not in the documents folder to avoid retriggering a
build, but it is added to the list of files to be converted to HTML by mkdocs.
## Customization
The layout of the tags page is a markdown file with jinja2 embedded contents.
The package provides such a template by default, with the following content:
```markdown
---
title: Tags
---
# Contents grouped by tag
{% for tag, pages in tags %}
## <span class="tag">{{tag}}</span>
{% for page in pages %}
* [{{page.title}}]({{page.filename}})
{% endfor %}
{% endfor %}
```
You can style the `h2.tag` element via CSS, if you want.
You can also provide your own markdown template, in case that you want a
different layout or metadata. The `page` object contains all the metadata
in a mkdocs page, and in addition a `.filename` attribute, which contains
the file name of the source of the page (relative to the docs folder),
which can be used to link to that page.
The full customizable options for the plugin are:
* `tags_folder`: Folder in which the auxiliar tags markdown file will be written
(`aux` by default, relative to the folder in which `mkdocs` is invoked).
It can be set to an absolute path, such as `/tmp/mysite/aux`.
The required folders are created.
* `tags_template`: path to the file which contains the markdown-jinja template
for the tags page. It is `None` by default, which means that the
package-provided template is used. It can be an absolute path,
or relative to the folder in which `mkdocs` is run.
* `css_name`: this allows you to pick what name styles the tag that appears on
the top of the page that contains a tag. This way things won't be overloaded
For example, this can be put at `mkdocs.yaml`:
```yaml
plugins:
- search
- tags:
tags_folder: /tmp/mysite/aux
tags_template: docs/theme/tags.md.template
```

View File

@ -0,0 +1 @@
mkdocs==1.2.3

View File

@ -0,0 +1,27 @@
[metadata]
name = mkdocs-plugin-tags
author = No Fuss Computing
author_email = helpdesk@nofusscomputing.com
url = https://gitlab.com/nofusscomputing/infrastructure/website
description = "Create tags in mkdocs"
long_description_content_type = text/markdown
long_description = file: README.md
license = MIT
keywords = "mkdocs python markdown tags"
classifiers =
Intended Audience :: Developers
License :: OSI Approved :: MIT License
Operating System :: OS Independent
Intended Audience :: Information Technology
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Topic :: Security :: Cryptography
[versioneer]
VCS = git
style = pep440
versionfile_source = tags/_version.py
versionfile_build = tags/_version.py
tag_prefix =
parentdir_prefix = tags-

View File

@ -0,0 +1,19 @@
"""
Setup the plugin
"""
from setuptools import setup, find_packages
setup(
version='0.0.1',
python_requires='>=3.6',
install_requires=[
'mkdocs==1.2.3',
],
packages=find_packages(exclude=['*.tests']),
package_data={'tags': ['templates/*.md.template']},
entry_points={
'mkdocs.plugins': [
'tags = tags.plugin:TagsPlugin'
]
}
)

View File

@ -0,0 +1,3 @@
from . import _version
__version__ = _version.get_versions()['version']

View File

@ -0,0 +1,644 @@
# This file helps to compute a version number in source trees obtained from
# git-archive tarball (such as those provided by githubs download-from-tag
# feature). Distribution tarballs (built by setup.py sdist) and build
# directories (produced by setup.py build) will contain a much shorter file
# that just contains the computed version number.
# This file is released into the public domain. Generated by
# versioneer-0.21 (https://github.com/python-versioneer/python-versioneer)
"""Git implementation of _version.py."""
import errno
import os
import re
import subprocess
import sys
from typing import Callable, Dict
def get_keywords():
"""Get the keywords needed to look up the version information."""
# these strings will be replaced by git during git-archive.
# setup.py/versioneer.py will grep for the variable names, so they must
# each be defined on a line of their own. _version.py will just call
# get_keywords().
git_refnames = "$Format:%d$"
git_full = "$Format:%H$"
git_date = "$Format:%ci$"
keywords = {"refnames": git_refnames, "full": git_full, "date": git_date}
return keywords
class VersioneerConfig:
"""Container for Versioneer configuration parameters."""
def get_config():
"""Create, populate and return the VersioneerConfig() object."""
# these strings are filled in when 'setup.py versioneer' creates
# _version.py
cfg = VersioneerConfig()
cfg.VCS = "git"
cfg.style = "pep440"
cfg.tag_prefix = ""
cfg.parentdir_prefix = "tags-"
cfg.versionfile_source = "tags/_version.py"
cfg.verbose = False
return cfg
class NotThisMethod(Exception):
"""Exception raised if a method is not valid for the current scenario."""
LONG_VERSION_PY: Dict[str, str] = {}
HANDLERS: Dict[str, Dict[str, Callable]] = {}
def register_vcs_handler(vcs, method): # decorator
"""Create decorator to mark a method as the handler of a VCS."""
def decorate(f):
"""Store f in HANDLERS[vcs][method]."""
if vcs not in HANDLERS:
HANDLERS[vcs] = {}
HANDLERS[vcs][method] = f
return f
return decorate
def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False,
env=None):
"""Call the given command(s)."""
assert isinstance(commands, list)
process = None
for command in commands:
try:
dispcmd = str([command] + args)
# remember shell=False, so use git.cmd on windows, not just git
process = subprocess.Popen([command] + args, cwd=cwd, env=env,
stdout=subprocess.PIPE,
stderr=(subprocess.PIPE if hide_stderr
else None))
break
except OSError:
e = sys.exc_info()[1]
if e.errno == errno.ENOENT:
continue
if verbose:
print("unable to run %s" % dispcmd)
print(e)
return None, None
else:
if verbose:
print("unable to find command, tried %s" % (commands,))
return None, None
stdout = process.communicate()[0].strip().decode()
if process.returncode != 0:
if verbose:
print("unable to run %s (error)" % dispcmd)
print("stdout was %s" % stdout)
return None, process.returncode
return stdout, process.returncode
def versions_from_parentdir(parentdir_prefix, root, verbose):
"""Try to determine the version from the parent directory name.
Source tarballs conventionally unpack into a directory that includes both
the project name and a version string. We will also support searching up
two directory levels for an appropriately named parent directory
"""
rootdirs = []
for _ in range(3):
dirname = os.path.basename(root)
if dirname.startswith(parentdir_prefix):
return {"version": dirname[len(parentdir_prefix):],
"full-revisionid": None,
"dirty": False, "error": None, "date": None}
rootdirs.append(root)
root = os.path.dirname(root) # up a level
if verbose:
print("Tried directories %s but none started with prefix %s" %
(str(rootdirs), parentdir_prefix))
raise NotThisMethod("rootdir doesn't start with parentdir_prefix")
@register_vcs_handler("git", "get_keywords")
def git_get_keywords(versionfile_abs):
"""Extract version information from the given file."""
# the code embedded in _version.py can just fetch the value of these
# keywords. When used from setup.py, we don't want to import _version.py,
# so we do it with a regexp instead. This function is not used from
# _version.py.
keywords = {}
try:
with open(versionfile_abs, "r") as fobj:
for line in fobj:
if line.strip().startswith("git_refnames ="):
mo = re.search(r'=\s*"(.*)"', line)
if mo:
keywords["refnames"] = mo.group(1)
if line.strip().startswith("git_full ="):
mo = re.search(r'=\s*"(.*)"', line)
if mo:
keywords["full"] = mo.group(1)
if line.strip().startswith("git_date ="):
mo = re.search(r'=\s*"(.*)"', line)
if mo:
keywords["date"] = mo.group(1)
except OSError:
pass
return keywords
@register_vcs_handler("git", "keywords")
def git_versions_from_keywords(keywords, tag_prefix, verbose):
"""Get version information from git keywords."""
if "refnames" not in keywords:
raise NotThisMethod("Short version file found")
date = keywords.get("date")
if date is not None:
# Use only the last line. Previous lines may contain GPG signature
# information.
date = date.splitlines()[-1]
# git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant
# datestamp. However we prefer "%ci" (which expands to an "ISO-8601
# -like" string, which we must then edit to make compliant), because
# it's been around since git-1.5.3, and it's too difficult to
# discover which version we're using, or to work around using an
# older one.
date = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
refnames = keywords["refnames"].strip()
if refnames.startswith("$Format"):
if verbose:
print("keywords are unexpanded, not using")
raise NotThisMethod("unexpanded keywords, not a git-archive tarball")
refs = {r.strip() for r in refnames.strip("()").split(",")}
# starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of
# just "foo-1.0". If we see a "tag: " prefix, prefer those.
TAG = "tag: "
tags = {r[len(TAG):] for r in refs if r.startswith(TAG)}
if not tags:
# Either we're using git < 1.8.3, or there really are no tags. We use
# a heuristic: assume all version tags have a digit. The old git %d
# expansion behaves like git log --decorate=short and strips out the
# refs/heads/ and refs/tags/ prefixes that would let us distinguish
# between branches and tags. By ignoring refnames without digits, we
# filter out many common branch names like "release" and
# "stabilization", as well as "HEAD" and "master".
tags = {r for r in refs if re.search(r'\d', r)}
if verbose:
print("discarding '%s', no digits" % ",".join(refs - tags))
if verbose:
print("likely tags: %s" % ",".join(sorted(tags)))
for ref in sorted(tags):
# sorting will prefer e.g. "2.0" over "2.0rc1"
if ref.startswith(tag_prefix):
r = ref[len(tag_prefix):]
# Filter out refs that exactly match prefix or that don't start
# with a number once the prefix is stripped (mostly a concern
# when prefix is '')
if not re.match(r'\d', r):
continue
if verbose:
print("picking %s" % r)
return {"version": r,
"full-revisionid": keywords["full"].strip(),
"dirty": False, "error": None,
"date": date}
# no suitable tags, so version is "0+unknown", but full hex is still there
if verbose:
print("no suitable tags, using unknown + full revision id")
return {"version": "0+unknown",
"full-revisionid": keywords["full"].strip(),
"dirty": False, "error": "no suitable tags", "date": None}
@register_vcs_handler("git", "pieces_from_vcs")
def git_pieces_from_vcs(tag_prefix, root, verbose, runner=run_command):
"""Get version from 'git describe' in the root of the source tree.
This only gets called if the git-archive 'subst' keywords were *not*
expanded, and _version.py hasn't already been rewritten with a short
version string, meaning we're inside a checked out source tree.
"""
GITS = ["git"]
TAG_PREFIX_REGEX = "*"
if sys.platform == "win32":
GITS = ["git.cmd", "git.exe"]
TAG_PREFIX_REGEX = r"\*"
_, rc = runner(GITS, ["rev-parse", "--git-dir"], cwd=root,
hide_stderr=True)
if rc != 0:
if verbose:
print("Directory %s not under git control" % root)
raise NotThisMethod("'git rev-parse --git-dir' returned error")
# if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty]
# if there isn't one, this yields HEX[-dirty] (no NUM)
describe_out, rc = runner(GITS, ["describe", "--tags", "--dirty",
"--always", "--long",
"--match",
"%s%s" % (tag_prefix, TAG_PREFIX_REGEX)],
cwd=root)
# --long was added in git-1.5.5
if describe_out is None:
raise NotThisMethod("'git describe' failed")
describe_out = describe_out.strip()
full_out, rc = runner(GITS, ["rev-parse", "HEAD"], cwd=root)
if full_out is None:
raise NotThisMethod("'git rev-parse' failed")
full_out = full_out.strip()
pieces = {}
pieces["long"] = full_out
pieces["short"] = full_out[:7] # maybe improved later
pieces["error"] = None
branch_name, rc = runner(GITS, ["rev-parse", "--abbrev-ref", "HEAD"],
cwd=root)
# --abbrev-ref was added in git-1.6.3
if rc != 0 or branch_name is None:
raise NotThisMethod("'git rev-parse --abbrev-ref' returned error")
branch_name = branch_name.strip()
if branch_name == "HEAD":
# If we aren't exactly on a branch, pick a branch which represents
# the current commit. If all else fails, we are on a branchless
# commit.
branches, rc = runner(GITS, ["branch", "--contains"], cwd=root)
# --contains was added in git-1.5.4
if rc != 0 or branches is None:
raise NotThisMethod("'git branch --contains' returned error")
branches = branches.split("\n")
# Remove the first line if we're running detached
if "(" in branches[0]:
branches.pop(0)
# Strip off the leading "* " from the list of branches.
branches = [branch[2:] for branch in branches]
if "master" in branches:
branch_name = "master"
elif not branches:
branch_name = None
else:
# Pick the first branch that is returned. Good or bad.
branch_name = branches[0]
pieces["branch"] = branch_name
# parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty]
# TAG might have hyphens.
git_describe = describe_out
# look for -dirty suffix
dirty = git_describe.endswith("-dirty")
pieces["dirty"] = dirty
if dirty:
git_describe = git_describe[:git_describe.rindex("-dirty")]
# now we have TAG-NUM-gHEX or HEX
if "-" in git_describe:
# TAG-NUM-gHEX
mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe)
if not mo:
# unparsable. Maybe git-describe is misbehaving?
pieces["error"] = ("unable to parse git-describe output: '%s'"
% describe_out)
return pieces
# tag
full_tag = mo.group(1)
if not full_tag.startswith(tag_prefix):
if verbose:
fmt = "tag '%s' doesn't start with prefix '%s'"
print(fmt % (full_tag, tag_prefix))
pieces["error"] = ("tag '%s' doesn't start with prefix '%s'"
% (full_tag, tag_prefix))
return pieces
pieces["closest-tag"] = full_tag[len(tag_prefix):]
# distance: number of commits since tag
pieces["distance"] = int(mo.group(2))
# commit: short hex revision ID
pieces["short"] = mo.group(3)
else:
# HEX: no tags
pieces["closest-tag"] = None
count_out, rc = runner(GITS, ["rev-list", "HEAD", "--count"], cwd=root)
pieces["distance"] = int(count_out) # total number of commits
# commit date: see ISO-8601 comment in git_versions_from_keywords()
date = runner(GITS, ["show", "-s", "--format=%ci", "HEAD"], cwd=root)[0].strip()
# Use only the last line. Previous lines may contain GPG signature
# information.
date = date.splitlines()[-1]
pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
return pieces
def plus_or_dot(pieces):
"""Return a + if we don't already have one, else return a ."""
if "+" in pieces.get("closest-tag", ""):
return "."
return "+"
def render_pep440(pieces):
"""Build up version string, with post-release "local version identifier".
Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you
get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty
Exceptions:
1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty]
"""
if pieces["closest-tag"]:
rendered = pieces["closest-tag"]
if pieces["distance"] or pieces["dirty"]:
rendered += plus_or_dot(pieces)
rendered += "%d.g%s" % (pieces["distance"], pieces["short"])
if pieces["dirty"]:
rendered += ".dirty"
else:
# exception #1
rendered = "0+untagged.%d.g%s" % (pieces["distance"],
pieces["short"])
if pieces["dirty"]:
rendered += ".dirty"
return rendered
def render_pep440_branch(pieces):
"""TAG[[.dev0]+DISTANCE.gHEX[.dirty]] .
The ".dev0" means not master branch. Note that .dev0 sorts backwards
(a feature branch will appear "older" than the master branch).
Exceptions:
1: no tags. 0[.dev0]+untagged.DISTANCE.gHEX[.dirty]
"""
if pieces["closest-tag"]:
rendered = pieces["closest-tag"]
if pieces["distance"] or pieces["dirty"]:
if pieces["branch"] != "master":
rendered += ".dev0"
rendered += plus_or_dot(pieces)
rendered += "%d.g%s" % (pieces["distance"], pieces["short"])
if pieces["dirty"]:
rendered += ".dirty"
else:
# exception #1
rendered = "0"
if pieces["branch"] != "master":
rendered += ".dev0"
rendered += "+untagged.%d.g%s" % (pieces["distance"],
pieces["short"])
if pieces["dirty"]:
rendered += ".dirty"
return rendered
def pep440_split_post(ver):
"""Split pep440 version string at the post-release segment.
Returns the release segments before the post-release and the
post-release version number (or -1 if no post-release segment is present).
"""
vc = str.split(ver, ".post")
return vc[0], int(vc[1] or 0) if len(vc) == 2 else None
def render_pep440_pre(pieces):
"""TAG[.postN.devDISTANCE] -- No -dirty.
Exceptions:
1: no tags. 0.post0.devDISTANCE
"""
if pieces["closest-tag"]:
if pieces["distance"]:
# update the post release segment
tag_version, post_version = pep440_split_post(pieces["closest-tag"])
rendered = tag_version
if post_version is not None:
rendered += ".post%d.dev%d" % (post_version+1, pieces["distance"])
else:
rendered += ".post0.dev%d" % (pieces["distance"])
else:
# no commits, use the tag as the version
rendered = pieces["closest-tag"]
else:
# exception #1
rendered = "0.post0.dev%d" % pieces["distance"]
return rendered
def render_pep440_post(pieces):
"""TAG[.postDISTANCE[.dev0]+gHEX] .
The ".dev0" means dirty. Note that .dev0 sorts backwards
(a dirty tree will appear "older" than the corresponding clean one),
but you shouldn't be releasing software with -dirty anyways.
Exceptions:
1: no tags. 0.postDISTANCE[.dev0]
"""
if pieces["closest-tag"]:
rendered = pieces["closest-tag"]
if pieces["distance"] or pieces["dirty"]:
rendered += ".post%d" % pieces["distance"]
if pieces["dirty"]:
rendered += ".dev0"
rendered += plus_or_dot(pieces)
rendered += "g%s" % pieces["short"]
else:
# exception #1
rendered = "0.post%d" % pieces["distance"]
if pieces["dirty"]:
rendered += ".dev0"
rendered += "+g%s" % pieces["short"]
return rendered
def render_pep440_post_branch(pieces):
"""TAG[.postDISTANCE[.dev0]+gHEX[.dirty]] .
The ".dev0" means not master branch.
Exceptions:
1: no tags. 0.postDISTANCE[.dev0]+gHEX[.dirty]
"""
if pieces["closest-tag"]:
rendered = pieces["closest-tag"]
if pieces["distance"] or pieces["dirty"]:
rendered += ".post%d" % pieces["distance"]
if pieces["branch"] != "master":
rendered += ".dev0"
rendered += plus_or_dot(pieces)
rendered += "g%s" % pieces["short"]
if pieces["dirty"]:
rendered += ".dirty"
else:
# exception #1
rendered = "0.post%d" % pieces["distance"]
if pieces["branch"] != "master":
rendered += ".dev0"
rendered += "+g%s" % pieces["short"]
if pieces["dirty"]:
rendered += ".dirty"
return rendered
def render_pep440_old(pieces):
"""TAG[.postDISTANCE[.dev0]] .
The ".dev0" means dirty.
Exceptions:
1: no tags. 0.postDISTANCE[.dev0]
"""
if pieces["closest-tag"]:
rendered = pieces["closest-tag"]
if pieces["distance"] or pieces["dirty"]:
rendered += ".post%d" % pieces["distance"]
if pieces["dirty"]:
rendered += ".dev0"
else:
# exception #1
rendered = "0.post%d" % pieces["distance"]
if pieces["dirty"]:
rendered += ".dev0"
return rendered
def render_git_describe(pieces):
"""TAG[-DISTANCE-gHEX][-dirty].
Like 'git describe --tags --dirty --always'.
Exceptions:
1: no tags. HEX[-dirty] (note: no 'g' prefix)
"""
if pieces["closest-tag"]:
rendered = pieces["closest-tag"]
if pieces["distance"]:
rendered += "-%d-g%s" % (pieces["distance"], pieces["short"])
else:
# exception #1
rendered = pieces["short"]
if pieces["dirty"]:
rendered += "-dirty"
return rendered
def render_git_describe_long(pieces):
"""TAG-DISTANCE-gHEX[-dirty].
Like 'git describe --tags --dirty --always -long'.
The distance/hash is unconditional.
Exceptions:
1: no tags. HEX[-dirty] (note: no 'g' prefix)
"""
if pieces["closest-tag"]:
rendered = pieces["closest-tag"]
rendered += "-%d-g%s" % (pieces["distance"], pieces["short"])
else:
# exception #1
rendered = pieces["short"]
if pieces["dirty"]:
rendered += "-dirty"
return rendered
def render(pieces, style):
"""Render the given version pieces into the requested style."""
if pieces["error"]:
return {"version": "unknown",
"full-revisionid": pieces.get("long"),
"dirty": None,
"error": pieces["error"],
"date": None}
if not style or style == "default":
style = "pep440" # the default
if style == "pep440":
rendered = render_pep440(pieces)
elif style == "pep440-branch":
rendered = render_pep440_branch(pieces)
elif style == "pep440-pre":
rendered = render_pep440_pre(pieces)
elif style == "pep440-post":
rendered = render_pep440_post(pieces)
elif style == "pep440-post-branch":
rendered = render_pep440_post_branch(pieces)
elif style == "pep440-old":
rendered = render_pep440_old(pieces)
elif style == "git-describe":
rendered = render_git_describe(pieces)
elif style == "git-describe-long":
rendered = render_git_describe_long(pieces)
else:
raise ValueError("unknown style '%s'" % style)
return {"version": rendered, "full-revisionid": pieces["long"],
"dirty": pieces["dirty"], "error": None,
"date": pieces.get("date")}
def get_versions():
"""Get version information or return default if unable to do so."""
# I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have
# __file__, we can work backwards from there to the root. Some
# py2exe/bbfreeze/non-CPython implementations don't do __file__, in which
# case we can only use expanded keywords.
cfg = get_config()
verbose = cfg.verbose
try:
return git_versions_from_keywords(get_keywords(), cfg.tag_prefix,
verbose)
except NotThisMethod:
pass
try:
root = os.path.realpath(__file__)
# versionfile_source is the relative path from the top of the source
# tree (where the .git directory might live) to this file. Invert
# this to find the root from __file__.
for _ in cfg.versionfile_source.split('/'):
root = os.path.dirname(root)
except NameError:
return {"version": "0+unknown", "full-revisionid": None,
"dirty": None,
"error": "unable to find root of source tree",
"date": None}
try:
pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose)
return render(pieces, cfg.style)
except NotThisMethod:
pass
try:
if cfg.parentdir_prefix:
return versions_from_parentdir(cfg.parentdir_prefix, root, verbose)
except NotThisMethod:
pass
return {"version": "0+unknown", "full-revisionid": None,
"dirty": None,
"error": "unable to compute version", "date": None}

View File

@ -0,0 +1,151 @@
#!/usr/bin/env python
"""
This plugin generates tags file as well as inserts markdown
at the beginning of a file that has tags
@Adopted from
JL Diaz (c) 2019
MIT License
"""
from collections import defaultdict
from pathlib import Path
from re import search, DOTALL, MULTILINE
from yaml import load, FullLoader, YAMLError
from jinja2 import Environment, FileSystemLoader
from mkdocs.structure.files import File
from mkdocs.plugins import BasePlugin
from mkdocs.config.config_options import Type
from mkdocs.__main__ import log
class TagsPlugin(BasePlugin):
"""
Creates "tags.md" file containing a list of the pages grouped by tags
It uses the info in the YAML metadata of each page, for the pages which
provide a "tags" keyword (whose value is a list of strings)
"""
config_scheme = (
('filename', Type(str, default='tags.md')),
('folder', Type(str, default='aux')),
('template', Type(str)),
('css_name', Type(str, default='.button')),
)
def __init__(self):
self.metadata = []
self.tag_dict = None
self.filename = "tags.md"
self.folder = "aux"
self.template = None
self.css_name = ".button"
self.templ = None
#pylint: disable=unused-argument
def on_page_markdown(self, markdown, page, config, files):
"""
takes markdown, page, config, and files
currently modifies the markdown to add a button to click to get related tag info
tag is customizeable by adding css that keys off the `self.css_name`
"""
page_url = page.url.split("/")
tags_link = ''
for i in range(len(page_url) - 1):
tags_link = tags_link + '../'
tags_link = tags_link + str(self.filename).strip('.md')
if tags_link[-1] != '/':
tags_link = tags_link + '/'
if 'tags' in page.meta:
swap_mark = [f"[{x}]({tags_link}#{x.lower()}){{{self.css_name}}}"
for x in page.meta['tags']]
swap_mark.append('\n')
return f'{" ".join(swap_mark)}{markdown}'
return markdown
def on_config(self, config):
"""Load config options"""
self.filename = Path(self.config.get("filename") or self.filename)
self.folder = Path(self.config.get("folder") or self.folder)
self.css_name = self.config.get("css_name")
# Make sure that the tags folder is absolute, and exists
if not self.folder.is_absolute():
self.folder = Path(config["docs_dir"]) / ".." / self.folder
if not self.folder.exists():
self.folder.mkdir(parents=True)
if self.config.get("template"):
self.template = Path(self.config.get("template"))
if self.template is None:
self.template = Path(__file__).parent.joinpath(
"templates"
).joinpath("tags.md.template")
environment = Environment(
loader=FileSystemLoader(searchpath=str(self.template.parent))
)
self.templ = environment.get_template(str(self.template.name))
def on_files(self, files, config):
"""Load files to check for tags"""
self.metadata = [
get_metadata(x.src_path, config['docs_dir'])
for x in files if x.src_path.endswith(".md")
]
# Create new file with tags
self.generate_tags_file()
# New file to add to the build
newfile = File(
path=str(self.filename),
src_dir=str(self.folder),
dest_dir=config["site_dir"],
use_directory_urls=False
)
files.append(newfile)
def generate_tags_page(self, data):
"""Generate the tags to be populated on the
mkdocs tag page"""
css_name = self.css_name
if css_name[0:1] == '.':
css_name = css_name[1:len(css_name)]
return self.templ.render(
tags=sorted(data.items(), key=lambda t: t[0].lower()),
css_name = css_name,
)
def generate_tags_file(self):
"""Generate a file to be stored on the mkdocs page"""
sorted_meta = sorted(self.metadata, key=lambda e: e.get("year", 5000) if e else 0)
self.tag_dict = defaultdict(list)
for meta in sorted_meta:
if not meta:
continue
if "title" not in meta:
meta["title"] = meta['filename'].split("/")[-1].strip('.md')
tags = meta.get("tags", [])
for tag in tags:
self.tag_dict[tag].append(meta)
with open(str(self.folder / self.filename), "w", encoding='utf-8') as fname:
fname.write(self.generate_tags_page(self.tag_dict))
# Helper functions
def get_metadata(name, path):
"""Get the metadata off of a file"""
filename = Path(path) / Path(name)
with filename.open() as fname:
match_string = search(r"\A\s*---\n.*?\n---", fname.read(), flags=DOTALL | MULTILINE)
if match_string:
try:
metadata = match_string.group(0).strip('---')
meta = load(metadata, Loader=FullLoader)
meta.update(filename=name)
return meta
except YAMLError as err:
log.error("Couldn't parse %s yaml due to %s", fname, err)
return None

View File

@ -0,0 +1,6 @@
# Contents grouped by tag
{% for tag, pages in tags %}
## <span class="{{css_name}}">{{tag}}</span>
{% for page in pages %}
* [{{page.title}}]({{page.filename}})
{% endfor %}{% endfor %}

159
mkdocs.yml Normal file
View File

@ -0,0 +1,159 @@
site_name: No Fuss Computing
site_description: A wiki with random bits of information you may find useful.
site_url: https://nofusscomputing.com
site_author: No Fuss Computing
copyright: Copyright &copy; No Fuss Computing 2021
#site_favicon: favicon.ico
# site_dir: 'docs/static/mkdocs_build'
docs_dir: 'pages'
site_dir: build
repo_name: Website
#repo_url: https://gitlab.com/nofusscomputing/infrastructure/website
repo_url: https://gitlab.com/nofusscomputing/infrastructure/website
#edit_uri: '-/blob/pages'
#edit_uri: '-/blob/master/pages/'
edit_uri: ''
theme:
name: material
logo: assets/logo.png
custom_dir: theme-overrides
icon:
repo: fontawesome/brands/gitlab # (1)!
locale: en
font: false
features:
- navigation.tracking
- navigation.tabs
- navigation.tabs.sticky
- navigation.expand
- navigation.indexes
- toc.integrate
- navigation.top
- header.autohide
- navigation.sections
palette:
- scheme: default
primary: indigo
accent: indigo
toggle:
icon: material/lightbulb-outline
name: Switch to dark mode
- scheme: slate
primary: indigo
accent: indigo
toggle:
icon: material/lightbulb
name: Switch to light mode
plugins:
- tags:
filename: tags.md
folder: pages
css_name: ".tags"
- search:
lang: en
- git-revision-date-localized:
type: iso_date
enable_creation_date: true
exclude:
- index.md
- tags.md
# - minify:
# minify_html: true
extra:
homepage: https://nofusscomputing.com
version: 1.0
social:
- link: https://hub.docker.com/u/nofusscomputing
name: DockerHub
icon: fontawesome/brands/docker
- link: https://facebook.com/NoFussComputing
name: Facebook
icon: fontawesome/brands/facebook
- link: https://gitlab.com/nofusscomputing
name: Gitlab
icon: fontawesome/brands/gitlab
- link: https://github.com/NoFussComputing
name: Github
icon: fontawesome/brands/github
# - link: https://readthedocs.org/profiles/nofusscomputing/
# nane: ReadTheDocs
# icon: fontawesome/brands/readthedocs
# link: https://
blog:
dir: articles
author: jon_nfc
author_image: https://gitlab.com/uploads/-/system/user/avatar/4125177/avatar.png
words_read_per_minute: 300
list_length: 25
extended_preview: true
extra_css:
- stylesheets/extra.css
markdown_extensions:
- def_list
- pymdownx.tasklist:
custom_checkbox: true
- meta
- attr_list
- admonition
- pymdownx.details
- pymdownx.superfences
# - pymdownx.emoji:
# emoji_index: !!python/name:materialx.emoji.twemoji
# emoji_generator: !!python/name:materialx.emoji.to_svg
# options:
# custom_icons:
# - .icons
nav:
- Home: index.md
- Articles:
- articles/index.md
- 2015:
- articles/2015/choose_internet_service.md
- Content Tags: tags.md
- Projects:
- projects/index.md
- Ansible Roles: projects/ansible-roles/README.md
- Gitlab CI Templates: projects/gitlab-ci/README.md
- Python Gitlab Management: projects/python-gitlab-management/README.md
- Operations:
- operations/index.md
- Development:
- operations/syntax.md
- Wiki:
- wiki/index.md
- Contact Us: contact.md

View File

@ -0,0 +1,150 @@
---
template: blog_post.html
title: Choosing an Internet Service
description: The Internet has now become a mainstream item within the average Australian home. The Internet has become so ingrained within our daily lives that for those of us that were around when the Internet was born have actually forgotten what life was like without it. I remember when I was growing up that if we wanted to learn about something you would go to the local library or to a family/friends house to look through their Encyclopaedia Britannica which more often than not was at least five years out of date. Believe it or not that was only 15 to 20 years ago. Now if I haven't lost you already and hopefully by the end of this article I have been able to provide you with more insight on being able to choose an Internet service from an ISP with a little more of an understanding of the technology behind that Internet connection.
date: 2015-02-25
tags:
- ADSL
- Archive
- Article
- Broadband
- Internet
- NBN
- Australia
---
!!! info
This article has been targeted towards the common mass who dont understand the technical details and considerations for choosing an Internet package.
The Internet has now become a mainstream item within the average Australian home. The Internet has become so ingrained within our daily lives that for those of us that were around when the Internet was born have actually forgotten what life was like without it. I remember when I was growing up that if we wanted to learn about something you would go to the local library or to a family/friends house to look through their Encyclopaedia Britannica which more often than not was at least five years out of date. Believe it or not that was only 15 to 20 years ago. I would consider myself lucky in the regard we were introduced to the Internet in high school way back when Web Crawler was what Google is today and the only thing of any value was searching for random phrases like <s>porn</s> homework answers. It was a very new concept to have the Internet or even access, which was often met with confusion and a sheer lack of knowledge. Being part of that generation we grew with the Internet and became the first generation to learn about it, and to the behest of the generations before us who were either left in the dark or were very slow on the uptake.
Now if I haven't lost you already and hopefully by the end of this article I have been able to provide you with more insight on being able to choose an Internet service from an ISP with a little more of an understanding of the technology behind that Internet connection.
Below I will cover a little of the technical details and hopefully bringing into perspective, so you can better understand what is being explained to you. To do this I will use the flow of water methodology.
<p hidden>#more</p>
## Bandwidth
Bandwidth is the actual speed of your Internet connection and its unit of measure is bits per second. So basically if you think water pipe, only so much water will flow through a water pipe but if you increase its pressure you will receive more water. For the actual Internet connection different technology is used to essentially achieve the same
thing.
## Quota
This is how much you can download and/or upload from the Internet. Its unit of measure is bytes. Think of a water tank, larger the tank the more quota you have available. This will be set by your ISP and 9 times out of 10 will be limited. Every Time you connect to the Internet you are using this available quota.
## Theory
Now to fully understand the quota and bandwidth I will have to cover a little bit of computer theory. Computers compute information by doing mathematical equations. The only numbers a computer recognizes are Base 2. Base 2 numbering means it uses the first 2 numbers, being zero and one. In common computer terms this is called binary which is always in the computer world as a minimum 8 bits wide i.e. 01010101. Each digit of the number is a bit, four bits to a nibble and 2 nibbles to a byte. Unlike the English language; Binary is read from right to left and each one or zero, within a binary number is actually counting from 1 through to 255, which takes 8 bits of information. Binary is a notational reference system, so starting from right to left each digit represents another number, the first number being one, each number after that is double the number before it so the next number would be two, then four, eight, 16, 32, 64 finishing with the leftmost digit as 128. Confusing? Not really, when the bit is zero you don't add each notated number, you only add if the bit is one. So 0001 would be one, 0010 would be two, 0011 is three and so on.
Communication between different components or computers (network or The Internet) is measured in bits per second or bps (lowercase). Computers store data in bytes or B (uppercase). Each unit of measure has multipliers like normal numbers, computers use the following multipliers, Kilo (K) for thousands, Mega (M) for millions, Giga (G) for billions, Tera (T) for trillions and Peta (P) for quintillion's. The conversion from bits to bytes is a division of 8.
So why use different units of measure for the same data? simply put, computers are electronic devices which communicate with an electronic signal with 1 being on and zero being off; basically the signal is either on or off. So the transmission of data is serial or singular and storage is in parallel or stored in octets which is a group of bits. Hence bits and bytes. generally you will find lowercase letters are used to represent bits and uppercase letters are used for bytes.
### Connection types
The common Internet connection types in Australia are ADSL or via the Mobile network. Very rarely used but still available if you look hard enough dial-up. and the newest and greatest is the National Broadband Network or NBN. With the exception of the NBN all of the above connection types will have a max speed. This max speed is a theoretical maximum speed and there are many factors which generally slow down your connection. All connection methods have a technological peak, which basically means there is no known way to improve that technology any further.
### Dial-Up
Dial-UpInternet was the first mainstream way to connect to the Internet. For this to happen you needed an active phone line, a computer with a MODEM (short for modulator/demodulator) and you would plug a phone cable into your computer, which would dial a number to connect to the Internet. At its technological peak the max theoretical download speed was 56kb and approx 33kb up. Dial-up modems are generally part of the computer. The downside to Dial-up is that it relies on good quality phone cables, basically if you have a bad phone line you will have unstable and slower Internet. Dial-up also suffers from signal attenuation which means the further away from the telephone exchange the lower the speed your Internet is going to be. The biggest downside to having Dial-up Internet is that you can either be connected to the Internet or on the phone, not both.
### ADSL
Asynchronous Digital Subscriber Line or ADSL is the most common Internet in Australia. This is also commonly referred to as broadband Internet, the biggest difference between ADSL and Dial-up is that it is always on. When ADSL first arrived it had a speed of 1.5mb, which was a massive increase over Dial-up. As ADSL evolved its speed increased, when this occurred its name slightly changed to suit the technological level, ADSL1, ADSL2 and finishing with ADSL2+ which has a maximum theoretical download speed of 24Mb and 2Mb Up. An ADSL connection like dial-up Internet requires a modem and suffers with the same line issues. Where ADSL is an improvement over Dial-up is that you can still make telephone calls when you are have an active Internet connection for this you will need a line filter. To utilise an ADSL connection you require an ADSL modem.
### Mobile Network
Again this method of connecting to the Internet has been around for a while and with the invention of the smartphone has become quite a common way to “surf the Web”. 4th generation or 4G being the current technology has a max theoretical speed of 50Mb. The connection speed is shared amongst all users utilizing that mobile tower to connect to the Internet, and if you dont have good mobile reception you will not have a stable Internet connection.
### NBN
The National broadband network or NBN as it is known is the new way to connect to the Internet. The NBN unlike Dial-up or ADSL does not use a phone line to connect to the Internet. The NBN uses fiber optic cable, which uses light not electricity to communicate. Fiber optic cable can be thinner than a human hair. Fiber Optic cable, or fiber networks have one purpose; transmit data, not voice or electronic signals like a copper cable Since fiber is designed for networking you require a router to connect to it. A router looks very similar to an ADSL modem. Unlike the other Internet connection methods above, communication in either direction is the same. Within Australia this is not the case, and for whatever reason you will find most NBN capable ISPs will still have packages with different upload and download speeds. Fiber networks are very mature and their speed is actual, not theoretical maximums and are capable of transmitting data at 10gbps. Using that speed for connecting to the Internet is overkill and you will find that most ISPs offer no connection speed above 100mbps at the moment.
## Choosing a suitable Internet service
Now hopefully by now I have given you a little better understanding of the connection types and terminology in relation to choosing an Internet service; believe me it is still a cumbersome task. Yes there are a lot of things to consider. From a technical standpoint the following should be taken into account:
- availability in your area
- what you will be using the Internet for
- bang for buck
### Availability in Your Area
For a majority of Australians, ADSL is the best Internet service you will have available. The most annoying thing when trying to connect an ADSL service is the wait time. This wait time is due to the requirement for a technician to have to go to your local telephone exchange to actually connect you, that is if there are spare ports available in the exchange. If though, you can get the NBN, go for it. Seriously you are being foolish if you don't. Why? the NBN is an actual data network and the speed you pay for is what you get, overall the NBN is more reliable.
### What You Will be Using the Internet For?
Most website designers will aim for a page load time of within one-two seconds; Even now how website technology is becoming more media focused, I would not recommend any speed lower that ADSL2+(24mbps) or 12mbps for the NBN. Why the different speeds? Remember that ADSL is a theoretical maximum, on average. Most ADSL users will have an actual connection speed of between 8mbps-22mbps and the NBN is actual speed. Anything faster than this for just “surfing the web” is overkill, and a waste of money. Where would you require a faster connection speed? if you start to use services like netflix and/or Foxtel IPTV to stream videos. Having more than ~5 users, may also be a consideration for a speed increase. How much quota do you need? if you have had the Internet before, go look at your previous bills, most of the time you will see what you used for the billing period, use this figure as a basis to guesstimate how much quota you are going to need. If you have never had an Internet package before then as a guide I would recommend nothing less than 10GB quota per month for the average light Internet user. I can't emphasize this enough, please do your research before you take this as gospel. Most people do know someone who <s>“knows boats”</s> would be able to assist in assessing how much quota you may require.
### Bang for Buck
Read the fine print………. READ THE FINE PRINT……… oh, did I mention fine print? Every Internet package has fine print. This fine print will cover things like:
- what is unmetered((this is a category of sites that you can use without it being counted towards your quota.))
- how much quota you have, read carefully some ISPs will charge by the megabyte if you go over
- what happens when you reach your quota limit (good ISPs will shape your speed ((slow your Internet connection speed)))
- what you should not do with your Internet package (some ISPs wont allow you to host your own website.)
- contract period
- exit fees associated with leaving your contract early
- fees associated with moving house
- support
- your responsibilities
### Further Considerations
- "**Unlimited Packages"** Some ISPs do offer "unlimited packages". Please read the fine print so you can get the definition of unlimited as sometimes unlimited does not exactly mean unlimited. Some ISPs have been know to use peak and off-peak times, during peak you will have a quota and off peak is “unlimited”. A big consideration for unlimited or large packages with lower download speeds is calculating what you could actually download in that billing period. This is a simple task and would use the following formula.
> (Billing Period Days x seconds in day) × max download speed in bits ÷ 8 = max bytes for period
>Example:
>
>- Billing Period days = 30
>- Second in one day = 86,400
>- Max download speed = 22,000,000
>- ( 30 x 86,400 ) × 22,000,000 ÷ 8 = 7,128,000,000,000Bytes or 7.128TB
>So with the example above a package with a quota above 7.128TB with a download speed of 22mb would be a waste of money.
- **Bundled Items** We have all seen and heard of them.
- "Select our Internet Package for $120 a month and we will give you a telephone with free calls, 200gb of download and if you sign up for a 24month contract we will throw in a free iPad"
- With the exception of a modem-if you don't have one; be very careful of falling into this trap. These “Bundled Packages” are plain and simply designed to get your business. Believe me when I say you can get all of this for a hell of a lot cheaper. Again <u>READ THE FINE PRINT</u> and calculate the cost of the whole contract period including any hidden fees and you will find that these are quite expensive packages. A simple way to test these packages is how much is thrown in, the more free stuff that is included outside of the Internet package, then the more desperate they are for your business. Listen to your gut and the age old saying "If it's too good to be true, than it probably is". Once in my life time I have seen one of these packages and it was too good to be true, but turned out to actually be worth while in the long run, again this was more than likely a “once in a lifetime good package”
- **Naked ADSL** works exactly the same as normal ADSL Internet but you dont have to pay for the phone line as it is included in the “Naked ADSL package” if you dont use the telephone much or you are utilizing VOIP choosing one of these packages can save you some money. Like ADSL this is only available in certain areas, Please confirm with your ISP for availability.
- **Support** It's common practice for ISPs to outsource the first stage of customer support. This problem is a plague that needs to be truncated from the IT((Information Technology)) industry. Why? 9 times out of 10 the person on the other end of the phone either does not have a good grasp on our native language or has an accent that is so thick you can not understand them, which makes it very difficult for the hearing impaired. When this occurs the assistance you called for doesn't happen, and is escalated to someone else in the chain who may or may not be able to help you. In the end you are stuck with no internet and built up frustration from a 1:30h phone call.
There are however some ISPs who are old school. they will give you a callback after being on hold for a few minutes and if your assistance call needs to be escalated will either call you back or give a detailed handover to the next person you need to speak to. bottom line if you are not technically minded than ask around to find a good ISP who can assist you and be wary of outsourced tech support.
## Conclusion
Lets face it, The Internet has made our lives easier. You can now sit in your lounge room and read this long, very mind numbing article on how to choose a better Internet Service, do your Banking, Pay Bills, Buy Goods, <s>look at porn</s> and best of all place video calls to family and friends. What will the future hold? Who knows but given how far technology has evolved in the last 50 years, I think the next 50 will yield even more from this simple little invention courtesy of DARPA.
<s>Like this article? Please consider buying me a coffee. Donations can be accepted via PayPal via our store at No Fuss Computing</s>
Some ISPs in Australia:
- Internode
- IINet
- WestNet
!!! warning
The information contained within this article based on the opinion of the author and is provided for informational purposes only. Before utilizing any information or advice from this article you are encouraged to do your own research
!!! attention
This post is considered an archived post.
This article was originally posted on 25 Feb 2015. It has been migrated from its original source _http://nofusscomputing.com/wiki/public/article/150225_choose_internet_service_ to here.

8
pages/articles/index.md Normal file
View File

@ -0,0 +1,8 @@
---
template: blog_list.html
title: No Fuss Computing Articles
---
Please see below for our articles.

BIN
pages/assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

23
pages/contact.md Normal file
View File

@ -0,0 +1,23 @@
# Contact Us
We can be found in the following places on the internet:
- [:fontawesome-brands-docker:{ .docker } Docker Hub](https://hub.docker.com/u/nofusscomputing)
- [:fontawesome-brands-facebook:{ .facebook } Facebook](https://www.facebook.com/NoFussComputing)
- [:fontawesome-brands-github:{ .github } Github](https://github.com/NoFussComputing)
- [:fontawesome-brands-gitlab:{ .gitlab } Gitlab](https://gitlab.com/nofusscomputing)
- [:books: Read the Docs](https://readthedocs.org/profiles/nofusscomputing/)
## Found an issue with a page on this website?
On every page of this website that you are able to edit, you will find this icon :material-pencil:. Located in the top right hand corner of the content. After clicking on this icon, you will be taken to the git repository that contains the page in question for you to edit. An understanding of Git and Gitlab is required for the use of this method.
For the non-developers out there, you can still contribute by submitting an issue about the related page. To do this find this icon :fontawesome-brands-gitlab: on the subject page. Copy the page url to your clipboard, then click :fontawesome-brands-gitlab: icon. You will be taken to Gitlab.com and the repository in question. There will be a menu on the left hand side of the screen, where you will click issues. On the issues page loading, click new issue and use a relevant template for your report. _**Don't forget to include the url of the subject page and to ensure there is enough details for us to rectify the issue.**_
??? info "Where is the owner located??"
Jon can be found on [:fontawesome-brands-github:{ .github } Github](https://github.com/jon-nfc) and [:fontawesome-brands-gitlab:{ .gitlab } Gitlab](https://gitlab.com/jon_nfc)

8
pages/index.md Normal file
View File

@ -0,0 +1,8 @@
---
hide:
- navigation
- toc
---
# No Fuss Computing
Home Page

View File

@ -0,0 +1,5 @@
# No Fuss Computing Operations
| :red_circle: This page is a placeholder for the operations repo's docs. |
|:---|
| _If you can see this page there has been an error, please report the issue on gitlab_ |

View File

@ -0,0 +1,15 @@
---
title: Supported Markdown Syntax
tags:
- Development
- Markdown
- Website
- mkdocs
---
# Supported Markdown Syntax
!!! Notice
This page is still being constructed
_This website uses markdown documents to create the pages, please see the [reference guide](https://squidfunk.github.io/mkdocs-material/reference/) for further items that can be used._

View File

@ -0,0 +1,5 @@
# Ansible Roles
| :red_circle: This page is a placeholder for the ansible-roles repo's docs. |
|:---|
| _If you can see this page there has been an error, please report the issue on gitlab_ |

View File

@ -0,0 +1,5 @@
# Gitlab Continuous Integration Templates
| :red_circle: This page is a placeholder for the gitlab-ci repo's docs. |
|:---|
| _If you can see this page there has been an error, please report the issue on gitlab_ |

8
pages/projects/index.md Normal file
View File

@ -0,0 +1,8 @@
---
tags:
- Development
- brand new
---
# No Fuss Computing Projects
## Our Projects

View File

@ -0,0 +1,5 @@
# Python Gitlab Management
| :red_circle: This page is a placeholder for the python-gitlab-management repo's docs. |
|:---|
| _If you can see this page there has been an error, please report the issue on gitlab_ |

13
pages/robots.txt Normal file
View File

@ -0,0 +1,13 @@
User-agent: *
# example: Redirect 301 /oldpage.html /newpage.html
Redirect 301 /wiki/public/article/150225_choose_internet_service /articles/2015/choose_internet_service
Redirect 301 /wiki/syntax /operations/syntax
Redirect 301 /wiki/public/help/mdt/* /wiki/info/*
Redirect 301 /wiki/public/help/mantis/* /wiki/info/*

View File

@ -0,0 +1,72 @@
html .md-social a[title="DockerHub"] {
color: #0DB7ED;
}
html .md-social a[title="Facebook"] {
color: #3B5998;
}
html .md-social a[title="Github"] {
color: #F5F5F5;
}
html .md-social a[title="Gitlab"] {
color: #fc6d26;
}
.docker {
color: #0DB7ED;
}
.facebook {
color: #3B5998;
}
.github {
color: #333;
}
.gitlab {
color: #fc6d26;
}
.tags {
background-color: #4051B5;
border-radius: 10px;
font-size: 12px;
color: white;
padding: 3px 6px;
text-align: center;
}
a.tags:hover {
color: #FFFF00;
}
.tags:link {
color: white;
}
.tags:visited {
color: white;
}
/* Blog Styles */
.mdx-author {
display: flex;
font-size: 13.6px;
}
.mdx-author img {
height: 40px;
border-radius: 100%;
}
.mdx-author p:first-child {
flex-shrink: 0;
margin-right: 16px;
}
.mdx-author p > span {
display: block;
}

3
pages/tags.md Normal file
View File

@ -0,0 +1,3 @@
# tags
Do not edit this file as it is auto generated.

View File

@ -1,3 +1,3 @@
# Welcome to the Wiki
## Wiki Sections

5
pytest.ini Normal file
View File

@ -0,0 +1,5 @@
[pytest]
#junit_suite_name=Unit Test
junit_log_passing_tests=true
#enable_assertion_pass_hook=true
junit_logging=all

7
requirements.txt Normal file
View File

@ -0,0 +1,7 @@
mkdocs-minify-plugin==0.5.0
mkdocs-material-extensions==1.0.3
wheel
mkdocs-material==8.1.7
./custom-plugins/mkdocs-plugin-tags
mkdocs-git-revision-date-localized-plugin==0.11.1
pymdown-extensions==9.1

4
test/requirements.txt Normal file
View File

@ -0,0 +1,4 @@
selenium==3.141.0
pytest==6.2.5
requests==2.27.1

160
test/unit/conftest.py Normal file
View File

@ -0,0 +1,160 @@
import hashlib
import json
import os
import re
import pytest
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
class Data:
def process_browser_log_entry(self, entry):
response = json.loads(entry['message'])['message']
return response
def parse_url(self, url):
request_protocol = re.match("^[http|file]+s?", url).group(0)
url_id = hashlib.md5(bytes(url, 'utf-8')).hexdigest()
if re.match("^http.*", url) is not None:
domain = re.match(r'^([a-z]+[\.|a-z|]+)',url.replace(request_protocol + '://', '')).group(0)
request_path = url.replace(request_protocol + '://','').replace(domain, '')[1:]
elif re.match("^file.*", url) is not None:
domain = 'file'
request_path = url.replace(request_protocol + '://','')[1:]
request_path = request_path.replace(self.suffux_path[1:], '')
return {
'url_id': url_id,
'url': url,
'request_protocol': request_protocol,
'domain': domain,
'request_path': request_path
}
def __init__(self):
caps = DesiredCapabilities.CHROME
caps['goog:loggingPrefs'] = {'performance': 'ALL'}
chrome_options = Options()
chrome_options.add_argument("no-sandbox")
chrome_options.add_argument("headless")
chrome_options.add_argument("start-maximized")
chrome_options.add_argument("window-size=1900,1080");
self.driver = webdriver.Chrome(desired_capabilities=caps, options=chrome_options)
self.urls = []
self.suffux_path = os.path.realpath('./build')
self.urls += [os.path.join(dp, f) for dp, dn, fn in os.walk(os.path.expanduser('./build')) for f in fn if f.endswith('.html')]
data = {
'page_load_resource_links': {},
'source_files': [],
'hyperlinks': {}
}
for check_file in self.urls:
check_url = 'file://' + self.suffux_path + check_file.replace('./build','')
source_file = check_file.replace('./build','')[1:]
if source_file not in data['source_files']:
data['source_files'].append(source_file)
self.driver.get(check_url)
links = self.driver.find_elements_by_css_selector("a")
for link in links:
link_location = link.location
url = link.get_attribute('href')
link = self.parse_url(url)
hyperlink_source_file = {'name': source_file, 'location': link_location}
if link['url_id'] in data['hyperlinks']:
data['hyperlinks'][link['url_id']]['source_files'].append(hyperlink_source_file)
else:
link['source_files'] = [ hyperlink_source_file ]
data['hyperlinks'][link['url_id']] = link
events = [self.process_browser_log_entry(entry) for entry in self.driver.get_log('performance')]
for entry in events:
if entry['method'] == 'Network.requestWillBeSent':
http_status = str([response['params']['response']['status'] for response in events if response['method'] == 'Network.responseReceived' and response['params']['requestId'] == entry['params']['requestId']]).replace('[', '').replace(']', '')
url = str(entry['params']['request']['url'])
url_id = hashlib.md5(bytes(url, 'utf-8')).hexdigest()
if re.match("^http|file.*", url) is not None:
source_file_line_number = ''
if 'lineNumber' in entry['params']['initiator']:
source_file_line_number = str(entry['params']['initiator']['lineNumber'])
request_protocol = re.match("^[http|file]+s?", url).group(0)
if re.match("^http.*", url) is not None:
domain = re.match(r'^([a-z]+[\.|a-z|]+)',url.replace(request_protocol + '://', '')).group(0)
request_path = url.replace(request_protocol + '://','').replace(domain, '')[1:]
elif re.match("^file.*", url) is not None:
domain = 'file'
request_path = url.replace(request_protocol + '://','')[1:]
if url_id in data['page_load_resource_links']:
data['page_load_resource_links'][url_id]['source_files'].append({'name': source_file, 'line_number': source_file_line_number, 'http_status': http_status})
else:
data['page_load_resource_links'][url_id] = {'url': url, 'request_protocol': request_protocol, 'domain': domain, 'request_path': request_path, 'source_files': [ {'name': source_file, 'line_number': source_file_line_number, 'http_status': http_status} ]}
self.driver.quit()
self.test_data = data
def __del__(self):
self.driver.quit()
print("\n"+'Creating test data')
print("\n\ntest data:\n" + json.dumps(Data().test_data, indent=2, default=str))

105
test/unit/main_test.py Normal file
View File

@ -0,0 +1,105 @@
import pytest
import os
from conftest import Data
class Test:
data = Data()
def setup_class(self):
#copy data so it can be used
self.source_files = self.data.test_data['source_files']
def setup_method(self):
pass
@pytest.mark.parametrize(
argnames='data',
argvalues=[link for url_id, link in data.test_data['hyperlinks'].items() if link['request_protocol'][0:4] =='http'],
ids=[url_id for url_id, link in data.test_data['hyperlinks'].items() if link['request_protocol'][0:4] =='http']
)
def test_hyperlink_external_alive_check(self, data):
"""Test hyperlinks that are found within each page of the site.
SSL verification has been disabled as this test only checks if the link is alive and valid.
Args:
data (dict): A dictionary of hyperlinks constructed within conftest.py
"""
from requests import get
from requests import packages
from urllib3.exceptions import InsecureRequestWarning
packages.urllib3.disable_warnings(category=InsecureRequestWarning)
request = get(data['url'], verify=False)
print(str(data) + str(request.status_code))
assert request.status_code == 200, (
f"Hyperlink [{data['url_id']}] to location [{data['url']}] failed,"
f"with status [{request.status_code}].")
@pytest.mark.parametrize(
argnames='data',
argvalues=[link for url_id, link in data.test_data['hyperlinks'].items() if link['request_protocol'][0:4] =='file' and link['request_path'] != ''],
ids=[url_id for url_id, link in data.test_data['hyperlinks'].items() if link['request_protocol'][0:4] =='file' and link['request_path'] != '']
)
def test_hyperlink_internal_alive_check(self, data):
""" Test all internal hyperlinks are valid and the page exists.
This test constructs the actual file path from a found internal (contains file as the protocol) link. After the link is found it is checked against the pages that exist.
Args:
data (list): list of dictionaries containing the urls to test
"""
path_suffix = os.path.realpath('./build')
print('URL Data:' + str(data))
request_path = str(data['request_path'])
if request_path[0:1] == '/':
if request_path[0:1] == request_path:
request_path = 'index.html'
else:
request_path = request_path[1:]
if '#' in request_path:
request_path_split = request_path.split('#')
request_path = str(request_path_split[0])
print('Debug # in path ' + request_path_split[0])
# Reconstruct a valid url. append 'index.html' for paths ending in '/'
if (request_path[len(request_path)-1:] == '/'
and request_path[len(request_path)-5:] != '.html'
):
request_path = str(request_path) + 'index.html'
elif (request_path[len(request_path)-1:] != '/'
and request_path[len(request_path)-5:] == '.html'
):
request_path = request_path
print('DEBUG consructed path:' + request_path)
assert request_path in self.source_files, (
f"hyperlink [{str(data['request_path'])}] that was reconstructed to[{request_path}] "
"does not exist. This link was found "
f"within the following pages [{str(data['source_files'])}]"
)
def teardown_method(self):
pass
def teardown_class(self):
del self.data

65
test/unit/privacy_test.py Normal file
View File

@ -0,0 +1,65 @@
import pytest
from conftest import Data
class Test:
data = Data()
def setup_method(self):
self.approved_external_requests = {
'gitlab.com': [
'api/v4/projects/nofusscomputing%2Finfrastructure%2Fwebsite',
'uploads/-/system/user/avatar/4125177/avatar.png'
]
}
@pytest.mark.parametrize(
argnames='data',
argvalues=[link for url_id, link in data.test_data['page_load_resource_links'].items() if link['request_protocol'][0:4] =='http'],
ids=[url_id for url_id, link in data.test_data['page_load_resource_links'].items() if link['request_protocol'][0:4] =='http']
)
def test_page_load_external_requests(self, data):
check_url = data['url']
print(str(data))
assert data['request_protocol'] == 'https', f"Insecure Request to domain [{data['request_path']}] in source files [{data['source_files']}]"
assert data['domain'] in self.approved_external_requests, f"A request is being made to a non-approved domain [{data['domain']}] path [{data['request_path']}] in source files [{data['source_files']}]"
assert data['request_path'] in self.approved_external_requests[data['domain']], f"A request is being made to a non-approved path [{data['request_path']}] on domain [{data['domain']}] in source files [{data['source_files']}]"
@pytest.mark.parametrize(
argnames='data',
argvalues=[link
for url_id, link in data.test_data['hyperlinks'].items()
if link['request_protocol'][0:4] =='http'],
ids=[url_id for url_id, link in data.test_data['hyperlinks'].items() if link['request_protocol'][0:4] =='http']
)
def test_ssl_hyperlinks_only(self, data):
"""Ensure all hyperlinks from our site are to https ONLY
Tests to ensure that all hyperlinks from our site are to 'https' links only. Any link that is not secure will fail this test.
Args:
data (dict): A dictionary of hyperlinks constructed within conftest.py
"""
print(str(data))
assert data['request_protocol'] == 'https', (
f"Hyperlink [{data['url_id']}] to location [{data['url']}] is insecure"
)
def teardown_method(self):
pass
def teardown_class(self):
del self.data

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z"/></svg>

After

Width:  |  Height:  |  Size: 663 B

View File

@ -0,0 +1,31 @@
{% extends "base.html" %}
{% block content %}
{{ page.content }}
{% set blog_posts = [] %}
{% for page in nav.pages %}
{% if page.url.startswith(config.extra.blog.dir) and page.meta.date is defined %}
<!-- or "" suppresses "None" output-->
{{ blog_posts.append( page ) or "" }}
{% endif %}
{% endfor %}
{% for page in (blog_posts|sort(attribute="meta.date", reverse=True))[:config.extra.blog.list_length] %}
<h2><a href="{{ page.url|url }}">{{ page.title }}</a></h2>
<hr>
{% include "partials/blog_metadata.html" %}
<p>
{{ page.meta.description }}
</p>
<!-- Use a hidden p tag to provide a preview -->
{% if config.extra.blog.extended_preview %}
<a href="{{ page.url|url }}#more">
<span class="twemoji">
{% include ".icons/octicons/arrow-right-24.svg" %}
</span>
Continue reading
<hr>
</a>
{% endif %}
{% endfor %}
{% endblock %}

View File

@ -0,0 +1,8 @@
{% extends "base.html" %}
{% block content %}
<h1>{{ page.title }}</h1>
{% include "partials/blog_metadata.html" %}
<hr>
{{ page.content }}
{% endblock %}

View File

@ -0,0 +1,7 @@
<a href="{{ page.url|url }}">
<span class="twemoji">
{% include ".icons/octicons/arrow-right-24.svg" %}
</span>
Continue reading
<hr>
</a>

View File

@ -0,0 +1,32 @@
<aside class="mdx-author">
{% if config.extra.blog.author_image is defined %}
<p>
<img alt={{ config.extra.blog.author }} src={{ config.extra.blog.author_image }}>
</p>
{% endif %}
<p>
<span>
{% if config.extra.blog.author %}
<strong>{{ config.extra.blog.author }}</strong>
·
{% endif %}
{% include "partials/blog_social.html" %}
</span>
<span>
<span class="twemoji">
{% include ".icons/octicons/calendar-24.svg" %}
</span>
{{ page.meta.date.strftime("%Y-%m-%d") }} ·
{% if page.meta.git_revision_date_localized %}Updated {{ page.meta.git_revision_date_localized.replace("\n", "").replace("\r", "") }} <br>{% endif %}
<span class="twemoji">
{% include ".icons/octicons/clock-24.svg" %}
</span>
<!--Min reading time is 1 minute-->
{% set read_time = page.content | wordcount // config.extra.blog.words_read_per_minute|default(300, true) %}
{% if read_time == 0 %}
{% set read_time = 1 %}
{% endif %}
{{ read_time }} min read
</span>
</p>
</aside>

View File

@ -0,0 +1,17 @@
{% if config.extra.social %}
{% set ns = namespace() %}
{% for social in config.extra.social %}
{% set title = social.name %}
{% if not title and "//" in social.link %}
{% set _,url = social.link.split("//") %}
{% set title = url.split("/")[0] %}
{% endif %}
{% if ns.line_break is defined %}
{{ ns.line_break }}
{% endif %}
<a href="{{ social.link }}" target="_blank" rel="noopener" title="{{ title | e }}" class="twemoji">
{% include ".icons/" ~ social.icon ~ ".svg" %}
</a>
{% set ns.line_break = " · " %}
{% endfor %}
{% endif %}

View File

@ -0,0 +1,14 @@
{#-
This file was automatically generated - do not edit
-#}
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
{% include "partials/copyright.html" %}
{% if config.extra.social %}
{% include "partials/social.html" %}
{% endif %}
</div>
</div>
</footer>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{%- for file in pages -%}
{% if not file.page.is_link %}
<url>
<loc>{% if file.page.canonical_url %}{{ file.page.canonical_url|e }}{% else %}{{ file.page.abs_url|e }}{% endif %}</loc>
{% if file.page.meta.git_revision_date_localized %}<lastmod>{{ file.page.meta.git_revision_date_localized.replace("\n", "").replace("\r", "").replace('<span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date">', '').replace('</span>','') }}</lastmod>{% endif %}
<changefreq>weekly</changefreq>
</url>
{%- endif -%}
{% endfor %}
</urlset>

View File

@ -1,109 +0,0 @@
====== Choosing an Internet Service ======
<wrap center info 90%>This article has been targeted towards the common mass who dont understand the technical details and considerations for choosing an Internet package.</wrap>
The Internet has now become a mainstream item within the average Australian home. The Internet has become so ingrained within our daily lives that for those of us that were around when the Internet was born have actually forgotten what life was like without it. I remember when I was growing up that if we wanted to learn about something you would go to the local library or to a family/friends house to look through their Encyclopaedia Britannica which more often than not was at least five years out of date. Believe it or not that was only 15 to 20 years ago.
I would consider myself lucky in the regard we were introduced to the Internet in high school way back when [[http://webcrawler.com|Web Crawler]] was what Google is today and the only thing of any value was searching for random phrases like <del>porn</del> homework answers. It was a very new concept to have the Internet or even access, which was often met with confusion and a sheer lack of knowledge. Being part of that generation we grew with the Internet and became the first generation to learn about it, and to the behest of the generations before us who were either left in the dark or were very slow on the uptake.
Now if I haven't lost you already and hopefully by the end of this article I have been able to provide you with more insight on being able to choose an Internet service from an ISP with a little more of an understanding of the technology behind that Internet connection.
Below I will cover a little of the technical details and hopefully bringing into perspective, so you can better understand what is being explained to you. To do this I will use the flow of water methodology.
===== Bandwidth =====
Bandwidth is the actual speed of your Internet connection and its unit of measure is bits per second. So basically if you think water pipe, only so much water will flow through a water pipe but if you increase its pressure you will receive more water. For the actual Internet connection different technology is used to essentially achieve the same thing.
===== Quota =====
This is how much you can download and/or upload from the Internet. Its unit of measure is bytes. Think of a water tank, larger the tank the more quota you have available. This will be set by your ISP and 9 times out of 10 will be limited. Every Time you connect to the Internet you are using this available quota.
===== Theory =====
Now to fully understand the quota and bandwidth I will have to cover a little bit of computer theory. Computers compute information by doing mathematical equations. The only numbers a computer recognizes are [[wp>Binary_number|Base 2]]. Base 2 numbering means it uses the first 2 numbers, being zero and one. In common computer terms this is called binary which is always in the computer world as a minimum 8 bits wide i.e. 01010101. Each digit of the number is a bit, four bits to a nibble and 2 nibbles to a byte. Unlike the English language; Binary is read from right to left and each one or zero, within a binary number is actually counting from 1 through to 255, which takes 8 bits of information. Binary is a [[wp>Notation|notational reference system]], so starting from right to left each digit represents another number, the first number being one, each number after that is double the number before it so the next number would be two, then four, eight, 16, 32, 64 finishing with the leftmost digit as 128.
Confusing? Not really, when the bit is zero you don't add each notated number, you only add if the bit is one. So 0001 would be one, 0010 would be two, 0011 is three and so on.
Communication between different components or computers (network or The Internet) is measured in bits per second or bps (lowercase). Computers store data in bytes or B (uppercase). Each unit of measure has multipliers like normal numbers, computers use the following multipliers, Kilo (K) for thousands, Mega (M) for millions, Giga (G) for billions, Tera (T) for trillions and Peta (P) for quintillion's. The conversion from bits to bytes is a division of 8.
So why use different units of measure for the same data? simply put, computers are electronic devices which communicate with an electronic signal with 1 being on and zero being off; basically the signal is either on or off. So the transmission of data is serial or singular and storage is in parallel or stored in octets which is a group of bits. Hence bits and bytes. generally you will find lowercase letters are used to represent bits and uppercase letters are used for bytes.
===== Connection types =====
The common Internet connection types in Australia are ADSL or via the Mobile network. Very rarely used but still available if you look hard enough dial-up. and the newest and greatest is the National Broadband Network or NBN. With the exception of the NBN all of the above connection types will have a max speed. This max speed is a theoretical maximum speed and there are many factors which generally slow down your connection. All connection methods have a technological peak, which basically means there is no known way to improve that technology any further.
==== Dial-Up ====
[[wp>56_kbit/s_modem|Dial-Up]] Internet was the first mainstream way to connect to the Internet. For this to happen you needed an active phone line, a computer with a MODEM (short for modulator/demodulator) and you would plug a phone cable into your computer, which would dial a number to connect to the Internet. At its technological peak the max theoretical download speed was 56kb and approx 33kb up. Dial-up modems are generally part of the computer. The downside to Dial-up is that it relies on good quality phone cables, basically if you have a bad phone line you will have unstable and slower Internet. Dial-up also suffers from signal attenuation which means the further away from the telephone exchange the lower the speed your Internet is going to be. The biggest downside to having Dial-up Internet is that you can either be connected to the Internet or on the phone, not both.
==== ADSL ====
[[wp>Asymmetric_digital_subscriber_line|Asynchronous Digital Subscriber Line]] or ADSL is the most common Internet in Australia. This is also commonly referred to as broadband Internet, the biggest difference between ADSL and Dial-up is that it is always on. When ADSL first arrived it had a speed of 1.5mb, which was a massive increase over Dial-up. As ADSL evolved its speed increased, when this occurred its name slightly changed to suit the technological level, ADSL1, ADSL2 and finishing with ADSL2+ which has a maximum theoretical download speed of 24Mb and 2Mb Up. An ADSL connection like dial-up Internet requires a modem and suffers with the same line issues. Where ADSL is an improvement over Dial-up is that you can still make telephone calls when you are have an active Internet connection for this you will need a line filter. To utilise an ADSL connection you require an ADSL modem.
==== Mobile Network ====
Again this method of connecting to the Internet has been around for a while and with the invention of the smartphone has become quite a common way to “surf the Web”. 4th generation or 4G being the current technology has a max theoretical speed of 50Mb. The connection speed is shared amongst all users utilizing that mobile tower to connect to the Internet, and if you dont have good mobile reception you will not have a stable Internet connection.
==== NBN ====
The National broadband network or NBN as it is known is the new way to connect to the Internet. The NBN unlike Dial-up or ADSL does not use a phone line to connect to the Internet. The NBN uses [[wp>Optical_fiber_cable|fiber optic cable]], which uses light not electricity to communicate. Fiber optic cable can be thinner than a human hair. Fiber Optic cable, or fiber networks have one purpose; transmit data, not voice or electronic signals like a [[wp>Copper_wire_and_cable|copper cable]]. Since fiber is designed for networking you require a router to connect to it. A router looks very similar to an ADSL modem. Unlike the other Internet connection methods above, communication in either direction is the same. Within Australia this is not the case, and for whatever reason you will find most NBN capable ISPs will still have packages with different upload and download speeds. Fiber networks are very mature and their speed is actual, not theoretical maximums and are capable of transmitting data at 10gbps. Using that speed for connecting to the Internet is overkill and you will find that most ISPs offer no connection speed above 100mbps at the moment.
===== Choosing a suitable Internet service =====
Now hopefully by now I have given you a little better understanding of the connection types and terminology in relation to choosing an Internet service; believe me it is still a cumbersome task. Yes there are a lot of things to consider. From a technical standpoint the following should be taken into account:
* availability in your area
* what you will be using the Internet for
* bang for buck
==== Availability in Your Area ====
For a majority of Australians, ADSL is the best Internet service you will have available. The most annoying thing when trying to connect an ADSL service is the wait time. This wait time is due to the requirement for a technician to have to go to your local [[wp>Telephone_exchange|telephone exchange]] to actually connect you, that is if there are spare ports available in the exchange. If though, you can get the NBN, go for it. Seriously you are being foolish if you don't. Why? the NBN is an actual data network and the speed you pay for is what you get, overall the NBN is more reliable.
==== What You Will be Using the Internet For? ====
Most website designers will aim for a page load time of within one-two seconds; Even now how website technology is becoming more media focused, I would not recommend any speed lower that ADSL2+(24mbps) or 12mbps for the NBN. Why the different speeds? Remember that ADSL is a theoretical maximum, on average. Most ADSL users will have an actual connection speed of between 8mbps-22mbps and the NBN is actual speed. Anything faster than this for just “surfing the web” is overkill, and a waste of money. Where would you require a faster connection speed? if you start to use services like netflix and/or Foxtel[[wp>IPTV| IPTV]] to stream videos. Having more than ~5 users, may also be a consideration for a speed increase.
How much quota do you need? if you have had the Internet before, go look at your previous bills, most of the time you will see what you used for the billing period, use this figure as a basis to guesstimate how much quota you are going to need. If you have never had an Internet package before then as a guide I would recommend nothing less than 10GB quota per month for the average light Internet user. I can't emphasize this enough, please do your research before you take this as gospel. Most people do know someone who <del>“knows boats”</del> would be able to assist in assessing how much quota you may require.
==== Bang for Buck ====
Read the fine print………. READ THE FINE PRINT……… oh, did I mention fine print? Every Internet package has fine print. This fine print will cover things like:
* what is unmetered((this is a category of sites that you can use without it being counted towards your quota.))
* how much quota you have, read carefully some ISPs will charge by the megabyte if you go over
* what happens when you reach your quota limit (good ISPs will shape your speed ((slow your Internet connection speed)))
* what you should not do with your Internet package (some ISPs wont allow you to host your own website.)
* contract period
* exit fees associated with leaving your contract early
* fees associated with moving house
* support
* your responsibilities
==== Further Considerations ====
**“Unlimited Packages”** Some ISPs do offer “unlimited packages”. Please read the fine print so you can get the definition of unlimited as sometimes unlimited does not exactly mean unlimited. Some ISPs have been know to use peak and off-peak times, during peak you will have a quota and off peak is “unlimited”.
A big consideration for unlimited or large packages with lower download speeds is calculating what you could actually download in that billing period. This is a simple task and would use the following formula.
(Billing Period Days x seconds in day) × max download speed in bits ÷ 8 = max bytes for period
Example:\\
Billing Period days = 30\\
Second in one day = 86,400\\
Max download speed = 22,000,000\\
\\
( 30 x 86,400 ) × 22,000,000 ÷ 8 = 7,128,000,000,000Bytes or 7.128TB
So with the example above a package with a quota above 7.128TB with a download speed of 22mb would be a waste of money.
**Bundled Items** We have all seen and heard of them.
//"Select our Internet Package for $120 a month and we will give you a telephone with free calls, 200gb of download and if you sign up for a 24month contract we will throw in a free iPad"//
With the exception of a modem-if you don't have one; be very careful of falling into this trap. These "Bundled Packages" are plain and simply designed to get your business. Believe me when I say you can get all of this for a hell of a lot cheaper. Again __READ THE FINE PRINT__ and calculate the cost of the whole contract period including any hidden fees and you will find that these are quite expensive packages. A simple way to test these packages is how much is thrown in, the more free stuff that is included outside of the Internet package, then the more desperate they are for your business. Listen to your gut and the age old saying //"If it's too good to be true, than it probably is"//. Once in my life time I have seen one of these packages and it was too good to be true, but turned out to actually be worth while in the long run, again this was more than likely a "once in a lifetime good package"
**Naked ADSL** works exactly the same as normal ADSL Internet but you dont have to pay for the phone line as it is included in the “Naked ADSL package” if you dont use the telephone much or you are utilizing VOIP choosing one of these packages can save you some money. Like ADSL this is only available in certain areas, Please confirm with your ISP for availability.
**Support** It's common practice for ISPs to outsource the first stage of customer support. This problem is a plague that needs to be truncated from the IT((Information Technology)) industry. Why? 9 times out of 10 the person on the other end of the phone either does not have a good grasp on our native language or has an accent that is so thick you can not understand them, which makes it very difficult for the hearing impaired. When this occurs the assistance you called for doesn't happen, and is escalated to someone else in the chain who may or may not be able to help you. In the end you are stuck with no internet and built up frustration from a 1:30h phone call.\\
There are however some ISPs who are old school. they will give you a callback after being on hold for a few minutes and if your assistance call needs to be escalated will either call you back or give a detailed handover to the next person you need to speak to. bottom line if you are not technically minded than ask around to find a good ISP who can assist you and be wary of outsourced tech support.
===== Conclusion =====
Lets face it, The Internet has made our lives easier. You can now sit in your lounge room and read this long, very mind numbing article on how to choose a better Internet Service, do your Banking, Pay Bills, Buy Goods, <del>look at porn</del> and best of all place video calls to family and friends. What will the future hold? Who knows but given how far technology has evolved in the last 50 years, I think the next 50 will yield even more from this simple little invention courtesy of [[wp>darpa|DARPA]].
Like this article? Please consider buying me a coffee. Donations can be accepted via PayPal via our store at [[NFC>product-category/donation/|No Fuss Computing]]
Some ISPs in Australia:
- [[http://internode.on.net|Internode]]
- [[http://iinet.net.au|IINet]]
- [[http://westnet.com.au|WestNet]]
<wrap center important 90%>The information contained within this article based on the opinion of the author and is provided for informational purposes only. Before utilizing any information or advice from this article you are encouraged to do your own research</wrap>