Skip to content

Commit 75c8d58

Browse files
committed
got freebase suggest css roughly working w/ twitter bootstrap, some other minor changes
1 parent b1e9b84 commit 75c8d58

13 files changed

+887
-51
lines changed

jobs/templates/home.html

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
{% extends "site.html" %}
2-
{% load pagination_tags %}
32

43
{% block content %}
5-
{% autopaginate jobs %}
6-
{% paginate %}
74
<table>
85
{% for job in jobs %}
96
<tr>
@@ -12,5 +9,5 @@
129
</tr>
1310
{% endfor %}
1411
</table>
15-
{% paginate %}
12+
{% include "paginator.html" %}
1613
{% endblock %}

jobs/templates/matcher.html

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{% extends "site.html" %}
22

33
{% block extra_head %}
4-
<link type="text/css" rel="stylesheet" href="http://freebaselibs.com/static/suggest/1.3/suggest.min.css">
5-
<script type="text/javascript" src="http://freebaselibs.com/static/suggest/1.3/suggest.min.js"></script>
4+
<link type="text/css" rel="stylesheet" href="/static/css/suggest.min.css">
5+
<script type="text/javascript" src="/static/js/suggest.min.js"></script>
66
<script type="text/javascript">
77

88
$(document).ready(setupMatcher);
@@ -46,7 +46,7 @@
4646

4747
function reloadTable() {
4848
var q = window.location.search;
49-
$("#matcher-table").load('/keywords/matcher/table/' + q, setupMatcher);
49+
$("#matcher-table").load('/keywords/matcher/' + q, setupMatcher);
5050
}
5151

5252
function keywordId(e) {
@@ -60,4 +60,5 @@
6060
<div id="matcher-table">
6161
{% include "matcher_table.html" %}
6262
</div>
63+
{% include "paginator.html" %}
6364
{% endblock %}

jobs/templates/matcher_table.html

+4-9
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
1-
{% load pagination_tags %}
2-
3-
{% autopaginate keywords %}
4-
{% paginate %}
51
<table>
62
<tr>
73
<th>Mentions</th>
84
<th>Job Keyword</th>
95
<th>Freebase Subject</th>
106
<th>Actions</th>
117
</tr>
12-
{% for keyword in keywords %}
13-
<tr id="keyword_{{ keyword.id }}">
8+
{% for keyword in page.object_list %}
9+
<tr id="keyword_{{ keyword.id }}" name="kw_{{ forloop.counter }}">
1410
<td class="keyword-count">{{ keyword.num_jobs }}</td>
1511
<td class="keyword">{{ keyword.name }}</td>
1612
<td class="freebase-concept">
@@ -22,11 +18,10 @@
2218
</td>
2319
<td>
2420
{% if keyword.subject %}
25-
<a class="unlink-keyword" href="#">unlink</a>
21+
<a class="unlink-keyword" href="#kw_{{ forloop.counter }}">unlink</a>
2622
{% endif %}
27-
<a class="ignore-keyword" href="#">ignore</a>
23+
<a class="ignore-keyword" href="#kw_{{ forloop.counter }}">ignore</a>
2824
</td>
2925
</tr>
3026
{% endfor %}
3127
</table>
32-
{% paginate %}

jobs/templates/paginator.html

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{% if paginator.num_pages > 1 %}
2+
3+
<div class="pagination">
4+
<ul>
5+
6+
{% if page.has_previous %}
7+
<li class="prev"><a href="?page={{ page.previous_page_number }}">&lsaquo;&lsaquo; Previous</a></li>
8+
{% else %}
9+
<li class="prev disabled"><a href="#">&lsaquo;&lsaquo; Previous</a></li>
10+
{% endif %}
11+
12+
{% if page.leading_range %}
13+
{% for num in page.leading_range %}
14+
<li {% ifequal page.number num %} class="active" {% endifequal %}><a href="{{ request.path }}?page={{ num }}">{{ num }}</a></li>
15+
{% endfor %}
16+
{% endif %}
17+
18+
{% if page.main_range %}
19+
{% for num in page.main_range %}
20+
<li {% ifequal page.number num %} class="active" {% endifequal %}><a href="{{ request.path }}?page={{ num }}">{{ num }}</a></li>
21+
{% endfor %}
22+
{% endif %}
23+
24+
{% if page.trailing_range %}
25+
{% for num in page.trailing_range %}
26+
<li {% ifequal page.number num %} class="active" {% endifequal %}><a href="{{ request.path }}?page={{ num }}">{{ num }}</a></li>
27+
{% endfor %}
28+
{% endif %}
29+
30+
{% if page.has_next %}
31+
<li class="next"><a href="?page={{ page.next_page_number }}">Next &rsaquo;&rsaquo;</a></li>
32+
{% else %}
33+
<li class="next disabled"><a href="?page={{ page.next_page_number }}">Next &rsaquo;&rsaquo;</a></li>
34+
{% endif %}
35+
36+
</ul>
37+
</div>
38+
{% endif %}

jobs/templates/site.html

+36-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
{% load pagination_tags %}
21
<!doctype html>
32
<html>
43
<head>
@@ -9,10 +8,42 @@
98
{% block extra_head %}{% endblock %}
109
</head>
1110
<body>
12-
<div id="content">
13-
{% block content %}{% endblock %}
11+
<div class="topbar">
12+
<div class="fill">
13+
<div class="container">
14+
<a class="brand" href="/">code4lib-jobs</a>
15+
<ul class="nav">
16+
<li class="active"><a href="/">Home</a></li>
17+
<li><a href="#about">About</a></li>
18+
<li><a href="#contact">Contact</a></li>
19+
</ul>
20+
</div>
21+
</div>
1422
</div>
15-
</body>
16-
</html>
1723

24+
<div class="container">
25+
<div class="content">
26+
<div class="page-header">
27+
<h1>Page name <small>Supporting text or tagline</small></h1>
28+
</div>
29+
<div class="row">
30+
<div class="span16">
31+
<h2>Main content</h2>
32+
{% block content %}{% endblock %}
33+
</div>
34+
<!--
35+
<div class="span4">
36+
<h3>Secondary content</h3>
37+
</div>
38+
-->
39+
</div>
40+
</div>
1841

42+
<footer>
43+
<p>Footer</p>
44+
</footer>
45+
46+
</div>
47+
48+
</body>
49+
</html>

jobs/tests.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
import sys
12
import email
3+
import logging
24
import unittest
35

46
from jobs.models import Job
57

68
import miner
79

10+
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
11+
812
class JobsTests(unittest.TestCase):
913

1014
def setUp(self):
@@ -25,11 +29,19 @@ def test_email_to_job(self):
2529
# test employer
2630
#self.assertEqual(j.from_domain, 'miami.edu')
2731

28-
def test_multipart_email(self):
32+
def test_multipart(self):
2933
msg = email.message_from_file(open("test-data/job-multipart-email"))
3034
j = miner.email_to_job(msg)
3135
self.assertEqual(j.title, "Library System Administrator Position")
3236

37+
def test_missing_charset(self):
38+
msg = email.message_from_file(open("test-data/job-email-missing-charset"))
39+
self.assertTrue(msg)
40+
self.assertTrue(miner.is_job_email(msg))
41+
j = miner.email_to_job(msg)
42+
self.assertTrue(j)
43+
self.assertEqual(j.title, "Job Posting: Programmer/Analyst 2, The University of Chicago Library")
44+
3345
class MinerTests(unittest.TestCase):
3446
text = "Experience in web application, web services development, and XM. Experience with Flash, AJAX, or other highly interactive web user interface development, digital video, and audio formats, and technologies and/or digital repositories (e.g., Fedora). Combinations of related education and experience will be considered."
3547

jobs/views.py

+29-13
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,46 @@
11
# Create your views here.
22

33
from django.db.models import Count
4-
from django.shortcuts import render, get_object_or_404, redirect
54
from django.core.urlresolvers import reverse
5+
from django.shortcuts import render, get_object_or_404, redirect
66

7-
from jobs import models
7+
from jobs4lib.jobs import models
8+
from jobs4lib.paginator import DiggPaginator
89

910
def home(request):
1011
jobs = models.Job.objects.all().order_by('-post_date')
11-
return render(request, 'home.html', {'jobs': jobs})
12+
paginator = DiggPaginator(jobs, 25, body=8)
13+
page = paginator.page(request.GET.get("page", 1))
14+
context = {
15+
'jobs': page.object_list,
16+
'page': page,
17+
'paginator': paginator,
18+
}
19+
return render(request, 'home.html', context)
1220

1321
def job(request, id):
1422
j = get_object_or_404(models.Job, id=id)
1523
return render(request, "job.html", {"job": j})
1624

1725
def matcher(request):
18-
return render(request, "matcher.html", {"keywords": _kw()})
26+
keywords = models.Keyword.objects.all()
27+
keywords = keywords.annotate(num_jobs=Count("jobs"))
28+
keywords = keywords.filter(num_jobs__gt=1, ignore=False)
29+
keywords = keywords.order_by("-num_jobs")
30+
31+
paginator = DiggPaginator(keywords, 25, body=8)
32+
page = paginator.page(request.GET.get("page", 1))
33+
if request.is_ajax():
34+
template = "matcher_table.html"
35+
else:
36+
template = "matcher.html"
37+
return render(request, template, {"page": page, "paginator": paginator})
1938

2039
def matcher_table(request):
21-
return render(request, "matcher_table.html", {"keywords": _kw()})
40+
keywords = _kw()
41+
paginator = DiggPaginator(keywords, 25, body=8)
42+
page = paginator.page(request.GET.get("page", 1))
43+
return render(request, "matcher_table.html", {"page": page})
2244

2345
def keyword(request, id):
2446
k = get_object_or_404(models.Keyword, id=id)
@@ -31,8 +53,7 @@ def keyword(request, id):
3153
return render(request, "keyword.html", {"keyword": k})
3254

3355
def subjects(request):
34-
35-
# adding a new subject
56+
# add a new subject
3657
if request.method == "POST":
3758
s, created = models.Subject.objects.get_or_create(
3859
name=request.POST.get('subjectName')
@@ -51,12 +72,7 @@ def subjects(request):
5172

5273
def subject(request, slug):
5374
s = get_object_or_404(models.Subject, slug=slug)
54-
j = models.Job.objects.filter(keywords__subject=s)
75+
j = models.Job.objects.filter(keywords__subject=s).distinct()
5576
j = j.order_by('-post_date')
5677
return render(request, "subject.html", {"subject": s, "jobs": j})
5778

58-
def _kw():
59-
kw = models.Keyword.objects.all()
60-
kw = kw.annotate(num_jobs=Count("jobs"))
61-
kw = kw.filter(num_jobs__gt=1, ignore=False)
62-
return kw.order_by("-num_jobs")

miner.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@
1919
NOUN_CODES = ["NNP"]
2020

2121
def email_to_job(msg):
22+
logging.info("looking at email with subject: %s", msg['subject'])
23+
2224
if not is_job_email(msg):
2325
return None
2426

2527
if Job.objects.filter(email_message_id=msg['message-id']).count() == 1:
2628
return None
2729

28-
logging.info("parsing email %s", msg['message-id'])
30+
logging.info("parsing job email %s", msg['message-id'])
2931

3032
j = Job()
3133
j.contact_name, j.contact_email = rfc822.parseaddr(msg['from'])
@@ -36,6 +38,7 @@ def email_to_job(msg):
3638
#j.from_domain = j.from_address.split('@')[1]
3739

3840
j.title = re.sub("^\[CODE4LIB\] ", "", msg['subject'])
41+
j.title = re.sub("[\n\r]", "", j.title)
3942
j.email_message_id = msg['message-id']
4043
j.description = get_body(msg)
4144

@@ -77,7 +80,8 @@ def get_body(msg):
7780
if msg.is_multipart():
7881
text_part = None
7982
for m in msg.get_payload():
80-
if m['content-type'].startswith('text'):
83+
print m['content-type']
84+
if m['content-type'].lower().startswith('text'):
8185
text_part = m
8286
break
8387
if not text_part:
@@ -87,8 +91,8 @@ def get_body(msg):
8791

8892
charset = msg.get_content_charset()
8993
if not charset:
90-
logging.warn("no charset")
91-
return None
94+
logging.warn("no charset assuming utf8")
95+
charset = "utf8"
9296

9397
try:
9498
codec = codecs.getreader(charset)

0 commit comments

Comments
 (0)