|
@@ -50,6 +50,14 @@ class Target(db.Model):
|
|
|
return str(self.get_ip())
|
|
|
|
|
|
|
|
|
+# Many-to-many table to record which target has been given to which
|
|
|
+# participant.
|
|
|
+handled_targets = db.Table('handled_targets',
|
|
|
+ db.Column('target_id', db.Integer, db.ForeignKey('target.id')),
|
|
|
+ db.Column('participant_id', db.Integer, db.ForeignKey('participant.id'))
|
|
|
+)
|
|
|
+
|
|
|
+
|
|
|
class Participant(db.Model):
|
|
|
"""Participant in the ping network"""
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
@@ -61,6 +69,11 @@ class Participant(db.Model):
|
|
|
contact = db.Column(db.String)
|
|
|
# Whether we accept this participant or not
|
|
|
active = db.Column(db.Boolean)
|
|
|
+ # Many-to-many relationship
|
|
|
+ targets = db.relationship('Target',
|
|
|
+ secondary=handled_targets,
|
|
|
+ backref=db.backref('participants', lazy='dynamic'),
|
|
|
+ lazy='dynamic')
|
|
|
|
|
|
def __init__(self, name, contact):
|
|
|
self.uuid = str(uuid4())
|
|
@@ -78,19 +91,18 @@ class Result(db.Model):
|
|
|
target_id = db.Column(db.Integer, db.ForeignKey('target.id'))
|
|
|
target = db.relationship('Target',
|
|
|
backref=db.backref('results', lazy='dynamic'))
|
|
|
- # Participant
|
|
|
- source_id = db.Column(db.Integer, db.ForeignKey('participant.id'))
|
|
|
- source = db.relationship('Participant',
|
|
|
- backref=db.backref('results', lazy='dynamic'))
|
|
|
+ participant_id = db.Column(db.Integer, db.ForeignKey('participant.id'))
|
|
|
+ participant = db.relationship('Participant',
|
|
|
+ backref=db.backref('results', lazy='dynamic'))
|
|
|
# In milliseconds
|
|
|
rtt = db.Column(db.Float)
|
|
|
|
|
|
- def __init__(self, target_id, source_uuid, rtt):
|
|
|
+ def __init__(self, target_id, participant_uuid, rtt):
|
|
|
target = Target.query.get_or_404(int(target_id))
|
|
|
- source = Participant.query.filter_by(uuid=source_uuid,
|
|
|
- active=True).first_or_404()
|
|
|
+ participant = Participant.query.filter_by(uuid=participant_uuid,
|
|
|
+ active=True).first_or_404()
|
|
|
self.target = target
|
|
|
- self.source = source
|
|
|
+ self.participant = participant
|
|
|
self.rtt = float(rtt)
|
|
|
|
|
|
|
|
@@ -122,32 +134,34 @@ def create_participant():
|
|
|
else:
|
|
|
return "Invalid arguments"
|
|
|
|
|
|
-@app.route('/targets/all')
|
|
|
-def get_jobs():
|
|
|
- """"List of targets to ping"""
|
|
|
- targets = Target.query.order_by('-id').all()
|
|
|
- return "\n".join("{} {}".format(t.id, t) for t in targets)
|
|
|
-
|
|
|
-@app.route('/targets/ipv4')
|
|
|
-def get_v4jobs():
|
|
|
- """"List of IPv4 targets to ping"""
|
|
|
- targets = Target.query.order_by('-id').all()
|
|
|
- return "\n".join("{} {}".format(t.id, t) for t in targets if t.is_v4())
|
|
|
-
|
|
|
-@app.route('/targets/ipv6')
|
|
|
-def get_v6jobs():
|
|
|
- """"List of IPv6 targets to ping"""
|
|
|
- targets = Target.query.order_by('-id').all()
|
|
|
- return "\n".join("{} {}".format(t.id, t) for t in targets if t.is_v6())
|
|
|
-
|
|
|
-@app.route('/result/report', methods=['POST'])
|
|
|
-def report_result():
|
|
|
- if {'rtt', 'target', 'source'}.issubset(request.form):
|
|
|
- target = request.form['target']
|
|
|
+@app.route('/target/<uuid>')
|
|
|
+def get_next_target(uuid):
|
|
|
+ """"Returns the next target to ping for the given participant"""
|
|
|
+ participant = Participant.query.filter_by(uuid=uuid, active=True).first_or_404()
|
|
|
+ # We want to get all targets that do not have a relationship with the
|
|
|
+ # given participant. Note that the following lines manipulate SQL
|
|
|
+ # queries, which are only executed at the very end.
|
|
|
+ # This gives all targets that have already been sent to the given
|
|
|
+ # participant.
|
|
|
+ already_done = Target.query.join(handled_targets).filter_by(participant_id=participant.id).with_entities(Target.id)
|
|
|
+ # This takes the negation of the previous set.
|
|
|
+ todo = Target.query.filter(~Target.id.in_(already_done))
|
|
|
+ target = todo.first()
|
|
|
+ if target is not None:
|
|
|
+ return "{} {}".format(target.id, target)
|
|
|
+ else:
|
|
|
+ return ""
|
|
|
+
|
|
|
+@app.route('/result/report/<uuid>', methods=['POST'])
|
|
|
+def report_result(uuid):
|
|
|
+ if {'rtt', 'target'}.issubset(request.form):
|
|
|
+ target_id = request.form['target']
|
|
|
rtt = request.form['rtt']
|
|
|
- source_uuid = request.form['source']
|
|
|
- result = Result(target, source_uuid, rtt)
|
|
|
+ result = Result(target_id, uuid, rtt)
|
|
|
db.session.add(result)
|
|
|
+ # Record that the participant has returned a result
|
|
|
+ participant = result.participant
|
|
|
+ participant.targets.append(result.target)
|
|
|
db.session.commit()
|
|
|
return "OK\n"
|
|
|
else:
|