commit
50233fc07b
|
@ -1,2 +0,0 @@
|
|||
#!/bin/bash
|
||||
who | cut -d' ' -f1 | sort -u | wc -l | xargs echo "active_user_count=" | sed 's/ //'
|
|
@ -1,13 +1,18 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Feed JSON/tdp output from "stats" into mustache template to generate
|
||||
# tilde.town homepage. Invoke periodically from crontab.
|
||||
|
||||
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
|
||||
|
||||
source /var/local/venvs/tildetown/bin/activate
|
||||
|
||||
stats=/usr/bin/stats
|
||||
template=/var/www/tilde.town/template.index.html
|
||||
mustache=/var/local/tildetown/scripts/mustache.hy
|
||||
template=/usr/local/tildetown-scripts/tildetown/templates/frontpage.html
|
||||
mustache=/usr/local/tildetown-scripts/tildetown/mustache.py
|
||||
input_path=/var/www/tilde.town/tilde.json
|
||||
output_path=/var/www/tilde.town/index.html
|
||||
|
||||
($stats || echo '{}') | hy $mustache $template > $output_path
|
||||
deactivate
|
||||
if [ ! -f "$input_path" ]; then
|
||||
print "homepage generation needs missing $input_path"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exec /usr/local/virtualenvs/tildetown/bin/python "$mustache" "$template" < "$input_path" > "$output_path"
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /var/local
|
||||
|
||||
source venvs/tildetown/bin/activate
|
||||
output=$(python tildetown/tildetown-py/stats.py)
|
||||
deactivate
|
||||
echo $output
|
||||
#!/bin/sh
|
||||
# run stats.py in the appropriate virtualenv.
|
||||
#
|
||||
# invoke periodically from crontab and direct the output to
|
||||
# /var/www/tilde.town/tilde.json
|
||||
exec /usr/local/virtualenvs/tildetown/bin/python /usr/local/tildetown-scripts/tildetown/stats.py
|
||||
|
|
|
@ -1,84 +1,169 @@
|
|||
#!/usr/local/bin/python3
|
||||
|
||||
# stats.py - tilde data in tilde data protocol format.
|
||||
# Copyright 2015 Michael F. Lamb <http://datagrok.org>
|
||||
# License: GPLv3+
|
||||
|
||||
"""
|
||||
Outputs JSON data conforming to "~dp (Tilde Description Protocol)" as defined
|
||||
at: http://protocol.club/~datagrok/beta-wiki/tdp.html
|
||||
|
||||
It is a JSON structure of the form:
|
||||
|
||||
{
|
||||
'name': (string) the name of the server.
|
||||
'url': (string) the URL of the server.
|
||||
'signup_url': (string) the URL of a page describing the process required to request an account on the server.
|
||||
'want_users': (boolean) whether the server is currently accepting new user requests.
|
||||
'admin_email': (string) the email address of the primary server administrator.
|
||||
'description': (string) a free-form description for the server.
|
||||
'users': [ (array) an array of users on the server, sorted by last activity time
|
||||
{
|
||||
'username': (string) the username of the user.
|
||||
'title': (string) the HTML title of the user’s index.html page.
|
||||
'mtime': (number) a timestamp representing the last time the user’s index.html was modified.
|
||||
},
|
||||
...
|
||||
]
|
||||
'user_count': (number) the number of users currently registered on the server.
|
||||
}
|
||||
|
||||
We also overload this with some data we were using in the previous version of
|
||||
stats.py, which is of the form:
|
||||
|
||||
{
|
||||
'users': [ (array) of users on the server.
|
||||
{
|
||||
'default': (boolean) Is the user still using their unmodified default index.html?
|
||||
'favicon': (string) a url to an image representing the user
|
||||
},
|
||||
...
|
||||
]
|
||||
'live_user_count': (number) count of live users (those who have changed their index.html)
|
||||
'active_user_count': (number) count of currently logged in users
|
||||
'generated_at': (string) the time this JSON was generated in '%Y-%m-%d %H:%M:%S' format.
|
||||
'generated_at_msec': (number) the time this JSON was generated, in milliseconds since the epoch.
|
||||
'uptime': (string) output of `uptime -p`
|
||||
|
||||
}
|
||||
Usage: stats.py > /var/www/html/tilde.json
|
||||
"""
|
||||
|
||||
import datetime
|
||||
import json
|
||||
from functools import partial
|
||||
from os import listdir
|
||||
from os.path import getmtime, join
|
||||
from datetime import datetime
|
||||
from sh import find, uptime, who, sort, wc, cut
|
||||
from tildetown.util import slurp, thread, p
|
||||
import os
|
||||
import pwd
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
# this script emits json on standard out that has information about tilde.town
|
||||
# users. It denotes who has not updated their page from the default. It also
|
||||
# reports the time this script was run. The user list is sorted by public_html update time.
|
||||
SYSTEM_USERS = ['wiki', 'root', 'ubuntu', 'nate', 'nobody']
|
||||
DEFAULT_HTML_FILENAME = "/etc/skel/public_html/index.html"
|
||||
title_re = re.compile(r'<title[^>]*>(.*)</title>', re.DOTALL)
|
||||
|
||||
SYSTEM_USERS = ['wiki', 'root', 'ubuntu', 'nate']
|
||||
def active_user_count():
|
||||
"""Return the count of unique usernames logged in."""
|
||||
return len(set(line.split()[0] for line in
|
||||
subprocess.check_output(
|
||||
["who"], universal_newlines=True).splitlines()))
|
||||
|
||||
DEFAULT_HTML = slurp("/etc/skel/public_html/index.html")
|
||||
def get_title(indexhtml):
|
||||
"""Given an html file, return the content of its <title>"""
|
||||
with open(indexhtml, 'rt', errors='ignore') as fp:
|
||||
title = title_re.search(fp.read())
|
||||
if title:
|
||||
return title.group(1)
|
||||
|
||||
username_to_html_path = lambda u: "/home/{}/public_html".format(u)
|
||||
def get_users():
|
||||
"""Generate tuples of the form (username, homedir) for all normal
|
||||
users on this system.
|
||||
|
||||
def default_p(username):
|
||||
return DEFAULT_HTML == slurp(join(username_to_html_path(username), "index.html"))
|
||||
"""
|
||||
return ((p.pw_name, p.pw_dir) for p in pwd.getpwall() if
|
||||
p.pw_uid >= 1000 and
|
||||
p.pw_shell != '/bin/false' and
|
||||
p.pw_name not in SYSTEM_USERS)
|
||||
|
||||
def bounded_find(path):
|
||||
# find might return 1 but still have worked fine.
|
||||
return find(path, "-maxdepth", "3", _ok_code=[0,1])
|
||||
def most_recent_within(path):
|
||||
"""Return the most recent timestamp among all files within path, 3
|
||||
levels deep.
|
||||
"""
|
||||
return max(modified_times(path, maxdepth=3))
|
||||
|
||||
def get_active_user_count():
|
||||
return int(wc(sort(cut(who(), "-d", " ", "-f1"), "-u"), "-l"))
|
||||
def modified_times(path, maxdepth=None):
|
||||
"""Walk the directories in path, generating timestamps for all
|
||||
files.
|
||||
"""
|
||||
for root, dirs, files in os.walk(path):
|
||||
if maxdepth and len(root[len(path):].split(os.sep)) == maxdepth:
|
||||
dirs.clear()
|
||||
for f in files:
|
||||
try:
|
||||
yield os.path.getmtime(os.path.join(root, f))
|
||||
except (FileNotFoundError, PermissionError):
|
||||
pass
|
||||
|
||||
def guarded_mtime(path):
|
||||
try:
|
||||
return getmtime(path.rstrip())
|
||||
except Exception as _:
|
||||
return 0
|
||||
def tdp_user(username, homedir):
|
||||
"""Given a unix username, and their home directory, return a TDP format
|
||||
dict with information about that user.
|
||||
|
||||
def modify_time(username):
|
||||
files_to_mtimes = partial(map, guarded_mtime)
|
||||
return thread(username,
|
||||
username_to_html_path,
|
||||
bounded_find,
|
||||
files_to_mtimes,
|
||||
list,
|
||||
max)
|
||||
"""
|
||||
public_html = os.path.join(homedir, 'public_html')
|
||||
index_html = os.path.join(public_html, 'index.html')
|
||||
if os.path.exists(index_html):
|
||||
return {
|
||||
'username': username,
|
||||
'title': get_title(index_html),
|
||||
'mtime': int(most_recent_within(public_html) * 1000),
|
||||
# tilde.town extensions and backward compatibility
|
||||
'favicon': 'TODO',
|
||||
'default': subprocess.call(
|
||||
['diff', '-q', DEFAULT_HTML_FILENAME, index_html],
|
||||
stdout=subprocess.DEVNULL) == 0,
|
||||
}
|
||||
else:
|
||||
return {
|
||||
'username': username,
|
||||
'default': False
|
||||
}
|
||||
|
||||
def sort_user_list(usernames):
|
||||
return sorted(usernames, key=modify_time)
|
||||
def tdp():
|
||||
now = datetime.datetime.now()
|
||||
users = sorted(
|
||||
(tdp_user(u, h) for u, h in get_users()),
|
||||
key=lambda x:x['mtime'],
|
||||
reverse=True)
|
||||
|
||||
def user_generator():
|
||||
ignore_system_users = lambda un: un not in SYSTEM_USERS
|
||||
return filter(ignore_system_users, listdir("/home"))
|
||||
# TDP format data
|
||||
data = {
|
||||
'name': 'tilde.town',
|
||||
'url': 'http://tilde.town',
|
||||
'signup_url': 'http://goo.gl/forms/8IvQFTDjlo',
|
||||
'want_users': True,
|
||||
'admin_email': 'nks@lambdaphil.es',
|
||||
'description': " ".join(l.strip() for l in """
|
||||
an intentional digital community for creating and sharing works of
|
||||
art, educating peers, and technological anachronism. we are a
|
||||
completely non-commercial, donation supported, and committed to
|
||||
rejecting false technological progress in favor of empathy and
|
||||
sustainable computing.
|
||||
""".splitlines()),
|
||||
'user_count': len(users),
|
||||
'users': users,
|
||||
}
|
||||
|
||||
def get_user_data():
|
||||
username_to_data = lambda u: {'username': u,
|
||||
'default': default_p(u),
|
||||
'favicon':'TODO'}
|
||||
live_p = lambda user: not user['default']
|
||||
# tilde.town extensions and backward compatibility
|
||||
data.update({
|
||||
'active_user_count': active_user_count(),
|
||||
'generated_at': now.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'generated_at_msec': int(now.timestamp() * 1000),
|
||||
'uptime': subprocess.check_output(['uptime', '-p'], universal_newlines=True),
|
||||
'live_user_count': sum(1 for x in data['users'] if not x['default']),
|
||||
})
|
||||
|
||||
all_users = thread(user_generator(),
|
||||
sort_user_list,
|
||||
reversed,
|
||||
partial(map, username_to_data),
|
||||
list)
|
||||
|
||||
live_users = list(filter(live_p, all_users))
|
||||
|
||||
active_user_count = get_active_user_count()
|
||||
|
||||
return {'all_users': all_users,
|
||||
'num_users': len(all_users),
|
||||
'num_live_users': len(live_users),
|
||||
'active_user_count': active_user_count,
|
||||
'live_users': live_users,}
|
||||
|
||||
def get_data():
|
||||
user_data = get_user_data()
|
||||
data = {'generated_at': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'site_name': 'tilde.town',
|
||||
'site_url': 'http://tilde.town',
|
||||
'uptime': str(uptime('-p')).rstrip(),}
|
||||
|
||||
data.update(user_data)
|
||||
return data
|
||||
|
||||
def main():
|
||||
print(json.dumps(tdp(), sort_keys=True, indent=2))
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(json.dumps(get_data()))
|
||||
raise SystemExit(main())
|
||||
|
|
|
@ -0,0 +1,381 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>welcome to tilde town!</title>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</head>
|
||||
<body>
|
||||
<h1 style="text-align:center">tilde.town</h1>
|
||||
<h3 style="text-align:center"><em>is a small unix server made for sharing</em></h3>
|
||||
<p style="text-align:center">
|
||||
<a href="/~wiki/faq.html">faq</a>
|
||||
| <a href="/guestbook">sign our guestbook</a>
|
||||
| <a href="http://goo.gl/forms/8IvQFTDjlo">signup</a>
|
||||
| <a href="/~wiki/conduct.html">code of conduct</a>
|
||||
| <a href="/helpdesk">file help ticket</a>
|
||||
| <a href="https://www.patreon.com/nathanielksmith">donate</a>
|
||||
| <a href="/~wiki">wiki</a>
|
||||
</p>
|
||||
<marquee behavior="alternate"><strong>~*~*~* {{active_user_count}} townies active right now *~*~*~</strong></marquee>
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td valign="top" width="20%">
|
||||
<h3>our esteemed users </h3>
|
||||
<sub>({{live_user_count}} / {{user_count}} shown)</sub><br>
|
||||
<sub>generated at {{generated_at}}</sub><br>
|
||||
<sub>sorted by recent changes</sub><br>
|
||||
|
||||
<ul>
|
||||
{{#users}}
|
||||
{{^default}}
|
||||
<li>
|
||||
<a href="/~{{username}}">{{username}}</a>
|
||||
</li>
|
||||
{{/default}}
|
||||
{{/users}}
|
||||
</ul>
|
||||
<a href="/users.html">full user list</a>
|
||||
</td>
|
||||
<td valign="top" width="40%">
|
||||
<p>this site is an intentional digital community for creating and
|
||||
sharing works of art, educating peers, and technological
|
||||
anachronism. we are a completely
|
||||
non-commercial, <a href="https://www.patreon.com/nathanielksmith?ty=h">donation supported</a>, and
|
||||
committed to rejecting false technological progress in favor of
|
||||
empathy and sustainable computing.</p>
|
||||
|
||||
<h3>stuff you can do here</h3>
|
||||
<ul>
|
||||
<li>geocities style hosting</li>
|
||||
<li>internal irc network</li>
|
||||
<li>private usenet constellation</li>
|
||||
<li>internal mail</li>
|
||||
<li>command line / unix tutelage</li>
|
||||
<li>make ascii art</li>
|
||||
<li>host twitter bots</li>
|
||||
<li>participate in our <a href="https://twitter.com/tildetown">communal twitter</a></li>
|
||||
<li>generate random poetry <em>(under construction)</em></li>
|
||||
</ul>
|
||||
|
||||
<a style="text-decoration:none" href="/cgi/random">
|
||||
<pre title="go to a random page">
|
||||
|
||||
|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
|
||||
| ! /\ | X |
|
||||
| ! //\\ | / \ |
|
||||
| @@@ ! |~~~~~~~~~~~~~| ///\\\ |/ \|
|
||||
| @@@@@ /i\|=============| ////\\\\ |\ /|
|
||||
| @@@ /(i)\====== == ===| /////\\\\\| \ / |
|
||||
| /((i))\============| //////\\\\\\ X |
|
||||
| |% % %|=== ===== ==| I||||||||||I / \ |
|
||||
| |% % %|====== =====| I||||||||||I/ \|
|
||||
|::: |% # %|============| I||||||||||I\ /|
|
||||
|::: |% % %|= ====== ===| I||||||||||I \ / |
|
||||
|::: |% % #|==== ==+++++++++++++|||||||I X |
|
||||
|:::HHHHHHHHHHHH |% % %|=======! ! ! ! ! ! !|||||||I / \ |
|
||||
|:::HHHHHH HHHHH |% # %|= =====! ! ! ! ! ! !|||||||I/ \|
|
||||
|:::HHHHHHHHHHHH |# % %|=== ===! ! ! ! ! ! !|||||||I\ /|
|
||||
|:::HHH HHHHHHHH |% % %|=======! ! ! ! ! ! !|||||||I \ / |
|
||||
|:::HHHHHHTTTTTTTTTTTTTTT % #|== = ==! ! ! ! ! ! !|||||||I X |
|
||||
|:::HHHHHHI [] [] [] [] I # #|=======! ! ! ! ! ! !|||||||I / \ |
|
||||
|::: HHHHHI [] [] [] [] I % %|==== =! ! ! ! ! ! !|||||||I/ \|
|
||||
|:::HHHH HI [] [] [] [] I # %|== ====! ! ! ! ! ! !|||||||I\ /|
|
||||
|:::HHHHHHI [] [] [] [] I % %|=======! ! ! ! ! ! !|||||||I \ / |
|
||||
|:::HHHHHHI [] [] [] [] I % #|=== = =! ! ! ! ! ! !|||||||I X |
|
||||
|:::HH HHHI [] [] [] [] I % #| ======! ! ! ! ! ! !|||||||I / \ |
|
||||
|:::HHHHHHI [] [] [] [] I # #|= = ===! ! ! ! ! ! !|||||||I/ \|
|
||||
|:::HHHHH I [] [] [] [] I % %|==== ==! ! ! ! ! ! !|||||||I\ /|
|
||||
|:::HHHHHHI [] [] [] [] I % #|=======! ! ! ! ! ! !|||||||I \ / |
|
||||
|:::HHHHHHI [] [] [] [] I # #|= =====! ! ! ! ! ! !|||||||I X |
|
||||
|:::H HHHHI [] [] [] [] I # #|=== = =! ! ! ! ! ! !|||||||I / \ |
|
||||
|:::HHHHHHI [] [] [] [] I # #|=======! ! ! ! ! ! !|||||||I/ \|
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
o | | |
|
||||
_|_ | | __| _ _|_ __ _ _
|
||||
| | |/ / | |/ | / \_| | |_/ |/ |
|
||||
|_/|_/|__/\_/|_/|__/o|_/\__/ \/ \/ | |_/
|
||||
</pre>
|
||||
</a>
|
||||
<hr>
|
||||
<pre>
|
||||
orators, singers, musicians to come!
|
||||
She will break it to you better than I can.
|
||||
Saturn expelled his father, and seized his throne
|
||||
-- I wish our opinions were the same.
|
||||
Ere departing fade from my eyes your forests of bayonets
|
||||
Emma soon recollected, and understood him
|
||||
|
||||
--'''' My dear papa, he is three-and-twenty.
|
||||
I hope time has not made you less willing to pardon.
|
||||
; Nay-be calm, for I am so: Does it burn?
|
||||
She will break it to you better than I can.
|
||||
play the part that looks back on the actor or actress!
|
||||
She continued to look back, but in vain
|
||||
|
||||
It is necessary and beside the large sort is puff.
|
||||
; she is living in dread of the visit.
|
||||
Year of comets and meteors transient and strange
|
||||
;'' remember that I am here.-- Mr.
|
||||
She will break it to you better than I can.
|
||||
; and Emma was quite in charity with him.
|
||||
|
||||
It is a mere nothing after all
|
||||
The doors of the two rooms were just opposite each other.
|
||||
She will break it to you better than I can.
|
||||
I shall just go round by Mrs. Cole 's
|
||||
Here is realization, Here is a man tallied
|
||||
Even pleasure, you know, is fatiguing
|
||||
|
||||
Keep your raptures for Harriet 's face.
|
||||
Ere departing fade from my eyes your forests of bayonets
|
||||
For to one side she leans, Then back she sways
|
||||
It soon appeared that London was not the place for her.
|
||||
Perhaps they had the figure of a winged horse on the prow
|
||||
She will break it to you better than I can.
|
||||
|
||||
She will break it to you better than I can.
|
||||
To conclude, I announce what comes after me.
|
||||
; nothing delineated or distinguished.
|
||||
Excelsior Who has gone farthest?
|
||||
To girlhood, boyhood look, the teacher and the school.
|
||||
`` How I could so long a time be fancying myself!
|
||||
|
||||
`` Yes, sometimes he can.'' Do you mean with regard to this letter?''
|
||||
Any nonsense will serve. the flesh over and over!
|
||||
Eleves, I salute you!`` I not aware!'
|
||||
</pre>
|
||||
<hr>
|
||||
<pre>
|
||||
Have you guess 'd you yourself would not continue?
|
||||
The wanderer would not heed me
|
||||
`` He told me at parting, that he should soon write
|
||||
Mr. Elton looked all happiness at this proposition
|
||||
what is it to us what the rest do or think?
|
||||
I doubted it more the next day on Box Hill
|
||||
|
||||
Come thou, arise from the ground unto the place yonder
|
||||
One was the son of Mars, and was killed before Troy
|
||||
He had done his duty and could return to his son.
|
||||
I never saw any thing so outree!
|
||||
; woods, together with mountains, are on fire.
|
||||
`` He told me at parting, that he should soon write
|
||||
|
||||
`` He told me at parting, that he should soon write
|
||||
; and, abhorring the light, they fly { abroad} by night.
|
||||
Can not you guess what this parcel holds?''
|
||||
And these things I see suddenly, what mean they?
|
||||
And you, paid to defile the People
|
||||
Very strongly may be sincerely fainting.
|
||||
|
||||
she cried with a most open eagerness
|
||||
`` He told me at parting, that he should soon write
|
||||
Let me hear from you without delay
|
||||
By him she was put in mind of what she might do
|
||||
; but Emma 's countenance was as steady as her words.
|
||||
Dear Miss Woodhouse, do advise me.''
|
||||
|
||||
It was certainly ‘barbara’ in the eyes of a Greek
|
||||
One can not creep upon a journey
|
||||
One was the son of Mars, and was killed before Troy
|
||||
`` He told me at parting, that he should soon write
|
||||
[ 77 and struck the guilty{ draught} from his mouth.
|
||||
; The golden sun of June declines, It has not caught her eye.
|
||||
|
||||
Clarke translates ‘miseri senis ore,
|
||||
: naught there is Save body, having property of touch.
|
||||
Alas poor boy, he will never be better,
|
||||
; but if he wished to do it, it might be done.
|
||||
`` He told me at parting, that he should soon write
|
||||
One was the son of Mars, and was killed before Troy
|
||||
|
||||
I knew who it came from. The virgin shrieks aloud
|
||||
To feel the presence of a brave commanding officer But she was always right.
|
||||
I 'd rather you would.'' This was a river of Troy
|
||||
</pre>
|
||||
</td>
|
||||
<td valign="top" width="40%">
|
||||
<h3>news</h3>
|
||||
|
||||
<h4>Systems status</h4>
|
||||
<p><sub><em>Wed Oct 14 13:49:12 PDT 2015</em></sub></p>
|
||||
<p>
|
||||
~vilmibm released a rewrite to the server's infrastructure yesterday. Nothing should be different, but it'll be much easier to work on new features and consume fewer resources.
|
||||
</p>
|
||||
<p>
|
||||
Currently, the <strong>guestbook</strong> is down. Usenet has also been disabled for now since no one was using it and it has a nontrivial impact on the system. If you want to talk about bringing usenet back, bring it up in irc <3.
|
||||
</p>
|
||||
|
||||
|
||||
<h4>BIRTHDAY! The Town Turns 1</h4>
|
||||
<p><sub><em>Sun Oct 11 18:54:35 UTC 2015</em></sub></p>
|
||||
<p>
|
||||
Exactly a year ago, <a href="/~vilmibm">~vilmibm</a> gave himself
|
||||
a birthday present in the form of a small unix server meant for
|
||||
commnunity and sharing. Now, tilde.town is a thriving community of
|
||||
feels, peer education and beautiful digital art.
|
||||
</p>
|
||||
<p>
|
||||
If you are not yet a towner, check out our <a
|
||||
href="http://tilde.town/~wiki/conduct.html">code of conduct</a>,
|
||||
look at some user pages, and <a
|
||||
href="https://docs.google.com/forms/d/1FSv_-gEU9LDy0b5gL8xm23d5QomMHIIstgr_fL5GFmg/viewform?c=0&w=1">sign
|
||||
up!</a>. Everyone is welcome here regardless of skill level and if
|
||||
making SSH keys is a little scary, that's okay. Reach out to <a
|
||||
href="https://twitter.com/tildetown">for help</a>.
|
||||
</p>
|
||||
<p>
|
||||
<strong>Here's to another year of html and feels.</strong>
|
||||
</p>
|
||||
|
||||
<h4>new stuff!</h4>
|
||||
<p><sub><em>Sat Aug 1 17:27:15 PDT 2015</em></sub></p>
|
||||
<p>
|
||||
today was a day of things happening!
|
||||
<ul>
|
||||
<li>the first ever tilde.town volunteer admin meeting happened today. <a href="/~insom">~insom</a>, <a href="/~krowbar">~krowbar</a>, and <a href="/~vilmibm">~vilmibm</a> all met to talk about the future tilde.town and how to ease the burden of things like user signups. Marks the first ever international face-to-face meeting of townies. exciting!
|
||||
</li>
|
||||
<li>
|
||||
<a href="/guestbook">guestbook</a> went live! (<em>lol</em>)
|
||||
</li>
|
||||
<li>
|
||||
you can now click on the pretty ascii tilde.town over to the
|
||||
left to visit a random page (or just go directly
|
||||
to <a href="/cgi/random">/cgi/random</a>).
|
||||
</li>
|
||||
</ul>
|
||||
as always, tilde.town is a place for html and feels. feels run
|
||||
strong and well today. come say hi!
|
||||
</p>
|
||||
<p><sub><em>Sun Jul 26 18:01:58 PDT 2015</em></sub></p>
|
||||
<h4>new homepage design</h4>
|
||||
<p><sub><em>Sun Jul 26 18:01:58 PDT 2015</em></sub></p>
|
||||
<p>
|
||||
<a href="/~vilmibm">~vilmibm</a> made a cleaned up homepage. it's linking to two under construction feature--a new help desk for admin requests and a random page linker. there is also a new <a href="/~wiki/faq.html">FAQ</a>.
|
||||
</p>
|
||||
<p>
|
||||
we've also hit a cool donation milestone of $60. thank you
|
||||
everyone who has donated! our monthly costs are now covered and if
|
||||
we hit $65 we can do some more server enhancements.
|
||||
</p>
|
||||
|
||||
<h4>donations! also, new disk</h4>
|
||||
<p><sub><em>Wed Apr 29 06:04:58 UTC 2015</em></sub></p> <p>An exciting day for
|
||||
tilde.town. We now have way to donate via <a
|
||||
href="https://www.patreon.com/nathanielksmith">patreon</a>. Thanks to all the
|
||||
folx who have already become patrons! y'all make the heart of this sysadmin
|
||||
warm and fuzz. A big part of the push for donations was a need for more server
|
||||
space which we have as of tonight's server upgrade/reboot. The main tilde.town
|
||||
server now has a 40gb disk. Enjoy!</p>
|
||||
|
||||
<p>Some updates coming down the pipe:
|
||||
<ul>
|
||||
<li>2gb quota for all users</li>
|
||||
<li>fixed poetry server</li>
|
||||
<li>better signup process/docs</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<h4>welcome haiku</h4>
|
||||
<p><sub><em> Thu Mar 5 21:19:42 UTC 2015</em></sub></p>
|
||||
<p>If you signed up in the last two months or so you had a bum welcome present
|
||||
in your /home. the script has been fixed and now everyone retroactively has a
|
||||
welcome haiku in their home directory. enjoy.</p>
|
||||
|
||||
<h4>server restart</h4>
|
||||
<p><sub><em>Tue Jan 27 21:13:27 UTC 2015</em></sub></p>
|
||||
<p>Hi. Today tilde.town had to restart to pick up a patch for <a
|
||||
href="http://seclists.org/oss-sec/2015/q1/276">CVE 2015-0235</a>.
|
||||
data.tilde.town (our poetry server) has also been patched and restated. Sorry
|
||||
for any inconvenience!</p>
|
||||
|
||||
<h4>lots of people</h4>
|
||||
<p><sub><em>Thu Jan 1 07:37:16 UTC 2015</em></sub></p>
|
||||
<p>we have ~370 users. isn't that wild?</p>
|
||||
|
||||
<h4>Scheduled Downtime Tonight</h4>
|
||||
<p><sub><em>Wed Nov 26 21:19:12 UTC 2014</em></sub></p>
|
||||
|
||||
<p>To accommodate our growing user base, there will be a server resize/reboot
|
||||
tonight (Pacific time). Sadly I cannot give an exact time as I still don't have
|
||||
internet at my new place and will have to opportunistically find some to
|
||||
execute this upgrade.</p>
|
||||
<p>The server should only be down for a few minutes, but this will terminate
|
||||
any running applications (like tmux/screen/irssi). Any files open in an editor
|
||||
should be preserved by a swap file but you still may want to save and close
|
||||
things in the next several hours.</p>
|
||||
<p>Also, this upgrade means that tilde.town is no longer an essentially free
|
||||
project, so I may put up something for donations soon.</p>
|
||||
|
||||
<h4>100+ users party report</h4>
|
||||
<p><sub><em>Sun Nov 9 23:07:08 UTC 2014</em></sub></em>
|
||||
<p>tilde.town now has 102 users. We crossed into three digits last night and
|
||||
lots of townies hung out in irc to celebrate. Some new features even
|
||||
launched!</p>
|
||||
|
||||
<ul>
|
||||
<li>the homepage userlist is now sorted by modified time</li>
|
||||
<li>there is now a shared <pre>tweet</pre> command that all users can use to tweet to the <a href="http://twitter.com/tildetown">@tildetown</a> account (protip: <pre>haiku | tweet</pre>)</li>
|
||||
<li>run <pre>random_pokemon.sh</pre> to get a random ascii art pokemon (thanks, <a href="http://tilde.town/~sanqui">~sanqui</a>)</li>
|
||||
<li>a <a href="http://tilde.town/~wiki">git-based wiki</a> that all townies can edit (thanks for the help, <a href="http://tilde.town/~datagrok">~datagrok</a>)</li>
|
||||
<li>an IRC bot (thanks, <a href="http://tilde.town/~selfsame">~selfsame</a>) that plays numberwang</li>
|
||||
<li>even moar learnings up on the page of <a href="http://tilde.town/~shanx">~shanx</a></li>
|
||||
<li>general good feels</li>
|
||||
</ul>
|
||||
|
||||
<h4>80 users!</h4>
|
||||
<p><sub><em>Wed Oct 29 18:19:45 UTC 2014</em></sub></em>
|
||||
|
||||
<p>tilde.town just added its 80th user. Welcome! Some folks have been having
|
||||
trouble with ssh public keys. Remember, public keys are really confusing if you
|
||||
aren't too familiar with them, and there is no judgement if you can't
|
||||
immediately get them to work. Feel free to tweet at <a
|
||||
href="https://twitter.com/tildetown">@tildetown</a> or send an email to <a
|
||||
href="mailto:nks@lambdaphil.es">~vilmibm</a> if you'd like some help.</p>
|
||||
|
||||
</p>
|
||||
|
||||
<h4>60 users</h4>
|
||||
<p><sub><em>Sat Oct 25 19:37:47 UTC 2014</em></sub></em>
|
||||
<p>tilde.town is up to 60 users. This is lovely! It is also only a tenth of our
|
||||
planned total user capacity, so if you are interested in a tilde* account we'd
|
||||
love to have you. You can even submit a user request with a fancy form now!</p>
|
||||
|
||||
<p>
|
||||
<strong><a href="http://goo.gl/forms/8IvQFTDjlo">submit a user account request!</a></strong>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
<h4>Change of IP, warnings when you ssh</h4>
|
||||
<p><sub><em>Sun Oct 19 03:28:59 UTC 2014</em></sub></p>
|
||||
<p>
|
||||
In the interest of making sure we don't suddenly disappear from the Internet
|
||||
as a result of a dynamic IP change on AWS I switched to using an Elastic
|
||||
IP (amusingly, "elastic" IPs are static).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The upside is that we now have a static IP (also it's free) (woo).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The downside is that when you try to SSH into tilde.town, now, you'll get an
|
||||
error about "something nasty" and there will be many @ characters. You'll want
|
||||
to edit your .ssh/known_hosts file and remove the entry for tilde.town (your
|
||||
error message should have a cute copy-pasta-able one-liner for doing this for
|
||||
you).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Go ahead and do that, and then log in With Confidence. Hopefully this won't happen again.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
I'll close by mentioning the imminent arrival of many new tildeverse members. We (the tildeverse operators) are just about ready to accept the signups currently languishing in a waitlist. This means lots of new users, which is lovely, but may mean some growing pains while I adapt our server to the new user load in the most cost-effective way.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue