Skip to content

Commit 642ad60

Browse files
committed
Merge branch 'hotfix-0.3.2'
2 parents 121de50 + 114c2c8 commit 642ad60

11 files changed

Lines changed: 380 additions & 84 deletions

File tree

baleen/models.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323

2424
from datetime import datetime
2525
from baleen.config import settings
26+
from baleen.utils.timez import humanizedelta
27+
2628

2729
##########################################################################
2830
## Module Constants
@@ -174,9 +176,62 @@ def pre_save(cls, sender, document, **kwargs):
174176
'collection': 'jobs',
175177
}
176178

179+
def duration(self, humanize=False):
180+
"""
181+
Returns the timedelta of the duration.
182+
"""
183+
finished = self.finished or datetime.now()
184+
delta = finished - self.started
185+
186+
if humanize:
187+
return humanizedelta(
188+
days=delta.days,
189+
seconds=delta.seconds,
190+
microseconds=delta.microseconds
191+
)
192+
return delta
193+
177194
def __unicode__(self):
178195
return "{} Job {}".format(self.name, self.jobid)
179196

197+
198+
class Log(me.DynamicDocument):
199+
200+
level = me.DictField()
201+
message = me.StringField(max_length=4096)
202+
host = me.StringField(max_length=255)
203+
user = me.StringField(max_length=255)
204+
error = me.DictField()
205+
logger = me.StringField(max_length=255)
206+
asctime = me.StringField(max_length=64)
207+
timestamp = me.DateTimeField()
208+
209+
meta = {
210+
'collection': 'logs',
211+
}
212+
213+
@property
214+
def bootstrap_class(self):
215+
"""
216+
Uses the log level to determine the bootstrap class.
217+
"""
218+
levels = {
219+
"DEBUG": "success",
220+
"INFO": "info",
221+
"WARNING": "warning",
222+
"WARN": "warning",
223+
"ERROR": "danger",
224+
"CRITICAL": "danger",
225+
}
226+
227+
key = self.level.get('name')
228+
if key and key in levels:
229+
return levels[key]
230+
return ""
231+
232+
def __unicode__(self):
233+
return self.message
234+
180235
##########################################################################
181236
## Signals
182237
##########################################################################

baleen/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
__version_info__ = {
2121
'major': 0,
2222
'minor': 3,
23-
'micro': 1,
23+
'micro': 2,
2424
'releaselevel': 'final',
2525
'serial': 0,
2626
}

baleen/www/app.py

Lines changed: 72 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,79 +18,122 @@
1818
##########################################################################
1919

2020
import os
21-
import codecs
22-
import datetime
2321
import baleen
24-
import baleen.models as db
2522

26-
from itertools import islice
27-
from flask import Flask, render_template
2823
from baleen.config import settings
24+
from baleen.models import Feed, Post, Job, Log
25+
from baleen.utils.timez import HUMAN_DATETIME
2926

27+
from flask import Flask, render_template, request
28+
from flask.ext.mongoengine import MongoEngine
29+
from flask_humanize import Humanize
3030

3131
##########################################################################
3232
## Flask Application
3333
##########################################################################
3434

3535
# set up an app instance
3636
app = Flask(__name__)
37+
3738
# set debug to true to get debug pages when there is an error
3839
app.debug = settings.debug
3940

41+
# configure the app with the confire settings
42+
app.config['MONGODB_SETTINGS'] = {
43+
'db': settings.database.name,
44+
'host': settings.database.host,
45+
'port': settings.database.port,
46+
}
47+
48+
# connect to the database using the Flask extension
49+
db = MongoEngine(app)
50+
51+
# add the humanize extension
52+
humanize = Humanize(app)
4053

4154
##########################################################################
4255
## Routes
4356
##########################################################################
4457

4558
@app.route("/")
4659
def index():
47-
# connect to the database
48-
db.connect()
60+
"""
61+
Displays an index page with the feed listing
62+
"""
4963
# get all the stuff we want
50-
feeds = db.Feed.objects()
64+
feeds = Feed.objects()
5165
feed_count = feeds.count()
52-
topics = set([feed.category for feed in db.Feed.objects.only('category')])
66+
topics = set([feed.category for feed in Feed.objects.only('category')])
5367
feeds_topics_counts = len(topics)
5468
feeds_topics = {
55-
topic: db.Feed.objects(category=topic)
69+
topic: Feed.objects(category=topic)
5670
for topic in topics
5771
}
5872

5973
# load all the data into the templates/feed_list.html template
60-
return render_template('feed_list.html',
74+
return render_template('index.html',
6175
feeds=feeds,
6276
feeds_topics=feeds_topics,
6377
feed_count=feed_count,
6478
topic_count=feeds_topics_counts)
6579

66-
def get_logs():
67-
infile = settings.logfile
68-
file = reversed(list(codecs.open(infile,'r',encoding='utf8')))
69-
logitems = islice(file,20)
70-
return logitems
7180

7281
@app.route("/status/")
73-
def latest_job():
74-
# get the last job executed
75-
db.connect()
82+
def status():
83+
"""
84+
Displays the current Baleen status and job listing
85+
"""
7686
version = baleen.get_version()
77-
counts = [db.Feed.objects.count(),db.Post.objects.count(),db.Job.objects.count()]
78-
latest_job = db.Job.objects.order_by('-started').first()
79-
latest_feed = db.Feed.objects.order_by('-updated').first()
80-
latest_post = db.Post.objects.order_by('-id').first()
81-
td = datetime.datetime.now() - latest_job.started
82-
running_time = str(td)
83-
logitems = get_logs()
87+
counts = {
88+
'feeds': Feed.objects.count(),
89+
'posts': Post.objects.count(),
90+
'jobs': Job.objects.count(),
91+
}
92+
latest_job = Job.objects.order_by('-started').first()
93+
latest_feed = Feed.objects.order_by('-updated').first()
94+
latest_post = Post.objects.order_by('-id').first()
8495

8596
# load all data into job_status template
86-
return render_template('job_status.html',
97+
return render_template('status.html',
8798
latest_job=latest_job,
8899
latest_feed=latest_feed,
89100
latest_post=latest_post,
90101
version=version,
91102
counts=counts,
92-
running_time=running_time,
93-
logitems=logitems)
103+
dtfmt=HUMAN_DATETIME,
104+
recent_jobs=Job.objects.order_by('-started').limit(10))
105+
106+
107+
@app.route("/logs/")
108+
def logs():
109+
"""
110+
Displays log records from the Mongo Database.
111+
This is paginated and allows flexible per-page counts (max 200 record).
112+
"""
113+
# Get pagination information for request
114+
page = int(request.args.get('page', 1))
115+
per_page = min(int(request.args.get('per_page', 50)), 200)
116+
117+
# Compute the pagination variables
118+
n_logs = Log.objects.count()
119+
n_pages = (n_logs + per_page // 2) // per_page
120+
nextp = page + 1 if page + 1 <= n_pages else None
121+
prevp = page - 1 if page > 1 else None
122+
123+
# Perform query
124+
offset = (page - 1) * per_page
125+
logs = Log.objects.order_by('-id').skip(offset).limit(per_page)
126+
127+
return render_template(
128+
'logs.html',
129+
page = page,
130+
num_pages = n_pages,
131+
per_page = per_page,
132+
logs = logs,
133+
num_logs = n_logs,
134+
next = nextp,
135+
prev = prevp,
136+
)
94137

95138

96139
##########################################################################

baleen/www/templates/components/navbar.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@
2626
Status
2727
</a>
2828
</li>
29+
<li>
30+
<a href="/logs/">
31+
<i class="fa fa-book"></i>
32+
Logs
33+
</a>
34+
</li>
2935
</ul>
3036

3137
<ul class="nav navbar-nav navbar-right">

baleen/www/templates/job_status.html

Lines changed: 0 additions & 52 deletions
This file was deleted.

baleen/www/templates/logs.html

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{% extends 'base.html' %}
2+
{% block title %}Baleen Log Records{% endblock %}
3+
4+
{% block body %}
5+
<div class="container">
6+
7+
<!-- Page Title -->
8+
<div id="top" class="row">
9+
<div class="col-xs-12">
10+
<div class="page-header">
11+
<h1>Log Records</h1>
12+
<p class="text-muted">Page {{ page }} of {{ num_pages }} &middot; {{ num_logs|humanize('intcomma') }} log records</small>
13+
</div>
14+
</div>
15+
</div>
16+
17+
<!-- Log table -->
18+
<div class="row">
19+
<div class="col-md-12">
20+
21+
<table class="table table-hover table-bordered">
22+
<tbody>
23+
{% for log in logs %}
24+
<tr>
25+
<td class="{{ log.bootstrap_class }}">{{ log.message }}</td>
26+
</tr>
27+
{% else %}
28+
<tr>
29+
<td>No log records yet</td>
30+
</tr>
31+
{% endfor %}
32+
</tbody>
33+
</table>
34+
35+
<nav>
36+
<ul class="pager">
37+
<li class="previous{% if not prev %} disabled{% endif %}"><a href="{% if prev %}/logs/?page={{ prev }}&per_page={{ per_page }}{% else %}#{% endif %}">
38+
<span aria-hidden="true">&larr;</span> Newer
39+
</a></li>
40+
<li class="next{% if not next %} disabled{% endif %}"><a href="{% if next %}/logs/?page={{ next }}&per_page={{ per_page }}{% else %}#{% endif %}">
41+
Older <span aria-hidden="true">&rarr;</span>
42+
</a></li>
43+
</ul>
44+
</nav>
45+
</div>
46+
</div>
47+
48+
{% endblock %}

0 commit comments

Comments
 (0)