Skip to content

Commit

Permalink
Migration to Baseframe (with Bootstrap3) for UI
Browse files Browse the repository at this point in the history
  • Loading branch information
jace committed May 14, 2014
1 parent 39b7847 commit 33bc9a3
Show file tree
Hide file tree
Showing 80 changed files with 2,159 additions and 4,594 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ packed.js
packed.css
baseframe-packed.js
baseframe-packed.css
firasans.css
editor.packed.css
uploads/
search/
26 changes: 7 additions & 19 deletions hasjob/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from flask.ext.mail import Mail
from flask.ext.lastuser import Lastuser
from flask.ext.lastuser.sqlalchemy import UserManager
from baseframe import baseframe, assets, Version, cache
from baseframe import baseframe, assets, Version
import coaster.app
from ._version import __version__

Expand All @@ -20,8 +20,8 @@

# Second, setup assets
version = Version(__version__)
assets['hasjob.js'][version] = 'js/scripts.js'
assets['hasjob.css'][version] = 'css/screen.css'
assets['hasjob.js'][version] = 'js/app.js'
assets['hasjob.css'][version] = 'css/app.css'

# Third, after config, import the models and views

Expand All @@ -33,23 +33,11 @@
def init_for(env):
coaster.app.init_app(app, env)
RQ(app)
if app.config.get('SERVER_NAME'):
subdomain = app.config.get('STATIC_SUBDOMAIN', 'static')
else:
subdomain = None
app.add_url_rule('/static/<path:filename>', endpoint='static',
view_func=app.send_static_file, subdomain=subdomain)

baseframe.init_app(app, requires=['hasjob'],
ext_requires=[('jquery.textarea-expander', 'jquery.tinymce', 'jquery.form', 'jquery.cookie',
'select2', 'jquery.sparkline','jquery.nouislider'), 'firasans', 'baseframe-networkbar'])
app.assets.register('js_tinymce', assets.require('tiny_mce.js>=3.5.0,<4.0.0'))
if subdomain:
# The /_baseframe path has to be under the current domain because TinyMCE
# doesn't like loading from a subdomain, but we also need access to /_baseframe
# in the static subdomain for other assets (potentially obsoleted by ext_requires)
app.add_url_rule(baseframe.static_url_path + '/<path:filename>',
view_func=baseframe.send_static_file,
endpoint='baseframe_static', subdomain=subdomain)
ext_requires=['baseframe-bs3', ('jquery.textarea-expander', 'jquery.cookie',
'jquery.sparkline','jquery.nouislider'), ('firasans', 'baseframe-firasans'), 'fontawesome>=4.0.0'])
app.assets.register('js_tinymce', assets.require('tinymce.js>=4.0.0'))

from hasjob.uploads import configure as uploads_configure
from hasjob.search import configure as search_configure
Expand Down
31 changes: 17 additions & 14 deletions hasjob/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@ class ListingForm(Form):
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",
description=u"Optional — Your company logo will appear at the top of your listing.",
) # validators=[file_allowed(uploaded_logos, "That image type is not supported")])
company_logo_remove = BooleanField("Remove existing logo")
company_url = TextField("URL",
Expand All @@ -112,10 +111,11 @@ class ListingForm(Form):
# 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. "
description=Markup(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",
u"<strong>Listings are classified by your email domain,</strong> "
u"so use a work email address. "
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"),
Expand Down Expand Up @@ -149,7 +149,10 @@ def validate_company_logo(form, field):
def validate_job_headline(form, field):
if EMAIL_RE.search(field.data) is not None:
raise ValidationError(u"Do not include contact information in the listing")
if simplify_text(field.data) == 'awesome coder wanted at awesome company':
if simplify_text(field.data) in (
'awesome coder wanted at awesome company',
'pragmatic programmer wanted at outstanding organisation',
'pragmatic programmer wanted at outstanding organization'):
raise ValidationError(u"Come on, write your own headline. You aren’t just another run-of-the-mill company, right?")
caps = len(CAPS_RE.findall(field.data))
small = len(SMALL_RE.findall(field.data))
Expand Down Expand Up @@ -185,10 +188,10 @@ def validate_job_pay_cash_min(form, field):
if form.job_pay_type.data != PAY_TYPE.NOCASH:
if not field.data:
raise ValidationError("Please specify what this job pays")
data = field.data
data = field.data.strip()
if not data[0].isdigit():
data = data[1:] # Remove currency symbol
data = data.replace(',', '') # Remove thousands separator
data = data.replace(',', '').strip() # Remove thousands separator
if data.isdigit():
field.data = int(data)
else:
Expand All @@ -198,11 +201,11 @@ def validate_job_pay_cash_min(form, field):

def validate_job_pay_cash_max(form, field):
if form.job_pay_type.data != PAY_TYPE.NOCASH:
data = field.data
data = field.data.strip()
if data:
if not data[0].isdigit():
data = data[1:] # Remove currency symbol
data = data.replace(',', '') # Remove thousands separator
data = data.replace(',', '').strip() # Remove thousands separator
if data and data.isdigit():
field.data = int(data)
else:
Expand All @@ -212,11 +215,11 @@ def validate_job_pay_cash_max(form, field):

def validate_job_pay_equity_min(form, field):
if form.job_pay_equity.data:
data = field.data
data = field.data.strip()
if data:
if not data[-1].isdigit():
data = field.data[:-1] # Remove % symbol
data = data.replace(',', '') # Remove thousands separator
data = data.replace(',', '').strip() # Remove thousands separator
try:
field.data = Decimal(data)
except InvalidOperation:
Expand All @@ -229,11 +232,11 @@ def validate_job_pay_equity_min(form, field):

def validate_job_pay_equity_max(form, field):
if form.job_pay_equity.data:
data = field.data
data = field.data.strip()
if data:
if not data[-1].isdigit():
data = field.data[:-1] # Remove % symbol
data = data.replace(',', '') # Remove thousands separator
data = data.replace(',', '').strip() # Remove thousands separator
try:
field.data = Decimal(data)
except InvalidOperation:
Expand Down
3 changes: 3 additions & 0 deletions hasjob/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
agelimit = timedelta(days=30)
newlimit = timedelta(days=1)

webmail_domains = set(['gmail.com', 'yahoo.com', 'yahoo.co.in', 'hotmail.com', 'outlook.com', 'aol.com',
'live.com', 'yopmail.com', 'pobox.com'])


class POSTSTATUS:
DRAFT = 0 # Being written
Expand Down
17 changes: 16 additions & 1 deletion hasjob/models/jobpost.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

from datetime import datetime
from werkzeug import cached_property
from flask import url_for
from coaster.sqlalchemy import timestamp_columns
from baseframe import cache
from . import agelimit, db, POSTSTATUS, EMPLOYER_RESPONSE, PAY_TYPE, BaseMixin, TimestampMixin
from . import agelimit, db, POSTSTATUS, EMPLOYER_RESPONSE, PAY_TYPE, BaseMixin, TimestampMixin, webmail_domains
from .jobtype import JobType
from .jobcategory import JobCategory
from .user import User
Expand All @@ -22,6 +23,7 @@ class JobPost(BaseMixin, db.Model):
datetime = db.Column(db.DateTime, default=datetime.utcnow, nullable=False) # Published
closed_datetime = db.Column(db.DateTime, nullable=True) # If withdrawn or rejected
sticky = db.Column(db.Boolean, nullable=False, default=False)
pinned = db.synonym('sticky')

# Job description
headline = db.Column(db.Unicode(100), nullable=False)
Expand Down Expand Up @@ -110,6 +112,19 @@ def is_old(self):
def pay_type_label(self):
return PAY_TYPE.get(self.pay_type)

def url_for(self, action='view', _external=False):
if action == 'view':
return url_for('jobdetail', hashid=self.hashid, _external=_external)
elif action == 'edit':
return url_for('editjob', hashid=self.hashid, _external=_external)
elif action == 'confirm':
return url_for('confirm', hashid=self.hashid, _external=_external)
elif action == 'browse':
if self.email_domain in webmail_domains:
return url_for('browse_by_email', md5sum=self.md5sum, _external=_external)
else:
return url_for('browse_by_domain', domain=self.email_domain, _external=_external)

@property
def pays_cash(self):
if self.pay_type is None:
Expand Down
Loading

0 comments on commit 33bc9a3

Please sign in to comment.