-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathremote.py
More file actions
117 lines (106 loc) · 3.97 KB
/
Copy pathremote.py
File metadata and controls
117 lines (106 loc) · 3.97 KB
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
#!/usr/bin/python
#Licensed under the GPLv2 (not later versions)
#see LICENSE.txt for details
import cgi
import os
import re
import lindenip
import time
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import memcache
def QueueString(av):
cachekey = 'queuestring-%s' % (av)
cachedata = memcache.get(cachekey)
query = QueuedCommand2.gql('WHERE av = :1', av)
if cachedata is not None:
#delete data from datastore
for record in query:
record.delete()
#delete data from cache
memcache.delete(cachekey, 0)
#return data
return cachedata
else:
#check memcache for av's queuestring. if present, return, and delete both cache and db values
#if not present, do as below
if query.count() > 0:
#return the string, capped at 2048
out = ''
for record in query:
add = '%s|%s\n' % (record.str, record.sender)
if len(out + add) < 2000:#lazy cushion of 48 chars so that 'more' itself isn't past the cap
out += add
record.delete()
else:
out += 'more'
return out
return out
else:
return None
def Enqueue(av, str, sender):
cachekey = 'queuestring-%s' % (av)
cachedata = memcache.get(cachekey)
if cachedata is not None:
#append
cachedata += '%s|%s\n' % (str, sender)
memcache.replace(cachekey, cachedata, 3600, 0)
else:
#just set
memcache.add(cachekey, '%s|%s\n' % (str, sender), 3600)
cmd = QueuedCommand2(av = av, str = str, sender = sender, ts = time.time())
cmd.put()
def CleanUp():
#look up all QueuedCommands older than timeout, and delete
timeout = 3600.0 #1 hour
query = QueuedCommand2.gql('WHERE ts < :1', time.time() - timeout)
for record in query:
record.delete()
class QueuedCommand2(db.Model):
av = db.StringProperty(required = True)
str = db.StringProperty(required = True)
sender = db.StringProperty(required = True)
ts = db.FloatProperty(required = True)#unix time showing when the cmd was given
class MainPage(webapp.RequestHandler):
def get(self):
#check linden ip
if not lindenip.inrange(os.environ['REMOTE_ADDR']):
self.redirect("/webinterface/", False)
else:
av = self.request.headers['X-SecondLife-Owner-Key']
out = QueueString(av)
if out is None:
#self.error(404)
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write(out)
else:
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write(out)
#get key
#look up cmds for key
#return in newline-delimited page, 2048 char limit, "more" if necessary
def put(self):
#check linden IP
if not lindenip.inrange(os.environ['REMOTE_ADDR']):
self.error(403)
else:
#get sender key
sender = self.request.headers['X-SecondLife-Owner-Key']
#url should be 'remote/<rcpt>/<num>/<str>
av = self.request.path.split("/")[-1]
cmd = self.request.body
#need to handle invalid keys somehow... maybe just delete all moldy queuedcommands on each request
#enqueue command
CleanUp()
Enqueue(av, cmd, sender)
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('enqueued %s=%s' % (self.request.path, cmd))
application = webapp.WSGIApplication(
[('.*', MainPage)
],
debug=True)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()