Skip to content

Commit

Permalink
Rewrite requests
Browse files Browse the repository at this point in the history
Rewrite the request infrastructure to facilitate more interation and to
intrinsically enforce some of our policies (must sell at known store, must
provide URL if you can, etc).

This also moves requests to logged-in users only, which should help following
through on confusing requests.
  • Loading branch information
ppannuto committed Jun 1, 2016
1 parent bce3b1d commit 2804a0f
Show file tree
Hide file tree
Showing 26 changed files with 610 additions and 150 deletions.
16 changes: 10 additions & 6 deletions chezbetty/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,10 @@ def debug(request):
config.add_route('shame', '/shame')
config.add_route('shame_csv', '/shame.csv')

config.add_route('items', '/items')
config.add_route('item_request', '/item/request')
config.add_route('item_request_new', '/item/request/new')
config.add_route('items', '/items')

config.add_route('paydebt', '/paydebt/{uniqname}')
config.add_route('paydebt_submit', '/paydebt/{uniqname}/submit')
config.add_route('paydebt', '/paydebt/{uniqname}')
config.add_route('paydebt_submit', '/paydebt/{uniqname}/submit')


# TERMINAL VIEWS
Expand Down Expand Up @@ -139,6 +137,10 @@ def debug(request):
config.add_route('user_deposit_cc_custom', '/user/deposit_cc/custom')
config.add_route('user_deposit_cc_submit', '/user/deposit_cc/submit')

config.add_route('user_item_request', '/user/item/request')
config.add_route('user_item_request_new', '/user/item/request/new')
config.add_route('user_item_request_post_new', '/user/item/request/{id}/post/new')

config.add_route('user_pools', '/user/pools')
config.add_route('user_pools_new_submit', '/user/pools/new/submit')
config.add_route('user_pool', '/user/pool/{pool_id}')
Expand All @@ -153,7 +155,8 @@ def debug(request):
config.add_route('admin_index', '/admin')
config.add_route('admin_index_dashboard', '/admin/dashboard')

config.add_route('admin_ajax_bool', '/admin/ajax/bool/{object}/{id}/{field}/{state}')
config.add_route('admin_ajax_bool', '/admin/ajax/bool/{object}/{id}/{field}/{value}')
config.add_route('admin_ajax_text', '/admin/ajax/text/{object}/{id}/{field}')
config.add_route('admin_ajax_new', '/admin/ajax/new/{object}/{arg}')
config.add_route('admin_ajax_connection', '/admin/ajax/connection/{object1}/{object2}/{arg1}/{arg2}')

Expand Down Expand Up @@ -235,6 +238,7 @@ def debug(request):
config.add_route('admin_password_edit_submit', '/admin/password/edit/submit')

config.add_route('admin_requests', '/admin/requests')
config.add_route('admin_item_request_post_new', '/admin/item/request/{id}/post/new')

config.add_route('admin_announcements_edit', '/admin/announcements/edit')
config.add_route('admin_announcements_edit_submit', '/admin/announcements/edit/submit')
Expand Down
4 changes: 2 additions & 2 deletions chezbetty/datalayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ def delete_box(box):


# Call this to make a new item request
def new_request(user, request_text):
r = request.Request(user, request_text)
def new_request(user, request_text, vendor, vendor_url=None):
r = request.Request(user, request_text, vendor, vendor_url)
DBSession.add(r)
DBSession.flush()
return r
Expand Down
4 changes: 3 additions & 1 deletion chezbetty/jinja2_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ def shorten(s, l):
return s[0:l-1] + '…'

def make_link(obj, str_len=0):
if type(obj) is box.Box:
if obj is None:
return ''
elif type(obj) is box.Box:
return '<a href="/admin/box/edit/{}">{}</a>'.format(obj.id, shorten(obj.name, str_len))
elif type(obj) is item.Item:
return '<a href="/admin/item/edit/{}">{}</a>'.format(obj.id, shorten(obj.name, str_len))
Expand Down
28 changes: 28 additions & 0 deletions chezbetty/migrations/migration_1.18.1-1.19.0.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* WARN: This migration drops all old requests since the storage format changed significantly */
COPY requests TO '/tmp/cb_old_requests.csv' DELIMITER ',' CSV HEADER;

CREATE TABLE requests_pre_v1_19 AS SELECT * FROM requests;

DELETE FROM requests;
ALTER TABLE requests ADD COLUMN vendor_id INTEGER NOT NULL;
ALTER TABLE requests ADD CONSTRAINT vendor_id FOREIGN KEY(vendor_id) REFERENCES vendors(id) MATCH FULL;
ALTER TABLE requests ADD COLUMN vendor_url TEXT;

ALTER TABLE vendors ADD COLUMN product_urls BOOLEAN;
UPDATE vendors SET product_urls=True WHERE name='Amazon';
UPDATE vendors SET product_urls=True WHERE name='TalDepot';

CREATE TABLE request_posts (
id SERIAL,
"timestamp" timestamp without time zone NOT NULL,
request_id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
post TEXT,
staff_post BOOLEAN NOT NULL DEFAULT FALSE,
deleted BOOLEAN NOT NULL DEFAULT FALSE
);
ALTER TABLE request_posts ADD CONSTRAINT request_id FOREIGN KEY(request_id) REFERENCES requests(id) MATCH FULL;
ALTER TABLE request_posts ADD CONSTRAINT user_id FOREIGN KEY(user_id) REFERENCES users(id) MATCH FULL;

/* ALTER TABLE requests ADD COLUMN response TEXT; */

48 changes: 38 additions & 10 deletions chezbetty/models/request.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,57 @@
from .model import *
from . import vendor
from . import request_post

from sqlalchemy_utils import ArrowType

class Request(Base):
__tablename__ = 'requests'

id = Column(Integer, primary_key=True, nullable=False)
timestamp = Column(ArrowType, nullable=False, default=datetime.datetime.utcnow)
user_id = Column(Integer, ForeignKey("users.id"), nullable=True) # user that made the request
request = Column(Text)
enabled = Column(Boolean, default=True, nullable=False)
deleted = Column(Boolean, default=False, nullable=False)
id = Column(Integer, primary_key=True, nullable=False)
timestamp = Column(ArrowType, nullable=False, default=datetime.datetime.utcnow)
user_id = Column(Integer, ForeignKey("users.id"), nullable=False)
request = Column(Text)
vendor_id = Column(Integer, ForeignKey("vendors.id"), nullable=False)
vendor_url = Column(Text)
enabled = Column(Boolean, default=True, nullable=False)
deleted = Column(Boolean, default=False, nullable=False)

def __init__(self, user, request):
if user:
self.user_id = user.id
vendor = relationship(
vendor.Vendor,
primaryjoin="and_(Request.vendor_id==Vendor.id, Request.deleted==False)",
backref="requests",
)

posts = relationship(
request_post.RequestPost,
primaryjoin="and_(RequestPost.request_id==Request.id, RequestPost.deleted==False)",
backref="request",
)
deleted_posts = relationship(
request_post.RequestPost,
primaryjoin="and_(RequestPost.request_id==Request.id, RequestPost.deleted==True)",
)
all_posts = relationship(
request_post.RequestPost,
primaryjoin="RequestPost.request_id==Request.id",
)

def __init__(self, user, request, vendor, vendor_url=None):
self.user_id = user.id
self.request = request
self.vendor_id = vendor.id
if vendor_url:
self.vendor_url = vendor_url

@classmethod
def from_id(cls, id):
return DBSession.query(cls).filter(cls.id == id).one()

@classmethod
def all(cls):
return DBSession.query(cls).filter(cls.deleted==False).all()
return DBSession.query(cls).filter(cls.deleted==False)\
.order_by(desc(cls.timestamp))\
.all()

@classmethod
def count(cls):
Expand Down
33 changes: 33 additions & 0 deletions chezbetty/models/request_post.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from .model import *

from sqlalchemy_utils import ArrowType

class RequestPost(Base):
__tablename__ = 'request_posts'

id = Column(Integer, primary_key=True, nullable=False)
timestamp = Column(ArrowType, nullable=False, default=datetime.datetime.utcnow)
request_id = Column(Integer, ForeignKey("requests.id"), nullable=False)
user_id = Column(Integer, ForeignKey("users.id"), nullable=False)
post = Column(Text)
# Allow admin users to post as users or admins by tracking the view that the post is posted from
staff_post = Column(Boolean, default=False, nullable=False)
deleted = Column(Boolean, default=False, nullable=False)

def __init__(self, request, user, post, staff_post=False, deleted=False):
self.request_id = request.id
self.user_id = user.id
self.post = post
self.staff_post = staff_post
self.deleted = deleted

@classmethod
def from_id(cls, id):
return DBSession.query(cls).filter(cls.id == id).one()

@classmethod
def all(cls):
return DBSession.query(cls).filter(cls.deleted==False)\
.order_by(desc(cls.timestamp))\
.all()

9 changes: 9 additions & 0 deletions chezbetty/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from .model import *
from . import account
from . import event
from . import request
from . import request_post
from chezbetty import utility

import ldap3
Expand Down Expand Up @@ -120,6 +122,13 @@ class User(account.Account):

administrative_events = relationship(event.Event, foreign_keys=[event.Event.user_id], backref="admin")
events_deleted = relationship(event.Event, foreign_keys=[event.Event.deleted_user_id], backref="deleted_user")
requests = relationship(request.Request, foreign_keys=[request.Request.user_id], backref="user")
request_posts = relationship(
request_post.RequestPost,
foreign_keys=[request_post.RequestPost.user_id],
backref="user",
)

__ldap = LDAPLookup()

def __init__(self, uniqname, umid, name):
Expand Down
7 changes: 4 additions & 3 deletions chezbetty/models/vendor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
class Vendor(Base):
__tablename__ = 'vendors'

id = Column(Integer, primary_key=True, nullable=False)
name = Column(String(255), nullable=False)
id = Column(Integer, primary_key=True, nullable=False)
name = Column(String(255), nullable=False)

enabled = Column(Boolean, default=True, nullable=False)
enabled = Column(Boolean, default=True, nullable=False)
product_urls = Column(Boolean)

def __init__(self, name, enabled=True):
self.name = name
Expand Down
16 changes: 16 additions & 0 deletions chezbetty/static/css/chezbetty-common.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,22 @@
padding: 2px 5px 2px 5px;
}

.deleted {
background-color: #f0f0f0;
text-decoration: line-through;
display: none;
}

/* Highlight a form element that's required that was not filled out */
.form-required-missing {
background-color: #ff8080;
padding: 2px 5px 2px 5px;
}
.form-required-message {
color: red;
display: none;
}

/* Support for auto-sizing text */
.fitin {
overflow: hidden;
Expand Down
4 changes: 2 additions & 2 deletions chezbetty/static/js/chezbetty-admin-onload.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// Make the Demo Mode checkbox in the sidebar a pretty on/off slider
$(".admin-switch").bootstrapSwitch();

function ajax_bool (js_obj, object, field, id, status) {
var url = "/admin/ajax/bool/"+object+"/"+id+"/"+field+"/"+status;
function ajax_bool (js_obj, object, field, id, state) {
var url = "/admin/ajax/bool/"+object+"/"+id+"/"+field+"/"+state;
$.ajax({
url: url,
context: js_obj,
Expand Down
Loading

0 comments on commit 2804a0f

Please sign in to comment.