Return-Path: X-Original-To: apmail-incubator-allura-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-allura-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 44AF3108B9 for ; Fri, 10 Jan 2014 18:26:37 +0000 (UTC) Received: (qmail 1420 invoked by uid 500); 10 Jan 2014 18:20:00 -0000 Delivered-To: apmail-incubator-allura-commits-archive@incubator.apache.org Received: (qmail 901 invoked by uid 500); 10 Jan 2014 18:19:30 -0000 Mailing-List: contact allura-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: allura-dev@incubator.apache.org Delivered-To: mailing list allura-commits@incubator.apache.org Received: (qmail 843 invoked by uid 99); 10 Jan 2014 18:19:26 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 10 Jan 2014 18:19:26 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 83F0C32A302; Fri, 10 Jan 2014 18:19:25 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: tvansteenburgh@apache.org To: allura-commits@incubator.apache.org Date: Fri, 10 Jan 2014 18:19:38 -0000 Message-Id: <46dc5a1307594088ba6a9062d05d6cdf@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [14/32] PEP8 cleanup http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeActivity/forgeactivity/tests/functional/test_root.py ---------------------------------------------------------------------- diff --git a/ForgeActivity/forgeactivity/tests/functional/test_root.py b/ForgeActivity/forgeactivity/tests/functional/test_root.py index eda71be..cafdfe4 100644 --- a/ForgeActivity/forgeactivity/tests/functional/test_root.py +++ b/ForgeActivity/forgeactivity/tests/functional/test_root.py @@ -29,6 +29,7 @@ from allura.tests import decorators as td class TestActivityController(TestController): + def setUp(self, *args, **kwargs): super(TestActivityController, self).setUp(*args, **kwargs) self._enabled = config.get('activitystream.enabled', 'false') @@ -58,37 +59,37 @@ class TestActivityController(TestController): from activitystream.storage.base import StoredActivity from bson import ObjectId director.get_timeline.return_value = [StoredActivity(**{ - "_id" : ObjectId("529fa331033c5e6406d8b338"), - "obj" : { - "activity_extras" : { - "allura_id" : "Post:971389ad979eaafa658beb807bf4629d30f5f642.tickets@test.p.sourceforge.net", - "summary" : "Just wanted to leave a comment on this..." - }, - "activity_url" : "/p/test/tickets/_discuss/thread/08e74efd/ed7c/", - "activity_name" : "a comment" + "_id": ObjectId("529fa331033c5e6406d8b338"), + "obj": { + "activity_extras": { + "allura_id": "Post:971389ad979eaafa658beb807bf4629d30f5f642.tickets@test.p.sourceforge.net", + "summary": "Just wanted to leave a comment on this..." + }, + "activity_url": "/p/test/tickets/_discuss/thread/08e74efd/ed7c/", + "activity_name": "a comment" }, - "target" : { - "activity_extras" : { - "allura_id" : "Ticket:529f57a6033c5e5985db2efa", - "summary" : "Make activitystream timeline look better" - }, - "activity_url" : "/p/test/tickets/34/", - "activity_name" : "ticket #34" + "target": { + "activity_extras": { + "allura_id": "Ticket:529f57a6033c5e5985db2efa", + "summary": "Make activitystream timeline look better" + }, + "activity_url": "/p/test/tickets/34/", + "activity_name": "ticket #34" }, - "actor" : { - "activity_extras" : { - "icon_url" : "/u/test-admin/user_icon", - "allura_id" : "User:521f96cb033c5e2587adbdff" - }, - "activity_url" : "/u/test-admin/", - "activity_name" : "Administrator 1", - "node_id" : "User:521f96cb033c5e2587adbdff" + "actor": { + "activity_extras": { + "icon_url": "/u/test-admin/user_icon", + "allura_id": "User:521f96cb033c5e2587adbdff" + }, + "activity_url": "/u/test-admin/", + "activity_name": "Administrator 1", + "node_id": "User:521f96cb033c5e2587adbdff" }, - "verb" : "posted", - "published" : dateutil.parser.parse("2013-12-04T21:48:19.817"), - "score" : 1386193699, - "node_id" : "Project:527a6584033c5e62126f5a60", - "owner_id" : "Project:527a6584033c5e62126f5a60" + "verb": "posted", + "published": dateutil.parser.parse("2013-12-04T21:48:19.817"), + "score": 1386193699, + "node_id": "Project:527a6584033c5e62126f5a60", + "owner_id": "Project:527a6584033c5e62126f5a60" })] r = self.app.get('/p/test/activity/') timeline = r.html.find('ul', 'timeline') @@ -156,7 +157,7 @@ class TestActivityController(TestController): @td.with_user_project('test-user-1') def test_background_aggregation(self): self.app.get('/u/test-admin/activity/follow?follow=True', - extra_environ=dict(username='test-user-1')) + extra_environ=dict(username='test-user-1')) # new ticket, creates activity d = {'ticket_form.summary': 'New Ticket'} self.app.post('/bugs/save_ticket', params=d) http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeActivity/forgeactivity/widgets/follow.py ---------------------------------------------------------------------- diff --git a/ForgeActivity/forgeactivity/widgets/follow.py b/ForgeActivity/forgeactivity/widgets/follow.py index ce05ef7..f5a15d7 100644 --- a/ForgeActivity/forgeactivity/widgets/follow.py +++ b/ForgeActivity/forgeactivity/widgets/follow.py @@ -22,8 +22,8 @@ import ew.jinja2_ew as ew class FollowToggle(ew.SimpleForm): - template='jinja:forgeactivity:templates/widgets/follow.html' - defaults=dict( + template = 'jinja:forgeactivity:templates/widgets/follow.html' + defaults = dict( ew.SimpleForm.defaults, thing='project', action='follow', http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeActivity/setup.py ---------------------------------------------------------------------- diff --git a/ForgeActivity/setup.py b/ForgeActivity/setup.py index bbc5372..45c546e 100644 --- a/ForgeActivity/setup.py +++ b/ForgeActivity/setup.py @@ -22,7 +22,8 @@ setup(name='ForgeActivity', description="", long_description="""\ """, - classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers + # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers + classifiers=[], keywords='', author='', author_email='', http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeBlog/forgeblog/command/base.py ---------------------------------------------------------------------- diff --git a/ForgeBlog/forgeblog/command/base.py b/ForgeBlog/forgeblog/command/base.py index c7bf329..8e67cc9 100644 --- a/ForgeBlog/forgeblog/command/base.py +++ b/ForgeBlog/forgeblog/command/base.py @@ -17,5 +17,6 @@ from allura.command.base import Command + class BlogCommand(Command): group_name = 'ForgeBlog' http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeBlog/forgeblog/command/rssfeeds.py ---------------------------------------------------------------------- diff --git a/ForgeBlog/forgeblog/command/rssfeeds.py b/ForgeBlog/forgeblog/command/rssfeeds.py index eeac4b2..ce02487 100644 --- a/ForgeBlog/forgeblog/command/rssfeeds.py +++ b/ForgeBlog/forgeblog/command/rssfeeds.py @@ -36,8 +36,8 @@ from allura.lib import exceptions from allura.lib.helpers import exceptionless from allura.lib.helpers import plain2markdown -## Everything in this file depends on html2text, -## so import attempt is placed in global scope. +# Everything in this file depends on html2text, +# so import attempt is placed in global scope. try: import html2text except ImportError: @@ -46,6 +46,7 @@ except ImportError: html2text.BODY_WIDTH = 0 + class RssFeedsCommand(base.BlogCommand): summary = 'Rss feed client' parser = base.BlogCommand.standard_parser(verbose=True) @@ -60,12 +61,15 @@ class RssFeedsCommand(base.BlogCommand): # activity, User.url() will be called. This method defers to an # AuthenticationProvider, which depends on a request being setup in # the current thread. So, we set one up here. - import pylons, webob + import pylons + import webob pylons.request._push_object(webob.Request.blank('/')) self.basic_setup() - self.process_feed = exceptionless(None, log=allura_base.log)(self.process_feed) - self.process_entry = exceptionless(None, log=allura_base.log)(self.process_entry) + self.process_feed = exceptionless( + None, log=allura_base.log)(self.process_feed) + self.process_entry = exceptionless( + None, log=allura_base.log)(self.process_entry) user = M.User.query.get(username=self.options.username) c.user = user @@ -78,10 +82,11 @@ class RssFeedsCommand(base.BlogCommand): def prepare_feeds(self): feed_dict = {} if self.options.appid != '': - gl_app = BM.Globals.query.get(app_config_id=ObjectId(self.options.appid)) + gl_app = BM.Globals.query.get( + app_config_id=ObjectId(self.options.appid)) if not gl_app: - raise exceptions.NoSuchGlobalsError("The globals %s " \ - "could not be found in the database" % self.options.appid) + raise exceptions.NoSuchGlobalsError("The globals %s " + "could not be found in the database" % self.options.appid) if len(gl_app.external_feeds) > 0: feed_dict[gl_app.app_config_id] = gl_app.external_feeds else: @@ -111,7 +116,8 @@ class RssFeedsCommand(base.BlogCommand): def process_entry(self, e, appid): title = e.title allura_base.log.info(" ...entry '%s'", title) - parsed_content = filter(None, e.get('content') or [e.get('summary_detail')]) + parsed_content = filter( + None, e.get('content') or [e.get('summary_detail')]) if parsed_content: content = u'' for ct in parsed_content: @@ -124,18 +130,19 @@ class RssFeedsCommand(base.BlogCommand): content += markdown_content else: content = plain2markdown(getattr(e, 'summary', - getattr(e, 'subtitle', - getattr(e, 'title')))) + getattr(e, 'subtitle', + getattr(e, 'title')))) content += u' [link](%s)' % e.link updated = datetime.utcfromtimestamp(calendar.timegm(e.updated_parsed)) base_slug = BM.BlogPost.make_base_slug(title, updated) - b_count = BM.BlogPost.query.find(dict(slug=base_slug, app_config_id=appid)).count() + b_count = BM.BlogPost.query.find( + dict(slug=base_slug, app_config_id=appid)).count() if b_count == 0: post = BM.BlogPost(title=title, text=content, timestamp=updated, - app_config_id=appid, - state='published') - post.neighborhood_id=c.project.neighborhood_id + app_config_id=appid, + state='published') + post.neighborhood_id = c.project.neighborhood_id post.make_slug() post.commit() http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeBlog/forgeblog/main.py ---------------------------------------------------------------------- diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py index bd0f821..1bb4ced 100644 --- a/ForgeBlog/forgeblog/main.py +++ b/ForgeBlog/forgeblog/main.py @@ -57,8 +57,9 @@ from forgeblog import widgets log = logging.getLogger(__name__) + class W: - thread=w.Thread( + thread = w.Thread( page=None, limit=None, page_size=None, count=None, style='linear') pager = widgets.BlogPager() @@ -73,30 +74,31 @@ class W: search_results = SearchResults() help_modal = SearchHelp() + class ForgeBlogApp(Application): __version__ = version.__version__ - tool_label='Blog' - tool_description=""" + tool_label = 'Blog' + tool_description = """ Share exciting news and progress updates with your community. """ - default_mount_label='Blog' - default_mount_point='blog' + default_mount_label = 'Blog' + default_mount_point = 'blog' permissions = ['configure', 'read', 'write', - 'unmoderated_post', 'post', 'moderate', 'admin'] + 'unmoderated_post', 'post', 'moderate', 'admin'] permissions_desc = { 'read': 'View blog entries.', 'write': 'Create new blog entry.', 'admin': 'Set permissions. Enable/disable commenting.', } - ordinal=14 + ordinal = 14 exportable = True config_options = Application.config_options default_external_feeds = [] - icons={ - 24:'images/blog_24.png', - 32:'images/blog_32.png', - 48:'images/blog_48.png' + icons = { + 24: 'images/blog_24.png', + 32: 'images/blog_32.png', + 48: 'images/blog_48.png' } def __init__(self, project, config): @@ -114,12 +116,14 @@ class ForgeBlogApp(Application): else: external_feeds = self.default_external_feeds return external_feeds + def fset(self, new_external_feeds): globals = BM.Globals.query.get(app_config_id=self.config._id) if globals is not None: globals.external_feeds = new_external_feeds elif len(new_external_feeds) > 0: - globals = BM.Globals(app_config_id=self.config._id, external_feeds=new_external_feeds) + globals = BM.Globals( + app_config_id=self.config._id, external_feeds=new_external_feeds) if globals is not None: session(globals).flush() @@ -132,7 +136,7 @@ class ForgeBlogApp(Application): menu_id = self.config.options.mount_label with h.push_config(c, app=self): return [ - SitemapEntry(menu_id, '.')[self.sidebar_menu()] ] + SitemapEntry(menu_id, '.')[self.sidebar_menu()]] @property def show_discussion(self): @@ -147,21 +151,23 @@ class ForgeBlogApp(Application): links = [ SitemapEntry('Home', base), SitemapEntry('Search', base + 'search'), - ] + ] if has_access(self, 'write')(): - links += [ SitemapEntry('New Post', base + 'new') ] + links += [SitemapEntry('New Post', base + 'new')] return links def admin_menu(self): import sys - admin_url = c.project.url() + 'admin/' + self.config.options.mount_point + '/' + admin_url = c.project.url() + 'admin/' + \ + self.config.options.mount_point + '/' # temporarily disabled until some bugs are fixed links = super(ForgeBlogApp, self).admin_menu(force_options=True) # We don't want external feeds in menu unless they're enabled if asbool(config.get('forgeblog.exfeed', 'false')): - links.insert(0, SitemapEntry('External feeds', admin_url + 'exfeed', className='admin_modal')) + links.insert(0, SitemapEntry('External feeds', + admin_url + 'exfeed', className='admin_modal')) return links - #return super(ForgeBlogApp, self).admin_menu(force_options=True) + # return super(ForgeBlogApp, self).admin_menu(force_options=True) def install(self, project): 'Set up any default permissions and roles here' @@ -180,7 +186,7 @@ class ForgeBlogApp(Application): M.ACE.allow(role_developer, 'moderate'), M.ACE.allow(role_admin, 'configure'), M.ACE.allow(role_admin, 'admin'), - ] + ] def uninstall(self, project): "Remove all the tool's artifacts from the database" @@ -198,6 +204,7 @@ class ForgeBlogApp(Application): json.dump(post, f, cls=jsonify.GenericJSON, indent=2) f.write(']}') + class RootController(BaseController, FeedController): def __init__(self): @@ -264,7 +271,6 @@ class RootController(BaseController, FeedController): post = BM.BlogPost.new(**kw) redirect(h.really_unicode(post.url()).encode('utf-8')) - @with_trailing_slash @expose('jinja:allura:templates/markdown_syntax_dialog.html') def markdown_syntax_dialog(self, **kw): @@ -281,6 +287,7 @@ class RootController(BaseController, FeedController): raise exc.HTTPNotFound() return PostController(post), rest + class PostController(BaseController, FeedController): def __init__(self, post): @@ -341,7 +348,7 @@ class PostController(BaseController, FeedController): self.post.delete() flash('Post deleted', 'info') redirect(h.really_unicode(c.app.url).encode('utf-8')) - for k,v in kw.iteritems(): + for k, v in kw.iteritems(): setattr(self.post, k, v) self.post.commit() redirect('.') @@ -379,13 +386,16 @@ class PostController(BaseController, FeedController): self.post.url()) def _get_version(self, version): - if not version: return self.post + if not version: + return self.post try: return self.post.get_version(version) except ValueError: raise exc.HTTPNotFound() + class BlogAdminController(DefaultAdminController): + def __init__(self, app): self.app = app @@ -399,9 +409,11 @@ class BlogAdminController(DefaultAdminController): @expose() @require_post() def set_options(self, show_discussion=False): - self.app.config.options['show_discussion'] = show_discussion and True or False + self.app.config.options[ + 'show_discussion'] = show_discussion and True or False flash('Blog options updated') - redirect(h.really_unicode(c.project.url()+'admin/tools').encode('utf-8')) + redirect(h.really_unicode(c.project.url() + 'admin/tools') + .encode('utf-8')) @without_trailing_slash @expose('jinja:forgeblog:templates/blog/admin_exfeed.html') @@ -442,12 +454,14 @@ class BlogAdminController(DefaultAdminController): self.app.external_feeds_list = exfeed_list flash('External feeds updated') if len(invalid_list) > 0: - flash('Invalid link(s): %s' % ','.join(link for link in invalid_list), 'error') + flash('Invalid link(s): %s' % + ','.join(link for link in invalid_list), 'error') - redirect(c.project.url()+'admin/tools') + redirect(c.project.url() + 'admin/tools') class RootRestController(BaseController): + def __init__(self): self._discuss = AppDiscussionRestController() @@ -472,7 +486,8 @@ class RootRestController(BaseController): post_titles = [] for post in posts: if has_access(post, 'read')(): - post_titles.append({'title': post.title, 'url': h.absurl('/rest' + post.url())}) + post_titles.append( + {'title': post.title, 'url': h.absurl('/rest' + post.url())}) return dict(posts=post_titles, count=result['count'], limit=result['limit'], page=result['page']) @expose() http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeBlog/forgeblog/model/blog.py ---------------------------------------------------------------------- diff --git a/ForgeBlog/forgeblog/model/blog.py b/ForgeBlog/forgeblog/model/blog.py index 7e34aea..f520265 100644 --- a/ForgeBlog/forgeblog/model/blog.py +++ b/ForgeBlog/forgeblog/model/blog.py @@ -36,23 +36,26 @@ from allura.lib import utils config = utils.ConfigProxy( common_suffix='forgemail.domain') + class Globals(MappedClass): class __mongometa__: name = 'blog-globals' session = M.project_orm_session - indexes = [ 'app_config_id' ] + indexes = ['app_config_id'] type_s = 'BlogGlobals' _id = FieldProperty(schema.ObjectId) - app_config_id = ForeignIdProperty('AppConfig', if_missing=lambda:c.app.config._id) - external_feeds=FieldProperty([str]) + app_config_id = ForeignIdProperty( + 'AppConfig', if_missing=lambda: c.app.config._id) + external_feeds = FieldProperty([str]) class BlogPostSnapshot(M.Snapshot): + class __mongometa__: - name='blog_post_snapshot' - type_s='Blog Post Snapshot' + name = 'blog_post_snapshot' + type_s = 'Blog Post Snapshot' def original(self): return BlogPost.query.get(_id=self.artifact_id) @@ -92,14 +95,18 @@ class BlogPostSnapshot(M.Snapshot): return None return orig.email_address + class BlogPost(M.VersionedArtifact, ActivityObject): + class __mongometa__: - name='blog_post' + name = 'blog_post' history_class = BlogPostSnapshot - unique_indexes = [ ('app_config_id', 'slug') ] + unique_indexes = [('app_config_id', 'slug')] indexes = [ - ('app_config_id', 'state', 'timestamp'), # for [[project_blog_posts]] macro - ('neighborhood_id', 'state', 'timestamp'), # for [[neighborhood_blog_posts]] macro + # for [[project_blog_posts]] macro + ('app_config_id', 'state', 'timestamp'), + # for [[neighborhood_blog_posts]] macro + ('neighborhood_id', 'state', 'timestamp'), ] type_s = 'Blog Post' @@ -109,7 +116,8 @@ class BlogPost(M.VersionedArtifact, ActivityObject): text_cache = FieldProperty(MarkdownCache) timestamp = FieldProperty(datetime, if_missing=datetime.utcnow) slug = FieldProperty(str) - state = FieldProperty(schema.OneOf('draft', 'published'), if_missing='draft') + state = FieldProperty( + schema.OneOf('draft', 'published'), if_missing='draft') neighborhood_id = ForeignIdProperty('Neighborhood', if_missing=None) @property @@ -128,12 +136,14 @@ class BlogPost(M.VersionedArtifact, ActivityObject): def _get_date(self): return self.timestamp.date() + def _set_date(self, value): self.timestamp = datetime.combine(value, self.time) date = property(_get_date, _set_date) def _get_time(self): return self.timestamp.time() + def _set_time(self, value): self.timestamp = datetime.combine(self.date, value) time = property(_get_time, _set_time) @@ -162,19 +172,20 @@ class BlogPost(M.VersionedArtifact, ActivityObject): # first and *then* truncating doesn't work either, because the # ellipsis tag ends up orphaned from the main text. ellipsis = '... [read more](%s)' % self.url() - paragraphs = self.text.replace('\r','').split('\n\n') + paragraphs = self.text.replace('\r', '').split('\n\n') total_length = 0 for i, p in enumerate(paragraphs): total_length += len(p) if total_length >= 400: break - text = '\n\n'.join(paragraphs[:i+1]) + text = '\n\n'.join(paragraphs[:i + 1]) return g.markdown.convert(text + (ellipsis if i + 1 < len(paragraphs) - else '')) + else '')) @property def email_address(self): - domain = '.'.join(reversed(self.app.url[1:-1].split('/'))).replace('_', '-') + domain = '.'.join( + reversed(self.app.url[1:-1].split('/'))).replace('_', '-') return '%s@%s%s' % (self.title.replace('/', '.'), domain, config.common_suffix) @staticmethod @@ -184,8 +195,8 @@ class BlogPost(M.VersionedArtifact, ActivityObject): for ch in title.replace(' ', '-') if ch.isalnum() or ch == '-') return '%s/%s' % ( - timestamp.strftime('%Y/%m'), - slugsafe) + timestamp.strftime('%Y/%m'), + slugsafe) def make_slug(self): base = BlogPost.make_base_slug(self.title, self.timestamp) @@ -195,7 +206,7 @@ class BlogPost(M.VersionedArtifact, ActivityObject): session(self).insert_now(self, state(self)) return self.slug except DuplicateKeyError: - self.slug = base + '-%.3d' % randint(0,999) + self.slug = base + '-%.3d' % randint(0, 999) def url(self): return self.app.url + self.slug + '/' @@ -215,26 +226,27 @@ class BlogPost(M.VersionedArtifact, ActivityObject): def get_version(self, version): HC = self.__mongometa__.history_class - return HC.query.find({'artifact_id':self._id, 'version':int(version)}).one() + return HC.query.find({'artifact_id': self._id, 'version': int(version)}).one() def commit(self): activity = functools.partial(g.director.create_activity, c.user, - target=c.project) + target=c.project) self.subscribe() super(BlogPost, self).commit() if self.version > 1: - v1 = self.get_version(self.version-1) + v1 = self.get_version(self.version - 1) v2 = self - la = [ line + '\n' for line in v1.text.splitlines() ] - lb = [ line + '\n' for line in v2.text.splitlines() ] + la = [line + '\n' for line in v1.text.splitlines()] + lb = [line + '\n' for line in v2.text.splitlines()] diff = ''.join(difflib.unified_diff( - la, lb, - 'v%d' % v1.version, - 'v%d' % v2.version)) + la, lb, + 'v%d' % v1.version, + 'v%d' % v2.version)) description = diff if v1.state != 'published' and v2.state == 'published': activity('created', self) - M.Feed.post(self, self.title, self.text, author=self.author(), pubdate=self.get_version(1).timestamp) + M.Feed.post(self, self.title, self.text, author=self.author(), + pubdate=self.get_version(1).timestamp) description = self.text subject = '%s created post %s' % ( c.user.username, self.title) @@ -252,7 +264,8 @@ class BlogPost(M.VersionedArtifact, ActivityObject): c.user.username, self.title) if self.state == 'published': activity('created', self) - M.Feed.post(self, self.title, self.text, author=self.author(), pubdate=self.timestamp) + M.Feed.post(self, self.title, self.text, + author=self.author(), pubdate=self.timestamp) if self.state == 'published': M.Notification.post( artifact=self, topic='metadata', text=description, subject=subject) @@ -282,10 +295,11 @@ class BlogPost(M.VersionedArtifact, ActivityObject): class Attachment(M.BaseAttachment): - ArtifactClass=BlogPost + ArtifactClass = BlogPost + class __mongometa__: - polymorphic_identity='BlogAttachment' - attachment_type=FieldProperty(str, if_missing='BlogAttachment') + polymorphic_identity = 'BlogAttachment' + attachment_type = FieldProperty(str, if_missing='BlogAttachment') Mapper.compile_all() http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeBlog/forgeblog/tests/functional/test_rest.py ---------------------------------------------------------------------- diff --git a/ForgeBlog/forgeblog/tests/functional/test_rest.py b/ForgeBlog/forgeblog/tests/functional/test_rest.py index b1b3bc7..05e06c8 100644 --- a/ForgeBlog/forgeblog/tests/functional/test_rest.py +++ b/ForgeBlog/forgeblog/tests/functional/test_rest.py @@ -44,7 +44,9 @@ class TestBlogApi(TestRestApiBase): 'labels': 'label1, label2' } r = self.api_post('/rest/p/test/blog/', **data) - assert_equal(r.location, 'http://localhost/rest/p/test/blog/%s/%s/test/' % (date.today().strftime("%Y"), date.today().strftime("%m"))) + assert_equal( + r.location, 'http://localhost/rest/p/test/blog/%s/%s/test/' % + (date.today().strftime("%Y"), date.today().strftime("%m"))) assert_equal(r.status_int, 201) url = '/rest' + BM.BlogPost.query.find().first().url() r = self.api_get('/rest/p/test/blog/') @@ -58,8 +60,6 @@ class TestBlogApi(TestRestApiBase): assert_equal(r.json['state'], data['state']) assert_equal(r.json['labels'], data['labels'].split(',')) - - def test_update_post(self): data = { 'title': 'test', @@ -100,8 +100,10 @@ class TestBlogApi(TestRestApiBase): assert_equal(r.status_int, 404) def test_read_permissons(self): - self.api_post('/rest/p/test/blog/', title='test', text='test text', state='published') - self.app.get('/rest/p/test/blog/', extra_environ={'username': '*anonymous'}, status=200) + self.api_post('/rest/p/test/blog/', title='test', + text='test text', state='published') + self.app.get('/rest/p/test/blog/', + extra_environ={'username': '*anonymous'}, status=200) p = M.Project.query.get(shortname='test') acl = p.app_instance('blog').config.acl anon = M.ProjectRole.by_name('*anonymous')._id @@ -113,7 +115,8 @@ class TestBlogApi(TestRestApiBase): def test_new_post_permissons(self): self.app.post('/rest/p/test/blog/', - params=dict(title='test', text='test text', state='published'), + params=dict(title='test', text='test text', + state='published'), extra_environ={'username': '*anonymous'}, status=401) p = M.Project.query.get(shortname='test') @@ -122,15 +125,18 @@ class TestBlogApi(TestRestApiBase): anon_write = M.ACE.allow(anon, 'write') acl.append(anon_write) self.app.post('/rest/p/test/blog/', - params=dict(title='test', text='test text', state='published'), + params=dict(title='test', text='test text', + state='published'), extra_environ={'username': '*anonymous'}, status=201) def test_update_post_permissons(self): - self.api_post('/rest/p/test/blog/', title='test', text='test text', state='published') + self.api_post('/rest/p/test/blog/', title='test', + text='test text', state='published') url = '/rest' + BM.BlogPost.query.find().first().url() self.app.post(url.encode('utf-8'), - params=dict(title='test2', text='test text2', state='published'), + params=dict(title='test2', text='test text2', + state='published'), extra_environ={'username': '*anonymous'}, status=401) p = M.Project.query.get(shortname='test') @@ -139,7 +145,8 @@ class TestBlogApi(TestRestApiBase): anon_write = M.ACE.allow(anon, 'write') acl.append(anon_write) self.app.post(url.encode('utf-8'), - params=dict(title='test2', text='test text2', state='published'), + params=dict(title='test2', text='test text2', + state='published'), extra_environ={'username': '*anonymous'}, status=200) r = self.api_get(url) @@ -148,12 +155,15 @@ class TestBlogApi(TestRestApiBase): assert_equal(r.json['state'], 'published') def test_permission_draft_post(self): - self.api_post('/rest/p/test/blog/', title='test', text='test text', state='draft') - r = self.app.get('/rest/p/test/blog/', extra_environ={'username': '*anonymous'}) + self.api_post('/rest/p/test/blog/', title='test', + text='test text', state='draft') + r = self.app.get('/rest/p/test/blog/', + extra_environ={'username': '*anonymous'}) assert_equal(r.json['posts'], []) url = '/rest' + BM.BlogPost.query.find().first().url() self.app.post(url.encode('utf-8'), - params=dict(title='test2', text='test text2', state='published'), + params=dict(title='test2', text='test text2', + state='published'), extra_environ={'username': '*anonymous'}, status=401) p = M.Project.query.get(shortname='test') @@ -161,22 +171,29 @@ class TestBlogApi(TestRestApiBase): anon = M.ProjectRole.by_name('*anonymous')._id anon_write = M.ACE.allow(anon, 'write') acl.append(anon_write) - r = self.app.get('/rest/p/test/blog/', extra_environ={'username': '*anonymous'}) + r = self.app.get('/rest/p/test/blog/', + extra_environ={'username': '*anonymous'}) assert_equal(r.json['posts'][0]['title'], 'test') def test_draft_post(self): - self.api_post('/rest/p/test/blog/', title='test', text='test text', state='draft') - r = self.app.get('/rest/p/test/blog/', extra_environ={'username': '*anonymous'}) + self.api_post('/rest/p/test/blog/', title='test', + text='test text', state='draft') + r = self.app.get('/rest/p/test/blog/', + extra_environ={'username': '*anonymous'}) assert_equal(r.json['posts'], []) url = '/rest' + BM.BlogPost.query.find().first().url() self.api_post(url, state='published') - r = self.app.get('/rest/p/test/blog/', extra_environ={'username': '*anonymous'}) + r = self.app.get('/rest/p/test/blog/', + extra_environ={'username': '*anonymous'}) assert_equal(r.json['posts'][0]['title'], 'test') def test_pagination(self): - self.api_post('/rest/p/test/blog/', title='test1', text='test text1', state='published') - self.api_post('/rest/p/test/blog/', title='test2', text='test text2', state='published') - self.api_post('/rest/p/test/blog/', title='test3', text='test text3', state='published') + self.api_post('/rest/p/test/blog/', title='test1', + text='test text1', state='published') + self.api_post('/rest/p/test/blog/', title='test2', + text='test text2', state='published') + self.api_post('/rest/p/test/blog/', title='test3', + text='test text3', state='published') r = self.api_get('/rest/p/test/blog/', limit='1', page='0') assert_equal(r.json['posts'][0]['title'], 'test3') assert_equal(len(r.json['posts']), 1) http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeBlog/forgeblog/tests/functional/test_root.py ---------------------------------------------------------------------- diff --git a/ForgeBlog/forgeblog/tests/functional/test_root.py b/ForgeBlog/forgeblog/tests/functional/test_root.py index 96a8113..d3eb932 100644 --- a/ForgeBlog/forgeblog/tests/functional/test_root.py +++ b/ForgeBlog/forgeblog/tests/functional/test_root.py @@ -32,14 +32,15 @@ from allura import model as M # CommentController methods exposed: # reply, delete + class Test(TestController): def _post(self, slug='', **kw): d = { - 'title':'My Post', - 'text':'Nothing to see here', - 'labels':'', - 'state':'published'} + 'title': 'My Post', + 'text': 'Nothing to see here', + 'labels': '', + 'state': 'published'} d.update(kw) r = self.app.post('/blog%s/save' % slug, params=d) return r @@ -210,7 +211,7 @@ class Test(TestController): self._post(title='two', text='[blog:%s/one]' % d) M.MonQTask.run_ready() ThreadLocalORMSession.flush_all() - r= self.app.get('/blog/%s/one/' % d) + r = self.app.get('/blog/%s/one/' % d) assert 'Related' in r assert 'Blog Post: %s/two' % d in r http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeBlog/forgeblog/tests/test_app.py ---------------------------------------------------------------------- diff --git a/ForgeBlog/forgeblog/tests/test_app.py b/ForgeBlog/forgeblog/tests/test_app.py index 895bb06..bab8f22 100644 --- a/ForgeBlog/forgeblog/tests/test_app.py +++ b/ForgeBlog/forgeblog/tests/test_app.py @@ -62,10 +62,13 @@ class TestBulkExport(object): blog.bulk_export(f) f.seek(0) blog = json.loads(f.read()) - blog['posts'] = sorted(blog['posts'], key=lambda x: x['title'], reverse=True) + blog['posts'] = sorted( + blog['posts'], key=lambda x: x['title'], reverse=True) assert_equal(blog['posts'][0]['title'], 'Test2 title') assert_equal(blog['posts'][0]['text'], 'test2 post') assert_equal(blog['posts'][1]['title'], 'Test title') assert_equal(blog['posts'][1]['text'], 'test post') - assert_equal(blog['posts'][1]['labels'], ['the firstlabel', 'the second label']) - assert_equal(blog['posts'][1]['discussion_thread']['posts'][0]['text'], 'test comment') + assert_equal(blog['posts'][1]['labels'], + ['the firstlabel', 'the second label']) + assert_equal(blog['posts'][1]['discussion_thread'] + ['posts'][0]['text'], 'test comment') http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeBlog/forgeblog/tests/test_commands.py ---------------------------------------------------------------------- diff --git a/ForgeBlog/forgeblog/tests/test_commands.py b/ForgeBlog/forgeblog/tests/test_commands.py index 569470e..a086519 100644 --- a/ForgeBlog/forgeblog/tests/test_commands.py +++ b/ForgeBlog/forgeblog/tests/test_commands.py @@ -30,15 +30,18 @@ from allura import model as M from forgeblog import model as BM -test_config = pkg_resources.resource_filename('allura', '../test.ini') + '#main' +test_config = pkg_resources.resource_filename( + 'allura', '../test.ini') + '#main' def setUp(): setup_basic_test() setup_global_objects() + def _mock_feed(*entries): class attrdict(dict): + def __getattr__(self, name): return self[name] @@ -53,11 +56,12 @@ def _mock_feed(*entries): subtitle='', summary='', link='http://example.com/', - updated=datetime.utcnow()+timedelta(days=_mock_feed.i - 100)) + updated=datetime.utcnow() + timedelta(days=_mock_feed.i - 100)) entry.update(e) entry['updated_parsed'] = entry['updated'].timetuple() if 'content' in entry: - entry['content'] = [attrdict(type=entry['content_type'], value=entry['content'])] + entry['content'] = [ + attrdict(type=entry['content_type'], value=entry['content'])] if 'summary_detail' in entry: entry['summary_detail'] = attrdict(entry['summary_detail']) feed.entries.append(entry) @@ -65,6 +69,7 @@ def _mock_feed(*entries): return feed _mock_feed.i = 0 + @skipif(module_not_available('html2text')) @mock.patch.object(feedparser, 'parse') def test_pull_rss_feeds(parsefeed): @@ -82,11 +87,11 @@ def test_pull_rss_feeds(parsefeed): ) rendered_html_content = "\n".join([ - r"1\. foo", + r"1\. foo", "", - r"\#foo bar [baz](baz) foo bar ", + r"\#foo bar [baz](baz) foo bar ", "", - r"\#foo bar [ baz ](baz)", + r"\#foo bar [ baz ](baz)", " [link](http://example.com/)", ]) @@ -97,13 +102,14 @@ def test_pull_rss_feeds(parsefeed): dict(summary_detail=dict(type='text/html', value=html_content)), ) - base_app = M.AppConfig.query.find().all()[0] - tmp_app = M.AppConfig(tool_name=u'Blog', discussion_id=base_app.discussion_id, - project_id=base_app.project_id, - options={u'ordinal': 0, u'show_right_bar': True, - u'project_name': base_app.project.name, - u'mount_point': u'blog', - u'mount_label': u'Blog'}) + base_app = M.AppConfig.query.find().all()[0] + tmp_app = M.AppConfig( + tool_name=u'Blog', discussion_id=base_app.discussion_id, + project_id=base_app.project_id, + options={u'ordinal': 0, u'show_right_bar': True, + u'project_name': base_app.project.name, + u'mount_point': u'blog', + u'mount_label': u'Blog'}) new_external_feeds = ['http://example.com/news/feed/'] BM.Globals(app_config_id=tmp_app._id, external_feeds=new_external_feeds) ThreadLocalORMSession.flush_all() @@ -113,7 +119,8 @@ def test_pull_rss_feeds(parsefeed): cmd.run([test_config, '-a', tmp_app._id]) cmd.command() parsefeed.assert_called_with('http://example.com/news/feed/') - posts = BM.BlogPost.query.find({'app_config_id': tmp_app._id}).sort('timestamp', 1) + posts = BM.BlogPost.query.find( + {'app_config_id': tmp_app._id}).sort('timestamp', 1) assert_equal(posts.count(), 4) posts = posts.all() assert_equal(posts[0].title, 'Test') @@ -125,6 +132,7 @@ def test_pull_rss_feeds(parsefeed): assert_equal(posts[3].title, 'Default Title 4') assert_equal(posts[3].text, rendered_html_content) + @skipif(module_not_available('html2text')) def test_plaintext_preprocessor(): from html2text import html2text @@ -140,10 +148,11 @@ def test_plaintext_preprocessor(): ) html = g.markdown.convert(text) assert_equal(html, - '

1. foo ' - '#foo bar baz foo bar ' - '#foo bar baz

' - ) + '

1. foo ' + '#foo bar baz foo bar ' + '#foo bar baz

' + ) + @skipif(module_not_available('html2text')) def test_plaintext_preprocessor_wrapped(): @@ -162,7 +171,7 @@ def test_plaintext_preprocessor_wrapped(): ) html = g.markdown.convert(text) assert_equal(html, - '

1. foo

\n' - '

#foo bar baz foo bar

\n' - '

#foo bar baz

' - ) + '

1. foo

\n' + '

#foo bar baz foo bar

\n' + '

#foo bar baz

' + ) http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeBlog/forgeblog/tests/test_roles.py ---------------------------------------------------------------------- diff --git a/ForgeBlog/forgeblog/tests/test_roles.py b/ForgeBlog/forgeblog/tests/test_roles.py index a352305..e270bec 100644 --- a/ForgeBlog/forgeblog/tests/test_roles.py +++ b/ForgeBlog/forgeblog/tests/test_roles.py @@ -22,6 +22,7 @@ from allura import model as M from allura.lib import security from allura.lib import helpers as h + def setUp(): setup_basic_test() setup_global_objects() @@ -29,10 +30,12 @@ def setUp(): c.project.install_app('blog', 'blog') g.set_app('blog') + def test_role_assignments(): admin = M.User.by_username('test-admin') user = M.User.by_username('test-user') anon = M.User.anonymous() + def check_access(perm): pred = security.has_access(c.app, perm) return pred(user=admin), pred(user=user), pred(user=anon) http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeBlog/forgeblog/tests/unit/__init__.py ---------------------------------------------------------------------- diff --git a/ForgeBlog/forgeblog/tests/unit/__init__.py b/ForgeBlog/forgeblog/tests/unit/__init__.py index 86e891f..dbef2b5 100644 --- a/ForgeBlog/forgeblog/tests/unit/__init__.py +++ b/ForgeBlog/forgeblog/tests/unit/__init__.py @@ -28,16 +28,18 @@ from alluratest.controller import setup_basic_test def setUp(): setup_basic_test() + class BlogTestWithModel(object): + def setUp(self): bootstrap.wipe_database() project_reg = plugin.ProjectRegistrationProvider.get() c.user = bootstrap.create_user('Test User') neighborhood = M.Neighborhood(name='Projects', url_prefix='/p/', - features=dict(private_projects = False, - max_projects = None, - css = 'none', - google_analytics = False)) + features=dict(private_projects=False, + max_projects=None, + css='none', + google_analytics=False)) project_reg.register_neighborhood_project(neighborhood, [c.user]) c.project = neighborhood.register_project('test', c.user) c.project.install_app('Blog', 'blog') http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeBlog/forgeblog/tests/unit/test_blog_post.py ---------------------------------------------------------------------- diff --git a/ForgeBlog/forgeblog/tests/unit/test_blog_post.py b/ForgeBlog/forgeblog/tests/unit/test_blog_post.py index f2274d9..fadfcf0 100644 --- a/ForgeBlog/forgeblog/tests/unit/test_blog_post.py +++ b/ForgeBlog/forgeblog/tests/unit/test_blog_post.py @@ -23,13 +23,16 @@ from forgeblog import model as M from forgeblog.tests.unit import BlogTestWithModel from allura.model import Feed + def wrapped(s): return '

%s

' % s class TestBlogPost(BlogTestWithModel): + def test_new(self): - post = M.BlogPost.new(title='test', text='test message', state='published') + post = M.BlogPost.new( + title='test', text='test message', state='published') assert_equal(post.title, 'test') assert_equal(post.text, 'test message') assert_equal(post.state, 'published') @@ -38,6 +41,7 @@ class TestBlogPost(BlogTestWithModel): class TestFeed(BlogTestWithModel): + def testd(self): post = M.BlogPost() post.title = 'test' @@ -57,6 +61,7 @@ class TestFeed(BlogTestWithModel): class TestHtmlPreview(BlogTestWithModel): + def _make_post(self, text): post = M.BlogPost() post.text = text http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeBlog/forgeblog/widgets.py ---------------------------------------------------------------------- diff --git a/ForgeBlog/forgeblog/widgets.py b/ForgeBlog/forgeblog/widgets.py index ea763ad..9d54903 100644 --- a/ForgeBlog/forgeblog/widgets.py +++ b/ForgeBlog/forgeblog/widgets.py @@ -24,42 +24,50 @@ from allura.lib.widgets import form_fields as ffw from allura.lib.widgets import forms from allura import model as M + class BlogPager(ffw.PageList): - template='jinja:forgeblog:templates/blog_widgets/page_list.html' + template = 'jinja:forgeblog:templates/blog_widgets/page_list.html' + class NewPostForm(forms.ForgeForm): - template='jinja:forgeblog:templates/blog_widgets/post_form.html' + template = 'jinja:forgeblog:templates/blog_widgets/post_form.html' + class fields(ew_core.NameList): title = ew.TextField(validator=fev.UnicodeString(not_empty=True, - messages={'empty':"You must provide a Title"}), + messages={'empty': "You must provide a Title"}), attrs=dict(placeholder='Enter your title here', title='Enter your title here', style='width: 425px')) text = ffw.MarkdownEdit(show_label=False, - attrs=dict(placeholder='Enter your content here', - title='Enter your content here')) + attrs=dict( + placeholder='Enter your content here', + title='Enter your content here')) state = ew.SingleSelectField( options=[ ew.Option(py_value='draft', label='Draft'), - ew.Option(py_value='published', label='Published') ]) + ew.Option(py_value='published', label='Published')]) labels = ffw.LabelEdit(placeholder='Add labels here', title='Add labels here') def resources(self): - for r in super(NewPostForm, self).resources(): yield r + for r in super(NewPostForm, self).resources(): + yield r yield ew.JSScript(''' $(function() { $('input[name="title"]').focus(); }); ''') + class EditPostForm(NewPostForm): + class buttons(ew_core.NameList): delete = ew.SubmitButton(label='Delete') + class ViewPostForm(ew_core.Widget): - template='jinja:forgeblog:templates/blog_widgets/view_post.html' - defaults=dict( + template = 'jinja:forgeblog:templates/blog_widgets/view_post.html' + defaults = dict( ew_core.Widget.defaults, value=None, subscribed=None, @@ -71,8 +79,9 @@ class ViewPostForm(ew_core.Widget): M.Mailbox.subscribed(artifact=kw.get('value')) return kw + class PreviewPostForm(ew_core.Widget): - template='jinja:forgeblog:templates/blog_widgets/preview_post.html' - defaults=dict( + template = 'jinja:forgeblog:templates/blog_widgets/preview_post.html' + defaults = dict( ew_core.Widget.defaults, value=None) http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeBlog/setup.py ---------------------------------------------------------------------- diff --git a/ForgeBlog/setup.py b/ForgeBlog/setup.py index 10f3fae..40befd6 100644 --- a/ForgeBlog/setup.py +++ b/ForgeBlog/setup.py @@ -16,7 +16,8 @@ # under the License. from setuptools import setup, find_packages -import sys, os +import sys +import os from forgeblog.version import __version__ @@ -25,7 +26,8 @@ setup(name='ForgeBlog', description="", long_description="""\ """, - classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers + # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers + classifiers=[], keywords='', author='', author_email='', http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeChat/forgechat/command.py ---------------------------------------------------------------------- diff --git a/ForgeChat/forgechat/command.py b/ForgeChat/forgechat/command.py index fdba6e2..e667843 100644 --- a/ForgeChat/forgechat/command.py +++ b/ForgeChat/forgechat/command.py @@ -38,9 +38,10 @@ from allura import model as M from forgechat import model as CM + class IRCBotCommand(allura.command.Command): - min_args=1 - max_args=1 + min_args = 1 + max_args = 1 usage = '' summary = 'Connect to all configured IRC servers and relay messages' parser = command.Command.standard_parser(verbose=True) @@ -58,11 +59,13 @@ class IRCBotCommand(allura.command.Command): asint(tg.config.get('forgechat.port', '6667'))) asyncore.loop() except Exception: - base.log.exception('Error in ircbot asyncore.loop(), restart in 5s') + base.log.exception( + 'Error in ircbot asyncore.loop(), restart in 5s') time.sleep(5) + class IRCBot(asynchat.async_chat): - TIME_BETWEEN_CONFIGS=timedelta(minutes=1) + TIME_BETWEEN_CONFIGS = timedelta(minutes=1) def __init__(self, host, port, nick='sfbot'): self.logger = logging.getLogger(__name__) @@ -91,7 +94,7 @@ class IRCBot(asynchat.async_chat): def found_terminator(self): request = ''.join(self.data) self.logger.debug('RECV %s', request) - self.data=[] + self.data = [] if request.startswith(':'): sender, cmd, rest = request[1:].split(' ', 2) sender = sender.split('!', 1) @@ -114,7 +117,7 @@ class IRCBot(asynchat.async_chat): def check_configure(self): if (datetime.utcnow() - self.last_configured - > self.TIME_BETWEEN_CONFIGS): + > self.TIME_BETWEEN_CONFIGS): self.configure() def say(self, s): @@ -131,7 +134,8 @@ class IRCBot(asynchat.async_chat): ThreadLocalORMSession.flush_all() def handle_command(self, sender, cmd, rest): - if cmd == 'NOTICE': pass + if cmd == 'NOTICE': + pass elif cmd == '433': self.set_nick() self.channels = {} @@ -140,10 +144,13 @@ class IRCBot(asynchat.async_chat): self.say('PONG ' + rest) elif cmd in ('NOTICE', 'PRIVMSG'): rcpt, msg = rest.split(' ', 1) - if not self.set_context(rcpt): return - if msg.startswith(':'): msg = msg[1:] + if not self.set_context(rcpt): + return + if msg.startswith(':'): + msg = msg[1:] self.log_channel(sender, cmd, rcpt, msg) - if cmd == 'NOTICE': return + if cmd == 'NOTICE': + return for lnk in search.find_shortlinks(msg): self.handle_shortlink(lnk, sender, rcpt) ThreadLocalORMSession.flush_all() @@ -152,9 +159,11 @@ class IRCBot(asynchat.async_chat): ThreadLocalORMSession.close_all() def set_context(self, rcpt): - if rcpt == self.nick: return False + if rcpt == self.nick: + return False chan = self.channels.get(rcpt, None) - if not chan: return False + if not chan: + return False h.set_context(chan.project_id, app_config_id=chan.app_config_id) return True @@ -164,8 +173,9 @@ class IRCBot(asynchat.async_chat): if security.has_access(art, 'read', user=M.User.anonymous())(): index = art.index() text = index['snippet_s'] or h.get_first(index, 'title') - url = urljoin(tg.config.get('base_url', 'http://sourceforge.net'), index['url_s']) - self.notice(rcpt, '[%s] - [%s](%s)' % (lnk.link, text,url)) + url = urljoin( + tg.config.get('base_url', 'http://sourceforge.net'), index['url_s']) + self.notice(rcpt, '[%s] - [%s](%s)' % (lnk.link, text, url)) def log_channel(self, sender, cmd, rcpt, rest): if cmd not in ('NOTICE', 'PRIVMSG'): http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeChat/forgechat/main.py ---------------------------------------------------------------------- diff --git a/ForgeChat/forgechat/main.py b/ForgeChat/forgechat/main.py index 1e7fb7b..c579ea5 100644 --- a/ForgeChat/forgechat/main.py +++ b/ForgeChat/forgechat/main.py @@ -43,25 +43,26 @@ from forgechat import version log = logging.getLogger(__name__) + class ForgeChatApp(Application): __version__ = version.__version__ - tool_label='Chat' - status='alpha' - default_mount_label='Chat' - default_mount_point='chat' - ordinal=13 - permissions = ['configure', 'read' ] + tool_label = 'Chat' + status = 'alpha' + default_mount_label = 'Chat' + default_mount_point = 'chat' + ordinal = 13 + permissions = ['configure', 'read'] permissions_desc = { 'configure': 'Set monitored IRC channel. Requires admin permission.', 'read': 'View chat logs.', } config_options = Application.config_options + [ ConfigOption('channel', str, ''), - ] - icons={ - 24:'images/chat_24.png', - 32:'images/chat_32.png', - 48:'images/chat_48.png' + ] + icons = { + 24: 'images/chat_24.png', + 32: 'images/chat_32.png', + 48: 'images/chat_48.png' } def __init__(self, project, config): @@ -79,14 +80,14 @@ class ForgeChatApp(Application): menu_id = self.config.options.mount_label with h.push_config(c, app=self): return [ - SitemapEntry(menu_id, '.')[self.sidebar_menu()] ] + SitemapEntry(menu_id, '.')[self.sidebar_menu()]] @h.exceptionless([], log) def sidebar_menu(self): return [ SitemapEntry('Home', '.'), SitemapEntry('Search', 'search'), - ] + ] def admin_menu(self): return super(ForgeChatApp, self).admin_menu() @@ -99,7 +100,7 @@ class ForgeChatApp(Application): self.config.acl = [ M.ACE.allow(role_anon, 'read'), M.ACE.allow(role_admin, 'configure'), - ] + ] CM.ChatChannel( project_id=self.config.project_id, app_config_id=self.config._id, @@ -108,15 +109,16 @@ class ForgeChatApp(Application): def uninstall(self, project): "Remove all the tool's artifacts from the database" CM.ChatChannel.query.remove(dict( - project_id=self.config.project_id, - app_config_id=self.config._id)) + project_id=self.config.project_id, + app_config_id=self.config._id)) super(ForgeChatApp, self).uninstall(project) + class AdminController(DefaultAdminController): @with_trailing_slash def index(self, **kw): - redirect(c.project.url()+'admin/tools') + redirect(c.project.url() + 'admin/tools') @expose() @require_post() @@ -130,6 +132,7 @@ class AdminController(DefaultAdminController): flash('Chat options updated') super(AdminController, self).configure(channel=channel) + class RootController(BaseController): @expose() @@ -159,8 +162,9 @@ class RootController(BaseController): @expose() def _lookup(self, y, m, d, *rest): - y,m,d = int(y), int(m), int(d) - return DayController(date(y,m,d)), rest + y, m, d = int(y), int(m), int(d) + return DayController(date(y, m, d)), rest + class DayController(RootController): @@ -171,8 +175,8 @@ class DayController(RootController): def index(self, **kw): q = dict( timestamp={ - '$gte':datetime.combine(self.day, time.min), - '$lte':datetime.combine(self.day, time.max)}) + '$gte': datetime.combine(self.day, time.min), + '$lte': datetime.combine(self.day, time.max)}) messages = CM.ChatMessage.query.find(q).sort('timestamp').all() prev = c.app.url + (self.day - timedelta(days=1)).strftime('%Y/%m/%d/') next = c.app.url + (self.day + timedelta(days=1)).strftime('%Y/%m/%d/') http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeChat/forgechat/model/chat.py ---------------------------------------------------------------------- diff --git a/ForgeChat/forgechat/model/chat.py b/ForgeChat/forgechat/model/chat.py index d2baeda..3907101 100644 --- a/ForgeChat/forgechat/model/chat.py +++ b/ForgeChat/forgechat/model/chat.py @@ -31,18 +31,20 @@ class ChatChannel(MappedClass): name = 'globals' session = M.main_orm_session indexes = ['project_id'] - unique_indexes = [ 'channel' ] + unique_indexes = ['channel'] _id = FieldProperty(S.ObjectId) project_id = FieldProperty(S.ObjectId) app_config_id = FieldProperty(S.ObjectId) channel = FieldProperty(str) - + + class ChatMessage(M.Artifact): + class __mongometa__: - name='chat_message' - indexes = [ 'timestamp' ] - type_s='Chat Message' + name = 'chat_message' + indexes = ['timestamp'] + type_s = 'Chat Message' timestamp = FieldProperty(datetime, if_missing=datetime.utcnow) sender = FieldProperty(str, if_missing='') @@ -50,7 +52,6 @@ class ChatMessage(M.Artifact): text = FieldProperty(str, if_missing='') text_cache = FieldProperty(MarkdownCache) - def index_id(self): id = 'Chat-%s:%s:%s.%s' % ( self.channel, @@ -73,7 +74,7 @@ class ChatMessage(M.Artifact): + str(self._id)) def shorthand_id(self): - return str(self._id) # pragma no cover + return str(self._id) # pragma no cover @property def sender_short(self): http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeChat/setup.py ---------------------------------------------------------------------- diff --git a/ForgeChat/setup.py b/ForgeChat/setup.py index 4f01472..6cb2c59 100644 --- a/ForgeChat/setup.py +++ b/ForgeChat/setup.py @@ -16,7 +16,8 @@ # under the License. from setuptools import setup, find_packages -import sys, os +import sys +import os from forgechat.version import __version__ @@ -25,7 +26,8 @@ setup(name='ForgeChat', description="", long_description="""\ """, - classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers + # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers + classifiers=[], keywords='', author='', author_email='', http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeDiscussion/forgediscussion/controllers/forum.py ---------------------------------------------------------------------- diff --git a/ForgeDiscussion/forgediscussion/controllers/forum.py b/ForgeDiscussion/forgediscussion/controllers/forum.py index 50ed7fb..fd2b816 100644 --- a/ForgeDiscussion/forgediscussion/controllers/forum.py +++ b/ForgeDiscussion/forgediscussion/controllers/forum.py @@ -39,27 +39,31 @@ from forgediscussion import tasks log = logging.getLogger(__name__) + class pass_validator(object): + def validate(self, v, s): return v -pass_validator=pass_validator() +pass_validator = pass_validator() + class ModelConfig(object): - Discussion=DM.Forum - Thread=DM.ForumThread - Post=DM.ForumPost - Attachment=M.DiscussionAttachment + Discussion = DM.Forum + Thread = DM.ForumThread + Post = DM.ForumPost + Attachment = M.DiscussionAttachment + class WidgetConfig(object): # Forms subscription_form = DW.SubscriptionForm() - subscribe_form=SubscribeForm() + subscribe_form = SubscribeForm() edit_post = DW.EditPost(show_subject=True) moderate_post = FW.ModeratePost() moderate_thread = FW.ModerateThread() flag_post = DW.FlagPost() post_filter = DW.PostFilter() - moderate_posts=DW.ModeratePosts() + moderate_posts = DW.ModeratePosts() # Other widgets discussion = FW.Forum() thread = FW.Thread() @@ -68,9 +72,10 @@ class WidgetConfig(object): announcements_table = FW.AnnouncementsTable() discussion_header = FW.ForumHeader() + class ForumController(DiscussionController): - M=ModelConfig - W=WidgetConfig + M = ModelConfig + W = WidgetConfig def _check_security(self): require_access(self.discussion, 'read') @@ -98,13 +103,14 @@ class ForumController(DiscussionController): limit=validators.Int(if_empty=25, if_invalid=25))) def index(self, threads=None, limit=25, page=0, count=0, **kw): if self.discussion.deleted: - redirect(self.discussion.url()+'deleted') + redirect(self.discussion.url() + 'deleted') limit, page, start = g.handle_paging(limit, page) - c.subscribed=M.Mailbox.subscribed(artifact=self.discussion) + c.subscribed = M.Mailbox.subscribed(artifact=self.discussion) threads = DM.ForumThread.query.find(dict(discussion_id=self.discussion._id, num_replies={'$gt': 0})) \ .sort([('flags', pymongo.DESCENDING), ('last_post_date', pymongo.DESCENDING)]) - response = super(ForumController, self).index(threads=threads.skip(start).limit(int(limit)).all(), - limit=limit, page=page, count=threads.count(), **kw) + response = super( + ForumController, self).index(threads=threads.skip(start).limit(int(limit)).all(), + limit=limit, page=page, count=threads.count(), **kw) c.discussion_header = self.W.discussion_header c.whole_forum_subscription_form = self.W.subscribe_form return response @@ -134,7 +140,7 @@ class ForumThreadController(ThreadController): limit=validators.Int(if_empty=25, if_invalid=25))) def index(self, limit=25, page=0, count=0, **kw): if self.thread.discussion.deleted and not has_access(c.app, 'configure')(): - redirect(self.thread.discussion.url()+'deleted') + redirect(self.thread.discussion.url() + 'deleted') return super(ForumThreadController, self).index(limit=limit, page=page, count=count, show_moderate=True, **kw) @h.vardec @@ -144,7 +150,7 @@ class ForumThreadController(ThreadController): def moderate(self, **kw): require_access(self.thread, 'moderate') if self.thread.discussion.deleted and not has_access(c.app, 'configure')(): - redirect(self.thread.discussion.url()+'deleted') + redirect(self.thread.discussion.url() + 'deleted') args = self.W.moderate_thread.validate(kw, None) tasks.calc_forum_stats.post(self.thread.discussion.shortname) if args.pop('delete', None): @@ -158,6 +164,7 @@ class ForumThreadController(ThreadController): self.thread.flags = args.pop('flags', []) redirect(self.thread.url()) + class ForumPostController(PostController): @h.vardec @@ -166,7 +173,7 @@ class ForumPostController(PostController): @utils.AntiSpam.validate('Spambot protection engaged') def index(self, **kw): if self.thread.discussion.deleted and not has_access(c.app, 'configure')(): - redirect(self.thread.discussion.url()+'deleted') + redirect(self.thread.discussion.url() + 'deleted') return super(ForumPostController, self).index(**kw) @expose() @@ -175,7 +182,7 @@ class ForumPostController(PostController): def moderate(self, **kw): require_access(self.post.thread, 'moderate') if self.thread.discussion.deleted and not has_access(c.app, 'configure')(): - redirect(self.thread.discussion.url()+'deleted') + redirect(self.thread.discussion.url() + 'deleted') args = self.W.moderate_post.validate(kw, None) tasks.calc_thread_stats.post(self.post.thread._id) tasks.calc_forum_stats(self.post.discussion.shortname) @@ -185,5 +192,6 @@ class ForumPostController(PostController): redirect(request.referer) super(ForumPostController, self).moderate(**kw) + class ForumModerationController(ModerationController): PostModel = DM.ForumPost http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeDiscussion/forgediscussion/controllers/root.py ---------------------------------------------------------------------- diff --git a/ForgeDiscussion/forgediscussion/controllers/root.py b/ForgeDiscussion/forgediscussion/controllers/root.py index d0526dc..82f4187 100644 --- a/ForgeDiscussion/forgediscussion/controllers/root.py +++ b/ForgeDiscussion/forgediscussion/controllers/root.py @@ -51,13 +51,14 @@ from forgediscussion.widgets.admin import AddForumShort log = logging.getLogger(__name__) + class RootController(BaseController, DispatchIndex, FeedController): class W(object): - forum_subscription_form=FW.ForumSubscriptionForm() - new_topic=DW.NewTopicPost(submit_text='Post') - announcements_table=FW.AnnouncementsTable() - add_forum=AddForumShort() + forum_subscription_form = FW.ForumSubscriptionForm() + new_topic = DW.NewTopicPost(submit_text='Post') + announcements_table = FW.AnnouncementsTable() + add_forum = AddForumShort() search_results = SearchResults() search_help = SearchHelp(comments=False, history=False) @@ -71,13 +72,13 @@ class RootController(BaseController, DispatchIndex, FeedController): c.new_topic = self.W.new_topic c.add_forum = self.W.add_forum c.announcements_table = self.W.announcements_table - announcements=model.ForumThread.query.find(dict( - app_config_id=c.app.config._id, - flags='Announcement', - )).all() + announcements = model.ForumThread.query.find(dict( + app_config_id=c.app.config._id, + flags='Announcement', + )).all() forums = model.Forum.query.find(dict( - app_config_id=c.app.config._id, - parent_id=None, deleted=False)).all() + app_config_id=c.app.config._id, + parent_id=None, deleted=False)).all() forums = [f for f in forums if h.has_access(f, 'read')()] return dict(forums=forums, announcements=announcements, @@ -105,7 +106,8 @@ class RootController(BaseController, DispatchIndex, FeedController): deleted=False)) c.new_topic = self.W.new_topic my_forums = [] - forum_name = h.really_unicode(unquote(forum_name)) if forum_name else None + forum_name = h.really_unicode(unquote( + forum_name)) if forum_name else None current_forum = None for f in forums: if forum_name == f.shortname: @@ -128,7 +130,7 @@ class RootController(BaseController, DispatchIndex, FeedController): redirect(request.referrer) require_access(discussion, 'post') thd = discussion.get_discussion_thread(dict( - headers=dict(Subject=subject)))[0] + headers=dict(Subject=subject)))[0] post = thd.post(subject, text) flash('Message posted') redirect(thd.url()) @@ -190,9 +192,10 @@ class RootController(BaseController, DispatchIndex, FeedController): thread = kw.pop('thread', []) objs = [] for data in forum: - objs.append(dict(obj=model.Forum.query.get(shortname=data['shortname'], - app_config_id=c.app.config._id), - subscribed=bool(data.get('subscribed')))) + objs.append( + dict(obj=model.Forum.query.get(shortname=data['shortname'], + app_config_id=c.app.config._id), + subscribed=bool(data.get('subscribed')))) for data in thread: objs.append(dict(obj=model.Thread.query.get(_id=data['id']), subscribed=bool(data.get('subscribed')))) @@ -212,7 +215,7 @@ class RootController(BaseController, DispatchIndex, FeedController): """ return FeedArgs( dict(project_id=project._id, app_config_id=app.config._id), - 'Recent posts to %s' % app.config.options.mount_label, + 'Recent posts to %s' % app.config.options.mount_label, app.url) @without_trailing_slash @@ -278,7 +281,8 @@ class RootController(BaseController, DispatchIndex, FeedController): next_expected_date = begin for d in mongo_data: - this_date = datetime(d['_id']['year'], d['_id']['month'], d['_id']['day']) + this_date = datetime( + d['_id']['year'], d['_id']['month'], d['_id']['day']) for day in h.daterange(next_expected_date, this_date): yield item(day, 0) yield item(this_date, d['posts']) @@ -306,9 +310,9 @@ class RootRestController(BaseController): def index(self, limit=100, page=0, **kw): limit, page, start = g.handle_paging(int(limit), int(page)) forums = model.Forum.query.find(dict( - app_config_id=c.app.config._id, - parent_id=None, deleted=False) - ).sort([('shortname', pymongo.ASCENDING)]).skip(start).limit(limit) + app_config_id=c.app.config._id, + parent_id=None, deleted=False) + ).sort([('shortname', pymongo.ASCENDING)]).skip(start).limit(limit) count = forums.count() json = dict(forums=[dict(_id=f._id, name=f.name, @@ -326,10 +330,12 @@ class RootRestController(BaseController): @expose('json:') def validate_import(self, doc=None, username_mapping=None, **kw): require_access(c.project, 'admin') - if username_mapping is None: username_mapping = {} + if username_mapping is None: + username_mapping = {} try: doc = json.loads(doc) - warnings, doc = import_support.validate_import(doc, username_mapping) + warnings, doc = import_support.validate_import( + doc, username_mapping) return dict(warnings=warnings, errors=[]) except Exception, e: raise @@ -338,12 +344,14 @@ class RootRestController(BaseController): @expose('json:') def perform_import( - self, doc=None, username_mapping=None, default_username=None, create_users=False, - **kw): + self, doc=None, username_mapping=None, default_username=None, create_users=False, + **kw): require_access(c.project, 'admin') - if username_mapping is None: username_mapping = '{}' + if username_mapping is None: + username_mapping = '{}' if c.api_token.get_capability('import') != [c.project.neighborhood.name, c.project.shortname]: - log.error('Import capability is not enabled for %s', c.project.shortname) + log.error('Import capability is not enabled for %s', + c.project.shortname) raise exc.HTTPForbidden(detail='Import is not allowed') try: doc = json.loads(doc) @@ -372,7 +380,8 @@ class ForumRestController(BaseController): @expose('json:') def index(self, limit=100, page=0, **kw): limit, page, start = g.handle_paging(int(limit), int(page)) - topics = model.Forum.thread_class().query.find(dict(discussion_id=self.forum._id)) + topics = model.Forum.thread_class().query.find( + dict(discussion_id=self.forum._id)) topics = topics.sort([('flags', pymongo.DESCENDING), ('last_post_date', pymongo.DESCENDING)]) topics = topics.skip(start).limit(limit) @@ -404,6 +413,7 @@ class ForumRestController(BaseController): return ForumTopicRestController(self.forum, topic), remainder raise exc.HTTPNotFound() + class ForumTopicRestController(BaseController): def __init__(self, forum, topic): http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeDiscussion/forgediscussion/forum_main.py ---------------------------------------------------------------------- diff --git a/ForgeDiscussion/forgediscussion/forum_main.py b/ForgeDiscussion/forgediscussion/forum_main.py index 1e55a2b..b9f033c 100644 --- a/ForgeDiscussion/forgediscussion/forum_main.py +++ b/ForgeDiscussion/forgediscussion/forum_main.py @@ -48,13 +48,16 @@ from widgets.admin import OptionsAdmin, AddForum log = logging.getLogger(__name__) + class W: options_admin = OptionsAdmin() add_forum = AddForum() + class ForgeDiscussionApp(Application): __version__ = version.__version__ - permissions = ['configure', 'read', 'unmoderated_post', 'post', 'moderate', 'admin'] + permissions = ['configure', 'read', + 'unmoderated_post', 'post', 'moderate', 'admin'] permissions_desc = { 'configure': 'Create new forums.', 'read': 'View posts.', @@ -63,22 +66,22 @@ class ForgeDiscussionApp(Application): config_options = Application.config_options + [ ConfigOption('PostingPolicy', schema.OneOf('ApproveOnceModerated', 'ModerateAll'), 'ApproveOnceModerated') - ] - PostClass=DM.ForumPost - AttachmentClass=DM.ForumAttachment - searchable=True - exportable=True - tool_label='Discussion' - tool_description=""" + ] + PostClass = DM.ForumPost + AttachmentClass = DM.ForumAttachment + searchable = True + exportable = True + tool_label = 'Discussion' + tool_description = """ Collaborate with your community in your forum. """ - default_mount_label='Discussion' - default_mount_point='discussion' - ordinal=7 - icons={ - 24:'images/forums_24.png', - 32:'images/forums_32.png', - 48:'images/forums_48.png' + default_mount_label = 'Discussion' + default_mount_point = 'discussion' + ordinal = 7 + icons = { + 24: 'images/forums_24.png', + 32: 'images/forums_32.png', + 48: 'images/forums_48.png' } def __init__(self, project, config): @@ -98,7 +101,7 @@ class ForgeDiscussionApp(Application): log.info('Message from %s (%s)', topic, self.config.options.mount_point) log.info('Headers are: %s', message['headers']) - shortname=urllib.unquote_plus(topic.replace('.', '/')) + shortname = urllib.unquote_plus(topic.replace('.', '/')) forum = DM.Forum.query.get( shortname=shortname, app_config_id=self.config._id) if forum is None: @@ -110,9 +113,9 @@ class ForgeDiscussionApp(Application): '''Apps should provide their entries to be added to the main nav :return: a list of :class:`SitemapEntries ` ''' - return [ SitemapEntry( - self.config.options.mount_label, - '.')] + return [SitemapEntry( + self.config.options.mount_label, + '.')] @property @h.exceptionless([], log) @@ -120,7 +123,7 @@ class ForgeDiscussionApp(Application): menu_id = self.config.options.mount_label with h.push_config(c, app=self): return [ - SitemapEntry(menu_id, '.')[self.sidebar_menu()] ] + SitemapEntry(menu_id, '.')[self.sidebar_menu()]] @property def forums(self): @@ -132,12 +135,13 @@ class ForgeDiscussionApp(Application): def subforums_of(self, parent_id): return DM.Forum.query.find(dict( - app_config_id=self.config._id, - parent_id=parent_id, - )).all() + app_config_id=self.config._id, + parent_id=parent_id, + )).all() def admin_menu(self): - admin_url = c.project.url() + 'admin/' + self.config.options.mount_point + '/' + admin_url = c.project.url() + 'admin/' + \ + self.config.options.mount_point + '/' links = [] if has_access(self, 'configure')(): links.append(SitemapEntry('Forums', admin_url + 'forums')) @@ -150,35 +154,44 @@ class ForgeDiscussionApp(Application): moderate_link = None forum_links = [] forums = DM.Forum.query.find(dict( - app_config_id=c.app.config._id, - parent_id=None, deleted=False)) + app_config_id=c.app.config._id, + parent_id=None, deleted=False)) for f in forums: - if has_access(f,'read')(): + if has_access(f, 'read')(): if f.url() in request.url and h.has_access(f, 'moderate')(): - moderate_link = SitemapEntry('Moderate', "%smoderate/" % f.url(), ui_icon=g.icons['pencil'], - small = DM.ForumPost.query.find({'discussion_id':f._id, 'status':{'$ne': 'ok'}}).count()) - forum_links.append(SitemapEntry(f.name, f.url(), small=f.num_topics)) + moderate_link = SitemapEntry( + 'Moderate', "%smoderate/" % f.url(), ui_icon=g.icons['pencil'], + small=DM.ForumPost.query.find({'discussion_id': f._id, 'status': {'$ne': 'ok'}}).count()) + forum_links.append( + SitemapEntry(f.name, f.url(), small=f.num_topics)) url = c.app.url + 'create_topic/' - url = h.urlquote(url + c.forum.shortname if getattr(c, 'forum', None) and c.forum else url) - l.append(SitemapEntry('Create Topic', url, ui_icon=g.icons['plus'])) + url = h.urlquote( + url + c.forum.shortname if getattr(c, 'forum', None) and c.forum else url) + l.append( + SitemapEntry('Create Topic', url, ui_icon=g.icons['plus'])) if has_access(c.app, 'configure')(): - l.append(SitemapEntry('Add Forum', c.app.url + 'new_forum', ui_icon=g.icons['conversation'])) - l.append(SitemapEntry('Admin Forums', c.project.url()+'admin/'+self.config.options.mount_point+'/forums', ui_icon=g.icons['pencil'])) + l.append(SitemapEntry('Add Forum', c.app.url + + 'new_forum', ui_icon=g.icons['conversation'])) + l.append(SitemapEntry('Admin Forums', c.project.url() + 'admin/' + + self.config.options.mount_point + '/forums', ui_icon=g.icons['pencil'])) if moderate_link: l.append(moderate_link) - # if we are in a thread and not anonymous, provide placeholder links to use in js + # if we are in a thread and not anonymous, provide placeholder + # links to use in js if '/thread/' in request.url and c.user not in (None, M.User.anonymous()): l.append(SitemapEntry( - 'Mark as Spam', 'flag_as_spam', - ui_icon=g.icons['flag'], className='sidebar_thread_spam')) - l.append(SitemapEntry('Stats Graph', c.app.url + 'stats', ui_icon=g.icons['stats'])) + 'Mark as Spam', 'flag_as_spam', + ui_icon=g.icons['flag'], className='sidebar_thread_spam')) + l.append(SitemapEntry('Stats Graph', c.app.url + + 'stats', ui_icon=g.icons['stats'])) if forum_links: l.append(SitemapEntry('Forums')) l = l + forum_links l.append(SitemapEntry('Help')) - l.append(SitemapEntry('Formatting Help', c.app.url + 'markdown_syntax')) + l.append( + SitemapEntry('Formatting Help', c.app.url + 'markdown_syntax')) return l - except: # pragma no cover + except: # pragma no cover log.exception('sidebar_menu') return [] @@ -198,7 +211,7 @@ class ForgeDiscussionApp(Application): M.ACE.allow(role_developer, 'moderate'), M.ACE.allow(role_admin, 'configure'), M.ACE.allow(role_admin, 'admin'), - ] + ] utils.create_forum(self, new_forum=dict( shortname='general', @@ -226,6 +239,7 @@ class ForgeDiscussionApp(Application): json.dump(forum, f, cls=jsonify.GenericJSON, indent=2) f.write(']}') + class ForumAdminController(DefaultAdminController): def _check_security(self): @@ -252,13 +266,14 @@ class ForumAdminController(DefaultAdminController): @expose() @require_post() def update_forums(self, forum=None, **kw): - if forum is None: forum = [] + if forum is None: + forum = [] for f in forum: forum = DM.Forum.query.get(_id=ObjectId(str(f['id']))) if f.get('delete'): - forum.deleted=True + forum.deleted = True elif f.get('undelete'): - forum.deleted=False + forum.deleted = False else: if '.' in f['shortname'] or '/' in f['shortname'] or ' ' in f['shortname']: flash('Shortname cannot contain space . or /', 'error') @@ -269,7 +284,8 @@ class ForumAdminController(DefaultAdminController): forum.monitoring_email = f['monitoring_email'] if 'members_only' in f: if 'anon_posts' in f: - flash('You cannot have anonymous posts in a members only forum.', 'warning') + flash( + 'You cannot have anonymous posts in a members only forum.', 'warning') forum.anon_posts = False del f['anon_posts'] forum.members_only = True http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c93733ac/ForgeDiscussion/forgediscussion/import_support.py ---------------------------------------------------------------------- diff --git a/ForgeDiscussion/forgediscussion/import_support.py b/ForgeDiscussion/forgediscussion/import_support.py index 60aff57..5318ec5 100644 --- a/ForgeDiscussion/forgediscussion/import_support.py +++ b/ForgeDiscussion/forgediscussion/import_support.py @@ -30,14 +30,17 @@ from forgediscussion import model as DM log = logging.getLogger(__name__) + def validate_import(json, username_mapping, default_username=None): warnings = [] schema = make_schema(username_mapping, default_username, warnings) json = schema.validate(json) return warnings, json + def perform_import(json, username_mapping, default_username=None, create_users=False): - if create_users: default_username=create_user + if create_users: + default_username = create_user # Validate the import, create missing users warnings, json = validate_import(json, username_mapping, default_username) @@ -69,42 +72,44 @@ def perform_import(json, username_mapping, default_username=None, create_users=F subject=head['subject']) for p in posts: p = create_post(f._id, t._id, p) - t.first_post_id=p._id + t.first_post_id = p._id ThreadLocalORMSession.flush_all() t.update_stats() ThreadLocalORMSession.flush_all() f.update_stats() return warnings + def make_schema(user_name_map, default_username, warnings): USER = AlluraUser(user_name_map, default_username, warnings) TIMESTAMP = TimeStamp() POST = { - 'msg_id':str, - 'is_followup_to':str, - 'is_deleted':str, - 'thread_id':str, - 'poster_name':str, - 'poster_user':USER, - 'subject':str, - 'date':TIMESTAMP, - 'body':str, - } + 'msg_id': str, + 'is_followup_to': str, + 'is_deleted': str, + 'thread_id': str, + 'poster_name': str, + 'poster_user': USER, + 'subject': str, + 'date': TIMESTAMP, + 'body': str, + } FORUM = { 'name': str, 'description': str, - 'threads': { str: [ POST ] }, - } + 'threads': {str: [POST]}, + } result = S.SchemaItem.make({ - 'class':str, - 'trackers':[None], - 'forums': { str: FORUM } - }) + 'class': str, + 'trackers': [None], + 'forums': {str: FORUM} + }) return result + class AlluraUser(S.FancySchemaItem): def __init__(self, mapping, default_username, warnings, **kw): @@ -131,6 +136,7 @@ class AlluraUser(S.FancySchemaItem): def _from_python(self, value, state): return value.username + class TimeStamp(S.FancySchemaItem): def _validate(self, value, **kwargs): @@ -141,6 +147,7 @@ class TimeStamp(S.FancySchemaItem): value = datetime.utcfromtimestamp(value) return value + def create_user(json_username): allura_username = c.project.shortname + '-' + json_username while True: @@ -156,6 +163,7 @@ def create_user(json_username): raise return allura_username + def create_post(discussion_id, thread_id, json_post): p = DM.ForumPost( _id='%s@import' % (json_post.msg_id),