AddTestcases.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #!/usr/bin/env python3
  2. # Contest Management System - http://cms-dev.github.io/
  3. # Copyright © 2016 Peyman Jabbarzade Ganje <peyman.jabarzade@gmail.com>
  4. # Copyright © 2016 Stefano Maggiolo <s.maggiolo@gmail.com>
  5. #
  6. # This program is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU Affero General Public License as
  8. # published by the Free Software Foundation, either version 3 of the
  9. # License, or (at your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU Affero General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU Affero General Public License
  17. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. """This script adds multiple testcases from the filesystem to an
  19. existing dataset.
  20. """
  21. import argparse
  22. import logging
  23. import re
  24. import sys
  25. from cms import utf8_decoder
  26. from cms.db import Contest, Dataset, SessionGen, Task
  27. from cms.db.filecacher import FileCacher
  28. from cmscommon.importers import import_testcases_from_zipfile
  29. logger = logging.getLogger(__name__)
  30. def add_testcases(archive, input_template, output_template,
  31. task_name, dataset_description=None, contest_name=None,
  32. public=False, overwrite=False):
  33. with SessionGen() as session:
  34. task = session.query(Task)\
  35. .filter(Task.name == task_name).first()
  36. if not task:
  37. logger.error("No task called %s found." % task_name)
  38. return False
  39. dataset = task.active_dataset
  40. if dataset_description is not None:
  41. dataset = session.query(Dataset)\
  42. .filter(Dataset.task_id == task.id)\
  43. .filter(Dataset.description == dataset_description)\
  44. .first()
  45. if not dataset:
  46. logger.error("No dataset called %s found."
  47. % dataset_description)
  48. return False
  49. if contest_name is not None:
  50. contest = session.query(Contest)\
  51. .filter(Contest.name == contest_name).first()
  52. if task.contest != contest:
  53. logger.error("%s is not in %s" %
  54. (task_name, contest_name))
  55. return False
  56. file_cacher = FileCacher()
  57. # Get input/output file names templates
  58. input_re = re.compile(
  59. re.escape(input_template).replace("\\*", "(.*)") + "$")
  60. output_re = re.compile(
  61. re.escape(output_template).replace("\\*", "(.*)") + "$")
  62. try:
  63. successful_subject, successful_message = \
  64. import_testcases_from_zipfile(
  65. session, file_cacher, dataset,
  66. archive, input_re, output_re, overwrite, public)
  67. except Exception as error:
  68. logger.error(str(error))
  69. return False
  70. logger.info(successful_subject)
  71. logger.info(successful_message)
  72. return True
  73. def main():
  74. """Parse arguments and launch process."""
  75. parser = argparse.ArgumentParser(description="Add testcases to CMS.")
  76. parser.add_argument("task_name", action="store", type=utf8_decoder,
  77. help="task testcases will be attached to")
  78. parser.add_argument("file", action="store", type=utf8_decoder,
  79. help="a zip file which contains testcases")
  80. parser.add_argument("inputtemplate", action="store", type=utf8_decoder,
  81. help="format of input")
  82. parser.add_argument("outputtemplate", action="store", type=utf8_decoder,
  83. help="format of output")
  84. parser.add_argument("-p", "--public", action="store_true",
  85. help="if testcases should be public")
  86. parser.add_argument("-o", "--overwrite", action="store_true",
  87. help="if testcases can overwrite existing testcases")
  88. parser.add_argument("-c", "--contest_name", action="store",
  89. help="contest which testcases will be attached to")
  90. parser.add_argument("-d", "--dataset_description", action="store",
  91. help="dataset testcases will be attached to")
  92. args = parser.parse_args()
  93. success = add_testcases(
  94. args.file, args.inputtemplate, args.outputtemplate,
  95. args.task_name, args.dataset_description, args.contest_name,
  96. args.public, args.overwrite)
  97. return 0 if success is True else 1
  98. if __name__ == "__main__":
  99. sys.exit(main())