Exemple #1
0
def test_printException():
    with app.app_context():
        # printException((mes="An Unknown Error Occured",level="error",err=None))
        assert utils.printException(mes="Not an error") == "Not an error"
        # create an acutal error
        with pytest.raises(Exception):
            try:
                if nothing == True:
                    pass
            except Exception as e:
                mes = utils.printException(mes="Should Be error", err=e)
                assert "NameError" in mes
Exemple #2
0
def edit(article_handle='0'):
    setExits()
    g.title = "Article"
    articles = Article(g.db)
    
    #import pdb; pdb.set_trace()
    rec_id = cleanRecordID(article_handle)
    rec = articles.get(article_handle)
    if not rec and not rec_id == 0:
        flash('Could not find that artcle')
        return redirect(g.homeURL)
    
    if rec_id == 0:
        rec = articles.new()    
    
    #Is there a form?
    if request.form:
        #import pdb; pdb.set_trace()
        
        articles.update(rec,request.form)
        if valid_form(rec):
            if request.form['publication_date']:
                # convert to a date time
                rec.publication_date = getDatetimeFromString(request.form['publication_date'])
            try:
                articles.save(rec)
                g.db.commit()
                return redirect(g.homeURL)
            except Exception as e:
                g.db.rollback()
                flash(printException("Error when attepting to save article.",e))
                
    
    return render_template('news/article_edit.html',rec=rec)
Exemple #3
0
def edit(rec_id=None):
    setExits()
    g.title = "Edit {} Record".format(g.title)

    role = Role(g.db)
    rec = None

    if rec_id == None:
        rec_id = request.form.get('id', request.args.get('id', -1))

    rec_id = cleanRecordID(rec_id)
    #import pdb;pdb.set_trace

    if rec_id < 0:
        flash("That is not a valid ID")
        return redirect(g.listURL)

    if not request.form:
        """ if no form object, send the form page """
        if rec_id == 0:
            rec = role.new()
        else:
            rec = role.get(rec_id)
            if not rec:
                flash("Unable to locate that record")
                return redirect(g.listURL)
    else:
        #have the request form
        #import pdb;pdb.set_trace()
        if rec_id and request.form['id'] != 'None':
            rec = role.get(rec_id)
        else:
            # its a new unsaved record
            rec = role.new()
            role.update(rec, request.form)

        if validForm(rec):
            #update the record
            role.update(rec, request.form)
            # make names lower case
            rec.name = request.form['name'].lower().strip()

            try:
                role.save(rec)
                g.db.commit()
            except Exception as e:
                g.db.rollback()
                flash(
                    printException(
                        'Error attempting to save ' + g.title + ' record.',
                        "error", e))

            return redirect(g.listURL)

        else:
            # form did not validate
            pass

    # display form
    return render_template('role/role_edit.html', rec=rec)
Exemple #4
0
def email_admin(subject=None, message=None):
    """
        Shortcut method to send a quick email to the admin
    """
    try:
        app_config = get_app_config()
        if subject == None:
            subject = "An alert was sent from {}".format(
                app_config['SITE_NAME'])

        if message == None:
            message = "An alert was sent from {} with no message...".format(
                app_config['SITE_NAME'])

        return send_message(
            None,
            subject=subject,
            body=message,
        )
    except Exception as e:
        flash(printException("Not able to send message to admin.", str(e)))
Exemple #5
0
def edit(rec_handle=None):
    setExits()
    g.title = "Edit {} Record".format(g.title)
    #import pdb;pdb.set_trace()

    user = User(g.db)
    rec = None
    request_rec_id = cleanRecordID(
        request.form.get('id', request.args.get('id', -1)))
    is_admin = g.admin.has_access(g.user, User)
    no_delete = not is_admin
    session_roles = session["user_roles"]  #roles of currnet user
    new_password = ''
    confirm_password = ''
    user_roles = ['user']  # default
    roles = Role(g.db).select()
    include_inactive = True

    if not is_admin:
        g.listURL = g.homeURL  # Non admins can't see the list
        include_inactive = False

    if rec_handle != None:
        pass  #rec_handle has to come from admin() at this point
    elif rec_handle == None and g.user != None and request_rec_id == -1:
        rec_handle = g.user
    else:
        rec_handle = request_rec_id
        if rec_handle < 0:
            flash("That is not a valid User ID")
            return redirect(g.listURL)

    if not request.form:
        """ if no form object, send the form page """
        if rec_handle != g.user and not is_admin:
            flash("You do not have access to that area")
            return redirect(g.homeURL)
        elif rec_handle == 0:
            rec = user.new()
        else:
            rec = user.get(rec_handle, include_inactive=include_inactive)
            if not rec:
                flash("Unable to locate user record")
                return redirect('/')

            user_roles = get_user_role_names(rec)

    else:
        #have the request form
        #import pdb;pdb.set_trace()
        is_new_user = False
        if rec_handle and request.form['id'] != 'None':
            rec = user.get(rec_handle, include_inactive=include_inactive)
            user_roles = get_user_role_names(rec)
        else:
            # its a new unsaved record
            is_new_user = True
            rec = user.new()
            user.update(rec, request.form)

        if validForm(rec):

            #Are we editing the current user's record?
            editingCurrentUser = ''
            if (g.user == rec.username):
                if 'new_username' in request.form:
                    editingCurrentUser = request.form['new_username'].strip()
                else:
                    editingCurrentUser = g.user
            else:
                if (g.user == rec.email):
                    editingCurrentUser = request.form['email'].strip()

            #update the record
            user.update(rec, request.form)

            set_username_from_form(rec)
            set_password_from_form(rec)

            try:
                user.save(rec)

                # update the user roles
                if 'roles_select' in request.form:
                    #delete all the users current roles
                    user.clear_roles(rec.id)
                    for role_name in request.form.getlist('roles_select'):
                        #find the role by name
                        role = Role(g.db).select_one(
                            where='name = "{}"'.format(role_name))
                        if role:
                            user.add_role(rec.id, role.id)

                # if the username or email address are the same as g.user
                # update g.user if it changes
                if (editingCurrentUser != ''):
                    setUserStatus(editingCurrentUser, rec.id)

                g.db.commit()

            except Exception as e:
                g.db.rollback()
                flash(
                    printException(
                        'Error attempting to save ' + g.title + ' record.',
                        "error", e))
                return redirect(g.listURL)

            if is_new_user == True and rec.email:
                from takeabeltof.mailer import send_message

                # send an email to welcome the new user
                full_name = '{} {}'.format(rec.first_name,
                                           rec.last_name).strip()

                context = {
                    'rec': rec,
                    'full_name': full_name,
                }
                to_address_list = [(full_name, rec.email)]
                sent, msg = send_message(
                    to_address_list,
                    subject="Welcome to {{config.SITE_NAME}}",
                    context=context,
                    html_template='user/email/welcome.html',
                    text_template='user/email/welcome.txt',
                )
                if not sent:
                    flash('The welcome message could not be sent. Error: {}'.
                          format(msg))

            return redirect(g.listURL)

        else:
            # form did not validate, give user the option to keep their old password if there was one
            #need to restore the username
            user.update(rec, request.form)
            if 'new_username' in request.form:
                rec.username = request.form[
                    'new_username']  #preserve user input
            # preserve the selected roles
            #import pdb;pdb.set_trace()
            if 'roles_select' in request.form:
                user_roles = request.form.getlist('roles_select')
            #and password
            new_password = request.form.get('new_password', '')
            confirm_password = request.form.get('confirm_password', '')

    # display form
    return render_template(
        'user/user_edit.html',
        rec=rec,
        no_delete=no_delete,
        is_admin=is_admin,
        user_roles=user_roles,
        roles=roles,
        session_roles=session_roles,
        new_password=new_password,
        confirm_password=confirm_password,
    )
Exemple #6
0
def register():
    """Allow people to sign up thier own accounts on the web site"""
    setExits()
    g.title = "Account Registration"
    g.editURL = url_for('.register')
    g.listURL = '/'  # incase user cancels
    user = User(g.db)
    rec = user.new()

    from takeabeltof.mailer import send_message
    from app import app

    is_admin = False
    user_roles = None
    roles = None
    no_delete = True
    success = True
    help = render_markdown_for("user/new_account_help.md", mod)

    if 'confirm' in request.args:
        #Try to find the user record that requested registration
        rec = user.select_one(where='access_token = "{}"'.format(
            request.args.get('confirm', '')).strip())
        if rec and rec.access_token_expires > time():
            if rec.active == 1:
                success = "active"
            else:
                success = "waiting"

            #inform the admin
            to = [(app.config['MAIL_DEFAULT_SENDER'],
                   app.config['MAIL_DEFAULT_ADDR'])]
            confirmURL = "{}://{}{}?activate={}".format(
                app.config['HOST_PROTOCOL'], app.config['HOST_NAME'],
                url_for('.activate'), rec.access_token)
            deleteURL = "{}://{}{}?delete={}".format(
                app.config['HOST_PROTOCOL'], app.config['HOST_NAME'],
                url_for('.delete'), rec.access_token)
            context = {
                'rec': rec,
                'confirmURL': confirmURL,
                'deleteURL': deleteURL
            }
            subject = 'Activate Account Request from - {}'.format(
                app.config['SITE_NAME'])
            html_template = 'user/email/admin_activate_acct.html'
            text_template = None
            send_message(to,
                         context=context,
                         subject=subject,
                         html_template=html_template,
                         text_template=text_template)

            return render_template('user/registration_success.html',
                                   success=success)
        else:
            flash("That registration request has expired")
            return redirect('/')

    if not request.form:
        pass
    else:
        if validForm(rec):
            #update the record
            user.update(rec, request.form)
            rec.active = 0  # Self registered accounts are inactive by default
            set_password_from_form(rec)
            set_username_from_form(rec)
            rec.access_token = get_access_token()
            rec.access_token_expires = time() + (3600 * 48)

            try:
                user.save(rec)

                #Send confirmation email to user
                full_name = '{} {}'.format(rec.first_name,
                                           rec.last_name).strip()
                to = [(full_name, rec.email)]
                context = {'rec': rec, 'confirmation_code': rec.access_token}
                subject = 'Signup Success'
                html_template = 'user/email/registration_confirm.html'
                text_template = 'user/email/registration_confirm.txt'
                send_message(to,
                             context=context,
                             subject=subject,
                             html_template=html_template,
                             text_template=text_template)

                #inform the admin
                to = [(app.config['MAIL_DEFAULT_SENDER'],
                       app.config['MAIL_DEFAULT_ADDR'])]
                deleteURL = "{}://{}{}?delete={}".format(
                    app.config['HOST_PROTOCOL'], app.config['HOST_NAME'],
                    url_for('.delete'), rec.access_token)
                context = {
                    'rec':
                    rec,
                    'deleteURL':
                    deleteURL,
                    'registration_exp':
                    datetime.fromtimestamp(
                        rec.access_token_expires).strftime('%Y-%m-%d %H:%M:%S')
                }
                subject = 'Unconfirmed Account Request from - {}'.format(
                    app.config['SITE_NAME'])
                html_template = 'user/email/admin_activate_acct.html'
                text_template = None
                send_message(to,
                             context=context,
                             subject=subject,
                             html_template=html_template,
                             text_template=text_template)

                g.db.commit()

            except Exception as e:
                g.db.rollback()
                mes = "An error occured while new user was attempting to register"
                printException(mes, "error", e)
                # Send email to the administrator
                to = [(app.config['MAIL_DEFAULT_SENDER'],
                       app.config['MAIL_DEFAULT_ADDR'])]
                context = {'mes': mes, 'rec': rec, 'e': str(e)}
                body = "Signup Error\n{{context.mes}}\n{{context.e}}\nrec:\n{{context.rec}}"
                send_message(to, context=context, body=body, subject=mes)
                success = False

            return render_template('user/registration_success.html',
                                   success=success)
        else:
            #validation failed
            user.update(rec, request.form)

    return render_template('user/user_edit.html',
                           rec=rec,
                           no_delete=no_delete,
                           is_admin=is_admin,
                           user_roles=user_roles,
                           roles=roles,
                           help=help)
Exemple #7
0
def get_jump_data():
    try:
        mes = 'No message Yet...'
        from takeabeltof.database import Database
        db = Database(working_path + "/" + app.config['DATABASE_PATH']).connect()
        init_tables(db) # creates tables if needed

    
        # Use this to determine if bikes have been off the system too long (getting recharged?)
        
        last_sighting_limit = (local_datetime_now() - timedelta(hours=2)).isoformat(sep=' ')

        #size=10
        #network = 165
        size = app.config['JUMP_REQUEST_SIZE']
        network = app.config['JUMP_NETWORK_ID']
        shapes_list = get_shape_list()
        if not shapes_list:
            # most likely the json files don't exist or are in the wrong place
            alert_admin("Error: No shape files were found when trying to get shapes_list in jump.get_data")
        # I now have 2 Jump accounts to use for polling the server, so I can poll more often
        # if the minutes are odd, or even...
    
        if (local_datetime_now().minute % 2 == 0): #even 
            row = 0
        else: #odd
            row = 1
        
        username = app.config['JUMP_LOGIN'][row][0]
        password = app.config['JUMP_LOGIN'][row][1]
    
        url = 'https://app.socialbicycles.com/api/bikes.json?page=1&per_page={}&network_id={}'.format(size,network)
        request_data = requests.get(url,auth=(username,password)).json()
        if "error" in request_data or 'items' not in request_data: # {"error":"Not Authenticated","code":401}
            db.close()
            mes = """An error occured while attempting to import Jump Bike data.
                Time: {}
                Error: {}""".format(local_datetime_now().isoformat(),str(request_data))
            alert_admin(mes)
        
            return "Error received while accessing Jump Data: {}".format(str(request_data))
    
        observations = request_data['items']
        
        retrieval_dt = local_datetime_now()
        sightings = Sighting(db)
        bikes = Bike(db)
        trips = Trip(db)
        new_data = {'sighting':0, 'bike': 0, 'trip': 0, 'available': 0,}
        avail_city_data = {}
    
        for ob in observations:        
            lng = ob['lng'] = ob['current_position']['coordinates'][0]
            lat = ob['lat'] = ob['current_position']['coordinates'][1]
            ob['retrieved'] = retrieval_dt

            sql = 'jump_bike_id = {}'.format(ob['id'])
            bike = bikes.select_one(where=sql)
            new_data['available'] += 1
            
            city = get_city(shapes_list,lng,lat)
            if city in avail_city_data:
                avail_city_data[city] += 1
            else:
                avail_city_data[city] = 1
            
            if not bike:
                # A new bike...
                bike = bikes.new()
                bike.jump_bike_id = ob.get('id',None)
                bike.name = ob.get('name',None)
                bikes.save(bike)
                new_data['bike'] += 1
                sightings.save(new_sighting(sightings,ob,shapes_list))
                new_data['sighting'] += 1
                continue
            
            #Get the last time we saw this bike
            where = 'jump_bike_id = {}'.format(bike.jump_bike_id)
            order_by = 'id desc' # should be by datetime, but there are issues

            sight = sightings.select_one(where=where, order_by=order_by)
            if not sight:
                #This should really never happen...
                sightings.save(new_sighting(sightings,ob,shapes_list))
                new_data['sighting'] += 1
                continue
                
            if long_time_no_see(datetime.strptime(sight.retrieved,'%Y-%m-%d %H:%M:%S.%f')):
                #This bike has been off getting service
                sight = new_sighting(sightings,ob,shapes_list,returned_to_service=1)
                sightings.save(sight)
                #print('Returned to service: {}'.format(sight))
                new_data['sighting'] += 1
                continue
                
            # Seeing the bike again so how far has it moved
            distance = miles_traveled(lng, lat, sight.lng, sight.lat)
            if distance >= 0.128:
                #bike moved at least 1/8 mile
                origin_id = sight.id
                sight = new_sighting(sightings,ob,shapes_list)
                sightings.save(sight)
                #print('New Trip Sighting: {}'.format(sight))
                
                new_data['sighting'] += 1
                # Make a trip
                trip = new_trip(trips,bike.jump_bike_id,origin_id,sight.id,distance)
                trips.save(trip)
                #print('New Trip : {}'.format(sight))
                new_data['trip'] += 1
                
            else:
                #too short a move, Just update the sighting record
                sightings.save(update_sighting(ob,sight))
                
        #end ob loop
        
        # record the number of available bikes
        if new_data['available'] > 0:
            for city in avail_city_data.keys():
                avail = AvailableBikeCount(db).new()
                avail.bikes_available = avail_city_data[city]
                avail.city = city
                avail.retrieved = retrieval_dt
                avail.day_number = day_number()
                AvailableBikeCount(db).save(avail)
        
        db.commit()
        mes = 'At {}; New Data added: Available: {}, Sightings: {}, Bikes: {}, Trips: {}'.format(local_datetime_now().isoformat(),new_data['available'],new_data['sighting'],new_data['bike'],new_data['trip'])
        
        return(mes)
    
    except Exception as e:
        try:
            if db:
                db.rollback()
        except Exception as e:
            mes = """Could not connect to db while attempting to import Jump Bike data.
                    Error: {}
                    """.format(str(e))
            mes = printException(mes,"error",e)
            alert_admin(mes)
            return mes
            
            
        mes = """An error occured while attempting to import Jump Bike data.
                Error: {}
                """.format(str(e))
        mes = printException(mes,"error",e)
                
        alert_admin(mes)
        return mes
Exemple #8
0
def contact():
    setExits()
    g.title = 'Contact Us'
    from app import app
    from takeabeltof.mailer import send_message
    rendered_html = render_markdown_for('contact.md', mod)

    show_form = True
    context = {}
    success = True
    passed_quiz = False
    mes = "No errors yet..."
    if request.form:
        #import pdb;pdb.set_trace()
        quiz_answer = request.form.get('quiz_answer', "A")
        if quiz_answer.upper() == "C":
            passed_quiz = True
        else:
            flash("You did not answer the quiz correctly.")
        if request.form['email'] and request.form['comment'] and passed_quiz:
            context.update({'date': datetime_as_string()})
            for key, value in request.form.items():
                context.update({key: value})

            # get best contact email
            to = []
            # See if the contact info is in Prefs
            try:
                from users.views.pref import get_contact_email
                contact_to = get_contact_email()
                if contact_to:
                    to.append(contact_to)
            except Exception as e:
                printException(
                    "Need to update home.contact to find contacts in prefs.",
                    "error", e)

            try:
                admin_to = None
                if not to:
                    to = [
                        (
                            app.config['CONTACT_NAME'],
                            app.config['CONTACT_EMAIL_ADDR'],
                        ),
                    ]
                if app.config['CC_ADMIN_ON_CONTACT']:
                    admin_to = (
                        app.config['MAIL_DEFAULT_SENDER'],
                        app.config['MAIL_DEFAULT_ADDR'],
                    )

                if admin_to:
                    to.append(admin_to, )

            except KeyError as e:
                mes = "Could not get email addresses."
                mes = printException(mes, "error", e)
                if to:
                    #we have at least a to address, so continue
                    pass
                else:
                    success = False

            if success:
                # Ok so far... Try to send
                success, mes = send_message(
                    to,
                    subject="Contact from {}".format(app.config['SITE_NAME']),
                    html_template="home/email/contact_email.html",
                    context=context,
                    reply_to=request.form['email'],
                )

            show_form = False
        else:
            context = request.form
            flash('You left some stuff out.')

    if success:
        return render_template('contact.html',
                               rendered_html=rendered_html,
                               show_form=show_form,
                               context=context,
                               passed_quiz=passed_quiz)

    handle_request_error(mes, request, 500)
    flash(mes)
    return render_template('500.html'), 500
Exemple #9
0
def get_gbfs_data():
    try:

        #import pdb;pdb.set_trace()

        mes = 'No message Yet...'
        raw_data = "No data fetched yet"  #just a place-holder for now
        db = g.db

        shapes_list = get_shape_list()
        if not shapes_list:
            # most likely the json files don't exist or are in the wrong place
            alert_admin(
                "Error: No shape files were found when trying to get shapes_list in jump.get_data"
            )

        # Get free bike status feed url
        url = get_free_bike_url()
        if not url:
            mes = """No Free bike status URL while attempting to import Jump Bike data for {}.
                Time: {}
                URL: {}""".format(app.config['JUMP_NETWORK_NAME'],
                                  local_datetime_now().isoformat(), str(url))
            alert_admin(mes)

        raw_data = requests.get(url).text
        if "error" in raw_data or '"bikes":' not in raw_data:  # Not sure what an error looks like
            mes = """An error occured while attempting to import Jump Bike data from {}.
                Time: {}
                Error: {}""".format(url,
                                    local_datetime_now().isoformat(), raw_data)
            alert_admin(mes)

            return mes

        #convert data from json
        try:
            request_data = json.loads(raw_data)
        except:
            # alert on conversion error
            mes = """An error occured while attempting to convert json data in "get_gbfs_data()".
                Time: {}
                Error: {}""".format(local_datetime_now().isoformat(), raw_data)
            alert_admin(mes)

            return mes

        #Are there any bikes?
        if not request_data['data']['bikes']:
            mes = """No bikes were retrievd in "get_gbfs_data()" step 2.
                Time: {}
                Error: {}""".format(local_datetime_now().isoformat(),
                                    str(request_data))
            alert_admin(mes)

            return mes3

        #got data!
        observations = request_data['data']['bikes']

        retrieval_dt = local_datetime_now()
        sightings = Sighting(db)
        bikes = Bike(db)
        trips = Trip(db)
        new_data = {
            'sighting': 0,
            'bike': 0,
            'trip': 0,
            'available': 0,
        }
        avail_city_data = {}

        # Temporary to only send email once per retireval
        found_a_different_vehicle = ''

        for ob in observations:
            # Jump added a new property for vehicle type. We are only interested in bikes
            if ob.get("jump_vehicle_type", "bike") != "bike":
                # Alert me when we see a vehicle type I don't recognize
                temp_veh = ob.get("jump_vehicle_type", "None")
                if found_a_different_vehicle != temp_veh:
                    found_a_different_vehicle = temp_veh
                    mes = """Received response with vehicle type of '{}'. Time: {}
Data: 
{}
""".format(temp_veh,
                    local_datetime_now().isoformat(), ob)
                    alert_admin(mes)

            lng = ob['lon']
            lat = ob['lat']
            ob['retrieved'] = retrieval_dt

            # the bike_id for jump is prepended with 'bike_' so we need to strip that off
            bike_id = ob.get('bike_id', None)
            if not bike_id:
                mes = """bike_id not in data.
                    Time: {}""".format(local_datetime_now().isoformat(), )
                alert_admin(mes)
                continue

            pos = ob['bike_id'].find('_')
            if pos > 0:
                ob['bike_id'] = ob['bike_id'][pos + 1:]

            # jump has a custom field 'jump_ebike_battery_level' with a '%' sign. Drop the sign
            batt_pct = ob.get('jump_ebike_battery_level', None)
            if batt_pct:
                pos = batt_pct.find("%")
                if pos > 0:
                    ob['jump_ebike_battery_level'] = batt_pct[:pos]

            sql = 'jump_bike_id = {}'.format(ob['bike_id'])
            bike = bikes.select_one(where=sql)
            new_data['available'] += 1

            city = get_city(lng, lat, shapes_list)
            if city in avail_city_data:
                avail_city_data[city] += 1
            else:
                avail_city_data[city] = 1

            if not bike:
                # A new bike...
                bike = bikes.new()
                bike.jump_bike_id = ob['bike_id']
                bike.name = ob.get('name', None)
                bike.vehicle_type = ob.get("jump_vehicle_type", None)
                bikes.save(bike)
                new_data['bike'] += 1
                sightings.save(new_sighting(sightings, ob, shapes_list))
                new_data['sighting'] += 1

                # no need to look for previous sightings
                continue

            #Get the last time we saw this bike
            where = 'jump_bike_id = {}'.format(bike.jump_bike_id)
            order_by = 'id desc'  # should be by datetime, but there are issues

            sight = sightings.select_one(where=where, order_by=order_by)
            if not sight:
                #This should really never happen...
                sightings.save(new_sighting(sightings, ob, shapes_list))
                new_data['sighting'] += 1
                continue

            #import pdb;pdb.set_trace()
            # sight.retrieved is a string so try to convert it to a datetime
            # Because some dates were stored as time zone aware and some not, just truncat it to seconds
            prev_sighting_date = datetime.strptime(sight.retrieved[:19],
                                                   '%Y-%m-%d %H:%M:%S')

            if long_time_no_see(make_tz_aware(prev_sighting_date)):
                #This bike has been off getting service
                sight = new_sighting(sightings,
                                     ob,
                                     shapes_list,
                                     returned_to_service=1)
                sightings.save(sight)
                #print('Returned to service: {}'.format(sight))
                new_data['sighting'] += 1
                continue

            # Seeing the bike again so how far has it moved
            distance = miles_traveled(lng, lat, sight.lng, sight.lat)
            if distance >= 0.128:
                #import pdb;pdb.set_trace()
                #bike moved at least 1/8 mile
                origin_id = sight.id
                sight = new_sighting(sightings, ob, shapes_list)
                sightings.save(sight)
                #print('New Trip Sighting: {}'.format(sight))

                new_data['sighting'] += 1
                # Make a trip
                trip = new_trip(trips, bike.jump_bike_id, origin_id, sight.id,
                                distance)
                trips.save(trip)
                #print('New Trip : {}'.format(sight))
                new_data['trip'] += 1

            else:
                #too short a move, Just update the sighting record
                sightings.save(update_sighting(ob, sight))

        #end ob loop

        # record the number of available bikes
        if new_data['available'] > 0:
            for city in avail_city_data.keys():
                avail = AvailableBikeCount(db).new()
                avail.bikes_available = avail_city_data[city]
                avail.city = city
                avail.retrieved = retrieval_dt
                avail.day_number = day_number()
                AvailableBikeCount(db).save(avail)

        db.commit()
        mes = 'At {}; New Data added: Available: {}, Sightings: {}, Bikes: {}, Trips: {}'.format(
            local_datetime_now().isoformat(), new_data['available'],
            new_data['sighting'], new_data['bike'], new_data['trip'])

        # Update the home page cache with the new data
        render_home_page_to_cache(force=True)

        return (mes)

    except Exception as e:
        try:
            mes_data_response = raw_data
        except:
            mes_data_response = "No Data Retrieved"

        mes = """An un-caught error occured while attempting to fetch bike data.
                Error: {}
                
                Data Retrived: {}
                """.format(str(e), mes_data_response)
        mes = printException(mes, "error", e)
        alert_admin(mes)
        return mes
Exemple #10
0
def send_message(to_address_list=None, **kwargs):
    """Send an email with the parameters as:
        to_address_list=[list of tuples (recipient name,recipient address)]=None
        
        If the to_address_list is not provided, mail will be sent to the admin
        
        -- all templates must use 'context' as their only context variable
        **kwargs:
            context = {a dictionary like object with data for rendering all emails} = {}
            body = <text for body of email> = None
            body_text_is_html = <True | False> = False
            text_template=<template to render as plain text message> = None
            html_template=<template to render as html message> = None
            subject=<subject text (will be rendered with the current context>)>= a default subject
            subject_prefix=<some text to prepend to the subject: = ''
            from_address=<from address> = app.config['MAIL_DEFAULT_ADDR']
            from_sender=<name of sender> = app.config['MAIL_DEFAULT_SENDER']
            reply_to_address=<replyto address> = from_address
            reply_to_name=<name of reply to account> = from_sender
            
        On completion returns a tuple of:
            success [True or False]
            message "some message"
    """
    #import pdb;pdb.set_trace()

    app_config = get_app_config(
    )  #update the settings. this also recreates the mail var in app with new settings

    context = kwargs.get('context', {})
    body = kwargs.get('body', None)
    body_is_html = kwargs.get('body_is_html', None)
    text_template = kwargs.get('text_template', None)
    html_template = kwargs.get('html_template', None)
    subject_prefix = kwargs.get('subject_prefix', '')

    try:
        admin_addr = app_config['MAIL_DEFAULT_ADDR']
        admin_name = app_config['MAIL_DEFAULT_SENDER']
    except KeyError as e:
        mes = "MAIL Settings not found"
        mes = printException(mes, 'error', e)
        return (False, mes)

    from_address = kwargs.get('from_address', admin_addr)
    from_sender = kwargs.get('from_sender', admin_name)
    reply_to = kwargs.get('reply_to', from_address)

    subject = subject_prefix + ' ' + kwargs.get(
        'subject', 'A message from {}'.format(from_sender))

    if not text_template and not html_template and not body:
        mes = "No message body was specified"
        printException(mes, "error")
        return (False, mes)

    if not to_address_list or len(to_address_list) == 0:
        #no valid address, so send it to the admin
        to_address_list = [
            (admin_name, admin_addr),
        ]

    with mail.record_messages() as outbox:
        sent_cnt = 0
        err_cnt = 0
        err_list = []
        result = True
        for who in to_address_list:
            #import pdb;pdb.set_trace()
            name = ""
            address = ""
            body_err_head = ""
            if type(who) is tuple:
                if len(who) == 1:
                    # extend whp
                    who = who[0] + (who[0], )
                name = who[0]
                address = who[1]
            else:
                address = who  #assume its a str
                name = who

            if not looksLikeEmailAddress(address) and looksLikeEmailAddress(
                    name):
                # swap values
                temp = address
                address = name
                name = temp
            if not looksLikeEmailAddress(address):
                # still not a good address...
                address = admin_addr
                name = admin_name
                if not body:
                    body = ""

                body_err_head = "Bad Addres: {}\r\r".format(who, )

            subject = render_template_string(subject.strip(), context=context)
            #Start a message
            msg = Message(subject,
                          sender=(from_sender, from_address),
                          recipients=[(name, address)])

            #Get the text body verson
            if body:
                if body_is_html:
                    msg.html = render_template_string("{}{}".format(
                        body_err_head,
                        body,
                    ),
                                                      context=context)
                else:
                    msg.body = render_template_string("{}{}".format(
                        body_err_head,
                        body,
                    ),
                                                      context=context)
            if html_template:
                msg.html = render_template(html_template, context=context)
            if text_template:
                msg.body = render_template(text_template, context=context)

            msg.reply_to = reply_to

            try:
                mail.send(msg)
                sent_cnt += 1
            except Exception as e:
                mes = "Error Sending email"
                printException(mes, "error", e)
                err_cnt += 1
                err_list.append("Error sending message to {} err: {}".format(
                    who, str(e)))

        # End Loop
        if sent_cnt == 0:
            mes = "No messages were sent."
            result = False
        else:
            mes = "{} messages sent successfully.".format(sent_cnt)
        if err_cnt > 0:
            mes = mes + " {} messages had errors.\r\r{}".format(
                err_cnt, err_list)

        return (result, mes)