-
Notifications
You must be signed in to change notification settings - Fork 7
/
cli.py
176 lines (141 loc) · 3.89 KB
/
cli.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
import os
import sys
import inspect
import werkzeug
import util
import fcgi
import config
import board
import interboard
from util import local
COMMANDS = {}
# decorators
def command(f):
COMMANDS[f.__name__] = f
return f
def need_application(f):
f.need_application = True
return f
def need_environment(f):
f.need_environment = True
return f
# commands
@command
@need_environment
def rebuild_cache(board_name):
"""
$0 rebuild_cache board_name
"""
this_board = board.Board(board_name)
local.environ['waka.board'] = this_board
this_board.rebuild_cache()
@command
@need_environment
def delete_by_ip(ip, boards):
"""
$0 delete_by_ip ip boards
"""
boards = boards.split(",")
interboard.process_global_delete_by_ip(ip, boards)
@command
@need_environment
def rebuild_global_cache():
"""
$0
"""
interboard.global_cache_rebuild()
def reset_password(username):
"""
$0 reset_password username
"""
import staff
new_password = os.urandom(8).encode("base64").strip("=\n")
try:
staff.edit_staff(username, clear_pass=new_password)
except staff.LoginError:
print "No such user %r" % username
else:
print "Password of %r set to %r" % (username, new_password)
@command
@need_application
def http(application, host='', port=8000):
"""
$0 http [host [port]]
Defaults to listening on all interfaces, port 8000
"""
app_path = os.path.basename(sys.argv[0])
werkzeug.run_simple(host, int(port),
util.wrap_static(application, app_path,
index='wakaba.html'),
use_reloader=True, use_debugger=config.DEBUG)
@command
@need_application
def fcgi_tcp(application, host='127.0.0.1', port=9000):
"""
$0 fcgi_tcp [host [port]]
Defaults to listening on 127.0.0.1, port 9000
"""
fcgi.WSGIServer(application, bindAddress=(host, int(port))).run()
@command
@need_application
def fcgi_unix(application, path):
"""
$0 fcgi_unix path
"""
fcgi.WSGIServer(application, bindAddress=path).run()
@command
def help(command=None):
"""
$0 help [command]
"""
print "Wakarimasen CLI"
f = COMMANDS.get(command, None)
if f is None:
print "Commands:", ', '.join(sorted(COMMANDS.keys()))
else:
docstring = str(f.__doc__).replace("$0", sys.argv[0])
print "Usage:", docstring
def init_environ():
"""
Initialize a wsgi-ish environment for commands.
Tries to get variables from the OS env and checks for required ones.
"""
ENV_VAR_HELP = """
Environment variables explanation:
- DOCUMENT_ROOT: full filesystem path to html files
ex: /srv/http/imageboard.example.com/
- SCRIPT_NAME: url to wakarimasen.py without host part
ex: /wakarimasen.py
- SERVER_NAME: hostname of the webserver
ex: imageboard.example.com
- SERVER_PORT: port of the webserver (optional)
ex: 80
"""
local.environ.update(os.environ)
werkzeug.BaseRequest(local.environ)
local.environ.setdefault('waka.rootpath',
os.path.join('/', config.BOARD_DIR, ''))
local.environ.setdefault('wsgi.url_scheme', 'http')
local.environ.setdefault('SERVER_PORT', '80')
required_vars = ['DOCUMENT_ROOT', 'SCRIPT_NAME', 'SERVER_NAME']
for var in required_vars:
if var not in local.environ:
print "Error: %s not in environment" % (var,)
print ENV_VAR_HELP
sys.exit(1)
def handle_command(args, application):
name = args.pop(0)
f = COMMANDS.get(name, help)
if hasattr(f, 'need_application'):
args.insert(0, application)
if hasattr(f, 'need_environment'):
# Initialize environment
init_environ()
try:
# attempt to call function with specified arguments
inspect.getcallargs(f, *args)
except TypeError:
# it doesn't fit
help(name)
sys.exit(1)
f(*args)