Skip to content

Commit

Permalink
backend: give the public some basic info about entries; plus campaign…
Browse files Browse the repository at this point in the history
… specific audit logs for coordinators
  • Loading branch information
slaporte committed Sep 5, 2017
1 parent c90f672 commit 7529161
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 11 deletions.
8 changes: 8 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ A bit of space for dev bookkeeping.
* Load dates (?)
* create round from previous round

... [stephen on the train]

* Endpoint to view reviews
* Handle NONE user in UserDAO
* check entry existance before getting from db or remote source
* what should happen when someone closes a round with open votes?
*

## Frontend

* Make URLs configurable for different backend paths (e.g., Labs versus localhost)
Expand Down
8 changes: 8 additions & 0 deletions montage/admin_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def get_admin_routes():
POST('/admin/campaign/<campaign_id:int>/unpublish', unpublish_report),
GET('/admin/campaign/<campaign_id:int>/report', get_campaign_report,
'report.html'),
GET('/admin/campaign/<campaign_id:int>/audit', get_campaign_log),
POST('/admin/round/<round_id:int>/import', import_entries),
POST('/admin/round/<round_id:int>/activate', activate_round),
POST('/admin/round/<round_id:int>/pause', pause_round),
Expand Down Expand Up @@ -255,6 +256,13 @@ def get_campaign_report(user_dao, campaign_id):
return ctx


def get_campaign_log(user_dao, campaign_id):
coord_dao = CoordinatorDAO.from_campaign(user_dao, campaign_id)
audit_logs = coord_dao.get_audit_log() # TODO: should this paginate?
ret = [a.to_info_dict() for a in audit_logs]
return {'data': ret}


def import_entries(user_dao, round_id, request_dict):
"""
Summary: Load entries into a new round identified by a round ID.
Expand Down
7 changes: 7 additions & 0 deletions montage/public_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def get_public_routes():
('/complete_login', complete_login),
('/series/<series_id?int>', get_series),
('/series', get_series),
('/entry/<entry_name:str>', get_entry_info),
('/campaign/<campaign_id:int>', get_report,
'report.html'),
('/campaign', get_all_reports),
Expand Down Expand Up @@ -205,6 +206,12 @@ def get_series(rdb_session, series_id=None):
series = dao.get_all_series()
return {'data': [s.to_details_dict() for s in series]}

@public
def get_entry_info(rdb_session, entry_name):
dao = PublicDAO(rdb_session)
ret = dao.get_public_entry_info(entry_name)
return {'data': ret}


@public
def get_report(rdb_session, campaign_id):
Expand Down
65 changes: 56 additions & 9 deletions montage/rdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ class Campaign(Base):

rounds = relationship('Round', back_populates='campaign')
series = relationship('Series')
results_summary = relationship('RoundResultsSummary')
campaign_coords = relationship('CampaignCoord',
cascade="save-update, merge, delete, delete-orphan")
coords = association_proxy('campaign_coords', 'user',
Expand Down Expand Up @@ -726,7 +727,7 @@ class RoundResultsSummary(Base):
round_id = Column(Integer, ForeignKey('rounds.id'), index=True)
round = relationship('Round')
campaign_id = Column(Integer, ForeignKey('campaigns.id'), index=True)
campaign = relationship('Campaign')
campaign = relationship('Campaign', back_populates='results_summary')

summary = Column(JSONEncodedDict)
status = Column(String(255), index=True) # private, public
Expand Down Expand Up @@ -809,6 +810,48 @@ def get_all_reports(self):
.all())
return reports

def _get_entry_by_name(self, entry_name):
entry = (self.query(Entry)
.filter_by(name=entry_name)
.one_or_none())
if not entry:
raise DoesNotExist('no entry named %s' % entry_name)
return entry

def get_public_entry_info(self, entry_name):
entry = self._get_entry_by_name(entry_name)
ret = entry.to_details_dict()
ret['campaigns'] = []
round_entries = entry.entered_rounds
for round_entry in round_entries:
campaign_id = round_entry.round.campaign.id,
disqualified = False
results_published = False
if campaign_id in [c['campaign_id'] for c in ret['campaigns']]:
# Only need the first round in a campaign
continue
if round_entry.dq_reason:
disqualified = True # Should montage let people see
# if their photo was dq'ed?
summary = round_entry.round.campaign.results_summary
if summary:
summary = summary[0]
results_published = True # If it's published, you can
# visit the campaign report
# to see the results
'''
# TODO: show the ranking, if it's a winner?
winners = [(e['entry']['name'],
e['ranking']) for e in results['winners']]
'''
re_info = {'campaign_id': campaign_id,
'campaign_name': round_entry.round.campaign.name,
'campaign_status': round_entry.round.campaign.status,
'campaign_results_published': results_published,
'disqualified': disqualified,
'source': round_entry.round_source.params}
ret['campaigns'].append(re_info)
return ret

class UserDAO(PublicDAO):
"""The Data Acccess Object wraps the rdb_session and active user
Expand Down Expand Up @@ -1553,13 +1596,11 @@ def finalize_ranking_round(self, round_id):
rnd = self.get_round(round_id)
assert rnd.vote_method == 'ranking'

# TODO: Ranking method?

rnd.close_date = datetime.datetime.utcnow()
rnd.status = FINALIZED_STATUS
# rnd.config['ranking_method'] = method

summary = self.build_campaign_report(rnd.campaign)
summary = self.build_campaign_report()

result_summary = RoundResultsSummary(round_id=round_id,
campaign_id=rnd.campaign.id,
Expand Down Expand Up @@ -1592,6 +1633,13 @@ def get_campaign_report(self):
.one_or_none()
return summary

def get_audit_log(self):
audit_logs = (self.query(AuditLogEntry)
.filter_by(campaign_id=self.campaign.id)
.order_by(AuditLogEntry.create_date.asc())
.all())
return audit_logs

def get_rating_advancing_group(self, round_id, threshold=None):
#assert rnd.vote_method in ('rating', 'yesno')

Expand Down Expand Up @@ -1781,7 +1829,6 @@ def modify_quorum(self, round_id, new_quorum, strategy=None):
# quorum would require handling some completed tasks (eg,
# whose vote do you discard? Randomly choose?)

# TODO: Support decreasing the quorum.
rnd = self.get_round(round_id)

old_quorum = rnd.quorum
Expand Down Expand Up @@ -1847,17 +1894,17 @@ def create_ranking_round(self, campaign, name, jurors, deadline_date):
source = 'round(#%s)' % prev_finalized_rnd.id
self.add_round_entries(rnd, advancing_group, source=source)

def build_campaign_report(self, campaign):
# TODO: must be a coordinator on the campaign
# TODO: assert campaign is finalized
def build_campaign_report(self):
campaign = self.campaign
# assert campaign.status is FINALIZED_STATUS

ret = {}
start_time = time.time()

ret["campaign"] = campaign.to_info_dict()

ret["rounds"] = [r.to_details_dict() for r in campaign.rounds
if r.status != CANCELLED_STATUS] # TODO: switch to == FINALIZED_STATUS
if r.status == FINALIZED_STATUS]

ret["coordinators"] = [cc.user.to_info_dict() for cc in
campaign.campaign_coords]
Expand Down
13 changes: 11 additions & 2 deletions run_server_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,12 @@ def full_run(url_base, remote):
'/admin/round/%s/import' % round_id,
data, as_user='LilyOfTheWest')

data = {'import_method': 'category',
'category': 'Images_from_Wiki_Loves_Monuments_2015_in_Albania'}
resp = fetch('coordinator: import entries from a category',
'/admin/round/%s/import' % round_id,
data, as_user='LilyOfTheWest')


resp = fetch('coordinator: activate a round',
'/admin/round/%s/activate' % round_id,
Expand Down Expand Up @@ -694,10 +700,13 @@ def full_run(url_base, remote):
'/admin/campaign/%s/publish' % campaign_id,
{'post': True}, as_user='LilyOfTheWest')


pprint(resp['data'])

print cookies
resp = fetch('coordinator: see the audit log with full campaign history',
'/admin/campaign/%s/audit' % campaign_id,
as_user='LilyOfTheWest')

pprint(resp['data'])
import pdb;pdb.set_trace()


Expand Down

0 comments on commit 7529161

Please sign in to comment.