Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ Misc.
----------
To run request.py or main.py, you need to set REFLECTION_ID to your
HS login and REFLECTION_SECRET to your HS password in your environmental
variables.
variables.


Ignore
----------
Expand Down
27 changes: 26 additions & 1 deletion reflection_scraper.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from bs4 import BeautifulSoup
import os
import re
import string

#create_frequency_dict can't handle keywords with characters like
#+, *, or ? that have special meanings in regex
Expand All @@ -14,6 +15,30 @@ def get_keywords(filename):
keywords.append(line.strip())
return keywords

extra_stops = ['code', 'planned', 'learn', 'learned', 'learning', 'will', 'continue', 'time', "i'm", 'today', 'tomorrow', 'yesterday']

def generate_popular(reflections_mapping, extra_stops):
'''input: mapping of names to reflections text
output: list of top 50 popular 'key' words'''
word_bucket = {}
file = open('stopword.txt', 'r')
dump = file.read()
file.close()
stopwords = dump.split()
for person in reflections_mapping:
words = reflections_mapping[person].strip().lower().split()
for word in words:
wordy = word.strip(string.punctuation+string.whitespace)
if stopwords.count(wordy) == 0:
if wordy in word_bucket:
word_bucket[wordy] += 1
else:
word_bucket[wordy] = 1
sorted = word_bucket.items()
sorted.sort(key=lambda x: x[1])
sorted.reverse()
return sorted[0:50]

def get_file_names(dir_path):
'''input: path to directory
output: list of file names in directory'''
Expand Down Expand Up @@ -77,4 +102,4 @@ def get_peoples_words():
reflections = get_reflections(file_names)
reflections_dict = scrape_reflections(reflections)
db_entries = create_db_entries(keywords, reflections_dict)
return db_entries
return db_entries
6 changes: 3 additions & 3 deletions request.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ def get_session(email, password, host='https://www.hackerschool.com'):
def download_reflections_pages():
'''downloads all reflection pages and stores them in a folder called html'''
host = 'https://hackerschool.com'
email = os.environ.get('REFLECTION_ID')
password = os.environ.get('REFLECTION_SECRET')
s = get_session(email, password)
# email = os.environ.get('REFLECTION_ID')
# password = os.environ.get('REFLECTION_SECRET')
s = get_session('jenna.zeigen@gmail.com', 'cataphora953')

if not os.path.exists ("html"):
os.mkdir ("html")
Expand Down
28 changes: 22 additions & 6 deletions server.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@
from pymongo import Connection
import json
import os
import re

import reflection_scraper

app = Flask(__name__)
connection = Connection()
db = connection.reflections
collection = db.words

reflections_dict = {}

@app.route('/')
def start():
return render_template('index.html')
Expand All @@ -27,16 +32,12 @@ def get_icon():
#described above.

def get_JSON(name):

print "got request for " + name

match_data = {}

match_data['name'] = name
match_data['children'] = []

doc = collection.find_one({'name':name})
print "name: " + name
my_keywords = doc['keywords'].keys()

for keyword in my_keywords:
Expand Down Expand Up @@ -67,9 +68,24 @@ def get_JSON(name):
match_data['children'].append(word_data)

return json.dumps(match_data)

@app.route('/<name>/<term>')
def get_mentions(name, term):
global reflections_dict
if len(reflections_dict) == 0:
reflections_dict = get_ref_dict(name, term)
print reflections_dict
places = [m.start() for m in re.finditer(term, reflections_dict[name])]
snippets = []
for loc in places:
snippets.append(['...' + reflections_dict[name][loc-100:loc+100] + '...'])
return json.dumps(snippets)

def get_ref_dict(name, term):
return reflection_scraper.scrape_reflections(reflection_scraper.get_reflections(reflection_scraper.get_file_names('html/')))

if __name__ == '__main__':
port = int(os.environ.get('PORT', 5000))
app.run(host='0.0.0.0', port=port)
port = int(os.environ.get('PORT', 5757))
app.run(debug=True)


38 changes: 38 additions & 0 deletions static/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,42 @@ circle {
font-size: 14px;
letter-spacing: 1px;
color: #574D37;
}

.tooltip {
position: absolute;
background-color: white;
padding: 5px;
border-radius: 10px;
box-shadow: 0 0 15px 5px #E3E3E3;
width: 300px;

}

.close{
width:15px;
height:15px;
border-radius:50px;
font-size:.75em;
font-family: sans-serif;
color: white;
text-align:center;
text-decoration:none;
background:red;
display: inline-block;
margin: 5px;
float: left;
}

.close:hover {
background-color: rgb(175,10,10);
cursor: pointer;
}

.hidden {
display: none;
}

.not-option {
color: #999;
}
62 changes: 54 additions & 8 deletions static/tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
//see original at http://mbostock.github.com/d3/ex/tree.html

var generate_tree = function(){
console.log("entering generate tree")
var radius = 960 / 2;

var tree = d3.layout.tree()
Expand Down Expand Up @@ -37,8 +36,18 @@ var generate_tree = function(){
.data(nodes)
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; });

.attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; })
.attr('id', function(d) {
if (d.parent){
return d.name + '-'+ d.parent.name
}
else {
return d.name
}

})
.attr('title', function(d){return d.depth})

node.append("circle")
.attr("r", 4.5);

Expand All @@ -48,6 +57,48 @@ var generate_tree = function(){
.attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
.attr("transform", function(d) { return d.x < 180 ? "translate(8)" : "rotate(180)translate(-8)"; })
.text(function(d) { return d.name; });

$('.node').click(function(e) {
var name = $.trim($(this).attr('id').split('-')[0].split('(')[0])
var parent = $(this).attr('id').split('-')[1]
var closed = null;
//if something's already open
if ($('.tooltip').length > 0) {
closed = $('.tooltip').remove()
}
//if it doesn't belong to just clicked thing
if ((!closed) || (closed.attr('id') !== name + '-' + parent)){
var depth = $(this).attr('title')
var x = e.pageX
var y = e.pageY-100
if (depth == 2){
$.get('/' + name + '/' + parent, function(data){
var lines = $.parseJSON(data)
var currDisp = 0
d3.select('#chart').append('div')
.style('top', y + 'px')
.style('left', x + 'px')
.attr('class', 'tooltip')
.attr('id', name + '-' + parent)
.html("<span class='close'>x</span> <p id='snip'>" + lines[currDisp]+ "</p><div><span id ='prev'>Previous</span> <span id='next'>Next</span></div>")

$('.close').click(function(){
$(this).parent().remove()
})

$('#next').click(function() {
currDisp = Math.min(currDisp+1, lines.length-1)
$('#snip').text(lines[currDisp][0])
})

$('#prev').click(function() {
currDisp = Math.max(currDisp-1, 0)
$('#snip').text(lines[currDisp][0])
})
});
}
}
})
});
};

Expand All @@ -57,10 +108,5 @@ $(document).ready(function(){
generate_tree();
return false;
});
$('#name').keypress(function(e){
if (e.keyCode===13) {
generate_tree();
}
});
$('#name').focus()
});