Skip to content

Commit

Permalink
Remove institute / region / province / city
Browse files Browse the repository at this point in the history
Leave institute_id as a simple integer ID, to be used with an external database of institutes (fetched from olimanager). See olimpiadi-informatica/training-frontend#13
  • Loading branch information
wil93 committed Jan 28, 2025
1 parent 1129a75 commit 0a29910
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 182 deletions.
1 change: 0 additions & 1 deletion cmsocial/db/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from cmsocial.db.socialcontest import SocialContest
from cmsocial.db.lesson import Lesson, LessonTask
from cmsocial.db.test import Test, TestQuestion, QuestionFile, TestScore
from cmsocial.db.location import Region, Province, City, Institute
from cmsocial.db.material import Material
from sqlalchemy.orm import relationship
SocialUser.tasktags = relationship("TaskTag")
71 changes: 0 additions & 71 deletions cmsocial/db/location.py

This file was deleted.

30 changes: 5 additions & 25 deletions cmsocial/db/socialuser.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,15 @@



from datetime import timedelta, datetime
from datetime import datetime

from sqlalchemy.schema import Column, ForeignKey, CheckConstraint
from sqlalchemy.types import Boolean, Integer, String, Unicode, DateTime, \
Interval
from sqlalchemy.schema import Column, ForeignKey
from sqlalchemy.types import Integer, String, DateTime
from sqlalchemy.orm import relationship, backref

from cms.db import Contest, Participation, User
from cms.db import Participation, User

from cmsocial.db.base import Base
from cmsocial.db.location import Institute


class SocialUser(Base):
Expand Down Expand Up @@ -76,25 +74,7 @@ class SocialUser(Base):
# CUSTOM FIELDS:

# Institute
institute_id = Column(
Integer,
ForeignKey(
Institute.id,
onupdate="CASCADE",
ondelete="SET NULL"
),
nullable=True,
index=True
)

institute = relationship(
Institute,
backref=backref(
"users",
cascade="all, delete-orphan",
passive_deletes=True
)
)
institute_id = Column(Integer, nullable=True, index=True)

# List of tasktags (not "approved" yet) created by this user
# FIXME: the following causes a circular dependency
Expand Down
127 changes: 42 additions & 85 deletions cmsocial/server/pws.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@
from cmscommon.datetime import make_datetime, make_timestamp
from cmsocial.db.lesson import Lesson
from cmsocial.db.material import Material
from cmsocial.db.location import City, Institute, Province, Region
from cmsocial.db.socialcontest import SocialContest
from cmsocial.db.socialtask import SocialTask, Tag, TaskScore, TaskTag
from cmsocial.db.socialuser import SocialParticipation, SocialUser
Expand Down Expand Up @@ -419,38 +418,24 @@ def send_mail(self, to, subject, body):
server.quit()
return sent

def get_institute_info(self, institute_id):
info = dict()
if institute_id is not None:
institute = local.session.query(Institute)\
.filter(Institute.id == institute_id).first()
info['id'] = institute.id
info['name'] = institute.name
info['city'] = institute.city.name
info['province'] = institute.city.province.name
info['region'] = institute.city.province.region.name
return info

def get_user_info(self, user):
info = dict()
info['username'] = user.username
info['global_access_level'] = user.social_user.access_level
info['access_level'] = info['global_access_level']
info['join_date'] = make_timestamp(user.social_user.registration_time)
info['mail_hash'] = self.hash(user.email, 'md5')
info['institute'] = self.get_institute_info(
user.social_user.institute_id)
info['first_name'] = user.first_name
info['last_name'] = user.last_name
info['tasks_solved'] = -1
info["username"] = user.username
info["global_access_level"] = user.social_user.access_level
info["access_level"] = info["global_access_level"]
info["join_date"] = make_timestamp(user.social_user.registration_time)
info["mail_hash"] = self.hash(user.email, "md5")
info["institute"] = user.social_user.institute_id
info["first_name"] = user.first_name
info["last_name"] = user.last_name
info["tasks_solved"] = -1
return info

def get_participation_info(self, participation):
info = self.get_user_info(participation.user)
info['score'] = participation.social_participation.score
info["score"] = participation.social_participation.score
if participation.social_participation.access_level is not None:
info[
'access_level'] = participation.social_participation.access_level
info["access_level"] = participation.social_participation.access_level
return info

def update_from_data(self, obj, *args, **kwargs):
Expand Down Expand Up @@ -484,7 +469,7 @@ def filename_to_contest_languages(self, contest, filename):
def task_supported_languages(self, contest, t: Task):
supported_languages = set()
for manager in t.active_dataset.managers:
if 'grader.' in manager or 'stub.' in manager:
if "grader." in manager or "stub." in manager:
for lang in self.filename_to_contest_languages(contest, manager):
supported_languages.add(lang.name)

Expand All @@ -496,27 +481,27 @@ def task_supported_languages(self, contest, t: Task):
# Handlers that do not require JSON data
def dbfile_handler(self, environ, args):
try:
fobj = self.file_cacher.get_file(args['digest'])
fobj = self.file_cacher.get_file(args["digest"])
except KeyError:
raise NotFound()

response = Response()
response.status_code = 200
response.mimetype = 'application/octet-stream'
response.mimetype = "application/octet-stream"

if 'name' in args:
if "name" in args:
if args["name"].endswith(".pdf"):
# Add header to allow the official pdf.js to work
response.headers.add_header('Access-Control-Allow-Origin',
'https://mozilla.github.io')
response.headers.add_header(
"Access-Control-Allow-Origin", "https://mozilla.github.io"
)
else:
# Don't do this on pdf files because it breaks the native pdf
# reader
response.headers.add_header(
'Content-Disposition',
'attachment',
filename=args['name'])
mimetype = mimetypes.guess_type(args['name'])[0]
"Content-Disposition", "attachment", filename=args["name"]
)
mimetype = mimetypes.guess_type(args["name"])[0]
if mimetype is not None:
response.mimetype = mimetype

Expand All @@ -532,20 +517,20 @@ def static_file_handler(self, environ, filename, contest_name=None):
return NotFound()

path = os.path.join(
pkg_resources.resource_filename('cmsocial-web-build', ''),
filename)
pkg_resources.resource_filename("cmsocial-web-build", ""), filename
)

try:
response = Response()
response.status_code = 200
response.mimetype = 'application/octet-stream'
response.mimetype = "application/octet-stream"
mimetype = mimetypes.guess_type(filename)[0]
if mimetype is not None:
response.mimetype = mimetype
response.last_modified = \
datetime.utcfromtimestamp(os.path.getmtime(path))\
.replace(microsecond=0)
response.response = wrap_file(environ, io.open(path, 'rb'))
response.last_modified = datetime.utcfromtimestamp(
os.path.getmtime(path)
).replace(microsecond=0)
response.response = wrap_file(environ, io.open(path, "rb"))
response.direct_passthrough = True
except OSError:
response = Response()
Expand All @@ -556,61 +541,33 @@ def static_file_handler(self, environ, filename, contest_name=None):
# Disable cache, so that the user will notice if the
# app.COMMIT_ID.js file has a new name

response.headers['Last-Modified'] = datetime.now()
response.headers[
'Cache-Control'] = 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0'
response.headers['Pragma'] = 'no-cache'
response.headers['Expires'] = '-1'
response.headers["Last-Modified"] = datetime.now()
response.headers["Cache-Control"] = (
"no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0"
)
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "-1"

return response

# Handlers that require JSON data
def check_handler(self):
try:
rtype = local.data['type']
rvalue = local.data['value']
rtype = local.data["type"]
rvalue = local.data["value"]
except KeyError:
logger.warning('Missing parameters')
return 'Bad request'
logger.warning("Missing parameters")
return "Bad request"

if rtype == 'username':
if rtype == "username":
err = self.check_user(rvalue)
elif rtype == 'email':
elif rtype == "email":
err = self.check_email(rvalue)
else:
logger.warning('Request type not understood')
return 'Bad request'
logger.warning("Request type not understood")
return "Bad request"
return err

def location_handler(self):
if local.data['action'] == 'get':
institute = local.session.query(Institute)\
.filter(Institute.id == local.data['id']).first()
if institute is None:
return 'Not found'
local.resp = self.get_institute_info(institute)
elif local.data['action'] == 'listregions':
out = local.session.query(Region).all()
local.resp['regions'] = [{'id': r.id, 'name': r.name} for r in out]
elif local.data['action'] == 'listprovinces':
out = local.session.query(Province)\
.filter(Province.region_id == local.data['id']).all()
local.resp['provinces'] = [{
'id': r.id,
'name': r.name
} for r in out]
elif local.data['action'] == 'listcities':
out = local.session.query(City)\
.filter(City.province_id == local.data['id']).all()
local.resp['cities'] = [{'id': r.id, 'name': r.name} for r in out]
elif local.data['action'] == 'listinstitutes':
out = local.session.query(Institute)\
.filter(Institute.city_id == local.data['id']).all()
local.resp['institutes'] = [{
'id': r.id,
'name': r.name
} for r in out]

def sso_handler(self):
if local.user is None:
return 'Unauthorized'
Expand Down

0 comments on commit 0a29910

Please sign in to comment.