summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--askbot/forms.py18
-rw-r--r--askbot/skins/default/templates/ask_by_widget.html16
-rw-r--r--askbot/skins/default/templates/ask_widget_complete.html8
-rw-r--r--askbot/skins/default/templates/widget_base.html18
-rw-r--r--askbot/tests/__init__.py1
-rw-r--r--askbot/tests/form_tests.py33
-rw-r--r--askbot/tests/widget_tests.py52
-rw-r--r--askbot/urls.py89
-rw-r--r--askbot/views/__init__.py1
-rw-r--r--askbot/views/widgets.py73
10 files changed, 264 insertions, 45 deletions
diff --git a/askbot/forms.py b/askbot/forms.py
index 978cdf0b..7906a5e0 100644
--- a/askbot/forms.py
+++ b/askbot/forms.py
@@ -888,6 +888,24 @@ ASK_BY_EMAIL_SUBJECT_HELP = _(
'[tag1, tag2, tag3,...] question title'
)
+class AskWidgetForm(forms.Form, FormWithHideableFields):
+ '''Simple form with just the title to ask a question'''
+
+ title = TitleField()
+ ask_anonymously = forms.BooleanField(
+ label=_('ask anonymously'),
+ help_text=_(
+ 'Check if you do not want to reveal your name '
+ 'when asking this question'
+ ),
+ required=False,
+ )
+
+ def __init__(self, *args, **kwargs):
+ super(AskWidgetForm, self).__init__(*args, **kwargs)
+ #hide ask_anonymously field
+ if askbot_settings.ALLOW_ASK_ANONYMOUSLY is False:
+ self.hide_field('ask_anonymously')
class AskByEmailForm(forms.Form):
""":class:`~askbot.forms.AskByEmailForm`
diff --git a/askbot/skins/default/templates/ask_by_widget.html b/askbot/skins/default/templates/ask_by_widget.html
new file mode 100644
index 00000000..f700f83a
--- /dev/null
+++ b/askbot/skins/default/templates/ask_by_widget.html
@@ -0,0 +1,16 @@
+{% extends "widget_base.html" %}
+{% block forestyle %}
+{%endblock%}
+
+{%block body%}
+Enter your question
+<form action="." method="POST" accept-charset="utf-8">
+ {% csrf_token %}
+ {{form.title}}
+ {% if form.ask_anonymously %}
+ {{form.ask_anonymously}}
+ {%endif%}
+ <input type="submit" value="Ask your question" />
+</form>
+{{form.errors}}
+{%endblock%}
diff --git a/askbot/skins/default/templates/ask_widget_complete.html b/askbot/skins/default/templates/ask_widget_complete.html
new file mode 100644
index 00000000..82fe570c
--- /dev/null
+++ b/askbot/skins/default/templates/ask_widget_complete.html
@@ -0,0 +1,8 @@
+{% extends "widget_base.html" %}
+{% block forestyle %}
+{%endblock%}
+
+{%block body%}
+<a href="{{question_url}}" >Question posted</a>
+{%endblock%}
+
diff --git a/askbot/skins/default/templates/widget_base.html b/askbot/skins/default/templates/widget_base.html
new file mode 100644
index 00000000..8156095d
--- /dev/null
+++ b/askbot/skins/default/templates/widget_base.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!-- template widget_base.html -->
+<html xmlns="http://www.w3.org/1999/xhtml">
+ {% spaceless %}
+ <head>
+ {% block before_css %}{% endblock %}
+ {% block forestyle %}{% endblock %}
+ {% block forejs %}{% endblock %}
+ </head>
+ {% endspaceless %}
+ <body class="lang-{{settings.LANGUAGE_CODE}}">
+ {% block body%}
+ {% endblock %}
+ {% block endjs %}
+ {% endblock %}
+ </body>
+</html>
+<!-- end template widget_base.html -->
diff --git a/askbot/tests/__init__.py b/askbot/tests/__init__.py
index c20b7f67..c1b80347 100644
--- a/askbot/tests/__init__.py
+++ b/askbot/tests/__init__.py
@@ -15,4 +15,5 @@ from askbot.tests.markup_test import *
from askbot.tests.post_model_tests import *
from askbot.tests.thread_model_tests import *
from askbot.tests.reply_by_email_tests import *
+from askbot.tests.widget_tests import *
from askbot.tests.category_tree_tests import CategoryTreeTests
diff --git a/askbot/tests/form_tests.py b/askbot/tests/form_tests.py
index a37f380c..be88cf39 100644
--- a/askbot/tests/form_tests.py
+++ b/askbot/tests/form_tests.py
@@ -72,8 +72,8 @@ class AskByEmailFormTests(AskbotTestCase):
askbot_settings.update('TAGS_ARE_REQUIRED', setting_backup)
def test_email(self):
- """loops through variants of the from field
- in the emails and tests the email address
+ """loops through variants of the from field
+ in the emails and tests the email address
extractor"""
for test_case in EMAIL_CASES:
self.data['sender'] = test_case[0]
@@ -178,7 +178,7 @@ class EditQuestionAnonymouslyFormTests(AskbotTestCase):
def setup_data(self, is_anon, can_be_anon, is_owner, box_checked):
"""sets up data in the same order as shown in the
truth table above
-
+
the four positional arguments are in the same order
"""
askbot_settings.update('ALLOW_ASK_ANONYMOUSLY', can_be_anon)
@@ -264,7 +264,7 @@ class UserStatusFormTest(AskbotTestCase):
self.moderator.set_status('m')
self.subject = self.create_user('normal_user')
self.subject.set_status('a')
- self.form = forms.ChangeUserStatusForm(data, moderator = self.moderator,
+ self.form = forms.ChangeUserStatusForm(data, moderator = self.moderator,
subject = self.subject)
def test_moderator_can_suspend_user(self):
self.setup_data('s')
@@ -292,7 +292,7 @@ class UserNameFieldTest(AskbotTestCase):
self.username_field.skip_clean = True
self.assertEquals(self.username_field.clean('bar'), 'bar')#will pass anything
- self.username_field.skip_clean = False
+ self.username_field.skip_clean = False
#will not pass b/c instance is not User model
self.username_field.user_instance = dict(foo=1)
@@ -328,7 +328,7 @@ class AnswerEditorFieldTests(AskbotTestCase):
self.field.clean,
'a'
)
-
+
def test_pass_long_body(self):
self.assertEquals(
self.field.clean(10*'a'),
@@ -361,3 +361,24 @@ class PostAsSomeoneFormTests(AskbotTestCase):
def test_missing_username_fails(self):
form = forms.PostAsSomeoneForm({'post_author_email': 'me@example.com'})
self.assertEqual(form.is_valid(), False)
+
+class AskWidgetFormTests(AskbotTestCase):
+
+ form = forms.AskWidgetForm
+
+ def setUp(self):
+ self.good_data = {'title': "What's the price of a house in london?"}
+ self.good_data_anon = {'title': "What's the price of a house in london?",
+ 'ask_anonymously': True}
+
+ self.bad_data = {'title': ''}
+
+ def test_valid_input(self):
+ form_object = self.form(self.good_data)
+ self.assertTrue(form_object.is_valid())
+ form_object = self.form(self.good_data_anon)
+ self.assertTrue(form_object.is_valid())
+
+ def test_invalid_input(self):
+ form_object = self.form(self.bad_data)
+ self.assertFalse(form_object.is_valid())
diff --git a/askbot/tests/widget_tests.py b/askbot/tests/widget_tests.py
new file mode 100644
index 00000000..e33f88b9
--- /dev/null
+++ b/askbot/tests/widget_tests.py
@@ -0,0 +1,52 @@
+from datetime import datetime
+
+from askbot import models
+from askbot.tests.utils import AskbotTestCase
+
+from django.test.client import Client
+from django.core.urlresolvers import reverse
+
+
+class WidgetViewsTests(AskbotTestCase):
+
+ def setUp(self):
+ self.client = Client()
+ self.user = self.create_user('user1')
+ self.user.set_password('sample')
+ self.user.save()
+ self.good_data = {'title': 'This is a title question',
+ 'ask_anonymously': False}
+
+ def test_post_with_auth(self):
+ self.client.login(username='user1', password='sample')
+ response = self.client.post(reverse('ask_by_widget'), self.good_data)
+ self.assertEquals(response.status_code, 302)
+ self.client.logout()
+
+ def test_post_without_auth(self):
+ response = self.client.post(reverse('ask_by_widget'), self.good_data)
+ self.assertEquals(response.status_code, 302)
+ self.assertTrue('widget_question' in self.client.session)
+ self.assertEquals(self.client.session['widget_question']['title'],
+ self.good_data['title'])
+
+ def test_post_after_login(self):
+ widget_question_data = { 'title': 'testing post after login, does it?',
+ 'author': self.user,
+ 'added_at': datetime.now(),
+ 'wiki': False,
+ 'text': ' ',
+ 'tagnames': '',
+ 'is_anonymous': False
+ }
+
+ self.client.login(username='user1', password='sample')
+
+ session = self.client.session
+ session['widget_question'] = widget_question_data
+ session.save()
+ response = self.client.get(reverse('ask_by_widget'),
+ {'action': 'post-after-login'})
+ self.assertFalse('widget_question' in self.client.session)
+ self.assertEquals(response.status_code, 302)
+ #verify posting question
diff --git a/askbot/urls.py b/askbot/urls.py
index f9bd74fb..703cdcbd 100644
--- a/askbot/urls.py
+++ b/askbot/urls.py
@@ -31,9 +31,9 @@ APP_PATH = os.path.dirname(__file__)
urlpatterns = patterns('',
url(r'^$', views.readers.index, name='index'),
url(
- r'^sitemap.xml$',
- 'django.contrib.sitemaps.views.sitemap',
- {'sitemaps': sitemaps},
+ r'^sitemap.xml$',
+ 'django.contrib.sitemaps.views.sitemap',
+ {'sitemaps': sitemaps},
name='sitemap'
),
#no translation for this url!!
@@ -43,13 +43,13 @@ urlpatterns = patterns('',
url(r'^%s$' % _('privacy/'), views.meta.privacy, name='privacy'),
url(r'^%s$' % _('help/'), views.meta.help, name='help'),
url(
- r'^%s(?P<id>\d+)/%s$' % (_('answers/'), _('edit/')),
- views.writers.edit_answer,
+ r'^%s(?P<id>\d+)/%s$' % (_('answers/'), _('edit/')),
+ views.writers.edit_answer,
name='edit_answer'
),
url(
- r'^%s(?P<id>\d+)/%s$' % (_('answers/'), _('revisions/')),
- views.readers.revisions,
+ r'^%s(?P<id>\d+)/%s$' % (_('answers/'), _('revisions/')),
+ views.readers.revisions,
kwargs = {'post_type': 'answer'},
name='answer_revisions'
),
@@ -67,12 +67,12 @@ urlpatterns = patterns('',
r'(%s)?' % r'/page:(?P<page>\d+)' +
r'/$'),
- views.readers.questions,
+ views.readers.questions,
name='questions'
),
# END main page urls
-
+
url(
r'^api/get_questions/',
views.commands.api_get_questions,
@@ -99,49 +99,49 @@ urlpatterns = patterns('',
name='get_users_info'
),
url(
- r'^%s%s$' % (_('questions/'), _('ask/')),
- views.writers.ask,
+ r'^%s%s$' % (_('questions/'), _('ask/')),
+ views.writers.ask,
name='ask'
),
url(
- r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('edit/')),
- views.writers.edit_question,
+ r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('edit/')),
+ views.writers.edit_question,
name='edit_question'
),
url(#this url is both regular and ajax
- r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('retag/')),
- views.writers.retag_question,
+ r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('retag/')),
+ views.writers.retag_question,
name='retag_question'
),
url(
- r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('close/')),
- views.commands.close,
+ r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('close/')),
+ views.commands.close,
name='close'
),
url(
- r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('reopen/')),
- views.commands.reopen,
+ r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('reopen/')),
+ views.commands.reopen,
name='reopen'
),
url(
- r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('answer/')),
- views.writers.answer,
+ r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('answer/')),
+ views.writers.answer,
name='answer'
),
url(#ajax only
- r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('vote/')),
- views.commands.vote,
+ r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('vote/')),
+ views.commands.vote,
name='vote'
),
url(
- r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('revisions/')),
- views.readers.revisions,
+ r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('revisions/')),
+ views.readers.revisions,
kwargs = {'post_type': 'question'},
name='question_revisions'
),
url(
r'^%s%s$' % (_('widgets/'), _('questions/')),
- views.readers.widget_questions,
+ views.readers.widget_questions,
name='widget_questions'
),
url(#ajax only
@@ -156,7 +156,7 @@ urlpatterns = patterns('',
),
url(#ajax only
r'^post_comments/$',
- views.writers.post_comments,
+ views.writers.post_comments,
name='post_comments'
),
url(#ajax only
@@ -166,17 +166,17 @@ urlpatterns = patterns('',
),
url(#ajax only
r'^comment/delete/$',
- views.writers.delete_comment,
+ views.writers.delete_comment,
name='delete_comment'
),
url(#ajax only
r'^comment/get_text/$',
- views.readers.get_comment,
+ views.readers.get_comment,
name='get_comment'
),
url(
- r'^%s$' % _('tags/'),
- views.readers.tags,
+ r'^%s$' % _('tags/'),
+ views.readers.tags,
name='tags'
),
url(
@@ -291,12 +291,12 @@ urlpatterns = patterns('',
),
url(
r'^%s$' % _('users/'),
- views.users.show_users,
+ views.users.show_users,
name='users'
),
url(
r'^%s%s(?P<group_id>\d+)/(?P<group_slug>.*)/$' % (_('users/'), _('by-group/')),
- views.users.show_users,
+ views.users.show_users,
kwargs = {'by_group': True},
name = 'users_by_group'
),
@@ -375,8 +375,19 @@ urlpatterns = patterns('',
views.commands.join_or_leave_group,
name = 'join_or_leave_group'
),
+ #widgets url!
+ url(
+ r'^widgets/ask/$',
+ views.widgets.ask_widget,
+ name = 'ask_by_widget'
+ ),
+ url(
+ r'^widgets/ask/complete/$',
+ views.widgets.ask_widget_complete,
+ name = 'ask_by_widget_complete'
+ ),
url(
- r'^feeds/(?P<url>.*)/$',
+ r'^feeds/(?P<url>.*)/$',
'django.contrib.syndication.views.feed',
{'feed_dict': feeds},
name='feeds'
@@ -386,7 +397,7 @@ urlpatterns = patterns('',
url(r'^%s$' % _('feedback/'), views.meta.feedback, name='feedback'),
#url(r'^feeds/rss/$', RssLastestQuestionsFeed, name="latest_questions_feed"),
url(
- r'^doc/(?P<path>.*)$',
+ r'^doc/(?P<path>.*)$',
'django.views.static.serve',
{'document_root': os.path.join(APP_PATH,'doc','build','html').replace('\\','/')},
name='askbot_docs',
@@ -421,14 +432,14 @@ urlpatterns = patterns('',
#therefore the stackexchange urls feature won't work
if getattr(settings, 'ASKBOT_USE_STACKEXCHANGE_URLS', False):
urlpatterns += (url(
- r'^%s(?P<id>\d+)/' % _('questions/'),
- views.readers.question,
+ r'^%s(?P<id>\d+)/' % _('questions/'),
+ views.readers.question,
name='question'
),)
else:
urlpatterns += (url(
- r'^%s(?P<id>\d+)/' % _('question/'),
- views.readers.question,
+ r'^%s(?P<id>\d+)/' % _('question/'),
+ views.readers.question,
name='question'
),)
diff --git a/askbot/views/__init__.py b/askbot/views/__init__.py
index b9aaf8a9..a3c5e06d 100644
--- a/askbot/views/__init__.py
+++ b/askbot/views/__init__.py
@@ -6,6 +6,7 @@ from askbot.views import writers
from askbot.views import commands
from askbot.views import users
from askbot.views import meta
+from askbot.views import widgets
from django.conf import settings
if 'avatar' in settings.INSTALLED_APPS:
from askbot.views import avatar_views
diff --git a/askbot/views/widgets.py b/askbot/views/widgets.py
new file mode 100644
index 00000000..ea093916
--- /dev/null
+++ b/askbot/views/widgets.py
@@ -0,0 +1,73 @@
+from datetime import datetime
+
+from django.views.decorators import csrf
+from django.shortcuts import redirect
+from django.utils import simplejson
+from django.contrib.auth.models import User
+from django.core import exceptions
+
+from django.contrib.auth.decorators import login_required
+
+from askbot.skins.loaders import render_into_skin
+from askbot import models
+from askbot import forms
+
+@csrf.csrf_protect
+def ask_widget(request):
+
+ def post_question(data, request):
+ thread = models.Thread.objects.create_new(**data_dict)
+ question = thread._question_post()
+ request.session['widget_question_url'] = question.get_absolute_url()
+ return question
+
+
+ if request.method == "POST":
+ form = forms.AskWidgetForm(request.POST)
+ if form.is_valid():
+ ask_anonymously = form.cleaned_data['ask_anonymously']
+ title = form.cleaned_data['title']
+ data_dict = {
+ 'title': title,
+ 'added_at': datetime.now(),
+ 'wiki': False,
+ 'text': ' ',
+ 'tagnames': '',
+ 'is_anonymous': ask_anonymously
+ }
+ if request.user.is_authenticated():
+ data_dict['author'] = request.user
+ question = post_question(data_dict, request)
+ return redirect('ask_by_widget_complete')
+ else:
+ request.session['widget_question'] = data_dict
+ #return redirect('widgets_login')
+ return redirect('user_signin')
+ else:
+ if 'widget_question' in request.session or \
+ request.GET.get('action', 'post-after-login'):
+ if request.user.is_authenticated():
+ data_dict = request.session['widget_question']
+ data_dict['author'] = request.user
+ question = post_question(request.session['widget_question'], request)
+ del request.session['widget_question']
+ return redirect('ask_by_widget_complete')
+ else:
+ #FIXME: this redirect is temporal need to create the correct view
+ #return redirect('widgets_login')
+ return redirect('user_signin')
+
+ form = forms.AskWidgetForm()
+ data = {'form': form}
+ return render_into_skin('ask_by_widget.html', data, request)
+
+@login_required
+def ask_widget_complete(request):
+ question_url = request.session.get('widget_question_url')
+ if question_url:
+ del request.session['widget_question_url']
+ else:
+ question_url = '#'
+
+ data = {'question_url': question_url}
+ return render_into_skin('ask_widget_complete.html', data, request)