from meta import *\r
from node import *\r
-from user import *
\ No newline at end of file
+from user import *\r
+from page import *
\ No newline at end of file
\r
return _("%(user)s accepted %(answerer)s answer on %(asker)s question %(question)s") % {\r
'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),\r
- 'answerer': self.hyperlink(answer.author.get_profile_url(), self.friendly_username(viewer, answer.author)),\r
+ 'answerer': self.hyperlink(answer.author.get_profile_url(), self.friendly_ownername(viewer, answer.author)),\r
'asker': asker,\r
'question': self.hyperlink(question.get_absolute_url(), question.title)\r
}\r
--- /dev/null
+from django.utils.translation import ugettext as _
+from forum.models.action import ActionProxy
+from forum.models import Page
+
+class NewPageAction(ActionProxy):
+ verb = _("created")
+
+ def process_data(self, **data):
+ title = data.pop('title')
+ body = data.pop('content')
+
+ page = Page(author=self.user, title=title, body=body, extra=data)
+ page.save()
+ self.node = page
+
+ def describe(self, viewer=None):
+ return _("%(user)s created a new page titled %(page)s") % {
+ 'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),
+ 'page': self.hyperlink(self.node.get_absolute_url(), self.node.title)
+ }
+
+class EditPageAction(ActionProxy):
+ verb = _("edited")
+
+ def process_data(self, **data):
+ title = data.pop('title')
+ body = data.pop('content')
+
+ if (title != self.node.title) and (body != self.node.body):
+ self.node.create_revision(self.user, title=title, body=body)
+
+ self.node.extra = data
+ self.node.save()
+
+ def describe(self, viewer=None):
+ return _("%(user)s edited the page titled %(page)s") % {
+ 'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),
+ 'page': self.hyperlink(self.node.get_absolute_url(), self.node.title)
+ }
+
+class PublishAction(ActionProxy):
+ verb = _("published")
+
+ def process_action(self):
+ self.node.marked = True
+ self.node.nstate.published = self
+ self.node.save()
+
+ def cancel_action(self):
+ self.node.marked = False
+ self.node.nstate.published = None
+ self.node.save()
+
+ def describe(self, viewer=None):
+ return _("%(user)s published a new page titled %(page)s") % {
+ 'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),
+ 'page': self.hyperlink(self.node.get_absolute_url(), self.node.title)
+ }
def describe(self, viewer=None):
return _("%(user)s edited %(hes_or_your)s %(profile_link)s") % {
'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),
- 'hes_or_your': self.viewer_or_user_verb(viewer, self.user, _('your'), _('hes')),
+ 'hes_or_your': self.viewer_or_user_verb(viewer, self.user, _('your'), _('his')),
'profile_link': self.hyperlink(self.user.get_profile_url(), _('profile')),
}
--- /dev/null
+from qanda import *
+from admin import *
+from auth import *
+from general import *
--- /dev/null
+import socket
+from django import forms
+from django.utils.translation import ugettext as _
+from qanda import TitleField, EditorField
+from forum import settings
+
+class IPListField(forms.CharField):
+ def clean(self, value):
+ ips = [ip.strip() for ip in value.strip().strip(',').split(',')]
+ iplist = []
+
+ if len(ips) < 1:
+ raise forms.ValidationError(_('Please input at least one ip address'))
+
+ for ip in ips:
+ try:
+ socket.inet_aton(ip)
+ except socket.error:
+ raise forms.ValidationError(_('Invalid ip address: %s' % ip))
+
+ if not len(ip.split('.')) == 4:
+ raise forms.ValidationError(_('Please use the dotted quad notation for the ip addresses'))
+
+ iplist.append(ip)
+
+ return iplist
+
+class MaintenanceModeForm(forms.Form):
+ ips = IPListField(label=_('Allow ips'),
+ help_text=_('Comma separated list of ips allowed to access the site while in maintenance'),
+ required=True,
+ widget=forms.TextInput(attrs={'class': 'longstring'}))
+
+ message = forms.CharField(label=_('Message'),
+ help_text=_('A message to display to your site visitors while in maintainance mode'),
+ widget=forms.Textarea)
+
+
+TEMPLATE_CHOICES = (
+ ('default', _('Default')),
+ ('sidebar', _('Default with sidebar')),
+ ('none', _('None')),
+)
+
+RENDER_CHOICES = (
+ ('markdown', _('Markdown')),
+ ('html', _('HTML')),
+ ('escape', _('Escaped'))
+)
+
+class UrlFieldWidget(forms.TextInput):
+ def render(self, name, value, attrs=None):
+ if not value:
+ value = ''
+
+ return """
+ <input class="url_field" type="text" name="%(name)s" value="%(value)s" />
+ <a class="url_field_anchor" target="_blank" href="%(app_url)s%(script_alias)s"></a>
+ """ % {'name': name, 'value': value, 'app_url': settings.APP_URL, 'script_alias': settings.FORUM_SCRIPT_ALIAS}
+
+
+class PageForm(forms.Form):
+
+ def __init__(self, page, *args, **kwargs):
+ if page:
+ initial = page.extra
+ initial.update(dict(title=page.title, content=page.body))
+ super(PageForm, self).__init__(initial=initial, *args, **kwargs)
+ else:
+ super(PageForm, self).__init__(*args, **kwargs)
+
+
+ title = forms.CharField(label=_('Title'), max_length=255, widget=forms.TextInput(attrs={'class': 'longstring'}), initial='New page')
+ path = forms.CharField(label=_('Page URL'), widget=UrlFieldWidget, initial='pages/new/')
+
+ content = forms.CharField(label=_('Page Content'), widget=forms.Textarea(attrs={'rows': 30}))
+ render = forms.ChoiceField(widget=forms.RadioSelect, choices=RENDER_CHOICES, initial='markdown', label=_('Render Mode'))
+
+ template = forms.ChoiceField(widget=forms.RadioSelect, choices=TEMPLATE_CHOICES, initial='default', label=_('Template'))
+ sidebar = forms.CharField(label=_('Sidebar Content'), widget=forms.Textarea(attrs={'rows': 20}), required=False)
+ sidebar_wrap = forms.BooleanField(label=_("Wrap sidebar block"), initial=True, required=False)
+ sidebar_render = forms.ChoiceField(widget=forms.RadioSelect, choices=RENDER_CHOICES, initial='markdown', label=_('Sidebar Render Mode'))
+
+ comments = forms.BooleanField(label=_("Allow comments"), initial=False, required=False)
+
+
\ No newline at end of file
-from forum.utils.forms import NextUrlField, UserNameField, UserEmailField, SetPasswordForm
+from general import NextUrlField, UserNameField, UserEmailField, SetPasswordForm
from forum.models import Question, User
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import ugettext as _
import re
from datetime import date
from django import forms
-from models import *
+from forum.models import *
from django.utils.translation import ugettext as _
from django.contrib.humanize.templatetags.humanize import apnumber
-from forum.models import User
from django.utils.safestring import mark_safe
-from forum.utils.forms import NextUrlField, UserNameField, SetPasswordForm
+from general import NextUrlField, UserNameField, SetPasswordForm
from forum import settings
import logging
if self.user.email != self.cleaned_data['email']:
if settings.EMAIL_UNIQUE == True:
if 'email' in self.cleaned_data:
+ from forum.models import User
try:
User.objects.get(email = self.cleaned_data['email'])
except User.DoesNotExist:
from django.http import HttpResponseRedirect
-from forum.utils.forms import get_next_url
+from forum.forms import get_next_url
from django.utils.translation import ugettext as _
from forum.user_messages import create_message, get_and_delete_messages
from forum import settings
from django.http import HttpResponseRedirect
-from forum.utils.forms import get_next_url
+from forum.forms import get_next_url
import logging
class CancelActionMiddleware(object):
def process_view(self, request, view_func, view_args, view_kwargs):
from action import Action, ActionRepute
from meta import Vote, Flag, Badge, Award
from utils import KeyValue
+from page import Page
try:
from south.modelsinspector import add_introspection_rules
'Answer', 'AnswerRevision',
'Tag', 'Comment', 'MarkedTag', 'Badge', 'Award',
'ValidationHash', 'AuthKeyUserAssociation', 'SubscriptionSettings', 'KeyValue', 'User',
- 'Action', 'ActionRepute', 'Vote', 'Flag'
+ 'Action', 'ActionRepute', 'Vote', 'Flag', 'Page'
]
def html(self):
return self.as_markdown()
+ @classmethod
+ def _as_markdown(cls, content, *extensions):
+ return mark_safe(sanitize_html(markdown.markdown(content, extensions=extensions)))
+
def as_markdown(self, *extensions):
- return mark_safe(sanitize_html(markdown.markdown(self.body, extensions=extensions)))
+ return self._as_markdown(self.body, *extensions)
@property
def headline(self):
--- /dev/null
+from base import *
+from django.utils.translation import ugettext as _
+
+class Page(Node):
+ friendly_name = _("page")
+
+ @property
+ def published(self):
+ return self.marked
+
+ def save(self, *args, **kwargs):
+ old_options = self._original_state.get('extra', None)
+
+ super(Page, self).save(*args, **kwargs)
+
+ registry = settings.STATIC_PAGE_REGISTRY
+
+ if old_options:
+ registry.pop(old_options.get('path', ''), None)
+
+ registry[self.extra['path']] = self.id
+
+
+ settings.STATIC_PAGE_REGISTRY.set_value(registry)
+
+ @property
+ def headline(self):
+ if self.published:
+ return self.title
+ else:
+ return _("[Unpublished] %s") % self.title
+
+ @models.permalink
+ def get_absolute_url(self):
+ return ('static_page', (), {'path': self.extra['path']})
+
+ class Meta(Node.Meta):
+ proxy = True
+
+
\ No newline at end of file
import os.path
from base import Setting, SettingSet
-from forms import ImageFormWidget
from django.forms.widgets import Textarea
from django.utils.translation import ugettext_lazy as _
APP_URL = djsettings.APP_URL
FORUM_SCRIPT_ALIAS = djsettings.FORUM_SCRIPT_ALIAS
+STATIC_PAGE_REGISTRY = Setting('STATIC_PAGE_REGISTRY', {})
+
from basic import *
from sidebar import *
import os
-import socket
from string import strip
from django import forms
-from base import Setting
+from forum.settings.base import Setting
from django.utils.translation import ugettext as _
from django.core.files.storage import FileSystemStorage
return ', '.join(data[name])
-class IPListField(forms.CharField):
- def clean(self, value):
- ips = [ip.strip() for ip in value.strip().strip(',').split(',')]
- iplist = []
-
- if len(ips) < 1:
- raise forms.ValidationError(_('Please input at least one ip address'))
-
- for ip in ips:
- try:
- socket.inet_aton(ip)
- except socket.error:
- raise forms.ValidationError(_('Invalid ip address: %s' % ip))
-
- if not len(ip.split('.')) == 4:
- raise forms.ValidationError(_('Please use the dotted quad notation for the ip addresses'))
-
- iplist.append(ip)
-
- return iplist
-
-class MaintenanceModeForm(forms.Form):
- ips = IPListField(label=_('Allow ips'),
- help_text=_('Comma separated list of ips allowed to access the site while in maintenance'),
- required=True,
- widget=forms.TextInput(attrs={'class': 'longstring'}))
-
- message = forms.CharField(label=_('Message'),
- help_text=_('A message to display to your site visitors while in maintainance mode'),
- widget=forms.Textarea)
-
}\r
}\r
});\r
+\r
+ $('.url_field').each(function() {\r
+ var $input = $(this);\r
+ var $anchor = $input.parent().find('.url_field_anchor');\r
+ var app_url = $anchor.attr('href');\r
+\r
+ function rewrite_anchor() {\r
+ var val = app_url + $input.val();\r
+\r
+ $anchor.attr('href', val);\r
+ $anchor.html(val);\r
+\r
+ }\r
+\r
+ $input.keyup(rewrite_anchor);\r
+ rewrite_anchor(); \r
+ });\r
});
\ No newline at end of file
</div>
</div>
<div class="breadcrumbs">
- <a href="{% url index %}">{% trans "Home" %}</a> >
+ <a href="{% url index %}">{% trans "Home" %}</a> >
<a href="{% url admin_index %}">{% trans "Dashboard" %}</a> >
{% block pagename %}{% endblock %} -
{% block description %}{% endblock %}
<div id="pages-sets-menu" class="module">
<h2>{% trans "Static content" %}</h2>
<ul>
+ <li><a href="{% url admin_static_pages %}">{% trans "Custom Pages" %}</a></li>
<li><a href="{% url admin_set allsets.about.name %}">{{ allsets.about.title }}</a></li>
<li><a href="{% url admin_set allsets.faq.name %}">{{ allsets.faq.title }}</a></li>
<li><a href="{% url admin_set allsets.sidebar.name %}">{{ allsets.sidebar.title }}</a></li>
--- /dev/null
+{% extends basetemplate %}
+
+{% load i18n %}
+
+{% block subtitle %}{% trans "Editing page" %}{% endblock %}
+{% block pagename %}
+ <a href="{% url admin_static_pages %}">{% trans "Static Pages" %}</a> >
+ {% if page %}{% trans "Editing page" %}{% else %}{% trans "Creating page" %}{% endif %}
+{% endblock %}
+{% block description %}
+ {% if page %}{{ page.title }}{% else %}{% trans "New page" %}{% endif %}
+ ({% if published %}{% trans "Published" %}{% else %}{% trans "Unpublished" %}{% endif %})
+{% endblock %}
+
+{% block admincontent %}
+ <form action="" method="post" accept-charset="utf-8">
+ <table style="width: 100%">
+ {{ form.as_table }}
+ <tr>
+ <th></th>
+ <td>
+ <input id="submit" name="submit" type="submit" value="{% trans "Save" %}" />
+ {% if published %}
+ <input id="unpublish" name="unpublish" type="submit" value="{% trans "Unpublish" %}" />
+ {% else %}
+ <input id="publish" name="publish" type="submit" value="{% trans "Publish" %}" />
+ {% endif %}
+ </td>
+ </tr>
+ </table>
+ </form>
+{% endblock %}
\ No newline at end of file
--- /dev/null
+{% extends basetemplate %}
+
+{% load i18n %}
+
+{% block subtitle %}{% trans "Static pages" %}{% endblock %}
+{% block pagename %}{% trans "Static pages" %}{% endblock %}
+{% block description %}{% trans "Allows you to create a set of static pages" %}{% endblock %}
+
+{% block admincontent %}
+ <h1>{% trans "Select page to edit" %}</h1>
+ <ul class="object-tools">
+ <li><a class="addlink" href="{% url admin_new_page %}">{% trans "New page" %}</a></li>
+ </ul>
+ <div class="module">
+ <table style="width: 100%">
+ <caption>{% trans "Pages" %}</caption>
+ <tbody>
+ {% for page in pages %}
+ <tr>
+ <th scope="row"><a href="{% url admin_edit_page id=page.id %}">{{ page.headline }}</a></th>
+ <td><a class="changelink" href="{% url admin_edit_page id=page.id %}">{% trans "Edit" %}</a></td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+
+{% endblock %}
\ No newline at end of file
--- /dev/null
+{% extends base %}
+{% load i18n markup node_tags general_sidebar_tags %}
+{% block title %}{% spaceless %}{{ page.title }}{% endspaceless %}{% endblock %}
+
+{% block content %}
+<div class="headNormal">{{ page.title }}</div>
+<div class="content">
+{{ body }}
+</div>
+{% if page.extra.comments %}
+ {% comments page request.user %}
+{% endif %}
+{% endblock %}
+
+{% ifequal page.extra.template "sidebar" %}
+ {% block sidebar %}
+ {% sidebar_upper %}
+ {% if page.extra.sidebar %}
+ {% if page.extra.sidebar_wrap %}<div class="boxC"><div class="body">{% endif %}
+ {{ sidebar }}
+ {% if page.extra.sidebar_wrap %}</div></div>{% endif %}
+ {% endif %}
+ {% sidebar_lower %}
+ {% endblock %}
+{% endifequal %}
+
+
url(r'^%s%s(?P<set_name>\w+)/(?P<var_name>\w+)/$' % (_('admin/'), _('settings/')), app.admin.get_default, name="admin_default"),
url(r'^%s%s$' % (_('admin/'), _('maintenance/')), app.admin.maintenance, name="admin_maintenance"),
url(r'^%s%s$' % (_('admin/'), _('flagged_posts/')), app.admin.flagged_posts, name="admin_flagged_posts"),
+ url(r'^%s%s$' % (_('admin/'), _('static_pages/')), app.admin.static_pages, name="admin_static_pages"),
+
+ url(r'^%s%s%s$' % (_('admin/'), _('static_pages/'), _('new/')), app.admin.edit_page, name="admin_new_page"),
+ url(r'^%s%s%s(?P<id>\d+)/$' % (_('admin/'), _('static_pages/'), _('edit/')), app.admin.edit_page, name="admin_edit_page"),
url(r'^%s%s(?P<set_name>\w+)/$' % (_('admin/'), _('settings/')), app.admin.settings_set, name="admin_set"),
url(r'^feeds/rss/$', RssLastestQuestionsFeed, name="latest_questions_feed"),
+
+ url(r'^(?P<path>.+)$', app.meta.page, name="static_page")
)
from datetime import datetime, timedelta
import time
-from django.shortcuts import render_to_response
+from django.shortcuts import render_to_response, get_object_or_404
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect, HttpResponse, HttpResponseForbidden, Http404
from django.template import RequestContext
from django.utils import simplejson
from django.db.models import Sum
from forum.settings.base import Setting
-from forum.settings.forms import SettingsSetForm, MaintenanceModeForm
+from forum.forms import MaintenanceModeForm, PageForm
+from forum.settings.forms import SettingsSetForm
-from forum.models import Question, Answer, User, Node, Action
+from forum.models import Question, Answer, User, Node, Action, Page
+from forum.actions import NewPageAction, EditPageAction, PublishAction
from forum import settings
def super_user_required(fn):
'flagged_posts': get_flagged_posts(),
})
+@admin_page
+def static_pages(request):
+ pages = Page.objects.all()
+
+ return ('osqaadmin/static_pages.html', {
+ 'pages': pages,
+ })
+
+@admin_page
+def edit_page(request, id=None):
+ if id:
+ page = get_object_or_404(Page, id=id)
+ else:
+ page = None
+
+ if request.POST:
+ form = PageForm(page, request.POST)
+
+ if form.is_valid():
+ if form.has_changed():
+ if not page:
+ page = NewPageAction(user=request.user, ip=request.META['REMOTE_ADDR']).save(data=form.cleaned_data).node
+ else:
+ EditPageAction(user=request.user, node=page, ip=request.META['REMOTE_ADDR']).save(data=form.cleaned_data)
+
+ if ('publish' in request.POST) and (not page.published):
+ PublishAction(user=request.user, node=page, ip=request.META['REMOTE_ADDR']).save()
+ elif ('unpublish' in request.POST) and page.published:
+ page.nstate.published.cancel(ip=request.META['REMOTE_ADDR'])
+
+ return HttpResponseRedirect(reverse('admin_edit_page', kwargs={'id': page.id}))
+
+ else:
+ form = PageForm(page)
+
+ if page:
+ published = page.published
+ else:
+ published = False
+
+ return ('osqaadmin/edit_page.html', {
+ 'page': page,
+ 'form': form,
+ 'published': published
+ })
+
+
import types
import datetime
-from forum.authentication.forms import SimpleRegistrationForm, SimpleEmailSubscribeForm, \
+from forum.forms import SimpleRegistrationForm, SimpleEmailSubscribeForm, \
TemporaryLoginRequestForm, ChangePasswordForm, SetPasswordForm
from forum.utils.mail import send_email, send_template_email
answer.nstate.accepted.cancel(user, ip=request.META['REMOTE_ADDR'])
commands['unmark_accepted'] = [answer.id]
else:
- if question.answer_accepted:
- accepted = question.accepted_answer
+ accepted = question.accepted_answer
+
+ if accepted:
accepted.nstate.accepted.cancel(user, ip=request.META['REMOTE_ADDR'])
commands['unmark_accepted'] = [accepted.id]
from django.shortcuts import render_to_response, get_object_or_404
from django.core.urlresolvers import reverse
from django.template import RequestContext, loader
-from django.http import HttpResponseRedirect, HttpResponse
+from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.views.static import serve
from forum import settings
from forum.forms import FeedbackForm
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
from django.db.models import Count
-from forum.utils.forms import get_next_url
-from forum.models import Badge, Award, User
+from forum.forms import get_next_url
+from forum.models import Badge, Award, User, Page
from forum.badges.base import BadgesMeta
from forum import settings
from forum.utils.mail import send_template_email
+from django.utils.safestring import mark_safe
import re
def favicon(request):
'badge' : badge,
}, context_instance=RequestContext(request))
+def page(request, path):
+ if path in settings.STATIC_PAGE_REGISTRY:
+ try:
+ page = Page.objects.get(id=settings.STATIC_PAGE_REGISTRY[path])
+
+ if not page.published or request.user.is_superuser:
+ raise Http404
+ except:
+ raise Http404
+ else:
+ raise Http404
+
+ template = page.extra.get('template', 'default')
+ sidebar = page.extra.get('sidebar', '')
+
+ if template == 'default':
+ base = 'base_content.html'
+ elif template == 'sidebar':
+ base = 'base.html'
+
+ sidebar_render = page.extra.get('render', 'markdown')
+
+ if sidebar_render == 'markdown':
+ sidebar = page._as_markdown(sidebar)
+ elif sidebar_render == 'html':
+ sidebar = mark_safe(sidebar)
+
+ else:
+ return HttpResponse(page.body)
+
+ render = page.extra.get('render', 'markdown')
+
+ if render == 'markdown':
+ body = page.as_markdown()
+ elif render == 'html':
+ body = mark_safe(page.body)
+ else:
+ body = page.body
+
+ return render_to_response('page.html', {
+ 'page' : page,
+ 'body' : body,
+ 'sidebar': sidebar,
+ 'base': base,
+ }, context_instance=RequestContext(request))
+
+
from forum.utils.diff import textDiff as htmldiff
from forum.forms import *
from forum.models import *
-from forum.utils.forms import get_next_url
+from forum.forms import get_next_url
from forum.actions import QuestionViewAction
from forum.modules.decorators import decoratable
import decorators
\r
@user_view('users/recent.html', 'recent', _('recent user activity'), _('recent activity'))\r
def user_recent(request, user):\r
- activities = user.actions.exclude(action_type__in=("voteup", "votedown", "voteupcomment", "flag")).order_by('-action_date')[:USERS_PAGE_SIZE]\r
+ activities = user.actions.exclude(action_type__in=("voteup", "votedown", "voteupcomment", "flag", "newpage", "editpage")).order_by('-action_date')[:USERS_PAGE_SIZE]\r
\r
return {"view_user" : user, "activities" : activities}\r
\r
from forum.modules.decorators import decoratable
from forum.forms import *
from forum.models import *
-from forum.utils.forms import get_next_url
+from forum.forms import get_next_url
def upload(request):#ajax upload file to a question or answer
-from forum.utils.forms import NextUrlField, UserNameField, UserEmailField, SetPasswordForm
+from forum.forms import NextUrlField, UserNameField, UserEmailField, SetPasswordForm
from forum.models import Question
from forum.modules import call_all_handlers
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import ugettext as _
from forms import ClassicRegisterForm
-from forum.authentication.forms import SimpleEmailSubscribeForm
+from forum.forms import SimpleEmailSubscribeForm
from forum.views.auth import login_and_forward
from forum.actions import UserJoinsAction
import traceback
traceback.print_exc()
import sys
- sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
+ sys.stderr.write("Error: Can't find the file 'forms.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file forms.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
sys.exit(1)
if __name__ == "__main__":