Browse Source

Merge branch 'master' of github.com:nisstyre56/TextbookEngine

master
wes 9 years ago
parent
commit
ce963b4d4b
  1. 6
      Makefile
  2. 5
      src/goasearch.py
  3. 13
      src/mcmaster/classes.py
  4. 2
      src/scripts/book.tag
  5. 4
      src/scripts/class.tag
  6. 11
      src/scripts/results.tag
  7. 26
      src/scripts/search.js
  8. 80
      src/scripts/search.tag
  9. 7
      src/search.py
  10. 85
      src/styles/search.scss
  11. 22
      src/templates/search.html

6
Makefile

@ -21,8 +21,8 @@ clean:
install:
$(MAKE) clean;
$(MAKE);
rm -rf ${SRV_ROOT}build/;
cp -rT ./build ${SRV_ROOT}build/;
rm -rf /srv/http/build/;
cp -rT ./build /srv/http/build/;
cp -rT ./build/scripts/ ${SRV_ROOT}scripts/;
cp -rT ./build/styles/ ${SRV_ROOT}styles/;
cp search.ini ${SRV_ROOT}build/;
cp search.ini /srv/http/build/;

5
src/goasearch.py

@ -1,7 +1,8 @@
#! /usr/bin/python2
from search import indexListing
from textbookExceptions import UnIndexable
from mcmaster.classes import allCourses, classToJSON, indexListing
from mcmaster.classes import allCourses
from search import indexListing, createIndex
from itertools import imap
try:
@ -11,7 +12,7 @@ except Exception as e:
print e
print "Downloading course info"
for c in imap(classToJSON, allCourses()):
for c in allCourses():
try:
print indexListing(c)
except UnIndexable as e:

13
src/mcmaster/classes.py

@ -118,10 +118,19 @@ class Section(dict):
self.time = time.encode("UTF-8")
self.loc = loc.encode("UTF-8")
self.prof = prof.encode("UTF-8")
self.sem = sem.encode("UTF-8")
self._sem = sem.encode("UTF-8")
self._date = False
self._day = False
@property
def sem(self):
if self._sem == fall:
return "Fall"
elif self._sem == winter:
return "Winter"
else:
return "Spring/Summer"
@property
def date(self):
if self.time != "TBA":
@ -341,7 +350,7 @@ def getCourses(semester, threadcount=10):
def allCourses():
return chain.from_iterable(
(getCourses(sem, threadcount=10)
(getCourses(sem, threadcount=25)
for sem in (fall, winter, spring_summer)))
if __name__ == "__main__":

2
src/scripts/book.tag

@ -23,7 +23,7 @@
</button>
</a>
</p>
<p class="centered" if={ noResources }>
<p class="centered wraptext" if={ noResources }>
Couldn't find anything, sorry :(
</p>
</dd>

4
src/scripts/class.tag

@ -21,8 +21,8 @@
</div>
</div>
<div class="toast" if={ !books }>
<p>No books at this time</p>
<p>Check back later, or verify the course has books</p>
<p class="wraptext">No books at this time</p>
<p class="wraptext">Check back later, or verify the course has books</p>
</div>
</class>

11
src/scripts/results.tag

@ -1,13 +1,22 @@
<results>
<div class="courses container">
<div if={notLoading} class="courses container">
<row class="course-row columns" each={ rows } data="{ this }" classrow={ row }></row>
</div>
this.rows = [];
var self = this;
results_passer.on("loading",
function() {
self.notLoading = false;
self.update();
});
results_passer.on("new_results",
function(data) {
console.log("new search results detected");
console.log(data);
self.rows = data;
self.notLoading = true;
self.update();
});
</results>

26
src/scripts/search.js

@ -8,11 +8,9 @@ function makeResourceGetter(self) {
"author" : this.bookauthor
};
var url = "/search/resources";
console.log(params);
$.getJSON(url, {
data : JSON.stringify(params)
}).done(function(results) {
if (results.iarchive) {
self.iarchive = results.iarchive[0];
}
@ -50,8 +48,11 @@ function ResultsPasser() {
var results_passer = new ResultsPasser();
riot.mount("search");
riot.mount("results");
riot.mount("search", {
showHelp : false,
booksLoading : false
});
riot.mount("results", {notLoading : true});
function autocomplete(element, endpoint) {
// The element should be an input class
@ -65,7 +66,24 @@ function autocomplete(element, endpoint) {
});
}
function realBook(book) {
var noAdoption = book.booktitle.indexOf("No Adoption");
var noBooks = book.booktitle.indexOf("No Textbooks");
return ((noAdoption == -1) &&
(noBooks == -1));
}
function filterCourses(courses) {
var books;
for (var i in courses) {
books = courses[i].books;
if ((books.length > 0) &&
(!realBook(books[0]))) {
courses[i].books = "";
}
}
return courses.filter(
function (c) {
return c.prof != "Staff";

80
src/scripts/search.tag

@ -1,30 +1,84 @@
<search>
<form class="form-horizontal search-form" onsubmit={ submit } type="submit"method="get">
<form class="form-horizontal search-form" onsubmit={ submit.bind(this) } type="submit"method="get">
<div class="form-group">
<div class="col-sm-8 form-item">
<input class="form-input" placeholder="Description" type="text" name="title"/>
</div>
<div class="col-sm-2 form-item">
<select class="form-select" aria-labelledby="dLabel" name="sem">
<div class="container">
<div class="columns">
<div class="col-sm-8 form-item">
<input onfocus={ showHelp }
class="form-input"
placeholder="Description"
type="text"
name="title"/>
</div>
<div class="col-sm-2 form-item">
<select class="form-select" aria-labelledby="dLabel" name="sem">
<option value="Fall">Fall</option>
<option value="Winter" selected>Winter</option>
<option value="Summer">Summer</option>
</select>
</div>
<div class="col-sm-2 form-item">
<button class="btn btn-primary" type="submit">Search</button>
<option value="Spring/Summer">Spring/Summer</option>
</select>
</div>
<div class="col-sm-2 form-item">
<button class="btn btn-primary" type="submit">Search</button>
</div>
</div>
</div>
</div>
</form>
<div if={ opts.showHelp }
class="help-toast toast toast-primary">
<button onclick={ clearHelp }
class="btn btn-clear float-right">
</button>
Type keywords of your course's name or the course code (e.g. PSYCH 2B03)
</div>
<div if={ opts.booksLoading } class="search-load">
</div>
</search>
this.showedHelp = false;
this.waiting = false;
function showHelp() {
if (!this.showedHelp) {
this.opts.showHelp = true;
this.update();
if (!waiting) {
waiting = true;
window.setTimeout(
(function() {
this.waiting = false;
clearHelpTemp.bind(this)();
}).bind(this), 10000);
}
}
}
function clearHelp() {
this.showedHelp = true;
this.opts.showHelp = false;
this.update();
}
function clearHelpTemp() {
this.opts.showHelp = false;
this.update();
}
function submit(ev) {
ev.preventDefault();
this.showedHelp = true;
this.opts.showHelp = false;
console.log("submitted");
this.opts.booksLoading = true;
this.update();
results_passer.trigger("loading");
var params = $(ev.currentTarget).serialize();
$.getJSON("/search/fc?"+params,
function(courses) {
(function(courses) {
var fcourses = filterCourses(courses);
var cgroups = groupsof(3, fcourses);
results_passer.trigger("new_results", cgroups);
});
this.opts.booksLoading = false;
this.update();
}).bind(this));
}

7
src/search.py

@ -9,6 +9,7 @@ from json import dumps, loads
from itertools import chain, imap
from hashlib import sha1
from syslog import syslog
from textbookExceptions import UnIndexable
@ -106,11 +107,12 @@ def indexListing(course):
}
"""
courseID = hashsec(course)
json_course = classToJSON(course)
courseID = hashsec(json_course)
print es.index(index="oersearch",
doc_type="course",
id=courseID,
body=course)
body=json_course)
# For every course we index, we also create a resource for it
# This should be an idempotent operation because we're putting it in couchdb
@ -169,6 +171,7 @@ def searchTerms(terms):
"""
Run a search for courses
"""
syslog(repr(terms))
# A list of all the queries we want to run
qs = [searchers[field](term) for

85
src/styles/search.scss

@ -6,6 +6,31 @@ header {
white-space: pre-wrap !important;
}
.search-load {
color: transparent !important;
min-height: 1.6rem;
pointer-events: none;
position: relative;
}
.search-load::after {
-webkit-animation: loading 500ms infinite linear;
animation: loading 500ms infinite linear;
border: .2rem solid #5764c6;
border-radius: 2.9rem;
border-right-color: transparent;
border-top-color: transparent;
content: "";
display: block;
height: 2.8rem;
left: 50%;
margin-left: -.8rem;
margin-top: -.8rem;
position: absolute;
top: 50%;
width: 3rem;
}
.body {
color: #1c75bc;
}
@ -18,9 +43,18 @@ a {
background-color: #1c75bc !important;
}
.courses {
@media (min-width: 1335px) {
.courses {
margin-top: 100px;
max-width: 75%;
}
}
@media (max-width: 1366px) {
.courses {
margin-top: 100px;
max-width: 85%;
}
}
.course {
@ -34,7 +68,7 @@ a {
}
.search-form {
margin-top: 9%;
margin-top: 6%;
-webkit-appearance: none !important;
}
@ -43,8 +77,9 @@ a {
}
.form-item {
padding-left: 15px;
padding-right: 15px;
padding-left: 5px;
padding-right: 5px;
margin-right: -15px;
}
#title {
@ -95,22 +130,28 @@ a {
background-image: none;
}
.logo-div {
height:67px;
width:150px;
margin-right:1%;
margin-bottom: 0%;
margin-top:1%;
margin-left:2%;
background-size: 100%;
background-size: cover;
-webkit-background-size: cover;
-o-background-size: cover;
background-size: cover;
background-position: center center;
/*background-image: url('https://mgoal.ca/goal_transp.png');*/
}
.title-div {
font-size: 25px;
@media (min-width: 480px) {
.logo {
margin-top: 20px;
margin-left: -175px;
}
}
@media (min-width: 480px) {
.title {
margin-left: 80px;
}
}
.page-top {
font-size: 15px;
width: 50% !important;
}
.help-toast {
background-color: rgba(28,117,188, 0.7) !important;
font-size: 0.8em;
max-width: 55%;
margin-top: -10px;
border: none;
}

22
src/templates/search.html

@ -3,16 +3,26 @@
{{super()}}
<meta name="viewport" content="width=device-width, initial-scale=1">
<header class="text-center nav navbar">
<section class="navbar-section">
<div class="title-div">
<h1>TextBook Commons</h1>
<h5>Type in the name of your course and start saving money on your books</h5>
<section class="centered page-top navbar-section">
<div class="container">
<div class="columns">
<div class="title column col-md-9"><h1>TextBook Commons</h1></div>
<div class="logo column col-md-3">
<figure class="avatar avatar-xl">
<img src="https://mgoal.ca/goal_small.png" />
</figure>
</div>
<search class="search-form"></search>
</section>
</div>
</div>
<h5>Search for your course and start saving money on your books</h5>
<search></search>
</section>
</header>
{% endblock %}
<html>
<figure class="avatar avatar-xl">
<img src="https://mgoal.ca/goal_small.png" />
</figure>
<body>
{% block content %}

Loading…
Cancel
Save