def logout(environ, start_response): """ Expire the tiddlyweb_user cookie when a POST is received. """ redirect = environ['tiddlyweb.query'].get('tiddlyweb_redirect', [None])[0] if redirect: uri = server_base_url(environ) + redirect.encode('UTF-8') else: uri = environ.get('HTTP_REFERER', server_base_url(environ) + environ['tiddlyweb.config'].get('logout_uri', '/')) path = environ.get('tiddlyweb.config', {}).get('server_prefix', '') cookie = Cookie.SimpleCookie() cookie['tiddlyweb_user'] = '' cookie['tiddlyweb_user']['path'] = '%s/' % path if 'MSIE' in environ.get('HTTP_USER_AGENT', ''): cookie['tiddlyweb_user']['expires'] = time.strftime( '%a, %d-%m-%y %H:%M:%S GMT', time.gmtime(time.time() - 600000)) else: cookie['tiddlyweb_user']['max-age'] = '0' cookie_output = cookie.output(header='') start_response('303 See Other', [ ('Set-Cookie', cookie_output), ('Expires', time.strftime( '%a, %d %b %Y %H:%M:%S GMT', time.gmtime(time.time() - 600000))), ('Cache-Control', 'no-store'), ('Location', uri), ]) return [uri]
def register(environ, start_response): domain = get_domain(environ["HTTP_HOST"]) query = environ["tiddlyweb.query"] name = query.get("name", [None])[0] company = query.get("company", [None])[0] country = query.get("country", [None])[0] email = query.get("email", [None])[0] if not (name and company and email): # The form has not been filled out raise HTTP302(server_base_url(environ) + "/pages/register.html") to_address = environ["tiddlyweb.config"].get("wikidata.register_address", "*****@*****.**") subject = "Registration Request" body = """ name: %s email: %s company: %s country: %s """ % ( name, email, company, country, ) try: send_email(to_address, subject=subject, body=body, from_="avox@" + domain) except socket.error: logging.debug("failed to send: %s:%s:%s", to_address, subject, body) raise HTTP303(server_base_url(environ) + "/pages/registered.html")
def get_home(environ, start_response): user = environ['tiddlyweb.usersign'] if user['name'] == 'GUEST' or 'MEMBER' not in user['roles']: raise HTTP302(server_base_url(environ) + '/') else: raise HTTP302(server_base_url(environ) + '/' + encode_name(user['name']))
def get_home(environ, start_response): user = environ['tiddlyweb.usersign'] if user['name'] == 'GUEST' or 'MEMBER' not in user['roles']: raise HTTP302(server_base_url(environ) + '/') else: raise HTTP302( server_base_url(environ) + '/' + encode_name(user['name']))
def _create_user(environ, start_response, creation=0, expiration=0, role='tier1'): domain = get_domain(environ['HTTP_HOST']) if creation == 0: creation = time.time() store = environ['tiddlyweb.store'] query = environ['tiddlyweb.query'] name = query.get('name', [None])[0] email = query.get('email', [None])[0] company = query.get('company', [None])[0] country = query.get('country', [None])[0] if not (name and email): # The form has not been filled out return _user_form(environ, start_response, role=role, message='Missing Data!', formdata={'name': name, 'email': email, 'company': company, 'country': country}) user = User(email) try: user = store.get(user) # User exists! return _user_form(environ, start_response, role=role, message='That account already exists!', formdata={'name': name, 'email': email, 'company': company, 'country': country}) except NoUserError: password = _random_pass() user.set_password(password) user.add_role(role) store.put(user) bag_name = environ['tiddlyweb.config'].get('magicuser.bag', 'MAGICUSER') ensure_bag(bag_name, store, policy_dict={ 'read': ['NONE'], 'write': ['NONE'], 'create': ['NONE'], 'manage': ['NONE']}) tiddler = Tiddler(email, bag_name) tiddler.fields['country'] = country tiddler.fields['company'] = company tiddler.fields['name'] = name # Set the creation and expiration times. now = time.time() tiddler.fields['creation'] = '%s' % creation tiddler.fields['expiry'] = '%s' % expiration store.put(tiddler) to_address = email subject = domain+" user info" body = """ Here's your info: Username: %s Password: %s """ % (email, password) query_string = '?email=%s' % to_address try: send_email(to_address, subject=subject, body=body, from_='avox@'+domain) query_string += '&success=1&role=%s' % role raise HTTP303(server_base_url(environ)+'/pages/new_account'+query_string) except socket.error: logging.debug('failed to send: %s:%s:%s', to_address, subject, body) query_string += '&failure=1&role=%s' % role raise HTTP302(server_base_url(environ)+'/pages/new_account'+query_string)
def _handle_response(self, environ, start_response): oidconsumer = consumer.Consumer({}, None) host = server_base_url(environ) url = urlparse.urljoin(host, '%s/challenge/%s' % ( environ['tiddlyweb.config']['server_prefix'], CHALLENGER_NAME)) query = {} for key in environ['tiddlyweb.query']: query[key] = environ['tiddlyweb.query'][key][0] info = oidconsumer.complete(query, url) display_identifier = info.getDisplayIdentifier() if info.status == consumer.FAILURE and display_identifier: return self._render_form(environ, start_response, openid=display_identifier, message='Verification of %s failed with: %s' % ( display_identifier, info.message)) elif info.status == consumer.SUCCESS: return self._success(environ, start_response, info) elif info.status == consumer.CANCEL: return self._render_form(environ, start_response, message='You cancelled, try again with something else?') elif info.status == consumer.SETUP_NEEDED: if info.setup_url: message = '<a href=%s>Setup needed at openid server.</a>' % info.setup_url else: message = 'More information needed at server' return self._render_form(environ, start_response, message=message) else: return self._render_form(environ, start_response, message='Unable to process. Unknown error')
def _tiddler_as_div(self, tiddler): """ Read in the tiddler from a div. """ recipe_name = '' if tiddler.recipe: recipe_name = tiddler.recipe try: host = server_base_url(self.environ) except KeyError: host = '' host = '%s/' % host if tiddler.type and tiddler.type != 'None': tiddler_output = self._binary_tiddler(tiddler) else: tiddler_output = tiddler.text return ('<div title="%s" server.title="%s" server.page.revision="%s" ' 'modifier="%s" server.workspace="bags/%s" ' 'server.type="tiddlyweb" server.host="%s" ' 'server.recipe="%s" server.bag="%s" server.permissions="%s" ' 'modified="%s" created="%s" tags="%s" %s>\n' '<pre>%s</pre>\n</div>\n' % (tiddler.title, tiddler.title, tiddler.revision, tiddler.modifier, tiddler.bag, host, recipe_name, tiddler.bag, self._tiddler_permissions(tiddler), tiddler.modified, tiddler.created, self.tags_as(tiddler.tags), self._tiddler_fields(tiddler.fields), self._html_encode(tiddler_output)))
def _return_to(self, environ, redirect, link, usersign): """ Generate the URL to which the user should return to after visiting their OpenID server. """ return '%s/challenge/openid?nonce=%s&tiddlyweb_redirect=%s&openid_server=%s&usersign=%s' \ % (web.server_base_url(environ), self._nonce(), redirect, link, usersign)
def get_tiddler_edit(environ, start_response): usersign = environ['tiddlyweb.usersign'] store = environ['tiddlyweb.store'] title = environ['tiddlyweb.query'].get('title', [''])[0] bag_name = environ['tiddlyweb.query'].get('bag', [''])[0] username = usersign['name'] if not 'MEMBER' in usersign['roles']: raise HTTP404('bad edit') if not title and not bag_name: tiddler = get_profile(store, usersign, username) page_title = 'Edit Profile' return_url = '%s/home' % server_base_url(environ) elif not title: tiddler = Tiddler('', bag_name) page_title = 'Edit New Tiddler' return_url = '' else: tiddler = Tiddler(title, bag_name) page_title = 'Edit %s' % title return_url = tiddler_url(environ, tiddler) try: tiddler = store.get(tiddler) except StoreError: pass bag = Bag(tiddler.bag) bag = store.get(bag) bag.policy.allows(usersign, 'write') data = {} data['tiddler'] = tiddler data['return_url'] = return_url data['title'] = page_title return send_template(environ, 'profile_edit.html', data)
def make_ticklist(environ, start_response): """ Record routes the user would like to climb. """ store = environ['tiddlyweb.store'] current_user = environ['tiddlyweb.usersign']['name'] gym = get_route_value(environ, 'gym') tick_wishes = environ['tiddlyweb.query'].get('addroute', []) routes = _get_gym_routes(environ, gym) for route in routes: route.bag = current_user if route.title in tick_wishes: route.tags = ['tickwish'] route.fields['gym'] = gym store.put(route) else: try: tiddler = store.get(route) tiddler.tags.remove('tickwish') store.put(tiddler) except (StoreError, ValueError): pass raise HTTP303(server_base_url(environ) + '/gyms/%s/ticklist' % encode_name(gym))
def record_climbs(environ, start_response): """ Record a climb that has been accomplished. """ query = environ['tiddlyweb.query'] store = environ['tiddlyweb.store'] current_user = environ['tiddlyweb.usersign']['name'] gym = get_route_value(environ, 'gym') routes = query['route'] dones = query['doneroute'] for index, value in enumerate(dones): if value != '': route_title = routes[index] tiddler = Tiddler(route_title, current_user) try: tiddler = store.get(tiddler) except StoreError: pass if value in CLEAN_CLIMB: try: tiddler.tags.remove('tickwish') except ValueError: pass tiddler.fields['climbtype'] = value tiddler.fields['gym'] = gym tiddler.tags.append('climb') store.put(tiddler) raise HTTP303(server_base_url(environ) + environ['REQUEST_URI'])
def create_app(environ, start_response): """ At the provider, register a client and provide them with an id, secret, etc. This is not part of the oAuth spec, but is fairly standard form for what is usually called "creating an app". On success redirects to the info page for the app. """ query = environ['tiddlyweb.query'] current_user = environ['tiddlyweb.usersign']['name'] data = {} for key in ['name', 'app_url', 'callback_url', 'logo']: if key in query: data[key] = query[key][0] data['owner'] = current_user try: app_tiddler = create(**data) except TypeError as exc: raise HTTP400('Invalid form submission: %s' % exc) # let a store error raise to a 500 (for now) app_tiddler = store_app(environ, app_tiddler) raise HTTP303(server_base_url(environ) + '/_oauth/appinfo?app=%s' % app_tiddler.title)
def home(environ, start_response): """ If we go to the base of the wiki route, redirect to the FrontPage. """ config = environ["tiddlyweb.config"] location = "%s%s/%s" % (server_base_url(environ), _route_base(config), _front_page(config)) raise HTTP302(location)
def submit(environ, start_response): """ Take POSTed input, put it in a Tiddler and save it into the store, and redirect back to the user page. """ user = environ['tiddlyweb.usersign']['name'] if user == 'GUEST': raise UserRequiredError, 'real user required to twote' recent_recipe = _check_recipe('recent', environ, user) all_recipe = _check_recipe('all', environ, user) tiddler = _make_tiddler(environ, user) bag = control.determine_bag_for_tiddler(all_recipe, tiddler) tiddler.bag = bag.name store = environ['tiddlyweb.store'] original_title = tiddler.title tester_tiddler = Tiddler(original_title, bag=bag.name) addendum = 2 while 1: try: tester_tiddler = store.get(tester_tiddler) new_title = '%s-%s' % (original_title, addendum) tiddler.title = new_title tester_tiddler.title = new_title addendum += 1 except NoTiddlerError: store.put(tiddler) break raise HTTP302, '%s/twoter/%s' % (server_base_url(environ), urllib.quote(user))
def spowt(environ, start_response): username = environ['tiddlyweb.usersign']['name'] if username == 'GUEST': template = template_env.get_template('spowt.html') return template.generate() else: raise HTTP302('%s/spowt2/%s' % (server_base_url(environ), urllib.quote(username)))
def tiddler_as(self, tiddler): host = '%s/' % server_base_url(self.environ) # TODO: normalize? title, bag = [encode_name(name) for name in (tiddler.title, tiddler.bag)] namespaces = { '': host, 'tweb': 'http://tiddlyweb.com/' } subject = ':bags/%s/%s' % (bag, title) rdf_data = { subject: { 'rdf:type': ['tweb:tiddler'], 'tweb:bag': [':bags/%s' % bag] } } for field, value in tiddler.fields.items(): try: prefix, suffix = field.split(':') # TODO: use collections.defaultdict rdf_data[subject] = rdf_data.get(subject) or {} rdf_data[subject][field] = rdf_data[subject].get(field) or [] rdf_data[subject][field].append(value) except ValueError: # not RDF-related pass return to_turtle(namespaces, rdf_data)
def webfinger(environ, start_response): """ Display the webfinger information for a given user. """ http_host, host_url = determine_host(environ) if http_host != host_url: raise HTTP404('No webfinger at this host: %s' % http_host) username = environ['tiddlyweb.query'].get('q', [None])[0] if not username: raise HTTP400('No account provided to webfinger query') if username.startswith('acct:'): username = username.split(':', 1)[1] username = username.split('@', 1)[0] start_response('200 OK', [('Content-Type', 'application/xrd+xml')]) return [ WEBFINGER_TEMPLATE % { 'username': username, 'host': http_host, 'server_host': server_base_url(environ) } ]
def get_tiddler_edit(environ, start_response): usersign = environ["tiddlyweb.usersign"] store = environ["tiddlyweb.store"] title = environ["tiddlyweb.query"].get("title", [""])[0] bag_name = environ["tiddlyweb.query"].get("bag", [""])[0] username = usersign["name"] if not "MEMBER" in usersign["roles"]: raise HTTP404("bad edit") if not title and not bag_name: tiddler = get_profile(store, usersign, username) page_title = "Edit Profile" return_url = "%s/home" % server_base_url(environ) elif not title: tiddler = Tiddler("", bag_name) page_title = "Edit New Tiddler" return_url = "" else: tiddler = Tiddler(title, bag_name) page_title = "Edit %s" % title return_url = tiddler_url(environ, tiddler) try: tiddler = store.get(tiddler) except StoreError: pass bag = Bag(tiddler.bag) bag = store.get(bag) bag.policy.allows(usersign, "write") data = {} data["tiddler"] = tiddler data["return_url"] = return_url data["title"] = page_title return send_template(environ, "profile_edit.html", data)
def _manage_update_routes(environ, gym): """ Update routes with new information. """ store = environ['tiddlyweb.store'] query = environ['tiddlyweb.query'] existing_titles = query.get('title', []) count = len(existing_titles) index = 0 delete = query.get('delete', []) lead_route = query.get(LEAD_FIELD, []) while index < count: title = existing_titles[index] tiddler = Tiddler(title, '%s_climbs' % gym) try: tiddler = store.get(tiddler) if title in delete: original_bag = tiddler.bag tiddler.bag = '%s_archive' % gym store.put(tiddler) tiddler.bag = original_bag store.delete(tiddler) index += 1 continue except StoreError: pass changed = False for key in ROUTE_FIELDS: value = query.get(key, [''])[index] if tiddler.fields[key] != value: tiddler.fields[key] = value changed = True if LEAD_FIELD in tiddler.fields and title not in lead_route: del tiddler.fields[LEAD_FIELD] changed = True elif title in lead_route and LEAD_FIELD not in tiddler.fields: tiddler.fields[LEAD_FIELD] = '1' changed = True if changed: store.put(tiddler) index += 1 try: title = query.get('title', [])[index] except IndexError: title = str(uuid4()) tiddler = Tiddler(title, '%s_climbs' % gym) new_route = False if 'new_one' in lead_route: tiddler.fields[LEAD_FIELD] = '1' for key in ROUTE_FIELDS: value = query.get(key, [''])[index] if value == '': continue new_route = True tiddler.fields[key] = value if new_route: store.put(tiddler) raise HTTP303(server_base_url(environ) + '/manager/%s' % gym)
def _manage_update_gym(environ, gym): """ Update the gym information. """ tiddler = Tiddler(gym, GYMS_BAG) _update_gym_info(environ, tiddler) raise HTTP303(server_base_url(environ) + '/manager/%s' % gym)
def _send_finish(environ, start_response): template = get_template(environ, "registered.html") username = environ["tiddlyweb.usersign"]["name"] start = { "href": environ["tiddlyweb.config"].get("register.start_href", "/"), "title": environ["tiddlyweb.config"].get("register.start_title", "Get Started"), } return template.generate(start=start, username=username, home=server_base_url(environ) + "/")
def _manage_create_news(environ, gym): store = environ['tiddlyweb.store'] news = environ['tiddlyweb.query'].get('news', [''])[0] tiddler = Tiddler(str(uuid4()), '%s_news' % gym) tiddler.text = news tiddler.type = TIDDLER_TYPE store.put(tiddler) raise HTTP303(server_base_url(environ) + '/manager/%s' % gym)
def _challenger_url(environ, system): """ Return the proper URL for a specific challenger system. """ default_redirect = "%s/" % environ["tiddlyweb.config"]["server_prefix"] redirect = environ["tiddlyweb.query"].get("tiddlyweb_redirect", [default_redirect])[0] redirect = "?tiddlyweb_redirect=%s" % quote(redirect.encode("utf-8"), safe="") return "%s/challenge/%s%s" % (server_base_url(environ), system, redirect)
def _get_config(self): json = {"workspace": self._get_container(), "host": server_base_url(self.environ)} return '''\ <script id="tiddlywikiconfig" type="application/json"> %s </script> ''' % (simplejson.dumps(json))
def _send_finish(environ, start_response): template = get_template(environ, 'registered.html') username = environ['tiddlyweb.usersign']['name'] start = { 'href': environ['tiddlyweb.config'].get('register.start_href', '/'), 'title': environ['tiddlyweb.config'].get('register.start_title', 'Get Started'), } return template.generate(start=start, username=username, home=server_base_url(environ) + '/')
def add_email(environ, start_response): user = get_user_object(environ) store = environ['tiddlyweb.store'] ensure_user_bag(store, user['name']) tiddler = Tiddler('email', user['name']) email = environ['tiddlyweb.query'].get('email', [''])[0] tiddler.text = email store.put(tiddler) raise HTTP303('%s/home' % server_base_url(environ))
def _challenger_url(environ, system): """ Return the proper URL for a specific challenger system. """ default_redirect = '%s/' % environ['tiddlyweb.config']['server_prefix'] redirect = (environ['tiddlyweb.query'].get('tiddlyweb_redirect', [default_redirect])[0]) redirect = '?tiddlyweb_redirect=%s' % urllib.quote(redirect, safe='') return '%s/challenge/%s%s' % (server_base_url(environ), system, redirect)
class Challenger(ChallengerInterface): def challenge_get(self, environ, start_response): openid_mode = environ['tiddlyweb.query'].get('openid.mode', [None])[0] if openid_mode: return self._handle_response(environ, start_response) else: return self._render_form(environ, start_response) def challenge_post(self, environ, start_response): openid_url = environ['tiddlyweb.query'].get('openid', [None])[0] redirect = environ['tiddlyweb.query'].get('tiddlyweb_redirect', ['/'])[0] if not openid_url: return self._render_form(environ, start_response, message='Enter an openid') # Make a bare bones stateless consumer oidconsumer = consumer.Consumer({}, None) try: request = oidconsumer.begin(openid_url) except consumer.DiscoveryFailure, exc: return self._render_form(environ, start_response, openid=openid_url, message='Error in discovery: %s' % exc[0]) if request is None: return self._render_form(environ, start_response, openid=openid_url, message='No open id services for %s' % openid_url) else: trust_root = server_base_url(environ) return_to = urlparse.urljoin( trust_root, '%s/challenge/%s' % (environ['tiddlyweb.config']['server_prefix'], CHALLENGER_NAME)) request.return_to_args['tiddlyweb_redirect'] = redirect if request.shouldSendRedirect(): redirect_url = request.redirectURL(trust_root, return_to, immediate=False) raise HTTP302(redirect_url) else: form_html = request.htmlMarkup( trust_root, return_to, form_tag_attrs={'id': 'openid_message'}, immediate=False) start_response('200 OK', [('Content-Type', 'text/html; charset=UTF-8')]) return [form_html]
def _put_tiddlers_in_tiddlywiki(self, tiddlers, title='TiddlyWeb Loading'): """ Take the provided tiddlers and inject them into the base_tiddlywiki, adjusting content for title, subtite, and the various pre and post head sections of the file. """ if tiddlers[0].recipe: workspace = '/recipes/%s/tiddlers' % urllib.quote(tiddlers[0].recipe.encode('UTF-8')) else: workspace = '/bags/%s/tiddlers' % urllib.quote(tiddlers[0].bag.encode('UTF-8')) browsable_url = server_base_url(self.environ) + workspace if len(tiddlers) == 1: default_tiddler = Tiddler('DefaultTiddlers') default_tiddler.text = '[[' + tiddlers[0].title + ']]' tiddlers = [tiddlers[0], default_tiddler] # figure out the content to be pushed into the # wiki and calculate the title lines = '' candidate_title = None candidate_subtitle = None markup_tiddlers = MARKUPS.keys() found_markup_tiddlers = {} for tiddler in tiddlers: lines += self._tiddler_as_div(tiddler) if tiddler.title == 'SiteTitle': candidate_title = tiddler.text if tiddler.title == 'SiteSubtitle': candidate_subtitle = tiddler.text if tiddler.title in markup_tiddlers: found_markup_tiddlers[tiddler.title] = tiddler.text # Turn the title into HTML and then turn it into # plain text so it is of a form satisfactory to <title> title = self._determine_title(title, candidate_title, candidate_subtitle) title = self._plain_textify_string(title) # load the wiki wiki = self._get_wiki() # put the title in place wiki = self._inject_title(wiki, title) wiki = self._replace_chunk(wiki, '\n<noscript>\n', '\n</noscript>\n', self._no_script(browsable_url)) # replace the markup bits if len(found_markup_tiddlers): for title in found_markup_tiddlers: start = '\n<!--%s-START-->\n' % MARKUPS[title] finish = '\n<!--%s-END-->\n' % MARKUPS[title] wiki = self._replace_chunk(wiki, start, finish, found_markup_tiddlers[title]) # split the wiki into the before store and after store # sections, put our content in the middle tiddlystart, tiddlyfinish = wiki.split(SPLITTER, 2) return tiddlystart + lines + SPLITTER + tiddlyfinish
def _get_author_avatar(self, author_name): author_avatar = None author_avatar_map = self.environ.get( 'tiddlyweb.config', {}).get( 'atom.author_avatar_map', None) if author_avatar_map: author_avatar = (server_base_url(self.environ) + author_avatar_map % author_name) return author_avatar
def add_email(environ, start_response): user = get_user_object(environ) store = environ["tiddlyweb.store"] ensure_user_bag(store, user["name"]) tiddler = Tiddler("email", user["name"]) email = environ["tiddlyweb.query"].get("email", [""])[0] tiddler.text = email store.put(tiddler) raise HTTP303("%s/home" % server_base_url(environ))
def spowt(environ, start_response): username = environ['tiddlyweb.usersign']['name'] if username == 'GUEST': start_response('200 OK', [('Content-Type', 'text/html')]) template = template_env.get_template('root.html') environ['tiddlyweb.title'] = 'Welcome to Spowt' return template.generate() else: raise HTTP302('%s/spowt/%s' % (server_base_url(environ), urllib.quote(username)))
def add_email(environ, start_response): user = get_user_object(environ) store = environ['tiddlyweb.store'] ensure_user_bag(store, user['name']) tiddler = Tiddler('email', user['name']) email = environ['tiddlyweb.query'].get('email', [''])[0] tiddler.text = email tiddler.modifier = user['name'] store.put(tiddler) raise HTTP303('%s/home' % server_base_url(environ))
def base(environ, start_response): """ Where a user comes to /twoter redirect to their own location, or if they aren't logged in, have them log in. """ user = environ['tiddlyweb.usersign']['name'] if user == 'GUEST': raise UserRequiredError, 'real user required to twote' else: raise HTTP302, '%s/twoter/%s' % (server_base_url(environ), urllib.quote(user))
def user(environ, start_response): """ Display an information page for the user. If they are not logged in, have them log in. """ userpath = environ['wsgiorg.routing_args'][1]['username'] user = environ['tiddlyweb.usersign']['name'] if user == 'GUEST': raise UserRequiredError, 'real user required to twote' if user != userpath: raise HTTP302, '%s/twoter/%s' % (server_base_url(environ), urllib.quote(user)) recent_recipe = _check_recipe('recent', environ, user) all_recipe = _check_recipe('all', environ, user) def recipe_href(recipe, extension): return '%s/tiddlers%s?sort=-modified' % ( recipe_url(environ, recipe), extension) template_values = { 'user': user, 'recent_url': recipe_href(recent_recipe, ''), 'recent_feed': recipe_href(recent_recipe, '.atom'), 'recent_wiki_d': recipe_href(recent_recipe, '.wiki') + '&download=twoter-recent.html', 'recent_wiki': recipe_href(recent_recipe, '.wiki'), 'recent_json': recipe_href(recent_recipe, '.json'), 'all_url': recipe_href(all_recipe, ''), 'all_wiki_d': recipe_href(all_recipe, '.wiki') + '&download=twoter-recent.html', 'all_wiki': recipe_href(all_recipe, '.wiki'), 'all_json': recipe_href(all_recipe, '.json'), 'twoter_url': '%s/twoter/%s' % (server_base_url(environ), urllib.quote(user)), } environ['tiddlyweb.title'] = 'Twoter for %s' % user start_response('200 OK', [ ('Content-Type', 'text/html') ]) template = template_env.get_template('user.html') return template.generate(template_values)
def send_template(environ, template_name, template_data=None): """ Set some defaults for a template and send the output. """ if template_data == None: template_data = {} template = get_template(environ, template_name) store = environ['tiddlyweb.store'] linked_resources = { 'HtmlCss': ['/bags/common/tiddlers/profile.css'], 'HtmlJavascript': [] } # Load CSS and JavaScript overrides. current_space = determine_space(environ, determine_host(environ)[0]) if current_space: recipe_name = determine_space_recipe(environ, current_space) try: recipe = store.get(Recipe(recipe_name)) for title in linked_resources: try: tiddler = Tiddler(title) bag = control.determine_bag_from_recipe( recipe, tiddler, environ) tiddler.bag = bag.name try: tiddler = store.get(tiddler) if 'Javascript' in title: urls = tiddler.text.strip().rstrip().split('\n') linked_resources[title] = urls else: url = '/bags/%s/tiddlers/%s' % (encode_name( tiddler.bag), title) linked_resources[title] = [url] except StoreError: continue except StoreError: pass except StoreError: pass template_defaults = { 'original_server_host': original_server_host_url(environ), 'css': linked_resources['HtmlCss'], 'js': linked_resources['HtmlJavascript'], 'server_host': server_base_url(environ), } template_defaults.update(template_data) return template.generate(template_defaults)
def _challenge_url(environ): """ Generate the URL of the challenge system so that GET requests are redirected to the right place. """ script_name = environ.get('SCRIPT_NAME', '') query_string = environ.get('QUERY_STRING', None) redirect = script_name if query_string: redirect += '?%s' % query_string redirect = urllib.quote(redirect, safe='') return '%s/challenge?tiddlyweb_redirect=%s' % ( server_base_url(environ), redirect)
def _create_tiddlers(self, title, tiddlers): """ Figure out the content to be pushed into the wiki and calculate the title. """ lines = [] window_title = None candidate_title = None candidate_subtitle = None markup_tiddlers = MARKUPS.keys() found_markup_tiddlers = {} tiddler_count = 0 for tiddler in tiddlers: lines.append(self._tiddler_as_div(tiddler)) tiddler_title = tiddler.title if tiddler_title == 'WindowTitle': window_title = tiddler.text if tiddler_title == 'SiteTitle': candidate_title = tiddler.text if tiddler_title == 'SiteSubtitle': candidate_subtitle = tiddler.text if tiddler_title in markup_tiddlers: found_markup_tiddlers[tiddler_title] = tiddler.text tiddler_count += 1 if tiddler_count == 1: default_tiddler = Tiddler('DefaultTiddlers', '_virtual') default_tiddler.text = '[[' + tiddler.title + ']]' lines.append(self._tiddler_as_div(default_tiddler)) browsable_url = None try: if tiddler.recipe: workspace = '/recipes/%s/tiddlers' % encode_name( tiddler.recipe) else: workspace = '/bags/%s/tiddlers' % encode_name(tiddler.bag) browsable_url = server_base_url(self.environ) + workspace except UnboundLocalError: pass # tiddler is not set because tiddlers was empty # Turn the title into HTML and then turn it into # plain text so it is of a form satisfactory to <title> title = self._determine_title(title, window_title, candidate_title, candidate_subtitle) title = self._plain_textify_string(title) return browsable_url, lines, title, found_markup_tiddlers
def add_friend(environ, start_response): user = get_user_object(environ) store = environ['tiddlyweb.store'] ensure_user_bag(store, user['name']) new_friend = environ['tiddlyweb.query'].get('name', [''])[0] friends = get_friends(store, user['name']) if new_friend and new_friend not in friends: friends.append(new_friend) tiddler = Tiddler('friends', user['name']) try: tiddler = store.get(tiddler) except NoTiddlerError: pass # is okay if tiddler doesn't exist yet tiddler.text = '\n'.join(friends) tiddler.modifier = user['name'] store.put(tiddler) raise HTTP303('%s/home' % server_base_url(environ))
def host_meta(environ, start_response): """ Send the host_meta information, so webfinger info can be found. """ http_host, host_url = determine_host(environ) if http_host != host_url: # Or should it be a 302? raise HTTP404('No host-meta at this host: %s' % http_host) start_response('200 OK', [('Content-Type', 'application/xrd+xml')]) return [ HOST_META_TEMPLATE % { 'host': http_host, 'server_host': server_base_url(environ) } ]
def recipe_favor(environ, start_response): user = get_user_object(environ) store = environ['tiddlyweb.store'] ensure_user_bag(store, user['name']) new_bookmark = environ['tiddlyweb.query'].get('recipe', [''])[0] bookmarks = get_bookmarks(store, user['name']) # XXX I suppose a set would be okay here. if new_bookmark and new_bookmark not in bookmarks: bookmarks.append(new_bookmark) tiddler = Tiddler('bookmarks', user['name']) try: tiddler = store.get(tiddler) except NoTiddlerError: pass # is okay if tiddler doesn't exist yet tiddler.text = '\n'.join(bookmarks) tiddler.modifier = user['name'] store.put(tiddler) raise HTTP303('%s/home' % server_base_url(environ))
def bag_favor(environ, start_response): user = get_user_object(environ) store = environ['tiddlyweb.store'] ensure_user_bag(store, user['name']) new_favorite = environ['tiddlyweb.query'].get('bag', [''])[0] favorites = get_favorites(store, user['name']) # XXX I suppose a set would be okay here. if new_favorite and new_favorite not in favorites: favorites.append(new_favorite) tiddler = Tiddler('favorites', user['name']) try: tiddler = store.get(tiddler) except NoTiddlerError: pass # is okay if tiddler doesn't exist yet tiddler.text = '\n'.join(favorites) tiddler.modifier = user['name'] store.put(tiddler) raise HTTP303('%s/home' % server_base_url(environ))
def post_createrecipe(environ, start_response): user = get_user_object(environ) store = environ['tiddlyweb.store'] recipe_name = environ['tiddlyweb.query'].get('recipe', [''])[0] bag_name = environ['tiddlyweb.query'].get('bag', [''])[0] publicity = environ['tiddlyweb.query'].get('publicity', [''])[0] description = environ['tiddlyweb.query'].get('description', [''])[0] if not bag_name or not recipe_name: raise HTTP400('missing data') recipe = Recipe(recipe_name) bag = Bag(bag_name) try: recipe = store.get(recipe) raise HTTP400('recipe exists') except NoRecipeError: pass try: bag = store.get(bag) try: bag.policy.allows(user, 'read') except (UserRequiredError, ForbiddenError): raise HTTP400('bag not readable') except NoBagError: bag.policy.owner = user['name'] for constraint in ['read', 'write', 'create', 'delete', 'manage']: setattr(bag.policy, constraint, [user['name']]) store.put(bag) if publicity == 'private': recipe.policy.read = [user['name']] else: recipe.policy.read = [] recipe.policy.manage = [user['name']] recipe.policy.owner = user['name'] recipe.desc = description recipe.set_recipe([ ('system', ''), (bag.name, ''), ]) store.put(recipe) raise HTTP303('%s/home' % server_base_url(environ))
def _tiddler_as_div(self, tiddler): """ Read in the tiddler from a div. """ recipe_name = '' if tiddler.recipe: recipe_name = tiddler.recipe try: host = server_base_url(self.environ) except KeyError: host = '' host = '%s/' % host if binary_tiddler(tiddler): tiddler_output = self._binary_tiddler(tiddler) else: tiddler_output = tiddler.text if tiddler.type == 'None' or not tiddler.type: tiddler.type = '' return ('<div title="%s" server.title="%s" server.page.revision="%s" ' 'server.etag="%s" ' 'modifier="%s" creator="%s" server.workspace="bags/%s" ' 'server.type="tiddlyweb" server.host="%s" ' 'server.recipe="%s" server.bag="%s" server.permissions="%s" ' 'server.content-type="%s" ' 'modified="%s" created="%s" tags="%s" %s>\n' '<pre>%s</pre>\n</div>\n' % (escape_attribute_value(tiddler.title), escape_attribute_value(tiddler.title), tiddler.revision, escape_attribute_value(_tiddler_etag(self.environ, tiddler)), escape_attribute_value( tiddler.modifier), escape_attribute_value( tiddler.creator), escape_attribute_value(tiddler.bag), host, escape_attribute_value(recipe_name), escape_attribute_value( tiddler.bag), self._tiddler_permissions(tiddler), tiddler.type, tiddler.modified, tiddler.created, escape_attribute_value(self.tags_as( tiddler.tags)), self._tiddler_fields( tiddler.fields), html_encode(tiddler_output)))
def _get_wiki(self): """ Read base_tiddlywiki from its location. """ global WIKI if WIKI: return WIKI base_tiddlywiki = open( self.environ['tiddlyweb.config']['base_tiddlywikii']) wiki = base_tiddlywiki.read() base_tiddlywiki.close() tag = "<!--POST-SCRIPT-END-->" wiki = wiki.replace(tag, ''' %(config)s <script type="text/javascript" src="%(host)s/bags/common/tiddlers/jquery.js"></script> <script type="text/javascript" src="%(host)s/bags/common/tiddlers/jQuery.twStylesheet.js"></script> <script type="text/javascript" src="%(host)s/bags/common/tiddlers/custom_twcore.js"></script> %(tag)s ''' % {"tag": tag, "config": self._get_config(), "host": server_base_url(self.environ)}) wiki = unicode(wiki, 'utf-8') WIKI = wiki return WIKI
def _handle_response(self, environ, start_response): oidconsumer = consumer.Consumer({}, None) host = server_base_url(environ) url = urlparse.urljoin( host, '%s/challenge/%s' % (environ['tiddlyweb.config']['server_prefix'], CHALLENGER_NAME)) query = {} for key in environ['tiddlyweb.query']: query[key] = environ['tiddlyweb.query'][key][0] info = oidconsumer.complete(query, url) display_identifier = info.getDisplayIdentifier() if info.status == consumer.FAILURE and display_identifier: return self._render_form( environ, start_response, openid=display_identifier, message='Verification of %s failed with: %s' % (display_identifier, info.message)) elif info.status == consumer.SUCCESS: return self._success(environ, start_response, info) elif info.status == consumer.CANCEL: return self._render_form( environ, start_response, message='You cancelled, try again with something else?') elif info.status == consumer.SETUP_NEEDED: if info.setup_url: message = '<a href=%s>Setup needed at openid server.</a>' % info.setup_url else: message = 'More information needed at server' return self._render_form(environ, start_response, message=message) else: return self._render_form( environ, start_response, message='Unable to process. Unknown error')
def _get_config(self): def get_container(environ): routing_args = environ.get('wsgiorg.routing_args', ([], {}))[1] container_name = False container_type = 'bags' store = environ['tiddlyweb.store'] if routing_args: if 'recipe_name' in routing_args: container_name = get_route_value(self.environ, 'recipe_name') container_type = 'recipes' elif 'bag_name' in routing_args: container_name = get_route_value(self.environ, 'bag_name') if container_name: return "%s/%s" % (container_type, container_name) else: return "" json = {"workspace": get_container(self.environ), "host": server_base_url(self.environ)} return ''' <script id="tiddlywikiconfig" type="application/json"> %s </script> ''' % (simplejson.dumps(json))
def new_wiki(environ, start_response): username = environ['tiddlyweb.usersign']['name'] if username == 'GUEST': raise UserRequiredError store = environ['tiddlyweb.store'] length = environ['CONTENT_LENGTH'] content = environ['wsgi.input'].read(int(length)) wikiname = cgi.parse_qs(content).get('wikiname', [''])[0] perms = cgi.parse_qs(content).get('perms', [''])[0] if wikiname: bag = Bag(wikiname) try: bag = store.get(bag) raise HTTP409('The bag already exists') except NoBagError: bag.desc = 'hello' bag.policy.owner = username bag.policy.manage = [username] if perms == 'closed': bag.policy.read = [username] bag.policy.write = [username] bag.policy.create = [username] bag.policy.delete = [username] if perms == 'authrw': bag.policy.read = ['ANY'] bag.policy.write = ['ANY'] bag.policy.create = ['ANY'] bag.policy.delete = ['ANY'] if perms == 'read': bag.policy.write = [username] bag.policy.create = [username] bag.policy.delete = [username] if perms == 'authw': bag.policy.write = ['ANY'] bag.policy.create = ['ANY'] bag.policy.delete = ['ANY'] store.put(bag) recipe = Recipe(wikiname) try: recipe = store.get(recipe) raise HTTP409('That recipe already exists') except NoRecipeError: recipe.desc = 'hello' recipe.policy.owner = username recipe.policy.manage = [username] recipe.set_recipe([[TIDDLYWEB_BAG, ''], [bag.name, '']]) store.put(recipe) user = User(username) note = '' try: user = store.get(user) note = user.note except NoUserError: pass note += '%s\n' % wikiname user.note = note store.put(user) raise HTTP302('%s/spowt/%s' % (server_base_url(environ), urllib.quote(username))) else: raise HTTP409('Missing form data')
def send_template(environ, template_name, template_data=None): """ Set some defaults for a template and send the output. """ default_css_tiddler = '/bags/common/tiddlers/profile.css' if template_data is None: template_data = {} html_template_prefix = environ['tiddlyweb.space_settings']['htmltemplate'] if html_template_prefix: default_css_tiddler = ('/bags/common/tiddlers/%s.css' % html_template_prefix) html_template_prefix += '/' try: name = html_template_prefix + template_name template = get_template(environ, name) except TemplateNotFound: template = get_template(environ, template_name) else: template = get_template(environ, template_name) store = environ['tiddlyweb.store'] linked_resources = {'HtmlCss': [], 'HtmlJavascript': []} if not html_template_prefix or template_name in CUSTOMIZABLES: linked_resources['HtmlCss'] = [default_css_tiddler] # Load CSS and JavaScript overrides. current_space = determine_space(environ, determine_host(environ)[0]) if current_space: recipe_name = determine_space_recipe(environ, current_space) try: recipe = store.get(Recipe(recipe_name)) for title in linked_resources: try: tiddler = Tiddler(title) bag = control.determine_bag_from_recipe( recipe, tiddler, environ) tiddler.bag = bag.name try: tiddler = store.get(tiddler) if 'Javascript' in title: url_content = tiddler.text.strip() if url_content: urls = url_content.split('\n') linked_resources[title] = urls else: url = '/bags/%s/tiddlers/%s' % (encode_name( tiddler.bag), title) linked_resources[title] = [url] except StoreError: continue except StoreError: pass except StoreError: pass template_defaults = { 'original_server_host': original_server_host_url(environ), 'css': linked_resources['HtmlCss'], 'js': linked_resources['HtmlJavascript'], 'server_host': server_base_url(environ), } template_defaults.update(template_data) return template.generate(template_defaults)
def tank_uri(environ, tank_name, slash=False): """ Create a redirect URI for a given tank. """ return server_base_url(environ) + '/tanks/%s' % encode_name(tank_name)
def front(environ, start_response): user = environ['tiddlyweb.usersign'] if user['name'] != 'GUEST' and 'MEMBER' in user['roles']: raise HTTP302( server_base_url(environ) + '/' + encode_name(user['name'])) return send_template(environ, 'home.html', {'title': 'Welcome'})