diff --git a/lib/wttr_srv.py b/lib/wttr_srv.py index 42a0223..4790c8b 100644 --- a/lib/wttr_srv.py +++ b/lib/wttr_srv.py @@ -44,6 +44,24 @@ def is_ip(ip_addr): except socket.error: return False +def show_text_file(name, lang): + """ + show static file `name` for `lang` + """ + text = "" + if name == ":help": + text = open(get_help_file(lang), 'r').read() + text = text.replace('FULL_TRANSLATION', ' '.join(FULL_TRANSLATION)) + text = text.replace('PARTIAL_TRANSLATION', ' '.join(PARTIAL_TRANSLATION)) + elif name == ":bash.function": + text = open(BASH_FUNCTION_FILE, 'r').read() + elif name == ":translation": + text = open(TRANSLATION_FILE, 'r').read() + text = text\ + .replace('NUMBER_OF_LANGUAGES', str(len(SUPPORTED_LANGS)))\ + .replace('SUPPORTED_LANGUAGES', ' '.join(SUPPORTED_LANGS)) + return text.decode('utf-8') + def location_normalize(location): """ Normalize location name `location` @@ -145,154 +163,73 @@ def wttr(location, request): request.referrer request.query_string """ - if request.referrer: - print request.referrer - hostname = request.headers['Host'] - lang = None - if hostname != 'wttr.in' and hostname.endswith('.wttr.in'): - lang = hostname[:-8] + if is_location_blocked(location): + return "" - if request.headers.getlist("X-Forwarded-For"): - ip_addr = request.headers.getlist("X-Forwarded-For")[0] - if ip_addr.startswith('::ffff:'): - ip_addr = ip_addr[7:] - else: - ip_addr = request.remote_addr + ip_addr = client_ip_address(request) try: LIMITS.check_ip(ip_addr) - except RuntimeError, e: - return str(e) - except Exception, e: - logging.error("Exception has occured", exc_info=1) - return "ERROR" - - if location is not None and location.lower() in LOCATION_BLACK_LIST: - return "" + except RuntimeError, exception: + return str(exception) png_filename = None if location is not None and location.lower().endswith(".png"): png_filename = location location = location[:-4] + lang = get_answer_language(request) query = parse_query.parse_query(request.args) - - if 'lang' in request.args: - lang = request.args.get('lang') - if lang is None and 'Accept-Language' in request.headers: - lang = find_supported_language( - parse_accept_language( - request.headers.get('Accept-Language', ''))) - + html_output = get_output_format(request) user_agent = request.headers.get('User-Agent', '').lower() - html_output = not any(agent in user_agent for agent in PLAIN_TEXT_AGENTS) + if location in PLAIN_TEXT_PAGES: - help_ = show_help(location, lang) + help_ = show_text_file(location, lang) if html_output: return render_template('index.html', body=help_) return help_ orig_location = location - if request.headers.getlist("X-Forwarded-For"): - ip_addr = request.headers.getlist("X-Forwarded-For")[0] - if ip_addr.startswith('::ffff:'): - ip_addr = ip_addr[7:] - else: - ip_addr = request.remote_addr + location, override_location_name, full_address, country, query_source_location = \ + location_processing() - try: - # if location is starting with ~ - # or has non ascii symbols - # it should be handled like a search term (for geolocator) - override_location_name = None - full_address = None - - if location is not None and not ascii_only(location): - location = "~" + location - - if location is not None and location.upper() in IATA_CODES: - location = '~%s' % location - - if location is not None and location.startswith('~'): - geolocation = geolocator(location_canonical_name(location[1:])) - if geolocation is not None: - override_location_name = location[1:].replace('+', ' ') - location = "%s,%s" % (geolocation['latitude'], geolocation['longitude']) - full_address = geolocation['address'] - print full_address - else: - location = NOT_FOUND_LOCATION #location[1:] - try: - query_source_location = get_location(ip_addr) - except: - query_source_location = NOT_FOUND_LOCATION, None - - # what units should be used - # metric or imperial - # based on query and location source (imperial for US by default) - print "lang = %s" % lang - if query.get('use_metric', False) and not query.get('use_imperial', False): - query['use_imperial'] = False - query['use_metric'] = True - elif query.get('use_imperial', False) and not query.get('use_metric', False): - query['use_imperial'] = True - query['use_metric'] = False - elif lang == 'us': - # slack uses m by default, to override it speciy us.wttr.in - query['use_imperial'] = True - query['use_metric'] = False - else: - if query_source_location[1] in ['US'] and 'slack' not in user_agent: - query['use_imperial'] = True - query['use_metric'] = False - else: - query['use_imperial'] = False - query['use_metric'] = True - - country = None - if location is None or location == 'MyLocation': - location, country = query_source_location - - if is_ip(location): - location, country = get_location(location) - if location.startswith('@'): - try: - location, country = get_location(socket.gethostbyname(location[1:])) - except: - query_source_location = NOT_FOUND_LOCATION, None + us_ip = query_source_location[1] == 'US' and 'slack' not in user_agent + query = parse_query.metric_or_imperial(query, lang, us_ip=us_ip) - location = location_canonical_name(location) - log("%s %s %s %s %s %s" \ - % (ip_addr, user_agent, orig_location, location, - query.get('use_imperial', False), lang)) + log(" ".join(map(str([ + ip_addr, user_agent, orig_location, location, + query.get('use_imperial', False), lang + ])))) - # We are ready to return the answer - if png_filename: - options = {} - if lang is not None: - options['lang'] = lang + if country and location != NOT_FOUND_LOCATION: + location = "%s, %s" % (location, country) - options['location'] = "%s,%s" % (location, country) + # We are ready to return the answer + try: + if png_filename: + options = { + 'lang': None, + 'location': "%s,%s" % (location, country)} options.update(query) cached_png_file = wttrin_png.make_wttr_in_png(png_filename, options=options) response = make_response(send_file(cached_png_file, attachment_filename=png_filename, mimetype='image/png')) + response.update({ + 'Cache-Control': 'no-cache, no-store, must-revalidate', + 'Pragma': 'no-cache', + 'Expires': '0', + }) # Trying to disable github caching - response.headers['Cache-Control'] = 'no-cache, no-store, must-revalidate' - response.headers['Pragma'] = 'no-cache' - response.headers['Expires'] = '0' return response if location == 'moon' or location.startswith('moon@'): output = get_moon(location, html=html_output, lang=lang) else: - if country and location != NOT_FOUND_LOCATION: - location = "%s, %s" % (location, country) output = get_wetter(location, ip_addr, html=html_output, lang=lang, @@ -302,35 +239,19 @@ def wttr(location, request): url=request.url, ) - if 'Malformed response' in str(output) \ - or 'API key has reached calls per day allowed limit' in str(output): - if html_output: - return MALFORMED_RESPONSE_HTML_PAGE - return get_message('CAPACITY_LIMIT_REACHED', lang).encode('utf-8') - if html_output: - output = output.replace('', - (TWITTER_BUTTON - + GITHUB_BUTTON - + GITHUB_BUTTON_3 - + GITHUB_BUTTON_2 - + GITHUB_BUTTON_FOOTER) + '') + output = add_buttons(output) else: if query.get('days', '3') != '0': #output += '\n' + get_message('NEW_FEATURE', lang).encode('utf-8') output += '\n' + get_message('FOLLOW_ME', lang).encode('utf-8') + '\n' return output - #except RuntimeError, e: - # return str(e) - except Exception, e: - if 'Malformed response' in str(e) \ - or 'API key has reached calls per day allowed limit' in str(e): + except RuntimeError, exception: + if 'Malformed response' in str(exception) \ + or 'API key has reached calls per day allowed limit' in str(exception): if html_output: return MALFORMED_RESPONSE_HTML_PAGE return get_message('CAPACITY_LIMIT_REACHED', lang).encode('utf-8') logging.error("Exception has occured", exc_info=1) return "ERROR" - -SERVER = WSGIServer((LISTEN_HOST, LISTEN_PORT), APP) -SERVER.serve_forever()