class VideoEditForm(Form): title = wtf.TextField( u"Title", validators=[wtf.Required()], description=u"Video title, without the speakers’ names") description = RichTextField(u'Description', description=u"Summary of this video's content")
class ParticipantForm(Form): skill_levels = [('Beginner', 'Beginner'), ('Intermediate', 'Intermediate'), ('Advanced', 'Advanced')] reason_to_join = RichTextField( "Reason To Join", description="Why would you love to join Hacknight", validators=[wtf.Required()], content_css="/static/css/editor.css") phone_no = wtf.TextField( "Telephone No", description="Telephone No", validators=[wtf.Required(), wtf.validators.length(max=15)]) email = wtf.html5.EmailField( "Email", description="Email Address, We will never spam you .", validators=[wtf.Required(), wtf.validators.length(max=80)]) job_title = wtf.TextField( "Job Title", description="What is your job title? E.G: Senior Software " "Engineer at Awesome company", validators=[wtf.Required(), wtf.validators.length(max=120)]) company = wtf.TextField( "Company", description="Company Name", validators=[wtf.Optional(), wtf.validators.length(max=1200)]) skill_level = wtf.RadioField("Skill Level", description="What is your skill level?", choices=skill_levels)
class SponsorForm(Form): title = wtforms.TextField( "Title", description="Title of the project", validators=[ wtforms.validators.Required("A title is required"), wtforms.validators.length(max=250) ]) description = RichTextField( u"Description", description="Detailed description of your project", content_css="/static/css/editor.css") website = wtforms.fields.html5.URLField( "Home Page", description="URL to the home page", validators=[ wtforms.validators.Optional(), wtforms.validators.length(max=250) ]) image_url = wtforms.fields.html5.URLField( "Image URL", description="URL to the image", validators=[ wtforms.validators.Required("An image is required."), wtforms.validators.length(max=250) ])
class VenueForm(Form): title = wtf.TextField("Name", description="Name of the venue", validators=[wtf.Required()]) description = RichTextField("Notes", description="Notes about the venue", content_css="/static/css/editor.css") address1 = wtf.TextField("Address (line 1)", validators=[wtf.Required()]) address2 = wtf.TextField("Address (line 2)", validators=[wtf.Optional()]) city = wtf.TextField("City", validators=[wtf.Required()]) state = wtf.TextField("State", validators=[wtf.Optional()]) postcode = wtf.TextField("Post code", validators=[wtf.Optional()]) country = wtf.SelectField("Country", validators=[wtf.Required()], choices=country_codes, default="IN") latitude = wtf.DecimalField( "Latitude", places=None, validators=[wtf.Optional(), wtf.NumberRange(-90, 90)]) longitude = wtf.DecimalField( "Longitude", places=None, validators=[wtf.Optional(), wtf.NumberRange(-180, 180)]) profile_id = wtf.SelectField("Owner", description="The owner of this listing", coerce=int, validators=[wtf.Required()])
class BoardForm(Form): """ Edit a board. """ description = RichTextField( "Description", validators=[ validators.Required("A description of the job board is required"), AllUrlsValid() ])
class ProjectForm(Form): title = wtf.TextField("Title", description="Title of the project", validators=[wtf.Required("A title is required"), wtf.validators.length(max=250)]) blurb = wtf.TextField("Blurb", description="A single-line summary of the project", validators=[wtf.Required("A blurb is required"), wtf.validators.length(max=250)]) description = RichTextField(u"Description", description="Detailed description of your project", content_css="/static/css/editor.css") participating = wtf.RadioField("Will you be participating?", default=1, coerce=getbool, choices=[(1, u"I will be working on this project"), (0, u"I’m proposing an idea for others to take up")])
class SendEmailForm(Form): subject = wtf.TextField( "Subject", description="Subject for the email", validators=[wtf.Required(), wtf.validators.length(max=250)]) message = RichTextField( "Message", description= "Email message, only `FULLNAME` will be replaced with participant fullname", validators=[wtf.Required()]) send_to = wtf.RadioField("Send email to", default=2, coerce=int)
class EmailEventParticipantsForm(Form): pending_message = RichTextField( "Pending Message", description= "Message to be sent for pending participants. '*|FULLNAME|*' will be replaced with user's fullname.", validators=[wtf.Optional()]) confirmation_message = RichTextField( "Confirmation Message", description= "Message to be sent for confirmed participants. '*|FULLNAME|*' will be replaced with user's fullname.", validators=[wtf.Optional()]) rejected_message = RichTextField( "Rejected Message", description= "Message to be sent for rejected participants. '*|FULLNAME|*' will be replaced with user's fullname.", validators=[wtf.Optional()]) waitlisted_message = RichTextField( "Waitlisted Message", description= "Message to be sent for waitlisted participants. '*|FULLNAME|*' will be replaced with user's fullname.", validators=[wtf.Optional()])
class EventForm(Form): title = wtf.TextField( "Title", description="Name of the Event", validators=[wtf.Required(), wtf.NoneOf(values=["new"])]) name = wtf.TextField( "URL name", validators=[ wtf.Optional(), ValidName(), AvailableName(u"There’s another event with the same name") ], description="URL identifier, leave blank to autogenerate") blurb = wtf.TextField( "Blurb", description="Single line blurb introducing the event") description = RichTextField( "Description", description="Detailed description of the event", content_css="/static/css/editor.css") venue = wtf.QuerySelectField( "Venue", description=Markup( 'Venue for this event (<a href="/venue/new">make new</a>)'), query_factory=lambda: Venue.query, get_label='title', ) start_datetime = DateTimeField( "Start date/time", description="The date and time at which this event begins", validators=[wtf.Required()]) end_datetime = DateTimeField( "End date/time", description="The date and time at which this event ends", validators=[wtf.Required()]) ticket_price = wtf.TextField( "Ticket price", description="Entry fee, if any, to be paid at the venue") total_participants = wtf.IntegerField( "Venue capacity", description= "The number of people this venue can accommodate. Registrations will be closed after that. Use 0 to indicate unlimited capacity", default=50, validators=[wtf.Required()]) website = wtf.TextField("Website", description="Related Website (Optional)", validators=[wtf.Optional()]) def validate_end_datetime(self, field): if field.data < self.start_datetime.data: raise wtf.ValidationError( u"Your event can’t end before it starts.")
class ExpenseReportForm(Form): """ Create or edit an expense report. """ title = wtforms.TextField(u"Title", validators=[wtforms.validators.Required()], description=u"What are these expenses for?") description = RichTextField(u"Description", validators=[wtforms.validators.Optional()], description=u"Notes on the expenses") currency = wtforms.SelectField(u"Currency", validators=[wtforms.validators.Required()], description=u"Currency for expenses in this report", choices=CURRENCIES) budget = QuerySelectField(u"Budget", validators=[wtforms.validators.Optional()], query_factory=sorted_budgets, get_label='title', allow_blank=True, description=u"The budget source for these expenses")
class EmailEventParticipantsForm(Form): pending_message = RichTextField( "Pending Message", description= "Message to be sent for pending participants. '*|FULLNAME|*' will be replaced with user's fullname.", validators=[wtforms.validators.Optional()], tinymce_options={ 'convert_urls': False, 'remove_script_host': False }) confirmation_message = RichTextField( "Confirmation Message", description= "Message to be sent for confirmed participants. '*|FULLNAME|*' will be replaced with user's fullname.", validators=[wtforms.validators.Optional()], tinymce_options={ 'convert_urls': False, 'remove_script_host': False }) rejected_message = RichTextField( "Rejected Message", description= "Message to be sent for rejected participants. '*|FULLNAME|*' will be replaced with user's fullname.", validators=[wtforms.validators.Optional()], tinymce_options={ 'convert_urls': False, 'remove_script_host': False }) waitlisted_message = RichTextField( "Waitlisted Message", description= "Message to be sent for waitlisted participants. '*|FULLNAME|*' will be replaced with user's fullname.", validators=[wtforms.validators.Optional()], tinymce_options={ 'convert_urls': False, 'remove_script_host': False })
class BudgetForm(Form): """ Create or edit a budget. """ title = wtforms.TextField(u"Budget title", validators=[wtforms.validators.Required()], description=u"The name of your project or other budget source") description = RichTextField(u"Description", description=u"Description of the budget") def validate_title(self, field): """ If the title is already in use, refuse to add this one. """ existing = set([simplify_text(b.title) for b in Budget.query.filter_by(workspace=g.workspace).all() if b != self.edit_obj]) if simplify_text(field.data) in existing: raise wtforms.ValidationError("You have an existing budget with the same name")
class SendEmailForm(Form): subject = wtforms.TextField("Subject", description="Subject for the email", validators=[ wtforms.validators.Required(), wtforms.validators.length(max=250) ]) message = RichTextField( "Message", description= "Email message, only *|FULLNAME|* will be replaced with participant fullname", validators=[wtforms.validators.Required()], tinymce_options={ 'convert_urls': False, 'remove_script_host': False }) send_to = wtforms.RadioField("Send email to", default=2, coerce=int)
class WorkspaceForm(Form): """ Manage workspace settings. """ description = RichTextField( u"Usage notes", description= u"Notes for your organization members on how to use this expense reporting tool" ) timezone = wtforms.SelectField( u"Timezone", validators=[wtforms.validators.Required("Select a timezone")], choices=[(tz, tz) for tz in common_timezones], description=u"The primary timezone in which your organization is based" ) access_teams = QuerySelectMultipleField( u"Access Teams", validators=[ wtforms.validators.Required("You need to select at least one team") ], get_label='title', description=u"Teams that can submit expense reports") review_teams = QuerySelectMultipleField( u"Review Teams", validators=[ wtforms.validators.Required("You need to select at least one team") ], get_label='title', description=u"Teams that can review and act on expense reports") admin_teams = QuerySelectMultipleField( u"Admin Teams", validators=[ wtforms.validators.Required("You need to select at least one team") ], get_label='title', description=u"Teams with administrative access to this workspace. " u"Admin access is required to create or edit budgets and categories") def validate_admin_teams(self, field): if self.edit_obj.owners not in field.data: field.data.append(self.edit_obj.owners)
class ParticipantForm(Form): reason_to_join = RichTextField( "Reason To Join", description="Why would you love to join Hacknight", validators=[wtf.Required()], content_css="/static/css/editor.css") phone_no = wtf.TextField("Telephone No", description="Telephone No", validators=[wtf.Required()]) email = wtf.html5.EmailField( "Email", description="Email Address, We will never spam you .", validators=[wtf.Required()]) job_title = wtf.TextField( "Job Title", description="What is your job title? E.G: Senior Software " "Engineer at Awesome company", validators=[wtf.Required()]) company = wtf.TextField("Company", description="Company Name", validators=[wtf.Optional()])
class PlaylistForm(Form): title = wtf.TextField(u"Title", validators=[wtf.Required()], description=u"The name of your playlist") short_title = wtf.TextField( u"Short title", validators=[wtf.Optional()], description= u"Shorter title, displayed next to the channel's name when viewing a video" ) name = wtf.TextField( u"URL Name", validators=[wtf.Optional()], description=u"Optional. Will be automatically generated if left blank") description = RichTextField(u"Description") recorded_date = wtf.DateField( u"Recorded date", validators=[wtf.Optional()], description= u"Date on which the videos in this playlist were recorded, if applicable" ) published_date = wtf.DateField( u"Published date", validators=[wtf.Required()], default=date.today(), description=u"Date on which this playlist was created or made public") public = wtf.BooleanField(u"This playlist is public", default=True) def validate_name(self, field): if invalid_name.search(field.data): raise wtf.ValidationError( "The name cannot have spaces or non-alphanumeric characters") existing = Playlist.query.filter_by(channel=self.channel, name=field.data).first() if existing and existing.id != self.edit_id: raise wtf.ValidationError("That name is already in use")
class ReviewForm(Form): """ Reviewer notes on expense reports. """ notes = RichTextField(u"Notes", validators=[wtforms.validators.Required()])
class ProfileForm(Form): type = wtf.SelectField(u"Profile type", coerce=int, validators=[wtf.Required()]) description = RichTextField(u"Description/Bio", content_css="/static/css/editor.css")
class ApplicationResponseForm(Form): response_message = RichTextField("")
class ListingForm(Form): """Form for new job posts""" job_headline = TextField( "Headline", description= "A single-line summary. This goes to the front page and across the network", validators=[ validators.Required("A headline is required"), validators.Length(min=1, max=100, message="%(max)d characters maximum") ]) job_type = RadioField( "Type", coerce=int, validators=[validators.Required("The job type must be specified")]) job_category = RadioField( "Category", coerce=int, validators=[validators.Required("Select a category")]) job_location = TextField( "Location", description= u'“Bangalore”, “Chennai”, “Pune”, etc or “Anywhere” (without quotes)', validators=[ validators.Required( u"If this job doesn’t have a fixed location, use “Anywhere”"), validators.Length(min=3, max=80, message="%(max)d characters maximum") ]) job_relocation_assist = BooleanField("Relocation assistance available") job_description = RichTextField( "Description", description= u"Don’t just describe the job, tell a compelling story for why someone should work for you", validators=[ validators.Required("A description of the job is required"), AllUrlsValid() ], tinymce_options={'convert_urls': True}) job_perks = BooleanField("Job perks are available") job_perks_description = RichTextField( "Describe job perks", description=u"Stock options, free lunch, free conference passes, etc", validators=[AllUrlsValid()]) job_how_to_apply = TextAreaField( "What should a candidate submit when applying for this job?", description=u"Example: “Include your LinkedIn and GitHub profiles.” " u"We now require candidates to apply through the job board only. " u"Do not include any contact information here. Candidates CANNOT " u"attach resumes or other documents, so do not ask for that", validators=[ validators.Required( u"HasGeek does not offer screening services. " u"Please specify what candidates should submit") ]) company_name = TextField( "Name", description=u"The name of the organization where the position is. " u"No intermediaries or unnamed stealth startups. Use your own real name if the company isn’t named " u"yet. We do not accept listings from third parties such as recruitment consultants. Such listings " u"may be removed without notice", validators=[ validators.Required( u"This is required. Posting any name other than that of the actual organization is a violation of the ToS" ), validators.Length( min=4, max=80, message="The name must be within %(min)d to %(max)d characters" ) ]) company_logo = FileField( "Logo", description= u"Optional — Your company logo will appear at the top of your listing. " u"170px wide is optimal. We’ll resize automatically if it’s wider", ) # validators=[file_allowed(uploaded_logos, "That image type is not supported")]) company_logo_remove = BooleanField("Remove existing logo") company_url = TextField("URL", description=u"Example: http://www.google.com", validators=[optional_url, AllUrlsValid()]) hr_contact = RadioField( u"Is it okay for recruiters and other " u"intermediaries to contact you about this listing?", coerce=getbool, description=u"We’ll display a notice to this effect on the listing", default=0, choices=[(0, u"No, it is NOT OK"), (1, u"Yes, recruiters may contact me")]) # Deprecated 2013-11-20 # poster_name = TextField("Name", # description=u"This is your name, for our records. Will not be revealed to applicants", # validators=[validators.Required("We need your name")]) poster_email = EmailField( "Email", description= u"This is where we’ll send your confirmation email and all job applications. " u"We recommend using a shared email address such as [email protected]. " u"Listings are classified by your email domain. " u"Your email address will not be revealed to applicants until you respond", validators=[ validators.Required( "We need to confirm your email address before the job can be listed" ), validators.Length(min=5, max=80, message="%(max)d characters maximum"), validators.Email( "That does not appear to be a valid email address"), ValidEmailDomain() ]) collaborators = HiddenMultiField( u"Collaborators", description= u"If someone is helping you evaluate candidates, type their names here. " u"They must have a HasGeek account. They will not receive email notifications " u"— use a shared email address above for that — but they will be able to respond " u"to candidates who apply") def validate_company_name(form, field): if len(field.data) > 5: caps = len(CAPS_RE.findall(field.data)) small = len(SMALL_RE.findall(field.data)) if small == 0 or caps / float(small) > 0.8: raise ValidationError( "Surely your company isn't named in uppercase?") def validate_company_logo(form, field): if not request.files['company_logo']: return try: g.company_logo = process_image(request.files['company_logo']) except IOError, e: raise ValidationError(e.message) except KeyError, e: raise ValidationError("Unknown file format")
class ChannelForm(Form): type = wtf.SelectField(u"Channel type", coerce=int, validators=[wtf.Required()]) description = RichTextField(u"Description")
class ApplicationForm(Form): apply_email = RadioField( "Email", validators=[validators.Required("Pick an email address")], description="Add new email addresses from your profile") apply_phone = TextField( "Phone", validators=[ validators.Required("Specify a phone number"), validators.Length(min=1, max=15, message="%(max)d characters maximum") ], description="A phone number the employer can reach you at") apply_message = RichTextField( "Job application", validators=[ validators.Required("You need to say something about yourself"), AllUrlsValid() ], description="Please provide all details the employer has requested") def __init__(self, *args, **kwargs): super(ApplicationForm, self).__init__(*args, **kwargs) self.apply_email.choices = [] if g.user: self.apply_email.description = Markup( u'Add new email addresses from <a href="{}" target="_blank">your profile</a>' .format(g.user.profile_url)) self.apply_email.choices = [(e, e) for e in lastuser.user_emails(g.user)] if not self.apply_email.choices: self.apply_email.choices = [ ('', Markup( '<em>You have not verified your email address</em>')) ] def validate_apply_message(form, field): words = get_word_bag(field.data) form.words = words similar = False for oldapp in JobApplication.query.filter_by( response=EMPLOYER_RESPONSE.SPAM).all(): if oldapp.words: s = SequenceMatcher(None, words, oldapp.words) if s.ratio() > 0.8: similar = True break if similar: raise ValidationError( "Your application is very similar to one previously identified as spam" ) # Check for email and phone numbers in the message # Prepare text by replacing non-breaking spaces with spaces (for phone numbers) and removing URLs. # URLs may contain numbers that are not phone numbers. phone_search_text = URL_RE.sub( '', field.data.replace(' ', ' ').replace(' ', ' ').replace(u'\xa0', ' ')) if EMAIL_RE.search(field.data) is not None or PHONE_DETECT_RE.search( phone_search_text) is not None: raise ValidationError( "Do not include your email address or phone number in the application" )
class EventForm(Form): title = wtforms.TextField("Title", description="Name of the Event", validators=[ wtforms.validators.Required(), wtforms.validators.NoneOf(values=["new"]), wtforms.validators.length(max=250) ]) name = wtforms.TextField( "URL name", validators=[ wtforms.validators.Optional(), ValidName(), AvailableName(u"There’s another event with the same name", scoped=True), wtforms.validators.length(max=250) ], description="URL identifier, leave blank to autogenerate") blurb = wtforms.TextField( "Blurb", description="Single line blurb introducing the event", validators=[wtforms.validators.length(max=250)]) description = RichTextField( "Description", description="Detailed description of the event", linkify=False, content_css="/static/css/editor.css", tinymce_options={ "valid_elements": "p,br,strong/b,em/i,sup,sub,h3,h4,h5,h6,ul,ol,li,a[!href|title|target|class],blockquote,pre,code,img[!src|alt|class|width|height|align]", "theme_advanced_buttons1": "bold,italic,|,sup,sub,|,bullist,numlist,|,link,unlink,|,blockquote,|,removeformat,code,image", "theme": "advanced" }, sanitize_tags=[ 'p', 'br', 'strong', 'em', 'sup', 'sub', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'li', 'a', 'span', 'blockquote', 'pre', 'code', 'img', 'table', 'thead', 'tbody', 'tfoot', 'tr', 'th', 'td', 'iframe' ], sanitize_attributes={ 'a': ['href', 'title', 'target', 'class'], 'span': ['class'], 'img': ['src', 'alt', 'class', 'width', 'height', 'align'] }, ) apply_instructions = RichTextField( "Instructions for participants", description= "This will be shown to participants on the hacknight joining form", content_css="/static/css/editor.css") venue = QuerySelectField( "Venue", description=Markup( 'Venue for this event (<a href="/venue/new">make new</a>)'), query_factory=lambda: Venue.query, get_label='title', allow_blank=True, blank_text="Online event", ) start_datetime = DateTimeField( "Start date/time", description="The date and time at which this event begins", validators=[wtforms.validators.Required()]) end_datetime = DateTimeField( "End date/time", description="The date and time at which this event ends", validators=[wtforms.validators.Required()]) ticket_price = wtforms.TextField( "Ticket price", description="Entry fee, if any, to be paid at the venue", validators=[wtforms.validators.length(max=250)]) maximum_participants = wtforms.IntegerField( "Venue capacity", description="The number of people this venue can accommodate.", default=50, validators=[wtforms.validators.Required()]) website = wtforms.fields.html5.URLField( "Website", description="Related Website (Optional)", validators=[ wtforms.validators.Optional(), wtforms.validators.length(max=250), wtforms.validators.URL() ]) status = wtforms.SelectField( "Event status", description="Current status of this hacknight", coerce=int, choices=STATUS_CHOICES) sync_service = wtforms.SelectField( "Sync service name", description="Name of the ticket sync service like doattend", choices=SYNC_CHOICES, validators=[ wtforms.validators.Optional(), wtforms.validators.length(max=100) ]) sync_eventsid = wtforms.TextField( "Sync event ID", description= "Sync events id like DoAttend event ID. More than one event ID is allowed separated by ,.", validators=[ wtforms.validators.Optional(), wtforms.validators.length(max=100) ]) sync_credentials = wtforms.TextField( "Sync credentials", description="Sync credentials like API Key for the event", validators=[ wtforms.validators.Optional(), wtforms.validators.length(max=100) ]) def validate_end_datetime(self, field): if field.data < self.start_datetime.data: raise wtforms.ValidationError( u"Your event can’t end before it starts.") def validate_sync_credentials(self, field): # Remove extra space in front and end. # TODO: Find better way to do it, because this code doesn't validate rather sanitizes. field.data = field.data.strip() def validate_sync_eventsid(self, field): if self.sync_service.data == SYNC_SERVICE.DOATTEND: #Event id in doattend is 5 digit integer, in future it may increase or change. event_id_pattern = r"\d{5,}" events_id = field.data.strip().split(',') for event_id in events_id: if not re.match(event_id_pattern, event_id.strip()): raise wtforms.ValidationError( u"Event id {event_id} is invalid".format( event_id=event_id)) if events_id: field.data = ",".join(events_id)