diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6123620
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+
+Parliament/client/stylesheets/
diff --git a/OtherResources/wikiparse.py b/OtherResources/wikiparse.py
new file mode 100644
index 0000000..d2e6d5b
--- /dev/null
+++ b/OtherResources/wikiparse.py
@@ -0,0 +1,17 @@
+from bs4 import BeautifulSoup
+import wikipedia
+import requests
+import urllib
+
+class Article(object):
+ """Represents a wikipedia article"""
+ def __init__(self, title):
+ if not title:
+ raise Exception
+
+ url = urllib.quote(title)
+ url = "http://en.wikipedia.org/wiki/"+url
+ html = requests.get(url)
+ soup = BeautifulSoup(html)
+
+
diff --git a/Parliament/.meteor/.gitignore b/Parliament/.meteor/.gitignore
new file mode 100644
index 0000000..4083037
--- /dev/null
+++ b/Parliament/.meteor/.gitignore
@@ -0,0 +1 @@
+local
diff --git a/Parliament/.meteor/packages b/Parliament/.meteor/packages
new file mode 100644
index 0000000..6daf4d5
--- /dev/null
+++ b/Parliament/.meteor/packages
@@ -0,0 +1,17 @@
+# Meteor packages used by this project, one per line.
+#
+# 'meteor add' and 'meteor remove' will edit this file for you,
+# but you can also edit it by hand.
+
+standard-app-packages
+coffeescript
+stylus
+jade
+less
+less-bootstrap-3
+font-awesome-4-less
+accounts-ui
+iron-router
+collection2
+pen
+accounts-google
diff --git a/Parliament/.meteor/release b/Parliament/.meteor/release
new file mode 100644
index 0000000..100435b
--- /dev/null
+++ b/Parliament/.meteor/release
@@ -0,0 +1 @@
+0.8.2
diff --git a/Parliament/client/ParlClient.coffee b/Parliament/client/ParlClient.coffee
new file mode 100644
index 0000000..6e3be2c
--- /dev/null
+++ b/Parliament/client/ParlClient.coffee
@@ -0,0 +1,124 @@
+Requests = new Meteor.Collection 'requests'
+Queries = new Meteor.Collection 'queries'
+Responses = new Meteor.Collection 'responses'
+
+Router.onBeforeAction 'loading'
+
+Router.map ->
+ this.route 'home',
+ path: '/'
+ waitOn: -> Meteor.subscribe 'latest'
+ data:
+ latest: Queries.find {}, {sort: [['created', 'desc'], 'query']}
+ this.route 'create'
+ this.route 'tag',
+ path: '/tagged/:tag'
+ waitOn: -> Meteor.subscribe 'tagged', decodeURI this.params.tag
+ data: ->
+ tag = this.params.tag
+ return {
+ tag: decodeURI tag
+ queries: Queries.find {}, {sort: [['created', 'desc'], 'query']}
+ }
+ this.route 'query',
+ path: '/queries/:_id'
+ waitOn: ->
+ Meteor.subscribe 'query', this.params._id
+ Meteor.subscribe 'responses', this.params._id
+ Meteor.subscribe 'queryRequest', this.params._id
+ data: ->
+ id = this.params._id
+ dict =
+ query: Queries.findOne id
+ responses: Responses.find {}
+ request: Requests.findOne {queries: id}
+ return dict
+ this.route 'request',
+ path: '/requests/:_id'
+ waitOn: ->
+ Meteor.subscribe 'request', this.params._id
+ Meteor.subscribe 'requestQueries', this.params._id
+ Meteor.subscribe 'requestResponses', this.params._id
+ data: ->
+ id = this.params._id
+ dict = Requests.findOne id
+ return dict
+ this.route 'me',
+ path: '/me'
+ waitOn: ->
+ Meteor.subscribe 'userSelf'
+
+Template.intro.events
+ 'click #create': ->
+ Router.go 'create'
+
+Template.create.events
+ 'click #submit': (event, template) ->
+ jhtml = template.$('.pen')
+ html = jhtml.html()
+ queryArray = (query.innerText for query in jhtml.find('u').get())
+ text = jhtml.text()
+ topic = template.find('#topic').value
+ comment = template.find('#comment').value
+ tags = template.find('#tags').value.split(/\s*,\s*/)
+ Meteor.call 'addQuery', topic, queryArray, tags, comment, text, html
+ Router.go 'home'
+
+Template.navbar.events
+ 'submit form#tagsearch': (event, template) ->
+ term = template.find('#searchfield').value
+ term = encodeURI(term)
+ Router.go 'tag',
+ tag: term
+ 'click a.userPage': (event, template) ->
+ Router.go 'me'
+
+Template.query.events
+ 'click button#add': (event, template) ->
+ jhtml = template.$('.pen')
+ html = jhtml.html()
+ id = this.query._id
+ # id = Queries.findOne({})._id
+ Meteor.call 'queryRespond', id, html
+ template.$('.pen').html('')
+ 'click button.up': (event, template) ->
+ id = this._id
+ Meteor.call 'upvote', id
+ 'click button.down': (event, template) ->
+ id = this._id
+ Meteor.call 'downvote', id
+
+Template.request.events
+ 'click u': (event, template) ->
+ name = event.currentTarget.innerText
+ id = Queries.findOne({query: name})._id
+ top = Responses.findOne {query: id},
+ sort: [['votes', 'desc'], ['created', 'desc']]
+ console.log this
+ Session.set 'topResponse', top
+ $('#explanation').modal 'show'
+ 'click button.close': (event, template) ->
+ $('#explanation').modal 'hide'
+
+Template.explanation.helpers
+ topResponse: ->
+ return Session.get 'topResponse'
+
+Template.create.rendered = ->
+ this._editor = new Pen('#editor')
+
+Template.create.destroyed = ->
+ this._editor.destroy
+
+Template.query.rendered = ->
+ this._editor = new Pen('#editor')
+
+Template.query.destroyed = ->
+ this._editor.destroy
+
+Template.explanation.rendered = ->
+ $('#explanation').modal
+ show: false
+
+Template.explanation.destroyed = ->
+ $('#explanation').modal 'hide'
diff --git a/Parliament/client/templates/create.jade b/Parliament/client/templates/create.jade
new file mode 100644
index 0000000..98952f7
--- /dev/null
+++ b/Parliament/client/templates/create.jade
@@ -0,0 +1,34 @@
+template(name='create')
+ if currentUser
+ +createForm
+ else
+ .container
+ .row
+ .panel.panel-default
+ .panel-body
+ h2 Please log in to submit a question:
+ +loginButtons
+
+template(name='createForm')
+ .container
+ .row
+ .col-xs-12
+ h1 Create a query:
+ br
+ .row
+ .col-md-8.col-md-offset-1
+ form
+ .form-group
+ label The specific topic of this query:
+ input(type='text' placeholder='Enter the topic').form-control#topic
+ .form-group
+ label Paste in the source you're using. Highlight any phrases that need clarification by selecting the text and clicking the underline button:
+ .form-control#editor
+ .form-group
+ label A brief comment on why you're confused:
+ textarea.form-control#comment(rows='7' placeholder="Comment on what's confusing you")
+ .form-group
+ label Tags, keep them general so people can find your query:
+ input(type='text' placeholder='Enter comma-separated tags').form-control#tags
+ .form-group
+ button.btn.btn-success.pull-right.btn-lg#submit(type='button') Submit
diff --git a/Parliament/client/templates/index.jade b/Parliament/client/templates/index.jade
new file mode 100644
index 0000000..cba0202
--- /dev/null
+++ b/Parliament/client/templates/index.jade
@@ -0,0 +1,38 @@
+head
+ title Parliament
+body
+ +navbar
+
+template(name='home')
+ +intro
+ +latest
+
+template(name='intro')
+ .jumbotron
+ .container
+ h1 Parliament
+ p is a cool thing that lets you make queries to simplify a body of information into a learnable format
+ button#create.btn.btn-primary.btn-lg Create a query!
+
+
+template(name='latest')
+ .container
+ .row
+ .panel.panel-default
+ .panel-heading
+ h2 Latest Queries
+ table.table
+ thead
+ tr
+ th Query
+ th Topic
+ th Tags
+ tbody
+ each latest
+ tr
+ td
+ a(href="{{pathFor 'query'}}") #{query}
+ td
+ a(href="{{pathFor 'request' _id=this.request}}") #{topic}
+ td.tagcol
+ +tagbox
diff --git a/Parliament/client/templates/misc.jade b/Parliament/client/templates/misc.jade
new file mode 100644
index 0000000..e055b6b
--- /dev/null
+++ b/Parliament/client/templates/misc.jade
@@ -0,0 +1,5 @@
+template(name='loading')
+ .container
+ .row
+ .col-xs-12
+ h2 Loading...
diff --git a/Parliament/client/templates/navbar.html b/Parliament/client/templates/navbar.html
new file mode 100644
index 0000000..1045af2
--- /dev/null
+++ b/Parliament/client/templates/navbar.html
@@ -0,0 +1,40 @@
+
+
+
diff --git a/Parliament/client/templates/query.jade b/Parliament/client/templates/query.jade
new file mode 100644
index 0000000..7c20912
--- /dev/null
+++ b/Parliament/client/templates/query.jade
@@ -0,0 +1,52 @@
+template(name='query')
+ .container
+ .row
+ h2 Explain #{query.query} from this material on #{query.topic}:
+ with request
+ .row
+ .panel.panel-default
+ .panel-body !{html}
+ .panel-body
+ p #{comment}
+ .panel-body
+ +tagbox
+ .row
+ if responses.count
+ h3 Here are some proposed explanations for the topic:
+ else
+ h3 There are no explanations yet. Write your own!
+ each responses
+ .row
+ img(src="{{createdBy.image}}").img-circle.userThumb.inline
+ div.inline.namevote
+ h3 #{createdBy.name} says:
+ .btn-group
+ if currentUser
+ button.btn.btn-danger.down
+ span.glyphicon.glyphicon-chevron-down
+ .btn.btn-default(disabled) #{votes}
+ button.btn.btn-success.up
+ span.glyphicon.glyphicon-chevron-up
+ else
+ button.btn.btn-danger.down(disabled)
+ span.glyphicon.glyphicon-chevron-down
+ .btn.btn-default(disabled) #{votes}
+ button.btn.btn-success.up(disabled)
+ span.glyphicon.glyphicon-chevron-up
+ .panel.panel-default
+ .panel-body !{response}
+ .row
+ if responses.count
+ h3 Add a response of your own:
+ if currentUser
+ form
+ .panel.panel-default
+ .panel-body
+ .form-control#editor
+ .panel-footer
+ button.btn.btn-success(type="button")#add Add this response
+ else
+ .panel.panel-default
+ .panel-body
+ h2 Please log in to submit a response:
+ +loginButtons
diff --git a/Parliament/client/templates/request.jade b/Parliament/client/templates/request.jade
new file mode 100644
index 0000000..f69f453
--- /dev/null
+++ b/Parliament/client/templates/request.jade
@@ -0,0 +1,21 @@
+template(name='request')
+ .container
+ .row
+ h2 #{name}
+ .panel.panel-default
+ .panel-body !{html}
+ .panel-body
+ p #{comment}
+ .panel-body
+ +tagbox
+ +explanation
+
+template(name='explanation')
+ .modal.fade#explanation(tabindex='-1')
+ .modal-dialog.modal-sm
+ .modal-content
+ .modal-header
+ button.close(type='button')
+ span(aria-hidden='true') ×
+ with topResponse
+ .modal-body !{response}
diff --git a/Parliament/client/templates/tag.jade b/Parliament/client/templates/tag.jade
new file mode 100644
index 0000000..e9550d5
--- /dev/null
+++ b/Parliament/client/templates/tag.jade
@@ -0,0 +1,25 @@
+template(name='tag')
+ .container
+ .row
+ .panel.panel-default
+ .panel-heading
+ h2 Queries tagged #{tag}:
+ table.table
+ thead
+ tr
+ th Query
+ th Topic
+ th Tags
+ tbody
+ each queries
+ tr
+ td #{query}
+ td #{topic}
+ td.tagcol
+ +tagbox
+
+template(name='tagbox')
+ .tagbox
+ each tags
+ a(href="{{pathFor 'tag' tag=this}}")
+ button.btn.btn-default.btn-sm #{this}
diff --git a/Parliament/client/templates/users.jade b/Parliament/client/templates/users.jade
new file mode 100644
index 0000000..9d70453
--- /dev/null
+++ b/Parliament/client/templates/users.jade
@@ -0,0 +1,4 @@
+template(name="me")
+ .container
+ .row
+ h1 Nothing here yet
diff --git a/Parliament/packages/.gitignore b/Parliament/packages/.gitignore
new file mode 100644
index 0000000..1a5de69
--- /dev/null
+++ b/Parliament/packages/.gitignore
@@ -0,0 +1,11 @@
+/jade
+/less-bootstrap-3
+/font-awesome-4-less
+/iron-router
+/blaze-layout
+/bootstrap3-wysihtml5
+/collection2
+/simple-schema
+/pen
+/bootstrap-wysiwyg
+/aloha-editor
diff --git a/eduwiki/static/fonts/glyphicons-halflings-regular.eot b/Parliament/public/fonts/glyphicons-halflings-regular.eot
old mode 100644
new mode 100755
similarity index 100%
rename from eduwiki/static/fonts/glyphicons-halflings-regular.eot
rename to Parliament/public/fonts/glyphicons-halflings-regular.eot
diff --git a/eduwiki/static/fonts/glyphicons-halflings-regular.svg b/Parliament/public/fonts/glyphicons-halflings-regular.svg
old mode 100644
new mode 100755
similarity index 100%
rename from eduwiki/static/fonts/glyphicons-halflings-regular.svg
rename to Parliament/public/fonts/glyphicons-halflings-regular.svg
diff --git a/eduwiki/static/fonts/glyphicons-halflings-regular.ttf b/Parliament/public/fonts/glyphicons-halflings-regular.ttf
old mode 100644
new mode 100755
similarity index 100%
rename from eduwiki/static/fonts/glyphicons-halflings-regular.ttf
rename to Parliament/public/fonts/glyphicons-halflings-regular.ttf
diff --git a/eduwiki/static/fonts/glyphicons-halflings-regular.woff b/Parliament/public/fonts/glyphicons-halflings-regular.woff
old mode 100644
new mode 100755
similarity index 100%
rename from eduwiki/static/fonts/glyphicons-halflings-regular.woff
rename to Parliament/public/fonts/glyphicons-halflings-regular.woff
diff --git a/Parliament/server/ParlServer.coffee b/Parliament/server/ParlServer.coffee
new file mode 100644
index 0000000..73ab340
--- /dev/null
+++ b/Parliament/server/ParlServer.coffee
@@ -0,0 +1,115 @@
+Requests = new Meteor.Collection 'requests'
+Queries = new Meteor.Collection 'queries'
+Responses = new Meteor.Collection 'responses'
+
+Meteor.methods
+ addQuery: (topic, queries, tags, comment, text, html) ->
+ # check topic, String
+ # check queries, [String]
+ # check tags, [String]
+ # check comment, String
+ # check text, String
+ # check html, String
+
+ if Meteor.userId()
+ requestId = Requests.insert
+ topic: topic
+ tags: tags
+ comment: comment
+ text: text
+ html: html
+ created: new Date
+ createdBy:
+ _id: Meteor.userId()
+ name: Meteor.user().profile.name
+ image: Meteor.user().services.google.picture
+
+ newQuery = (qu) ->
+ Queries.insert
+ topic: topic
+ query: qu
+ tags: tags
+ text: text
+ request: requestId
+ created: new Date
+ createdBy:
+ _id: Meteor.userId()
+ name: Meteor.user().profile.name
+ image: Meteor.user().services.google.picture
+
+ queryIds = (newQuery query for query in queries)
+
+ Requests.update requestId,
+ $set:
+ queries: queryIds
+
+ queryRespond: (queryId, response) ->
+ if Meteor.userId()
+ responseId = Responses.insert
+ query: queryId
+ response: response
+ votes: 0
+ created: new Date
+ createdBy:
+ _id: Meteor.userId()
+ name: Meteor.user().profile.name
+ image: Meteor.user().services.google.picture
+
+ Queries.update queryId,
+ $push:
+ responses: responseId
+
+ upvote: (responseId) ->
+ if Meteor.userId()
+ Responses.update responseId,
+ $inc:
+ votes: 1
+
+ downvote: (responseId) ->
+ if Meteor.userId()
+ Responses.update responseId,
+ $inc:
+ votes: -1
+
+
+
+Meteor.publish 'latest', ->
+ Queries.find {},
+ sort: [['created', 'desc'], 'query']
+ limit: 20
+
+Meteor.publish 'tagged', (tag) ->
+ return Queries.find {tags: tag},
+ sort: [['created', 'desc'], 'query']
+
+Meteor.publish 'responses', (queryId) ->
+ return Responses.find {query: queryId},
+ sort: [['votes', 'desc'], ['created', 'desc']]
+
+Meteor.publish 'query', (id) -> Queries.find id
+
+Meteor.publish 'request', (id) -> Requests.find id
+
+Meteor.publish 'requestQueries', (requestId) ->
+ Queries.find
+ request: requestId
+
+Meteor.publish 'queryRequest', (queryId) ->
+ Requests.find
+ queries: queryId
+
+Meteor.publish 'requestResponses', (requestId) ->
+ request = Requests.findOne requestId
+ queriesCursor = Queries.find
+ _id:
+ $in: request.queries
+ queries = queriesCursor.fetch()
+ responseIds = []
+ for query in queries
+ responseIds = responseIds.concat query.responses
+ return Responses.find
+ _id:
+ $in: responseIds
+
+Meteor.publish 'userSelf', ->
+ return Meteor.user()
diff --git a/Parliament/smart.json b/Parliament/smart.json
new file mode 100644
index 0000000..7af0f58
--- /dev/null
+++ b/Parliament/smart.json
@@ -0,0 +1,10 @@
+{
+ "packages": {
+ "jade": {},
+ "less-bootstrap-3": {},
+ "font-awesome-4-less": {},
+ "iron-router": {},
+ "collection2": {},
+ "pen": {}
+ }
+}
diff --git a/Parliament/smart.lock b/Parliament/smart.lock
new file mode 100644
index 0000000..7315ec2
--- /dev/null
+++ b/Parliament/smart.lock
@@ -0,0 +1,55 @@
+{
+ "meteor": {},
+ "dependencies": {
+ "basePackages": {
+ "jade": {},
+ "less-bootstrap-3": {},
+ "font-awesome-4-less": {},
+ "iron-router": {},
+ "collection2": {},
+ "pen": {}
+ },
+ "packages": {
+ "jade": {
+ "git": "https://github.com/mquandalle/meteor-jade.git",
+ "tag": "v0.2.4",
+ "commit": "a47a4c59daaa57e7fe5f1544d4ea76d95a5c9abf"
+ },
+ "less-bootstrap-3": {
+ "git": "https://github.com/DerMambo/less-bootstrap-3.git",
+ "tag": "v0.0.2",
+ "commit": "b5010b2ff9e9ae6b0e6e13eb0f6c81c9cb84373e"
+ },
+ "font-awesome-4-less": {
+ "git": "https://github.com/svub/fontawesome4-less.git",
+ "tag": "v4.4.0",
+ "commit": "250d2336a217c18eb70e9d074784a7db3ca38472"
+ },
+ "iron-router": {
+ "git": "https://github.com/EventedMind/iron-router.git",
+ "tag": "v0.7.1",
+ "commit": "d1ffb3f06ea4c112132b030f2eb1a70b81675ecb"
+ },
+ "collection2": {
+ "git": "https://github.com/aldeed/meteor-collection2.git",
+ "tag": "v0.4.2",
+ "commit": "4ff4b707bec8be434919730bf101325adb215444"
+ },
+ "pen": {
+ "git": "https://github.com/rabisg/meteor-pen.git",
+ "tag": "v0.1.0",
+ "commit": "5bc32652aa407fa9669809faf13384eb15c69d0a"
+ },
+ "blaze-layout": {
+ "git": "https://github.com/EventedMind/blaze-layout.git",
+ "tag": "v0.2.4",
+ "commit": "b40e9b0612329288d75cf52ad14a7da64bb8618f"
+ },
+ "simple-schema": {
+ "git": "https://github.com/aldeed/meteor-simple-schema.git",
+ "tag": "v0.6.0",
+ "commit": "418ec496612fb2afc853e342f0d2269b6674a2fe"
+ }
+ }
+ }
+}
diff --git a/README.md b/README.md
index 0ff7cff..d5dc845 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,2 @@
-= EduWiki =
-EduWiki is a prototype for an experimental system that creates custom lesson plans and assessments from wikipedia articles and other web resources using a combination of machine and crowd intelligence.
-
-== Tools Used ==
-
-Eduwiki uses Python for its API handling code, Django for its app structure, and Twitter Bootstrap 3.0 for its styling. It uses a modified version of the Wikipedia library to wrap the MediaWiki API, Beautiful Soup 4 for some assorted HTML parsing tasks, and the Python Requests library. It is currently in active prototype development and research at Carnegie Mellon University.
+# EduWiki
+This repo contains prototypes of the EduWiki and Parliament systems. These were experimental systems that were designed to create crowd-generated lessons for arbitrary topics. They evolved into the as-of-yet-unnamed project [here](https://github.com/andrew-w-sherman/turk-study) which focuses on curating links as a method of crowd-generating lessons.
diff --git a/eduwiki/.idea/.name b/eduwiki/.idea/.name
new file mode 100644
index 0000000..9055c86
--- /dev/null
+++ b/eduwiki/.idea/.name
@@ -0,0 +1 @@
+eduwiki2
\ No newline at end of file
diff --git a/eduwiki/.idea/dictionaries/Andrew.xml b/eduwiki/.idea/dictionaries/Andrew.xml
new file mode 100644
index 0000000..b42b49b
--- /dev/null
+++ b/eduwiki/.idea/dictionaries/Andrew.xml
@@ -0,0 +1,3 @@
+
+
+
+
+
+ In machine learning, support vector machines (SVMs, also support vector networks[1]) are supervised learning models with associated learning algorithms that analyze data and recognize patterns, used for classification and regression analysis. Given a set of training examples, each marked as belonging to one of two categories, an SVM training algorithm builds a model that assigns new examples into one category or the other, making it a non-probabilistic binary linear classifier. An SVM model is a representation of the examples as points in space, mapped so that the examples of the separate categories are divided by a clear gap that is as wide as possible. New examples are then mapped into that same space and predicted to belong to a category based on which side of the gap they fall on.
+
+ In addition to performing linear classification, SVMs can efficiently perform a non-linear classification using what is called the kernel trick, implicitly mapping their inputs into high-dimensional feature spaces.
+
| Correct answer: {{ topic.description }} | +
Distractor answers: (check the good ones) |
+
| Good + Bad + {{ distractor.snippet }} taken from the page on: {{ distractor.pagetitle }} | +
| + |
Would you consider this a prerequisite for learning about {{ topic.parent }}?+ Yes + No |
+
| + + | +
+ {{ writeup.text }} +
++ {{ main_writeup.text }} +
+tag to be - an empty-element tag (it's not in - HTMLBuilder.empty_element_tags). This means an empty
tag - will be presented as "
", not "". - - The default implementation has no opinion about which tags are - empty-element tags, so a tag will be presented as an - empty-element tag if and only if it has no contents. - "", "
") - self.assertSoupEquals("foo
") - - def test_namespaces_are_preserved(self): - markup = 'A bold statement.
" - with warnings.catch_warnings(record=True) as w: - soup = self.soup(markup, parse_only=strainer) - self.assertEqual( - soup.decode(), self.document_for(markup)) - - self.assertTrue( - "the html5lib tree builder doesn't support parse_only" in - str(w[0].message)) - - def test_correctly_nested_tables(self): - """html5lib inserts tags where other parsers don't.""" - markup = ('