Esempio n. 1
0
def _final_validation_and_upload(result_page):
    logger = logging.getLogger("uploadprocessing")
    
    # Process each race and load it into the DB.             
    for race in result_page.parsed_races:
        # Set the new trackname on each of the race objects.
        race.trackName = result_page.upload_record.trackname.trackname
        
        try:
            new_singleracedetails = process_singlerace(race)
            # We are going to track who uploaded this race.
            EasyUploadedRaces.objects.create(upload=result_page.upload_record, racedetails=new_singleracedetails)
            result_page.uploaded_race_list.append((race.raceClass, new_singleracedetails.id))
            result_page.uploaded_raceid_list.append(new_singleracedetails.id)
        except FileAlreadyUploadedError:
            # result_page.upload_record.filename
            logger.error("This race has already been uploaded, filename=" + result_page.upload_record.filename + " raceobject:" + str(race))        
            result_page.upload_record.errorenum = 6
            result_page.upload_record.save()             
        except Exception as e:
            exc_type, exc_value, exc_traceback = sys.exc_info()
            trace = traceback.format_exception(exc_type, exc_value, exc_traceback)
            logger.error("Unable to process file: {0} exception:{1} \n {2}".format(result_page.upload_record.filename, str(e), trace))
            result_page.upload_record.errorenum = 7
            result_page.upload_record.save()
             
    
    # TODO - push out and run in Celery so we wont wait forever here.
    #
    #_update_ranking(track, uploaded_raceid_list)        
                
    # Log this upload as processed (we do NOT want to support
    # multiple attempts at uploading the file).
    result_page.upload_record.processed = True
    utcnow = datetime.datetime.utcnow()
    utcnow = utcnow.replace(tzinfo=pytz.utc)
    result_page.upload_record.uploadfinish = utcnow  
    result_page.upload_record.save()
Esempio n. 2
0
def upload_validate(request, upload_id):
    """    
    We want to provide a form for the user to change the trackname before
    it is processed and placed in the database.
    
    A large chunk of this code is error handling and file checking
    to make sure the results were parsed correctly (and hopefully
    give enough information for me to fix the problem later or to
    let them make the change and retry the upload).
    
    Overview of the code:
        We get the record of the upload from the DB
        We then get the singlerace objects (parse each item in the file).
        Display these objects to user.
        
        
    """
    upload_record = get_object_or_404(UploadRecord, pk=upload_id)

    # We have already recorded this file as processed, there is nothing more
    # this script can do at this point. It is likely a user error.
    # I only think this will occur if you try to reload the results processing page.
    if (upload_record.processed):
        state = "File has already been processed. If you believe there was an ERROR, than instead " +\
            "of trying to re-upload the race you should contact an administrator for help."
        return render_to_response('easyupload/upload_validate.html',
                                  {'state':state,},
                                  context_instance=RequestContext(request))
    
    # ***************************************************************
    # Error checking, we will parse the file from memory and log/communicate
    # the problems as best as possible. 
    # LOTS OF VALIDATION PRIOR TO MOVING TO THE NEXT STEP.
    # ***************************************************************
    
    logger = logging.getLogger("uploadprocessing")
    # Get the uploaded file name from the database.
    filename = os.path.join(settings.MEDIA_USER_UPLOAD, upload_record.filename)

    # General Error message in case processing of the file fails for any reason.    
    state = "We were unable to process the file you uploaded. Please double " +\
            "check that the file is in the supported format. If you still believe " +\
            "there is an error, please contact the admin."            
    
    try:
        prevalidation_race_list = _parse_file(filename)
    except IOError:
        logger.error("Invalid filename=" + filename)        
        return render_to_response('easyupload/upload_validate.html',
                                  {'state':state,},
                                  context_instance=RequestContext(request))         
    except Exception as e:
        exc_type, exc_value, exc_traceback = sys.exc_info()
        trace = traceback.format_exception(exc_type, exc_value, exc_traceback)
        logger.error("Unable to process file: {0} exception:{1} \n {2}".format(filename, str(e), trace))
        return render_to_response('easyupload/upload_validate.html',
                                  {'state':state,},
                                  context_instance=RequestContext(request)) 
        
    # Now that we have a possible set of race result, we are most concerned with
    # making sure they have a valid track name prior to upload. If they have bad
    # class names or other garbage data, it will not be as big a deal.
    
    # There must be at least 1 race.
    if (len(prevalidation_race_list) < 1):
        logger.error("No races found in the file=" + filename)        
        return render_to_response('easyupload/upload_validate.html',
                                  {'state':state,},
                                  context_instance=RequestContext(request)) 
    
    upload_trackname = prevalidation_race_list[0].trackName
    
    # We are going to force them to have a trackname already set. 
    #     It makes this code so much simpler, if they need to change 
    #     the trackname (then I can easily replace it and save the 
    #     modified version).
    if (upload_trackname.strip() == ""):
        state = "You MUST have a trackname set in the race results to proceed."
        logger.error("There was no trackname set in the file=" + filename)        
        return render_to_response('easyupload/upload_validate.html',
                                  {'state':state,},
                                  context_instance=RequestContext(request)) 
    
    # Validate all the track names are the same. 
    #     I don't think this would ever happen but I am going 
    #     to check because I don't want people doing it.    
    for race in prevalidation_race_list:
        if (race.trackName != upload_trackname):
            logger.error("Not all races have the same trackname in the file=" + filename)        
            return render_to_response('easyupload/upload_validate.html',
                                      {'state':state,},
                                      context_instance=RequestContext(request)) 


    # ***************************************************************
    # Basic Validation Complete, we have been able to at least parse
    # the upladed file and if NOT, we have returned and communicated/logged
    # the problem.
    # ***************************************************************
    if request.method == 'POST':
        form = TrackNameForm(request.POST)  
        if (form.is_valid()):
            # Note - They have clicked on the submit button and have set a desired trackname
            # We want to process and upload the file.
            cd = form.cleaned_data
            track = get_object_or_404(TrackName, pk=cd['track_id'])
            
            # Now we know the trackname that the file should be using.
            # We want to save this information from the user to a new file.
            #     This is to hopefully simplify restoring data in the event of
            #     an emergency (all that would be needed would be these text files).
            _modify_trackname(upload_record.filename, upload_trackname, track.trackname)
            
            uploaded_races_list = [] # This is to display to the user.
            uploaded_raceid_list = [] # This is for ranking
            
            # Process each race and load it into the DB.             
            for race in prevalidation_race_list:
                # Set the new trackname on each of the race objects.
                race.trackName = track.trackname
                        
                try:
                    new_singleracedetails = process_singlerace(race)
                    # We are going to track who uploaded this race.
                    UploadedRaces.objects.create(upload=upload_record, racedetails=new_singleracedetails)
                    uploaded_races_list.append((race.raceClass, new_singleracedetails.id))
                    uploaded_raceid_list.append(new_singleracedetails.id)
                except FileAlreadyUploadedError:
                    logger.error("This race has already been uploaded, filename=" + filename + " raceobject:" + str(race))        
                    return render_to_response('easyupload/upload_validate.html',
                                              {'state':"This race has ALREADY been uploaded. " + state,},
                                              context_instance=RequestContext(request)) 
                except Exception as e:
                    exc_type, exc_value, exc_traceback = sys.exc_info()
                    trace = traceback.format_exception(exc_type, exc_value, exc_traceback)
                    logger.error("Unable to process file: {0} exception:{1} \n {2}".format(filename, str(e), trace))
                    return render_to_response('easyupload/upload_validate.html',
                                              {'state':state,},
                                              context_instance=RequestContext(request)) 
            
            _update_ranking(track, uploaded_raceid_list)        
                        
            # Log this upload as processed (we do NOT want to support
            # multiple attempts at uploading the file).
            upload_record.processed = True
            upload_record.save()
            
            return render_to_response('easyupload/upload_complete.html',
                                      {'uploaded_races_list':uploaded_races_list},
                                      context_instance=RequestContext(request))
    
            
            
        else:
            logger.error("Invalid form, file=" + filename + " form.error:" + str(form.errors))        
            return render_to_response('easyupload/upload_validate.html',
                                      {'state':"Invalid option selected.",},
                                      context_instance=RequestContext(request))
    
    # We are always going to require that the select a trackname, at least for now.
    # I can see this behavior changing the future to streamline the process.
    form = TrackNameForm()
                   
    return render_to_response('easyupload/upload_validate.html',
                              {'form':form,
                               'uploadtrackname': upload_trackname,
                               'prevalidation_race_list':prevalidation_race_list,},
                              context_instance=RequestContext(request))