def add_gc_job(_id): # Check auth if not current_user.is_admin(): flash("Only admins can add new GC jobs.", "danger") return redirect(request.referrer or url_for("index")) # Check replay exists _replay = Replay.query.filter(Replay.id == _id).first() if _replay is None: flash("Replay {} doesn't exist.".format(_id), "danger") return redirect(request.referrer or url_for("index")) # Update status _replay.status = "WAITING_GC" _replay.gc_fails = 0 db.session.add(_replay) # Add to job queue. queued = Replay.add_gc_job(_replay) if queued: flash("Added GC job for replay {}.".format(_id), "info") db.session.commit() else: flash("Error adding GC job for replay {}.".format(_id), "danger") db.session.rollback() return redirect(request.referrer or url_for("index"))
def search(): form = SearchForm() if form.validate_on_submit(): match_id = form.query.data error = False search_log = Search(current_user.get_id(), match_id, request.access_route[0]) # Trim whitespace chars match_id = match_id.strip() # Normalize input (in case of unicode variants of chars; can break at urllib.urlencode level later on without this) match_id = unicodedata.normalize('NFKC', match_id) # If not a decimal input, let's try pull match id from inputs we recognise if not unicode.isdecimal(match_id): # Pull out any numbers in the search query and interpret as a match id. search = re.search(r'([0-9]+)', match_id) if search is not None: match_id = search.group(1) if unicode.isdecimal(match_id): _replay = Replay.query.filter(Replay.id == match_id).first() # If we don't have match_id in database, check if it's a valid match via the WebAPI and if so add it to DB. if not _replay: try: # Only continue if the WebAPI doesn't throw an error for this match ID, and if the match ID for the # info returned matches the match_id we sent (Fixes edge-case bug that downed Dotabank once, where # a user searched 671752079671752079 and the WebAPI returned details for 368506255). match_data = steam.api.interface( "IDOTA2Match_570").GetMatchDetails( match_id=match_id).get("result") if "error" not in match_data.keys() and int( match_data.get("match_id")) == int(match_id): # Use get_or_create in case of race-hazard where another request (e.g. double submit) has already processed this replay while we were waiting for match_data. # DOESN'T FIX A FOOKIN THINGA _replay, created = Replay.get_or_create( id=match_id, skip_webapi=True) if created: _replay._populate_from_webapi(match_data) db.session.add(_replay) queued = Replay.add_gc_job(_replay, skip_commit=True) if queued: flash( "Replay {} was not in our database, so we've added it to the job queue to be parsed!" .format(match_id), "info") try: db.session.commit() except IntegrityError: db.session.rollback() pass # F*****g piece of shit. else: db.session.rollback() error = True except steam.api.HTTPError: error = True if _replay: search_log.replay_id = _replay.id search_log.success = True db.session.add(search_log) db.session.commit() return redirect(url_for("replays.replay", _id=match_id)) # We only get this far if there was an error or the matchid is invalid. if error: flash( "Replay {} was not on our database, and we encountered errors trying to add it. Please try again later." .format(match_id), "warning") else: flash( "Invalid match id. If this match id corresponds to a practice match it is also interpreted as invalid - Dotabank is unable to access practice lobby replays.", "danger") search_log.success = False db.session.add(search_log) db.session.commit() return redirect(request.referrer or url_for("index"))