Commit 0f34696d by swdanielli

v0.1 before user feedback

parent a3139fc1
...@@ -20,7 +20,7 @@ class HelpResource(dict): ...@@ -20,7 +20,7 @@ class HelpResource(dict):
self.update(s) self.update(s)
else: else:
raise TypeError("Inappropriate type "+str(type(s))+" initializing HelpResource. Should be str or dict") raise TypeError("Inappropriate type "+str(type(s))+" initializing HelpResource. Should be str or dict")
for e,t in (('title', str), ('url', str), ('upvotes', int), ('downvotes', int), ('thumbnail', str)): for e,t in (('id', int), ('title', str), ('url', str), ('upvotes', int), ('downvotes', int), ('description', str)):
if e not in self: if e not in self:
raise TypeError("Insufficient fields initializing HelpResource. "+e+" required.") raise TypeError("Insufficient fields initializing HelpResource. "+e+" required.")
if not isinstance(self["e"], t): if not isinstance(self["e"], t):
...@@ -71,29 +71,76 @@ class RecommenderXBlock(XBlock): ...@@ -71,29 +71,76 @@ class RecommenderXBlock(XBlock):
data = pkg_resources.resource_string(__name__, path) data = pkg_resources.resource_string(__name__, path)
return data.decode("utf8") return data.decode("utf8")
def getResourceNewId(self):
recoms = self.recommendations
if not recoms:
recoms = self.default_recommendations
resourceId = -1
for recom in recoms:
if recom['id'] > resourceId:
resourceId = recom['id']
return resourceId + 1
def getRecommendationIndex(self, recomId):
recoms = self.recommendations
if not recoms:
recoms = self.default_recommendations
for idx in range(0, len(recoms)):
if recoms[idx]['id'] == recomId:
return idx
return -1
@XBlock.json_handler @XBlock.json_handler
def handle_upvote(self, data, suffix=''): def handle_upvote(self, data, suffix=''):
''' untested ''' ''' untested '''
resource = data['resource'] resource = data['resource']
if resource in upvotes: idx = self.getRecommendationIndex(resource)
if resource in self.upvotes:
print "Upvote failed!"
return {"Success": False} return {"Success": False}
if resource in self.downvotes: if resource in self.downvotes:
del self.downvotes[self.downvotes.index(resource)] del self.downvotes[self.downvotes.index(resource)]
self.recommendations[resource]['downvotes'] -= 1 self.recommendations[idx]['downvotes'] -= 1
else:
self.upvotes.append(resource)
self.recommendations[idx]['upvotes'] += 1
print "Upvote clicked!"
return {"Success": True}
self.upvotes.append(resource) @XBlock.json_handler
self.recommendations[resource]['upvotes'] += 1 def handle_downvote(self, data, suffix=''):
''' untested '''
resource = data['resource']
idx = self.getRecommendationIndex(resource)
if resource in self.downvotes:
print "Downvote failed!"
return {"Success": False}
print "Upvote clicked!" if resource in self.upvotes:
del self.upvotes[self.upvotes.index(resource)]
self.recommendations[idx]['upvotes'] -= 1
else:
self.downvotes.append(resource)
self.recommendations[idx]['downvotes'] += 1
print "Downvote clicked!"
return {"Success": True} return {"Success": True}
@XBlock.json_handler @XBlock.json_handler
def add_resource(self, data, suffix=''): def add_resource(self, data, suffix=''):
''' untested ''' ''' untested '''
resource = data['resource'] resource = data['resource']
## TODO: Return if already in resources # check url for redundancy
recoms = self.recommendations
#if not recoms:
# recoms = self.default_recommendations
for recom in recoms:
if recom['url'] == data['resource']['url']:
print "add redundant resource"
return {"Success": False}
# Construct new resource # Construct new resource
valid_fields = ['url', 'title', 'description'] valid_fields = ['url', 'title', 'description']
new_resource = {} new_resource = {}
...@@ -101,15 +148,43 @@ class RecommenderXBlock(XBlock): ...@@ -101,15 +148,43 @@ class RecommenderXBlock(XBlock):
new_resource[field] = data['resource'][field] new_resource[field] = data['resource'][field]
new_resource['upvotes'] = 0 new_resource['upvotes'] = 0
new_resource['downvotes'] = 0 new_resource['downvotes'] = 0
self.resources.append(new_resource) new_resource['id'] = self.getResourceNewId()
return {"Success": True} new_resource['isMisuse'] = "notMisuse"
# self.resources.append(new_resource)
self.recommendations.append(new_resource)
return {"Success": True, "id": new_resource['id']}
@XBlock.json_handler @XBlock.json_handler
def edit_resource(self, data, suffix=''): def edit_resource(self, data, suffix=''):
pass resource = data['resource']
idx = self.getRecommendationIndex(resource)
if idx not in range(0, len(self.recommendations)):
print "Edit failed!"
return {"Success": False}
# check url for redundancy
recoms = self.recommendations
for recom in recoms:
if recom['url'] == data['url']:
print "edit to esisting resource"
return {"Success": False}
for key in data:
if key == 'resource':
next
if data[key] == '':
next
self.recommendations[idx][key] = data[key]
return {"Success": True}
@XBlock.json_handler @XBlock.json_handler
def flag_resource(self, data, suffix=''): def flag_resource(self, data, suffix=''):
resource = data['resource']
idx = self.getRecommendationIndex(resource)
if idx not in range(0, len(self.recommendations)):
print "Flag failed!"
return {"Success": False}
self.recommendations[idx]['isMisuse'] = data['isMisuse']
return {"Success": True} return {"Success": True}
# TO-DO: change this view to display your data your own way. # TO-DO: change this view to display your data your own way.
...@@ -130,7 +205,8 @@ class RecommenderXBlock(XBlock): ...@@ -130,7 +205,8 @@ class RecommenderXBlock(XBlock):
# TODO: Sort by votes # TODO: Sort by votes
# Ideally, we'd estimate score based on votes, such that items with 1 vote have a sensible ranking (rather than a perfect rating) # Ideally, we'd estimate score based on votes, such that items with 1 vote have a sensible ranking (rather than a perfect rating)
# #
resources = [{'title' : r['title'], "votes" : r['up'] - r['down'], 'url' : r['url'], 'thumbnail' : r['thumbnail']} for r in self.recommendations] resources = [{'id' : r['id'], 'title' : r['title'], "votes" : r['upvotes'] - r['downvotes'], 'url' : r['url'], 'description' : r['description'], 'isMisuse': r['isMisuse']} for r in self.recommendations]
resources = sorted(resources, key = lambda r: r['votes'], reverse=True)
frag = Fragment(self.template_lookup.get_template("recommender.html").render(resources = resources)) frag = Fragment(self.template_lookup.get_template("recommender.html").render(resources = resources))
frag.add_css_url("//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css") frag.add_css_url("//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css")
...@@ -148,16 +224,20 @@ class RecommenderXBlock(XBlock): ...@@ -148,16 +224,20 @@ class RecommenderXBlock(XBlock):
return [ return [
("RecommenderXBlock", ("RecommenderXBlock",
"""<vertical_demo> """<vertical_demo>
<recommender> <html_demo><img class="question" src="http://people.csail.mit.edu/swli/edx/recommendation/img/pset.png"></img></html_demo>
{"title": "Covalent bonding and periodic trends", "up" : 15, "down" : 5, "url" : "https://courses.edx.org/courses/MITx/3.091X/2013_Fall/courseware/SP13_Week_4/SP13_Periodic_Trends_and_Bonding/", "thumbnail" : "http://people.csail.mit.edu/swli/edx/recommendation/img/videopage1.png"} <recommender>
{"title": "Polar covalent bonds and electronegativity", "up" : 10, "down" : 7, "url" : "https://courses.edx.org/courses/MITx/3.091X/2013_Fall/courseware/SP13_Week_4/SP13_Covalent_Bonding/", "thumbnail" : "http://people.csail.mit.edu/swli/edx/recommendation/img/videopage2.png"} {"id": 1, "title": "Covalent bonding and periodic trends", "upvotes" : 15, "downvotes" : 5, "url" : "https://courses.edx.org/courses/MITx/3.091X/2013_Fall/courseware/SP13_Week_4/SP13_Periodic_Trends_and_Bonding/", "description" : "http://people.csail.mit.edu/swli/edx/recommendation/img/videopage1.png", "isMisuse": "notMisuse"}
{"title": "Longest wavelength able to to break a C-C bond ...", "up" : 10, "down" : 7, "url" : "https://answers.yahoo.com/question/index?qid=20081112142253AA1kQN1", "thumbnail" : "http://people.csail.mit.edu/swli/edx/recommendation/img/dispage1.png"} {"id": 2, "title": "Polar covalent bonds and electronegativity", "upvotes" : 10, "downvotes" : 7, "url" : "https://courses.edx.org/courses/MITx/3.091X/2013_Fall/courseware/SP13_Week_4/SP13_Covalent_Bonding/", "description" : "http://people.csail.mit.edu/swli/edx/recommendation/img/videopage2.png", "isMisuse": "notMisuse"}
{"title": "Calculate the maximum wavelength of light for ...", "up" : 10, "down" : 7, "url" : "https://answers.yahoo.com/question/index?qid=20100110115715AA6toHw", "thumbnail" : "http://people.csail.mit.edu/swli/edx/recommendation/img/dispage2.png"} {"id": 3, "title": "Longest wavelength able to to break a C-C bond ...", "upvotes" : 10, "downvotes" : 7, "url" : "https://answers.yahoo.com/question/index?qid=20081112142253AA1kQN1", "description" : "http://people.csail.mit.edu/swli/edx/recommendation/img/dispage1.png", "isMisuse": "notMisuse"}
{"title": "Covalent bond - wave mechanical concep", "up" : 10, "down" : 7, "url" : "", "thumbnail" : "http://people.csail.mit.edu/swli/edx/recommendation/img/textbookpage1.png"} {"id": 4, "title": "Calculate the maximum wavelength of light for ...", "upvotes" : 10, "downvotes" : 7, "url" : "https://answers.yahoo.com/question/index?qid=20100110115715AA6toHw", "description" : "http://people.csail.mit.edu/swli/edx/recommendation/img/dispage2.png", "isMisuse": "notMisuse"}
{"title": "Covalent bond - Energetics of covalent bond", "up" : 10, "down" : 7, "url" : "", "thumbnail" : "http://people.csail.mit.edu/swli/edx/recommendation/img/textbookpage2.png"}
</recommender> </recommender>
</vertical_demo> </vertical_demo>
"""), """),
# {"id": 5, "title": "Covalent bond - wave mechanical concep", "upvotes" : 10, "downvotes" : 7, "url" : "", "description" : "http://people.csail.mit.edu/swli/edx/recommendation/img/textbookpage1.png", "isMisuse": "notMisuse"}
# {"id": 6, "title": "Covalent bond - Energetics of covalent bond", "upvotes" : 10, "downvotes" : 7, "url" : "", "description" : "http://people.csail.mit.edu/swli/edx/recommendation/img/textbookpage2.png", "isMisuse": "notMisuse"}
# </recommender>
# </vertical_demo>
# """),
] ]
@classmethod @classmethod
......
<style> <style>
.hidden { display: none;}
.recommender_block { .recommender_block {
width : 100%; width : 100%;
} }
.recommender_row { .recommender_content {
width: 700px;
float: left;
}
.recommender_row { overflow:hidden; }
.question {
width:700px; width:700px;
} }
...@@ -13,8 +22,8 @@ ...@@ -13,8 +22,8 @@
margin : 1; margin : 1;
/* display:table-cell;*/ /* display:table-cell;*/
float:left; float:left;
width:300px; width:340px;
border-color:red; border-color:gray;
border-width:1px; border-width:1px;
border-style:solid; border-style:solid;
border-radius:5px; border-radius:5px;
...@@ -26,17 +35,21 @@ ...@@ -26,17 +35,21 @@
} }
.recommender_title { .recommender_title {
flex-grow : 1 flex-grow : 1;
}
.recommender_modify {
width: 500px;
float: left;
} }
.thumbnailImg { .descriptionImg {
width: 600px; height: 400px;
height: 450px; overflow-x: scroll;
} }
.recommender_recommendations { .recommender_recommendations {
display:table; display:table;
width:100%;
} }
.recommender_blurb { .recommender_blurb {
...@@ -47,7 +60,7 @@ ...@@ -47,7 +60,7 @@
text-overflow:ellipsis; text-overflow:ellipsis;
} }
.recommender_url, .recommender_thumbnail { .recommender_entryId, .recommender_url, .recommender_descriptionSlot {
display:none; display:none;
} }
...@@ -77,31 +90,56 @@ ...@@ -77,31 +90,56 @@
display:inline-block; display:inline-block;
vertical-align: top; vertical-align: top;
} }
</style>
<div class="question"><img src="http://people.csail.mit.edu/swli/edx/recommendation/img/pset.png" width=700px></div> .misuse, .redTxt {
color: red;
}
.addSourceBlockTitle, .editSourceBlockTitle {
margin-top: 1em;
margin-bottom: 1em;
}
.resource_hovered { background: lightsteelblue; }
.recommender_modify { margin-left: 2em; }
</style>
<div class="recommender_block"> <div class="recommender_block">
<div class="recommender_header"> <div class="recommender_title">Helpful resources</div><div class="recommender_add"> <span class="ui-icon ui-icon-plusthick"></span></div></div> <div class="recommender_header">
<div class="recommender_title">Helpful resources</div>
</div>
<div class="recommender_recommendations"> <div class="recommender_recommendations">
<!-- <div class="recommender_content">
<iframe width=800 height=600 src="http://wikipedia.com"></iframe>
<iframe width=800 height=600 src="http://www.moocworkshop.org/"></iframe>
<iframe width=800 height=600 src="https://answers.yahoo.com/question/index?qid=20081112142253AA1kQN1"></iframe>
<iframe style="width:800px height:600px" src="https://courses.edx.org/courses/MITx/3.091X/2013_Fall/courseware/SP13_Week_4/SP13_Covalent_Bonding/"></iframe>
-->
<div class="recommender_row"> <div class="recommender_row">
% for elem in resources: % for elem in resources:
<!-- <li> ${elem} </li> <%include file="resourcebox.html" args="id=elem['id'],title=elem['title'],votes=elem['votes'],url=elem['url'],description=elem['description'],isMisuse=elem['isMisuse']" />
-->
<%include file="resourcebox.html" args="title=elem['title'],votes=elem['votes'],url=elem['url'],thumbnail=elem['thumbnail']" />
% endfor % endfor
</div> </div>
<div class="recommender_description">
<div class="descriptionImg"></div>
</div>
</div>
<div class='recommender_modify'>
<div class="editSourceBlock">
</div>
<div class="recommender_add">
<div class="addSourceBlockTitle">Add new resource</div>
Title: <input type="text" class="in_title"><br>
Url: <input type="text" class="in_url"><br>
<form id="addResourceForm" action="http://danielswli.s3.amazonaws.com/" method="post" enctype="multipart/form-data">
<input type="hidden" name="acl" value="public-read">
<input type="hidden" name="Content-Type" value="image/jpeg">
<input type="hidden" name="AWSAccessKeyId" value="AKIAIRDHSV6YZJZ4RFGA">
<input type="hidden" name="key" value="">
</form>
<!-- Resource description: <input type="text" class="in_description"><br>-->
</div>
</div>
</div> </div>
<!--
<div class="recommender_description"> <div class="recommender_description">
<div class="thumbnailImg"></div> <div class="descriptionImg"></div>
</div> </div>-->
</div> </div>
<%page args="title,votes,url,thumbnail"/> <%page args="title,votes,url,description,id,isMisuse"/>
<div class="recommender_resource"> <div class="recommender_resource">
<div class="recommender_vote_box"> <div class="recommender_vote_box">
<div class="recommender_vote_arrow_up" role="button" aria-label="upvote" tabindex="0"><span class="ui-icon ui-icon-triangle-1-n"></span></div> <div class="recommender_vote_arrow_up" role="button" aria-label="upvote" tabindex="0"><span class="ui-icon ui-icon-triangle-1-n"></span></div>
...@@ -7,6 +7,6 @@ ...@@ -7,6 +7,6 @@
<!--div class="recommender_vote_score_likes">2927</div--> <!--div class="recommender_vote_score_likes">2927</div-->
<div class="recommender_vote_arrow_down" role="button" aria-label="downvote" tabindex="0"><span class="ui-icon ui-icon-triangle-1-s"></span></div> <div class="recommender_vote_arrow_down" role="button" aria-label="downvote" tabindex="0"><span class="ui-icon ui-icon-triangle-1-s"></span></div>
</div> </div>
<div class="recommender_blurb">${title}<div class="recommender_url">${url}</div><div class="recommender_thumbnail">${thumbnail}</div></div> <div class="recommender_blurb"><div class="recommender_title">${title}</div><div class="recommender_url">${url}</div><div class="recommender_descriptionSlot">${description}</div><div class="recommender_entryId">${id}</div></div>
<div class="recommender_edit"><span class="ui-icon ui-icon-pencil"></span></div> <div class="recommender_edit"><input type="button" value="Edit" class="editResource"><br><input type="button" value="Misuse" class="flagResource ${isMisuse}"></div>
</div> </div>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment