Skip to content

Commit 44100ca

Browse files
committed
Merge 'rebased' in 'master'
1 parent 1541576 commit 44100ca

File tree

207 files changed

+5399
-9367
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

207 files changed

+5399
-9367
lines changed

.gitignore

+2-3
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@
44
build/
55
dist/
66
cms.egg-info/
7-
8-
!cms/web/assets/pdfjs/build/
9-
107
.testfailures
118
.unittestfailures
129
.coverage*
1310
cache/
1411
lib/
1512
log/
13+
14+
!cms/web/assets/pdfjs/build/

AUTHORS.txt

+4
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,21 @@ Luca Wehrstedt <[email protected]>
1111

1212
OTHER CONTRIBUTORS
1313

14+
Vytis Banaitis <[email protected]>
1415
Giovanni Campagna (aka gcampax) <[email protected]>
1516
Cheng, Ting-Yuan (aka magrady24) <[email protected]>
17+
William Di Luigi (aka wil93) <[email protected]>
1618
Vittorio Gambaletta (aka VittGam) <[email protected]>
1719
David Greenaway <[email protected]>
1820
Fabian Gundlach (aka fagu) <[email protected]>
1921
Masaki Hara (aka qnighy) <[email protected]>
22+
Artem Iglikov (aka arti) <[email protected]>
2023
Damien Leroy <[email protected]>
2124
Evgeny Martynov <[email protected]>
2225
Kento Nikaido (aka snukent) <[email protected]>
2326
William Pettersson <[email protected]>
2427
Federico Scrinzi (aka volpino) <[email protected]>
28+
Luca Versari <[email protected]>
2529
Kenneth Wong <[email protected]>
2630

2731
And many other people that didn't write code, but provided useful

LICENSE.txt

-16
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,6 @@ Files: cms/server/static/img/mimetypes/*.png
5353
Copyright: 2009 Tango Desktop Project, http://tango.freedesktop.org/
5454
License: public-domain
5555

56-
Files: cms/web/admin/lib/jquery/*
57-
Copyright: 2013 jQuery Foundation and other contributors, http://jquery.com/
58-
License: Expat
59-
60-
Files: cms/web/admin/lib/angular/*
61-
Copyright: 2010-2012 Google, Inc., http://angularjs.org
62-
License: Expat
63-
64-
Files: cms/web/admin/lib/angular-ui/*
65-
Copyright: 2012-2013 the AngularUI Team, https://github.com/organizations/angular-ui/teams/291112
66-
License: Expat
67-
68-
Files: cms/web/admin/lib/bootstrap/*
69-
Copyright: 2012 Twitter, Inc.
70-
License: Apache-2.0
71-
7256
Files: isolate/*
7357
Copyright: 2012-2013 Martin Mares <[email protected]>
7458
2012-2013 Bernard Blackham <[email protected]>

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ sistema di valutazione automatica dei programmi inviati dagli utenti,
1111
statistiche sul miglioramento nel tempo delle abilità di ogni utente,
1212
un forum di discussione. Il software include gran parte di Contest
1313
Management System (<https://github.com/cms-dev/cms>) e ne mantiene la
14-
licenza AGPL.
14+
licenza AGPL.

REQUIREMENTS.txt

+2
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,5 @@ six>=1.1
1515
requests>=1.1
1616
gevent>=1.0
1717
werkzeug>=0.8
18+
pycups>=1.9
19+
PyPDF2>=1.19

cms/__init__.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# Copyright © 2010-2013 Giovanni Mascellani <[email protected]>
66
# Copyright © 2010-2012 Stefano Maggiolo <[email protected]>
77
# Copyright © 2010-2012 Matteo Boscariol <[email protected]>
8-
# Copyright © 2013 Luca Wehrstedt <[email protected]>
8+
# Copyright © 2013-2014 Luca Wehrstedt <[email protected]>
99
#
1010
# This program is free software: you can redistribute it and/or modify
1111
# it under the terms of the GNU Affero General Public License as
@@ -41,7 +41,7 @@
4141
# log
4242
# Nothing intended for external use, no need to advertise anything.
4343
# util
44-
"mkdir", "Address", "ServiceCoord", "get_safe_shard",
44+
"mkdir", "utf8_decoder", "Address", "ServiceCoord", "get_safe_shard",
4545
"get_service_address", "get_service_shards", "default_argument_parser",
4646
# conf
4747
"config",
@@ -100,12 +100,9 @@
100100
LANG_C: ".h",
101101
LANG_CPP: ".h",
102102
LANG_PASCAL: "lib.pas",
103-
LANG_PYTHON: ".py",
104-
LANG_PHP: ".php",
105-
LANG_JAVA: ".java",
106103
}
107104

108-
from .util import mkdir, Address, ServiceCoord, get_safe_shard, \
105+
from .util import mkdir, utf8_decoder, Address, ServiceCoord, get_safe_shard, \
109106
get_service_address, get_service_shards, default_argument_parser
110107
from .conf import config
111108
from .plugin import plugin_list, plugin_lookup

cms/conf.py

+12-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
# -*- coding: utf-8 -*-
33

44
# Contest Management System - http://cms-dev.github.io/
5-
# Copyright © 2010-2013 Giovanni Mascellani <[email protected]>
5+
# Copyright © 2010-2014 Giovanni Mascellani <[email protected]>
66
# Copyright © 2010-2012 Stefano Maggiolo <[email protected]>
77
# Copyright © 2010-2012 Matteo Boscariol <[email protected]>
88
# Copyright © 2013 Luca Wehrstedt <[email protected]>
9+
# Copyright © 2014 Fabian Gundlach <[email protected]>
910
#
1011
# This program is free software: you can redistribute it and/or modify
1112
# it under the terms of the GNU Affero General Public License as
@@ -55,6 +56,7 @@ def __init__(self):
5556
# System-wide
5657
self.temp_dir = "/tmp"
5758
self.backdoor = False
59+
self.file_log_debug = False
5860

5961
# Database.
6062
self.database = "postgresql+psycopg2://cmsuser@localhost/cms"
@@ -67,7 +69,7 @@ def __init__(self):
6769
self.sandbox_implementation = 'isolate'
6870

6971
# WebServers.
70-
self.secret_key = "8e045a51e4b102ea803c06f92841a1fb",
72+
self.secret_key = "8e045a51e4b102ea803c06f92841a1fb"
7173
self.tornado_debug = False
7274

7375
# ContestWebServer.
@@ -106,6 +108,14 @@ def __init__(self):
106108
self.rankings = ["http://usern4me:passw0rd@localhost:8890/"]
107109
self.https_certfile = None
108110

111+
# PrintingService
112+
self.max_print_length = 10000000
113+
self.printer = None
114+
self.paper_size = "A4"
115+
self.max_pages_per_job = 10
116+
self.max_jobs_per_user = 10
117+
self.pdf_printing_allowed = False
118+
109119
# Installed or from source?
110120
self.installed = sys.argv[0].startswith("/usr/") and \
111121
sys.argv[0] != '/usr/bin/ipython' and \

cms/db/__init__.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@
6565
# usertest
6666
"UserTest", "UserTestFile", "UserTestManager", "UserTestResult",
6767
"UserTestExecutable",
68+
# printjob
69+
"PrintJob",
6870
# fsobject
6971
"FSObject",
7072
# init
@@ -82,7 +84,7 @@
8284

8385
# Instantiate or import these objects.
8486

85-
version = 11
87+
version = 12
8688

8789

8890
engine = create_engine(config.database, echo=config.database_debug,
@@ -105,6 +107,7 @@
105107
UserTestResult, UserTestExecutable
106108
from .test import Test, TestQuestion, QuestionFile, TestScore
107109
from .forum import PrivateMessage, Talk, Forum, Topic, Post
110+
from .printjob import PrintJob
108111
from .fsobject import FSObject
109112

110113
from .init import init_db

cms/db/contest.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ class Contest(Base):
157157
# Max contest time for each user in seconds.
158158
per_user_time = Column(
159159
Interval,
160+
CheckConstraint("per_user_time >= '0 seconds'"),
160161
nullable=True)
161162

162163
# Maximum number of submissions or user_tests allowed for each user
@@ -491,8 +492,8 @@ def tokens_available(self, username, task_name, timestamp=None):
491492
492493
username (string): the username of the user.
493494
task_name (string): the name of the task.
494-
timestamp (datetime): the time relative to which making the
495-
calculation.
495+
timestamp (datetime|None): the time relative to which making
496+
the calculation, or None to use now.
496497
497498
return ((int, datetime|None, datetime|None)): see description
498499
above.

cms/db/filecacher.py

+11-9
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,8 @@ def list(self, session=None):
320320
This implementation also accepts an additional (and optional)
321321
parameter: a SQLAlchemy session to use to query the database.
322322
323-
session (Session): the session to use; if not given a temporary
324-
one will be created and used.
323+
session (Session|None): the session to use; if not given a
324+
temporary one will be created and used.
325325
326326
"""
327327
def _list(session):
@@ -391,13 +391,15 @@ def __init__(self, service=None, path=None, null=False, enabled=None):
391391
By default the database-powered backend will be used, but this
392392
can be changed using the parameters.
393393
394-
service (Service): the service we are running for. Only used to
395-
determine the location of the file-system cache (and to
396-
provide the shard number to the Sandbox... sigh!).
397-
path (string): if specified, back the FileCacher with a file
398-
system-based storage instead of the default database-based
399-
one. The specified directory will be used as root for the
400-
storage and it will be created if it doesn't exist.
394+
service (Service|None): the service we are running for. Only
395+
used if present to determine the location of the
396+
file-system cache (and to provide the shard number to the
397+
Sandbox... sigh!).
398+
path (string|None): if specified, back the FileCacher with a
399+
file system-based storage instead of the default
400+
database-based one. The specified directory will be used
401+
as root for the storage and it will be created if it
402+
doesn't exist.
401403
null (bool): if True, back the FileCacher with a NullBackend,
402404
that just discards every file it receives. This setting
403405
takes priority over path.

cms/db/fsobject.py

+11-3
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ def _execute(self, operation, parameters, message, cursor=None):
135135
parameters (dict): the parameters to fill in the operation.
136136
message (unicode): a description to tell humans what we were
137137
doing in case something went wrong.
138-
cursor (cursor): the cursor to use to execute the statement
139-
(create and use a temporary one if not given).
138+
cursor (cursor|None): the cursor to use to execute the
139+
statement (create and use a temporary one if not given).
140140
141141
"""
142142
if cursor is None:
@@ -206,6 +206,9 @@ def readinto(self, buf):
206206
207207
return (int): the number of bytes read.
208208
209+
raise (io.UnsopportedOperation): when the file is closed or
210+
not open for reads.
211+
209212
"""
210213
if self._fd is None:
211214
raise io.UnsupportedOperation("Large object is closed.")
@@ -231,6 +234,9 @@ def write(self, buf):
231234
232235
return (int): the number of bytes written.
233236
237+
raise (io.UnsopportedOperation): when the file is closed or
238+
not open for writes.
239+
234240
"""
235241
if self._fd is None:
236242
raise io.UnsupportedOperation("Large object is closed.")
@@ -252,6 +258,8 @@ def seek(self, offset, whence=io.SEEK_SET):
252258
253259
return (int): the new absolute position.
254260
261+
raise (io.UnsopportedOperation): when the file is closed.
262+
255263
"""
256264
if self._fd is None:
257265
raise io.UnsupportedOperation("Large object is closed.")
@@ -280,7 +288,7 @@ def tell(self):
280288
def truncate(self, size=None):
281289
"""Trucate a large object.
282290
283-
size (int): the desired new size. If not given defaults to
291+
size (int|None): the desired new size. If None, defaults to
284292
current position.
285293
286294
return (int): the new actual size.

cms/db/printjob.py

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/usr/bin/env python2
2+
# -*- coding: utf-8 -*-
3+
4+
# Contest Management System - http://cms-dev.github.io/
5+
# Copyright © 2014 Fabian Gundlach <[email protected]>
6+
#
7+
# This program is free software: you can redistribute it and/or modify
8+
# it under the terms of the GNU Affero General Public License as
9+
# published by the Free Software Foundation, either version 3 of the
10+
# License, or (at your option) any later version.
11+
#
12+
# This program is distributed in the hope that it will be useful,
13+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
# GNU Affero General Public License for more details.
16+
#
17+
# You should have received a copy of the GNU Affero General Public License
18+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
20+
"""Print-job-related database interface for SQLAlchemy.
21+
22+
"""
23+
24+
from __future__ import absolute_import
25+
from __future__ import print_function
26+
from __future__ import unicode_literals
27+
28+
from sqlalchemy.schema import Column, ForeignKey
29+
from sqlalchemy.types import Integer, String, Unicode, DateTime, Boolean
30+
from sqlalchemy.orm import relationship, backref
31+
32+
from . import Base, User
33+
34+
35+
class PrintJob(Base):
36+
"""Class to store a print job.
37+
38+
"""
39+
__tablename__ = 'printjobs'
40+
41+
# Auto increment primary key.
42+
id = Column(
43+
Integer,
44+
primary_key=True)
45+
46+
# User (id and object) that did the submission.
47+
user_id = Column(
48+
Integer,
49+
ForeignKey(User.id,
50+
onupdate="CASCADE", ondelete="CASCADE"),
51+
nullable=False,
52+
index=True)
53+
user = relationship(
54+
User,
55+
backref=backref("printjobs",
56+
cascade="all, delete-orphan",
57+
passive_deletes=True))
58+
59+
# Submission time of the print job.
60+
timestamp = Column(
61+
DateTime,
62+
nullable=False)
63+
64+
# Filename and digest of the submitted file.
65+
filename = Column(
66+
Unicode,
67+
nullable=False)
68+
digest = Column(
69+
String,
70+
nullable=False)
71+
72+
done = Column(
73+
Boolean,
74+
nullable=False,
75+
default=False)
76+
77+
status = Column(
78+
Unicode,
79+
nullable=True)

cms/db/submission.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,8 @@ class SubmissionResult(Base):
313313
# Score as computed by ScoringService. Null means not yet scored.
314314
score = Column(
315315
Float,
316-
nullable=True)
316+
nullable=True,
317+
index=True)
317318

318319
# Score details. It's a JSON-encoded string containing information
319320
# that is given to ScoreType.get_html_details to generate an HTML

0 commit comments

Comments
 (0)