Skip to content

Commit 7276878

Browse files
authored
Merge pull request #158 from uw-it-aca/qa
Qa
2 parents 434906d + 9f6ac4b commit 7276878

File tree

154 files changed

+13261
-1756
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

154 files changed

+13261
-1756
lines changed

.coveragerc

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[run]
2+
source = scout

.gitignore

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
.DS_Store
22

3+
# devights added other ignores
4+
.idea
5+
project/*
6+
manage.py
7+
38
# Byte-compiled / optimized / DLL files
49
__pycache__/
510
*.py[cod]
@@ -67,4 +72,7 @@ static/CACHE
6772
*.sqlite3
6873

6974
#sass cache
70-
*.sass-cache
75+
*.sass-cache
76+
77+
# node
78+
node_modules/

.travis.yml

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
sudo: false
2+
language: python
3+
python:
4+
- "2.7.6"
5+
install:
6+
- python setup.py -q install
7+
before_script:
8+
- pip install coverage
9+
- pip install python-coveralls
10+
- pip install pep8
11+
- pip install -r requirements.txt
12+
- cp travis-ci/manage.py manage.py
13+
- python manage.py migrate --noinput
14+
- npm install mocha
15+
- npm install jquery
16+
- npm install jsdom@3
17+
script:
18+
- pep8 scout/ --exclude=migrations
19+
- coverage run --source=scout/ --omit=scout/migrations/* manage.py test scout
20+
- mocha scout/static/scout/js/test --recursive
21+
after_script:
22+
- coveralls
23+
notifications:
24+
webhooks:
25+
urls:
26+
- https://yarn.cac.washington.edu/rest/botalyst/v1/travis-ci
27+
slack:
28+
secure: QhQcPJdxvdl5GlPdiewvyMMzDAM5fFB0Db2kRwpDphn8KiyNv2cF1SVeiYaJcQ4fObA7eWgsBXGBd/be8OC/1ujGNncz92bJM5xHePzMxs37hjPFaHuDGH0pnqurQIhRTz6OoWDi2+2OzC3xP1VkpOv0/2ApFjhUkO8S6JodH9A=

README.md

+68-24
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
[![Build Status](https://travis-ci.org/uw-it-aca/scout.svg?branch=develop)](https://travis-ci.org/uw-it-aca/scout) [![Coverage Status](https://coveralls.io/repos/uw-it-aca/scout/badge.svg?branch=master&service=github)](https://coveralls.io/github/uw-it-aca/scout?branch=master)
12
SCOUT
23
=====
34

@@ -9,37 +10,80 @@ The Scout project uses Vagrant and Ansible to build your development environment
910

1011
https://github.com/uw-it-aca/scout-vagrant
1112

12-
13+
1314
## API ##
1415

15-
Refer to the Spotseeker API https://github.com/uw-it-aca/spotseeker_server/wiki/REST-protocol-v1
16+
Refer to the Spotseeker API https://github.com/uw-it-aca/spotseeker_server/wiki/REST-protocol-v1 to view documentation regarding core data that is needed for all spots.
1617

1718

1819
The following types are to be used for Food finding...
1920

20-
"type": ["cafe", "cafeteria", "market", "restaurant", "food_truck"],
21+
"type" : ["cafe", "cafeteria", "food_court", "food_truck" "market", "restaurant"],
22+
23+
Scout specific extended info...
2124

22-
This meta type is needed...
25+
"extended_info": {
2326

24-
"meta_type": ["food"],
27+
// global
2528

26-
General extended info...
27-
28-
"extended_info": {
29-
"campus","seattle"
30-
"hours_notes", ""
31-
"access_notes", ""
32-
},
33-
34-
Scout specific extended info...
35-
36-
"extended_info": {
37-
“cuisine” : [“american”, “bbq”, "chinese", "hawaiian", "itallian"],
38-
“food_served” : [“burgers”, “salads”, “appetizers”, “pizza”, "sandwiches", "coffee_espresso"],
39-
“menu_url” : “”,
40-
“website_url” : “”,
41-
“has_delivery” : true,
42-
“payment_accepted” : [“cash”, “visa”, “mastercard”, “husky_card”, “dining_account”],
43-
“open_period” : [“breakfast”, “lunch”, “dinner”, “late_night”],
44-
},
29+
"app_type" : ["food", "study", "other"],
30+
"campus" : "seattle", ( or bothell, tacoma, south_lake_union)
31+
"hours_notes" : "",
32+
"access_notes" : "",
33+
34+
// scout
35+
36+
"s_menu_url" : "",
37+
"s_website_url" : "",
38+
"s_phone" : "",
39+
"s_email" : "",
40+
41+
"s_has_alert" : false,
42+
"s_alert_notes" : "",
43+
44+
"s_has_reservation" : false,
45+
"s_reservation_notes" : "",
46+
47+
"s_has_coupon" : "true",
48+
"s_coupon_expiration" : "datetime",
49+
"s_coupon_url" : "",
50+
51+
// cuisine
52+
53+
"s_cuisine_american" : true,
54+
"s_cuisine_bbq" : false,
55+
"s_cuisine_chinese" : false,
56+
"s_cuisine_hawaiian" : false,
57+
"s_cuisine_indian" : false,
58+
"s_cuisine_italian" : false,
59+
"s_cuisine_korean" : false,
60+
"s_cuisine_mexican" : false,
61+
"s_cuisine_vietnamese" : false,
62+
63+
// food served
64+
65+
"s_food_breakfast" : true,
66+
"s_food_burgers" : true,
67+
"s_food_curry" : true,
68+
"s_food_desserts" : true,
69+
"s_food_entrees" : true,
70+
"s_food_espresso" : true,
71+
"s_food_frozen_yogurt" : true,
72+
"s_food_pasta" : true,
73+
"s_food_pastries" : true,
74+
"s_food_pho" : true,
75+
"s_food_pizza" : true,
76+
"s_food_salads" : true,
77+
"s_food_sandwiches" : true,
78+
"s_food_smoothies" : true,
79+
"s_food_sushi_packaged" : true,
80+
"s_food_tacos" : true,
81+
82+
// payment extended info
4583

84+
"s_pay_cash" : true,
85+
"s_pay_visa" : true,
86+
"s_pay_mastercard" : true,
87+
"s_pay_husky" : true,
88+
"s_pay_dining" : true,
89+
},

requirements.txt

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,2 @@
1-
django
2-
django-compressor
3-
django_mobileesp
4-
django-turbolinks
5-
django-htmlmin
6-
libsass
7-
1+
-e git+https://github.com/uw-it-aca/spotseeker_client.git#egg=spotseeker-restclient
82
-e .

requirements_saucelabs.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
sauceclient
2+
selenium
3+
pyvirtualdisplay

scout/context_processors.py

+20-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
from django.conf import settings
22

3+
4+
def google_maps(request):
5+
""" See if there is a Google Analytics web property id
6+
"""
7+
gmaps_api_key = getattr(settings, 'GOOGLE_MAPS_API', False)
8+
return {
9+
'GOOGLE_MAPS_API': gmaps_api_key,
10+
'google_maps': gmaps_api_key
11+
}
12+
13+
314
def google_analytics(request):
415

516
ga_key = getattr(settings, 'GOOGLE_ANALYTICS_KEY', False)
@@ -8,19 +19,20 @@ def google_analytics(request):
819
'google_analytics': ga_key
920
}
1021

22+
1123
def is_desktop(request):
12-
24+
1325
desktopapp = not request.is_mobile and not request.is_tablet
14-
26+
1527
return {
16-
'is_desktop' : desktopapp
28+
'is_desktop': desktopapp
1729
}
18-
30+
31+
1932
def is_hybrid(request):
20-
33+
2134
hybridapp = request.GET.get('hybrid')
22-
35+
2336
return {
24-
'is_hybrid' : hybridapp
37+
'is_hybrid': hybridapp
2538
}
26-

scout/dao/__init__.py

Whitespace-only changes.

scout/dao/image.py

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from django.conf import settings
2+
from spotseeker_restclient.spotseeker import Spotseeker
3+
from spotseeker_restclient.exceptions import DataFailureException
4+
import oauth2
5+
6+
7+
def get_client():
8+
# Required settings for the client
9+
if not hasattr(settings, 'SPOTSEEKER_HOST'):
10+
raise(Exception("Required setting missing: SPOTSEEKER_HOST"))
11+
if not hasattr(settings, 'SPOTSEEKER_OAUTH_KEY'):
12+
raise(Exception("Required setting missing: SPOTSEEKER_OAUTH_KEY"))
13+
if not hasattr(settings, 'SPOTSEEKER_OAUTH_SECRET'):
14+
raise(Exception("Required setting missing: SPOTSEEKER_OAUTH_SECRET"))
15+
16+
consumer = oauth2.Consumer(key=settings.SPOTSEEKER_OAUTH_KEY,
17+
secret=settings.SPOTSEEKER_OAUTH_SECRET)
18+
client = oauth2.Client(consumer)
19+
20+
return client
21+
22+
23+
def get_image(spot_id, image_id, width=None):
24+
client = get_client()
25+
if width is not None:
26+
url = "%s/api/v1/spot/%s/image/%s/thumb/constrain/width:%s" % (
27+
settings.SPOTSEEKER_HOST,
28+
spot_id,
29+
image_id,
30+
width)
31+
else:
32+
url = "%s/api/v1/spot/%s/image/%s" % (settings.SPOTSEEKER_HOST,
33+
spot_id,
34+
image_id)
35+
return client.request(url, 'GET')

scout/dao/item.py

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
from scout.dao.space import get_spots_by_filter, _get_spot_filters, \
2+
_get_extended_info_by_key
3+
import copy
4+
5+
6+
def get_item_by_id(item_id):
7+
spot = get_spots_by_filter([
8+
('item:id', item_id),
9+
('extended_info:app_type', 'tech')
10+
])
11+
if spot:
12+
spot = _filter_spot_items(item_id, spot[0])
13+
return spot
14+
15+
16+
def _filter_spot_items(item_id, spot):
17+
for item in spot.items:
18+
if item.item_id == item_id:
19+
spot.item = item
20+
return spot
21+
22+
23+
def add_item_info(spot):
24+
for item in spot.items:
25+
item.model = _get_extended_info_by_key("i_model",
26+
item.extended_info)
27+
item.brand = _get_extended_info_by_key("i_brand",
28+
item.extended_info)
29+
item.checkout_period = _get_extended_info_by_key(
30+
"i_checkout_period",
31+
item.extended_info
32+
)
33+
item.has_access_restriction = _get_extended_info_by_key(
34+
"i_has_access_restriction",
35+
item.extended_info
36+
)
37+
item.access_limit_role = _get_extended_info_by_key(
38+
"i_access_limit_role",
39+
item.extended_info
40+
)
41+
item.access_role_students = _get_extended_info_by_key(
42+
"i_access_role_students",
43+
item.extended_info
44+
)
45+
item.reservation_required = _get_extended_info_by_key(
46+
"i_reservation_required",
47+
item.extended_info
48+
)
49+
item.is_active = _get_extended_info_by_key(
50+
"i_is_active",
51+
item.extended_info
52+
)
53+
item.quantity = _get_extended_info_by_key(
54+
"i_quantity",
55+
item.extended_info
56+
)
57+
item.description = _get_extended_info_by_key(
58+
"i_description",
59+
item.extended_info
60+
)
61+
item.reserve_url = _get_extended_info_by_key(
62+
"i_reserve_url",
63+
item.extended_info
64+
)
65+
item.manual_url = _get_extended_info_by_key(
66+
"i_manual_url",
67+
item.extended_info
68+
)
69+
return spot
70+
71+
72+
def get_filtered_items(spots, request):
73+
parameter_list = _get_spot_filters(request)
74+
brand = []
75+
subcategory = []
76+
for param in parameter_list:
77+
if param[0] == "item:extended_info:i_brand":
78+
brand.append(param[1])
79+
elif param[0] == "item:subcategory":
80+
subcategory.append(param[1])
81+
82+
if len(brand) <= 0 and len(subcategory) <= 0:
83+
return spots
84+
85+
newSpots = []
86+
87+
for spot in spots:
88+
newSpot = copy.deepcopy(spot)
89+
newSpot.items = []
90+
for item in spot.items:
91+
if item.subcategory in subcategory:
92+
newSpot.items.append(item)
93+
else:
94+
if item.brand in brand:
95+
newSpot.items.append(item)
96+
newSpots.append(newSpot)
97+
return newSpots
98+
99+
100+
def get_item_count(spots):
101+
item_count = 0
102+
for spot in spots:
103+
item_count += len(spot.items)
104+
return item_count

0 commit comments

Comments
 (0)