Trees | Indices | Help |
---|
|
1 import re 2 from six.moves.urllib.parse import urlparse 3 4 import flask 5 import wtforms 6 import json 7 8 from flask_wtf.file import FileAllowed, FileRequired, FileField 9 10 from flask.ext import wtf 11 from jinja2 import Markup 12 13 from coprs import constants 14 from coprs import helpers 15 from coprs import models 16 from coprs.logic.coprs_logic import CoprsLogic 17 from coprs.logic.users_logic import UsersLogic 18 from coprs.logic.modules_logic import ModulesLogic 19 from coprs.models import Package 20 from coprs import exceptions23 """ 24 Params 25 ------ 26 source_type_text : str 27 name of the source type (tito/mock/pypi/rubygems/upload) 28 29 Returns 30 ------- 31 BasePackageForm child 32 based on source_type_text input 33 """ 34 if source_type_text == 'git_and_tito': 35 return PackageFormTito 36 elif source_type_text == 'mock_scm': 37 return PackageFormMock 38 elif source_type_text == 'pypi': 39 return PackageFormPyPI 40 elif source_type_text == 'rubygems': 41 return PackageFormRubyGems 42 else: 43 raise exceptions.UnknownSourceTypeException("Invalid source type")4447 widget = wtforms.widgets.ListWidget(prefix_label=False) 48 option_widget = wtforms.widgets.CheckboxInput()49527254 if not message: 55 message = ("A list of http[s] URLs separated by whitespace characters" 56 " is needed ('{0}' doesn't seem to be a valid URL).") 57 self.message = message5860 urls = field.data.split() 61 for u in urls: 62 if not self.is_url(u): 63 raise wtforms.ValidationError(self.message.format(u))6466 parsed = urlparse(url) 67 if not parsed.scheme.startswith("http"): 68 return False 69 if not parsed.netloc: 70 return False 71 return True75 """ Allows also `repo://` schema"""9177 parsed = urlparse(url) 78 if parsed.scheme not in ["http", "https", "copr"]: 79 return False 80 if not parsed.netloc: 81 return False 82 # copr://username/projectname 83 # ^^ schema ^^ netlock ^^ path 84 if parsed.scheme == "copr": 85 # check if projectname missed 86 path_split = parsed.path.split("/") 87 if len(path_split) < 2 or path_split[1] == "": 88 return False 89 90 return True10595 if not message: 96 message = ("URLs must end with .src.rpm" 97 " ('{0}' doesn't seem to be a valid SRPM URL).") 98 super(UrlSrpmListValidator, self).__init__(message)99117109 if not message: 110 message = "You can upload only .src.rpm and .nosrc.rpm files" 111 self.message = message112120143122 if not message: 123 if group is None: 124 message = "You already have project named '{}'." 125 else: 126 message = "Group {} ".format(group) + "already have project named '{}'." 127 self.message = message 128 if not user: 129 user = flask.g.user 130 self.user = user 131 self.group = group132134 if self.group: 135 existing = CoprsLogic.exists_for_group( 136 self.group, field.data).first() 137 else: 138 existing = CoprsLogic.exists_for_user( 139 self.user, field.data).first() 140 141 if existing and str(existing.id) != form.id.data: 142 raise wtforms.ValidationError(self.message.format(field.data))156147 if not message: 148 message = "Name must contain only letters, digits, underscores, dashes and dots." 149 self.message = message150159168 185161 if not message: 162 message = "Project's name can not be just number." 163 self.message = message164188198190 if not value: 191 return '' 192 # Replace every whitespace string with one newline 193 # Formats ideally for html form filling, use replace('\n', ' ') 194 # to get space-separated values or split() to get list 195 result = value.strip() 196 regex = re.compile(r"\s+") 197 return regex.sub(lambda x: '\n', result)201206203 if value: 204 return helpers.PermissionEnum("request") 205 return helpers.PermissionEnum("nothing")209 210 @staticmethod279 280 def validate_mock_chroots_not_empty(self): 281 have_any = False 282 for c in self.chroots_list: 283 if getattr(self, c).data: 284 have_any = True 285 return have_any 286 287 F.chroots_list = list(map(lambda x: x.name, 288 models.MockChroot.query.filter( 289 models.MockChroot.is_active == True 290 ).all())) 291 F.chroots_list.sort() 292 # sets of chroots according to how we should print them in columns 293 F.chroots_sets = {} 294 for ch in F.chroots_list: 295 checkbox_default = False 296 if mock_chroots and ch in map(lambda x: x.name, 297 mock_chroots): 298 checkbox_default = True 299 300 setattr(F, ch, wtforms.BooleanField(ch, default=checkbox_default)) 301 if ch[0] in F.chroots_sets: 302 F.chroots_sets[ch[0]].append(ch) 303 else: 304 F.chroots_sets[ch[0]] = [ch] 305 306 return F 307212 class F(wtf.Form): 213 # also use id here, to be able to find out whether user 214 # is updating a copr if so, we don't want to shout 215 # that name already exists 216 id = wtforms.HiddenField() 217 group_id = wtforms.HiddenField() 218 219 name = wtforms.StringField( 220 "Name", 221 validators=[ 222 wtforms.validators.DataRequired(), 223 NameCharactersValidator(), 224 CoprUniqueNameValidator(user=user, group=group), 225 NameNotNumberValidator() 226 ]) 227 228 homepage = wtforms.StringField( 229 "Homepage", 230 validators=[ 231 wtforms.validators.Optional(), 232 wtforms.validators.URL()]) 233 234 contact = wtforms.StringField( 235 "Contact", 236 validators=[ 237 wtforms.validators.Optional(), 238 EmailOrURL()]) 239 240 description = wtforms.TextAreaField("Description") 241 242 instructions = wtforms.TextAreaField("Instructions") 243 244 repos = wtforms.TextAreaField( 245 "External Repositories", 246 validators=[UrlRepoListValidator()], 247 filters=[StringListFilter()]) 248 249 initial_pkgs = wtforms.TextAreaField( 250 "Initial packages to build", 251 validators=[ 252 UrlListValidator(), 253 UrlSrpmListValidator()], 254 filters=[StringListFilter()]) 255 256 disable_createrepo = wtforms.BooleanField(default=False) 257 build_enable_net = wtforms.BooleanField(default=False) 258 unlisted_on_hp = wtforms.BooleanField("Do not display this project on home page", default=False) 259 persistent = wtforms.BooleanField(default=False) 260 auto_prune = wtforms.BooleanField("If backend auto-prunning script should be run for this project", default=True) 261 use_bootstrap_container = wtforms.BooleanField("Enable use_bootstrap_container mock's feature (experimental)", default=False) 262 263 @property 264 def selected_chroots(self): 265 selected = [] 266 for ch in self.chroots_list: 267 if getattr(self, ch).data: 268 selected.append(ch) 269 return selected270 271 def validate(self): 272 if not super(F, self).validate(): 273 return False 274 275 if not self.validate_mock_chroots_not_empty(): 276 self.errors["chroots"] = ["At least one chroot must be selected"] 277 return False 278 return True310 verify = wtforms.TextField( 311 "Confirm deleting by typing 'yes'", 312 validators=[ 313 wtforms.validators.Required(), 314 wtforms.validators.Regexp( 315 r"^yes$", 316 message="Type 'yes' - without the quotes, lowercase.") 317 ])318319 320 # @TODO jkadlcik - rewrite via BaseBuildFormFactory after fe-dev-cloud is back online 321 -class BuildFormRebuildFactory(object):322 @staticmethod350 351 F.chroots_list = list(map(lambda x: x.name, active_chroots)) 352 F.chroots_list.sort() 353 F.chroots_sets = {} 354 for ch in F.chroots_list: 355 setattr(F, ch, wtforms.BooleanField(ch, default=True)) 356 if ch[0] in F.chroots_sets: 357 F.chroots_sets[ch[0]].append(ch) 358 else: 359 F.chroots_sets[ch[0]] = [ch] 360 361 return F 362324 class F(wtf.Form): 325 @property 326 def selected_chroots(self): 327 selected = [] 328 for ch in self.chroots_list: 329 if getattr(self, ch).data: 330 selected.append(ch) 331 return selected332 333 memory_reqs = wtforms.IntegerField( 334 "Memory requirements", 335 validators=[ 336 wtforms.validators.NumberRange( 337 min=constants.MIN_BUILD_MEMORY, 338 max=constants.MAX_BUILD_MEMORY)], 339 default=constants.DEFAULT_BUILD_MEMORY) 340 341 timeout = wtforms.IntegerField( 342 "Timeout", 343 validators=[ 344 wtforms.validators.NumberRange( 345 min=constants.MIN_BUILD_TIMEOUT, 346 max=constants.MAX_BUILD_TIMEOUT)], 347 default=constants.DEFAULT_BUILD_TIMEOUT) 348 349 enable_net = wtforms.BooleanField()365 package_name = wtforms.StringField( 366 "Package name", 367 validators=[wtforms.validators.DataRequired()]) 368 webhook_rebuild = wtforms.BooleanField(default=False)369372 git_url = wtforms.StringField( 373 "Git URL", 374 validators=[ 375 wtforms.validators.DataRequired(), 376 wtforms.validators.URL()]) 377 378 git_directory = wtforms.StringField( 379 "Git Directory", 380 validators=[ 381 wtforms.validators.Optional()]) 382 383 git_branch = wtforms.StringField( 384 "Git Branch", 385 validators=[ 386 wtforms.validators.Optional()]) 387 388 tito_test = wtforms.BooleanField(default=False) 389 390 @property398392 return json.dumps({ 393 "git_url": self.git_url.data, 394 "git_branch": self.git_branch.data, 395 "git_dir": self.git_directory.data, 396 "tito_test": self.tito_test.data 397 })401 scm_type = wtforms.SelectField( 402 "SCM Type", 403 choices=[("git", "Git"), ("svn", "SVN")]) 404 405 scm_url = wtforms.StringField( 406 "SCM URL", 407 validators=[ 408 wtforms.validators.DataRequired(), 409 wtforms.validators.URL()]) 410 411 scm_branch = wtforms.StringField( 412 "Git Branch", 413 validators=[ 414 wtforms.validators.Optional()]) 415 416 spec = wtforms.StringField( 417 "Spec File", 418 validators=[ 419 wtforms.validators.Regexp( 420 "^.+\.spec$", 421 message="RPM spec file must end with .spec")]) 422 423 @property431434 pypi_package_name = wtforms.StringField( 435 "PyPI package name", 436 validators=[wtforms.validators.DataRequired()]) 437 438 pypi_package_version = wtforms.StringField( 439 "PyPI package version", 440 validators=[ 441 wtforms.validators.Optional(), 442 ]) 443 444 python_versions = MultiCheckboxField( 445 'Build for Python', 446 choices=[ 447 ('3', 'python3'), 448 ('2', 'python2') 449 ], 450 default=['3', '2']) 451 452 @property459454 return json.dumps({ 455 "pypi_package_name": self.pypi_package_name.data, 456 "pypi_package_version": self.pypi_package_version.data, 457 "python_versions": self.python_versions.data 458 })462 gem_name = wtforms.StringField( 463 "Gem Name", 464 validators=[wtforms.validators.DataRequired()]) 465 466 @property471474 clone_url = wtforms.StringField( 475 "Clone Url", 476 validators=[wtforms.validators.DataRequired()]) 477 478 branch = wtforms.StringField( 479 "Branch", 480 validators=[wtforms.validators.Optional()]) 481 482 @property488500 501 F.memory_reqs = wtforms.IntegerField( 502 "Memory requirements", 503 validators=[ 504 wtforms.validators.Optional(), 505 wtforms.validators.NumberRange( 506 min=constants.MIN_BUILD_MEMORY, 507 max=constants.MAX_BUILD_MEMORY)], 508 default=constants.DEFAULT_BUILD_MEMORY) 509 510 F.timeout = wtforms.IntegerField( 511 "Timeout", 512 validators=[ 513 wtforms.validators.Optional(), 514 wtforms.validators.NumberRange( 515 min=constants.MIN_BUILD_TIMEOUT, 516 max=constants.MAX_BUILD_TIMEOUT)], 517 default=constants.DEFAULT_BUILD_TIMEOUT) 518 519 520 F.enable_net = wtforms.BooleanField() 521 F.background = wtforms.BooleanField(default=False) 522 F.package_name = wtforms.StringField() 523 524 F.chroots_list = list(map(lambda x: x.name, active_chroots)) 525 F.chroots_list.sort() 526 F.chroots_sets = {} 527 for ch in F.chroots_list: 528 setattr(F, ch, wtforms.BooleanField(ch, default=True)) 529 if ch[0] in F.chroots_sets: 530 F.chroots_sets[ch[0]].append(ch) 531 else: 532 F.chroots_sets[ch[0]] = [ch] 533 return F 534 539 544 549 554 559492 class F(form): 493 @property 494 def selected_chroots(self): 495 selected = [] 496 for ch in self.chroots_list: 497 if getattr(self, ch).data: 498 selected.append(ch) 499 return selected568563 form = BaseBuildFormFactory(active_chroots, wtf.Form) 564 form.pkgs = FileField('srpm', validators=[ 565 FileRequired(), 566 SrpmValidator()]) 567 return form581572 form = BaseBuildFormFactory(active_chroots, wtf.Form) 573 form.pkgs = wtforms.TextAreaField( 574 "Pkgs", 575 validators=[ 576 wtforms.validators.DataRequired(message="URLs to packages are required"), 577 UrlListValidator(), 578 UrlSrpmListValidator()], 579 filters=[StringListFilter()]) 580 return form584 modulemd = FileField("modulemd", validators=[ 585 FileRequired(), 586 # @TODO Validate modulemd.yaml file 587 ]) 588 589 create = wtforms.BooleanField("create", default=True) 590 build = wtforms.BooleanField("build", default=True)591594 modulemd = FileField("modulemd") 595 scmurl = wtforms.StringField() 596 branch = wtforms.StringField() 597 copr_owner = wtforms.StringField() 598 copr_project = wtforms.StringField()599602 603 """ 604 Validator for editing chroots in project 605 (adding packages to minimal chroot) 606 """ 607 608 buildroot_pkgs = wtforms.TextField( 609 "Packages") 610 611 repos = wtforms.TextAreaField('Repos', 612 validators=[UrlRepoListValidator(), 613 wtforms.validators.Optional()], 614 filters=[StringListFilter()]) 615 616 module_md = FileField("module_md") 617 618 comps = FileField("comps_xml")619622 comment = wtforms.TextAreaField("Comment")623626 627 @staticmethod 631 632 builder_default = False 633 admin_default = False 634 635 if permission: 636 if permission.copr_builder != helpers.PermissionEnum("nothing"): 637 builder_default = True 638 if permission.copr_admin != helpers.PermissionEnum("nothing"): 639 admin_default = True 640 641 setattr(F, "copr_builder", 642 wtforms.BooleanField( 643 default=builder_default, 644 filters=[ValueToPermissionNumberFilter()])) 645 646 setattr(F, "copr_admin", 647 wtforms.BooleanField( 648 default=admin_default, 649 filters=[ValueToPermissionNumberFilter()])) 650 651 return F652655 656 """Creates a dynamic form for given set of copr permissions""" 657 @staticmethod 661 662 for perm in permissions: 663 builder_choices = helpers.PermissionEnum.choices_list() 664 admin_choices = helpers.PermissionEnum.choices_list() 665 666 builder_default = perm.copr_builder 667 admin_default = perm.copr_admin 668 669 setattr(F, "copr_builder_{0}".format(perm.user.id), 670 wtforms.SelectField( 671 choices=builder_choices, 672 default=builder_default, 673 coerce=int)) 674 675 setattr(F, "copr_admin_{0}".format(perm.user.id), 676 wtforms.SelectField( 677 choices=admin_choices, 678 default=admin_default, 679 coerce=int)) 680 681 return F682685 description = wtforms.TextAreaField('Description', 686 validators=[wtforms.validators.Optional()]) 687 688 instructions = wtforms.TextAreaField('Instructions', 689 validators=[wtforms.validators.Optional()]) 690 691 repos = wtforms.TextAreaField('Repos', 692 validators=[UrlRepoListValidator(), 693 wtforms.validators.Optional()], 694 filters=[StringListFilter()]) 695 696 disable_createrepo = wtforms.BooleanField(validators=[wtforms.validators.Optional()]) 697 unlisted_on_hp = wtforms.BooleanField(validators=[wtforms.validators.Optional()]) 698 build_enable_net = wtforms.BooleanField(validators=[wtforms.validators.Optional()]) 699 auto_prune = wtforms.BooleanField(validators=[wtforms.validators.Optional()]) 700 use_bootstrap_container = wtforms.BooleanField(validators=[wtforms.validators.Optional()])701704 @staticmethod726706 class F(wtf.Form): 707 source = wtforms.StringField( 708 "Source", 709 default=copr.full_name) 710 711 owner = wtforms.SelectField( 712 "Fork owner", 713 choices=[(user.name, user.name)] + [(g.at_name, g.at_name) for g in groups], 714 default=user.name, 715 validators=[wtforms.validators.DataRequired()]) 716 717 name = wtforms.StringField( 718 "Fork name", 719 default=copr.name, 720 validators=[wtforms.validators.DataRequired(), NameCharactersValidator()]) 721 722 confirm = wtforms.BooleanField( 723 "Confirm", 724 default=False)725 return F729 buildroot_pkgs = wtforms.TextField('Additional packages to be always present in minimal buildroot') 730 repos = wtforms.TextAreaField('Additional repos to be used for builds in chroot', 731 validators=[UrlRepoListValidator(), 732 wtforms.validators.Optional()], 733 filters=[StringListFilter()]) 734 upload_comps = FileField("Upload comps.xml") 735 delete_comps = wtforms.BooleanField("Delete comps.xml")736739 playground = wtforms.BooleanField("Playground")740743 project = wtforms.TextField("Project")744747756749 if not message: 750 message = "Group with the alias '{}' already exists." 751 self.message = message752754 if UsersLogic.group_alias_exists(field.data): 755 raise wtforms.ValidationError(self.message.format(field.data))759 760 name = wtforms.StringField( 761 validators=[ 762 wtforms.validators.Regexp( 763 re.compile(r"^[\w.-]+$"), 764 message="Name must contain only letters," 765 "digits, underscores, dashes and dots."), 766 GroupUniqueNameValidator() 767 ] 768 )769772 name = wtforms.StringField("Name") 773 stream = wtforms.StringField("Stream") 774 version = wtforms.IntegerField("Version") 775 builds = wtforms.FieldList(wtforms.StringField("Builds ID list")) 776 packages = wtforms.FieldList(wtforms.StringField("Packages list")) 777 filter = wtforms.FieldList(wtforms.StringField("Package Filter")) 778 api = wtforms.FieldList(wtforms.StringField("Module API")) 779 profile_names = wtforms.FieldList(wtforms.StringField("Install Profiles"), min_entries=2) 780 profile_pkgs = wtforms.FieldList(wtforms.FieldList(wtforms.StringField("Install Profiles")), min_entries=2) 781 785812787 if not wtf.Form.validate(self): 788 return False 789 790 module = ModulesLogic.get_by_nsv(self.copr, self.name.data, self.stream.data, self.version.data).first() 791 if module: 792 self.errors["nsv"] = [Markup("Module <a href='{}'>{}</a> already exists".format( 793 helpers.copr_url("coprs_ns.copr_module", module.copr, id=module.id), module.full_name))] 794 return False 795 796 # Profile names should be unique 797 names = filter(None, self.profile_names.data) 798 if len(set(names)) < len(names): 799 self.errors["profiles"] = ["Profile names must be unique"] 800 return False 801 802 # WORKAROUND 803 # profile_pkgs are somehow sorted so if I fill profile_name in the first box and 804 # profile_pkgs in seconds box, it is sorted and validated correctly 805 for i in range(0, len(self.profile_names.data)): 806 # If profile name is not set, then there should not be any packages in this profile 807 if not flask.request.form["profile_names-{}".format(i)]: 808 if [j for j in range(0, len(self.profile_names)) if "profile_pkgs-{}-{}".format(i, j) in flask.request.form]: 809 self.errors["profiles"] = ["Missing profile name"] 810 return False 811 return True815 owner = wtforms.StringField("Owner Name", validators=[wtforms.validators.DataRequired()]) 816 copr = wtforms.StringField("Copr Name", validators=[wtforms.validators.DataRequired()]) 817 name = wtforms.StringField("Name", validators=[wtforms.validators.DataRequired()]) 818 stream = wtforms.StringField("Stream", validators=[wtforms.validators.DataRequired()]) 819 version = wtforms.IntegerField("Version", validators=[wtforms.validators.DataRequired()]) 820 arch = wtforms.StringField("Arch", validators=[wtforms.validators.DataRequired()])821
Trees | Indices | Help |
---|
Generated by Epydoc 3.0.1 | http://epydoc.sourceforge.net |