<s> from flask import Flask , render_template , flash , redirect , request , url_for , session , Response , json <EOL> from flask_bootstrap import Bootstrap <EOL> from flask_login import login_user , current_user , login_required , logout_user <EOL> from model import db , Move , Sample , MoveEdit , User , UserPreference , AlembicVersion <EOL> from datetime import timedelta , datetime <EOL> from sqlalchemy . sql import func <EOL> from sqlalchemy import distinct , literal <EOL> import os <EOL> import re <EOL> from flask_bcrypt import Bcrypt <EOL> import imports <EOL> import gpx_export <EOL> import csv_export <EOL> import dateutil . parser <EOL> from flask . helpers import make_response <EOL> from flask_script import Manager , Server <EOL> from flask_migrate import Migrate , MigrateCommand <EOL> from commands import AddUser , ImportMove , DeleteMove , ListMoves <EOL> from filters import register_filters , register_globals , radian_to_degree , get_city <EOL> from login import login_manager , load_user , LoginForm <EOL> import itertools <EOL> from collections import OrderedDict <EOL> from flask_util_js import FlaskUtilJs <EOL> from _import import postprocess_move <EOL> from geopy . distance import vincenty <EOL> import math <EOL> import operator <EOL> import pytz <EOL> from monthdelta import monthdelta <EOL> from jinja2 . exceptions import TemplateNotFound <EOL> try : <EOL> from urllib . parse import quote_plus <EOL> except ImportError : <EOL> from urllib import quote_plus as __quote_plus <EOL> quote_plus = lambda x : __quote_plus ( x . encode ( '<STR_LIT:utf-8>' ) ) <EOL> app = Flask ( '<STR_LIT>' ) <EOL> fujs = FlaskUtilJs ( app ) <EOL> app_bcrypt = Bcrypt ( ) <EOL> migrate = Migrate ( app , db ) <EOL> register_filters ( app ) <EOL> register_globals ( app ) <EOL> def _parse_revision ( filename ) : <EOL> pattern = re . compile ( r"<STR_LIT>" ) <EOL> with open ( filename , '<STR_LIT:r>' ) as f : <EOL> for line in f : <EOL> match = pattern . match ( line ) <EOL> if match : <EOL> return int ( match . group ( <NUM_LIT:1> ) ) <EOL> raise RuntimeError ( "<STR_LIT>" % filename ) <EOL> def initialize_config ( f ) : <EOL> random_bytes = os . urandom ( <NUM_LIT:32> ) <EOL> if isinstance ( random_bytes [ <NUM_LIT:0> ] , str ) : <EOL> random_bytes = [ ord ( c ) for c in random_bytes ] <EOL> data = "<STR_LIT>" % "<STR_LIT>" . join ( "<STR_LIT>" . format ( c ) for c in random_bytes ) <EOL> f . write ( data ) <EOL> def _sample_to_point ( sample ) : <EOL> return ( radian_to_degree ( sample . latitude ) , radian_to_degree ( sample . longitude ) ) <EOL> def _get_date_range ( ) : <EOL> timezone = pytz . timezone ( session [ '<STR_LIT>' ] ) <EOL> now = timezone . localize ( datetime . now ( ) ) <EOL> if '<STR_LIT>' in request . args : <EOL> start_date = request . args . get ( '<STR_LIT>' ) <EOL> start_date = dateutil . parser . parse ( start_date ) <EOL> start_date = start_date . date ( ) <EOL> else : <EOL> start_date = now . date ( ) - monthdelta ( months = <NUM_LIT:1> ) <EOL> if '<STR_LIT>' in request . args : <EOL> end_date = request . args . get ( '<STR_LIT>' ) <EOL> end_date = dateutil . parser . parse ( end_date ) <EOL> end_date = end_date . date ( ) <EOL> else : <EOL> end_date = now . date ( ) <EOL> return start_date , end_date <EOL> def calculate_distances ( model , samples ) : <EOL> total_distance_horizontal = <NUM_LIT:0.0> <EOL> total_distance_real = <NUM_LIT:0.0> <EOL> total_distance_descent = <NUM_LIT:0.0> <EOL> total_distance_ascent = <NUM_LIT:0.0> <EOL> total_distance_flat = <NUM_LIT:0.0> <EOL> previous_gps_sample = None <EOL> current_altitude_sample = None <EOL> previous_altitude_sample = None <EOL> for sample in samples : <EOL> if sample . altitude : <EOL> current_altitude_sample = sample <EOL> if sample . latitude : <EOL> if previous_gps_sample : <EOL> distance_horizontal = vincenty ( _sample_to_point ( previous_gps_sample ) , _sample_to_point ( sample ) ) . meters <EOL> if previous_altitude_sample : <EOL> if current_altitude_sample != previous_altitude_sample and distance_horizontal > <NUM_LIT:0> : <EOL> total_distance_horizontal += distance_horizontal <EOL> hm = current_altitude_sample . altitude - previous_altitude_sample . altitude <EOL> distance_real = math . sqrt ( distance_horizontal ** <NUM_LIT:2> + hm ** <NUM_LIT:2> ) <EOL> if hm > <NUM_LIT:0> : <EOL> total_distance_ascent += distance_real <EOL> elif hm < <NUM_LIT:0> : <EOL> total_distance_descent += distance_real <EOL> else : <EOL> total_distance_flat += distance_real <EOL> total_distance_real += distance_real <EOL> previous_gps_sample = sample <EOL> previous_altitude_sample = current_altitude_sample <EOL> else : <EOL> previous_altitude_sample = current_altitude_sample <EOL> else : <EOL> previous_gps_sample = sample <EOL> model [ '<STR_LIT>' ] = total_distance_horizontal <EOL> model [ '<STR_LIT>' ] = total_distance_ascent <EOL> model [ '<STR_LIT>' ] = total_distance_descent <EOL> model [ '<STR_LIT>' ] = total_distance_flat <EOL> model [ '<STR_LIT>' ] = total_distance_real <EOL> def init ( configfile ) : <EOL> app . config . from_pyfile ( '<STR_LIT>' , silent = False ) <EOL> if configfile : <EOL> if not os . path . exists ( configfile ) : <EOL> with open ( configfile , '<STR_LIT:w>' ) as f : <EOL> initialize_config ( f ) <EOL> print ( "<STR_LIT>" % configfile ) <EOL> app . config . from_pyfile ( configfile , silent = False ) <EOL> assert app . config [ '<STR_LIT>' ] <EOL> SESSION_VERSION = <NUM_LIT:1> <EOL> app . config [ '<STR_LIT>' ] = "<STR_LIT>" % ( app . config [ '<STR_LIT>' ] , SESSION_VERSION ) <EOL> assert '<STR_LIT>' not in app . config <EOL> app . config [ '<STR_LIT>' ] = False <EOL> db . init_app ( app ) <EOL> with app . app_context ( ) : <EOL> if db . engine . name == '<STR_LIT>' : <EOL> db . create_all ( ) <EOL> Bootstrap ( app ) <EOL> app_bcrypt . init_app ( app ) <EOL> login_manager . init_app ( app ) <EOL> login_manager . login_view = "<STR_LIT>" <EOL> return app <EOL> @ app . before_first_request <EOL> def check_db_schema ( ) : <EOL> if db . engine . name != '<STR_LIT>' : <EOL> version = AlembicVersion . query . scalar ( ) <EOL> assert version , "<STR_LIT>" % __file__ <EOL> migrations = os . path . join ( os . path . dirname ( os . path . realpath ( __file__ ) ) , '<STR_LIT>' , '<STR_LIT>' ) <EOL> revisions = [ _parse_revision ( os . path . join ( migrations , filename ) ) for filename in os . listdir ( migrations ) if filename . endswith ( '<STR_LIT>' ) ] <EOL> max_revision = max ( revisions ) <EOL> db_version = int ( version . version_num ) <EOL> assert db_version == max_revision , "<STR_LIT>" % ( db_version , __file__ , max_revision ) <EOL> def command_app_context ( ) : <EOL> app . config . update ( SQLALCHEMY_ECHO = False ) <EOL> return app . app_context ( ) <EOL> manager = Manager ( init ) <EOL> manager . add_option ( '<STR_LIT:-c>' , '<STR_LIT>' , dest = '<STR_LIT>' , default = '<STR_LIT>' , required = False ) <EOL> manager . add_command ( "<STR_LIT>" , Server ( use_debugger = True ) ) <EOL> manager . add_command ( '<STR_LIT>' , MigrateCommand ) <EOL> manager . add_command ( '<STR_LIT>' , AddUser ( command_app_context , app_bcrypt ) ) <EOL> manager . add_command ( '<STR_LIT>' , ImportMove ( command_app_context ) ) <EOL> manager . add_command ( '<STR_LIT>' , DeleteMove ( command_app_context ) ) <EOL> manager . add_command ( '<STR_LIT>' , ListMoves ( command_app_context ) ) <EOL> @ app . errorhandler ( <NUM_LIT> ) <EOL> def error404 ( error ) : <EOL> return render_template ( '<STR_LIT>' ) , <NUM_LIT> <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT:GET>' , '<STR_LIT:POST>' ] ) <EOL> @ login_required <EOL> def move_import ( ) : <EOL> xmlfiles = request . files . getlist ( '<STR_LIT>' ) <EOL> imported_moves = [ ] <EOL> for xmlfile in xmlfiles : <EOL> filename = xmlfile . filename <EOL> if filename : <EOL> app . logger . info ( "<STR_LIT>" % filename ) <EOL> move = imports . move_import ( xmlfile , filename , current_user , request . form ) <EOL> if move : <EOL> imported_moves . append ( move ) <EOL> if imported_moves : <EOL> if len ( imported_moves ) == <NUM_LIT:1> : <EOL> move = imported_moves [ <NUM_LIT:0> ] <EOL> flash ( "<STR_LIT>" % ( xmlfile . filename , move . id ) ) <EOL> return redirect ( url_for ( '<STR_LIT>' , id = move . id ) ) <EOL> else : <EOL> flash ( "<STR_LIT>" % len ( imported_moves ) ) <EOL> return redirect ( url_for ( '<STR_LIT>' ) ) <EOL> else : <EOL> return render_template ( '<STR_LIT>' ) <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT:GET>' , '<STR_LIT:POST>' ] ) <EOL> def login ( ) : <EOL> form = LoginForm ( ) <EOL> if form . validate_on_submit ( ) : <EOL> user = load_user ( username = form . username . data ) <EOL> if not user : <EOL> flash ( '<STR_LIT>' , '<STR_LIT:error>' ) <EOL> return render_template ( '<STR_LIT>' , form = form ) <EOL> if app_bcrypt . check_password_hash ( user . password , form . password . data ) : <EOL> login_user ( user ) <EOL> assert '<STR_LIT>' in request . form <EOL> pytz . timezone ( request . form [ '<STR_LIT>' ] ) <EOL> session [ '<STR_LIT>' ] = request . form [ '<STR_LIT>' ] <EOL> if '<STR_LIT>' in request . args : <EOL> return redirect ( request . args . get ( '<STR_LIT>' ) ) <EOL> return redirect ( url_for ( '<STR_LIT>' ) ) <EOL> else : <EOL> flash ( "<STR_LIT>" , '<STR_LIT:error>' ) <EOL> return render_template ( '<STR_LIT>' , form = form ) <EOL> return render_template ( '<STR_LIT>' , form = form ) <EOL> @ app . route ( '<STR_LIT>' ) <EOL> @ login_required <EOL> def logout ( ) : <EOL> logout_user ( ) <EOL> return redirect ( url_for ( '<STR_LIT:index>' ) ) <EOL> @ app . route ( '<STR_LIT:/>' ) <EOL> def index ( ) : <EOL> nr_of_moves = Move . query . count ( ) <EOL> return render_template ( '<STR_LIT>' , nr_of_moves = nr_of_moves ) <EOL> @ app . route ( '<STR_LIT>' ) <EOL> @ login_required <EOL> def dashboard ( ) : <EOL> start_date , end_date = _get_date_range ( ) <EOL> moves = _current_user_filtered ( Move . query ) . filter ( Move . date_time >= start_date ) . filter ( Move . date_time < end_date + timedelta ( days = <NUM_LIT:1> ) ) . all ( ) <EOL> model = { } <EOL> model [ '<STR_LIT>' ] = start_date <EOL> model [ '<STR_LIT>' ] = end_date <EOL> model [ '<STR_LIT>' ] = len ( moves ) <EOL> total_distance_by_activity = { } <EOL> total_duration_by_activity = { } <EOL> total_average_by_activity = { } <EOL> total_ascent_by_activity = { } <EOL> total_descent_by_activity = { } <EOL> for move in moves : <EOL> if move . activity not in total_distance_by_activity : <EOL> total_distance_by_activity [ move . activity ] = <NUM_LIT:0> <EOL> total_distance_by_activity [ move . activity ] += move . distance <EOL> if move . activity not in total_duration_by_activity : <EOL> total_duration_by_activity [ move . activity ] = <NUM_LIT:0> <EOL> total_duration_by_activity [ move . activity ] += move . duration . total_seconds ( ) <EOL> if move . activity not in total_ascent_by_activity : <EOL> total_ascent_by_activity [ move . activity ] = <NUM_LIT:0> <EOL> if move . ascent : <EOL> total_ascent_by_activity [ move . activity ] += move . ascent <EOL> if move . activity not in total_descent_by_activity : <EOL> total_descent_by_activity [ move . activity ] = <NUM_LIT:0> <EOL> if move . ascent : <EOL> total_descent_by_activity [ move . activity ] += move . descent <EOL> for activity in list ( total_distance_by_activity . keys ( ) ) : <EOL> if ( total_distance_by_activity [ activity ] == <NUM_LIT:0> ) : <EOL> del total_distance_by_activity [ activity ] <EOL> for activity in list ( total_duration_by_activity . keys ( ) ) : <EOL> if ( total_duration_by_activity [ activity ] == timedelta ( <NUM_LIT:0> ) ) : <EOL> del total_duration_by_activity [ activity ] <EOL> for activity in list ( total_ascent_by_activity . keys ( ) ) : <EOL> if ( total_ascent_by_activity [ activity ] == <NUM_LIT:0> ) : <EOL> del total_ascent_by_activity [ activity ] <EOL> for activity in list ( total_descent_by_activity . keys ( ) ) : <EOL> if ( total_descent_by_activity [ activity ] == <NUM_LIT:0> ) : <EOL> del total_descent_by_activity [ activity ] <EOL> total_duration_with_distance = <NUM_LIT:0> <EOL> for activity in total_distance_by_activity . keys ( ) : <EOL> if activity not in total_duration_by_activity : <EOL> continue <EOL> total_average_by_activity [ activity ] = total_distance_by_activity [ activity ] / total_duration_by_activity [ activity ] <EOL> total_duration_with_distance += total_duration_by_activity [ activity ] <EOL> model [ '<STR_LIT>' ] = OrderedDict ( sorted ( total_distance_by_activity . items ( ) , key = operator . itemgetter ( <NUM_LIT:1> ) , reverse = True ) ) <EOL> model [ '<STR_LIT>' ] = OrderedDict ( sorted ( total_duration_by_activity . items ( ) , key = operator . itemgetter ( <NUM_LIT:1> ) , reverse = True ) ) <EOL> model [ '<STR_LIT>' ] = OrderedDict ( sorted ( total_average_by_activity . items ( ) , key = operator . itemgetter ( <NUM_LIT:1> ) , reverse = True ) ) <EOL> model [ '<STR_LIT>' ] = OrderedDict ( sorted ( total_ascent_by_activity . items ( ) , key = operator . itemgetter ( <NUM_LIT:1> ) , reverse = True ) ) <EOL> model [ '<STR_LIT>' ] = OrderedDict ( sorted ( total_descent_by_activity . items ( ) , key = operator . itemgetter ( <NUM_LIT:1> ) , reverse = True ) ) <EOL> model [ '<STR_LIT>' ] = sum ( total_distance_by_activity . values ( ) ) <EOL> model [ '<STR_LIT>' ] = sum ( total_duration_by_activity . values ( ) , <NUM_LIT:0> ) <EOL> model [ '<STR_LIT>' ] = model [ '<STR_LIT>' ] / total_duration_with_distance if total_duration_with_distance > <NUM_LIT:0> else None <EOL> model [ '<STR_LIT>' ] = sum ( total_ascent_by_activity . values ( ) ) <EOL> model [ '<STR_LIT>' ] = sum ( total_descent_by_activity . values ( ) ) <EOL> return render_template ( '<STR_LIT>' , ** model ) <EOL> def _parse_move_filter ( filter_query ) : <EOL> if not filter_query : <EOL> return None <EOL> filter_parts = [ part . strip ( ) for part in filter_query . split ( '<STR_LIT::>' ) ] <EOL> if len ( filter_parts ) != <NUM_LIT:2> or filter_parts [ <NUM_LIT:0> ] not in ( '<STR_LIT>' ) : <EOL> flash ( "<STR_LIT>" % filter_query , '<STR_LIT:error>' ) <EOL> return None <EOL> else : <EOL> filter_attr = filter_parts [ <NUM_LIT:0> ] <EOL> filter_value = filter_parts [ <NUM_LIT:1> ] <EOL> return { filter_attr : filter_value } <EOL> def _current_user_filtered ( query ) : <EOL> return query . filter_by ( user = current_user ) <EOL> @ app . route ( '<STR_LIT>' ) <EOL> @ login_required <EOL> def moves ( ) : <EOL> start_date , end_date = _get_date_range ( ) <EOL> filter_end_date = end_date + timedelta ( days = <NUM_LIT:1> ) <EOL> moves = _current_user_filtered ( Move . query ) . filter ( Move . date_time >= start_date ) . filter ( Move . date_time < filter_end_date ) <EOL> total_moves_count = moves . count ( ) <EOL> move_filter = _parse_move_filter ( request . args . get ( '<STR_LIT>' ) ) <EOL> if move_filter : <EOL> moves = moves . filter_by ( ** move_filter ) <EOL> sort = request . args . get ( '<STR_LIT>' ) <EOL> sort_order = request . args . get ( '<STR_LIT>' ) <EOL> sort_default = '<STR_LIT>' <EOL> if '<STR_LIT>' not in current_user . preferences : <EOL> default_sort_value = { '<STR_LIT>' : sort_default , '<STR_LIT>' : '<STR_LIT>' } <EOL> current_user . preferences [ '<STR_LIT>' ] = UserPreference ( '<STR_LIT>' , default_sort_value ) <EOL> db . session . commit ( ) <EOL> if not sort : <EOL> sort = current_user . preferences [ '<STR_LIT>' ] . value [ '<STR_LIT>' ] <EOL> if not sort_order : <EOL> sort_order = current_user . preferences [ '<STR_LIT>' ] . value [ '<STR_LIT>' ] <EOL> if not hasattr ( Move , sort ) : <EOL> flash ( "<STR_LIT>" % sort , '<STR_LIT:error>' ) <EOL> sort = sort_default <EOL> new_sort_value = { '<STR_LIT>' : sort , '<STR_LIT>' : sort_order } <EOL> if current_user . preferences [ '<STR_LIT>' ] . value != new_sort_value : <EOL> app . logger . debug ( "<STR_LIT>" % new_sort_value ) <EOL> current_user . preferences [ '<STR_LIT>' ] . value = new_sort_value <EOL> db . session . commit ( ) <EOL> activity_counts = OrderedDict ( _current_user_filtered ( db . session . query ( Move . activity , func . count ( Move . id ) ) ) <EOL> . filter ( Move . date_time >= start_date ) <EOL> . filter ( Move . date_time < filter_end_date ) <EOL> . group_by ( Move . activity ) <EOL> . order_by ( func . count ( Move . id ) . desc ( ) ) ) <EOL> actual_activities_query = _current_user_filtered ( db . session . query ( distinct ( Move . activity ) ) ) <EOL> if move_filter : <EOL> actual_activities_query = actual_activities_query . filter_by ( ** move_filter ) <EOL> actual_activities = set ( [ activity for activity , in actual_activities_query ] ) <EOL> sort_attr = getattr ( Move , sort ) <EOL> if not sort_order or sort_order == '<STR_LIT>' : <EOL> sort_attr = sort_attr . asc ( ) <EOL> else : <EOL> sort_attr = sort_attr . desc ( ) <EOL> if db . engine . name == "<STR_LIT>" : <EOL> sort_attr = sort_attr . nullslast ( ) <EOL> show_columns = { } <EOL> for column in ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) : <EOL> attr = getattr ( Move , column ) <EOL> base_query = _current_user_filtered ( db . session . query ( attr ) . filter ( attr != None ) <EOL> . filter ( Move . date_time >= start_date ) <EOL> . filter ( Move . date_time < filter_end_date ) ) <EOL> if move_filter : <EOL> base_query = base_query . filter_by ( ** move_filter ) <EOL> exists_query = db . session . query ( literal ( True ) ) . filter ( base_query . exists ( ) ) <EOL> show_columns [ column ] = exists_query . scalar ( ) <EOL> show_columns [ '<STR_LIT>' ] = not move_filter or '<STR_LIT>' not in move_filter <EOL> moves = moves . order_by ( sort_attr ) <EOL> return render_template ( '<STR_LIT>' , <EOL> start_date = start_date , <EOL> end_date = end_date , <EOL> moves = moves , <EOL> total_moves_count = total_moves_count , <EOL> activity_counts = activity_counts , <EOL> actual_activities = actual_activities , <EOL> show_columns = show_columns , <EOL> sort = sort , <EOL> sort_order = sort_order ) <EOL> @ app . route ( '<STR_LIT>' ) <EOL> @ login_required <EOL> def delete_move ( id ) : <EOL> return delete_moves ( "<STR_LIT:%s>" % id ) <EOL> @ app . route ( '<STR_LIT>' ) <EOL> @ login_required <EOL> def delete_moves ( ids ) : <EOL> parsed_ids = [ int ( id ) for id in ids . split ( '<STR_LIT:U+002C>' ) ] <EOL> if parsed_ids : <EOL> for id in parsed_ids : <EOL> move = _current_user_filtered ( Move . query ) . filter_by ( id = id ) . first_or_404 ( ) <EOL> Sample . query . filter_by ( move = move ) . delete ( synchronize_session = False ) <EOL> MoveEdit . query . filter_by ( move = move ) . delete ( synchronize_session = False ) <EOL> db . session . delete ( move ) <EOL> db . session . commit ( ) <EOL> if len ( parsed_ids ) == <NUM_LIT:1> : <EOL> flash ( "<STR_LIT>" % parsed_ids [ <NUM_LIT:0> ] , '<STR_LIT:success>' ) <EOL> else : <EOL> flash ( "<STR_LIT>" % len ( parsed_ids ) , '<STR_LIT:success>' ) <EOL> else : <EOL> flash ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> return redirect ( url_for ( '<STR_LIT>' ) ) <EOL> @ app . route ( '<STR_LIT>' ) <EOL> def export_move ( id ) : <EOL> move = Move . query . filter_by ( id = id ) . first_or_404 ( ) <EOL> if not move . public and move . user != current_user : <EOL> return app . login_manager . unauthorized ( ) <EOL> if "<STR_LIT>" in request . args : <EOL> format = request . args . get ( "<STR_LIT>" ) . lower ( ) <EOL> else : <EOL> format = "<STR_LIT>" <EOL> format_handlers = { '<STR_LIT>' : gpx_export . gpx_export , <EOL> '<STR_LIT>' : csv_export . csv_export } <EOL> if format not in format_handlers : <EOL> flash ( "<STR_LIT>" % format , '<STR_LIT:error>' ) <EOL> return redirect ( url_for ( '<STR_LIT>' , id = id ) ) <EOL> export_file = format_handlers [ format ] ( move ) <EOL> if not export_file : <EOL> return redirect ( url_for ( '<STR_LIT>' , id = id ) ) <EOL> response = make_response ( export_file ) <EOL> date_time = move . date_time . strftime ( '<STR_LIT>' ) <EOL> if move . location_raw : <EOL> address = move . location_raw [ '<STR_LIT:address>' ] <EOL> city = get_city ( address ) <EOL> country_code = address [ '<STR_LIT>' ] . upper ( ) <EOL> filename = "<STR_LIT>" % ( date_time , country_code , city , move . activity , format ) <EOL> else : <EOL> filename = "<STR_LIT>" % ( date_time , move . activity , format ) <EOL> response . headers [ '<STR_LIT>' ] = "<STR_LIT>" % ( quote_plus ( filename ) ) <EOL> return response <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT:POST>' ] ) <EOL> @ login_required <EOL> def edit_move ( id ) : <EOL> name = request . form . get ( '<STR_LIT:name>' ) <EOL> pk = request . form . get ( '<STR_LIT>' ) <EOL> value = request . form . get ( '<STR_LIT:value>' ) <EOL> assert id == int ( pk ) <EOL> move = _current_user_filtered ( Move . query ) . filter_by ( id = id ) . first_or_404 ( ) <EOL> if name == '<STR_LIT>' : <EOL> result = db . session . query ( Move . activity_type ) . filter ( Move . activity == value ) . first ( ) <EOL> if not result : <EOL> raise ValueError ( "<STR_LIT>" % value ) <EOL> activity_type , = result <EOL> move_edit = MoveEdit ( ) <EOL> move_edit . date_time = datetime . now ( ) <EOL> move_edit . move = move <EOL> move_edit . old_value = { '<STR_LIT>' : move . activity , '<STR_LIT>' : move . activity_type } <EOL> move_edit . new_value = { '<STR_LIT>' : value , '<STR_LIT>' : activity_type } <EOL> db . session . add ( move_edit ) <EOL> move . activity_type = activity_type <EOL> move . activity = value <EOL> db . session . commit ( ) <EOL> elif name == '<STR_LIT>' : <EOL> move_edit = MoveEdit ( ) <EOL> move_edit . date_time = datetime . now ( ) <EOL> move_edit . move = move <EOL> move_edit . old_value = { '<STR_LIT>' : move . public } <EOL> move_edit . new_value = { '<STR_LIT>' : not move . public } <EOL> db . session . add ( move_edit ) <EOL> move . public = not move . public <EOL> db . session . commit ( ) <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" % name ) <EOL> return "<STR_LIT:OK>" <EOL> @ app . route ( '<STR_LIT>' ) <EOL> @ login_required <EOL> def activity_types ( ) : <EOL> activities = db . session . query ( Move . activity ) . group_by ( Move . activity ) . order_by ( Move . activity . asc ( ) ) <EOL> data = [ { '<STR_LIT:value>' : activity , '<STR_LIT:text>' : activity } for activity , in activities ] <EOL> return Response ( json . dumps ( data ) , mimetype = '<STR_LIT:application/json>' ) <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT:GET>' ] ) <EOL> def move ( id ) : <EOL> move = Move . query . filter_by ( id = id ) . first_or_404 ( ) <EOL> if not move . public and move . user != current_user : <EOL> return app . login_manager . unauthorized ( ) <EOL> samples = move . samples . order_by ( '<STR_LIT>' ) . all ( ) <EOL> events = [ sample for sample in samples if sample . events ] <EOL> filtered_events = [ ] <EOL> pauses = [ ] <EOL> laps = [ ] <EOL> pause_begin = None <EOL> for sample in events : <EOL> assert len ( sample . events . keys ( ) ) == <NUM_LIT:1> <EOL> if '<STR_LIT>' in sample . events : <EOL> state = sample . events [ '<STR_LIT>' ] [ '<STR_LIT:state>' ] . lower ( ) == '<STR_LIT:true>' <EOL> if state : <EOL> pause_begin = sample <EOL> elif not state and pause_begin : <EOL> pauses . append ( [ pause_begin , sample ] ) <EOL> elif '<STR_LIT>' in sample . events : <EOL> laps . append ( sample ) <EOL> else : <EOL> filtered_events . append ( sample ) <EOL> model = { } <EOL> model [ '<STR_LIT>' ] = app . config [ '<STR_LIT>' ] if '<STR_LIT>' in app . config else None <EOL> model [ '<STR_LIT>' ] = move <EOL> model [ '<STR_LIT>' ] = samples <EOL> model [ '<STR_LIT>' ] = filtered_events <EOL> model [ '<STR_LIT>' ] = pauses <EOL> model [ '<STR_LIT>' ] = laps <EOL> gps_samples = [ sample for sample in samples if sample . sample_type and sample . sample_type . startswith ( '<STR_LIT>' ) ] <EOL> model [ '<STR_LIT>' ] = gps_samples <EOL> if gps_samples : <EOL> if not move . gps_center_max_distance : <EOL> postprocess_move ( move ) <EOL> flash ( u"<STR_LIT>" % len ( gps_samples ) , u'<STR_LIT>' ) <EOL> db . session . commit ( ) <EOL> gps_center_max_distance = move . gps_center_max_distance <EOL> if gps_center_max_distance < <NUM_LIT> : <EOL> map_zoom_level = <NUM_LIT> <EOL> elif gps_center_max_distance < <NUM_LIT> : <EOL> map_zoom_level = <NUM_LIT> <EOL> elif gps_center_max_distance < <NUM_LIT> : <EOL> map_zoom_level = <NUM_LIT:12> <EOL> elif gps_center_max_distance < <NUM_LIT> : <EOL> map_zoom_level = <NUM_LIT:11> <EOL> else : <EOL> map_zoom_level = <NUM_LIT:10> <EOL> calculate_distances ( model , move . samples ) <EOL> model [ '<STR_LIT>' ] = map_zoom_level <EOL> if '<STR_LIT>' in move . activity : <EOL> swimming_events = [ sample for sample in filtered_events if '<STR_LIT>' in sample . events ] <EOL> model [ '<STR_LIT>' ] = swimming_events <EOL> model [ '<STR_LIT>' ] = [ sample for sample in swimming_events if sample . events [ '<STR_LIT>' ] [ '<STR_LIT:type>' ] == '<STR_LIT>' ] <EOL> model [ '<STR_LIT>' ] = [ sample for sample in swimming_events if sample . events [ '<STR_LIT>' ] [ '<STR_LIT:type>' ] == '<STR_LIT>' ] <EOL> swimming_strokes = [ sample for sample in swimming_events if sample . events [ '<STR_LIT>' ] [ '<STR_LIT:type>' ] == '<STR_LIT>' ] <EOL> model [ '<STR_LIT>' ] = swimming_strokes <EOL> pause_samples = list ( itertools . chain . from_iterable ( pauses ) ) <EOL> model [ '<STR_LIT>' ] = sorted ( swimming_strokes + pause_samples , key = lambda sample : sample . time ) <EOL> model [ '<STR_LIT>' ] = timedelta ( seconds = move . duration . total_seconds ( ) / move . distance ) <EOL> if move . stroke_count : <EOL> assert len ( model [ '<STR_LIT>' ] ) == move . stroke_count <EOL> activity_name = move . activity . lower ( ) . replace ( '<STR_LIT:U+0020>' , '<STR_LIT:_>' ) <EOL> try : <EOL> return render_template ( "<STR_LIT>" % activity_name , ** model ) <EOL> except TemplateNotFound : <EOL> return render_template ( "<STR_LIT>" , ** model ) <EOL> except Exception as e : <EOL> if app . debug or app . testing : <EOL> raise e <EOL> else : <EOL> flash ( "<STR_LIT>" % activity_name ) <EOL> return redirect ( url_for ( '<STR_LIT:index>' ) ) <EOL> @ app . route ( '<STR_LIT>' , methods = [ '<STR_LIT:GET>' ] ) <EOL> @ login_required <EOL> def tests ( ) : <EOL> return render_template ( '<STR_LIT>' ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> manager . run ( ) </s>
