Compare commits

...

99 Commits

Author SHA1 Message Date
6f92a6738d feat: Add umami
All checks were successful
Build Docker / Build Main Image (push) Successful in 37s
Build Docker / Build SLDs Image (push) Successful in 44s
2023-12-20 17:00:30 +11:00
a628be259d feat: Add analytics to tribes page
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 19s
Build Docker / Build Main Image (push) Successful in 21s
2023-12-13 15:17:18 +11:00
09ef9857d9 feat: Dynamically inject analytics into head of sites
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 19s
Build Docker / Build Main Image (push) Successful in 21s
2023-12-13 15:04:28 +11:00
bb10db2f00 feat: Add analytics to plain html 2023-12-13 15:00:12 +11:00
f65cbdb8e0 fix: Make alt tlds clickable
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 17s
Build Docker / Build Main Image (push) Successful in 20s
2023-12-13 10:54:45 +11:00
5a8d185837 feat: Add alternative tlds to account page
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 21s
Build Docker / Build Main Image (push) Successful in 22s
2023-12-13 10:52:40 +11:00
3c6829826f fix: Stop duplicating A and TLSA records and fix alts
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 19s
Build Docker / Build Main Image (push) Successful in 21s
2023-12-12 14:51:38 +11:00
f68186314b fix: Clone new TLSA and fix some typos
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 19s
Build Docker / Build Main Image (push) Successful in 21s
2023-12-12 14:43:05 +11:00
5980edbf89 feat: Start clone to alts function
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 36s
Build Docker / Build Main Image (push) Successful in 39s
2023-12-12 14:33:23 +11:00
80594ca9ac fix: Use A record instead of Alias
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 18s
Build Docker / Build Main Image (push) Successful in 19s
2023-11-23 14:01:10 +11:00
35322653a0 fix: Don't require crypto addresses
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 20s
Build Docker / Build Main Image (push) Successful in 20s
2023-11-23 13:53:00 +11:00
27039657c4 fix: Add trailing slash to tribe members
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 18s
Build Docker / Build Main Image (push) Successful in 19s
2023-11-22 13:17:45 +11:00
8ecc960c58 feat: Allow tribe renaming
All checks were successful
Build Docker / Build Main Image (push) Successful in 17s
Build Docker / Build SLDs Image (push) Successful in 19s
2023-11-22 13:16:36 +11:00
bd149f012e feat: Allow underscores in tribe names
All checks were successful
Build Docker / Build Main Image (push) Successful in 18s
Build Docker / Build SLDs Image (push) Successful in 19s
2023-11-22 13:12:38 +11:00
74ab088461 feat: Add delete tribe function
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 18s
Build Docker / Build Main Image (push) Successful in 20s
2023-11-22 13:07:55 +11:00
cd43dd3dc6 feat: Add initial tribes
All checks were successful
Build Docker / Build Main Image (push) Successful in 19s
Build Docker / Build SLDs Image (push) Successful in 20s
2023-11-22 13:00:04 +11:00
5d70dc862d feat: Start working on tribe feature
All checks were successful
Build Docker / Build Main Image (push) Successful in 19s
Build Docker / Build SLDs Image (push) Successful in 22s
2023-11-21 16:14:20 +11:00
cc62c04e6f fix: Increase contrast for icons
All checks were successful
Build Docker / Build Main Image (push) Successful in 19s
Build Docker / Build SLDs Image (push) Successful in 20s
2023-11-20 12:20:23 +11:00
5964ae5a23 fix: Add spacing for footer and set donate footer to not be absolute
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 19s
Build Docker / Build Main Image (push) Successful in 21s
2023-11-20 12:11:54 +11:00
fabf37d446 fix: Typo in templates list
All checks were successful
Build Docker / Build Main Image (push) Successful in 17s
Build Docker / Build SLDs Image (push) Successful in 18s
2023-11-20 12:01:51 +11:00
b968c90c2f fix: Exclude no data page from redirecting
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 18s
Build Docker / Build Main Image (push) Successful in 20s
2023-11-20 12:00:06 +11:00
fa5915b0df fix: Unreferenced variables if no address given
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 17s
Build Docker / Build Main Image (push) Successful in 19s
2023-11-20 11:54:33 +11:00
b805c3e655 feat: Add new templates with donate footer
All checks were successful
Build Docker / Build Main Image (push) Successful in 19s
Build Docker / Build SLDs Image (push) Successful in 21s
2023-11-20 11:51:44 +11:00
e2522a61d6 feat: Add placeholder documentation
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 19s
Build Docker / Build Main Image (push) Successful in 21s
2023-11-20 11:37:40 +11:00
cd1253d0fd feat: Add more address and logo options
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 18s
Build Docker / Build Main Image (push) Successful in 20s
2023-11-20 11:12:54 +11:00
c69a600aa1 feat: Add footer to render for template testing
All checks were successful
Build Docker / Build Main Image (push) Successful in 21s
Build Docker / Build SLDs Image (push) Successful in 20s
2023-11-20 10:44:26 +11:00
2c419d73a2 feat: Add function to allow for template testing
All checks were successful
Build Docker / Build Main Image (push) Successful in 21s
Build Docker / Build SLDs Image (push) Successful in 20s
2023-11-19 12:21:43 +11:00
8f1b141828 feat: Remove slash from HNSChat name before saving
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 19s
Build Docker / Build Main Image (push) Successful in 20s
2023-11-18 19:27:05 +11:00
1c0e0059c1 feat: Update page titles
All checks were successful
Build Docker / Build Main Image (push) Successful in 20s
Build Docker / Build SLDs Image (push) Successful in 20s
2023-11-18 19:15:28 +11:00
c7e38a7f22 feat: Add empty site page
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 18s
Build Docker / Build Main Image (push) Successful in 21s
2023-11-18 19:05:50 +11:00
07eb15bd0c fix: Increase address text box size to fit content
All checks were successful
Build Docker / Build Main Image (push) Successful in 18s
Build Docker / Build SLDs Image (push) Successful in 19s
2023-11-18 18:40:03 +11:00
3e9ff9d916 feat: Add HIP2 Display toggle
All checks were successful
Build Docker / Build Main Image (push) Successful in 19s
Build Docker / Build SLDs Image (push) Successful in 20s
2023-11-18 18:36:18 +11:00
743a8d6916 feat: Add blank template and footer part
All checks were successful
Build Docker / Build Main Image (push) Successful in 18s
Build Docker / Build SLDs Image (push) Successful in 19s
2023-11-18 17:59:28 +11:00
d5e9100634 feat: Add 2 new templates without card backgrounds
All checks were successful
Build Docker / Build Main Image (push) Successful in 19s
Build Docker / Build SLDs Image (push) Successful in 19s
2023-11-18 16:09:54 +11:00
f2801f5660 fix: Updated template comments
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 17s
Build Docker / Build Main Image (push) Successful in 19s
2023-11-18 15:39:50 +11:00
ed2994bf89 feat: Add city html template
All checks were successful
Build Docker / Build Main Image (push) Successful in 18s
Build Docker / Build SLDs Image (push) Successful in 20s
2023-11-18 15:38:00 +11:00
e1e485e619 feat: Add uptime to footer
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 19s
Build Docker / Build Main Image (push) Successful in 20s
2023-11-18 15:10:42 +11:00
5438235144 feat: Hide address div if user has addresses
All checks were successful
Build Docker / Build Main Image (push) Successful in 23s
Build Docker / Build SLDs Image (push) Successful in 27s
2023-11-18 14:44:06 +11:00
d2b78ea6cf fix: Edit page crash when no template saved
All checks were successful
Build Docker / Build Main Image (push) Successful in 17s
Build Docker / Build SLDs Image (push) Successful in 19s
2023-11-18 13:32:37 +11:00
c2d4a36da0 fix: Typo class instead of style
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 17s
Build Docker / Build Main Image (push) Successful in 19s
2023-11-18 13:30:03 +11:00
eba3b5faca fix: Colour for text outside cards
All checks were successful
Build Docker / Build Main Image (push) Successful in 18s
Build Docker / Build SLDs Image (push) Successful in 19s
2023-11-18 13:28:28 +11:00
ca10141843 feat: Add option for selecting template
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 19s
Build Docker / Build Main Image (push) Successful in 19s
2023-11-18 13:21:38 +11:00
4a21cf9a5a fix: Overriding avatar didn't update DNS record
All checks were successful
Build Docker / Build Main Image (push) Successful in 19s
Build Docker / Build SLDs Image (push) Successful in 20s
2023-11-18 12:10:37 +11:00
268721555c fix: Typo in file name
All checks were successful
Build Docker / Build Main Image (push) Successful in 17s
Build Docker / Build SLDs Image (push) Successful in 18s
2023-11-18 11:57:20 +11:00
d879aa32d6 fix: Cleanup file name on upload
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 19s
Build Docker / Build Main Image (push) Successful in 21s
2023-11-18 11:54:25 +11:00
eb53b955b8 feat: Add address validation to try to stop typos
All checks were successful
Build Docker / Build Main Image (push) Successful in 19s
Build Docker / Build SLDs Image (push) Successful in 19s
2023-11-18 11:47:28 +11:00
253b202a5f fix: Update varo with avatar edit
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 20s
Build Docker / Build Main Image (push) Successful in 21s
2023-11-18 11:39:07 +11:00
40a794c0d4 feat: Add image uploading
All checks were successful
Build Docker / Build Main Image (push) Successful in 20s
Build Docker / Build SLDs Image (push) Successful in 21s
2023-11-18 00:25:59 +11:00
cb6dda7fca feat: Add error page
All checks were successful
Build Docker / Build Main Image (push) Successful in 22s
Build Docker / Build SLDs Image (push) Successful in 27s
2023-11-17 23:36:15 +11:00
25e546d7c5 fix: Shorten metadata description
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 17s
Build Docker / Build Main Image (push) Successful in 19s
2023-11-17 13:24:27 +11:00
f1da43fbce feat: Add page metadata for social embeds
All checks were successful
Build Docker / Build Main Image (push) Successful in 18s
Build Docker / Build SLDs Image (push) Successful in 20s
2023-11-17 13:21:38 +11:00
7e5235efb8 fix: Update domain verification
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 18s
Build Docker / Build Main Image (push) Successful in 20s
2023-11-17 13:12:33 +11:00
8c895eddea fix: Update no domain data to use False instead of empty string
All checks were successful
Build Docker / Build Main Image (push) Successful in 19s
Build Docker / Build SLDs Image (push) Successful in 20s
2023-11-17 13:06:43 +11:00
f5c610b5cf fix: Add donate to mobile view
All checks were successful
Build Docker / Build Main Image (push) Successful in 19s
Build Docker / Build SLDs Image (push) Successful in 21s
2023-11-17 13:00:55 +11:00
4a0f17f1c8 fix: Lowercase domain for signup
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 16s
Build Docker / Build Main Image (push) Successful in 17s
2023-11-17 10:43:46 +11:00
cb055cc13e fix: Update domain to block starting with _
All checks were successful
Build Docker / Build Main Image (push) Successful in 18s
Build Docker / Build SLDs Image (push) Successful in 21s
2023-11-17 10:43:23 +11:00
abf9f946d0 fix: Cleaned up readme
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 18s
Build Docker / Build Main Image (push) Successful in 20s
2023-11-16 15:52:59 +11:00
9425851810 feat: Add hnschat to index info
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 17s
Build Docker / Build Main Image (push) Successful in 18s
2023-11-16 15:41:16 +11:00
727ed07304 fix: Add temp donate address
All checks were successful
Build Docker / Build Main Image (push) Successful in 18s
Build Docker / Build SLDs Image (push) Successful in 19s
2023-11-16 15:38:40 +11:00
7db16b7e85 feat: Add default site colours
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 19s
Build Docker / Build Main Image (push) Successful in 20s
2023-11-16 15:31:45 +11:00
d54d91f6a4 fix: Site data autocreation when visiting an unclaimed domain
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 19s
Build Docker / Build Main Image (push) Successful in 20s
2023-11-16 15:25:48 +11:00
0ca9a8ac91 fix: Catch errors fir no records returned via API
All checks were successful
Build Docker / Build Main Image (push) Successful in 20s
Build Docker / Build SLDs Image (push) Successful in 19s
2023-11-16 15:11:54 +11:00
f49a14c5b2 fix: Add ALIAS and TLSA for sites
All checks were successful
Build Docker / Build Main Image (push) Successful in 20s
Build Docker / Build SLDs Image (push) Successful in 18s
2023-11-16 14:55:38 +11:00
2d152de2f4 feat: Add HNSChat linking
All checks were successful
Build Docker / Build Main Image (push) Successful in 20s
Build Docker / Build SLDs Image (push) Successful in 53s
2023-11-16 14:12:24 +11:00
e5a0560f2c feat: Add ssl redirect
All checks were successful
Build Docker / Build Main Image (push) Successful in 18s
Build Docker / Build SLDs Image (push) Successful in 19s
2023-11-16 13:05:46 +11:00
ee435a6e1d fix: Error loading site editor
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 17s
Build Docker / Build Main Image (push) Successful in 19s
2023-11-16 12:56:34 +11:00
935d534e24 feat: Add email to city and cleanup display
All checks were successful
Build Docker / Build Main Image (push) Successful in 20s
Build Docker / Build SLDs Image (push) Successful in 19s
2023-11-16 12:52:12 +11:00
8067c33a38 fix: Remove contact button borders on mobile
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 19s
Build Docker / Build Main Image (push) Successful in 20s
2023-11-15 23:02:42 +11:00
f79730387e fix: Remove borders on contact buttons
All checks were successful
Build Docker / Build Main Image (push) Successful in 17s
Build Docker / Build SLDs Image (push) Successful in 19s
2023-11-15 22:59:40 +11:00
28e325da32 fix: Home link not visible on mobile
All checks were successful
Build Docker / Build Main Image (push) Successful in 19s
Build Docker / Build SLDs Image (push) Successful in 19s
2023-11-15 22:56:47 +11:00
6616e27ced fix: Home screen spacing
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 17s
Build Docker / Build Main Image (push) Successful in 18s
2023-11-15 22:55:08 +11:00
bbb47144f4 feat: Add home page info
All checks were successful
Build Docker / Build Main Image (push) Successful in 37s
Build Docker / Build SLDs Image (push) Successful in 37s
2023-11-15 22:51:30 +11:00
5be0abeccd feat: Add logos for site info and addresses
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 19s
Build Docker / Build Main Image (push) Successful in 21s
2023-11-15 22:08:49 +11:00
ffc0a2ba9a fix: Remove any quotes from error message
All checks were successful
Build Docker / Build Main Image (push) Successful in 18s
Build Docker / Build SLDs Image (push) Successful in 19s
2023-11-15 21:35:59 +11:00
f246b9d033 fix: Update error message on website load fail
All checks were successful
Build Docker / Build Main Image (push) Successful in 19s
Build Docker / Build SLDs Image (push) Successful in 18s
2023-11-15 21:32:10 +11:00
a501142f12 fix: Update address layout on other screens
All checks were successful
Build Docker / Build Main Image (push) Successful in 18s
Build Docker / Build SLDs Image (push) Successful in 19s
2023-11-15 21:30:23 +11:00
178b8ec597 feat: Hide addresses not in use
All checks were successful
Build Docker / Build Main Image (push) Successful in 19s
Build Docker / Build SLDs Image (push) Successful in 18s
2023-11-15 21:27:03 +11:00
ee49e8341c fix: Decrease width of the address section
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 18s
Build Docker / Build Main Image (push) Successful in 19s
2023-11-15 21:23:28 +11:00
d39347515a fix: Align text centre for large screens
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 20s
Build Docker / Build Main Image (push) Successful in 22s
2023-11-15 21:16:02 +11:00
26ba39ae90 fix: Increase image size on large screens
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 18s
Build Docker / Build Main Image (push) Successful in 19s
2023-11-15 21:10:58 +11:00
1a110b1170 fix: Try setting the images directly
All checks were successful
Build Docker / Build Main Image (push) Successful in 19s
Build Docker / Build SLDs Image (push) Successful in 20s
2023-11-15 21:09:03 +11:00
70fc0102d0 fix: Don't limit max px count on image
All checks were successful
Build Docker / Build Main Image (push) Successful in 18s
Build Docker / Build SLDs Image (push) Successful in 19s
2023-11-15 21:00:54 +11:00
2e02d54277 fix: Fix image size
All checks were successful
Build Docker / Build Main Image (push) Successful in 19s
Build Docker / Build SLDs Image (push) Successful in 18s
2023-11-15 20:57:50 +11:00
9e0ae8e98c fix: Image warping on small screen
All checks were successful
Build Docker / Build Main Image (push) Successful in 18s
Build Docker / Build SLDs Image (push) Successful in 18s
2023-11-15 20:52:51 +11:00
8ef4410c55 fix: mobile layout using incorrect logout label
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 18s
Build Docker / Build Main Image (push) Successful in 21s
2023-11-15 20:50:19 +11:00
10d3df6460 feat: More responsive display
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 19s
Build Docker / Build Main Image (push) Successful in 20s
2023-11-15 19:15:10 +11:00
05a67dcb2b fix: Add home link in image
All checks were successful
Build Docker / Build Main Image (push) Successful in 17s
Build Docker / Build SLDs Image (push) Successful in 17s
2023-11-15 18:39:03 +11:00
4f72525009 fix: Increase size for HNS addresses
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 17s
Build Docker / Build Main Image (push) Successful in 19s
2023-11-15 18:36:40 +11:00
8a52f04ccf fix: Error catching for old sites
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 17s
Build Docker / Build Main Image (push) Successful in 19s
2023-11-15 18:28:40 +11:00
8b3e0d4cab feat: Add more colour control
All checks were successful
Build Docker / Build Main Image (push) Successful in 18s
Build Docker / Build SLDs Image (push) Successful in 20s
2023-11-15 18:24:11 +11:00
c5cc90daac fix: Fix copy templates into cities image
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 17s
Build Docker / Build Main Image (push) Successful in 20s
2023-11-15 18:06:44 +11:00
400505d472 feat: Update city page
All checks were successful
Build Docker / Build Main Image (push) Successful in 20s
Build Docker / Build SLDs Image (push) Successful in 20s
2023-11-15 18:03:43 +11:00
771debdc50 feat: Add favicon
All checks were successful
Build Docker / Build Main Image (push) Successful in 16s
Build Docker / Build SLDs Image (push) Successful in 18s
2023-11-15 16:27:27 +11:00
eaa4075a39 feat: Finish adding v2 layout
All checks were successful
Build Docker / Build SLDs Image (push) Successful in 20s
Build Docker / Build Main Image (push) Successful in 22s
2023-11-15 16:24:56 +11:00
3ed4f24e7e feat: Add new layout for account page 2023-11-15 16:00:30 +11:00
0c0a82d5ad feat: Start new page layout 2023-11-15 15:52:44 +11:00
5af1161579 feat: Redirect claim to signup page
All checks were successful
Build Docker / Build Main Image (push) Successful in 18s
Build Docker / Build SLDs Image (push) Successful in 19s
2023-11-09 13:06:58 +11:00
15b62ad29e feat: Add city domain to env
All checks were successful
Build Docker / Build Main Image (push) Successful in 18s
Build Docker / Build SLDs Image (push) Successful in 19s
2023-11-09 12:59:15 +11:00
ec53b5862b feat: Redirect empty domain to main server 2023-11-09 12:51:35 +11:00
51 changed files with 3232 additions and 144 deletions

View File

@@ -56,7 +56,7 @@ jobs:
- name: Build Docker image
run : |
cd sites
cp -r ../templates/* .
cp -r ../templates/ .
cp ../requirements.txt .
echo "${{ secrets.DOCKERGIT_TOKEN }}" | docker login git.woodburn.au -u nathanwoodburn --password-stdin

4
.gitignore vendored
View File

@@ -4,3 +4,7 @@
__pycache__/
*.json
sites/templates/
images/

134
PLACEHOLDERS.md Normal file
View File

@@ -0,0 +1,134 @@
# Template Placeholders
- [Template Placeholders](#template-placeholders)
- [Colours](#colours)
- [Background colour (bg\_colour)](#background-colour-bg_colour)
- [Text colour (text\_colour)](#text-colour-text_colour)
- [Foreground colour (fg\_colour)](#foreground-colour-fg_colour)
- [Parts](#parts)
- [Avatar](#avatar)
- [HNSChat](#hnschat)
- [Location](#location)
- [Email](#email)
- [Footer (footer)](#footer-footer)
- [Text Placeholders](#text-placeholders)
- [Main domain (main\_domain)](#main-domain-main_domain)
- [Data (data)](#data-data)
- [Crypto Address Placeholders](#crypto-address-placeholders)
- [Icons](#icons)
- [Full parts](#full-parts)
- [Address only](#address-only)
## Colours
### Background colour (bg_colour)
Use #000000 for the background colour as the app overwrites this colour
### Text colour (text_colour)
Use #1fffff for the background colour as the app overwrites this colour
### Foreground colour (fg_colour)
Use #f1ffff for the background colour as the app overwrites this colour
## Parts
### Avatar
`avatar` can be used to get the avatar of the user.
If the user doesn't have an avatar this is just
```html
<h1>domain.shakecities/</h1>
```
If the user does have an avatar this is
```html
<img src='avatar-url' width='200vw' height='200vw' style='border-radius: 50%;margin-right: 5px;'>
```
### HNSChat
If the user has a HNSChat name set this will return
```html
<a href='https://hns.chat/#message:username' target='_blank'>
<img src='hns_icon' width='20px' height='20px' style='margin-right: 5px;'>
username/
</a>
```
### Location
If the user has a location set this will return
```html
<img src='location_icon' width='20px' height='30px' style='margin-right: 5px;'>
location
```
### Email
If the user has a email set this will return
```html
<a href='mailto:email@example'>
<img src='email_icon' width='30px' height='20px' style='margin-right: 5px;margin-left:-10px;'>
email@example
</a>
```
### Footer (footer)
This is the Shakecities footer. It will always be the same "Powered by Shakecities"
## Text Placeholders
### Main domain (main_domain)
`main_domain` can be used to get the main domain of the site e.g. shakecities.com
### Data (data)
`data` can be used to get the data of the site.
This is the main body
## Crypto Address Placeholders
### Icons
These are the icons for the crypto addresses.
There are 2 versions of each icon. One with a contrast to the background colour and one without.
These return the path to the image of the icon (eg. `assets/img/HNS.png`)
They are as follows:
- hns_icon
- hns_icon_invert
- btc_icon
- btc_icon_invert
- eth_icon
- eth_icon_invert
### Full parts
These are the full parts for the crypto addresses.
They return both the icon and the address.
For example `hns` returns
```html
<img src='hns_icon' width='20px' height='20px' style='margin-right: 5px;'>hs1...
```
The list of full parts are:
- hns
- btc
- eth
- hns_invert
- btc_invert
- eth_invert
### Address only
These are plain text addresses without the icon.
Eg. `hns_address` returns
```html
hs1...
```
They are as follows:
- hns_address
- btc_address
- eth_address

View File

@@ -7,6 +7,23 @@ Every domain comes enabled with HTTPS via DANE. We have support HIP02 aliases, s
### Template testing
Replace `new` with your template name
```sh
cd <Git-REPONAME>
# Copy template
cp templates/city_template.html templates/city_new.html
# Edit template
# Test site with template
python3 -m pip install -r requirements.txt
python3 template.py city_new
```
Visit http://127.0.0.1:5000/ to view the template
Here is a list of placeholders you can use [PLACEHOLDERS.md](PLACEHOLDERS.md)
### Deployment
```
@@ -16,11 +33,17 @@ services:
image: git.woodburn.au/nathanwoodburn/shakecities:latest
depends_on:
- db
volumes:
- images:/data
environment:
DB_HOST: db
DB_USER: main
DB_PASSWORD: your-db-password
DB_NAME: main
CITY_DOMAIN: exampledomainnathan1
REG_KEY: <your-varo-apikey>
CITY_ALIAS: city.hnshosting.au # ICANN domain that points to the IP for the cities server
MAIN_DOMAIN: cities.hnshosting.au
WORKERS: 2 # number of workers to run (should be 2 * number of cores)
sites:
@@ -32,6 +55,7 @@ services:
DB_USER: main
DB_PASSWORD: your-db-password
DB_NAME: main
MAIN_DOMAIN: cities.hnshosting.au
WORKERS: 2 # number of workers to run (should be 2 * number of cores)
db:
@@ -45,4 +69,5 @@ services:
- db_data:/var/lib/mysql
volumes:
db_data:
images:
```

View File

@@ -33,8 +33,12 @@ def generate_cookie():
# Create a new user
def create_user(email, domain, password):
if len(email) < 4 or len(domain) < 4 or len(password) < 4:
return {'success': False, 'message': 'Invalid email, domain, or password'}
if len(email) < 4:
return {'success': False, 'message': 'Unfortunatly your email is not valid'}
if len(domain) < 4:
return {'success': False, 'message': 'We only allow domains with 4 or more characters'}
if len(password) < 4:
return {'success': False, 'message': 'Your password is not complex enough'}
# Hash password
@@ -52,13 +56,13 @@ def create_user(email, domain, password):
# Check if user exists
if db.search_users(email) != []:
return {'success': False, 'message': 'User already exists'}
return {'success': False, 'message': 'It looks like someone already is using that email address'}
if db.search_users_domain(domain) != []:
return {'success': False, 'message': 'Domain already exists'}
return {'success': False, 'message': 'Someone has already claimed that domain'}
db.add_user(email, domain, hashed_password, token)
return {'success': True, 'message': 'User created', 'token': token}
return {'success': True, 'message': 'Congrats on creating an account', 'token': token}
def validate_token(token):
search = db.search_users_token(token)
@@ -83,15 +87,18 @@ def login(email,password):
# Verify email
search = db.search_users(email)
if search == []:
return {'success': False, 'message': 'Invalid email'}
return {'success': False, 'message': 'Sorry, we couldn\'t find your account<br>Check your email and password'}
user = convert_db_users(search[0])
# Verify password
if not verify_password(password, user['password']):
return {'success': False, 'message': 'Invalid password'}
return {'success': False, 'message': 'Sorry, we couldn\'t find your account<br>Check your email and password'}
# Create a cookie
token = generate_cookie()
user['tokens'].append(token)
# Get the newest 2 tokens
user['tokens'] = user['tokens'][-2:]
# Update user
db.update_tokens(user['id'], user['tokens'])
return {'success': True, 'message': 'Logged in', 'token': token}

50
avatar.py Normal file
View File

@@ -0,0 +1,50 @@
import os
import dotenv
import db
import random
import json
import varo
import re
IMAGE_LOCATION = os.getenv('IMAGE_LOCATION')
if IMAGE_LOCATION == None:
IMAGE_LOCATION = "/data"
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
MAIN_DOMAIN = os.getenv('MAIN_DOMAIN')
if MAIN_DOMAIN == None:
MAIN_DOMAIN = "shakecities.com"
if MAIN_DOMAIN == "127.0.0.1:5000":
MAIN_DOMAIN = f"http://{MAIN_DOMAIN}"
else:
MAIN_DOMAIN = f"https://{MAIN_DOMAIN}"
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
def save_avatar(file,owner):
filename = re.sub(r'[^a-zA-Z0-9.]', '', file.filename).lower()
while os.path.exists(f"{IMAGE_LOCATION}/{filename}"):
filename = f"{random.randint(0,1000000)}-{filename}"
file.save(f"{IMAGE_LOCATION}/{filename}")
user_data = db.get_website_data_raw(owner)
user_data['avatar'] = MAIN_DOMAIN + "/avatar/" + filename
db.update_website_data_raw(owner,json.dumps(user_data))
varo.update_avatar(user_data['avatar'],owner)
return filename
def clear(owner):
user_data = db.get_website_data_raw(owner)
filename = user_data['avatar'].split('/')[-1]
if filename != "":
os.remove(f"{IMAGE_LOCATION}/{filename}")
user_data['avatar'] = ""
db.update_website_data_raw(owner,json.dumps(user_data))
varo.update_avatar(user_data['avatar'],owner)

177
db.py
View File

@@ -2,6 +2,7 @@ import mysql.connector
import os
import dotenv
import json
import random
dotenv.load_dotenv()
@@ -13,9 +14,6 @@ dbargs = {
'database':os.getenv('DB_NAME')
}
def check_tables():
connection = mysql.connector.connect(**dbargs)
cursor = connection.cursor()
@@ -37,6 +35,15 @@ def check_tables():
PRIMARY KEY (id)
)
""")
cursor.execute("""
CREATE TABLE IF NOT EXISTS tribes (
id INT(11) NOT NULL AUTO_INCREMENT,
tribe VARCHAR(255) NOT NULL,
data JSON,
owner VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
)
""")
cursor.close()
connection.close()
print("Checked tables")
@@ -197,6 +204,170 @@ def update_website_wallet(domain,token,address):
update_query = "UPDATE site SET data = %s WHERE domain = %s"
cursor.execute(update_query, (json.dumps(data), domain))
connection.commit()
cursor.close()
connection.close()
def get_random_sites():
connection = mysql.connector.connect(**dbargs)
cursor = connection.cursor()
cursor.execute("""
SELECT * FROM site
""")
data = cursor.fetchall()
cursor.close()
connection.close()
# Randomly pick 5
if len(data) > 5:
data = random.sample(data,5)
names = []
for site in data:
names.append(site[1])
return names
def get_tribes():
connection = mysql.connector.connect(**dbargs)
cursor = connection.cursor()
cursor.execute("""
SELECT * FROM tribes
""")
data = cursor.fetchall()
cursor.close()
connection.close()
tribes = []
for tribe in data:
tribes.append(tribe[1])
return tribes
def get_user_tribes(user):
connection = mysql.connector.connect(**dbargs)
cursor = connection.cursor()
cursor.execute("""
SELECT * FROM tribes WHERE owner = %s
""", (user,))
data = cursor.fetchall()
cursor.close()
connection.close()
# Also check members
connection = mysql.connector.connect(**dbargs)
cursor = connection.cursor()
cursor.execute("""
SELECT * FROM tribes
""")
data2 = cursor.fetchall()
cursor.close()
connection.close()
for tribe in data2:
tribe = json.loads(tribe[2])
if user in tribe['members']:
data.append(tribe)
return len(data)
def get_user_owned_tribe(user):
connection = mysql.connector.connect(**dbargs)
cursor = connection.cursor()
cursor.execute("""
SELECT * FROM tribes WHERE owner = %s
""", (user,))
data = cursor.fetchall()
cursor.close()
connection.close()
return data
def create_tribe(tribe,owner):
# Get users' tribes
if (get_user_tribes(owner) > 0):
return False
connection = mysql.connector.connect(**dbargs)
cursor = connection.cursor()
data = {
"data": "",
"members": [
owner
]
}
insert_query = "INSERT INTO tribes (data,tribe,owner) VALUES (%s,%s,%s)"
cursor.execute(insert_query, (json.dumps(data), tribe, owner))
connection.commit()
cursor.close()
connection.close()
return True
def get_tribe_data_raw(tribe):
connection = mysql.connector.connect(**dbargs)
cursor = connection.cursor()
cursor.execute("""
SELECT * FROM tribes WHERE tribe = %s
""", (tribe,))
data = cursor.fetchall()
cursor.close()
connection.close()
if len(data) == 0:
return False
return json.loads(data[0][2])
def check_tribe_owner(tribe,owner):
connection = mysql.connector.connect(**dbargs)
cursor = connection.cursor()
cursor.execute("""
SELECT * FROM tribes WHERE tribe = %s
""", (tribe,))
data = cursor.fetchall()
cursor.close()
connection.close()
if len(data) == 0:
return False
if data[0][3] == owner:
return True
else:
return False
def update_tribe_data_raw(tribe,data):
connection = mysql.connector.connect(**dbargs)
cursor = connection.cursor()
# Update json object
data = json.loads(data)
update_query = "UPDATE tribes SET data = %s WHERE tribe = %s"
cursor.execute(update_query, (json.dumps(data), tribe))
connection.commit()
cursor.close()
connection.close()
def delete_tribe(tribe):
connection = mysql.connector.connect(**dbargs)
cursor = connection.cursor()
cursor.execute("""
DELETE FROM tribes WHERE tribe = %s
""", (tribe,))
connection.commit()
cursor.close()
connection.close()
def rename_tribe(old,new):
connection = mysql.connector.connect(**dbargs)
cursor = connection.cursor()
cursor.execute("""
UPDATE tribes SET tribe = %s WHERE tribe = %s
""", (new,old))
connection.commit()
cursor.close()
connection.close()

528
main.py
View File

@@ -8,6 +8,9 @@ import time
from email_validator import validate_email, EmailNotValidError
import accounts
import db
import varo
import re
import avatar
app = Flask(__name__)
dotenv.load_dotenv()
@@ -20,17 +23,54 @@ dbargs = {
'database':os.getenv('DB_NAME')
}
CITY_DOMAIN = os.getenv('CITY_DOMAIN')
if CITY_DOMAIN == None:
CITY_DOMAIN = "exampledomainnathan1"
IMAGE_LOCATION = os.getenv('IMAGE_LOCATION')
if IMAGE_LOCATION == None:
IMAGE_LOCATION = "/data"
random_sites = ""
# Templates available for user
templates = [
'Standard',
'Original',
'No card around data',
'No card around data (2)',
'Blank',
'Standard with donate footer',
'No card with donate footer'
]
#Assets routes
@app.route('/assets/<path:path>')
def assets(path):
return send_from_directory('templates/assets', path)
@app.route('/avatar/<path:path>')
def avatar_view(path):
return send_from_directory(IMAGE_LOCATION, path)
def error(message):
return jsonify({'success': False, 'message': message}), 400
return render_template('error.html', message=message)
@app.route('/')
def index():
global random_sites
if random_sites == "":
random_sites_names = db.get_random_sites()
for site in random_sites_names:
random_sites += "<a href='https://" + site + "." + CITY_DOMAIN + "' target='_blank'>" + site + "." +CITY_DOMAIN+ "</a><br>"
tribes = db.get_tribes()
tribesHTML = ""
for tribe in tribes:
tribesHTML += "<a href='/tribe/" + tribe + "'>" + tribe.capitalize() + "</a><br>"
if 'token' in request.cookies:
token = request.cookies['token']
# Verify token
@@ -40,14 +80,19 @@ def index():
resp = make_response(redirect('/'))
resp.set_cookie('token', '', expires=0)
return resp
return render_template('index.html',account=user['email'],account_link="account")
return render_template('index.html',account="Login",account_link="login")
return render_template('index.html',account=user['email'],account_link="account",account_link_name="Account",CITY_DOMAIN=CITY_DOMAIN,random_sites=random_sites,tribes=tribesHTML)
return render_template('index.html',account="Login",account_link="login",account_link_name="Login",CITY_DOMAIN=CITY_DOMAIN,random_sites=random_sites,tribes=tribesHTML)
@app.route('/signup', methods=['POST'])
def signup():
email = request.form['email']
domain = request.form['domain']
domain = request.form['domain'].lower()
password = request.form['password']
# Verify domain
if not re.match("^[a-z0-9]*$", domain):
return error('Sorry domain can only contain lowercase letters and numbers')
try:
valid = validate_email(email)
email = valid.email
@@ -71,20 +116,23 @@ def login():
if not user['success']:
return error(user['message'])
# Redirect to dashboard with cookie
resp = make_response(redirect('/edit'))
resp = make_response(redirect('/account'))
resp.set_cookie('token', user['token'])
return resp
@app.route('/edit')
def edit():
if 'token' not in request.cookies:
return redirect('/login')
token = request.cookies['token']
if not accounts.validate_token(token):
return error('Invalid token')
return error('Sorry we had an issue verifying your account')
# Verify token
user = accounts.validate_token(token)
if not user:
# Remove cookie
resp = make_response(redirect('/'))
resp = make_response(redirect('/login'))
resp.set_cookie('token', '', expires=0)
return resp
@@ -93,6 +141,14 @@ def edit():
hns = ""
btc = ""
eth = ""
hnschat = ""
location = ""
avatar = ""
bg_colour = ""
fg_colour = ""
text_colour = ""
email = ""
hip2_display = False
if 'data' in data:
html = data['data'].encode('utf-8').decode('unicode-escape')
@@ -102,29 +158,77 @@ def edit():
btc = data['BTC']
if 'ETH' in data:
eth = data['ETH']
if 'hnschat' in data:
hnschat = data['hnschat']
if 'location' in data:
location = data['location']
if 'avatar' in data:
avatar = data['avatar']
if avatar != "":
avatar = "<img class='rounded-circle' width='100px' height='100px' src='"+avatar+"' style='margin-right: 25px;' />"
else:
avatar = "<p style='margin-right: 25px;'>No avatar set</p>"
return render_template('edit.html',account=user['email'],account_link="account",data=html,hns=hns,btc=btc,eth=eth)
if 'bg_colour' in data:
bg_colour = data['bg_colour']
if 'fg_colour' in data:
fg_colour = data['fg_colour']
else:
fg_colour = "#ffffff"
if 'text_colour' in data:
text_colour = data['text_colour']
if 'email' in data:
email = data['email']
if 'template' in data:
selected_template = data['template']
else:
selected_template = templates[0]
if 'hip2_display' in data:
hip2_display = data['hip2_display']
return render_template('edit.html',account=user['email'],account_link="account",account_link_name="Account",data=html,
hns=hns,btc=btc,eth=eth,hnschat=hnschat,email=email,location=location,avatar=avatar,
bg_colour=bg_colour,fg_colour=fg_colour,text_colour=text_colour,templates=templates,
selected_template=selected_template,CITY_DOMAIN=CITY_DOMAIN,domain=user['domain'],hip2_display=hip2_display)
@app.route('/edit', methods=['POST'])
def send_edit():
token = request.cookies['token']
if not accounts.validate_token(token):
return error('Invalid token')
return error('Sorry we had an issue verifying your account')
# Verify token
user = accounts.validate_token(token)
if not user:
# Remove cookie
resp = make_response(redirect('/'))
resp = make_response(redirect('/login'))
resp.set_cookie('token', '', expires=0)
return resp
# Json data
data = {}
data['data'] = request.form['data']
data['HNS'] = request.form['hns']
data['BTC'] = request.form['btc']
data['ETH'] = request.form['eth']
data = db.get_website_data_raw(user['domain'])
data['data'] = request.form['data'].strip()
data['HNS'] = request.form['hns'].strip()
data['BTC'] = request.form['btc'].strip()
data['ETH'] = request.form['eth'].strip()
data['hnschat'] = request.form['hnschat'].strip()
data['hnschat'] = data['hnschat'].replace("/","").strip()
data['location'] = request.form['location'].strip()
data['bg_colour'] = request.form['bg_colour'].strip()
data['fg_colour'] = request.form['fg_colour'].strip()
data['text_colour'] = request.form['text_colour'].strip()
data['email'] = request.form['email'].strip()
data['template'] = request.form['template'].strip()
if 'hip2_display' in request.form:
data['hip2_display'] = True
else:
data['hip2_display'] = False
# Convert to json
data = json.dumps(data)
@@ -137,18 +241,374 @@ def send_edit():
def logout():
token = request.cookies['token']
if not accounts.logout(token)['success']:
return error('Invalid token')
return error('Sorry we had an issue verifying your account')
# Remove cookie
resp = make_response(redirect('/'))
resp.set_cookie('token', '', expires=0)
return resp
@app.route('/claim')
def claim():
# Find domain
domain = request.args.get('domain')
return redirect('/signup?domain=' + domain)
@app.route('/hnschat')
def hnschat():
token = request.cookies['token']
if not accounts.validate_token(token):
return error('Sorry we had an issue verifying your account')
# Verify token
user = accounts.validate_token(token)
if not user:
# Remove cookie
resp = make_response(redirect('/login'))
resp.set_cookie('token', '', expires=0)
return resp
record = varo.get_auth(user['domain'])
return render_template('hnschat.html',account=user['email'],account_link="account",account_link_name="Account",CITY_DOMAIN=CITY_DOMAIN,domain=user['domain'],hnschat=record)
@app.route('/hnschat', methods=['POST'])
def save_hnschat():
token = request.cookies['token']
if not accounts.validate_token(token):
return error('Sorry we had an issue verifying your account')
# Verify token
user = accounts.validate_token(token)
if not user:
# Remove cookie
resp = make_response(redirect('/login'))
resp.set_cookie('token', '', expires=0)
return resp
record = request.form['hnschat']
varo.update_auth(record,user['domain'])
return redirect('/hnschat')
@app.route('/upload', methods=['POST'])
def upload_avatar():
token = request.cookies['token']
if not accounts.validate_token(token):
return error('Sorry we had an issue verifying your account')
# Verify token
user = accounts.validate_token(token)
if not user:
# Remove cookie
resp = make_response(redirect('/login'))
resp.set_cookie('token', '', expires=0)
return resp
if 'file' not in request.files:
return error('We couldn\'t find a file in your request')
file = request.files['file']
if file.filename == '':
return error('We couldn\'t find a file in your request')
if file and avatar.allowed_file(file.filename):
# Save the file to the upload folder
avatar.save_avatar(file,user['domain'])
return redirect('/edit')
return error('Sorry we couldn\'t upload your file')
@app.route('/avatar/clear')
def avatar_clear():
token = request.cookies['token']
if not accounts.validate_token(token):
return error('Sorry we had an issue verifying your account')
# Verify token
user = accounts.validate_token(token)
if not user:
# Remove cookie
resp = make_response(redirect('/login'))
resp.set_cookie('token', '', expires=0)
return resp
avatar.clear(user['domain'])
return redirect('/edit')
@app.route('/tribe')
def tribe_list():
tribes = db.get_tribes()
tribesHTML = ""
for tribe in tribes:
tribesHTML += "<a href='/tribe/" + tribe + "'>" + tribe.capitalize() + "</a><br>"
# Add create link if user is logged in
if 'token' in request.cookies:
token = request.cookies['token']
# Verify token
user = accounts.validate_token(token)
if user:
tribesHTML += "<br><br><a class='btn btn-primary' role='button' style='width: 100%;' href='/new_tribe'>Create a tribe</a>"
return render_template('tribe.html',account="Account",account_link="account",account_link_name="Account",CITY_DOMAIN=CITY_DOMAIN,tribes=tribesHTML)
return render_template('tribe.html',account="Login",account_link="login",account_link_name="Login",CITY_DOMAIN=CITY_DOMAIN,tribes=tribesHTML)
@app.route('/new_tribe')
def new_tribe():
if 'token' not in request.cookies:
return redirect('/login')
token = request.cookies['token']
if not accounts.validate_token(token):
return error('Sorry we had an issue verifying your account')
# Verify token
user = accounts.validate_token(token)
if not user:
# Remove cookie
resp = make_response(redirect('/login'))
resp.set_cookie('token', '', expires=0)
return resp
return render_template('new_tribe.html',account=user['email'],account_link="account",account_link_name="Account",CITY_DOMAIN=CITY_DOMAIN)
@app.route('/new_tribe', methods=['POST'])
def create_tribe():
token = request.cookies['token']
if not accounts.validate_token(token):
return error('Sorry we had an issue verifying your account')
# Verify token
user = accounts.validate_token(token)
if not user:
# Remove cookie
resp = make_response(redirect('/login'))
resp.set_cookie('token', '', expires=0)
return resp
tribe = request.form['tribe'].strip().lower()
if not re.match("^[a-z0-9_]*$", tribe):
return error('Sorry tribe can only contain lowercase letters, numbers and underscores')
if tribe.startswith("_") or tribe.endswith("_"):
return error('Sorry tribe can\'t start or end with an underscore')
if len(tribe) < 3:
return error('Sorry tribe must be at least 3 characters long')
if len(tribe) > 255:
return error('Sorry tribe must be less than 255 characters long')
if db.create_tribe(tribe,user['domain']):
return redirect('/tribe/' + tribe)
else:
return error('Sorry you already have a tribe')
@app.route('/tribe/<tribe>')
def tribe(tribe):
tribe = tribe.lower()
if not re.match("^[a-z0-9_]*$", tribe):
return error('Sorry we couldn\'t find that tribe')
data = db.get_tribe_data_raw(tribe)
if data == None:
return error('Sorry we couldn\'t find that tribe')
html = ""
if 'data' in data:
html = data['data'].encode('utf-8').decode('unicode-escape')
html = html.replace("\n","<br>")
tribe = tribe.capitalize()
members_html = ""
members = data['members']
for member in members:
members_html += "<a href='https://" + member + "." + CITY_DOMAIN + "' target='_blank'>" + member + "." +CITY_DOMAIN+ "/</a><br>"
edit = ""
# Add edit link if user is logged in
if 'token' in request.cookies:
token = request.cookies['token']
# Verify token
user = accounts.validate_token(token)
if user:
if db.check_tribe_owner(tribe,user['domain']):
edit = "<a class='btn btn-primary' role='button' style='width: 100%;' href='/edit_tribe'>Edit tribe</a>"
elif user['domain'] not in members:
edit = "<a class='btn btn-primary' role='button' style='width: 100%;' href='/join_tribe/" + tribe + "'>Join tribe</a>"
return render_template('tribe_view.html',tribe=tribe,data=html,edit=edit,members=members_html)
@app.route('/join_tribe/<tribe>')
def join_tribe(tribe):
tribe = tribe.lower()
if not re.match("^[a-z0-9_]*$", tribe):
return error('Sorry we couldn\'t find that tribe')
data = db.get_tribe_data_raw(tribe)
if data == None:
return error('Sorry we couldn\'t find that tribe')
# Verify token
token = request.cookies['token']
if not accounts.validate_token(token):
# Remove cookie
resp = make_response(redirect('/login'))
resp.set_cookie('token', '', expires=0)
return resp
user = accounts.validate_token(token)
if not user:
# Remove cookie
resp = make_response(redirect('/login'))
resp.set_cookie('token', '', expires=0)
return resp
members = data['members']
if user['domain'] in members:
return error('Sorry you are already a member of this tribe')
members.append(user['domain'])
data['members'] = members
# Convert to json
data = json.dumps(data)
db.update_tribe_data_raw(tribe,data)
return redirect('/tribe/' + tribe)
@app.route('/edit_tribe')
def edit_tribe_view():
token = request.cookies['token']
if not accounts.validate_token(token):
return error('Sorry we had an issue verifying your account')
# Verify token
user = accounts.validate_token(token)
if not user:
# Remove cookie
resp = make_response(redirect('/'))
resp.set_cookie('token', '', expires=0)
return resp
tribeData = db.get_user_owned_tribe(user['domain'])
if len(tribeData) == 0:
return error('Sorry you don\'t own a tribe')
tribe = tribeData[0][1]
data = tribeData[0][2]
data = json.loads(data)
html = data['data'].encode('utf-8').decode('unicode-escape')
members = data['members']
members_html = ""
for member in members:
members_html += "<a href='https://" + member + "." + CITY_DOMAIN + "' target='_blank'>" + member + "." +CITY_DOMAIN+ "</a> <a href='/remove_member?member=" + member + "'>(Remove)</a><br>"
return render_template('edit_tribe.html',account=user['email'],account_link="account",account_link_name="Account",CITY_DOMAIN=CITY_DOMAIN,tribe=tribe,data=html,members=members_html)
@app.route('/edit_tribe', methods=['POST'])
def edit_tribe():
token = request.cookies['token']
if not accounts.validate_token(token):
return error('Sorry we had an issue verifying your account')
# Verify token
user = accounts.validate_token(token)
if not user:
# Remove cookie
resp = make_response(redirect('/'))
resp.set_cookie('token', '', expires=0)
return resp
tribeData = db.get_user_owned_tribe(user['domain'])
if len(tribeData) == 0:
return error('Sorry you don\'t own a tribe')
tribe = tribeData[0][1]
data = tribeData[0][2]
data = json.loads(data)
data['data'] = request.form['data'].strip()
# Convert to json
data = json.dumps(data)
db.update_tribe_data_raw(tribe,data)
# Check if tribe name changed
if tribe != request.form['tribe']:
# Verify new tribe name
new_tribe = request.form['tribe'].strip().lower()
if not re.match("^[a-z0-9_]*$", new_tribe):
return error('Sorry tribe can only contain lowercase letters, numbers and underscores')
if new_tribe.startswith("_") or new_tribe.endswith("_"):
return error('Sorry tribe can\'t start or end with an underscore')
# Delete old tribe
db.rename_tribe(tribe,new_tribe)
return redirect('/edit_tribe')
@app.route('/remove_member')
def remove_member():
token = request.cookies['token']
if not accounts.validate_token(token):
return error('Sorry we had an issue verifying your account')
member = request.args.get('member')
# Verify token
user = accounts.validate_token(token)
if not user:
# Remove cookie
resp = make_response(redirect('/'))
resp.set_cookie('token', '', expires=0)
return resp
tribeData = db.get_user_owned_tribe(user['domain'])
if len(tribeData) == 0:
return error('Sorry you don\'t own a tribe')
# Verify member isn't owner
if member == user['domain']:
return error('Sorry you can\'t remove yourself from your own tribe')
tribe = tribeData[0][1]
data = tribeData[0][2]
data = json.loads(data)
members = data['members']
if member in members:
members.remove(member)
data['members'] = members
# Convert to json
data = json.dumps(data)
db.update_tribe_data_raw(tribe,data)
return redirect('/edit_tribe')
@app.route('/delete_tribe')
def delete_tribe():
token = request.cookies['token']
if not accounts.validate_token(token):
return error('Sorry we had an issue verifying your account')
# Verify token
user = accounts.validate_token(token)
if not user:
# Remove cookie
resp = make_response(redirect('/'))
resp.set_cookie('token', '', expires=0)
return resp
tribeData = db.get_user_owned_tribe(user['domain'])
if len(tribeData) == 0:
return error('Sorry you don\'t own a tribe')
tribe = tribeData[0][1]
db.delete_tribe(tribe)
return redirect('/tribe')
@app.route('/<path:path>')
def catch_all(path):
account = "Login"
account_link = "login"
account_link_name = "Login"
site = "Null"
sld = ""
domain = ""
tribe_title = "Join a tribe"
tribe_link = "tribe"
if 'domain' in request.args:
domain = request.args.get('domain')
if 'token' in request.cookies:
token = request.cookies['token']
# Verify token
@@ -160,26 +620,50 @@ def catch_all(path):
return resp
account = user['email']
account_link = "account"
site = user['domain'] + ".exampledomainnathan1"
elif path != "signup" and path != "login":
account_link_name = "Account"
site = user['domain'] + "." + CITY_DOMAIN
sld = user['domain']
# Check if user owns tribe
tribeData = db.get_user_owned_tribe(user['domain'])
if len(tribeData) > 0:
tribe_title = "Edit your tribe"
tribe_link = "edit_tribe"
elif path != "signup" and path != "login" and path != "empty_site":
return redirect('/')
if path == "account":
account_link = "logout"
account_link_name = "Logout"
# If file exists, load it
if os.path.isfile('templates/' + path):
return render_template(path,account=account,account_link=account_link,site=site)
return render_template(path,account=account,account_link=account_link,
account_link_name=account_link_name,site=site,
CITY_DOMAIN=CITY_DOMAIN,domain=domain,sld=sld,
tribe_title=tribe_title,tribe_link=tribe_link)
# Try with .html
if os.path.isfile('templates/' + path + '.html'):
return render_template(path + '.html',account=account,account_link=account_link,site=site)
return render_template(path + '.html',account=account,account_link=account_link,
account_link_name=account_link_name,site=site,
CITY_DOMAIN=CITY_DOMAIN,domain=domain,sld=sld,
tribe_title=tribe_title,tribe_link=tribe_link)
return redirect('/') # 404 catch all
# 404 catch all
@app.errorhandler(404)
def not_found(e):
return redirect('/')
def update_random_sites():
global random_sites
random_sites_names = db.get_random_sites()
random_sites = ""
for site in random_sites_names:
random_sites += "<a href='https://" + site + "." + CITY_DOMAIN + "' target='_blank'>" + site + "." +CITY_DOMAIN+ "</a><br>"
if __name__ == '__main__':
db.check_tables()
app.run(debug=False, port=5000, host='0.0.0.0')
app.run(debug=True, port=5000, host='0.0.0.0')

View File

@@ -9,4 +9,5 @@ py3dns
passlib
argon2-cffi
mysql-connector-python
beautifulsoup4
beautifulsoup4
apscheduler

View File

@@ -8,8 +8,13 @@ import dotenv
import sys
import json
import db
from apscheduler.schedulers.background import BackgroundScheduler
def update_sites_job():
print("Updating random sites", flush=True)
main.update_random_sites()
class GunicornApp(BaseApplication):
def __init__(self, app, options=None):
self.options = options or {}
@@ -26,6 +31,12 @@ class GunicornApp(BaseApplication):
if __name__ == '__main__':
db.check_tables()
scheduler = BackgroundScheduler()
scheduler.add_job(update_sites_job, 'interval', minutes=15)
scheduler.start()
workers = os.getenv('WORKERS')
threads = os.getenv('THREADS')
if workers is None:

View File

@@ -24,7 +24,7 @@ def get_website_data(domain):
connection.close()
if data == []:
return "No data found for this domain"
return False
parsed = data[0][2]
parsed = json.loads(parsed)
@@ -34,6 +34,24 @@ def get_website_data(domain):
return parsed
def get_website_data_raw(domain):
connection = mysql.connector.connect(**dbargs)
cursor = connection.cursor()
cursor.execute("""
SELECT * FROM site WHERE domain = %s
""", (domain,))
data = cursor.fetchall()
cursor.close()
connection.close()
if data == []:
return ""
parsed = data[0][2]
parsed = json.loads(parsed)
return parsed
def get_website_wallet(domain,token):
connection = mysql.connector.connect(**dbargs)
cursor = connection.cursor()

7
sites/parts/footer.html Normal file
View File

@@ -0,0 +1,7 @@
<div style="height: 100px;"></div>
<div style="position: fixed;bottom: 10px;width: 100%;left:25px;">
<div style="display: inline-block; background: {{fg_colour}};border-radius: 50%;padding: 10px;">
<img src="{{hns_icon}}" width="50px" height="50px">
</div>
<p style="margin-left: 25px; display:inline; color:{{fg_colour}};">Powered by <a href="https://{{main_domain}}" target="_blank">ShakeCities</a></p>
</div>

View File

@@ -12,27 +12,27 @@ import website
app = Flask(__name__)
dotenv.load_dotenv()
main_domain = "cities.hnshosting.au"
if os.getenv('MAIN_DOMAIN') != None:
main_domain = os.getenv('MAIN_DOMAIN')
#Assets routes
@app.route('/assets/<path:path>')
def assets(path):
return send_from_directory('templates/assets', path)
#! TODO make prettier
def error(message):
return jsonify({'success': False, 'message': message}), 400
@app.route('/')
def index():
host = request.host
if len(host.split('.')) != 2:
return error('Invalid domain')
return redirect('https://'+main_domain)
host = host.split('.')[0]
# Get website data
data = db.get_website_data(host)
db_object = db.get_website_data_raw(host)
# Render as HTML
return website.render(data)
return website.render(data,db_object)
@app.route('/.well-known/wallets/<token>')
@@ -54,6 +54,21 @@ def catch_all(path):
def not_found(e):
return redirect('/')
def clean_templates():
# Clean template
for file in os.listdir('templates'):
if file.endswith('.html'):
with open('templates/' + file) as f:
data = f.read()
data = data.replace('#f1ffff', '{{fg_colour}}')
data = data.replace('#1fffff', '{{text_colour}}')
data = data.replace('#000000', '{{bg_colour}}')
# Save
with open('templates/' + file, 'w') as f:
f.write(data)
print("Cleaned " + file, flush=True)
print("Cleaned template", flush=True)
if __name__ == '__main__':
app.run(debug=False, port=5000, host='0.0.0.0')

View File

@@ -24,6 +24,8 @@ class GunicornApp(BaseApplication):
return self.application
if __name__ == '__main__':
print("Cleaning template...", flush=True)
slds.clean_templates()
workers = os.getenv('WORKERS')
threads = os.getenv('THREADS')
if workers is None:

View File

@@ -1,18 +1,229 @@
from flask import Flask, make_response, redirect, render_template_string, request, jsonify, render_template, send_from_directory
from flask import Flask, redirect, render_template_string, request
from bs4 import BeautifulSoup
import os
import dotenv
def render(data):
if data == "":
return "No data found for this domain"
main_domain = "shakecities.com"
if os.getenv('MAIN_DOMAIN') != None:
main_domain = os.getenv('MAIN_DOMAIN')
FOOTER=""
if os.path.exists("parts/footer.html"):
with open("parts/footer.html") as f:
FOOTER = f.read()
elif os.path.exists("sites/parts/footer.html"):
with open("sites/parts/footer.html") as f:
FOOTER = f.read()
def render(data,db_object):
if data == False:
return redirect("https://" + main_domain + '/claim?domain=' + request.host.split('.')[0])
elif data == "":
return redirect("https://" + main_domain + '/empty_site?nodata')
# Render as HTML
html = ""
ssl = "<script src='https://nathan.woodburn/https.js'></script>"
if ("localhost" in request.host or "127.0.0.1" in request.host):
ssl = ""
try:
soup = BeautifulSoup(data, 'html.parser')
for script in soup.find_all('script'):
script.extract()
modified = str(soup)
return render_template_string(modified)
# Inject SSL
soup.append(BeautifulSoup(ssl, 'html.parser'))
html = str(soup)
except Exception as e:
return "<h1>Invalid HTML</h1><br>" + str(e)
return redirect("https://" + main_domain + '/empty_site?error='+str(e))
try:
avatar = db_object['avatar']
hnschat = db_object['hnschat']
location = db_object['location']
email = db_object['email']
hns = db_object['HNS']
if 'hip2_display' in db_object:
if db_object['hip2_display'] == True:
hns = "@"+request.host
btc = db_object['BTC']
eth = db_object['ETH']
bg_colour = db_object['bg_colour']
fg_colour = db_object['fg_colour']
text_colour = db_object['text_colour']
if (rgb_to_hex(generate_foreground_color(bg_colour)) == "#000000"):
hns_icon = "assets/img/HNSW.png"
btc_icon = "assets/img/BTCW.png"
eth_icon = "assets/img/ETHW.png"
hns_icon_invert = "assets/img/HNS.png"
btc_icon_invert = "assets/img/BTC.png"
eth_icon_invert = "assets/img/ETH.png"
else:
hns_icon = "assets/img/HNS.png"
btc_icon = "assets/img/BTC.png"
eth_icon = "assets/img/ETH.png"
hns_icon_invert = "assets/img/HNSW.png"
btc_icon_invert = "assets/img/BTCW.png"
eth_icon_invert = "assets/img/ETHW.png"
if (rgb_to_hex(generate_foreground_color(fg_colour)) == "#000000"):
hns_chat_icon = "assets/img/HNS.png"
location_icon = "assets/img/map.png"
email_icon = "assets/img/email.png"
else:
hns_chat_icon = "assets/img/HNSW.png"
location_icon = "assets/img/mapw.png"
email_icon = "assets/img/emailw.png"
hns_address = hns
btc_address = btc
eth_address = eth
hns_invert = hns_address
btc_invert = btc_address
eth_invert = eth_address
if hns != "":
hns = "<img src='" + hns_icon + "' width='20px' height='20px' style='margin-right: 5px;'>" + hns
hns_invert = "<img src='" + hns_icon_invert + "' width='20px' height='20px' style='margin-right: 5px;'>" + hns_address
if btc != "":
btc = "<img src='" + btc_icon + "' width='20px' height='25px' style='margin-right: 5px;'>" + btc
btc_invert = "<img src='" + btc_icon_invert + "' width='20px' height='25px' style='margin-right: 5px;'>" + btc_address
if eth != "":
eth = "<img src='" + eth_icon + "' width='20px' height='30px' style='margin-right: 5px;'>" + eth
eth_invert = "<img src='" + eth_icon_invert + "' width='20px' height='30px' style='margin-right: 5px;'>" + eth_address
hide_addresses = False
if hns == "" and btc == "" and eth == "":
hide_addresses = True
if hnschat != "":
hnschat = "<a href='https://hns.chat/#message:"+hnschat+"' target='_blank'><img src='"+hns_chat_icon+"' width='20px' height='20px' style='margin-right: 5px;'>" + hnschat + "/</a>"
if location != "":
location = "<img src='"+location_icon+"' width='20px' height='30px' style='margin-right: 5px;'>" + location
if email != "":
email = "<a href='mailto:"+email+"'><img src='"+email_icon+"' width='30px' height='20px' style='margin-right: 5px;margin-left:-10px;'>" + email + "</a>"
if avatar != "":
avatar = "<img src='"+avatar+"' width='200vw' height='200vw' style='border-radius: 50%;margin-right: 5px;'>"
else:
avatar = "<h1 style='color:"+fg_colour+";'>" + request.host.split(':')[0] + "/</h1>"
template = "Standard"
if 'template' in db_object:
if db_object['template'] != "":
template = db_object['template']
footer = render_template_string(FOOTER,main_domain=main_domain,fg_colour=fg_colour,hns_icon=hns_icon)
return render_template_string(get_template(template,hide_addresses),bg_colour=bg_colour,text_colour=text_colour,
fg_colour=fg_colour, avatar=avatar,main_domain=main_domain,
hnschat=hnschat,email=email,location=location, hns_icon=hns_icon,
hns=hns,btc=btc,eth=eth,hns_invert=hns_invert,btc_invert=btc_invert,
eth_invert=eth_invert,hns_address=hns_address,btc_address=btc_address,eth_address=eth_address,
hns_icon_invert=hns_icon_invert,btc_icon=btc_icon,btc_icon_invert=btc_icon_invert,
eth_icon=eth_icon,eth_icon_invert=eth_icon_invert,
data=html,footer=footer)
except Exception as e:
return redirect("https://" + main_domain + '/empty_site?error='+str(e))
def get_template(template,hide_addresses=False):
file = "templates/" +get_template_file(template)
with open(file) as f:
data = f.read()
# Read template
soup = BeautifulSoup(data, 'html.parser')
# Remove addresses div
if hide_addresses:
try:
addresses = soup.find(id="addresses")
addresses.decompose()
except:
pass
# If <!-- Matomo --> comment doesn't exist, add tracking to end of head
if 'Matomo' not in str(soup):
head = soup.find("head")
head.append(BeautifulSoup("""
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.woodburn.au/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '7']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
""", 'html.parser'))
return str(soup)
def calculate_contrast_ratio(color1, color2):
def calculate_luminance(color):
def adjust_color_value(value):
value /= 255.0
if value <= 0.03928:
return value / 12.92
return ((value + 0.055) / 1.055) ** 2.4
r, g, b = color
r = adjust_color_value(r)
g = adjust_color_value(g)
b = adjust_color_value(b)
return 0.2126 * r + 0.7152 * g + 0.0722 * b
luminance1 = calculate_luminance(color1)
luminance2 = calculate_luminance(color2)
brighter = max(luminance1, luminance2)
darker = min(luminance1, luminance2)
contrast_ratio = (brighter + 0.05) / (darker + 0.05)
return contrast_ratio
def generate_foreground_color(background_color):
# Convert to RGB tuple
background_color=background_color.lstrip('#')
background_color = tuple(int(background_color[i:i+2], 16) for i in (0, 2, 4))
contrast_color = (255, 255, 255) # White
ratio = calculate_contrast_ratio(background_color, contrast_color)
if ratio < 4.5:
return (0, 0, 0) # Black
else:
return contrast_color
def rgb_to_hex(rgb_color):
return "#{:02x}{:02x}{:02x}".format(*rgb_color)
def get_template_file(template):
if template.endswith(".html"):
return template
template = template.lower()
templates = {
"standard": "city.html",
"original": "city_old.html",
"no card around data": "city_no_card.html",
"no card around data (2)": "city_no_card_2.html",
"blank": "city_blank.html",
"standard with donate footer": "city_donate_footer.html",
"no card with donate footer": "city_no_card_donate_footer.html",
}
if template in templates:
return templates[template]
return "city.html"

71
template.py Normal file
View File

@@ -0,0 +1,71 @@
from flask import Flask, send_from_directory
import sys
import sites.website as website
import json
import os
app = Flask(__name__)
template = "city"
data = "<h1>Test site</h1><p>This is a test site</p>"
# data = "<div style=\"text-align:center;\"><h1>Nathan.Woodburn/</h1><h2>This is fully customizable!</h2><p>You can even add custom css rules like below.<br>Try hovering over this image</p><style>img.background:hover {filter: blur(5px)}</style><div class=\"profile-container\" style=\"height: 300px;margin-bottom: 2em;\"><img class=\"profile background\" src=\"https://nathan.woodburn.au/assets/img/profile.jpg\" style=\"border-radius: 50%;width: 300px;position: absolute;left: 50%;margin-left: -150px;aspect-ratio: 1;padding-top: calc(var(--s)/5);transform: scale(1);transition: .5s;\" alt=\"My Profile\"><img class=\"profile foreground\" src=\"https://nathan.woodburn.au/assets/img/pfront.webp\" alt=\"\" style=\"border-radius: 50%;pointer-events: none;width: 300px;position: absolute;left: 50%;margin-left: -150px;aspect-ratio: 1;padding-top: calc(var(--s)/5);transform: scale(1);transition: .5s;\"></div>"
db_object = {
'avatar': "https://woodburn.au/favicon.png",
'hnschat':"nathan.woodburn",
'location': "Australia",
'email': "test@email",
'HNS': "hs1qh7c98nexsrzwrmnh2avved6awe59jzpr3xx2xf",
'BTC': "bc1qhs94zzcw64qnwq4hvk056rwxwvgrkd7tq7d4xw",
'ETH' : "0x6cB4B39bEc23a921C9a20D061Bf17d4640B0d39e",
'bg_colour': "#000000",
# 'fg_colour': "#ffffff",
# 'text_colour': "#152D45",
'text_colour': "#ffffff",
'fg_colour': "#8f00db",
}
@app.route('/')
def index():
if os.path.exists("templates/"+template+".html"):
with open("templates/"+template+".html") as f:
filedata = f.read()
filedata = filedata.replace('#f1ffff', '{{fg_colour}}')
filedata = filedata.replace('#1fffff', '{{text_colour}}')
filedata = filedata.replace('#000000', '{{bg_colour}}')
# Save
with open('templates/' + template+".tmp.html", 'w') as f:
f.write(filedata)
else:
return "Template not found"
db_object['template'] = template + ".tmp.html"
render = website.render(data,db_object)
# Delete tmp
os.remove('templates/' + template+".tmp.html")
return render
@app.route('/assets/<path:path>')
def send_assets(path):
return send_from_directory('templates/assets', path)
@app.route('/.well-known/wallets/<path:path>')
def send_wallets(path):
if path in db_object:
return db_object[path]
else:
return "Not found"
if __name__ == "__main__":
# Get second arg
if len(sys.argv) > 1:
template = sys.argv[1]
else:
print("Usage: python3 template.py <template>")
sys.exit(0)
app.run(host='0.0.0.0', port=5000, debug=True)

View File

@@ -1,34 +1,77 @@
<!DOCTYPE html>
<html data-bs-theme="light" lang="en">
<html data-bs-theme="light" lang="en" style="background: #000000;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>shakecities</title>
<title>ShakeCities | Account</title>
<meta name="twitter:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="twitter:card" content="summary">
<meta property="og:type" content="website">
<meta property="og:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:title" content="ShakeCities">
<meta name="twitter:title" content="ShakeCities">
<meta name="twitter:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.woodburn.au/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '7']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
<script async src="https://umami.woodburn.au/script.js" data-website-id="9a7af01b-9ebf-49a9-8337-907ff3744a02"></script>
</head>
<body>
<nav class="navbar navbar-expand-md bg-dark py-3" data-bs-theme="dark">
<div class="container"><a class="navbar-brand d-flex align-items-center" href="/"><span class="bs-icon-sm bs-icon-rounded bs-icon-primary d-flex justify-content-center align-items-center me-2 bs-icon"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-bezier">
<path fill-rule="evenodd" d="M0 10.5A1.5 1.5 0 0 1 1.5 9h1A1.5 1.5 0 0 1 4 10.5v1A1.5 1.5 0 0 1 2.5 13h-1A1.5 1.5 0 0 1 0 11.5v-1zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1zm10.5.5A1.5 1.5 0 0 1 13.5 9h1a1.5 1.5 0 0 1 1.5 1.5v1a1.5 1.5 0 0 1-1.5 1.5h-1a1.5 1.5 0 0 1-1.5-1.5v-1zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1zM6 4.5A1.5 1.5 0 0 1 7.5 3h1A1.5 1.5 0 0 1 10 4.5v1A1.5 1.5 0 0 1 8.5 7h-1A1.5 1.5 0 0 1 6 5.5v-1zM7.5 4a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1z"></path>
<path d="M6 4.5H1.866a1 1 0 1 0 0 1h2.668A6.517 6.517 0 0 0 1.814 9H2.5c.123 0 .244.015.358.043a5.517 5.517 0 0 1 3.185-3.185A1.503 1.503 0 0 1 6 5.5v-1zm3.957 1.358A1.5 1.5 0 0 0 10 5.5v-1h4.134a1 1 0 1 1 0 1h-2.668a6.517 6.517 0 0 1 2.72 3.5H13.5c-.123 0-.243.015-.358.043a5.517 5.517 0 0 0-3.185-3.185z"></path>
</svg></span><span>Brand</span></a><button data-bs-toggle="collapse" class="navbar-toggler" data-bs-target="#navcol-6"><span class="visually-hidden">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse flex-grow-0 order-md-first" id="navcol-6">
<ul class="navbar-nav me-auto">
<li class="nav-item"><a class="nav-link active" href="/signup">Create your page</a></li>
<li class="nav-item"><a class="nav-link" href="/edit">Edit your page</a></li>
</ul>
<div class="d-md-none my-2"><button class="btn btn-light me-2" type="button">Button</button><button class="btn btn-primary" type="button">Button</button></div>
</div>
<div class="d-none d-md-block"><a class="btn btn-primary" role="button" href="/account">{{account}}</a></div>
</div>
</nav>
<body style="background: #000000;color: #ffffff;margin: auto;width: 95%;">
<section>
<section style="height: 15vh;background: url(&quot;assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp&quot;) bottom / cover no-repeat;min-height: 130px;"></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="width: 30vw;border-radius: 50%;background: #000000;padding: 20px;height: 30vw;margin: auto;margin-top: -15vw;display: flex;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="display: block;width: 100%;text-align: center;margin-top: 10px;">
<div style="display: inline-block;margin: auto;"><a class="btn btn-primary" role="button" style="margin: 10px;" href="/signup">Create your page</a><a class="btn btn-primary" role="button" style="margin: 10px;" href="/{{account_link}}">{{account_link_name}}</a></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="display: block;">
<div style="width: 100%;text-align: right;margin-top: -4em;"><a class="btn btn-primary" role="button" style="margin: 10px;" href="/signup">Create a new page</a><a class="btn btn-primary" role="button" style="margin: 10px;" href="/{{account_link}}">{{account_link_name}}</a></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="width: 15vw;border-radius: 50%;background: #000000;padding: 20px;height: 15vw;margin: auto;display: flex;margin-top: -6vw;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="height: 3em;"></section>
</section>
<section style="margin-top: 50px;text-align: center;">
<p>Email: {{account}}<br>Site: <a href="https://{{site}}" target="_blank">{{site}}</a></p><a class="btn btn-primary" role="button" href="/logout">Logout</a>
<h1>Welcome to ShakeCities</h1>
<p>Congratulations your site is ready for use.<br>Your site is available at <a href="https://{{sld}}.shakecities" target="_blank">{{sld}}.shakecities/</a> <a href="https://{{sld}}.shakec" target="_blank">{{sld}}.shakec/</a> &amp; <a href="https://{{sld}}.onsc" target="_blank">{{sld}}.onsc/</a><br><br></p>
<div style="max-width: 10em;margin: auto;"><a class="btn btn-primary" role="button" href="https://{{site}}" style="display: block;margin: 10px;" target="_blank">Visit your site</a><a class="btn btn-primary" role="button" href="/edit" style="display: block;margin: 10px;">Edit your site</a><a class="btn btn-primary" role="button" href="/{{tribe_link}}" style="display: block;margin: 10px;">{{tribe_title}}</a><a class="btn btn-primary" role="button" href="/hnschat" style="display: block;margin: 10px;">Link HNSChat</a><a class="btn btn-primary" role="button" href="/logout" style="display: block;margin: 10px;">Logout</a></div>
</section>
<section style="margin: 20px;height: 40px;text-align: center;margin-top: 40px;">
<footer class="text-center bg-dark"></footer>
<div style="display: inline-block;">
<ul class="list-inline">
<li class="list-inline-item me-4" style="color: rgb(255,255,255);">Copyright © ShakeCities 2023</li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/54/uptime?labelPrefix=Main+Server+' style="height:1.3em;margin-bottom:-.3em;width: 13em;"></iframe></li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/55/uptime?labelPrefix=Cities+' style="height:1.3em;margin-bottom:-.3em;width:11em;"></iframe></li>
</ul>
</div>
</section>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/script.min.js"></script>
</body>
</html>

1
templates/assets/css/city.min.css vendored Normal file
View File

@@ -0,0 +1 @@
a{color:inherit}

View File

@@ -1 +1 @@
.bs-icon{--bs-icon-size:.75rem;display:flex;flex-shrink:0;justify-content:center;align-items:center;font-size:var(--bs-icon-size);width:calc(var(--bs-icon-size) * 2);height:calc(var(--bs-icon-size) * 2);color:var(--bs-primary)}.bs-icon-xs{--bs-icon-size:1rem;width:calc(var(--bs-icon-size) * 1.5);height:calc(var(--bs-icon-size) * 1.5)}.bs-icon-sm{--bs-icon-size:1rem}.bs-icon-md{--bs-icon-size:1.5rem}.bs-icon-lg{--bs-icon-size:2rem}.bs-icon-xl{--bs-icon-size:2.5rem}.bs-icon.bs-icon-primary{color:var(--bs-white);background:var(--bs-primary)}.bs-icon.bs-icon-primary-light{color:var(--bs-primary);background:rgba(var(--bs-primary-rgb),.2)}.bs-icon.bs-icon-semi-white{color:var(--bs-primary);background:rgba(255,255,255,.5)}.bs-icon.bs-icon-rounded{border-radius:.5rem}.bs-icon.bs-icon-circle{border-radius:50%}
a{color:inherit}.bs-icon{--bs-icon-size:.75rem;display:flex;flex-shrink:0;justify-content:center;align-items:center;font-size:var(--bs-icon-size);width:calc(var(--bs-icon-size) * 2);height:calc(var(--bs-icon-size) * 2);color:var(--bs-primary)}.bs-icon-xs{--bs-icon-size:1rem;width:calc(var(--bs-icon-size) * 1.5);height:calc(var(--bs-icon-size) * 1.5)}.bs-icon-sm{--bs-icon-size:1rem}.bs-icon-md{--bs-icon-size:1.5rem}.bs-icon-lg{--bs-icon-size:2rem}.bs-icon-xl{--bs-icon-size:2.5rem}.bs-icon.bs-icon-primary{color:var(--bs-white);background:var(--bs-primary)}.bs-icon.bs-icon-primary-light{color:var(--bs-primary);background:rgba(var(--bs-primary-rgb),.2)}.bs-icon.bs-icon-semi-white{color:var(--bs-primary);background:rgba(255,255,255,.5)}.bs-icon.bs-icon-rounded{border-radius:.5rem}.bs-icon.bs-icon-circle{border-radius:50%}.right-align{right:0;margin-right:1%}.top-align{top:0;margin-top:1%}.sticky-bottom{width:100%;bottom:1%;left:0}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

1
templates/assets/js/script.min.js vendored Normal file
View File

@@ -0,0 +1 @@
document.addEventListener("DOMContentLoaded",(function(){[].slice.call(document.querySelectorAll("[data-bss-tooltip]")).map((function(t){return new bootstrap.Tooltip(t)}))}),!1);

81
templates/city.html Normal file
View File

@@ -0,0 +1,81 @@
<!DOCTYPE html>
<html data-bs-theme="light" lang="en" style="width: 100vw;height: 99vh;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>ShakeCities</title>
<meta name="twitter:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="twitter:card" content="summary">
<meta property="og:type" content="website">
<meta property="og:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:title" content="ShakeCities">
<meta name="twitter:title" content="ShakeCities">
<meta name="twitter:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.woodburn.au/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '7']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
<script async src="https://umami.woodburn.au/script.js" data-website-id="9a7af01b-9ebf-49a9-8337-907ff3744a02"></script>
</head>
<body style="height: 99vh;width: 100vw;color: #1fffff;background: #000000;overflow-x: hidden;">
<div class="text-center" style="margin: 10px;">
<div>{{avatar|safe}}</div>
<div style="color: #f1ffff;">
<div>
<p style="font-size: 24px;">{{hnschat|safe}}</p>
</div>
<div>
<p style="font-size: 24px;">{{email|safe}}</p>
</div>
<div>
<p style="font-size: 24px;">{{location|safe}}</p>
</div>
</div>
</div>
<div style="background: #f1ffff;border-radius: 10px;padding: 25px;padding-top: 2%;padding-left: 2%;padding-right: 2%;padding-bottom: 2%;margin: 22px;">
<p style="font-size: 24px;">{{data|safe}}</p>
</div>
<div class="text-center" id="addresses" style="background: #f1ffff;padding: 25px;border-radius: 10px;margin: 22px;">
<h1>Donate</h1>
<div>
<div>
<p style="font-size: 24px;margin-bottom: 0px;"><a href="/.well-known/wallets/HNS" target="_blank">{{hns|safe}}</a></p>
</div>
<div>
<p style="font-size: 24px;margin-bottom: 0px;"><a href="/.well-known/wallets/BTC" target="_blank">{{btc|safe}}</a></p>
</div>
<div>
<p style="font-size: 24px;margin-bottom: 0px;"><a href="/.well-known/wallets/ETH" target="_blank">{{eth|safe}}</a></p>
</div>
</div>
</div>{{footer | safe}}
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/script.min.js"></script>
</body>
</html>

58
templates/city_blank.html Normal file
View File

@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html style="width: 100vw;height: 99vh;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>ShakeCities</title>
<meta name="twitter:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="twitter:card" content="summary">
<meta property="og:type" content="website">
<meta property="og:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:title" content="ShakeCities">
<meta name="twitter:title" content="ShakeCities">
<meta name="twitter:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
</head>
<!-- Template colours
#f1ffff foreground colour
#1fffff text colour
#000000 background colour
These colours will be overriden with the user's colour scheme
-->
<body style="height: 99vh;width: 100vw;color: #1fffff;background: #000000;overflow-x: hidden;">
<!-- <div class="text-center" style="margin: 10px;">
<div>{{avatar|safe}}</div> This needs the safe filter to allow HTML to be rendered
<div style="color: #f1ffff;">
<p style="font-size: 24px;">{{hnschat|safe}}</p>
<p style="font-size: 24px;">{{email|safe}}</p>
<p style="font-size: 24px;">{{location|safe}}</p>
</div>
</div>
<div style="padding: 2%;margin: 22px;">
<p style="font-size: 24px;">
</p>
</div> -->
{{data|safe}} <!-- This needs the safe filter to allow HTML to be rendered -->
<!-- Footer to display the powered by ShakeCities. -->
{{footer|safe}}
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/script.min.js"></script>
</body>
</html>

View File

@@ -0,0 +1,67 @@
<!DOCTYPE html>
<html data-bs-theme="light" lang="en" style="width: 100vw;height: 99vh;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>ShakeCities</title>
<meta name="twitter:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="twitter:card" content="summary">
<meta property="og:type" content="website">
<meta property="og:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:title" content="ShakeCities">
<meta name="twitter:title" content="ShakeCities">
<meta name="twitter:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
</head>
<body style="height: 99vh;width: 100vw;color: #1fffff;background: #000000;overflow-x: hidden;">
<div class="text-center" style="margin: 10px;">
<div>{{avatar|safe}}</div>
<div style="color: #f1ffff;">
<div>
<p style="font-size: 24px;">{{hnschat|safe}}</p>
</div>
<div>
<p style="font-size: 24px;">{{email|safe}}</p>
</div>
<div>
<p style="font-size: 24px;">{{location|safe}}</p>
</div>
</div>
</div>
<div style="background: #f1ffff;border-radius: 10px;padding: 25px;padding-top: 2%;padding-left: 2%;padding-right: 2%;padding-bottom: 2%;margin: 22px;">
<p style="font-size: 24px;">{{data|safe}}</p>
</div>
<div id="addresses" style="width: 100%;text-align: center;">
<p style="font-size: 20px;margin-bottom: 0px;">
<a style="text-decoration: none;color: #f1ffff;" href="/.well-known/wallets/HNS" target="_blank">
<img src='{{hns_icon_invert}}' width='20px' height='20px' style='margin-right: 5px;'>
</a>
<a style="text-decoration: none;color: #f1ffff;" href="/.well-known/wallets/BTC" target="_blank">
<img src='{{btc_icon_invert}}' width='20px' height='25px' style='margin-right: 5px;'>
</a>
<a style="text-decoration: none;color: #f1ffff;" href="/.well-known/wallets/ETH" target="_blank">
<img src='{{eth_icon_invert}}' width='20px' height='30px' style='margin-right: 5px;'>
</a>
</p>
</div>
<div style="height: 25px;"></div>
{{footer | safe}}
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/script.min.js"></script>
</body>
</html>

View File

@@ -0,0 +1,65 @@
<!DOCTYPE html>
<html style="width: 100vw;height: 99vh;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>ShakeCities</title>
<meta name="twitter:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="twitter:card" content="summary">
<meta property="og:type" content="website">
<meta property="og:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:title" content="ShakeCities">
<meta name="twitter:title" content="ShakeCities">
<meta name="twitter:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
</head>
<!-- Template colours
#f1ffff foreground colour
#1fffff text colour
#000000 background colour
These colours will be overriden with the user's colour scheme
-->
<body style="height: 99vh;width: 100vw;color: #1fffff;background: #000000;overflow-x: hidden;">
<div class="text-center" style="margin: 10px;">
<div>{{avatar|safe}}</div> <!-- This needs the safe filter to allow HTML to be rendered -->
<div style="color: #f1ffff;">
<p style="font-size: 24px;">{{hnschat|safe}}</p>
<p style="font-size: 24px;">{{email|safe}}</p>
<p style="font-size: 24px;">{{location|safe}}</p>
</div>
</div>
<div style="padding: 2%;margin: 22px;">
<p style="font-size: 24px;">
{{data|safe}} <!-- This needs the safe filter to allow HTML to be rendered -->
</p>
</div>
<div class="text-center" id="addresses" style="background: #f1ffff;padding: 25px;border-radius: 10px;margin: 22px;"> <!-- Adding the id addresses will remove this div from the page when the user doesn't have any addresses -->
<h1>Donate</h1>
<div>
<p style="font-size: 24px;margin-bottom: 0px;"><a href="/.well-known/wallets/HNS" target="_blank">{{hns|safe}}</a></p>
<p style="font-size: 24px;margin-bottom: 0px;"><a href="/.well-known/wallets/BTC" target="_blank">{{btc|safe}}</a></p>
<p style="font-size: 24px;margin-bottom: 0px;"><a href="/.well-known/wallets/ETH" target="_blank">{{eth|safe}}</a></p>
</div>
</div>
<!-- Footer to display the powered by ShakeCities. -->
{{footer|safe}}
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/script.min.js"></script>
</body>
</html>

View File

@@ -0,0 +1,65 @@
<!DOCTYPE html>
<html style="width: 100vw;height: 99vh;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>ShakeCities</title>
<meta name="twitter:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="twitter:card" content="summary">
<meta property="og:type" content="website">
<meta property="og:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:title" content="ShakeCities">
<meta name="twitter:title" content="ShakeCities">
<meta name="twitter:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
</head>
<!-- Template colours
#f1ffff foreground colour
#1fffff text colour
#000000 background colour
These colours will be overriden with the user's colour scheme
-->
<body style="height: 99vh;width: 100vw;color: #1fffff;background: #000000;overflow-x: hidden;">
<div class="text-center" style="margin: 10px;">
<div>{{avatar|safe}}</div> <!-- This needs the safe filter to allow HTML to be rendered -->
<div style="color: #f1ffff;">
<p style="font-size: 24px;">{{hnschat|safe}}</p>
<p style="font-size: 24px;">{{email|safe}}</p>
<p style="font-size: 24px;">{{location|safe}}</p>
</div>
</div>
<div style="padding: 2%;margin: 22px;">
<p style="font-size: 24px;">
{{data|safe}} <!-- This needs the safe filter to allow HTML to be rendered -->
</p>
</div>
<div class="text-center" id="addresses" style="padding: 25px;border-radius: 10px;margin: 22px;"> <!-- Adding the id addresses will remove this div from the page when the user doesn't have any addresses -->
<h1>Donate</h1>
<div>
<p style="font-size: 24px;margin-bottom: 0px;"><a href="/.well-known/wallets/HNS" target="_blank">{{hns|safe}}</a></p>
<p style="font-size: 24px;margin-bottom: 0px;"><a href="/.well-known/wallets/BTC" target="_blank">{{btc|safe}}</a></p>
<p style="font-size: 24px;margin-bottom: 0px;"><a href="/.well-known/wallets/ETH" target="_blank">{{eth|safe}}</a></p>
</div>
</div>
<!-- Footer to display the powered by ShakeCities. -->
{{footer|safe}}
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/script.min.js"></script>
</body>
</html>

View File

@@ -0,0 +1,70 @@
<!DOCTYPE html>
<html style="width: 100vw;height: 99vh;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>ShakeCities</title>
<meta name="twitter:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="twitter:card" content="summary">
<meta property="og:type" content="website">
<meta property="og:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:title" content="ShakeCities">
<meta name="twitter:title" content="ShakeCities">
<meta name="twitter:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
</head>
<!-- Template colours
#f1ffff foreground colour
#1fffff text colour
#000000 background colour
These colours will be overriden with the user's colour scheme
-->
<body style="height: 99vh;width: 100vw;color: #1fffff;background: #000000;overflow-x: hidden;">
<div class="text-center" style="margin: 10px;">
<div>{{avatar|safe}}</div> <!-- This needs the safe filter to allow HTML to be rendered -->
<div style="color: #f1ffff;">
<p style="font-size: 24px;">{{hnschat|safe}}</p>
<p style="font-size: 24px;">{{email|safe}}</p>
<p style="font-size: 24px;">{{location|safe}}</p>
</div>
</div>
<div style="padding: 2%;margin: 22px;">
<p style="font-size: 24px;">
{{data|safe}} <!-- This needs the safe filter to allow HTML to be rendered -->
</p>
</div>
<div id="addresses" style="width: 100%;text-align: center;">
<p style="font-size: 20px;margin-bottom: 0px;">
<a style="text-decoration: none;color: #f1ffff;" href="/.well-known/wallets/HNS" target="_blank">
<img src='{{hns_icon_invert}}' width='20px' height='20px' style='margin-right: 5px;'>
</a>
<a style="text-decoration: none;color: #f1ffff;" href="/.well-known/wallets/BTC" target="_blank">
<img src='{{btc_icon_invert}}' width='20px' height='25px' style='margin-right: 5px;'>
</a>
<a style="text-decoration: none;color: #f1ffff;" href="/.well-known/wallets/ETH" target="_blank">
<img src='{{eth_icon_invert}}' width='20px' height='30px' style='margin-right: 5px;'>
</a>
</p>
</div>
<div style="height: 25px;"></div>
<!-- Footer to display the powered by ShakeCities. -->
{{footer|safe}}
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/script.min.js"></script>
</body>
</html>

89
templates/city_old.html Normal file
View File

@@ -0,0 +1,89 @@
<!DOCTYPE html>
<html data-bs-theme="light" lang="en" style="width: 100vw;height: 99vh;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>ShakeCities</title>
<meta name="twitter:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="twitter:card" content="summary">
<meta property="og:type" content="website">
<meta property="og:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:title" content="ShakeCities">
<meta name="twitter:title" content="ShakeCities">
<meta name="twitter:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.woodburn.au/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '7']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
<script async src="https://umami.woodburn.au/script.js" data-website-id="9a7af01b-9ebf-49a9-8337-907ff3744a02"></script>
</head>
<body style="height: 99vh;width: 100vw;color: #1fffff;background: #000000;overflow-x: hidden;">
<div style="margin: 10px;">
<div class="row row-cols-1 row-cols-sm-1 row-cols-md-1 row-cols-lg-1 row-cols-xl-2 row-cols-xxl-2 justify-content-center align-items-center" style="margin: 0px;">
<div class="col text-center align-self-center m-auto">
<div class="d-xl-flex align-items-xl-center" style="background: #f1ffff;padding: 10px;border-radius: 10px;">
<div>{{avatar|safe}}</div>
<div class="d-none d-sm-none d-md-none d-lg-none d-xl-block d-xxl-block" style="width: 40px;"></div>
<div>
<div>
<p style="font-size: 24px;">{{hnschat|safe}}</p>
</div>
<div>
<p style="font-size: 24px;">{{email|safe}}</p>
</div>
<div>
<p style="font-size: 24px;">{{location|safe}}</p>
</div>
</div>
</div>
</div>
<div class="col text-center align-self-center m-auto">
<div class="d-xl-flex align-items-xl-center" id="addresses" style="background: #f1ffff;padding: 10px;border-radius: 10px;">
<div>
<div>
<p style="font-size: 24px;margin-bottom: 0px;"><a href="/.well-known/wallets/HNS" target="_blank">{{hns|safe}}</a></p>
</div>
<div>
<p style="font-size: 24px;margin-bottom: 0px;"><a href="/.well-known/wallets/BTC" target="_blank">{{btc|safe}}</a></p>
</div>
<div>
<p style="font-size: 24px;margin-bottom: 0px;"><a href="/.well-known/wallets/ETH" target="_blank">{{eth|safe}}</a></p>
</div>
</div>
</div>
</div>
</div>
</div>
<div style="background: #f1ffff;border-radius: 10px;padding-top: 2%;padding-left: 2%;padding-right: 2%;padding-bottom: 2%;margin: 22px;">
<p style="font-size: 24px;">{{data|safe}}</p>
</div>{{footer | safe}}
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/script.min.js"></script>
</body>
</html>

View File

@@ -0,0 +1,65 @@
<!DOCTYPE html>
<html style="width: 100vw;height: 99vh;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>ShakeCities</title>
<meta name="twitter:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="twitter:card" content="summary">
<meta property="og:type" content="website">
<meta property="og:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:title" content="ShakeCities">
<meta name="twitter:title" content="ShakeCities">
<meta name="twitter:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
</head>
<!-- Template colours
#f1ffff foreground colour
#1fffff text colour
#000000 background colour
These colours will be overriden with the user's colour scheme
-->
<body style="height: 99vh;width: 100vw;color: #1fffff;background: #000000;overflow-x: hidden;">
<div class="text-center" style="margin: 10px;">
<div>{{avatar|safe}}</div> <!-- This needs the safe filter to allow HTML to be rendered -->
<div style="color: #f1ffff;">
<p style="font-size: 24px;">{{hnschat|safe}}</p>
<p style="font-size: 24px;">{{email|safe}}</p>
<p style="font-size: 24px;">{{location|safe}}</p>
</div>
</div>
<div style="background: #f1ffff;border-radius: 10px;padding: 2%;margin: 22px;">
<p style="font-size: 24px;">
{{data|safe}} <!-- This needs the safe filter to allow HTML to be rendered -->
</p>
</div>
<div class="text-center" id="addresses" style="background: #f1ffff;padding: 25px;border-radius: 10px;margin: 22px;"> <!-- Adding the id addresses will remove this div from the page when the user doesn't have any addresses -->
<h1>Donate</h1>
<div>
<p style="font-size: 24px;margin-bottom: 0px;"><a href="/.well-known/wallets/HNS" target="_blank">{{hns|safe}}</a></p>
<p style="font-size: 24px;margin-bottom: 0px;"><a href="/.well-known/wallets/BTC" target="_blank">{{btc|safe}}</a></p>
<p style="font-size: 24px;margin-bottom: 0px;"><a href="/.well-known/wallets/ETH" target="_blank">{{eth|safe}}</a></p>
</div>
</div>
<!-- Footer to display the powered by ShakeCities. -->
{{footer|safe}}
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/script.min.js"></script>
</body>
</html>

View File

@@ -1,37 +1,101 @@
<!DOCTYPE html>
<html data-bs-theme="light" lang="en">
<html data-bs-theme="light" lang="en" style="background: #000000;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>shakecities</title>
<title>ShakeCities | Edit</title>
<meta name="twitter:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="twitter:card" content="summary">
<meta property="og:type" content="website">
<meta property="og:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:title" content="ShakeCities">
<meta name="twitter:title" content="ShakeCities">
<meta name="twitter:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.min.css">
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.woodburn.au/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '7']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
<script async src="https://umami.woodburn.au/script.js" data-website-id="9a7af01b-9ebf-49a9-8337-907ff3744a02"></script>
</head>
<body>
<nav class="navbar navbar-expand-md bg-dark py-3" data-bs-theme="dark">
<div class="container"><a class="navbar-brand d-flex align-items-center" href="/"><span class="bs-icon-sm bs-icon-rounded bs-icon-primary d-flex justify-content-center align-items-center me-2 bs-icon"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-bezier">
<path fill-rule="evenodd" d="M0 10.5A1.5 1.5 0 0 1 1.5 9h1A1.5 1.5 0 0 1 4 10.5v1A1.5 1.5 0 0 1 2.5 13h-1A1.5 1.5 0 0 1 0 11.5v-1zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1zm10.5.5A1.5 1.5 0 0 1 13.5 9h1a1.5 1.5 0 0 1 1.5 1.5v1a1.5 1.5 0 0 1-1.5 1.5h-1a1.5 1.5 0 0 1-1.5-1.5v-1zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1zM6 4.5A1.5 1.5 0 0 1 7.5 3h1A1.5 1.5 0 0 1 10 4.5v1A1.5 1.5 0 0 1 8.5 7h-1A1.5 1.5 0 0 1 6 5.5v-1zM7.5 4a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1z"></path>
<path d="M6 4.5H1.866a1 1 0 1 0 0 1h2.668A6.517 6.517 0 0 0 1.814 9H2.5c.123 0 .244.015.358.043a5.517 5.517 0 0 1 3.185-3.185A1.503 1.503 0 0 1 6 5.5v-1zm3.957 1.358A1.5 1.5 0 0 0 10 5.5v-1h4.134a1 1 0 1 1 0 1h-2.668a6.517 6.517 0 0 1 2.72 3.5H13.5c-.123 0-.243.015-.358.043a5.517 5.517 0 0 0-3.185-3.185z"></path>
</svg></span><span>Brand</span></a><button data-bs-toggle="collapse" class="navbar-toggler" data-bs-target="#navcol-6"><span class="visually-hidden">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse flex-grow-0 order-md-first" id="navcol-6">
<ul class="navbar-nav me-auto">
<li class="nav-item"><a class="nav-link active" href="/signup">Create your page</a></li>
<li class="nav-item"><a class="nav-link" href="/edit">Edit your page</a></li>
</ul>
<div class="d-md-none my-2"><button class="btn btn-light me-2" type="button">Button</button><button class="btn btn-primary" type="button">Button</button></div>
</div>
<div class="d-none d-md-block"><a class="btn btn-primary" role="button" href="/account">{{account}}</a></div>
</div>
</nav>
<body style="background: #000000;color: #ffffff;width: 95%;margin: auto;">
<section>
<section style="height: 15vh;background: url(&quot;assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp&quot;) bottom / cover no-repeat;min-height: 130px;"></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="width: 30vw;border-radius: 50%;background: #000000;padding: 20px;height: 30vw;margin: auto;margin-top: -15vw;display: flex;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="display: block;width: 100%;text-align: center;margin-top: 10px;">
<div style="display: inline-block;margin: auto;"><a class="btn btn-primary" role="button" style="margin: 10px;" href="/signup">Create your page</a><a class="btn btn-primary" role="button" style="margin: 10px;" href="/{{account_link}}">{{account_link_name}}</a></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="display: block;">
<div style="width: 100%;text-align: right;margin-top: -4em;"><a class="btn btn-primary" role="button" style="margin: 10px;" href="/signup">Create a new page</a><a class="btn btn-primary" role="button" style="margin: 10px;" href="/{{account_link}}">{{account_link_name}}</a></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="width: 15vw;border-radius: 50%;background: #000000;padding: 20px;height: 15vw;margin: auto;display: flex;margin-top: -6vw;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="height: 3em;"></section>
</section>
<section style="margin-top: 50px;">
<h1 style="text-align: center;">Edit your page</h1>
<h1 style="text-align: center;margin-bottom: 30px;">Edit your page</h1>
</section>
<section style="width: 80%;margin: auto;">
<form method="post"><textarea class="form-control form-control-lg" rows="25" name="data" placeholder="Website data">{{data}}</textarea><input class="form-control" type="text" style="margin-top: 10px;" placeholder="HNS Address" name="hns" value="{{hns}}"><input class="form-control" type="text" style="margin-top: 10px;" name="btc" placeholder="BTC Address" value="{{btc}}"><input class="form-control" type="text" style="margin-top: 10px;" placeholder="ETH Address" name="eth" value="{{eth}}"><input class="btn btn-primary" type="submit" style="margin-top: 10px;"></form>
<form action="/upload" method="post" enctype="multipart/form-data"><label class="form-label" style="margin-right: 20px;">Avatar</label>
<div style="display: inline-block;">{{avatar|safe}}</div><input class="form-control" type="file" style="display: inline-block;width: 300px;margin-right: 25px;" name="file" accept="image/*" required=""><input class="btn btn-primary" type="submit" style="margin-right: 20px;" value="Upload"><a class="btn btn-primary" role="button" href="/avatar/clear">Clear</a>
</form>
<form class="text-center" method="post"><input class="form-control" type="text" style="margin-top: 10px;" name="location" value="{{location}}" placeholder="Location"><input class="form-control" type="text" style="margin-top: 10px;" name="hnschat" placeholder="HNSChat" value="{{hnschat}}"><input class="form-control" type="text" style="margin-top: 10px;" name="email" placeholder="Public Email" value="{{email}}">
<div class="d-xl-flex justify-content-xl-center align-items-xl-center" style="margin-bottom: 10px;margin-top: 10px;"><label class="form-label" style="display: inline-block;margin-right: 15px;">Background colour&nbsp;</label><input class="form-control form-control-color" type="color" style="display: inline-block;border-radius: 50%;width: 50px;height: 50px;" name="bg_colour" value="{{bg_colour}}"></div>
<div class="d-xl-flex justify-content-xl-center align-items-xl-center" style="margin-bottom: 10px;margin-top: 10px;"><label class="form-label" style="display: inline-block;margin-right: 15px;">Foreground colour&nbsp;</label><input class="form-control form-control-color" type="color" style="display: inline-block;border-radius: 50%;width: 50px;height: 50px;" name="fg_colour" value="{{fg_colour}}"></div>
<div class="d-xl-flex justify-content-xl-center align-items-xl-center" style="margin-bottom: 10px;margin-top: 10px;"><label class="form-label" style="display: inline-block;margin-right: 15px;">Text colour&nbsp;</label><input class="form-control form-control-color" type="color" style="display: inline-block;border-radius: 50%;width: 50px;height: 50px;" name="text_colour" value="{{text_colour}}"></div><textarea class="form-control form-control-lg" rows="15" name="data" placeholder="HTML Content">{{data}}</textarea>
<div class="text-center">
<div><input class="form-control" type="text" style="margin-top: 10px;display: inline-block;width: 500px;" placeholder="HNS Address" name="hns" value="{{hns}}" pattern="hs1[A-Za-z0-9]+"><div class="form-check form-switch form-check-inline" style="display: inline-block;margin-left: 10px;">
<input id="formCheck-1" class="form-check-input" type="checkbox" {% if hip2_display %}checked{% endif %} name="hip2_display" />
<label class="form-check-label" for="formCheck-1">Show as @{{domain}}.{{CITY_DOMAIN}}</label>
</div>
</div>
<div><input class="form-control" type="text" style="margin-top: 10px;width: 500px;display: inline-block;" name="btc" placeholder="BTC Address" value="{{btc}}"></div>
<div><input class="form-control" type="text" style="margin-top: 10px;width: 500px;display: inline-block;" placeholder="ETH Address" name="eth" value="{{eth}}" pattern="0x[A-Za-z0-9]+"></div>
</div>
<div style="margin-top: 10px;display: inline-block;"><label class="form-label" style="margin-right: 25px;">Template</label><select class="form-select" id="template" name="template" style="width:auto;display:inline-block;">
{% for template in templates %}
<option value="{{ template }}" {% if template == selected_template %}selected{% endif %}>{{ template }}</option>
{% endfor %}
</select></div>
<div style="text-align: center;"><input class="btn btn-primary" type="submit" style="margin-top: 10px;"></div>
</form>
</section>
<section style="margin: 20px;height: 40px;text-align: center;margin-top: 40px;">
<footer class="text-center bg-dark"></footer>
<div style="display: inline-block;">
<ul class="list-inline">
<li class="list-inline-item me-4" style="color: rgb(255,255,255);">Copyright © ShakeCities 2023</li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/54/uptime?labelPrefix=Main+Server+' style="height:1.3em;margin-bottom:-.3em;width: 13em;"></iframe></li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/55/uptime?labelPrefix=Cities+' style="height:1.3em;margin-bottom:-.3em;width:11em;"></iframe></li>
</ul>
</div>
</section>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/script.min.js"></script>
</body>
</html>

120
templates/edit_tribe.html Normal file
View File

@@ -0,0 +1,120 @@
<!DOCTYPE html>
<html data-bs-theme="light" lang="en" style="background: black;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>ShakeCities | Tribes</title>
<meta name="twitter:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="twitter:card" content="summary">
<meta property="og:type" content="website">
<meta property="og:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:title" content="ShakeCities">
<meta name="twitter:title" content="ShakeCities">
<meta name="twitter:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.min.css">
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.woodburn.au/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '7']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
<script async src="https://umami.woodburn.au/script.js" data-website-id="9a7af01b-9ebf-49a9-8337-907ff3744a02"></script>
</head>
<body style="width: 95%;margin: auto;background: transparent;color: #ffffff;">
<section>
<section style="height: 15vh;background: url(&quot;assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp&quot;) bottom / cover no-repeat;min-height: 130px;"></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="width: 30vw;border-radius: 50%;background: #000000;padding: 20px;height: 30vw;margin: auto;margin-top: -15vw;display: flex;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="display: block;width: 100%;text-align: center;margin-top: 10px;">
<div style="display: inline-block;margin: auto;"><a class="btn btn-primary" role="button" style="margin: 10px;" href="/signup">Create your page</a><a class="btn btn-primary" role="button" style="margin: 10px;" href="/{{account_link}}">{{account_link_name}}</a></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="display: block;">
<div style="width: 100%;text-align: right;margin-top: -4em;"><a class="btn btn-primary" role="button" style="margin: 10px;" href="/{{account_link}}">{{account_link_name}}</a></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="width: 15vw;border-radius: 50%;background: #000000;padding: 20px;height: 15vw;margin: auto;display: flex;margin-top: -6vw;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="height: 3em;"></section>
</section>
<section style="margin-top: 10px;">
<div class="row" style="margin: 0px;">
<div class="col" style="background: var(--bs-body-color);margin-right: 10px;border-radius: 10px;margin-top: 10px;margin-left: 10px;">
<h1 style="margin: 10px;">Edit {{tribe}} tribe</h1>
<form method="post" style="margin-bottom: 20px;"><input class="form-control" type="text" style="margin-top: 20px;" name="tribe" placeholder="Tribe Name" value="{{tribe}}"><textarea class="form-control" style="margin-top: 20px;" rows="5" placeholder="Content" name="data">{{data}}</textarea>
<p style="margin-top: 20px;">{{members|safe}}</p><input class="btn btn-primary" type="submit" style="margin-top: 20px;" value="Edit"><a class="btn btn-primary" role="button" style="margin-top: 20px;margin-left: 50px;" href="/delete_tribe">Delete Tribe</a>
</form>
</div>
</div>
</section>
<section>
<section class="d-print-none d-md-none d-lg-none d-xl-none d-xxl-none" style="background: var(--bs-body-color);text-align: center;padding-top: 10px;padding-bottom: 10px;margin-bottom: 25px;margin-top: 40px;border-radius: 10px;">
<div style="margin: 20px;">
<h1>Contact</h1>
<div class="list-group list-group-horizontal" data-bs-theme="dark" style="margin: auto;width: 80%;"><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="https://discord.com">Discord</a></button><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="mailto:email@example.com">Email</a></button><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="https://twitter.com">Twitter</a></button></div>
</div>
<div style="margin: 20px;">
<h1>Donate</h1>
<p>hs1qfqy9ewc3g4p06d4m5j8zm74qzhan7rxu7n8u9y</p>
</div>
</section>
<section class="d-none d-print-block d-md-block d-lg-block d-xl-block d-xxl-block" style="background: var(--bs-body-color);text-align: center;padding-top: 10px;padding-bottom: 10px;margin-bottom: 25px;margin-top: 40px;border-radius: 10px;">
<div style="margin: 20px;">
<h1>Contact</h1>
<div class="list-group list-group-horizontal" data-bs-theme="dark" style="margin: auto;width: 50%;"><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="https://l.woodburn.au/discord">Discord</a></button><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="mailto:shakecities@woodburn.au">Email</a></button><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="https://hnschat#channel:woodburn">HNSChat</a></button></div>
</div>
<div style="margin: 20px;">
<h1>Donate</h1>
<p data-bs-toggle="tooltip" data-bss-tooltip="" id="hns_address" title="Copy">hs1qfqy9ewc3g4p06d4m5j8zm74qzhan7rxu7n8u9y</p><script>
function copyToClipboard(element) {
const textToCopy = element.textContent;
const textArea = document.createElement('textarea');
textArea.value = textToCopy;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
}
const hns = document.getElementById('hns_address');
hns.addEventListener('click', () => {
copyToClipboard(hns);
});
</script>
</div>
</section>
</section>
<section style="margin: 20px;height: 40px;text-align: center;margin-top: 40px;">
<footer class="text-center bg-dark"></footer>
<div style="display: inline-block;">
<ul class="list-inline">
<li class="list-inline-item me-4" style="color: rgb(255,255,255);">Copyright © ShakeCities 2023</li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/54/uptime?labelPrefix=Main+Server+' style="height:1.3em;margin-bottom:-.3em;width: 13em;"></iframe></li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/55/uptime?labelPrefix=Cities+' style="height:1.3em;margin-bottom:-.3em;width:11em;"></iframe></li>
</ul>
</div>
</section>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/script.min.js"></script>
</body>
</html>

79
templates/empty_site.html Normal file
View File

@@ -0,0 +1,79 @@
<!DOCTYPE html>
<html data-bs-theme="light" lang="en" style="background: #000000;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>ShakeCities | Empty Site</title>
<meta name="twitter:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="twitter:card" content="summary">
<meta property="og:type" content="website">
<meta property="og:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:title" content="ShakeCities">
<meta name="twitter:title" content="ShakeCities">
<meta name="twitter:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.woodburn.au/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '7']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
<script async src="https://umami.woodburn.au/script.js" data-website-id="9a7af01b-9ebf-49a9-8337-907ff3744a02"></script>
</head>
<body style="background: #000000;width: 95%;margin: auto;">
<section>
<section style="height: 15vh;background: url(&quot;assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp&quot;) bottom / cover no-repeat;min-height: 130px;"></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="width: 30vw;border-radius: 50%;background: #000000;padding: 20px;height: 30vw;margin: auto;margin-top: -15vw;display: flex;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="display: block;width: 100%;text-align: center;margin-top: 10px;">
<div style="display: inline-block;margin: auto;"><a class="btn btn-primary" role="button" style="margin: 10px;" href="/signup">Create your page</a><a class="btn btn-primary" role="button" style="margin: 10px;" href="/{{account_link}}">{{account_link_name}}</a></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="display: block;">
<div style="width: 100%;text-align: right;margin-top: -4em;"></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="width: 15vw;border-radius: 50%;background: #000000;padding: 20px;height: 15vw;margin: auto;display: flex;margin-top: -6vw;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="height: 3em;"></section>
</section>
<section style="width: 50%;margin: auto;margin-top: 50px;">
<div class="card bg-dark" style="padding-bottom: 40px;">
<div class="card-body">
<h4 class="card-title" style="color: rgb(255,255,255);">Nothing here yet</h4>
</div><a class="btn btn-primary" role="button" style="margin: 10px;" href="/">Back</a>
</div>
</section>
<section style="margin: 20px;height: 40px;text-align: center;margin-top: 40px;">
<footer class="text-center bg-dark"></footer>
<div style="display: inline-block;">
<ul class="list-inline">
<li class="list-inline-item me-4" style="color: rgb(255,255,255);">Copyright © ShakeCities 2023</li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/54/uptime?labelPrefix=Main+Server+' style="height:1.3em;margin-bottom:-.3em;width: 13em;"></iframe></li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/55/uptime?labelPrefix=Cities+' style="height:1.3em;margin-bottom:-.3em;width:11em;"></iframe></li>
</ul>
</div>
</section>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/script.min.js"></script>
</body>
</html>

80
templates/error.html Normal file
View File

@@ -0,0 +1,80 @@
<!DOCTYPE html>
<html data-bs-theme="light" lang="en" style="background: #000000;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>ShakeCities | Error</title>
<meta name="twitter:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="twitter:card" content="summary">
<meta property="og:type" content="website">
<meta property="og:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:title" content="ShakeCities">
<meta name="twitter:title" content="ShakeCities">
<meta name="twitter:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.woodburn.au/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '7']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
<script async src="https://umami.woodburn.au/script.js" data-website-id="9a7af01b-9ebf-49a9-8337-907ff3744a02"></script>
</head>
<body style="background: #000000;width: 95%;margin: auto;">
<section>
<section style="height: 15vh;background: url(&quot;assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp&quot;) bottom / cover no-repeat;min-height: 130px;"></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="width: 30vw;border-radius: 50%;background: #000000;padding: 20px;height: 30vw;margin: auto;margin-top: -15vw;display: flex;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="display: block;width: 100%;text-align: center;margin-top: 10px;">
<div style="display: inline-block;margin: auto;"><a class="btn btn-primary" role="button" style="margin: 10px;" href="/signup">Create your page</a><a class="btn btn-primary" role="button" style="margin: 10px;" href="/{{account_link}}">{{account_link_name}}</a></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="display: block;">
<div style="width: 100%;text-align: right;margin-top: -4em;"></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="width: 15vw;border-radius: 50%;background: #000000;padding: 20px;height: 15vw;margin: auto;display: flex;margin-top: -6vw;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="height: 3em;"></section>
</section>
<section style="width: 50%;margin: auto;margin-top: 50px;">
<div class="card bg-dark" style="padding-bottom: 40px;">
<div class="card-body">
<h4 class="card-title" style="color: rgb(255,255,255);">Sorry we ran into an error</h4>
<p style="color: rgb(255,255,255);text-align: center;">{{message | safe}}</p>
</div><a class="btn btn-primary" role="button" style="margin: 10px;" href="javascript:history.back()">Back</a>
</div>
</section>
<section style="margin: 20px;height: 40px;text-align: center;margin-top: 40px;">
<footer class="text-center bg-dark"></footer>
<div style="display: inline-block;">
<ul class="list-inline">
<li class="list-inline-item me-4" style="color: rgb(255,255,255);">Copyright © ShakeCities 2023</li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/54/uptime?labelPrefix=Main+Server+' style="height:1.3em;margin-bottom:-.3em;width: 13em;"></iframe></li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/55/uptime?labelPrefix=Cities+' style="height:1.3em;margin-bottom:-.3em;width:11em;"></iframe></li>
</ul>
</div>
</section>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/script.min.js"></script>
</body>
</html>

81
templates/hnschat.html Normal file
View File

@@ -0,0 +1,81 @@
<!DOCTYPE html>
<html data-bs-theme="light" lang="en" style="background: #000000;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>ShakeCities | HNSChat</title>
<meta name="twitter:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="twitter:card" content="summary">
<meta property="og:type" content="website">
<meta property="og:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:title" content="ShakeCities">
<meta name="twitter:title" content="ShakeCities">
<meta name="twitter:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.woodburn.au/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '7']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
<script async src="https://umami.woodburn.au/script.js" data-website-id="9a7af01b-9ebf-49a9-8337-907ff3744a02"></script>
</head>
<body style="background: #000000;color: #ffffff;width: 95%;margin: auto;">
<section>
<section style="height: 15vh;background: url(&quot;assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp&quot;) bottom / cover no-repeat;min-height: 130px;"></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="width: 30vw;border-radius: 50%;background: #000000;padding: 20px;height: 30vw;margin: auto;margin-top: -15vw;display: flex;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="display: block;width: 100%;text-align: center;margin-top: 10px;">
<div style="display: inline-block;margin: auto;"><a class="btn btn-primary" role="button" style="margin: 10px;" href="/signup">Create your page</a><a class="btn btn-primary" role="button" style="margin: 10px;" href="/{{account_link}}">{{account_link_name}}</a></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="display: block;">
<div style="width: 100%;text-align: right;margin-top: -4em;"><a class="btn btn-primary" role="button" style="margin: 10px;" href="/signup">Create a new page</a><a class="btn btn-primary" role="button" style="margin: 10px;" href="/{{account_link}}">{{account_link_name}}</a></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="width: 15vw;border-radius: 50%;background: #000000;padding: 20px;height: 15vw;margin: auto;display: flex;margin-top: -6vw;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="height: 3em;"></section>
</section>
<section style="margin-top: 50px;">
<h1 style="text-align: center;margin-bottom: 30px;">HNSChat</h1>
</section>
<section style="width: 80%;margin: auto;">
<p>Link your domain to HNSChat using Varo Auth.<br>1. Click Authenticate with Varo Auth<br>2. Enter {{domain}}<br>3. Copy TXT record (including the varo= part) into the below box and save<br>4. Verify your domain (it might take a few minutes for the cache to clear)</p>
<form method="post"><input class="form-control" type="text" style="margin-top: 10px;" name="hnschat" value="{{hnschat}}" placeholder="varo=....." required="" minlength="5">
<div style="text-align: center;"><input class="btn btn-primary" type="submit" style="margin-top: 10px;"></div>
</form>
</section>
<section style="margin: 20px;height: 40px;text-align: center;margin-top: 40px;">
<footer class="text-center bg-dark"></footer>
<div style="display: inline-block;">
<ul class="list-inline">
<li class="list-inline-item me-4" style="color: rgb(255,255,255);">Copyright © ShakeCities 2023</li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/54/uptime?labelPrefix=Main+Server+' style="height:1.3em;margin-bottom:-.3em;width: 13em;"></iframe></li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/55/uptime?labelPrefix=Cities+' style="height:1.3em;margin-bottom:-.3em;width:11em;"></iframe></li>
</ul>
</div>
</section>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/script.min.js"></script>
</body>
</html>

View File

@@ -1,31 +1,135 @@
<!DOCTYPE html>
<html data-bs-theme="light" lang="en">
<html data-bs-theme="light" lang="en" style="background: black;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>shakecities</title>
<title>ShakeCities</title>
<meta name="twitter:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="twitter:card" content="summary">
<meta property="og:type" content="website">
<meta property="og:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:title" content="ShakeCities">
<meta name="twitter:title" content="ShakeCities">
<meta name="twitter:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "WebSite",
"name": "ShakeCities",
"url": "https://shakecities.com"
}
</script>
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.woodburn.au/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '7']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
<script async src="https://umami.woodburn.au/script.js" data-website-id="9a7af01b-9ebf-49a9-8337-907ff3744a02"></script>
</head>
<body>
<nav class="navbar navbar-expand-md bg-dark py-3" data-bs-theme="dark">
<div class="container"><a class="navbar-brand d-flex align-items-center" href="/"><span class="bs-icon-sm bs-icon-rounded bs-icon-primary d-flex justify-content-center align-items-center me-2 bs-icon"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-bezier">
<path fill-rule="evenodd" d="M0 10.5A1.5 1.5 0 0 1 1.5 9h1A1.5 1.5 0 0 1 4 10.5v1A1.5 1.5 0 0 1 2.5 13h-1A1.5 1.5 0 0 1 0 11.5v-1zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1zm10.5.5A1.5 1.5 0 0 1 13.5 9h1a1.5 1.5 0 0 1 1.5 1.5v1a1.5 1.5 0 0 1-1.5 1.5h-1a1.5 1.5 0 0 1-1.5-1.5v-1zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1zM6 4.5A1.5 1.5 0 0 1 7.5 3h1A1.5 1.5 0 0 1 10 4.5v1A1.5 1.5 0 0 1 8.5 7h-1A1.5 1.5 0 0 1 6 5.5v-1zM7.5 4a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1z"></path>
<path d="M6 4.5H1.866a1 1 0 1 0 0 1h2.668A6.517 6.517 0 0 0 1.814 9H2.5c.123 0 .244.015.358.043a5.517 5.517 0 0 1 3.185-3.185A1.503 1.503 0 0 1 6 5.5v-1zm3.957 1.358A1.5 1.5 0 0 0 10 5.5v-1h4.134a1 1 0 1 1 0 1h-2.668a6.517 6.517 0 0 1 2.72 3.5H13.5c-.123 0-.243.015-.358.043a5.517 5.517 0 0 0-3.185-3.185z"></path>
</svg></span><span>Brand</span></a><button data-bs-toggle="collapse" class="navbar-toggler" data-bs-target="#navcol-6"><span class="visually-hidden">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse flex-grow-0 order-md-first" id="navcol-6">
<ul class="navbar-nav me-auto">
<li class="nav-item"><a class="nav-link active" href="/signup">Create your page</a></li>
<li class="nav-item"><a class="nav-link" href="/edit">Edit your page</a></li>
</ul>
<div class="d-md-none my-2"><button class="btn btn-light me-2" type="button">Button</button><button class="btn btn-primary" type="button">Button</button></div>
<body style="width: 95%;margin: auto;background: transparent;color: #ffffff;">
<section>
<section style="height: 15vh;background: url(&quot;assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp&quot;) bottom / cover no-repeat;min-height: 130px;"></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="width: 30vw;border-radius: 50%;background: #000000;padding: 20px;height: 30vw;margin: auto;margin-top: -15vw;display: flex;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="display: block;width: 100%;text-align: center;margin-top: 10px;">
<div style="display: inline-block;margin: auto;"><a class="btn btn-primary" role="button" style="margin: 10px;" href="/signup">Create your page</a><a class="btn btn-primary" role="button" style="margin: 10px;" href="/{{account_link}}">{{account_link_name}}</a></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="display: block;">
<div style="width: 100%;text-align: right;margin-top: -4em;"><a class="btn btn-primary" role="button" style="margin: 10px;" href="/signup">Create a new page</a><a class="btn btn-primary" role="button" style="margin: 10px;" href="/{{account_link}}">{{account_link_name}}</a></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="width: 15vw;border-radius: 50%;background: #000000;padding: 20px;height: 15vw;margin: auto;display: flex;margin-top: -6vw;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="height: 3em;"></section>
</section>
<section style="margin-top: 10px;">
<div class="row" style="margin: 0px;">
<div class="col" style="background: var(--bs-body-color);margin-right: 10px;border-radius: 10px;margin-top: 10px;margin-left: 10px;">
<h1 style="margin: 10px;">Introducing ShakeCities</h1>
<p style="margin: 10px;">ShakeCities is a site offering free personalizable&nbsp;websites. This is a perfect way to start your journey into Handshake domains! Step into a new experience where Handshake domains become instant sites, and where everyone can create their own unique decentralized page.<br>Secured with HTTPS powered by DANE (DNS-based Authentication of Named Entities).<br>But that's not all ShakeCities goes beyond, allowing you to seamlessly integrate crypto addresses into your site, providing an easy way to get paid. Simply send crypto to <code>@yourname.{{CITY_DOMAIN}}</code><br>Your ShakeCity domain can be used to chat on <a href="https://hns.chat" target="_blank">HNSChat</a>&nbsp;or to authenticate on any site using Varo auth<br>Join us in building a decentralized, secure, and innovative internet landscape. Embrace the future with ShakeCities where Handshake domains meet simplicity.</p>
</div>
<div class="col" style="background: var(--bs-body-color);margin-left: 10px;border-radius: 10px;margin-top: 10px;margin-right: 10px;">
<h1 style="margin: 10px;">Find a site</h1>
<p style="margin: 10px;font-size: 20px;">{{random_sites|safe}}</p>
</div>
<div class="d-none d-md-block"><a class="btn btn-primary" role="button" href="/{{account_link}}">{{account}}</a></div>
</div>
</nav>
<div class="row" style="margin: 0px;">
<div class="col" style="background: var(--bs-body-color);margin-right: 10px;border-radius: 10px;margin-top: 10px;margin-left: 10px;">
<h1 style="margin: 10px;">Tribes</h1>
<p style="margin: 10px;font-size: 20px;">{{tribes|safe}}</p>
</div>
</div>
</section>
<section>
<section class="d-print-none d-md-none d-lg-none d-xl-none d-xxl-none" style="background: var(--bs-body-color);text-align: center;padding-top: 10px;padding-bottom: 10px;margin-bottom: 25px;margin-top: 40px;border-radius: 10px;">
<div style="margin: 20px;">
<h1>Contact</h1>
<div class="list-group list-group-horizontal" data-bs-theme="dark" style="margin: auto;width: 80%;"><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="https://discord.com">Discord</a></button><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="mailto:email@example.com">Email</a></button><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="https://twitter.com">Twitter</a></button></div>
</div>
<div style="margin: 20px;">
<h1>Donate</h1>
<p>hs1qfqy9ewc3g4p06d4m5j8zm74qzhan7rxu7n8u9y</p>
</div>
</section>
<section class="d-none d-print-block d-md-block d-lg-block d-xl-block d-xxl-block" style="background: var(--bs-body-color);text-align: center;padding-top: 10px;padding-bottom: 10px;margin-bottom: 25px;margin-top: 40px;border-radius: 10px;">
<div style="margin: 20px;">
<h1>Contact</h1>
<div class="list-group list-group-horizontal" data-bs-theme="dark" style="margin: auto;width: 50%;"><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="https://l.woodburn.au/discord">Discord</a></button><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="mailto:shakecities@woodburn.au">Email</a></button><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="https://hnschat#channel:woodburn">HNSChat</a></button></div>
</div>
<div style="margin: 20px;">
<h1>Donate</h1>
<p data-bs-toggle="tooltip" data-bss-tooltip="" id="hns_address" title="Copy">hs1qfqy9ewc3g4p06d4m5j8zm74qzhan7rxu7n8u9y</p><script>
function copyToClipboard(element) {
const textToCopy = element.textContent;
const textArea = document.createElement('textarea');
textArea.value = textToCopy;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
}
const hns = document.getElementById('hns_address');
hns.addEventListener('click', () => {
copyToClipboard(hns);
});
</script>
</div>
</section>
</section>
<section style="margin: 20px;height: 40px;text-align: center;margin-top: 40px;">
<footer class="text-center bg-dark"></footer>
<div style="display: inline-block;">
<ul class="list-inline">
<li class="list-inline-item me-4" style="color: rgb(255,255,255);">Copyright © ShakeCities 2023</li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/54/uptime?labelPrefix=Main+Server+' style="height:1.3em;margin-bottom:-.3em;width: 13em;"></iframe></li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/55/uptime?labelPrefix=Cities+' style="height:1.3em;margin-bottom:-.3em;width:11em;"></iframe></li>
</ul>
</div>
</section>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/script.min.js"></script>
</body>
</html>

View File

@@ -1,29 +1,60 @@
<!DOCTYPE html>
<html data-bs-theme="light" lang="en">
<html data-bs-theme="light" lang="en" style="background: #000000;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>shakecities</title>
<title>ShakeCities | Login</title>
<meta name="twitter:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="twitter:card" content="summary">
<meta property="og:type" content="website">
<meta property="og:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:title" content="ShakeCities">
<meta name="twitter:title" content="ShakeCities">
<meta name="twitter:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.woodburn.au/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '7']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
<script async src="https://umami.woodburn.au/script.js" data-website-id="9a7af01b-9ebf-49a9-8337-907ff3744a02"></script>
</head>
<body>
<nav class="navbar navbar-expand-md bg-dark py-3" data-bs-theme="dark">
<div class="container"><a class="navbar-brand d-flex align-items-center" href="/"><span class="bs-icon-sm bs-icon-rounded bs-icon-primary d-flex justify-content-center align-items-center me-2 bs-icon"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-bezier">
<path fill-rule="evenodd" d="M0 10.5A1.5 1.5 0 0 1 1.5 9h1A1.5 1.5 0 0 1 4 10.5v1A1.5 1.5 0 0 1 2.5 13h-1A1.5 1.5 0 0 1 0 11.5v-1zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1zm10.5.5A1.5 1.5 0 0 1 13.5 9h1a1.5 1.5 0 0 1 1.5 1.5v1a1.5 1.5 0 0 1-1.5 1.5h-1a1.5 1.5 0 0 1-1.5-1.5v-1zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1zM6 4.5A1.5 1.5 0 0 1 7.5 3h1A1.5 1.5 0 0 1 10 4.5v1A1.5 1.5 0 0 1 8.5 7h-1A1.5 1.5 0 0 1 6 5.5v-1zM7.5 4a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1z"></path>
<path d="M6 4.5H1.866a1 1 0 1 0 0 1h2.668A6.517 6.517 0 0 0 1.814 9H2.5c.123 0 .244.015.358.043a5.517 5.517 0 0 1 3.185-3.185A1.503 1.503 0 0 1 6 5.5v-1zm3.957 1.358A1.5 1.5 0 0 0 10 5.5v-1h4.134a1 1 0 1 1 0 1h-2.668a6.517 6.517 0 0 1 2.72 3.5H13.5c-.123 0-.243.015-.358.043a5.517 5.517 0 0 0-3.185-3.185z"></path>
</svg></span><span>Brand</span></a><button data-bs-toggle="collapse" class="navbar-toggler" data-bs-target="#navcol-6"><span class="visually-hidden">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse flex-grow-0 order-md-first" id="navcol-6">
<ul class="navbar-nav me-auto">
<li class="nav-item"><a class="nav-link active" href="/signup">Create your page</a></li>
<li class="nav-item"><a class="nav-link" href="/edit">Edit your page</a></li>
</ul>
<div class="d-md-none my-2"><button class="btn btn-light me-2" type="button">Button</button><button class="btn btn-primary" type="button">Button</button></div>
</div>
</div>
</nav>
<body style="background: #000000;width: 95%;margin: auto;">
<section>
<section style="height: 15vh;background: url(&quot;assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp&quot;) bottom / cover no-repeat;min-height: 130px;"></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="width: 30vw;border-radius: 50%;background: #000000;padding: 20px;height: 30vw;margin: auto;margin-top: -15vw;display: flex;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="display: block;width: 100%;text-align: center;margin-top: 10px;">
<div style="display: inline-block;margin: auto;"><a class="btn btn-primary" role="button" style="margin: 10px;" href="/signup">Create your page</a><a class="btn btn-primary" role="button" style="margin: 10px;" href="/{{account_link}}">{{account_link_name}}</a></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="display: block;">
<div style="width: 100%;text-align: right;margin-top: -4em;"><a class="btn btn-primary" role="button" style="margin: 10px;" href="/signup">Create a new page</a><a class="btn btn-primary" role="button" style="margin: 10px;" href="/{{account_link}}">{{account_link_name}}</a></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="width: 15vw;border-radius: 50%;background: #000000;padding: 20px;height: 15vw;margin: auto;display: flex;margin-top: -6vw;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="height: 3em;"></section>
</section>
<section style="width: 50%;margin: auto;margin-top: 50px;">
<div class="card bg-dark" style="padding-bottom: 40px;">
<div class="card-body">
@@ -32,7 +63,18 @@
<form style="width: 80%;margin: auto;text-align: right;margin-top: 20px;" method="post"><input class="form-control" type="email" style="margin: auto;width: 100%;margin-top: 10px;" placeholder="email" name="email" required=""><input class="form-control" type="password" style="margin: auto;width: 100%;margin-top: 10px;" name="password" placeholder="Password" required="" minlength="6"><input class="btn btn-primary" type="submit" style="margin-top: 10px;"></form>
</div>
</section>
<section style="margin: 20px;height: 40px;text-align: center;margin-top: 40px;">
<footer class="text-center bg-dark"></footer>
<div style="display: inline-block;">
<ul class="list-inline">
<li class="list-inline-item me-4" style="color: rgb(255,255,255);">Copyright © ShakeCities 2023</li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/54/uptime?labelPrefix=Main+Server+' style="height:1.3em;margin-bottom:-.3em;width: 13em;"></iframe></li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/55/uptime?labelPrefix=Cities+' style="height:1.3em;margin-bottom:-.3em;width:11em;"></iframe></li>
</ul>
</div>
</section>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/script.min.js"></script>
</body>
</html>

117
templates/new_tribe.html Normal file
View File

@@ -0,0 +1,117 @@
<!DOCTYPE html>
<html data-bs-theme="light" lang="en" style="background: black;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>ShakeCities | Tribes</title>
<meta name="twitter:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="twitter:card" content="summary">
<meta property="og:type" content="website">
<meta property="og:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:title" content="ShakeCities">
<meta name="twitter:title" content="ShakeCities">
<meta name="twitter:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.woodburn.au/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '7']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
<script async src="https://umami.woodburn.au/script.js" data-website-id="9a7af01b-9ebf-49a9-8337-907ff3744a02"></script>
</head>
<body style="width: 95%;margin: auto;background: transparent;color: #ffffff;">
<section>
<section style="height: 15vh;background: url(&quot;assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp&quot;) bottom / cover no-repeat;min-height: 130px;"></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="width: 30vw;border-radius: 50%;background: #000000;padding: 20px;height: 30vw;margin: auto;margin-top: -15vw;display: flex;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="display: block;width: 100%;text-align: center;margin-top: 10px;">
<div style="display: inline-block;margin: auto;"><a class="btn btn-primary" role="button" style="margin: 10px;" href="/signup">Create your page</a><a class="btn btn-primary" role="button" style="margin: 10px;" href="/{{account_link}}">{{account_link_name}}</a></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="display: block;">
<div style="width: 100%;text-align: right;margin-top: -4em;"><a class="btn btn-primary" role="button" style="margin: 10px;" href="/{{account_link}}">{{account_link_name}}</a></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="width: 15vw;border-radius: 50%;background: #000000;padding: 20px;height: 15vw;margin: auto;display: flex;margin-top: -6vw;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="height: 3em;"></section>
</section>
<section style="margin-top: 10px;">
<div class="row" style="margin: 0px;">
<div class="col" style="background: var(--bs-body-color);margin-right: 10px;border-radius: 10px;margin-top: 10px;margin-left: 10px;">
<h1 style="margin: 10px;">Create a tribe</h1>
<form method="post" style="margin-bottom: 20px;"><input class="form-control" type="text" style="margin-top: 20px;" name="tribe" placeholder="Tribe Name"><input class="btn btn-primary" type="submit" style="margin-top: 20px;" value="Create"></form>
</div>
</div>
</section>
<section>
<section class="d-print-none d-md-none d-lg-none d-xl-none d-xxl-none" style="background: var(--bs-body-color);text-align: center;padding-top: 10px;padding-bottom: 10px;margin-bottom: 25px;margin-top: 40px;border-radius: 10px;">
<div style="margin: 20px;">
<h1>Contact</h1>
<div class="list-group list-group-horizontal" data-bs-theme="dark" style="margin: auto;width: 80%;"><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="https://discord.com">Discord</a></button><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="mailto:email@example.com">Email</a></button><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="https://twitter.com">Twitter</a></button></div>
</div>
<div style="margin: 20px;">
<h1>Donate</h1>
<p>hs1qfqy9ewc3g4p06d4m5j8zm74qzhan7rxu7n8u9y</p>
</div>
</section>
<section class="d-none d-print-block d-md-block d-lg-block d-xl-block d-xxl-block" style="background: var(--bs-body-color);text-align: center;padding-top: 10px;padding-bottom: 10px;margin-bottom: 25px;margin-top: 40px;border-radius: 10px;">
<div style="margin: 20px;">
<h1>Contact</h1>
<div class="list-group list-group-horizontal" data-bs-theme="dark" style="margin: auto;width: 50%;"><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="https://l.woodburn.au/discord">Discord</a></button><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="mailto:shakecities@woodburn.au">Email</a></button><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="https://hnschat#channel:woodburn">HNSChat</a></button></div>
</div>
<div style="margin: 20px;">
<h1>Donate</h1>
<p data-bs-toggle="tooltip" data-bss-tooltip="" id="hns_address" title="Copy">hs1qfqy9ewc3g4p06d4m5j8zm74qzhan7rxu7n8u9y</p><script>
function copyToClipboard(element) {
const textToCopy = element.textContent;
const textArea = document.createElement('textarea');
textArea.value = textToCopy;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
}
const hns = document.getElementById('hns_address');
hns.addEventListener('click', () => {
copyToClipboard(hns);
});
</script>
</div>
</section>
</section>
<section style="margin: 20px;height: 40px;text-align: center;margin-top: 40px;">
<footer class="text-center bg-dark"></footer>
<div style="display: inline-block;">
<ul class="list-inline">
<li class="list-inline-item me-4" style="color: rgb(255,255,255);">Copyright © ShakeCities 2023</li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/54/uptime?labelPrefix=Main+Server+' style="height:1.3em;margin-bottom:-.3em;width: 13em;"></iframe></li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/55/uptime?labelPrefix=Cities+' style="height:1.3em;margin-bottom:-.3em;width:11em;"></iframe></li>
</ul>
</div>
</section>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/script.min.js"></script>
</body>
</html>

View File

@@ -1,41 +1,82 @@
<!DOCTYPE html>
<html data-bs-theme="light" lang="en">
<html data-bs-theme="light" lang="en" style="background: #000000;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>shakecities</title>
<title>ShakeCities | Signup</title>
<meta name="twitter:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="twitter:card" content="summary">
<meta property="og:type" content="website">
<meta property="og:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:title" content="ShakeCities">
<meta name="twitter:title" content="ShakeCities">
<meta name="twitter:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.woodburn.au/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '7']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
<script async src="https://umami.woodburn.au/script.js" data-website-id="9a7af01b-9ebf-49a9-8337-907ff3744a02"></script>
</head>
<body>
<nav class="navbar navbar-expand-md bg-dark py-3" data-bs-theme="dark">
<div class="container"><a class="navbar-brand d-flex align-items-center" href="/"><span class="bs-icon-sm bs-icon-rounded bs-icon-primary d-flex justify-content-center align-items-center me-2 bs-icon"><svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor" viewBox="0 0 16 16" class="bi bi-bezier">
<path fill-rule="evenodd" d="M0 10.5A1.5 1.5 0 0 1 1.5 9h1A1.5 1.5 0 0 1 4 10.5v1A1.5 1.5 0 0 1 2.5 13h-1A1.5 1.5 0 0 1 0 11.5v-1zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1zm10.5.5A1.5 1.5 0 0 1 13.5 9h1a1.5 1.5 0 0 1 1.5 1.5v1a1.5 1.5 0 0 1-1.5 1.5h-1a1.5 1.5 0 0 1-1.5-1.5v-1zm1.5-.5a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1zM6 4.5A1.5 1.5 0 0 1 7.5 3h1A1.5 1.5 0 0 1 10 4.5v1A1.5 1.5 0 0 1 8.5 7h-1A1.5 1.5 0 0 1 6 5.5v-1zM7.5 4a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1z"></path>
<path d="M6 4.5H1.866a1 1 0 1 0 0 1h2.668A6.517 6.517 0 0 0 1.814 9H2.5c.123 0 .244.015.358.043a5.517 5.517 0 0 1 3.185-3.185A1.503 1.503 0 0 1 6 5.5v-1zm3.957 1.358A1.5 1.5 0 0 0 10 5.5v-1h4.134a1 1 0 1 1 0 1h-2.668a6.517 6.517 0 0 1 2.72 3.5H13.5c-.123 0-.243.015-.358.043a5.517 5.517 0 0 0-3.185-3.185z"></path>
</svg></span><span>Brand</span></a><button data-bs-toggle="collapse" class="navbar-toggler" data-bs-target="#navcol-6"><span class="visually-hidden">Toggle navigation</span><span class="navbar-toggler-icon"></span></button>
<div class="collapse navbar-collapse flex-grow-0 order-md-first" id="navcol-6">
<ul class="navbar-nav me-auto">
<li class="nav-item"><a class="nav-link active" href="/signup">Create your page</a></li>
<li class="nav-item"><a class="nav-link" href="/edit">Edit your page</a></li>
</ul>
<div class="d-md-none my-2"><button class="btn btn-light me-2" type="button">Button</button><button class="btn btn-primary" type="button">Button</button></div>
</div>
<div class="d-none d-md-block"><a class="btn btn-primary" role="button" href="/{{account_link}}">{{account}}</a></div>
</div>
</nav>
<body style="background: #000000;width: 95%;margin: auto;">
<section>
<section style="height: 15vh;background: url(&quot;assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp&quot;) bottom / cover no-repeat;min-height: 130px;"></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="width: 30vw;border-radius: 50%;background: #000000;padding: 20px;height: 30vw;margin: auto;margin-top: -15vw;display: flex;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="display: block;width: 100%;text-align: center;margin-top: 10px;">
<div style="display: inline-block;margin: auto;"><a class="btn btn-primary" role="button" style="margin: 10px;" href="/signup">Create your page</a><a class="btn btn-primary" role="button" style="margin: 10px;" href="/{{account_link}}">{{account_link_name}}</a></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="display: block;">
<div style="width: 100%;text-align: right;margin-top: -4em;"><a class="btn btn-primary" role="button" style="margin: 10px;" href="/signup">Create a new page</a><a class="btn btn-primary" role="button" style="margin: 10px;" href="/{{account_link}}">{{account_link_name}}</a></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="width: 15vw;border-radius: 50%;background: #000000;padding: 20px;height: 15vw;margin: auto;display: flex;margin-top: -6vw;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="height: 3em;"></section>
</section>
<section style="width: 50%;margin: auto;margin-top: 50px;">
<div class="card bg-dark" style="padding-bottom: 40px;">
<div class="card-body">
<h4 class="card-title" style="color: rgb(255,255,255);">Sign up for your free page</h4>
</div>
<form style="width: 80%;margin: auto;text-align: right;margin-top: 20px;" method="post">
<p class="tld" style="position: relative;display: inline;color: rgb(0,0,0);margin-right: 10px;">.exampledomainnathan1</p><input class="form-control" type="text" id="domain" style="margin: auto;width: 100%;margin-top: -30px;" placeholder="yourname" name="domain" required=""><input class="form-control" type="email" style="margin: auto;width: 100%;margin-top: 10px;" placeholder="email" name="email" required=""><input class="form-control" type="password" style="margin: auto;width: 100%;margin-top: 10px;" name="password" placeholder="Password" required="" minlength="6"><input class="btn btn-primary" type="submit" style="margin-top: 10px;">
<p class="tld" style="position: relative;display: inline;color: rgb(0,0,0);margin-right: 10px;">.{{CITY_DOMAIN}}</p><input class="form-control" type="text" id="domain" style="margin: auto;width: 100%;margin-top: -30px;" placeholder="yourname" name="domain" required="" value="{{domain}}"><input class="form-control" type="email" style="margin: auto;width: 100%;margin-top: 10px;" placeholder="email" name="email" required=""><input class="form-control" type="password" style="margin: auto;width: 100%;margin-top: 10px;" name="password" placeholder="Password" required="" minlength="6"><input class="btn btn-primary" type="submit" style="margin-top: 10px;">
</form>
</div>
</section>
<section style="margin: 20px;height: 40px;text-align: center;margin-top: 40px;">
<footer class="text-center bg-dark"></footer>
<div style="display: inline-block;">
<ul class="list-inline">
<li class="list-inline-item me-4" style="color: rgb(255,255,255);">Copyright © ShakeCities 2023</li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/54/uptime?labelPrefix=Main+Server+' style="height:1.3em;margin-bottom:-.3em;width: 13em;"></iframe></li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/55/uptime?labelPrefix=Cities+' style="height:1.3em;margin-bottom:-.3em;width:11em;"></iframe></li>
</ul>
</div>
</section>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/script.min.js"></script>
</body>
</html>

121
templates/tribe.html Normal file
View File

@@ -0,0 +1,121 @@
<!DOCTYPE html>
<html data-bs-theme="light" lang="en" style="background: black;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>ShakeCities | Tribes</title>
<meta name="twitter:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="twitter:card" content="summary">
<meta property="og:type" content="website">
<meta property="og:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:title" content="ShakeCities">
<meta name="twitter:title" content="ShakeCities">
<meta name="twitter:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:description" content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="assets/img/HNS.png">
<link rel="stylesheet" href="assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/styles.min.css">
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.woodburn.au/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '7']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
<script async src="https://umami.woodburn.au/script.js" data-website-id="9a7af01b-9ebf-49a9-8337-907ff3744a02"></script>
</head>
<body style="width: 95%;margin: auto;background: transparent;color: #ffffff;">
<section>
<section style="height: 15vh;background: url(&quot;assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp&quot;) bottom / cover no-repeat;min-height: 130px;"></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="width: 30vw;border-radius: 50%;background: #000000;padding: 20px;height: 30vw;margin: auto;margin-top: -15vw;display: flex;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-print-none d-lg-none d-xl-none d-xxl-none" style="display: block;width: 100%;text-align: center;margin-top: 10px;">
<div style="display: inline-block;margin: auto;"><a class="btn btn-primary" role="button" style="margin: 10px;" href="/signup">Create your page</a><a class="btn btn-primary" role="button" style="margin: 10px;" href="/{{account_link}}">{{account_link_name}}</a></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="display: block;">
<div style="width: 100%;text-align: right;margin-top: -4em;"><a class="btn btn-primary" role="button" style="margin: 10px;" href="/{{account_link}}">{{account_link_name}}</a></div>
</section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="width: 15vw;border-radius: 50%;background: #000000;padding: 20px;height: 15vw;margin: auto;display: flex;margin-top: -6vw;"><a href="/"><img class="img-fluid" src="assets/img/HNSW.png" width="100%"></a></section>
<section class="d-none d-print-block d-lg-block d-xl-block d-xxl-block" style="height: 3em;"></section>
</section>
<section style="margin-top: 10px;">
<div class="row" style="margin: 0px;">
<div class="col" style="background: var(--bs-body-color);margin-right: 10px;border-radius: 10px;margin-top: 10px;margin-left: 10px;">
<h1 style="margin: 10px;">About Tribes</h1>
<p style="margin: 10px;">ShakeCities offers tribes as a way to create communities on ShakeCities. Create a tribe with your group of friends or colleagues.</p>
</div>
<div class="col" style="background: var(--bs-body-color);margin-left: 10px;border-radius: 10px;margin-top: 10px;margin-right: 10px;">
<h1 style="margin: 10px;">Find a tribe</h1>
<p style="margin: 10px;font-size: 20px;">{{tribes|safe}}</p>
</div>
</div>
</section>
<section>
<section class="d-print-none d-md-none d-lg-none d-xl-none d-xxl-none" style="background: var(--bs-body-color);text-align: center;padding-top: 10px;padding-bottom: 10px;margin-bottom: 25px;margin-top: 40px;border-radius: 10px;">
<div style="margin: 20px;">
<h1>Contact</h1>
<div class="list-group list-group-horizontal" data-bs-theme="dark" style="margin: auto;width: 80%;"><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="https://discord.com">Discord</a></button><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="mailto:email@example.com">Email</a></button><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="https://twitter.com">Twitter</a></button></div>
</div>
<div style="margin: 20px;">
<h1>Donate</h1>
<p>hs1qfqy9ewc3g4p06d4m5j8zm74qzhan7rxu7n8u9y</p>
</div>
</section>
<section class="d-none d-print-block d-md-block d-lg-block d-xl-block d-xxl-block" style="background: var(--bs-body-color);text-align: center;padding-top: 10px;padding-bottom: 10px;margin-bottom: 25px;margin-top: 40px;border-radius: 10px;">
<div style="margin: 20px;">
<h1>Contact</h1>
<div class="list-group list-group-horizontal" data-bs-theme="dark" style="margin: auto;width: 50%;"><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="https://l.woodburn.au/discord">Discord</a></button><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="mailto:shakecities@woodburn.au">Email</a></button><button class="list-group-item list-group-item-action" style="width: 33%;padding: 0px;margin: 10px;border-style: none;"><a class="btn btn-primary" role="button" style="width: 100%;" target="_blank" href="https://hnschat#channel:woodburn">HNSChat</a></button></div>
</div>
<div style="margin: 20px;">
<h1>Donate</h1>
<p data-bs-toggle="tooltip" data-bss-tooltip="" id="hns_address" title="Copy">hs1qfqy9ewc3g4p06d4m5j8zm74qzhan7rxu7n8u9y</p><script>
function copyToClipboard(element) {
const textToCopy = element.textContent;
const textArea = document.createElement('textarea');
textArea.value = textToCopy;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
}
const hns = document.getElementById('hns_address');
hns.addEventListener('click', () => {
copyToClipboard(hns);
});
</script>
</div>
</section>
</section>
<section style="margin: 20px;height: 40px;text-align: center;margin-top: 40px;">
<footer class="text-center bg-dark"></footer>
<div style="display: inline-block;">
<ul class="list-inline">
<li class="list-inline-item me-4" style="color: rgb(255,255,255);">Copyright © ShakeCities 2023</li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/54/uptime?labelPrefix=Main+Server+' style="height:1.3em;margin-bottom:-.3em;width: 13em;"></iframe></li>
<li class="list-inline-item me-4"><iframe src='https://uptime.woodburn.au/api/badge/55/uptime?labelPrefix=Cities+' style="height:1.3em;margin-bottom:-.3em;width:11em;"></iframe></li>
</ul>
</div>
</section>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/script.min.js"></script>
</body>
</html>

83
templates/tribe_view.html Normal file
View File

@@ -0,0 +1,83 @@
<!DOCTYPE html>
<html style="width: 100vw;height: 99vh;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>ShakeCities</title>
<meta name="twitter:description"
content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="description"
content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<meta name="twitter:card" content="summary">
<meta property="og:type" content="website">
<meta property="og:image" content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:title" content="ShakeCities">
<meta name="twitter:title" content="ShakeCities">
<meta name="twitter:image"
content="https://shakecities.com/assets/img/alexander-slattery-LI748t0BK8w-unsplash.webp">
<meta property="og:description"
content="Unlock web ownership's future with ShakeCities! Create your free, secure Handshake domain site. Integrate crypto payments, explore HNSChat, and join us in shaping the decentralized web!">
<link rel="icon" type="image/png" sizes="670x700" href="/assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="/assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="/assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="/assets/img/HNSW.png" media="(prefers-color-scheme: dark)">
<link rel="icon" type="image/png" sizes="670x700" href="/assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="/assets/img/HNS.png">
<link rel="icon" type="image/png" sizes="670x700" href="/assets/img/HNS.png">
<link rel="stylesheet" href="/assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="/assets/css/styles.min.css">
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function () {
var u = "https://analytics.woodburn.au/";
_paq.push(['setTrackerUrl', u + 'matomo.php']);
_paq.push(['setSiteId', '7']);
var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
g.async = true; g.src = u + 'matomo.js'; s.parentNode.insertBefore(g, s);
})();
</script>
<!-- End Matomo Code -->
</head>
<body style="height: 99vh;width: 100vw;color: #ffffff;background: #000000;overflow-x: hidden;">
<h1 style="margin: auto;text-align: center;font-size: 5em;">{{tribe}}</h1>
<div style="padding: 2%;margin: 22px;text-align: center;">
<p style="font-size: 24px;">
{{data|safe}} <!-- This needs the safe filter to allow HTML to be rendered -->
</p>
</div>
<div style="padding: 2%;margin: 22px;text-align: center;">
<h2>Tribe members</h2>
<p style="font-size: 24px;">
{{members|safe}} <!-- This needs the safe filter to allow HTML to be rendered -->
</p>
</div>
<!-- Edit footer -->
<div style="height: 100px;"></div>
<div style="position: fixed;bottom: 10px;right:25px;">
<p style="color:#ffffff;">{{edit|safe}}</p>
</div>
</div>
<!-- Footer to display the powered by ShakeCities. -->
<div style="height: 100px;"></div>
<div style="position: fixed;bottom: 10px;left:25px;">
<div style="display: inline-block; background: #ffffff;border-radius: 50%;padding: 10px;">
<img src="/assets/img/HNS.png" width="50px" height="50px">
</div>
<p style="margin-left: 25px; display:inline; color:#ffffff;">Powered by <a style="color: inherit;"
href="https://shakecities.com" target="_blank">ShakeCities</a></p>
</div>
<script src="assets/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/js/script.min.js"></script>
</body>
</html>

340
varo.py Normal file
View File

@@ -0,0 +1,340 @@
import requests
import os
import dotenv
dotenv.load_dotenv()
zone = ""
TLSA = ""
REG_KEY = os.getenv('REG_KEY')
city_domain = os.getenv('CITY_DOMAIN')
if city_domain == "localhost":
city_domain = "exampledomainnathan1"
alt_domains = os.getenv('ALT_DOMAINS')
if alt_domains == None:
alt_domains = []
else:
alt_domains = alt_domains.split(",")
server_ip = os.getenv('CITY_IP')
def update_auth(auth,domain):
verify_ALIAS(domain)
record = get_auth_id(domain)
if record == "":
data = {
"action": "addRecord",
"zone": zone,
"type": "TXT",
"name": domain,
"content": auth,
}
else:
data = {
"action": "updateRecord",
"zone": zone,
"record": record,
"column": "content",
"value": auth
}
if auth == "" and record == "":
return
if auth == "" and record != "":
data = {
"action": "deleteRecord",
"zone": zone,
"record": record
}
# Update TXT record
url = "https://reg.woodburn.au/api"
headers = {
'Authorization': 'Bearer '+REG_KEY,
'Content-Type': 'application/json'
}
r = requests.put(url, headers=headers, json=data)
copy_to_alts(domain)
return r.text
def get_auth_id(domain):
if zone == "":
get_zone()
data = {
"action": "getRecords",
"zone": zone,
"name": domain + "." + city_domain,
"type": "TXT",
"content": ""
}
url = "https://reg.woodburn.au/api"
headers = {
'Authorization': 'Bearer '+REG_KEY,
'Content-Type': 'application/json'
}
r = requests.post(url, headers=headers, json=data)
r = r.json()
if 'data' not in r:
return ""
for record in r['data']:
if 'profile avatar=' not in record['content']:
return record['uuid']
return ""
def get_auth(domain):
if zone == "":
get_zone()
data = {
"action": "getRecords",
"zone": zone,
"name": domain + "." + city_domain,
"type": "TXT",
"content": ""
}
url = "https://reg.woodburn.au/api"
headers = {
'Authorization': 'Bearer '+REG_KEY,
'Content-Type': 'application/json'
}
r = requests.post(url, headers=headers, json=data)
r = r.json()
if 'data' not in r:
return ""
for record in r['data']:
if 'profile avatar=' not in record['content']:
return record['content']
return ""
def get_zone():
global zone
global TLSA
url = "https://reg.woodburn.au/api"
headers = {
'Authorization': 'Bearer '+REG_KEY,
'Content-Type': 'application/json'
}
data = {
"action": "getZones"
}
r = requests.post(url, headers=headers, json=data)
r = r.json()
for domain in r['data']:
if domain['name'] == city_domain:
zone = domain['id']
data = {
"action": "getRecords",
"zone": zone,
"name": "*."+city_domain,
"type": "TLSA",
"content": ""
}
r = requests.post(url, headers=headers, json=data)
r = r.json()
for record in r['data']:
TLSA = record['content']
return zone
def update_avatar(avatar,domain):
verify_ALIAS(domain)
if zone == "":
get_zone()
data = {
"action": "getRecords",
"zone": zone,
"name": domain + "." + city_domain,
"type": "TXT",
"content": ""
}
url = "https://reg.woodburn.au/api"
headers = {
'Authorization': 'Bearer '+REG_KEY,
'Content-Type': 'application/json'
}
r = requests.post(url, headers=headers, json=data)
r = r.json()
record_id = ""
if 'data' in r:
for record in r['data']:
if record['name'] == domain + "." + city_domain:
if 'profile avatar=' in record['content']:
if record['content'].split("profile avatar=")[1] == avatar:
print("Avatar already set", flush=True)
return "Avatar already set"
record_id = record['uuid']
if record_id == "":
data = {
"action": "addRecord",
"zone": zone,
"type": "TXT",
"name": domain,
"content": "profile avatar=" + avatar,
}
else:
data = {
"action": "updateRecord",
"zone": zone,
"record": record_id,
"column": "content",
"value": "profile avatar=" + avatar
}
if avatar == "" and record_id == "":
return
if avatar == "" and record_id != "":
data = {
"action": "deleteRecord",
"zone": zone,
"record": record_id
}
r = requests.post(url, headers=headers, json=data)
copy_to_alts(domain)
return r.text
def verify_ALIAS(domain):
if zone == "":
get_zone()
data = {
"action": "getRecords",
"zone": zone,
"name": domain+"."+city_domain,
"type": "A",
"content": ""
}
url = "https://reg.woodburn.au/api"
headers = {
'Authorization': 'Bearer '+REG_KEY,
'Content-Type': 'application/json'
}
r = requests.post(url, headers=headers, json=data)
r = r.json()
if 'data' in r:
return
data = {
"action": "addRecord",
"zone": zone,
"type": "A",
"name": domain,
"content": server_ip,
}
r = requests.post(url, headers=headers, json=data)
data = {
"action": "addRecord",
"zone": zone,
"type": "TLSA",
"name": "_443._tcp."+domain+"."+city_domain,
"content": TLSA,
}
r = requests.post(url, headers=headers, json=data)
copy_to_alts(domain)
return r.text
def copy_to_alts(domain):
# Get DNS from domain and copy to each alt
data = {
"action": "getRecords",
"zone": zone,
"name": domain+"."+city_domain,
"type": "",
"content": ""
}
url = "https://reg.woodburn.au/api"
headers = {
'Authorization': 'Bearer '+REG_KEY,
'Content-Type': 'application/json'
}
r = requests.post(url, headers=headers, json=data)
r = r.json()
if 'data' not in r:
return
records = r['data']
for alt_domain in alt_domains:
# Get the zone for the alt
alt_zone = ""
data = {
"action": "getZones"
}
r = requests.post(url, headers=headers, json=data)
r = r.json()
for tmpzone in r['data']:
if tmpzone['name'] == alt_domain:
alt_zone = tmpzone['id']
print(alt_zone)
if alt_zone == "":
continue
# Delete all records from domain.alt
data = {
"action": "getRecords",
"zone": alt_zone,
"name": domain+"."+alt_domain,
"type": "",
"content": ""
}
r = requests.post(url, headers=headers, json=data)
r = r.json()
if 'data' in r:
for record in r['data']:
data = {
"action": "deleteRecord",
"zone": alt_zone,
"record": record['uuid']
}
r = requests.post(url, headers=headers, json=data)
print(r.text)
# Add each record to each alt
for record in records:
data = {
"action": "addRecord",
"zone": alt_zone,
"type": record['type'],
"name": domain+"."+alt_domain,
"content": record['content'],
}
print(data)
r = requests.post(url, headers=headers, json=data)
print(r.text)
# Add TLSA record if it doesn't exist
data = {
"action": "getRecords",
"zone": alt_zone,
"name": "_443._tcp."+domain+"."+alt_domain,
"type": "TLSA",
"content": ""
}
r = requests.post(url, headers=headers, json=data)
r = r.json()
if 'data' not in r:
# Get alt TLSA from _443._tcp.alt_domain
data = {
"action": "getRecords",
"zone": alt_zone,
"name": "_443._tcp."+alt_domain,
"type": "TLSA",
"content": ""
}
r = requests.post(url, headers=headers, json=data)
r = r.json()
if 'data' not in r:
continue
for record in r['data']:
ALT_TLSA = record['content']
data = {
"action": "addRecord",
"zone": alt_zone,
"type": "TLSA",
"name": "_443._tcp."+domain+"."+alt_domain,
"content": ALT_TLSA,
}
r = requests.post(url, headers=headers, json=data)
print(r.text)