Fix lodgeit used in puppet

It appears the official lodgeit was abandoned in a broken state (I can't get it to work)
This branch switches to a hg branch of lodgeit that works and removes the need for the db hacks in the process

Change-Id: Ic4860e61b26bbde9bac7d5767e94ce066d244f78
This commit is contained in:
Andrew Hutchings 2012-02-01 11:13:13 +00:00
parent e3166c9102
commit b0ae2fea97
4 changed files with 27 additions and 239 deletions

View File

@ -1,202 +0,0 @@
# -*- coding: utf-8 -*-
"""
lodgeit.database
~~~~~~~~~~~~~~~~
Database fun :)
:copyright: 2007-2008 by Armin Ronacher, Christopher Grebs.
:license: BSD
"""
import time
import difflib
from datetime import datetime
from werkzeug import cached_property
from sqlalchemy import MetaData, Integer, Text, DateTime, ForeignKey, \
String, Boolean, Table, Column, select, and_, func
from sqlalchemy.orm import scoped_session, create_session, backref, relation
from sqlalchemy.orm.scoping import ScopedSession
from lodgeit import local
from lodgeit.utils import generate_paste_hash
from lodgeit.lib.highlighting import highlight, preview_highlight, LANGUAGES
from sqlalchemy.orm import mapper as sqla_mapper
def session_mapper(scoped_session):
def mapper(cls, *arg, **kw):
cls.query = scoped_session.query_property()
return sqla_mapper(cls, *arg, **kw)
return mapper
session = scoped_session(lambda: create_session(local.application.engine),
scopefunc=local._local_manager.get_ident)
metadata = MetaData()
pastes = Table('pastes', metadata,
Column('paste_id', Integer, primary_key=True),
Column('code', Text),
Column('parent_id', Integer, ForeignKey('pastes.paste_id'),
nullable=True),
Column('pub_date', DateTime),
Column('language', String(30)),
Column('user_hash', String(40), nullable=True),
Column('handled', Boolean, nullable=False),
Column('private_id', String(40), unique=True, nullable=True)
)
class Paste(object):
"""Represents a paste."""
def __init__(self, code, language, parent=None, user_hash=None,
private=False):
if language not in LANGUAGES:
language = 'text'
self.code = u'\n'.join(code.splitlines())
self.language = language
if isinstance(parent, Paste):
self.parent = parent
elif parent is not None:
self.parent_id = parent
self.pub_date = datetime.now()
self.handled = False
self.user_hash = user_hash
self.private = private
@staticmethod
def get(identifier):
"""Return the paste for an identifier. Private pastes must be loaded
with their unique hash and public with the paste id.
"""
if isinstance(identifier, basestring) and not identifier.isdigit():
return Paste.query.filter(Paste.private_id == identifier).first()
return Paste.query.filter(
(Paste.paste_id == int(identifier)) &
(Paste.private_id == None)
).first()
@staticmethod
def find_all():
"""Return a query for all public pastes ordered by the id in reverse
order.
"""
return Paste.query.filter(Paste.private_id == None) \
.order_by(Paste.paste_id.desc())
@staticmethod
def count():
"""Count all pastes."""
s = select([func.count(pastes.c.paste_id)])
return session.execute(s).fetchone()[0]
@staticmethod
def resolve_root(identifier):
"""Find the root paste for a paste tree."""
paste = Paste.get(identifier)
if paste is None:
return
while paste.parent_id is not None:
paste = paste.parent
return paste
@staticmethod
def fetch_replies():
"""Get the new replies for the ower of a request and flag them
as handled.
"""
s = select([pastes.c.paste_id],
Paste.user_hash == local.request.user_hash
)
paste_list = Paste.query.filter(and_(
Paste.parent_id.in_(s),
Paste.handled == False,
Paste.user_hash != local.request.user_hash,
)).order_by(pastes.c.paste_id.desc()).all()
to_mark = [p.paste_id for p in paste_list]
session.execute(pastes.update(pastes.c.paste_id.in_(to_mark),
values={'handled': True}))
return paste_list
def _get_private(self):
return self.private_id is not None
def _set_private(self, value):
if not value:
self.private_id = None
return
if self.private_id is None:
while 1:
self.private_id = generate_paste_hash()
paste = Paste.query.filter(Paste.private_id ==
self.private_id).first()
if paste is None:
break
private = property(_get_private, _set_private, doc='''
The private status of the paste. If the paste is private it gets
a unique hash as identifier, otherwise an integer.
''')
del _get_private, _set_private
@property
def identifier(self):
"""The paste identifier. This is a string, the same the `get`
method accepts.
"""
if self.private:
return self.private_id
return str(self.paste_id)
@property
def url(self):
"""The URL to the paste."""
return '/show/%s/' % self.identifier
def compare_to(self, other, context_lines=4, template=False):
"""Compare the paste with another paste."""
udiff = u'\n'.join(difflib.unified_diff(
self.code.splitlines(),
other.code.splitlines(),
fromfile='Paste #%s' % self.identifier,
tofile='Paste #%s' % other.identifier,
lineterm='',
n=context_lines
))
if template:
from lodgeit.lib.diff import prepare_udiff
diff, info = prepare_udiff(udiff)
return diff and diff[0] or None
return udiff
@cached_property
def parsed_code(self):
"""The paste as rendered code."""
return highlight(self.code, self.language)
def to_xmlrpc_dict(self):
"""Convert the paste into a dict for XMLRCP."""
return {
'paste_id': self.paste_id,
'code': self.code,
'parsed_code': self.parsed_code,
'pub_date': int(time.mktime(self.pub_date.timetuple())),
'language': self.language,
'parent_id': self.parent_id,
'url': self.url
}
def render_preview(self, num=5):
"""Render a preview for this paste."""
return preview_highlight(self.code, self.language, num)
mapper= session_mapper(session)
mapper(Paste, pastes, properties={
'children': relation(Paste,
primaryjoin=pastes.c.parent_id==pastes.c.paste_id,
cascade='all',
backref=backref('parent', remote_side=[pastes.c.paste_id])
)
})

View File

@ -40,7 +40,7 @@ class lodgeit {
# otherwise get a new clone of it # otherwise get a new clone of it
exec { "get_lodgeit": exec { "get_lodgeit":
command => "hg clone http://dev.pocoo.org/hg/lodgeit-main /tmp/lodgeit-main", command => "hg clone https://bitbucket.org/dcolish/lodgeit-main /tmp/lodgeit-main",
path => "/bin:/usr/bin", path => "/bin:/usr/bin",
onlyif => "test ! -d /tmp/lodgeit-main" onlyif => "test ! -d /tmp/lodgeit-main"
} }

View File

@ -33,13 +33,6 @@ define lodgeit::site($port, $image="") {
} }
} }
# Database file needs replacing to be compatible with SQLAlchemy 0.7
file { "/srv/lodgeit/${name}/lodgeit/database.py":
replace => true,
source => 'puppet:///modules/lodgeit/database.py'
}
file { "/srv/lodgeit/${name}/manage.py": file { "/srv/lodgeit/${name}/manage.py":
mode => 755, mode => 755,
replace => true, replace => true,

View File

@ -1,11 +1,12 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"> "http://www.w3.org/TR/html4/loose.dtd">
<html> <html>
<head> <head>
<title>{{ page_title|e }} | LodgeIt!</title> <title>{{ page_title|e }} | LodgeIt!</title>
<link rel="stylesheet" href="/static/style.css" type="text/css"> <link rel="stylesheet" href="/static/style.css" type="text/css" />
<link rel="stylesheet" href="/static/print.css" type="text/css" media="print"> <link rel="stylesheet" href="/static/print.css" type="text/css" media="print" />
<script type="text/javascript" src="/static/jquery.js"></script> <script type="text/javascript" src="/static/jquery.js"></script>
<script type="text/javascript" src="/static/jquery.autocomplete.js"></script>
<script type="text/javascript" src="/static/cookie.js"></script> <script type="text/javascript" src="/static/cookie.js"></script>
<script type="text/javascript" src="/static/lodgeit.js"></script> <script type="text/javascript" src="/static/lodgeit.js"></script>
{%- if css %} {%- if css %}
@ -23,23 +24,26 @@
<% else %> <% else %>
<%= name.capitalize %> Pastebin <%= name.capitalize %> Pastebin
<% end %> <% end %>
</h1></div> </h1>
</div>
<ul id="navigation"> <ul id="navigation">
{%- for href, id, caption in [ {%- for href, id, caption in [
('/', 'new', _('New')), ('pastes/new_paste', 'new', _('New')),
('/all/', 'all', _('All')), ('pastes/show_all', 'all', _('All')),
('/about/', 'about', _('About')), ('static/about', 'about', _('About')),
('/help/', 'help', '?') ('static/help', 'help', '?')
] %} ] %}
<li{% if active_page == id %} class="active"{% endif %}> <li {% if active_page == id %} class="active"{% endif %} >
<a href="{{ href|e }}">{{ caption|e }}</a> <a href="{{ url_for(href) | e }}">{{ caption|e }}</a>
</li> </li>
{%- endfor %} {%- endfor %}
</ul> </ul>
{# <ul id="languages"> {# <ul id="languages">
{% for lang, name in i18n_languages %} {% for lang, name in i18n_languages %}
<li{% if request.locale.language == lang %} class="active"{% endif %}> <li {% if request.locale.language == lang %}class="active"{% endif %}>
<a href="{{ '/language/%s'|format(lang) }}"><img alt="{{ lang }}" src="{{ '/static/flags/%s.png'|format(lang) }}"></a> <a href="{{ url_for('pastes/new_paste', language='%s' % lang) }}">
<img alt="{{ lang }}" src="{{ '/static/flags/%s.png' % lang }}" />
</a>
</li> </li>
{% endfor %} {% endfor %}
</ul> #} </ul> #}
@ -53,9 +57,9 @@
paste=paste.paste_id, paste_url=paste.url|e, parent_url=paste.parent.url|e %} paste=paste.paste_id, paste_url=paste.url|e, parent_url=paste.parent.url|e %}
on {{ date }} someone replied to your paste on {{ date }} someone replied to your paste
<a href="{{ parent_url }}">#{{ parent }}</a>, <a href="{{ parent_url }}">#{{ parent }}</a>,
in paste <a href="{{ paste_url }}">#{{ paste }}</a>. Click here to in paste <a href="{{ paste_url }}">#{{ paste }}</a>. Click here to {% endtrans %}
<a href="/compare/{{ paste }}/{{ parent }}/">compare <a href="{{ url_for('pastes/compare_paste', new_id=paste.paste_id, old_id=paste.parent.paste_id) }}">
those two pastes</a>.{% endtrans %} {%- trans %}compare those two pastes{% endtrans %}</a>.
</p> </p>
{% endfor %} {% endfor %}
<p><a href="javascript:LodgeIt.hideNotification()">{% trans %}hide this notification{% endtrans %}</a></p> <p><a href="javascript:LodgeIt.hideNotification()">{% trans %}hide this notification{% endtrans %}</a></p>
@ -67,25 +71,18 @@
Welcome to the LodgeIt pastebin. In order to use the notification feature Welcome to the LodgeIt pastebin. In order to use the notification feature
a 31 day cookie with an unique ID was created for you. The lodgeit database a 31 day cookie with an unique ID was created for you. The lodgeit database
does not store any information about you, it's just used for an advanced does not store any information about you, it's just used for an advanced
pastebin experience :-). Read more on the <a href="/about/#privacy">about pastebin experience :-). Read more on the {% endtrans -%}
lodgeit</a> page. Have fun :-){%- endtrans -%} <a href="{{ url_for('static/about') }}#privacy">{% trans %}about lodgeit{% endtrans %}</a>
{%- trans %} page. Have fun :-){%- endtrans -%}
</p>
<p>
<a href="javascript:LodgeIt.hideNotification()">{% trans %}hide this notification{% endtrans %}</a>
</p> </p>
<p><a href="javascript:LodgeIt.hideNotification()">{% trans %}hide this notification{% endtrans %}</a></p>
</div> </div>
{% endif -%} {% endif -%}
{% block body %}{% endblock -%} {% block body %}{% endblock -%}
<div class="footer"></div> <div class="footer"></div>
</div> </div>
</div> </div>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-27485426-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</body> </body>
</html> </html>