cleaned up code styles and pages

This commit is contained in:
Oliver Marks 2015-12-18 13:43:17 +00:00
parent 2b98d87928
commit ff7a9a2337
33 changed files with 180 additions and 450 deletions

View File

@ -1,25 +1,21 @@
import os
import sys
import time
import uuid
import hashlib
import datetime
from werkzeug import secure_filename
from werkzeug.security import generate_password_hash, check_password_hash
from flask import Flask, session, flash, get_flashed_messages
from flask import session, flash
from flask import redirect, abort
from flask import make_response
from flask import request
from flask import Blueprint
from flask.ext.login import LoginManager, login_required, UserMixin, login_user, logout_user, current_user, make_secure_token
from flask.ext.login import LoginManager, login_required, UserMixin, login_user, logout_user, make_secure_token
from requests_oauthlib import OAuth2Session
from scaffold import web
from libs.mail import sendmail
from pages import header, footer
from pages import profile
from data import site_user
from config.settings import *
from constants import *
@ -162,10 +158,9 @@ def oauth(provider=None):
oauth_access_type = 'offline'
oauth_approval_prompt = "force"
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
print session
print provider
if provider:
print provider
oauth_session = OAuth2Session(
oauth_provider.get('client_id'),
scope=oauth_provider.get('scope'),
@ -173,25 +168,27 @@ def oauth(provider=None):
# offline for refresh token
# force to always make user click authorize
#generate the google url we will use to authorize and redirect there
# generate the google url we will use to authorize and redirect there
authorization_url, state = oauth_session.authorization_url(
oauth_provider.get('auth_uri'),
access_type=oauth_access_type,
approval_prompt=oauth_approval_prompt)
print state
# State is used to prevent CSRF, keep this for later, make sure oauth returns to the same url.
# if testing and oauth_state errors make sure you logged in with localhost and not 127.0.0.1
session['oauth_state'] = state
session.modified = True
print session
return redirect(authorization_url)
print session
#allready authorised so lets handle the callback
# allready authorised so lets handle the callback
oauth_session = OAuth2Session(
oauth_provider.get('client_id'),
state=session['oauth_state'],
redirect_uri=oauth_provider.get('redirect_uri'))
token = oauth_session.fetch_token(
oauth_session.fetch_token(
oauth_provider.get('token_uri'),
client_secret=oauth_provider.get('client_secret'),
authorization_response=request.url,
@ -201,11 +198,6 @@ def oauth(provider=None):
r = oauth_session.get('https://www.googleapis.com/oauth2/v1/userinfo')
oauth_user = r.json()
#https://www.googleapis.com/auth/plus.login
#https://www.googleapis.com/auth/plus.me
print oauth_user
user_details = site_user.get_by_email({
'email': oauth_user.get('email')
}).get()
@ -228,6 +220,7 @@ def oauth(provider=None):
site_user.update_last_login().execute(user_details)
return redirect('/profile')
@authorize_pages.route("/change-password/<code>", methods=['GET'])
@authorize_pages.route("/change-password", methods=['GET'])
def change_password(code=None):

View File

@ -31,7 +31,7 @@ oauth_conf = {
}
gocardless_enviroment = 'sandbox'
gocardless_environment = 'sandbox'
gocardless_redirect_uri = 'https://test.maidstone-hackspace.org.uk'
gocardless_credentials = {
'app_id': '',
@ -40,7 +40,8 @@ gocardless_credentials = {
'merchant_id': ''
}
google_calendar_id = 'contact@maidstone-hackspace.org.uk'
google_calendar_api_key = 'AIzaSyA98JvRDmplA9lVLZeKwrs1f2k17resLy0'
if os.path.exists('config/settings_dev.py'):
print 'Using settings for dev enviroment'

View File

@ -6,6 +6,14 @@ page_menu = [
('Donate', '/donate'),
('Contact', '#mailing-list-signup')]
nav_for_authenticated_user = (
('Profile', '/profile'),
('Equipment', '/equipment'),
('Members', '/members'),
('Mailing List', '/mailing-list'),
('Logout', '/logout')
)
banner_images = [
('/static/images/banners/hackspace-banner.png', '', '', ''),
('/static/images/banners/audio_board.jpg', 'Audio board', 'Audio board', ''),

View File

@ -1,12 +1,11 @@
import os
import time
import sys
sys.path.append(os.path.abspath('../../../../scaffold/'))
sys.path.insert(0,os.path.abspath('../../../../scaffold/'))
from scaffold.core.data.select import select_data
from scaffold.core.data.insert import insert_data
from scaffold.core.data.update import update_data
from scaffold.core.data.delete import delete_data
#~ from scaffold.core.data.delete import delete_data
from scaffold.core.data.sql import query_builder
query_builder.query_path = os.path.abspath('./data/sql/')

View File

@ -1,9 +1,8 @@
import os
import time
from scaffold.core.data.select import select_data
from scaffold.core.data.insert import insert_data
from scaffold.core.data.update import update_data
from scaffold.core.data.delete import delete_data
#~ from scaffold.core.data.insert import insert_data
#~ from scaffold.core.data.update import update_data
#~ from scaffold.core.data.delete import delete_data
from scaffold.core.data.sql import query_builder
query_builder.query_path = os.path.abspath('./data/sql/')

View File

@ -1,10 +1,9 @@
import os
import time
from scaffold.core.data.select import select_data
#~ from scaffold.core.data.select import select_data
from scaffold.core.data.insert import insert_data
from scaffold.core.data.update import update_data
from scaffold.core.data.delete import delete_data
#~ from scaffold.core.data.delete import delete_data
from scaffold.core.data.sql import query_builder
query_builder.query_path = os.path.abspath('./data/sql/')
@ -12,8 +11,14 @@ query_builder.query_path = os.path.abspath('./data/sql/')
class update_description(update_data):
#~ debug = True
debug = True
table = 'user_detail'
required = {'user_id', 'description', 'skills'}
columns = {'user_id', 'description', 'skills'}
class create_description(insert_data):
debug = True
table = 'user_detail'
required = {'user_id'}
columns = {'user_id'}

View File

@ -9,15 +9,8 @@ sys.path.insert(0,os.path.abspath('../../../scaffold/'))
from scaffold import web
web.load_widgets('widgets')
from libs.rss_fetcher import feed_reader
import constants as site
import pages
from pages import web
from pages import header, footer
from pages import blog
from pages import competition
from pages import donate
from config.settings import *

View File

@ -1,10 +1,7 @@
import os
import sys
import requests
from lxml import etree
from flask import Flask
from flask import make_response
from flask.ext.login import LoginManager, login_required
sys.path.append(os.path.abspath('../../../scaffold/'))
sys.path.insert(0,os.path.abspath('../../../scaffold/'))
@ -14,8 +11,6 @@ import generate
from pages import homepage
from pages import chat
from pages import blog
from pages import competition
from pages import members
from pages.donate import donate_pages
@ -52,30 +47,6 @@ def index():
"""home page"""
return make_response(homepage.index())
#~ @login_required
#~ @web_app.route("/equipment", methods=['GET'])
#~ def equipment_view():
#~ """home page"""
#~ return make_response(equipment.index())
#~ @login_required
#~ @web_app.route("/equipment/edit/<request_id>/", methods=['GET'])
#~ def equipment_edit_view(request_id):
#~ """home page"""
#~ return make_response(equipment.edit(request_id))
#~ @login_required
#~ @web_app.route("/equipment", methods=['POST'])
#~ def equipment_submit():
#~ """home page"""
#~ equipment.insert()
#~ return make_response(equipment.index())
#~ @web_app.route("/donate/", methods=['GET'])
#~ def donate_index():
#~ """list of members"""
#~ return make_response(donate.index())
@web_app.route("/members/", methods=['GET'])
def members_index():
"""list of members"""

View File

@ -1,247 +0,0 @@
import os
import sys
import lxml
import pytz
import StringIO
import datetime
import requests
import functools
import requests.exceptions
from operator import itemgetter
from lxml import etree
from lxml.html.clean import Cleaner
namespaces = {
'openSearch': "http://a9.com/-/spec/opensearchrss/1.0/",
'blogger': "http://schemas.google.com/blogger/2008",
'rdf': "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
'slash': "http://purl.org/rss/1.0/modules/slash/",
'content': "http://purl.org/rss/1.0/modules/content/",
'taxo': "http://purl.org/rss/1.0/modules/taxonomy/",
'dc': "http://purl.org/dc/elements/1.1/",
'syn': "http://purl.org/rss/1.0/modules/syndication/",
'admin': "http://webns.net/mvcb/",
'feedburner': "http://rssnamespace.org/feedburner/ext/1.0",
'wfw': "http://wellformedweb.org/CommentAPI/",
'dc': "http://purl.org/dc/elements/1.1/",
'atom': "http://www.w3.org/2005/Atom",
'sy': "http://purl.org/rss/1.0/modules/syndication/",
'slash': "http://purl.org/rss/1.0/modules/slash/",
'atom': "http://www.w3.org/2005/Atom",
'content': "http://purl.org/rss/1.0/modules/content/",
'media': "http://search.yahoo.com/mrss/",
}
from email.utils import parsedate_tz, mktime_tz
class feed_reader:
"""parse a list of feeds and return details as dictionary data"""
#create the html cleaner, this is to clean out unwanted html tags in the description text
#page_structure=True,remove_unknown_tags=True
html_cleaner = Cleaner()
html_cleaner.javascript = True
html_cleaner.style = True
html_cleaner.remove_tags = ['script', 'iframe', 'link', 'style', 'img', 'div']
#~ html_cleaner.allow_tags = ['a', 'p', 'strong']
filter_by_date_expire = datetime.datetime.now() - datetime.timedelta(days=int(1.5*365)) # 1 and a half years ago
html_img_cleaner = Cleaner(allow_tags=['img'], remove_unknown_tags=False)
html_img_cleaner.allow_tags = ['img']
html_parser = lxml.etree.HTMLParser()
xml_parser = lxml.etree.XMLParser(remove_blank_text=True, ns_clean=True, encoding='utf-8')
enable_date_filter = True
def __init__(self, feed_details, timeout=5):
self.results = {}
for feed_info in feed_details:
self.url = feed_info.get('url')
self.author = feed_info.get('author')
self.tags = feed_info.get('tags')
if feed_info.get('url').startswith('http:'):
try:
response = requests.get(feed_info.get('url'), stream=True, timeout=timeout)
except requests.exceptions.Timeout as e:
continue
if response.headers.get('content-encoding') == 'gzip':
response.raw.read = functools.partial(response.raw.read, decode_content=True)
try:
self.feed = lxml.etree.parse(response.raw, self.xml_parser)
except:
continue
else:
with open(os.path.abspath(feed_info.get('url')), 'r') as file_stream:
try:
self.feed = lxml.etree.parse(file_stream, self.xml_parser)
except:
continue
self.feed = self.feed.getroot()
# rss feed defaults
self.channel_image = self.fetch_node_text(self.feed, 'channel/image/url', '')
self.parse_feed()
def convert_rfc822_to_datetime(self, rfcdate):
"""rss uses rfc822 dates so lets convert them to datetime for use later"""
if len(rfcdate):
parsed_rfcdate = parsedate_tz(rfcdate)
if not parsed_rfcdate:
return None
return datetime.datetime.fromtimestamp(
mktime_tz(parsed_rfcdate), pytz.utc).replace(tzinfo=None)
return None
def clean_up_text(self, text):
"""strip out any dirty tags like <script> they may break the sites"""
if text is None:
return ''
cleaned_html = self.html_cleaner.clean_html(text)
# parse large text seperately
if len(text) > 600:
description = lxml.etree.parse(StringIO.StringIO(cleaned_html), self.html_parser)
root = description.getroot()
build = ''
for node in root[-1][-1].iter():
#skip any nodes with no text
if node.text is None and node.tail is None:
continue
# we may want to do some other node checks here
# perhaps count paragraphs, html layout changes a lot
if node.tag == 'br':
return build
else:
if node.tag == 'a' and node.text is None:
build += node.tail
else:
build += etree.tostring(node)
return self.html_cleaner.clean_html(text)
def fetch_image_from_node_text(self, text):
description = lxml.etree.parse(StringIO.StringIO(text), self.html_parser)
for image in description.xpath('.//img'):
return image.get('src')
return None
def fetch_image(self, node):
"""Try and get an image from an item in the feed, use various fall back methods"""
image = node.xpath('media:thumbnail', namespaces=namespaces)
if image:
return image[0].get('url', '')
# no media:thumbnail so lets try and grab an image from content:encoded
image = node.xpath('content:encoded', namespaces=namespaces)
if image:
image = self.fetch_image_from_node_text(image[0].text)
if image:
return image
# final attempt at getting an image from the item using description
result = self.fetch_node_text(node, 'description')
if result:
image = self.fetch_image_from_node_text(result)
if image:
return image
# no image so lets fall back to the channel image if it exists
return self.channel_image
def fetch_node_text(self, node, name, default=''):
"""fetch the text from the node we are given, we are working in unicode
so decode byte strings to unicode"""
result = node.xpath('./%s' % name)
if result is None or len(result) is 0:
return default
if type(result[-1].text) is str:
return result[-1].text.decode('utf8')
else:
return result[-1].text
def fetch_node_attribute(self, node, name, attribs, default):
result = node.xpath('./%s' % name)
if result:
return result.get(attribs, '')
else:
return default
def format_author(self, author):
"""extract the authors name from the author text node"""
return author.split('(')[-1].strip(')')
def filter_by_tags(self, node, tags=None):
"""filter the feed out by category tag, if no tags assume its pre filtered"""
if self.tags is None:
return True
for category in node.xpath('./category', namespaces=namespaces):
if category.text.lower() in self.tags:
return True
return False
def filter_by_date(self, date):
"""filter the feed out by date"""
if self.enable_date_filter is False:
return True
if date > self.filter_by_date_expire:
return True
return False
def parse_feed(self):
"""Parse the items in the feed, filter out bad data and put in defaults"""
for item in self.feed.xpath('.//item', namespaces=namespaces):
date = self.convert_rfc822_to_datetime(self.fetch_node_text(item, 'pubDate'))
if self.filter_by_date(date) and self.filter_by_tags(item):
author = self.format_author(self.fetch_node_text(item, 'author', self.author))
self.results.setdefault(author, []).append({
#~ self.results.append({
'title': self.fetch_node_text(item, 'title'),
'date': date,
'url': self.fetch_node_text(item, 'link'),
'author': author,
'image': self.fetch_image(item),
'description': self.clean_up_text(self.fetch_node_text(item, 'description'))})
#order authors articles by date
for author in self.results.keys():
self.results[author] = sorted(self.results[author], key=itemgetter('date'), reverse=True)
def alternate_dict_and_sort_by_list_item_key(self, dict_of_lists, sort_key='date'):
""" take a dictonary of ordered lists, step through each row and sort the current
item position in each list and yield the result.
basically gives the ordering of date while stepping through the blog entries to make it fair
for people who do not blog often. """
longest_list_length = max([len(dict_of_lists[d]) for d in dict_of_lists.keys()])
for i in xrange(0, longest_list_length):
#get first value from each key, and order the list
results = sorted([d.pop() for d in dict_of_lists.values() if d], key=itemgetter(sort_key), reverse=True)
for item in results:
yield item
def __iter__(self):
"""return results ordered by date"""
for author in self.alternate_dict_and_sort_by_list_item_key(self.results):
yield author
if __name__ == "__main__":
rss_tests = [
{'author': 'Mike McRoberts', 'url': './rss_invalid.xml'},
{'author': 'Mike McRoberts', 'url': './rss_no_tags.xml'}]
test = feed_reader(rss_tests)

View File

@ -6,7 +6,6 @@ from config import settings
from scaffold.core.data.database import db
print settings.database
db.config(settings.database)
from scaffold.core.data import migrations
from scaffold.core.data.migrations import export_schema, import_schema
export_schema()

View File

@ -1,7 +1,5 @@
import os
import sys
from libs.rss_fetcher import feed_reader
from scaffold.web import webpage as html
@ -56,10 +54,11 @@ def header(title, description='Maidstone Hackspace is a shared space where artis
if current_user and current_user.is_authenticated:
web.menu.append('logout', '/logout')
web.navigation_bar.create(hide=(False if url=='/profile' else True))
web.navigation_bar.append('Profile', '/profile')
web.navigation_bar.append('Equipment', '/equipment')
web.navigation_bar.append('Members', '/members')
web.navigation_bar.append('Mailing List', '/mailing-list')
web.navigation_bar * site.nav_for_authenticated_user
#~ web.navigation_bar.append('Profile', '/profile')
#~ web.navigation_bar.append('Equipment', '/equipment')
#~ web.navigation_bar.append('Members', '/members')
#~ web.navigation_bar.append('Mailing List', '/mailing-list')
web.template.body.append(web.navigation_bar.render())
else:
web.menu.append('login', '/login')

View File

@ -1,7 +1,3 @@
import constants as site
from libs.rss_fetcher import feed_reader
from pages import web
from pages import header, footer

View File

@ -1,7 +1,3 @@
import constants as site
from libs.rss_fetcher import feed_reader
from pages import web
from pages import header, footer
@ -9,8 +5,6 @@ from pages import header, footer
def index():
web.template.create('Maidstone Hackspace - Chat room')
header('Maidstone Hackspace Chat')
#web.template.body.append(web.header_strip.create({}).render())
#web.template.body.append(web.menu.render())
web.page.create(web.title.create('IRC Chat Room').render())
web.page.create(web.paragraph.create('Pop in and say hi, please be patient users tend to idle, but will likely respond given a chance.').render())
web.page.section(web.chat.create('maidstone-hackspace').render())

View File

@ -1,7 +1,3 @@
import constants as site
from libs.rss_fetcher import feed_reader
from pages import web
from pages import header, footer

View File

@ -1,12 +1,8 @@
import sys
from flask import session
from flask import request
from flask import Blueprint
from flask import make_response
from flask.ext.login import current_user, login_required
import constants as site
from libs.rss_fetcher import feed_reader
from pages import web
from pages import header, footer
from data import equipment

View File

@ -1,7 +1,3 @@
import constants as site
from libs.rss_fetcher import feed_reader
from pages import web
from pages import header, footer

View File

@ -1,8 +1,4 @@
import constants as site
from libs.rss_fetcher import feed_reader
from pages import web
#~ from pages import web
from pages import header, footer

View File

@ -1,15 +1,8 @@
from flask import session
from flask import request
from flask import Blueprint
from flask import make_response
from flask.ext.login import current_user, login_required
import constants as site
from flask.ext.login import login_required
from libs.rss_fetcher import feed_reader
from pages import web
from pages import header, footer
from data import equipment
google_groups_pages = Blueprint('google_group', __name__, template_folder='templates')

View File

@ -1,6 +1,10 @@
import constants as site
from libs.rss_fetcher import feed_reader
#~ from config.settings import *
from config.settings import google_calendar_id, google_calendar_api_key
from scaffold.readers.rss_reader import feed_reader
#~ from libs.rss_fetcher import feed_reader
from scaffold import web
#~ from pages import web
from pages import header, footer
@ -12,16 +16,12 @@ def index():
web.page.create('')
web.page.section(
web.div.create(
web.google_calendar.create().render()
#~ web.images.create(
#~ web.template.uri.add_domain(site.tile_images[0][0])
#~ ).append(
#~ web.template.uri.add_domain(site.tile_images[1][0])
#~ ).render()
web.google_calendar.create(
calendar_id=google_calendar_id,
api_key=google_calendar_api_key).render()
).set_classes('tile-right tile-image').render())
web.banner_slider.reset()
web.banner_slider * site.banner_images
web.page.append(web.banner_slider.render())
web.page.section(web.title.create('Introduction').render())
@ -48,8 +48,9 @@ def index():
web.list * bullet_list
web.page.append(web.list.render())
web.div.create('').set_classes('panel')
#~ web.div.create('').set_classes('panel')
# fetch the rss feeds from the various blogs for the homepage
web.columns.create()
feed = feed_reader(site.rss_feeds)
for row in feed:

View File

@ -1,9 +1,5 @@
from flask import session
from flask import request
from flask.ext.login import current_user, login_required
import constants as site
from flask.ext.login import login_required
from libs.rss_fetcher import feed_reader
from pages import web
from pages import header, footer
from data import members
@ -16,9 +12,7 @@ def index():
web.page.create('Members')
web.member_tiles.create()
for item in members.get_members():
print item
name = '%s %s' % (item.get('first_name'), item.get('last_name'))
user_id = '%s %s' % (item.get('first_name'), item.get('last_name'))
web.member_tiles.append(
name = name,
image = item.get('profile_image'),

View File

@ -1,17 +1,14 @@
from flask import session
from flask import Blueprint
from flask import request
from flask import redirect, abort
from flask import redirect
from flask.ext.login import current_user, login_required
import constants as site
import gocardless
from libs.rss_fetcher import feed_reader
from pages import web
from pages import header, footer
from data.site_user import get_user_details
from data.profile import update_description
from config.settings import gocardless_enviroment, gocardless_credentials
from data.profile import update_description, create_description
from config.settings import gocardless_environment, gocardless_credentials
profile_pages = Blueprint('profile_pages', __name__, template_folder='templates')
@ -37,8 +34,11 @@ def index():
web.paragraph.add('Last Login %s' % (user.get('last_login', '')))
web.paragraph.add('Member since %s' % (user.get('created', '')))
web.paragraph.add('Description %s' % (user.get('description', '')))
web.paragraph.add('Skills %s' % (user.get('skills', '')))
web.columns.append(web.paragraph.render())
web.columns.append(web.member_card.create(str(user.get('user_id')).zfill(5), name).render())
web.paragraph.create(
web.link.create(
'Edit Description',
@ -51,10 +51,12 @@ def index():
#~ web.form.render()
web.columns.append(web.paragraph.render())
web.columns.append(web.member_card.create(str(user.get('user_id')).zfill(5), name).render())
web.page.section(web.columns.render())
web.template.body.append(web.page.render())
web.template.body.append(web.popup.create('').render())
web.template.body.append('<script type="type/javascript">document.cookie = "status=1";</script>')
return footer()
@ -76,10 +78,14 @@ def pay_membership():
@profile_pages.route("/profile/details", methods=['GET'])
@login_required
def edit_profile():
user = get_user_details({'id': current_user.get_id()}).get()
user_details = get_user_details({'id': current_user.get_id()}).get() or {}
print user_details
if not user_details:
print 'create'
create_description().execute({'user_id': current_user.get_id()})
web.form.create('Update your details', '/profile/update')
web.form.append(name='description', label='Description', placeholder='This is me i am great')
web.form.append(name='skills', label='skills', placeholder='python, arduino, knitting')
web.form.append(name='description', label='Description', placeholder='This is me i am great', value=user_details.get('description'))
web.form.append(name='skills', label='skills', placeholder='python, arduino, knitting', value=user_details.get('skills'))
return web.form.render()

View File

@ -1,5 +1,6 @@
table_name, column_name, column_type, default
#members
ALTER TABLE members ADD INDEX user_id_UNIQUE (user_id ASC);
#pledges
@ -8,26 +9,27 @@ ALTER TABLE pledges ADD INDEX id_UNIQUE (id ASC);
#pledge_amounts
ALTER TABLE pledge_amounts ADD INDEX id_UNIQUE (id ASC);
ALTER TABLE pledge_amounts ADD UNIQUE INDEX reference_UNIQUE (reference ASC);
#requests
ALTER TABLE requests ADD INDEX id_UNIQUE (id ASC);
#users
ALTER TABLE users ADD INDEX id_UNIQUE (id ASC);
ALTER TABLE users ADD INDEX member_reference_UNIQUE (member_reference ASC);
ALTER TABLE users ADD INDEX email_UNIQUE (email ASC);
ALTER TABLE users ADD UNIQUE INDEX email_UNIQUE (email ASC);
#user_detail
ALTER TABLE user_detail ADD INDEX id_UNIQUE (id ASC);
ALTER TABLE user_detail ADD INDEX user_id_UNIQUE (user_id ASC);
ALTER TABLE user_detail ADD INDEX member_id_UNIQUE (member_id ASC);
ALTER TABLE user_detail ADD UNIQUE INDEX user_id_UNIQUE (user_id ASC);
ALTER TABLE user_detail ADD UNIQUE INDEX member_id_UNIQUE (member_id ASC);
#user_password_reset
ALTER TABLE user_password_reset ADD INDEX id_UNIQUE (id ASC);
ALTER TABLE user_password_reset ADD INDEX user_id_UNIQUE (user_id ASC);
ALTER TABLE user_password_reset ADD INDEX password_UNIQUE (reset_code ASC);
ALTER TABLE user_password_reset ADD UNIQUE INDEX password_UNIQUE (reset_code ASC);
ALTER TABLE user_password_reset ADD UNIQUE INDEX user_id_UNIQUE (user_id ASC);

View File

@ -1,16 +1,20 @@
table_name, column_name, column_type, default
#members
ALTER TABLE members ADD COLUMN id int(5) unsigned zerofill PRIMARY KEY (`id`) ;
ALTER TABLE members CHANGE COLUMN id id int(5) unsigned zerofill PRIMARY KEY (`id`) ;
ALTER TABLE members ADD COLUMN id int(4) unsigned zerofill PRIMARY KEY (`id`) AUTO_INCREMENT ;
ALTER TABLE members CHANGE COLUMN id id int(4) unsigned zerofill PRIMARY KEY (`id`) AUTO_INCREMENT ;
ALTER TABLE members ADD COLUMN user_id varchar(45) NULL ;
ALTER TABLE members CHANGE COLUMN user_id user_id varchar(45) NULL ;
#pledges
ALTER TABLE pledges ADD COLUMN expired tinyint(1) NULL DEFAULT 0;
ALTER TABLE pledges CHANGE COLUMN expired expired tinyint(1) NULL DEFAULT 0;
ALTER TABLE pledges ADD COLUMN id int(10) unsigned PRIMARY KEY (`id`) AUTO_INCREMENT ;
ALTER TABLE pledges CHANGE COLUMN id id int(10) unsigned PRIMARY KEY (`id`) AUTO_INCREMENT ;
ALTER TABLE pledges ADD COLUMN name varchar(255) NULL ;
ALTER TABLE pledges CHANGE COLUMN name name varchar(255) NULL ;
ALTER TABLE pledges ADD COLUMN target decimal(10,2) unsigned NULL DEFAULT 0.00;
ALTER TABLE pledges CHANGE COLUMN target target decimal(10,2) unsigned NULL DEFAULT 0.00;
ALTER TABLE pledges ADD COLUMN total decimal(10,2) NULL DEFAULT 0.00;
ALTER TABLE pledges CHANGE COLUMN total total decimal(10,2) NULL DEFAULT 0.00;
@ -18,10 +22,12 @@ ALTER TABLE pledges CHANGE COLUMN total total decimal(10,2) NULL DEFAULT 0.00;
#pledge_amounts
ALTER TABLE pledge_amounts ADD COLUMN amount decimal(10,2) NULL ;
ALTER TABLE pledge_amounts CHANGE COLUMN amount amount decimal(10,2) NULL ;
ALTER TABLE pledge_amounts ADD COLUMN environment tinyint(1) NULL DEFAULT 0;
ALTER TABLE pledge_amounts CHANGE COLUMN environment environment tinyint(1) NULL DEFAULT 0;
ALTER TABLE pledge_amounts ADD COLUMN id int(10) unsigned PRIMARY KEY (`id`) AUTO_INCREMENT ;
ALTER TABLE pledge_amounts CHANGE COLUMN id id int(10) unsigned PRIMARY KEY (`id`) AUTO_INCREMENT ;
ALTER TABLE pledge_amounts ADD COLUMN pledge_id varchar(20) NULL ;
ALTER TABLE pledge_amounts CHANGE COLUMN pledge_id pledge_id varchar(20) NULL ;
ALTER TABLE pledge_amounts ADD COLUMN pledge_id int(10) NULL ;
ALTER TABLE pledge_amounts CHANGE COLUMN pledge_id pledge_id int(10) NULL ;
ALTER TABLE pledge_amounts ADD COLUMN reference varchar(255) NULL ;
ALTER TABLE pledge_amounts CHANGE COLUMN reference reference varchar(255) NULL ;
@ -35,10 +41,12 @@ ALTER TABLE requests ADD COLUMN name varchar(45) NULL ;
ALTER TABLE requests CHANGE COLUMN name name varchar(45) NULL ;
ALTER TABLE requests ADD COLUMN price decimal(10,2) NULL ;
ALTER TABLE requests CHANGE COLUMN price price decimal(10,2) NULL ;
ALTER TABLE requests ADD COLUMN quantity int(11) NULL DEFAULT 1;
ALTER TABLE requests CHANGE COLUMN quantity quantity int(11) NULL DEFAULT 1;
ALTER TABLE requests ADD COLUMN url varchar(255) NULL ;
ALTER TABLE requests CHANGE COLUMN url url varchar(255) NULL ;
ALTER TABLE requests ADD COLUMN user_id int(10) unsigned ;
ALTER TABLE requests CHANGE COLUMN user_id user_id int(10) unsigned ;
ALTER TABLE requests ADD COLUMN user_id int(10) unsigned NULL ;
ALTER TABLE requests CHANGE COLUMN user_id user_id int(10) unsigned NULL ;
#users
@ -48,39 +56,41 @@ ALTER TABLE users ADD COLUMN email varchar(255) NULL ;
ALTER TABLE users CHANGE COLUMN email email varchar(255) NULL ;
ALTER TABLE users ADD COLUMN first_name varchar(45) NULL ;
ALTER TABLE users CHANGE COLUMN first_name first_name varchar(45) NULL ;
ALTER TABLE users ADD COLUMN id int(10) unsigned PRIMARY KEY (`id`) ;
ALTER TABLE users CHANGE COLUMN id id int(10) unsigned PRIMARY KEY (`id`) ;
ALTER TABLE users ADD COLUMN id int(10) unsigned PRIMARY KEY (`id`) AUTO_INCREMENT ;
ALTER TABLE users CHANGE COLUMN id id int(10) unsigned PRIMARY KEY (`id`) AUTO_INCREMENT ;
ALTER TABLE users ADD COLUMN last_login varchar(45) NULL ;
ALTER TABLE users CHANGE COLUMN last_login last_login varchar(45) NULL ;
ALTER TABLE users ADD COLUMN last_name varchar(45) NULL ;
ALTER TABLE users CHANGE COLUMN last_name last_name varchar(45) NULL ;
ALTER TABLE users ADD COLUMN member_reference int(5) unsigned zerofill AUTO_INCREMENT ;
ALTER TABLE users CHANGE COLUMN member_reference member_reference int(5) unsigned zerofill AUTO_INCREMENT ;
ALTER TABLE users ADD COLUMN memberid varchar(45) NULL ;
ALTER TABLE users CHANGE COLUMN memberid memberid varchar(45) NULL ;
ALTER TABLE users ADD COLUMN password varchar(160) NULL ;
ALTER TABLE users CHANGE COLUMN password password varchar(160) NULL ;
ALTER TABLE users ADD COLUMN profile_image varchar(255) NULL ;
ALTER TABLE users CHANGE COLUMN profile_image profile_image varchar(255) NULL ;
ALTER TABLE users ADD COLUMN status tinyint(2) NULL DEFAULT 0;
ALTER TABLE users CHANGE COLUMN status status tinyint(2) NULL DEFAULT 0;
ALTER TABLE users ADD COLUMN username varchar(25) ;
ALTER TABLE users CHANGE COLUMN username username varchar(25) ;
ALTER TABLE users ADD COLUMN team_id int(11) NULL DEFAULT 0;
ALTER TABLE users CHANGE COLUMN team_id team_id int(11) NULL DEFAULT 0;
ALTER TABLE users ADD COLUMN username varchar(25) NULL ;
ALTER TABLE users CHANGE COLUMN username username varchar(25) NULL ;
#user_detail
ALTER TABLE user_detail ADD COLUMN description text NULL ;
ALTER TABLE user_detail CHANGE COLUMN description description text NULL ;
ALTER TABLE user_detail ADD COLUMN id int(11) PRIMARY KEY (`id`) ;
ALTER TABLE user_detail CHANGE COLUMN id id int(11) PRIMARY KEY (`id`) ;
ALTER TABLE user_detail ADD COLUMN id int(11) PRIMARY KEY (`id`) AUTO_INCREMENT ;
ALTER TABLE user_detail CHANGE COLUMN id id int(11) PRIMARY KEY (`id`) AUTO_INCREMENT ;
ALTER TABLE user_detail ADD COLUMN image varchar(45) NULL ;
ALTER TABLE user_detail CHANGE COLUMN image image varchar(45) NULL ;
ALTER TABLE user_detail ADD COLUMN member_id int(5) unsigned zerofill ;
ALTER TABLE user_detail CHANGE COLUMN member_id member_id int(5) unsigned zerofill ;
ALTER TABLE user_detail ADD COLUMN member_id int(5) unsigned zerofill NULL ;
ALTER TABLE user_detail CHANGE COLUMN member_id member_id int(5) unsigned zerofill NULL ;
ALTER TABLE user_detail ADD COLUMN profile_image varchar(255) NULL ;
ALTER TABLE user_detail CHANGE COLUMN profile_image profile_image varchar(255) NULL ;
ALTER TABLE user_detail ADD COLUMN skills varchar(255) NULL ;
ALTER TABLE user_detail CHANGE COLUMN skills skills varchar(255) NULL ;
ALTER TABLE user_detail ADD COLUMN user_id int(11) unsigned ;
ALTER TABLE user_detail CHANGE COLUMN user_id user_id int(11) unsigned ;
ALTER TABLE user_detail ADD COLUMN user_id int(11) unsigned NULL ;
ALTER TABLE user_detail CHANGE COLUMN user_id user_id int(11) unsigned NULL ;
#user_password_reset
@ -88,9 +98,9 @@ ALTER TABLE user_password_reset ADD COLUMN created timestamp NULL DEFAULT CURREN
ALTER TABLE user_password_reset CHANGE COLUMN created created timestamp NULL DEFAULT CURRENT_TIMESTAMP;
ALTER TABLE user_password_reset ADD COLUMN id int(11) PRIMARY KEY (`id`) AUTO_INCREMENT ;
ALTER TABLE user_password_reset CHANGE COLUMN id id int(11) PRIMARY KEY (`id`) AUTO_INCREMENT ;
ALTER TABLE user_password_reset ADD COLUMN reset_code varchar(160) ;
ALTER TABLE user_password_reset CHANGE COLUMN reset_code reset_code varchar(160) ;
ALTER TABLE user_password_reset ADD COLUMN user_id int(11) ;
ALTER TABLE user_password_reset CHANGE COLUMN user_id user_id int(11) ;
ALTER TABLE user_password_reset ADD COLUMN reset_code varchar(160) NULL ;
ALTER TABLE user_password_reset CHANGE COLUMN reset_code reset_code varchar(160) NULL ;
ALTER TABLE user_password_reset ADD COLUMN user_id int(11) NULL ;
ALTER TABLE user_password_reset CHANGE COLUMN user_id user_id int(11) NULL ;

View File

@ -2,25 +2,48 @@ html {background-color:#fff;height:100%;font-family:'Arial';font-size:18px;}
body {margin:0px;padding:0px;}
form button {margin:none;}
a {color:#fff;}
li p {margin: 20px 0px 0px 30px;}
li p {margin: 20px 0px 0px 30px;height:45px;}
fieldset {margin:20px;}
label {margin:20px;color:#fff;}
input {float:right;margin:0px;color:#000;padding:10px;}
fieldset p {margin: 20px 0px 0px 0px;height:45px;}
label {color:#fff;text-align:left;}
input {line-height:45px;float:right;margin:0px;color:#000;padding-left:10px;}
select {float:right;margin:0px;color:#000;padding:10px;}
p {margin:25px;line-height:150%;}
h2 {margin-left:25px;color:#fff;}
h3 {color:#fff;}
li {padding-bottom:10px;line-height:150%;}
/*
input {margin:0px;margin-bottom:20px;padding:10px;}
*/
button {margin-top:20px;background-color: #fff; height: 48px; width:100%; border-radius: 3px;box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.2);}
button {margin-top:20px;background-color: #fff; height: 48px; width:100%; border-radius: 3px;box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.2);
border:1px solid #000a0d; -webkit-border-radius: 3px; -moz-border-radius: 3px;border-radius: 3px;
font-size:12px;font-family:arial, helvetica, sans-serif; font-weight:bold;
padding: 10px 10px 10px 10px;
text-decoration:none;
/*
display:inline-block;
*/
text-shadow: -1px -1px 0 rgba(0,0,0,0.3);color: #FFFFFF;
background-color: #003645; background-image: -webkit-gradient(linear, left top, left bottom, from(#003645), to(#00232D));
background-image: -webkit-linear-gradient(top, #003645, #00232D);
background-image: -moz-linear-gradient(top, #003645, #00232D);
background-image: -ms-linear-gradient(top, #003645, #00232D);
background-image: -o-linear-gradient(top, #003645, #00232D);
}
.left {float:left;}
.right {float:right;}
.bottom {position:absolute;bottom:0px;}
.full_width {left:0px;right:0px;}
.hide {display:none;}
#ajaxPopup {position:absolute;width:750px;height:550px;background-color:#fff;top:68px;left:50%;margin-left: -375px;}
#ajaxPopup {position:absolute;width:750px;height:550px;background-color:#fff;top:68px;left:50%;margin-left: -375px;box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.2);background-color:#93B1C6;}
#ajaxPopup legend {width:720px;padding:15px;color:#fff;background-color:#000;margin:0px;}
#ajaxPopup fieldset {border:0px;margin:0px;padding:0px;}
#ajaxPopup label {width:160px;color:#000;}
#ajaxPopup p {position:relative;}
#ajaxPopup input {position:absolute;left:160px;}
#ajaxPopup label {width:160px;color:#000;line-height:48px;}
#ajaxPopup p {margin:20px;}
#ajaxPopup input {width:50%;}
#ajaxPopup button {position:absolute;bottom:0px;}
@ -66,10 +89,7 @@ tbody tr:nth-child(odd) {
/* new styles */
.copyright {float:right;margin-top:20px;color:#fff;}
p {margin:25px;line-height:150%;}
h2 {margin-left:25px;color:#fff;}
h3 {color:#fff;}
li {padding-bottom:10px;line-height:150%;}
.tile-right {margin-top:20px;width:230px;float:right;margin-right:20px;}
@ -77,7 +97,8 @@ li {padding-bottom:10px;line-height:150%;}
.tile-image {float:right;clear:right;}
#headerstrip{position:absolute;left:0px;right:0px;height:68px;top:0px;background-color:#00232D;}
#headerstrip .navstrip{margin:10px;height:48px;}
#headerstrip .mini-logo-text{position:absolute;padding-top: 12px;font-size:22px;color:#fff;font-weight:bold;padding-left:10px;}
#headerstrip .mini-logo-text{position:absolute;left:56px;padding-top: 12px;font-size:22px;color:#fff;font-weight:bold;padding-left:10px;}
#headerstrip .mini_logo{position:absolute;width:48px;height:48px;}
#headerstrip .mini-logo:hover{
transition:ease-in-out;
-webkit-transform-origin: 50% 50%;
@ -110,8 +131,8 @@ height:48px;width:48px; -webkit-animation:spin 2s linear infinite ;-moz-animatio
.columns{float:right;clear:right;width:460px;margin-left:20px;margin-bottom:20px;}
.google-groups-signup {width:300px;float:left;}
.google-groups-signup input{width:274px;}
.google-groups-signup a{color:#fff;}
.google-groups-signup input{margin-top:20px;width:282px;}
.google-groups-signup a{color:#fff;width:282px;}
.banner-slide {position:absolute;width:700px;margin:20px;}
.banner-slide ul{position:relative;overflow:hidden;width:700px;height:300px;margin:0px;}
@ -193,9 +214,9 @@ height:48px;width:48px; -webkit-animation:spin 2s linear infinite ;-moz-animatio
.members .tile{ width:220px;float:left;}
.members .tile-img{margin:10px;width:200px;}
#member_navigation {position:absolute;top:68px;left:0px;width:200px;height:100%;background-color:#0087A8;}
#member_navigation a {color:#fff;font-weight:bold;}
#member_navigation ul {padding:0px;}
#member_navigation {z-index:2;position:fixed;top:68px;left:0px;width:180px;height:100%;}
#member_navigation a {color:#ffffff;font-weight:bold;text-decoration:none;}
#member_navigation ul {padding:0px;margin:0px;box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.26);}
#member_navigation li {margin:0px;padding:10px;background-color:#0087A8;list-style-type: none;}
#member_navigation li:hover {background-color:#E7EAEF;}
@ -216,19 +237,15 @@ height:48px;width:48px; -webkit-animation:spin 2s linear infinite ;-moz-animatio
width: 430px;
height: 240px;
margin-left:20px;
/*
line-height: 240px;
*/
text-align: center;
position:relative;
}
#membercard .date {position:absolute;margin:25px;top:0px;left:0px;}
#membercard .container {position:relative;top:50%; width:100%;}
#membercard .middle {position:absolute;top:-60px;width:100%;}
#membercard p {margin:0px;}
#membercard label {color:#000;}
#membercard legend {margin:10px;}
#membercard fieldset {margin:20px;border:0px;}
#membercard label {color:#000;text-align:left;line-height:48px;}
#membercard legend {margin-top:10px;margin-bottom:10px;font-weight:strong;}
#membercard fieldset {position:absolute;top:0px;left:0px;right:0px;padding:0px;margin:28px;border:0px;}
.calendar {width:230px;height:300px;overflow:auto;}
.calendar ul{list-style:none;padding:0px;margin:0px;}

View File

@ -1,5 +1,5 @@
from scaffold.core.widget import base_widget_extended
import requests
class control(base_widget_extended):
link = None

View File

@ -1,6 +1,4 @@
import os
from scaffold import web
from scaffold.loaders import load
from scaffold.readers.markdown_reader import markdown_reader
from scaffold.core.widget import base_widget

View File

@ -2,9 +2,10 @@ from scaffold.core.widget import base_widget
class control(base_widget):
def create(self, title, url, method='post', enctype="", button='submit'):
def create(self, title, url, method='post', enctype="", button='submit', seperator=','):
self.title = title
self.url = url
self.seperator = seperator
self.method = method
self.button = button
self.enctype = enctype
@ -24,8 +25,16 @@ class control(base_widget):
if input_type == 'hidden':
htm+='<input type="hidden" name="%s" value="%s">' % (name, value)
continue
if input_type == 'select':
htm += '<p><label for="%s">%s<select name="%s">' % (name, label, name)
for item in placeholder.split(self.seperator):
htm += '<option value="%s" %s>%s</option>' % (
item,
'selected="selected"' if item==value else '',
item)
htm += '</select></label></p>'
continue
htm+='<p><label for="%s">%s<input type="%s" name="%s" placeholder="%s" value="%s"></label></p>' % (name, label, input_type ,name, placeholder, value)
htm+='<button type="submit">%s</button>' % self.button
htm+='<p class="bottom full_width"><button type="submit">%s</button></p>' % self.button
htm+='</fieldset></form>'
return htm

View File

@ -7,19 +7,27 @@ class control(base_widget_extended):
contents = []
def create(self, title="Events", calendar_id=None, api_key=None):
super(control, self).create()
url = 'https://www.googleapis.com/calendar/v3/calendars/%s/events?singleEvents=true&maxResults=2&timeMin=%s&key=%s' % (
calendar_id,
datetime.now().strftime('%Y-%m-%dT%H:%M:%S-00:00'),
api_key)
print url
date_now = datetime.now().strftime('%Y-%m-%dT%H:%M:%S-00:00')
print date_now
response = requests.get('https://www.googleapis.com/calendar/v3/calendars/contact@maidstone-hackspace.org.uk/events?singleEvents=true&maxResults=2&timeMin=%s&key=AIzaSyA98JvRDmplA9lVLZeKwrs1f2k17resLy0' % date_now)
calendar_data = response.json()
self.contents = []
print calendar_data
# loop over calendar results, and format for display
for event in calendar_data.get('items'):
str_datetime = time.strptime(event.get('start').get('dateTime'), '%Y-%m-%dT%H:%M:%SZ')
formatted_date = time.strftime('%d %b %Y %H:%M', str_datetime)
description = event.get('description') + '<br />' if event.get('description') else ''
location = '<a target="_blank" href="https://www.google.co.uk/maps/search/%s">%s</a>' % (event.get('location'), event.get('location')) if event.get('location') else ''
location = '<a target="_blank" href="https://www.google.co.uk/maps/search/%s">%s</a>' % (
event.get('location'), event.get('location')) if event.get('location') else ''
self.contents.append((
event.get('summary')+ '<br />', description, formatted_date+ '<br />' +location))
event.get('summary')+ '<br />',
description,
formatted_date + '<br />' + location))
return self
def render(self):

View File

@ -35,7 +35,7 @@ class control(base_widget):
if self.twitter_script is False:
self.twitter_script = True
self.footer.append("""
<script><!--//--><![CDATA[//><!--!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');\n//]]></script>""")
<script><!--//--><![CDATA[//><!--!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'http://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');\n//]]></script>""")
if linkedin is not None:
if self.linkedin_script is False:
@ -54,7 +54,7 @@ class control(base_widget):
self.count += 1
htm = ''
if self.twitter:
htm += '<div class="btn"><a href="https://twitter.com/share" class="twitter-share-button" data-via="%s">Tweet</a></div>' % self.twitter
htm += '<div class="btn"><a href="https://twitter.com/share" class="twitter-share-button" data-via="%s">Tweet</a></div>' % self.url
if self.facebook:
htm += '<div class="btn"><div class="fb-share-button" data-href="%s" data-layout="button_count"></div></div>' % self.url
if self.linkedin:

View File

@ -24,7 +24,7 @@ class control(base_widget):
htm += u'<div class="tile-img" style="background:center no-repeat url(%s);background-size:contain;"></div>' % project.get('image')
else:
htm += u'<div class="tile-img"></div>'
htm += u'<header class="tile-content"><h2><a href="%s/%s">%s</a> Skills in %s</h2></header>' % (
htm += u'<header class="tile-content"><h2><a href="%s/%s">%s</a> Skilled in %s</h2></header>' % (
project.get('link'), project.get('name'), project.get('name'), project.get('skills'))
htm += u'<div class="tile-content"><p>%s</p></div>' % (project.get('description'))
htm += u'</div>'

View File

@ -25,5 +25,4 @@ class control(base_widget):
<label>Confirm Password</label><input id="password" name="password_confirm" type="password"/>
<input type="Update" value="password_change"/>
</form>'''
return htm

View File

@ -1,5 +1,5 @@
from scaffold.core.widget import base_widget_extended
import requests
class control(base_widget_extended):
link = None

View File

@ -1,4 +1,3 @@
from config import settings
from index import web_app as application
if __name__ == "__main__":