]> git.frykholm.com Git - friends.git/blame - friends/server.py
first hello world working
[friends.git] / friends / server.py
CommitLineData
b3102128
MF
1import tornado.ioloop
2import tornado.web
ddf4123d 3import os, os.path
b3102128 4import tornado.httpserver
ca027dea 5import tornado.httpclient as httpclient
ddf4123d
MF
6import sqlite3
7import arrow
8import datetime
9from rd import RD, Link
087a104b 10import hashlib
ca027dea 11import hmac
ddf4123d
MF
12db = None
13#insert into user (name,email) values('mikael','mikael@frykholm.com');
14#insert into entry (userid,text) values (1,'My thoughts on ostatus');
15import tornado.options
16
17settings = {
18 "static_path": os.path.join(os.path.dirname(__file__), "static"),
19 "cookie_secret": "__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__",
20 "login_url": "/login",
21 "xsrf_cookies": False,
22 "domain":"https://ronin.frykholm.com",
23
24}
25class PushHandler(tornado.web.RequestHandler):
26#curl -v -k "https://ronin.frykholm.com/hub" -d "hub.callback=a" -d "hub.mode=b" -d "hub.topic=c" -d "hub.verify=d"
27 def post(self):
28 """ Someone wants to subscribe to hub_topic feed"""
29 hub_callback = self.get_argument('hub.callback')
30 hub_mode = self.get_argument('hub.mode')
31 hub_topic = self.get_argument('hub.topic')
32 hub_verify = self.get_argument('hub.verify')
33 hub_lease_seconds = self.get_argument('hub.lease_seconds','')
ca027dea 34 hub_secret = self.get_argument('hub.secret','')
ddf4123d 35 hub_verify_token = self.get_argument('hub.verify_token','')
511b6ecb 36 print(self.request.body)
ddf4123d
MF
37 if hub_mode == 'unsubscribe':
38 pass #FIXME
39 path = hub_topic.split(self.settings['domain'])[1]
40 user = path.split('user/')[1]
41 row = db.execute("select id from user where name=?",(user,)).fetchone()
ca027dea
MF
42 expire = datetime.datetime.utcnow() + datetime.timedelta(seconds=int(hub_lease_seconds))
43 if row:
44 db.execute("INSERT into subscriptions (userid, expires, callback, secret, verified) "
45 "values (?,?,?,?,?)",(row['id'],expire,hub_callback,hub_secret,False))
ddf4123d
MF
46 db.commit()
47 self.set_status(202)
ca027dea
MF
48 http_client = httpclient.HTTPClient()
49 try:
50 response = http_client.fetch(hub_callback+"?hub.mode={}&hub.topic={}&hub.secret".format(hub_mode,hub_topic,hub_secret))
51 print(response.body)
52 except httpclient.HTTPError as e:
53 # HTTPError is raised for non-200 responses; the response
54 # can be found in e.response.
55 print("Error: " + str(e))
56 except Exception as e:
57 # Other errors are possible, such as IOError.
58 print("Error: " + str(e))
59 http_client.close()
087a104b
MF
60 #TODO add secret to outgoing feeds with hmac
61
b3102128
MF
62class XrdHandler(tornado.web.RequestHandler):
63 def get(self):
ddf4123d
MF
64 self.render("templates/xrd.xml", hostname="ronin.frykholm.com", url=self.settings['domain'])
65
66class FingerHandler(tornado.web.RequestHandler):
67 def get(self):
68 user = self.get_argument('resource')
69 user = user.split('acct:')[1]
70 (user,domain) = user.split('@')
71 rows = db.execute("select id from user where user.name=?",(user,)).fetchone()
72 if not rows:
73 self.set_status(404)
74 self.write("Not found")
75 self.finish()
76 return
77 lnk = Link(rel='http://spec.example.net/photo/1.0',
78 type='image/jpeg',
79 href='{}/static/{}.jpg'.format(self.settings['domain'],user))
80 lnk.titles.append(('User Photo', 'en'))
81 lnk.titles.append(('Benutzerfoto', 'de'))
82 lnk.properties.append(('http://spec.example.net/created/1.0', '1970-01-01'))
83 lnk2 = Link(rel='http://schemas.google.com/g/2010#updates-from',
84 type='application/atom+xml',
85 href='{}/user/{}'.format(self.settings['domain'],user))
86
87 rd = RD(subject='{}/{}'.format(self.settings['domain'],user))
88 rd.properties.append('http://spec.example.net/type/person')
89 rd.links.append(lnk)
90 rd.links.append(lnk2)
91 self.write(rd.to_json())
b3102128
MF
92
93class UserHandler(tornado.web.RequestHandler):
94 def get(self, user):
ddf4123d
MF
95 entries = db.execute("select entry.id,text,ts from user,entry where user.id=entry.userid and user.name=?",(user,))
96 #import pdb;pdb.set_trace()
97 self.set_header("Content-Type", 'application/atom+xml')
ca027dea 98 out = self.render("templates/feed.xml",
ddf4123d
MF
99 user=user,
100 feed_url="{}/user/{}".format(self.settings['domain'], user),
101 hub_url="{}/hub".format(self.settings['domain']),
102 entries=entries,
103 arrow=arrow )
ca027dea 104 #digest = hmac.new()
b3102128
MF
105
106application = tornado.web.Application([
107 (r"/.well-known/host-meta", XrdHandler),
ddf4123d 108 (r"/.well-known/webfinger", FingerHandler),
b3102128 109 (r"/user/(.+)", UserHandler),
ddf4123d
MF
110 (r"/hub", PushHandler),
111 ],debug=True,**settings)
ca027dea 112srv = tornado.httpserver.HTTPServer(application, )
ddf4123d
MF
113def setup_db(path):
114 print("No db found, creating in {}".format(path))
115 con = sqlite3.connect(path)
116 con.execute(""" create table user (id integer primary key,
117 name varchar,
118 email varchar);
119 create table entry (id integer primary key,
120 userid INTEGER,
121 text varchar,
122 ts timestamp default current_timestamp,
123 FOREIGN KEY(userid) REFERENCES user(id));
124 create table subscriptions (id integer primary key,
125 userid integer,
126 expires datetime,
127 callback varchar,
087a104b 128 secret varchar,
ddf4123d
MF
129 verified bool,
130 FOREIGN KEY(userid) REFERENCES user(id));""")
131 con.commit()
b3102128 132
b3102128 133if __name__ == "__main__":
ddf4123d
MF
134 dbPath = 'friends.db'
135 tornado.options.parse_command_line()
136 if not os.path.exists(dbPath):
137 setup_db(dbPath)
138 db = sqlite3.connect(dbPath, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
139 db.row_factory = sqlite3.Row
ca027dea 140 srv.listen(8080)
3ffcd3f8 141 tornado.ioloop.IOLoop.instance().start()
ca027dea
MF
142 #TODO hmac.new(b'5cc324285ece71e21e9554f4056563806f6ce0b7e4ab18d0133b602f8ba7e87a',open("apa.xml","rb").read(),digestmod='sha1').hexdigest()
143'b75d4733e0802629a0c15d0faa8de8fc9778cd05' queue runner