diff --git a/.DS_Store b/.DS_Store index a154cb0..a646d0a 100755 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/.gitignore b/.gitignore index 0cece3a..46422b1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,13 @@ +.DS_Store + +scripts/ + +# The local config file should be specific to the machine running the app. +local_config.py *.pyc -# The settings.cfg file should be specific to the machine running the app. -settings.cfg + +app.wsgi +runserver.py + +*.log +application.log diff --git a/departmentArray.py b/departmentArray.py index 9eb3d95..2bc2f4f 100644 --- a/departmentArray.py +++ b/departmentArray.py @@ -17,7 +17,8 @@ def combineShortAndLong(depts_list): for dept in depts_list: short_name = dept[0] long_name = dept[1] - combined_list.append(short_name + "-" + long_name) + combined_list.append(short_name.lower() + "-" + long_name.lower()) + print combined_list return combined_list ## diff --git a/runserver.py b/runserver.py index ca42c79..113c369 100644 --- a/runserver.py +++ b/runserver.py @@ -11,4 +11,4 @@ from study_buddy import app print "Starting server..." -app.run(debug=True) \ No newline at end of file +app.run(debug=True) diff --git a/study_buddy/__init__.py b/study_buddy/__init__.py old mode 100644 new mode 100755 index f918ffd..b4ca97b --- a/study_buddy/__init__.py +++ b/study_buddy/__init__.py @@ -1,72 +1,60 @@ -from flask import Flask -from flask.ext.sqlalchemy import SQLAlchemy -from flask.ext.security import Security, SQLAlchemyUserDatastore -from flask.ext.social import Social, SQLAlchemyConnectionDatastore, \ - login_failed -from mongokit import * -from models import * +from flask import Flask, render_template, request, session, abort -app = Flask(__name__) +# from flask.ext.wtf.csrf import CsrfProtect +from flask.ext.assets import Environment, Bundle +from flask.ext.mail import Mail, Message -# TODO: move all configs into external file. -app.config['SOCIAL_FACEBOOK'] = { - 'consumer_key': '804807199563793', - 'consumer_secret': 'e7d68bbbd3b828743dc3d6fff7cc9406' -} +from itsdangerous import URLSafeTimedSerializer +from inflection import titleize -app.config['SOCIAL_GOOGLE'] = { - 'consumer_key': '967982158206-146hbl8954b0oa45e71ii9efuuaj4fj0.apps.googleusercontent.com', - 'consumer_secret': 'JFYgnNsq8FR6qfjSC-uDHFEl' -} +import os, binascii, logging, sys -app.config['SECURITY_POST_LOGIN'] = '/profile' +logging.basicConfig(level=logging.DEBUG, + streamHandler=sys.stderr, + format='[%(levelname)s] <%(asctime)s> %(message)s') -## -# STAGE FOR DELETE -################################################# -app.config.update( - SECRET_KEY='Tieng3us3Xie5meiyae6iKKHVUIUDF', - GOOGLE_LOGIN_CLIENT_ID='1002179078501-mdq5hvm940d0hbuhqltr0o1qhsr7sduc.apps.googleusercontent.com', - GOOGLE_LOGIN_CLIENT_SECRET='O1kpQ8Is9s2pD3eOpxRfh-7x', - GOOGLE_LOGIN_REDIRECT_URI='http://127.0.0.1:5000/oauth2callback', -) -################################################# +app = Flask(__name__) -db = SQLAlchemy(app) +app.config.from_object('study_buddy.base_config') +app.config.from_object('study_buddy.local_config') -connection = Connection() -connection.register([StudySession]) -mongo_db = connection.succor +APP_ROOT = os.path.dirname(os.path.abspath(__file__)) -print "Running app..." +def output_time(result): + format = "%a, %-d at %-I:%M %p" + return result.strftime(format) -from . import views, models +def generate_csrf_token(): + if '_csrf_token' not in session: + session['_csrf_token'] = binascii.hexlify(os.urandom(24)) + return session['_csrf_token'] -# security_ds = SQLAlchemyUserDatastore(db, models.User, models.Role) -# social_ds = SQLAlchemyConnectionDatastore(db, models.Connection) +# assets = Environment(app) +# scss = Bundle('', filters='pyscss', output='all.css') +# assets.register('scss_all', scss) -# app.security = Security(app, security_ds) -# app.social = Social(app, social_ds) +# csrf = CsrfProtect() +# csrf.init_app(app) -# class SocialLoginError(Exception): -# def __init__(self, provider): -# self.provider = provider +ts = URLSafeTimedSerializer(app.config["SECRET_KEY"]) + +mail = Mail(app) + +print "Running app..." +app.jinja_env.globals.update(output_time=output_time) +app.jinja_env.globals.update(titleize=titleize) +app.jinja_env.globals['csrf_token'] = generate_csrf_token -# @app.before_first_request -# def before_first_request(): -# try: -# models.db.create_all() -# except Exception, e: -# app.logger.error(str(e)) +from study_buddy import views, models -# @login_failed.connect_via(app) -# def on_login_failed(sender, provider, oauth_response): -# app.logger.debug('Social Login Failed via %s; ' -# '&oauth_response=%s' % (provider.name, oauth_response)) +@app.errorhandler(404) +def page_not_found(e): + return render_template('404.html'), 404 -# # Save the oauth response in the session so we can make the connection -# # later after the user possibly registers -# session['failed_login_connection'] = \ -# get_connection_values_from_oauth_response(provider, oauth_response) +@app.before_request +def csrf_protect(): + if request.method == "POST": + token = session.pop('_csrf_token', None) + if not token or token != request.form.get('_csrf_token'): + abort(403) -# raise SocialLoginError(provider) \ No newline at end of file diff --git a/study_buddy/backup/department_names.json b/study_buddy/backup/department_names.json new file mode 100644 index 0000000..009f721 --- /dev/null +++ b/study_buddy/backup/department_names.json @@ -0,0 +1 @@ +{department_name:"Computer Science",school:"Wesleyan University",names:"[comp, compsci, computer]"} diff --git a/study_buddy/backup/slangscommand b/study_buddy/backup/slangscommand new file mode 100644 index 0000000..c529f66 --- /dev/null +++ b/study_buddy/backup/slangscommand @@ -0,0 +1,4 @@ +#mongoimport --db succor --collection slangs --type json --file backup/department_names.json --jsonArray +#Copy paste this command after running mongod on the terminal and adding to the +# file department_names located in backup folder. MAKE SURE TO COPY THE FORMAT or else +# it won't import diff --git a/study_buddy/base_config.py b/study_buddy/base_config.py new file mode 100644 index 0000000..03da528 --- /dev/null +++ b/study_buddy/base_config.py @@ -0,0 +1,10 @@ +SECURITY_POST_LOGIN = '/profile' + +MAIL_SERVER = 'smtp.gmail.com' +MAIL_PORT = 587 +MAIL_USE_TLS = True +MAIL_USE_SSL = False +ADMINS = ['succorapp@gmail.com'] + +DB_HOST = 'localhost' +DB_PORT = 27017 \ No newline at end of file diff --git a/study_buddy/forms.py b/study_buddy/forms.py index c0f40f4..0c82996 100644 --- a/study_buddy/forms.py +++ b/study_buddy/forms.py @@ -1,35 +1,101 @@ -from flask import current_app from flask.ext.wtf import Form -from wtforms import TextField, PasswordField, ValidationError -from wtforms.validators import Required, Email, Length, Regexp, EqualTo - -class UniqueUser(object): - def __init__(self, message="User exists"): - self.message = message - - def __call__(self, form, field): - if current_app.security.datastore.find_user(email=field.data): - raise ValidationError(self.message) - - -validators = { - 'email': [ - Required(), - Email(), - UniqueUser(message='Email address is associated with ' - 'an existing account') - ], - 'password': [ - Required(), - Length(min=6, max=50), - EqualTo('confirm', message='Passwords must match'), - Regexp(r'[A-Za-z0-9@#$%^&+=]', - message='Password contains invalid characters') - ] -} - - -class RegisterForm(Form): - email = TextField('Email', validators['email']) - password = PasswordField('Password', validators['password'], ) +from wtforms import TextField, PasswordField, ValidationError, BooleanField, IntegerField, DateTimeField, HiddenField, validators +from init_db import mongo_db +from werkzeug.security import check_password_hash +import re + +class EmailForm(Form): + email = TextField('Email', validators = [validators.Email(), validators.Required()]) + + def validate_email(self, field): + if self.get_user() is None: + raise validators.ValidationError('There is no account with this email') + + def get_user(self): + return mongo_db.users.User.find_one({'email' : self.email.data}) + + +class PasswordForm(Form): + password = PasswordField('New Password', validators = [validators.Required()]) + +class GroupForm(Form): + email = TextField('Contact') + department = TextField('Department', [ + validators.Required() + ]) + course_no = IntegerField('Course Number', [ + validators.Required(), + ]) + datetime = DateTimeField('Date and time', format="%Y/%m/%d %H:%M") + where = TextField('Where', [ + validators.Required() + ]) + assignment = TextField('Assignment', [ + validators.Required() + ]) + + school = TextField('School') + details = TextField('Details') + geo_location = HiddenField() + #all_nighter=BooleanField('All nighter') + + def validate_course_no(self, field): + if not self.course_no.data < 1000 or len(str(self.course_no.data)) != 3: + raise validators.ValidationError('Please enter a 3 digit course number') + + def validate_email(self, field): + if self.email.data and '.edu' not in self.email.data: + raise validators.ValidationError('Please use a .edu email') + +class EditUserForm(Form): + first_name = TextField('First Name', [ + #validators.Regexp(r'^[A-Za-z0-9.]+$', message= u'That\'s not a valid first name'), + validators.Required() + ]) + last_name = TextField('Last Name', [ + validators.Required() + ]) + course = TextField('Class') + + +class LoginForm(Form): + email = TextField('Email', [ + validators.Required() + ]) + + password = PasswordField('Password') + + remember = BooleanField('Remember me') + + def validate_password(self, field): + user = self.get_user() + + if user is None: + raise validators.ValidationError('Email does not exist') + + if not check_password_hash(user.password, self.password.data): + raise validators.ValidationError('Invalid password') + + def get_user(self): + return mongo_db.users.User.find_one({'email' : self.email.data}) + + +class RegistrationForm(Form): + email = TextField('Email', [ + validators.Required(), + validators.length(min=6, max=50), + validators.Email() + ]) + + def validate_email(self, field): + if '.edu' not in self.email.data: + raise validators.ValidationError('Please use a .edu email') + + if mongo_db.users.User.find({'email' : self.email.data}).count() > 0: + raise validators.ValidationError('Account with that email already exists') + + password = PasswordField('Password', [ + validators.Required(), + validators.EqualTo('confirm', message='Passwords must match') + ]) confirm = PasswordField('Confirm Password') \ No newline at end of file diff --git a/study_buddy/helpers.py b/study_buddy/helpers.py new file mode 100644 index 0000000..34f897a --- /dev/null +++ b/study_buddy/helpers.py @@ -0,0 +1,141 @@ +from study_buddy import app, ts +from flask import url_for, render_template +from pymongo import MongoClient +from json import dumps + +import boto.ses +import re + +## +# Given a wtf form object, return a json representation of the data +# in that form. +# +# @param form WTF form object +# +# @return Returns a JSON representation of the data in form +## +def json_from_form(form): + form_dict = {} + for field_name, value, in form.data.items(): + form_dict[field_name] = value + return form_dict + +## +# Given a search term for a department, determines what the user +# meant to search for. +# +# @param search_term The user-input search term. +# @param school The school in which we are searching for a department. +# +# @return Returns the term most closely matching the term the user input. +## +def smart_search(search_term, school): + client = MongoClient() + conn = client.succor.smart_search + search_term_processed = search_term.replace(" ", "").lower() + if school: + school = school.lower() + result = conn.find_one( + {'school' : school, + 'alternative_names' : {'$in' : [search_term_processed]}} + ) + else: + result = conn.find_one( + {'alternative_names' : {'$in' : [search_term_processed]}} + ) + if result: + return result['department_name'] + else: + return search_term + +## +# Finds the school name based on the email domain name given. +# +# @param email_ending The email domain name of the users email address. +# +# @return Returns the school name based on the email address given. +## +def school_name_from_email(email_ending): + client = MongoClient() + conn = client.succor.schools + result = conn.find_one({'email' : email_ending}) + if result: + return result['school'] + else: + return email_ending + +## +# Sends an email to a user who has just registered, with +# with instructions on how to verify account. +# +# @param email Email address to send verification link to. +## +def send_verification_email(user): + token = ts.dumps(user.email, salt='email-confirm-key') + confirm_url = url_for('verify', token=token, _external=True) + send_email( + "Vefiry your account with Succor", + app.config['FROM_EMAIL_ADDRESS'], + [user.email], + render_template("email/verify.txt", url=confirm_url, user=user), + render_template("email/verify.html", url=confirm_url, user=user) + ) + +def send_email(subject, sender, recipients, text_body, html_body): + conn = boto.ses.connect_to_region( + 'us-west-2', + aws_access_key_id=app.config['AWS_ACCESS_KEY_ID'], + aws_secret_access_key=app.config['AWS_SECRET_KEY_ACCESS'] + ) + + conn.send_email( + sender, + subject, + None, + recipients, + text_body=text_body, + html_body=html_body + ) + +## +# @returns returns True if c is a number +## +def is_number(c): + try: + float(c) + return True + except ValueError: + return False + +## +# Given a string, query, this function parses it to find a +# department and a course number and returns a tuple of the two. +# @returns return (department : string, course_number : string) +## +def parse_new_find(query): + is_digit = False + department_end = -1 + number_end = -1 + for i in range(1, len(query)+1): + c = query[len(query) - i] + if is_number(c) and is_digit: + continue + if is_number(c): + is_digit = True + number_end = (len(query) + 1) - i + if not is_number(c): + is_digit = False + department_end = (len(query) + 1) - i + break + + if department_end >= 0 and number_end >= 0: + course_number = query[department_end : number_end] + department_name = query[0 : department_end] + elif department_end >= 0: + department_name = query[0 : department_end] + course_number = '' + else: + department_name = '' + course_number = '' + + return (department_name.strip(), course_number.strip()) diff --git a/study_buddy/init_db.py b/study_buddy/init_db.py new file mode 100644 index 0000000..4d5e74d --- /dev/null +++ b/study_buddy/init_db.py @@ -0,0 +1,29 @@ +from study_buddy import app + +from models import StudySession, User + +from pymongo import GEOSPHERE +from mongokit import Connection, ObjectId + +from flask import redirect, url_for +from flask.ext.login import LoginManager + +connection = Connection(host=app.config['DB_HOST'], port=app.config['DB_PORT']) +connection.register([StudySession, User]) +mongo_db = connection[app.config['DB_NAME']] +# mongo_db.study_sessions.ensure_index([('geo_location', GEOSPHERE)]) + +login_manager = LoginManager() +login_manager.init_app(app) +login_manager.login_view = 'login' + +@login_manager.user_loader +def load_user(user_id): + return mongo_db.users.User.find_one({'_id' : ObjectId(user_id)}) + +# @login_manager.unauthorized_handler +# def unauthorized(): +# flash("Please log in to access this page") +# session['next'] = request. +# return redirect(url_for('login')) + diff --git a/study_buddy/models.py b/study_buddy/models.py index cb3d8e6..c3ab73f 100644 --- a/study_buddy/models.py +++ b/study_buddy/models.py @@ -1,23 +1,61 @@ -from flask.ext.security import UserMixin, RoleMixin +from study_buddy import app -from mongokit import Document +from flask.ext.login import UserMixin + +from mongokit import Document, Connection import datetime +class User(Document, UserMixin): + __database__ = app.config['DB_NAME'] + __collection__ = 'users' + + structure = { + 'date_creation' : datetime.datetime, + 'email' : basestring, + 'password' : basestring, + 'school' : basestring, + 'verified' : bool, + 'name' : { + 'first' : basestring, + 'last' : basestring, + 'full' : basestring + }, + 'classes' : [basestring], + 'groups_joined' : [basestring] + } + + default_values = { + 'date_creation' : datetime.datetime.utcnow + } + + required_fields = ['email', 'password'] + + use_dot_notation = True + + def get_id(self): + return str(self._id) + class StudySession(Document): - __database__ = 'succor' + __database__ = app.config['DB_NAME'] __collection__ = 'study_sessions' structure = { 'date_creation': datetime.datetime, 'department': basestring, 'course_no': basestring, - 'time': basestring, + 'time': datetime.datetime, 'location': basestring, 'description': basestring, 'contact_info': basestring, - 'details': basestring - } + 'details': basestring, + 'name': basestring, + 'geo_location' : dict, + 'school' : basestring, + 'participants' : [basestring] + # _id : ObjectId - mongo gives this to you automatically + } + required_fields = ['department', 'course_no', 'time', 'location'] @@ -27,48 +65,14 @@ class StudySession(Document): use_dot_notation = True -# roles_users = db.Table('roles_users', -# db.Column('user_id', db.Integer(), db.ForeignKey('users.id')), -# db.Column('role_id', db.Integer(), db.ForeignKey('roles.id'))) - -# class Role(db.Model, RoleMixin): - -# __tablename__ = "roles" - -# id = db.Column(db.Integer(), primary_key=True) -# name = db.Column(db.String(80), unique=True) -# description = db.Column(db.String(255)) - -# class User(db.Model, UserMixin): - -# __tablename__ = "users" - -# id = db.Column(db.Integer, primary_key=True) -# email = db.Column(db.String(255), unique=True) -# password = db.Column(db.String(120)) -# active = db.Column(db.Boolean()) -# last_login_at = db.Column(db.DateTime()) -# current_login_at = db.Column(db.DateTime()) -# last_login_ip = db.Column(db.String(100)) -# current_login_ip = db.Column(db.String(100)) -# login_count = db.Column(db.Integer) -# roles = db.relationship('Role', secondary=roles_users, -# backref=db.backref('users', lazy='dynamic')) -# connections = db.relationship('Connection', -# backref=db.backref('user', lazy='joined'), cascade="all") - -# class Connection(db.Model): - -# __tablename__ = "connections" - -# id = db.Column(db.Integer, primary_key=True) -# user_id = db.Column(db.Integer, db.ForeignKey('users.id')) -# provider_id = db.Column(db.String(255)) -# provider_user_id = db.Column(db.String(255)) -# access_token = db.Column(db.String(255)) -# secret = db.Column(db.String(255)) -# display_name = db.Column(db.String(255)) -# full_name = db.Column(db.String(255)) -# profile_url = db.Column(db.String(512)) -# image_url = db.Column(db.String(512)) -# rank = db.Column(db.Integer) \ No newline at end of file +class Slangs(Document): + __database__ = 'succor' + __collection__ = 'smart_search' + + structure = { + 'school' : basestring, + 'department_name': basestring, + 'alternative_names' : [basestring] + } + + use_dot_notation = True diff --git a/study_buddy/people_bios.json b/study_buddy/people_bios.json new file mode 100644 index 0000000..bc971a8 --- /dev/null +++ b/study_buddy/people_bios.json @@ -0,0 +1,26 @@ +{ + "Katya Sapozhnina" : {"picture" : "katya.png", + "name" : "Katya Sapozhnina", + "position" : "CEO", + "bio" : "Katya is the Founder and President of the Wesleyan Entrepreneurship Society. She founded the society her freshman year to spearhead entrepreneurship culture at Wesleyan and since it has grown to a popular and active society at Wesleyan. Katya will co-lead a for-credit class on Entrepreneurship this Spring for the second year in a row. She is also a Peer Advisor for the Patricelli Center of Social Entrepreneurship. She advises many startups on campus. She came up with the idea for Succor her freshman year and is excited that it is now a tool Wesleyan student use. She wishes Succor existed her freshman year when she was studying for her Biology tests. She currently uses Succor to study with friends for Statistics."}, + + "Aaron Rosen" : {"picture" : "aaron.png", + "name" : "Aaron Rosen", + "position" : "CTO", + "bio" : "Aaron is a former Google engineering intern and has been the lead engineer on several startups at Wesleyan to date. Some of his favorite projects have been involved with environmentalism at Wesleyan. Aaron loves to hike, travel, and cook and dreams of one day learning how to fly planes. He has been using Succor to advertise all of his study sessions for finals!"}, + + "Hora" : {"picture" : "hora.png", + "name" : "Hora", + "position" : "VP of Engineering", + "bio" : "Hora is currently a part of the Varsity Crew team at Wesleyan. In addition to Succor, he is involved with research in Physics and is a course assistant for the Physics department. In the future, he wants to explore the field of machine learning. Hora likes to play the drums, travel and do physical activity."}, + + "Denise Fransisco" : {"picture" : "denise.png", + "name" : "Denise Fransisco", + "position" : "VP of Engineering", + "bio" : "Denise is a Junior at Wesleyan University majoring in Computer Science. She is currently involved with two dance groups on campus and is a Programmer for Instructional Media Services. She is currently interested in Web Development. She helped create the front end of Succor in September 2014 during the Wesleyan Hackathon. She hopes that Succor will be widely used on campus and will continue making studying more convenient for everyone."}, + + "Aditya Gupta" : {"picture" : "adii.png", + "name" : "Aditya Gupta", + "position" : "Engineer", + "bio" : "Aditya is a Computer Science major. He hopes to improve his programming skills while helping people through ventures such as Succor. He is a big Liverpool F.C. fan and likes to play chess. He hopes to become an internationally rated chess player soon. He has been using Succor to create study groups as he does not want to leave the comfort of his room but also wants to study with other people."} +} \ No newline at end of file diff --git a/study_buddy/people_bios.txt b/study_buddy/people_bios.txt new file mode 100644 index 0000000..c21eaa7 --- /dev/null +++ b/study_buddy/people_bios.txt @@ -0,0 +1,21 @@ +{"people" : [ + {"name" : "Yekaterina Sapozhnina", + "position" : "CEO", + "bio" : "Katya is the Founder and President of the Wesleyan Entrepreneurship Society. She founded the society her freshman year to spearhead entrepreneurship culture at Wesleyan and since it has grown to a popular and active society at Wesleyan. Katya will co-lead a for-credit class on Entrepreneurship this Spring for the second year in a row. She is also a Peer Advisor for the Patricelli Center of Social Entrepreneurship. She advises many startups on campus. She came up with the idea for Succor her freshman year and is excited that it is now a tool Wesleyan student use. She wishes Succor existed her freshman year when she was studying for her Biology tests. She currently uses Succor to study with friends for Statistics."}, + + {"name" : "Aaron Rosen", + "position" : "CTO", + "bio" : "Aaron is a former Google engineering intern and has been the lead engineer on several startups at Wesleyan to date. Some of his favorite projects have been involved with environmentalism at Wesleyan. Aaron loves to hike, travel, and cook and dreams of one day learning how to fly planes. He has been using Succor to advertise all of his study sessions for finals!"}, + + {"name" : "Hora", + "position" : "VP of Engineering", + "bio" : "He is currently a part of the Varsity Crew team at Wesleyan. In addition to Succor, he is involved with research in Physics and is a course assistant for the Physics department. In the future, he wants to explore the field of machine learning. Hora likes to play the drums, travel and do physical activity."}, + + {"name" : "Denise Francisco", + "position" : "VP of Engineering", + "bio" : "Denise is a Junior at Wesleyan University majoring in Computer Science. She is currently involved with two dance groups on campus and is a Programmer for Instructional Media Services. She is currently interested in Web Development. She helped create the front end of Succor in September 2014 during the Wesleyan Hackathon. She hopes that Succor will be widely used on campus and will continue making studying more convenient for everyone."}, + + {"name" : "Aditya Gupta", + "position" : "Engineer", + "bio" : "Aditya is a Computer Science major. He hopes to improve his programming skills while helping people through ventures such as Succor. He is a big Liverpool F.C. fan and likes to play chess. He hopes to become an internationally rated chess player soon. He has been using Succor to create study groups as he does not want to leave the comfort of his room but also wants to study with other people."} +]} \ No newline at end of file diff --git a/study_buddy/static/.DS_Store b/study_buddy/static/.DS_Store new file mode 100644 index 0000000..b6bfae5 Binary files /dev/null and b/study_buddy/static/.DS_Store differ diff --git a/study_buddy/static/old_styles.css b/study_buddy/static/old_styles.css new file mode 100755 index 0000000..3bc1135 --- /dev/null +++ b/study_buddy/static/old_styles.css @@ -0,0 +1,283 @@ +/* +* +* Grey: #C7D0D5; +* Blue: #93B1C6; +* White: #F5F5F5; +* Orange: #FF7148; +* Red: #EC583A; +*/ + +@font-face { + font-family: josefinslab; + src: url(josefinslab-bold-webfont.woff); +} + +html { + font-family: josefinslab; +} +html, body { + height: 100%; +} +body { + width: 100%; + background: url(resources/images/wesleyan.jpg) !important; + background-color: #E0E0D1; + background-size: cover !important; + background-repeat: no-repeat; + background-attachment: fixed; +} + +.center-elmt { + margin-left: auto; + margin-right: auto; +} + +.center-txt { + text-align: center; +} + +.search-row-odd { + padding-bottom: 5px; + padding-top: 5px; + margin-bottom: 2px; + background-color: rgba(51, 51, 51, 0.7); + color: white; +} + +.search-row-even { + padding-bottom: 2px; + padding-top: 5px; + margin-bottom: 2px; + background-color: rgba(0, 51, 102, 0.7); + color: white; +} + +#search-results-container { + color: white; +} + +#no-search-results { + margin: 15px 0; +} + +#ui-datepicker-div { + width: 20%; + text-decoration: none; + list-style-type: none; + margin-left: auto; + margin-right: auto; +} + +/*class for centering*/ +.center { + width: 100%; + text-align: center; + margin-top: 100px; +} +.custom-title { + font-size: 500%; + text-align: center; + margin-top: 100px; + font-weight: bold; + color: beige; + min-width: 500px; + text-shadow: 3px 3px #000000; +} +.create-forms { + margin-top: 120px; +} +.ui-helper-hidden-accessible { + visibility: hidden; +} +.ui-menu-item:hover{ + background-color: #99D6FF; +} +.ui-menu-item { + padding-left: 10px; +} +.ui-widget-content { + width: 73%; + border: 1px solid black; + color: #222222; + background-color: white; + text-decoration: none; + list-style-type: none; + margin-left: auto; + margin-right: auto; + font-size: 12px; +} + +nav.top-bar { + opacity: 0.8; +} + +.top-bar-section ul li > h1 { + width: 100%; + color: white; + font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; + font-size: 0.8125rem; + font-weight: normal; + text-transform: none; + padding-top: 11px; +} + +#text-background { + /*background-color: rgba(51,51,51,0.5);*/ + margin-left: 30%; + margin-right: 30%; + padding: 5px; + line-height: initial; + border-radius: 25px; + text-shadow: 3px 3px #000000; + font-family:josefinslab; +} +.columns input { + width: 100% !important; +} +#intro { + font-size: 200%; + text-align: center; + margin-top: 65px; + margin-bottom: 50px; + color: beige; + /*background-color: rgba(51,51,51,0.5);*/ + line-height: initial; + margin-left: 22%; + margin-right: 22%; + padding: 10px; + border-radius: 10px; + text-shadow: 2px 2px #000000; + font-family:josefinslab; +} + +#text-input { + margin-bottom: 15px; + text-align: center; + + padding-left: 8px; + padding-right: 8px; +} + +#text-input input { + padding-top: 8px; + padding-bottom: 8px; + padding-left: 8px; + padding-right: 8px; + font-size: 25px; + margin-left: auto; + margin-right: auto; +} + +#searchresults { + width: 80%; + margin-left: 10%; +} +#searchbar { + width: 20%; + float: right; + margin-right: 20%; +} +#front-page-buttons { + margin-left: auto; + margin-right: auto; + text-align: center; +} +.container { + display: none; +} +.click { + cursor: pointer; +} + +#login-button a { + color: white; +} +#login-button { + margin-left: auto; + margin-right: auto; + text-align: center; +} +#button-wrapper { + width: 100%; + text-align: center; + margin-top: 100px; +} +#about-panel { + width: 75%; + margin-right: auto; + margin-left: auto; + margin-top: 65px; + background-color: rgba(255, 255, 255, 0.5); + font-size: 32px; +} +#about-panel p { + font-size: 20px; + margin-top: 7px; +} + + +#course { + width: 35.5%; +} + + +#page-header{ + width:90%; + margin-top: 8%; + margin-left: 10%; + margin-bottom: none; + display: inline-block; +} +#create-group { + width: 60%; + margin-left: auto; + margin-right: auto; +} +#search-input { + width: 50%; + margin-left: 10%; + display: inline-block; +} +.students-table { + width: 30%; + display: inline-block; +} +.notes { + display: inline-block; + width: 60%; + float: right; + height: 100%; + overflow: auto; +} +/*footer stuff*/ + +.footer { + margin-left: auto; + margin-right: auto; + text-shadow: 0.7px 0.7px #000000; + position: fixed; + bottom: 0; +} +#bot { + font-size: 16px; + text-align: center; + color: beige; + margin-bottom: 0; + +} + +.wrapper { + min-height: 95%; + height: auto !important; + height: 95%; + margin: ;0 + 0 auto -2em; +} +.footer, .push { + height: 2em; +} +#errors{ + margin-top: 5%; + +} + diff --git a/study_buddy/static/resources/.DS_Store b/study_buddy/static/resources/.DS_Store new file mode 100644 index 0000000..cd3a2cf Binary files /dev/null and b/study_buddy/static/resources/.DS_Store differ diff --git a/study_buddy/static/resources/fonts/Bitstream-Vera-Sans/Bitstream Vera License.txt b/study_buddy/static/resources/fonts/Bitstream-Vera-Sans/Bitstream Vera License.txt new file mode 100755 index 0000000..cf00835 --- /dev/null +++ b/study_buddy/static/resources/fonts/Bitstream-Vera-Sans/Bitstream Vera License.txt @@ -0,0 +1,123 @@ +Bitstream Vera Fonts Copyright + +The fonts have a generous copyright, allowing derivative works (as +long as "Bitstream" or "Vera" are not in the names), and full +redistribution (so long as they are not *sold* by themselves). They +can be be bundled, redistributed and sold with any software. + +The fonts are distributed under the following copyright: + +Copyright +========= + +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream +Vera is a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the fonts accompanying this license ("Fonts") and associated +documentation files (the "Font Software"), to reproduce and distribute +the Font Software, including without limitation the rights to use, +copy, merge, publish, distribute, and/or sell copies of the Font +Software, and to permit persons to whom the Font Software is furnished +to do so, subject to the following conditions: + +The above copyright and trademark notices and this permission notice +shall be included in all copies of one or more of the Font Software +typefaces. + +The Font Software may be modified, altered, or added to, and in +particular the designs of glyphs or characters in the Fonts may be +modified and additional glyphs or characters may be added to the +Fonts, only if the fonts are renamed to names not containing either +the words "Bitstream" or the word "Vera". + +This License becomes null and void to the extent applicable to Fonts +or Font Software that has been modified and is distributed under the +"Bitstream Vera" names. + +The Font Software may be sold as part of a larger software package but +no copy of one or more of the Font Software typefaces may be sold by +itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL +BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, +OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT +SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. + +Except as contained in this notice, the names of Gnome, the Gnome +Foundation, and Bitstream Inc., shall not be used in advertising or +otherwise to promote the sale, use or other dealings in this Font +Software without prior written authorization from the Gnome Foundation +or Bitstream Inc., respectively. For further information, contact: +fonts at gnome dot org. + +Copyright FAQ +============= + + 1. I don't understand the resale restriction... What gives? + + Bitstream is giving away these fonts, but wishes to ensure its + competitors can't just drop the fonts as is into a font sale system + and sell them as is. It seems fair that if Bitstream can't make money + from the Bitstream Vera fonts, their competitors should not be able to + do so either. You can sell the fonts as part of any software package, + however. + + 2. I want to package these fonts separately for distribution and + sale as part of a larger software package or system. Can I do so? + + Yes. A RPM or Debian package is a "larger software package" to begin + with, and you aren't selling them independently by themselves. + See 1. above. + + 3. Are derivative works allowed? + Yes! + + 4. Can I change or add to the font(s)? + Yes, but you must change the name(s) of the font(s). + + 5. Under what terms are derivative works allowed? + + You must change the name(s) of the fonts. This is to ensure the + quality of the fonts, both to protect Bitstream and Gnome. We want to + ensure that if an application has opened a font specifically of these + names, it gets what it expects (though of course, using fontconfig, + substitutions could still could have occurred during font + opening). You must include the Bitstream copyright. Additional + copyrights can be added, as per copyright law. Happy Font Hacking! + + 6. If I have improvements for Bitstream Vera, is it possible they might get + adopted in future versions? + + Yes. The contract between the Gnome Foundation and Bitstream has + provisions for working with Bitstream to ensure quality additions to + the Bitstream Vera font family. Please contact us if you have such + additions. Note, that in general, we will want such additions for the + entire family, not just a single font, and that you'll have to keep + both Gnome and Jim Lyles, Vera's designer, happy! To make sense to add + glyphs to the font, they must be stylistically in keeping with Vera's + design. Vera cannot become a "ransom note" font. Jim Lyles will be + providing a document describing the design elements used in Vera, as a + guide and aid for people interested in contributing to Vera. + + 7. I want to sell a software package that uses these fonts: Can I do so? + + Sure. Bundle the fonts with your software and sell your software + with the fonts. That is the intent of the copyright. + + 8. If applications have built the names "Bitstream Vera" into them, + can I override this somehow to use fonts of my choosing? + + This depends on exact details of the software. Most open source + systems and software (e.g., Gnome, KDE, etc.) are now converting to + use fontconfig (see www.fontconfig.org) to handle font configuration, + selection and substitution; it has provisions for overriding font + names and subsituting alternatives. An example is provided by the + supplied local.conf file, which chooses the family Bitstream Vera for + "sans", "serif" and "monospace". Other software (e.g., the XFree86 + core server) has other mechanisms for font substitution. \ No newline at end of file diff --git a/study_buddy/static/resources/fonts/Bitstream-Vera-Sans/Vera-Bold-Italic.ttf b/study_buddy/static/resources/fonts/Bitstream-Vera-Sans/Vera-Bold-Italic.ttf new file mode 100755 index 0000000..b55eee3 Binary files /dev/null and b/study_buddy/static/resources/fonts/Bitstream-Vera-Sans/Vera-Bold-Italic.ttf differ diff --git a/study_buddy/static/resources/fonts/Bitstream-Vera-Sans/Vera-Bold.ttf b/study_buddy/static/resources/fonts/Bitstream-Vera-Sans/Vera-Bold.ttf new file mode 100755 index 0000000..51d6111 Binary files /dev/null and b/study_buddy/static/resources/fonts/Bitstream-Vera-Sans/Vera-Bold.ttf differ diff --git a/study_buddy/static/resources/fonts/Bitstream-Vera-Sans/Vera-Italic.ttf b/study_buddy/static/resources/fonts/Bitstream-Vera-Sans/Vera-Italic.ttf new file mode 100755 index 0000000..cc23c9e Binary files /dev/null and b/study_buddy/static/resources/fonts/Bitstream-Vera-Sans/Vera-Italic.ttf differ diff --git a/study_buddy/static/resources/fonts/Bitstream-Vera-Sans/Vera.ttf b/study_buddy/static/resources/fonts/Bitstream-Vera-Sans/Vera.ttf new file mode 100755 index 0000000..58cd6b5 Binary files /dev/null and b/study_buddy/static/resources/fonts/Bitstream-Vera-Sans/Vera.ttf differ diff --git a/study_buddy/static/resources/fonts/asap/Asap-Bold.otf b/study_buddy/static/resources/fonts/asap/Asap-Bold.otf new file mode 100755 index 0000000..06aca04 Binary files /dev/null and b/study_buddy/static/resources/fonts/asap/Asap-Bold.otf differ diff --git a/study_buddy/static/resources/fonts/asap/Asap-BoldItalic.otf b/study_buddy/static/resources/fonts/asap/Asap-BoldItalic.otf new file mode 100755 index 0000000..c369040 Binary files /dev/null and b/study_buddy/static/resources/fonts/asap/Asap-BoldItalic.otf differ diff --git a/study_buddy/static/resources/fonts/asap/Asap-Italic.otf b/study_buddy/static/resources/fonts/asap/Asap-Italic.otf new file mode 100755 index 0000000..28b0e1f Binary files /dev/null and b/study_buddy/static/resources/fonts/asap/Asap-Italic.otf differ diff --git a/study_buddy/static/resources/fonts/asap/Asap-Regular.otf b/study_buddy/static/resources/fonts/asap/Asap-Regular.otf new file mode 100755 index 0000000..fba028b Binary files /dev/null and b/study_buddy/static/resources/fonts/asap/Asap-Regular.otf differ diff --git a/study_buddy/static/resources/fonts/asap/SIL Open Font License.txt b/study_buddy/static/resources/fonts/asap/SIL Open Font License.txt new file mode 100755 index 0000000..c9d69b5 --- /dev/null +++ b/study_buddy/static/resources/fonts/asap/SIL Open Font License.txt @@ -0,0 +1,44 @@ +Copyright (c) 2011, Omnibus-Type (www.omnibus-type.com|omnibus.type@gmail.com), +with Reserved Font Name "Asap". + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. + +The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the copyright statement(s). + +"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. + +"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. + +5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. \ No newline at end of file diff --git a/study_buddy/static/resources/images/aaron.png b/study_buddy/static/resources/images/aaron.png new file mode 100644 index 0000000..eb035f6 Binary files /dev/null and b/study_buddy/static/resources/images/aaron.png differ diff --git a/study_buddy/static/resources/images/adii.png b/study_buddy/static/resources/images/adii.png new file mode 100644 index 0000000..c9f9eb8 Binary files /dev/null and b/study_buddy/static/resources/images/adii.png differ diff --git a/study_buddy/static/resources/images/congruent_pentagon.png b/study_buddy/static/resources/images/congruent_pentagon.png new file mode 100644 index 0000000..c712660 Binary files /dev/null and b/study_buddy/static/resources/images/congruent_pentagon.png differ diff --git a/study_buddy/static/resources/images/denise.png b/study_buddy/static/resources/images/denise.png new file mode 100644 index 0000000..2e522dc Binary files /dev/null and b/study_buddy/static/resources/images/denise.png differ diff --git a/study_buddy/static/resources/images/diamond_upholstery.png b/study_buddy/static/resources/images/diamond_upholstery.png new file mode 100644 index 0000000..1c4701a Binary files /dev/null and b/study_buddy/static/resources/images/diamond_upholstery.png differ diff --git a/study_buddy/static/resources/images/hora.png b/study_buddy/static/resources/images/hora.png new file mode 100644 index 0000000..c4a4b45 Binary files /dev/null and b/study_buddy/static/resources/images/hora.png differ diff --git a/study_buddy/static/resources/images/katya.png b/study_buddy/static/resources/images/katya.png new file mode 100644 index 0000000..bc51240 Binary files /dev/null and b/study_buddy/static/resources/images/katya.png differ diff --git a/study_buddy/static/resources/images/logos/succor_finals-01.png b/study_buddy/static/resources/images/logos/succor_finals-01.png new file mode 100644 index 0000000..d81178d Binary files /dev/null and b/study_buddy/static/resources/images/logos/succor_finals-01.png differ diff --git a/study_buddy/static/resources/images/logos/succor_finals-02.png b/study_buddy/static/resources/images/logos/succor_finals-02.png new file mode 100644 index 0000000..d8d19d1 Binary files /dev/null and b/study_buddy/static/resources/images/logos/succor_finals-02.png differ diff --git a/study_buddy/static/resources/images/logos/succor_finals-03.png b/study_buddy/static/resources/images/logos/succor_finals-03.png new file mode 100644 index 0000000..0cd2518 Binary files /dev/null and b/study_buddy/static/resources/images/logos/succor_finals-03.png differ diff --git a/study_buddy/static/resources/images/logos/succor_finals-04.png b/study_buddy/static/resources/images/logos/succor_finals-04.png new file mode 100644 index 0000000..032d595 Binary files /dev/null and b/study_buddy/static/resources/images/logos/succor_finals-04.png differ diff --git a/study_buddy/static/resources/images/logos/succor_finals.svg b/study_buddy/static/resources/images/logos/succor_finals.svg new file mode 100644 index 0000000..aeba67e --- /dev/null +++ b/study_buddy/static/resources/images/logos/succor_finals.svg @@ -0,0 +1,1337 @@ + + + + diff --git a/study_buddy/static/resources/images/placeholder.png b/study_buddy/static/resources/images/placeholder.png new file mode 100644 index 0000000..175a72d Binary files /dev/null and b/study_buddy/static/resources/images/placeholder.png differ diff --git a/study_buddy/static/resources/images/succor-favicon.ico b/study_buddy/static/resources/images/succor-favicon.ico new file mode 100644 index 0000000..99f5be6 Binary files /dev/null and b/study_buddy/static/resources/images/succor-favicon.ico differ diff --git a/study_buddy/static/resources/images/thumbnail.png b/study_buddy/static/resources/images/thumbnail.png new file mode 100644 index 0000000..b96801b Binary files /dev/null and b/study_buddy/static/resources/images/thumbnail.png differ diff --git a/study_buddy/static/resources/js/datetimepicker/bower.json b/study_buddy/static/resources/js/datetimepicker/bower.json index 9c913ee..8350605 100755 --- a/study_buddy/static/resources/js/datetimepicker/bower.json +++ b/study_buddy/static/resources/js/datetimepicker/bower.json @@ -1,6 +1,6 @@ { "name":"datetimepicker", - "version":"2.3.4", + "version":"2.4.1", "main": [ "jquery.datetimepicker.js", "jquery.datetimepicker.css" @@ -12,7 +12,8 @@ "**/*.txt", "**/*.md", "**/*.html", - "**/*.tpl" + "**/*.tpl", + "**/jquery.js" ], "keywords": [ "calendar", diff --git a/study_buddy/static/resources/js/datetimepicker/datetimepicker.jquery.json b/study_buddy/static/resources/js/datetimepicker/datetimepicker.jquery.json index 8a05bd8..9cdff03 100755 --- a/study_buddy/static/resources/js/datetimepicker/datetimepicker.jquery.json +++ b/study_buddy/static/resources/js/datetimepicker/datetimepicker.jquery.json @@ -1,47 +1,47 @@ -{ - "name": "datetimepicker", - "version": "2.3.4", - "title": "jQuery Date and Time picker", - "description": "jQuery plugin for date, time, or datetime manipulation in form", - "keywords": [ - "calendar", - "date", - "time", - "form", - "datetime", - "datepicker", - "timepicker", - "datetimepicker", - "validation", - "ui", - "scroller", - "picker", - "i18n", - "input", - "jquery", - "touch" - ], - "author": { - "name": "Chupurnov Valeriy", - "email": "chupurnov@gmail.com", - "url": "http://xdsoft.net/contacts.html" - }, - "maintainers": [{ - "name": "Chupurnov Valeriy", - "email": "chupurnov@gmail.com", - "url": "http://xdsoft.net" - }], - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/xdan/datetimepicker/blob/master/MIT-LICENSE.txt" - } - ], - "bugs": "https://github.com/xdan/datetimepicker/issues", - "homepage": "http://xdsoft.net/jqplugins/datetimepicker/", - "docs": "http://xdsoft.net/jqplugins/datetimepicker/", - "download": "https://github.com/xdan/datetimepicker/archive/master.zip", - "dependencies": { - "jquery": ">=1.7" - } +{ + "name": "datetimepicker", + "version": "2.4.1", + "title": "jQuery Date and Time picker", + "description": "jQuery plugin for date, time, or datetime manipulation in form", + "keywords": [ + "calendar", + "date", + "time", + "form", + "datetime", + "datepicker", + "timepicker", + "datetimepicker", + "validation", + "ui", + "scroller", + "picker", + "i18n", + "input", + "jquery", + "touch" + ], + "author": { + "name": "Chupurnov Valeriy", + "email": "chupurnov@gmail.com", + "url": "http://xdsoft.net/contacts.html" + }, + "maintainers": [{ + "name": "Chupurnov Valeriy", + "email": "chupurnov@gmail.com", + "url": "http://xdsoft.net" + }], + "licenses": [ + { + "type": "MIT", + "url": "https://github.com/xdan/datetimepicker/blob/master/MIT-LICENSE.txt" + } + ], + "bugs": "https://github.com/xdan/datetimepicker/issues", + "homepage": "http://xdsoft.net/jqplugins/datetimepicker/", + "docs": "http://xdsoft.net/jqplugins/datetimepicker/", + "download": "https://github.com/xdan/datetimepicker/archive/master.zip", + "dependencies": { + "jquery": ">=1.7" + } } \ No newline at end of file diff --git a/study_buddy/static/resources/js/datetimepicker/index.html b/study_buddy/static/resources/js/datetimepicker/index.html index b75560d..9e5bc62 100755 --- a/study_buddy/static/resources/js/datetimepicker/index.html +++ b/study_buddy/static/resources/js/datetimepicker/index.html @@ -12,6 +12,7 @@
+Make the background of the date 2 days from now bright red.
+thank for this https://github.com/lampslave
+ -