Changes in lib/sct [41:94cb242769c6:219:854608cc314c]
- Files:
-
- lib/sct/AUTHORS (modified) (2 diffs)
- lib/sct/dist/scripts/compile-all-sph-messages.py (modified) (2 diffs)
- lib/sct/sphenecoll/sphene/community/context_processors.py (modified) (1 diff)
- lib/sct/sphenecoll/sphene/community/locale/it/LC_MESSAGES/django.mo (added)
- lib/sct/sphenecoll/sphene/community/locale/it/LC_MESSAGES/django.po (added)
- lib/sct/sphenecoll/sphene/community/locale/ru/LC_MESSAGES/django.mo (added)
- lib/sct/sphenecoll/sphene/community/locale/ru/LC_MESSAGES/django.po (added)
- lib/sct/sphenecoll/sphene/community/middleware.py (modified) (6 diffs)
- lib/sct/sphenecoll/sphene/community/models.py (modified) (4 diffs)
- lib/sct/sphenecoll/sphene/community/sphpermalink.py (modified) (2 diffs)
- lib/sct/sphenecoll/sphene/community/sphsettings.py (modified) (1 diff)
- lib/sct/sphenecoll/sphene/community/sphutils.py (modified) (2 diffs)
- lib/sct/sphenecoll/sphene/community/templates/sphene/community/_display_username.html (modified) (1 diff)
- lib/sct/sphenecoll/sphene/community/templatetags/sph_extras.py (modified) (4 diffs)
- lib/sct/sphenecoll/sphene/contrib/libs/common/text/bbcode.py (modified) (1 diff)
- lib/sct/sphenecoll/sphene/contrib/libs/markdown/markdown.py (modified) (1 diff)
- lib/sct/sphenecoll/sphene/sphblockframework/models.py (modified) (2 diffs)
- lib/sct/sphenecoll/sphene/sphblog/categorytypes.py (modified) (3 diffs)
- lib/sct/sphenecoll/sphene/sphblog/feeds.py (modified) (2 diffs)
- lib/sct/sphenecoll/sphene/sphblog/locale/it/LC_MESSAGES/django.mo (added)
- lib/sct/sphenecoll/sphene/sphblog/locale/it/LC_MESSAGES/django.po (added)
- lib/sct/sphenecoll/sphene/sphblog/locale/ru/LC_MESSAGES/django.mo (added)
- lib/sct/sphenecoll/sphene/sphblog/locale/ru/LC_MESSAGES/django.po (added)
- lib/sct/sphenecoll/sphene/sphblog/models.py (modified) (2 diffs)
- lib/sct/sphenecoll/sphene/sphblog/templates/sphene/sphblog/blogindex.html (modified) (2 diffs)
- lib/sct/sphenecoll/sphene/sphblog/templates/sphene/sphblog/feeds/latestposts_description.html (modified) (1 diff)
- lib/sct/sphenecoll/sphene/sphblog/templates/sphene/sphblog/feeds/latestposts_title.html (modified) (1 diff)
- lib/sct/sphenecoll/sphene/sphblog/templates/sphene/sphblog/nopost.html (modified) (1 diff)
- lib/sct/sphenecoll/sphene/sphblog/views.py (modified) (6 diffs)
- lib/sct/sphenecoll/sphene/sphboard/categorytypes.py (modified) (2 diffs)
- lib/sct/sphenecoll/sphene/sphboard/forms.py (modified) (4 diffs)
- lib/sct/sphenecoll/sphene/sphboard/locale/en/LC_MESSAGES/django.po (modified) (3 diffs)
- lib/sct/sphenecoll/sphene/sphboard/locale/it/LC_MESSAGES/django.mo (added)
- lib/sct/sphenecoll/sphene/sphboard/locale/it/LC_MESSAGES/django.po (added)
- lib/sct/sphenecoll/sphene/sphboard/locale/ru/LC_MESSAGES/django.mo (added)
- lib/sct/sphenecoll/sphene/sphboard/locale/ru/LC_MESSAGES/django.po (added)
- lib/sct/sphenecoll/sphene/sphboard/models.py (modified) (15 diffs)
- lib/sct/sphenecoll/sphene/sphboard/templates/sphene/sphboard/_displayPostForm.html (modified) (1 diff)
- lib/sct/sphenecoll/sphene/sphboard/templates/sphene/sphboard/_displayPostIcon.html (added)
- lib/sct/sphenecoll/sphene/sphboard/templates/sphene/sphboard/_post_header.html (added)
- lib/sct/sphenecoll/sphene/sphboard/templates/sphene/sphboard/base.html (modified) (1 diff)
- lib/sct/sphenecoll/sphene/sphboard/templates/sphene/sphboard/listCategories.html (modified) (3 diffs)
- lib/sct/sphenecoll/sphene/sphboard/templates/sphene/sphboard/showPrivateMessages.html (added)
- lib/sct/sphenecoll/sphene/sphboard/templates/sphene/sphboard/showThread.html (modified) (3 diffs)
- lib/sct/sphenecoll/sphene/sphboard/templatetags/sphboard_extras.py (modified) (3 diffs)
- lib/sct/sphenecoll/sphene/sphboard/views.py (modified) (16 diffs)
- lib/sct/sphenecoll/sphene/sphboard/widgets.py (added)
- lib/sct/sphenecoll/sphene/sphlinklist/locale/it/LC_MESSAGES/django.mo (added)
- lib/sct/sphenecoll/sphene/sphlinklist/locale/it/LC_MESSAGES/django.po (added)
- lib/sct/sphenecoll/sphene/sphlinklist/locale/ru/LC_MESSAGES/django.po (added)
- lib/sct/sphenecoll/sphene/sphwiki/__init__.py (modified) (1 diff)
- lib/sct/sphenecoll/sphene/sphwiki/docutils_extras.py (added)
- lib/sct/sphenecoll/sphene/sphwiki/locale/it/LC_MESSAGES/django.mo (added)
- lib/sct/sphenecoll/sphene/sphwiki/locale/it/LC_MESSAGES/django.po (added)
- lib/sct/sphenecoll/sphene/sphwiki/locale/ru/LC_MESSAGES/django.po (added)
- lib/sct/sphenecoll/sphene/sphwiki/models.py (modified) (9 diffs)
- lib/sct/sphenecoll/sphene/sphwiki/urls.py (modified) (1 diff)
- lib/sct/static/sphene/emoticons/README.txt (modified) (1 diff)
- lib/sct/static/sphene/emoticons/angel.gif (deleted)
- lib/sct/static/sphene/emoticons/angel.png (added)
- lib/sct/static/sphene/emoticons/angry.png (added)
- lib/sct/static/sphene/emoticons/bad.png (added)
- lib/sct/static/sphene/emoticons/beer.png (added)
- lib/sct/static/sphene/emoticons/bluemad.gif (deleted)
- lib/sct/static/sphene/emoticons/coffee.png (added)
- lib/sct/static/sphene/emoticons/confused.gif (deleted)
- lib/sct/static/sphene/emoticons/confused.png (added)
- lib/sct/static/sphene/emoticons/cool.gif (deleted)
- lib/sct/static/sphene/emoticons/crying.gif (deleted)
- lib/sct/static/sphene/emoticons/crying.png (added)
- lib/sct/static/sphene/emoticons/devil.png (added)
- lib/sct/static/sphene/emoticons/dont-know.png (added)
- lib/sct/static/sphene/emoticons/eek.gif (deleted)
- lib/sct/static/sphene/emoticons/embarrassed.png (added)
- lib/sct/static/sphene/emoticons/exclamation.png (added)
- lib/sct/static/sphene/emoticons/eyeroll.png (added)
- lib/sct/static/sphene/emoticons/fingers-crossed.png (added)
- lib/sct/static/sphene/emoticons/foot-in-mouth.png (added)
- lib/sct/static/sphene/emoticons/glasses-cool.png (added)
- lib/sct/static/sphene/emoticons/glasses-nerdy.png (added)
- lib/sct/static/sphene/emoticons/good.png (added)
- lib/sct/static/sphene/emoticons/grin.gif (deleted)
- lib/sct/static/sphene/emoticons/highfive.png (added)
- lib/sct/static/sphene/emoticons/hug-left.png (added)
- lib/sct/static/sphene/emoticons/hug-right.png (added)
- lib/sct/static/sphene/emoticons/kiss.png (added)
- lib/sct/static/sphene/emoticons/lamp.png (added)
- lib/sct/static/sphene/emoticons/laugh.png (added)
- lib/sct/static/sphene/emoticons/mad.gif (deleted)
- lib/sct/static/sphene/emoticons/neutral.png (added)
- lib/sct/static/sphene/emoticons/party.png (added)
- lib/sct/static/sphene/emoticons/pitoncino.png (added)
- lib/sct/static/sphene/emoticons/qmark.png (added)
- lib/sct/static/sphene/emoticons/question.png (added)
- lib/sct/static/sphene/emoticons/quiet.png (added)
- lib/sct/static/sphene/emoticons/sad.gif (deleted)
- lib/sct/static/sphene/emoticons/sad.png (added)
- lib/sct/static/sphene/emoticons/sarcastic.png (added)
- lib/sct/static/sphene/emoticons/secret.png (added)
- lib/sct/static/sphene/emoticons/shock.png (added)
- lib/sct/static/sphene/emoticons/sick.png (added)
- lib/sct/static/sphene/emoticons/sleepy.png (added)
- lib/sct/static/sphene/emoticons/smile.gif (deleted)
- lib/sct/static/sphene/emoticons/smile.png (added)
- lib/sct/static/sphene/emoticons/standard.png (added)
- lib/sct/static/sphene/emoticons/teeth.png (added)
- lib/sct/static/sphene/emoticons/thinking.png (added)
- lib/sct/static/sphene/emoticons/tongue.gif (deleted)
- lib/sct/static/sphene/emoticons/tongue.png (added)
- lib/sct/static/sphene/emoticons/unsure.gif (deleted)
- lib/sct/static/sphene/emoticons/vampire.png (added)
- lib/sct/static/sphene/emoticons/wink.gif (deleted)
- lib/sct/static/sphene/emoticons/wink.png (added)
- lib/sct/static/sphene/sphboard/js/editor.js (modified) (3 diffs)
- lib/sct/static/sphene/sphboard/js/inline.js (modified) (2 diffs)
- lib/sct/static/sphene/sphboard/styles/base.css (modified) (2 diffs)
- lib/sct/static/sphene/sphboard/styles/editor.css (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
lib/sct/AUTHORS
r41 r147 25 25 26 26 27 Daniele Varrazzo - for providing various patches especially for the 28 blog. 29 30 27 31 Eric Simorre <eric.simorre@c-s.fr> - contributed french 28 32 translations for all apps and communitydraft. … … 43 47 44 48 49 Walter Woods <woodswalben@gmail.com> - contributing patch for the forum and testing many posting/permission related problems. 50 51 45 52 Young Gyu Park <ygpark2@gmail.com> - for contributing korean 46 53 translations for all applications. lib/sct/dist/scripts/compile-all-sph-messages.py
r40 r81 5 5 ## SCT apps. 6 6 7 #from django.bin.compile-messages import compile_messages 8 c = __import__('django.bin.compile-messages', None, None, 'compile_messages') 7 from django.core.management.commands.compilemessages import compile_messages 9 8 10 9 import os … … 24 23 for app in sphapps: 25 24 os.chdir( os.path.join(ROOT_PATH, 'sphenecoll', 'sphene', app ) ) 26 c .compile_messages()25 compile_messages() 27 26 28 27 os.chdir( olddir ) lib/sct/sphenecoll/sphene/community/context_processors.py
r40 r147 31 31 return { 'navigation_left': Navigation.objects.filter( group = group, 32 32 navigationType = 0 ), 33 'navigation_top': Navigation.objects.filter( group = group, 34 navigationType = 1 ), 33 35 'urlPrefix': urlPrefix, 34 36 'group': group, lib/sct/sphenecoll/sphene/community/middleware.py
r41 r169 1 1 from django.conf import settings 2 2 from django.conf.urls.defaults import * 3 from django.core import urlresolvers 4 3 5 from django.http import Http404 4 6 from django.shortcuts import get_object_or_404 5 from sphene.community.models import Group 6 from django.core import urlresolvers 7 8 from django.contrib.sites.models import SiteManager, Site 9 10 11 from sphene.community.models import Group, get_group 12 from sphene.community.sphsettings import get_sph_setting 13 14 7 15 import re 8 9 from django.contrib.sites.models import SiteManager, Site 16 import logging 17 18 19 logger = logging.getLogger('sphene.community.middleware') 10 20 11 21 def my_get_current(self): … … 22 32 23 33 # If all are used the following order has to remain: 24 # 1.) ThreadLocals 25 # 2.) MultiHostMiddleware 26 # 3.) GroupMiddleware 34 # 1.) ThreadLocals (required) 35 # 2.) MultiHostMiddleware (optional, but very much recommended!) 36 # 3.) GroupMiddleware (required) 27 37 # all other orders will lead to problems .. 38 39 40 # 41 # Short descriptions: 42 # every module within SCT requires a Group object - this can either come from the 43 # MultiHostMiddleware - ie. from the domain/host name (vhosts) or from an URL parameter. 44 # we need to somehow distuingish between those two within the reverse URL lookups. 45 # 28 46 29 47 class MultiHostMiddleware: 30 48 def process_request(self, request): 31 49 try: 50 sphdata = get_current_sphdata() 32 51 host = request.META['HTTP_HOST'] 33 52 if host[-3:] == ':80': … … 52 71 break 53 72 if not urlconf: 54 print "Unable to find urlconf for %s / map: %s !!!" % (host, str(settings.SPH_HOST_MIDDLEWARE_URLCONF_MAP))73 logging.info("Unable to find urlconf for %s / map: %s !!!" % (host, str(settings.SPH_HOST_MIDDLEWARE_URLCONF_MAP))) 55 74 return 56 75 while 'alias' in urlconf: … … 63 82 if myparams and 'groupName' in myparams: 64 83 try: 65 set_current_group( Group.objects.get( name__exact = myparams['groupName'] ) ) 84 set_current_group( get_group( myparams['groupName'] ) ) 85 sphdata['group_fromhost'] = True 66 86 except Group.DoesNotExist: 67 87 pass … … 97 117 groupName = view_kwargs['groupName'] 98 118 if groupName == None: groupName = get_current_urlconf_params()['groupName'] 119 sphdata = get_current_sphdata() 99 120 if group == None: 100 121 group = get_object_or_404(Group, name = groupName ) 122 sphdata['group_fromhost'] = not get_sph_setting('community_groups_in_url') 101 123 del view_kwargs['groupName'] 102 124 view_kwargs['group'] = group … … 135 157 136 158 def get_current_group(): 137 return getattr(_thread_locals, 'group', None) 159 try: 160 return _thread_locals.group 161 except AttributeError, e: 162 logger.error('Unable to retrieve group. Is GroupMiddleware enabled?') 163 raise e 138 164 139 165 def get_current_urlconf_params(): lib/sct/sphenecoll/sphene/community/models.py
r41 r169 1 1 from django.db import models 2 from django.db.models import signals 3 from django.core.cache import cache 2 4 from django.contrib import admin 3 5 from django.contrib.auth.models import User 4 6 from django.contrib.contenttypes.models import ContentType 5 7 from django.contrib.contenttypes import generic 6 from sphene.community.sphpermalink import sphpermalink as permalink, get_urlconf8 from sphene.community.sphpermalink import sphpermalink 7 9 from django.utils.translation import ugettext as _, ugettext_lazy 8 10 from django.db import connection … … 49 51 return self.name; 50 52 51 52 53 def get_group(name): 54 """Return a `Group` by name. 55 56 Cache the group and return the cached version if available. 57 Raise `Group.DoesNotExist` if not found. 58 """ 59 group = cache.get(_get_group_cache_key(name)) 60 if group is not None: 61 return group 62 63 # raise if not found 64 group = Group.objects.get( name__exact = name ) 65 cache.add(_get_group_cache_key(name), group) 66 67 return group 68 69 def invalidate_group_cache(sender, instance, **kwargs): 70 """Signal handler to remove a `Group` from the cache.""" 71 if instance.name: 72 cache.delete(_get_group_cache_key(instance.name)) 73 74 signals.pre_save.connect( 75 invalidate_group_cache, 76 sender=Group) 77 78 def _get_group_cache_key(name): 79 return "__group__" + name 80 53 81 USERLEVEL_CHOICES = ( 54 82 (0, ugettext_lazy('Normal User')), … … 222 250 def get_absolute_editurl(self): 223 251 return ('sphene.community.views.admin_permission_role_edit', (), { 'groupName': self.group.name, 'role_id': self.id, } ) 224 get_absolute_editurl = permalink(get_absolute_editurl, get_urlconf)252 get_absolute_editurl = sphpermalink(get_absolute_editurl) 225 253 226 254 def get_absolute_memberlisturl(self): 227 255 return ('sphene.community.views.admin_permission_role_member_list', (), { 'groupName': self.group.name, 'role_id': self.id, } ) 228 get_absolute_memberlisturl = permalink(get_absolute_memberlisturl, get_urlconf)256 get_absolute_memberlisturl = sphpermalink(get_absolute_memberlisturl) 229 257 230 258 def get_absolute_memberaddurl(self): 231 259 return ('sphene.community.views.admin_permission_role_member_add', (), { 'groupName': self.group.name, 'role_id': self.id, } ) 232 get_absolute_memberaddurl = permalink(get_absolute_memberaddurl, get_urlconf)260 get_absolute_memberaddurl = sphpermalink(get_absolute_memberaddurl) 233 261 234 262 def get_absolute_groupmemberaddurl(self): 235 263 return ('sphene.community.views.admin_permission_role_groupmember_add', (), { 'groupName': self.group.name, 'role_id': self.id, } ) 236 get_absolute_groupmemberaddurl = permalink(get_absolute_groupmemberaddurl, get_urlconf)264 get_absolute_groupmemberaddurl = sphpermalink(get_absolute_groupmemberaddurl) 237 265 238 266 class Meta: … … 302 330 def get_absolute_editurl(self): 303 331 return ('sphene.community.views.admin_permission_rolegroup_edit', (), { 'groupName': self.group.name, 'rolegroup_id': self.id, } ) 304 get_absolute_editurl = permalink(get_absolute_editurl, get_urlconf)332 get_absolute_editurl = sphpermalink(get_absolute_editurl) 305 333 306 334 class Meta: lib/sct/sphenecoll/sphene/community/sphpermalink.py
r40 r147 1 from django.core.urlresolvers import reverse2 1 3 2 … … 5 4 # Decorator. Takes a function that returns a tuple in this format: 6 5 # (viewname, viewargs, viewkwargs) 7 # Optionally takes a function which should either return an object with8 # an attribute 'urlconf' or directly a python list which is used instead of9 # settings.ROOT_URLCONF10 6 # Returns a function that calls urlresolvers.reverse() on that data, to return 11 7 # the URL for those parameters. 12 def sphpermalink(func, get_urlconf_func = None): 13 from django.core.urlresolvers import reverse 8 def sphpermalink(func): 14 9 def inner(*args, **kwargs): 10 from sphene.community.sphutils import sph_reverse 15 11 # Find urlconf ... 16 urlconf = None17 if get_urlconf_func != None:18 urlconf = get_urlconf_func()19 if hasattr(urlconf, 'urlconf'):20 # If type is no list, we assume it is a request object and21 # look for a 'urlconf' attribute22 urlconf = getattr(urlconf, 'urlconf', None)23 24 12 bits = func(*args, **kwargs) 25 viewname = bits[0] 26 # OMG that is an ugly hack !! 27 if 'groupName' in bits[2]: 28 del bits[2]['groupName'] 13 viewname, args, kwargs = bits 29 14 30 if not hasattr( urlconf, '__iter__' ) \ 31 and not isinstance( urlconf, str ): 32 # If urlconf is not a list / tuple set it to None. 33 urlconf = None 34 35 return reverse(bits[0], urlconf, *bits[1:3]) 15 return sph_reverse(viewname, args=args, kwargs=kwargs) 36 16 return inner 37 17 lib/sct/sphenecoll/sphene/community/sphsettings.py
r40 r147 23 23 # $(dir)/$(groupName)/$(templateName) 24 24 'community_groupaware_template_dir': None, 25 26 # If True, the group name is set in the URL 27 'community_groups_in_url': False, 25 28 26 29 # used by sphene.community.views.groupaware_redirect_to which looks up this variable lib/sct/sphenecoll/sphene/community/sphutils.py
r41 r147 5 5 from django.core.urlresolvers import reverse 6 6 from django.shortcuts import render_to_response 7 from sphene.community.middleware import get_current_request, get_current_sphdata 7 from sphene.community.middleware import get_current_request, get_current_sphdata, get_current_group 8 8 from sphene.community.sphpermalink import sphpermalink as imported_sphpermalink 9 9 from sphene.community import sphsettings … … 198 198 req = get_current_request() 199 199 urlconf = getattr(req, 'urlconf', None) 200 sphdata = get_current_sphdata() 201 if 'group_fromhost' in sphdata and \ 202 not sphdata.get('group_fromhost', False): 203 kwargs['groupName'] = get_current_group().name 204 elif 'groupName' in kwargs: 205 del kwargs['groupName'] 200 206 return reverse( viewname, urlconf, args, kwargs ) 201 207 lib/sct/sphenecoll/sphene/community/templates/sphene/community/_display_username.html
r40 r145 3 3 {% if user %} 4 4 <a href="{{ user|sph_user_profile_link }}"> 5 {{ user|sph_user_displayname }}6 </a> 5 {{ user|sph_user_displayname }} 6 </a>{{ suffix }} 7 7 {% else %} 8 8 {% trans "Anonymous" %} lib/sct/sphenecoll/sphene/community/templatetags/sph_extras.py
r41 r147 19 19 20 20 import logging 21 log = logging.getLogger('sph _extras')21 log = logging.getLogger('sphene.community.sph_extras') 22 22 23 23 register = template.Library() … … 240 240 def sph_user_profile_link(value): 241 241 """ Returns the URL to the user profile. """ 242 req = get_current_request() 243 urlconf = getattr(req, 'urlconf', None) 244 return reverse('sphene.community.views.profile', urlconf, (), { 'user_id': value.id } ) 242 kwargs = { 'user_id': value.id, } 243 return sph_reverse('sphene.community.views.profile', kwargs = kwargs ) 245 244 246 245 … … 273 272 for k, v in self.kwargs.items()]) 274 273 275 #if not 'groupName' in kwargs:276 # kwargs['groupName'] = get_current_group().name277 278 req = get_current_request()279 urlconf = getattr(req, 'urlconf', None)280 281 274 try: 282 return reverse(self.view_name, urlconf=urlconf,283 args=args, kwargs=kwargs)275 return sph_reverse(self.view_name, 276 args=args, kwargs=kwargs) 284 277 except NoReverseMatch: 285 278 try: 286 279 project_name = settings.SETTINGS_MODULE.split('.')[0] 287 return reverse(project_name + '.' + self.view_name, 288 urlconf=urlconf, 289 args=args, kwargs=kwargs) 280 return sph_reverse(project_name + '.' + self.view_name, 281 args=args, kwargs=kwargs) 290 282 except NoReverseMatch: 291 283 return '' … … 302 294 urlconf = getattr(req, 'urlconf', None) 303 295 try: 304 return reverse(view, urlconf)296 return sph_reverse(view) 305 297 except: 298 log.exception('Unable to reverse sph_url for view %r' % view) 306 299 return 'NOT FOUND' 307 300 lib/sct/sphenecoll/sphene/contrib/libs/common/text/bbcode.py
r40 r112 386 386 387 387 _EMOTICONS = { 388 '0:-)': 'angel.gif', 389 'O:-)':'angel.gif', 390 ':angel:':'angel.gif', 391 ':)':'smile.gif', 392 ':(':'sad.gif', 393 ':D':'grin.gif', 394 ':p':'tongue.gif', 395 ';)':'wink.gif', 396 ':-)':'smile.gif', 397 ':-(': 'sad.gif', 398 ':-D': 'grin.gif', 399 ':-P': 'tongue.gif', 400 ':-p': 'tongue.gif', 401 ':-/': 'unsure.gif', 402 ':-\\': 'unsure.gif', 403 ';-)': 'wink.gif', 404 ':-$': 'confused.gif', 405 ':-S': 'confused.gif', 406 'B-)': 'cool.gif', 407 ':lol:': 'lol.gif', 408 ':batman:': 'batman.gif', 409 ':rolleyes:': 'rolleyes.gif', 410 ':icymad:': 'bluemad.gif', 411 ':mad:': 'mad.gif', 412 ':crying:': 'crying.gif', 413 ':eek:': 'eek.gif', 414 ':eyebrow:': 'eyebrow.gif', 415 ':grim:': 'grim_reaper.gif', 416 ':idea:': 'idea.gif', 417 ':rotfl:': 'rotfl.gif', 418 ':shifty:': 'shifty.gif', 419 ':sleep:': 'sleep.gif', 420 ':thinking:': 'thinking.gif', 421 ':wave:': 'wave.gif', 422 ':bow:': 'bow.gif', 423 ':sheep:': 'sheep.gif', 424 ':santa:': 'santaclaus.gif', 425 ':anvil:': 'anvil.gif', 426 ':bandit:': 'bandit.gif', 427 ':chop:': 'behead.gif', 428 ':biggun:': 'biggun.gif', 429 ':mouthful:': 'blowingup,gif', 430 ':gun:': 'bluekillsred.gif', 431 ':box:': 'boxing.gif', 432 ':gallows:': 'hanged.gif', 433 ':jedi:': 'lightsaber1.gif', 434 ':bosh:': 'mallet1.gif', 435 ':saw:': 'saw.gif', 436 ':stupid:': 'youarestupid.gif', 388 # __replace_start__: emoticons_map 389 ':)': 'smile.png', 390 ';)': 'wink.png', 391 ':thinking:': 'thinking.png', 392 ':dont-know:': 'dont-know.png', 393 ':eyeroll:': 'eyeroll.png', 394 ':|': 'neutral.png', 395 ':embarrassed:': 'embarrassed.png', 396 ':confused:': 'confused.png', 397 ':sarcastic:': 'sarcastic.png', 398 ':(': 'sad.png', 399 ';(': 'crying.png', 400 ':angry:': 'angry.png', 401 ':O': 'shock.png', 402 ':ok:': 'good.png', 403 ':ko:': 'bad.png', 404 ':fingers-crossed:': 'fingers-crossed.png', 405 ':foot-in-mouth:': 'foot-in-mouth.png', 406 ':glasses-cool:': 'glasses-cool.png', 407 '8)': 'glasses-nerdy.png', 408 ':batti5:': 'highfive.png', 409 ':hug-left:': 'hug-left.png', 410 ':hug-right:': 'hug-right.png', 411 ':*': 'kiss.png', 412 ':D': 'laugh.png', 413 ':party:': 'party.png', 414 ':question:': 'question.png', 415 ':quiet:': 'quiet.png', 416 ':segreto:': 'secret.png', 417 ':sick:': 'sick.png', 418 ':sleepy:': 'sleepy.png', 419 ':teeth:': 'teeth.png', 420 ':P': 'tongue.png', 421 ':vampire:': 'vampire.png', 422 ':angel:': 'angel.png', 423 ':devil:': 'devil.png', 424 ':birrame:': 'beer.png', 425 u':caff\xe8:': 'coffee.png', 426 ':py:': 'pitoncino.png', 427 # __replace_end__: emoticons_map 437 428 } 438 429 lib/sct/sphenecoll/sphene/contrib/libs/markdown/markdown.py
r40 r107 1489 1489 for i in range(self.htmlStash.html_counter) : 1490 1490 html = self.htmlStash.rawHtmlBlocks[i] 1491 if self.safeMode :1491 if self.safeMode and html not in (u'<hr />', u'<br />'): 1492 1492 html = "[HTML_REMOVED]" 1493 1493 lib/sct/sphenecoll/sphene/sphblockframework/models.py
r40 r147 6 6 7 7 from sphene.community.middleware import get_current_group, get_current_request 8 from sphene.community.sphutils import sphpermalink as permalink8 from sphene.community.sphutils import sphpermalink 9 9 from sphene.community.models import Group 10 10 … … 128 128 def get_absolute_edit_url(self): 129 129 return ('sphene.sphblockframework.views.edit_block_config', (), { 'block_config_id': self.id }) 130 get_absolute_edit_url = permalink(get_absolute_edit_url, get_current_request)130 get_absolute_edit_url = sphpermalink(get_absolute_edit_url) 131 131 132 132 lib/sct/sphenecoll/sphene/sphblog/categorytypes.py
r41 r147 3 3 from django.utils.safestring import mark_safe 4 4 5 5 6 from sphene.community.middleware import get_current_user, get_current_sphdata, get_current_urlconf 7 from sphene.community.sphutils import sph_reverse 6 8 from sphene.community.models import Tag, TagLabel, TaggedItem, tag_set_labels, tag_get_labels 7 9 from sphene.community.fields import TagField … … 29 31 slug = slugify(self.cleaned_data['subject'], model=BlogPostExtension) 30 32 else: 31 slug = slugify(slug, model=BlogPostExtension )33 slug = slugify(slug, model=BlogPostExtension, pk=self.__ext_id) 32 34 return slug 33 35 … … 109 111 def get_absolute_url_for_category(self): 110 112 try: 111 blog_url = reverse('sphblog_category_index', urlconf=get_current_urlconf(), args = (), kwargs = { 'category_id': self.category.id })113 blog_url = sph_reverse('sphblog_category_index', kwargs = { 'category_id': self.category.id }) 112 114 return blog_url 113 115 except Exception, e: lib/sct/sphenecoll/sphene/sphblog/feeds.py
r41 r136 6 6 from sphene.community.middleware import get_current_group 7 7 from sphene.sphblog.models import BlogPostExtension 8 from sphene.sphblog.views import get_board_categories, get_ posts_queryset8 from sphene.sphblog.views import get_board_categories, get_blog_posts_queryset 9 9 from sphene.sphboard.models import Post 10 10 … … 39 39 group = get_current_group() 40 40 categories = obj 41 threads = get_ posts_queryset(group, categories )41 threads = get_blog_posts_queryset(group, categories ) 42 42 return threads 43 43 44 45 44 def item_pubdate(self, item): 46 return item.post date45 return item.post.postdate 47 46 48 47 def item_link(self, item): 49 try: 50 return item.blogpostextension_set.get().get_absolute_url() 51 except BlogPostExtension.DoesNotExist: 52 # This should never happen. 53 return item.get_absolute_url() 48 return item.get_absolute_url() 54 49 50 def item_categories(self, item): 51 return item.get_tag_labels() 52 lib/sct/sphenecoll/sphene/sphblog/models.py
r41 r147 5 5 6 6 from sphene.community.models import tag_get_labels 7 from sphene.community.sphutils import sphpermalink as permalink7 from sphene.community.sphutils import sphpermalink 8 8 from sphene.community.middleware import get_current_request 9 9 … … 39 39 'slug': self.slug, 40 40 }) 41 get_absolute_url = permalink(get_absolute_url, get_current_request)41 get_absolute_url = sphpermalink(get_absolute_url) 42 42 43 43 lib/sct/sphenecoll/sphene/sphblog/templates/sphene/sphblog/blogindex.html
r41 r147 50 50 {% endif %} 51 51 52 {% if not threads.object_list %} 53 <p>{% trans "There are no blog posts yet." %}</p> 54 {% endif %} 52 55 53 56 {% for thread in threads.object_list %} … … 100 103 101 104 <p> 102 <a href="{% sph_url2 sphblog-feeds "latestposts" %}">{% trans "RSS Feed" %}</a>105 <a href="{% sph_url2 sphblog-feeds url="latestposts" %}">{% trans "RSS Feed" %}</a> 103 106 </p> 104 107 lib/sct/sphenecoll/sphene/sphblog/templates/sphene/sphblog/feeds/latestposts_description.html
r40 r136 1 {{ obj. body_escaped }}1 {{ obj.post.body_escaped }} lib/sct/sphenecoll/sphene/sphblog/templates/sphene/sphblog/feeds/latestposts_title.html
r40 r137 1 {{ obj. subject}}1 {{ obj.post.subject|safe }} lib/sct/sphenecoll/sphene/sphblog/templates/sphene/sphblog/nopost.html
r41 r147 1 {% extends "sphene/sphblog/base.html" %}2 3 {% block content %}4 No posts matched the given criteria.5 {% endblock %}lib/sct/sphenecoll/sphene/sphblog/views.py
r41 r147 8 8 from django.template.context import RequestContext 9 9 from django.http import HttpResponse, HttpResponseRedirect, Http404 10 from django.core.urlresolvers import reverse11 10 from django.db.models import Q 12 11 from django.core.paginator import Paginator, InvalidPage, EmptyPage 12 13 13 14 14 from sphene.community.models import Tag, tag_get_models_by_tag … … 18 18 from sphene.sphboard.models import Category, ThreadInformation, Post, get_tags_for_categories 19 19 from sphene.sphblog.models import BlogPostExtension 20 from sphene.community.sphutils import get_sph_setting 20 from sphene.community.sphutils import get_sph_setting, sph_reverse 21 21 22 22 def get_board_categories(group): … … 32 32 return blogcategories 33 33 34 def get_blog_posts_queryset(group, categories, year=None, month=None): 35 """ 36 Return a list of blog posts. 37 If given, year and month should be integers. 38 """ 39 threads = BlogPostExtension.objects.filter( post__thread__isnull = True, 40 post__category__group__id = group.id, 41 post__category__id__in = map(lambda x: x.id, categories) ).order_by( '-post__postdate' ) 42 43 return _year_month_filter(threads, year, month) 44 34 45 def get_posts_queryset(group, categories, year=None, month=None): 35 46 """ … … 37 48 If given, year and month should be integers. 38 49 """ 39 if month is not None and (month > 12 or month < 1):40 return None41 42 50 threads = Post.objects.filter( thread__isnull = True, 43 51 category__group__id = group.id, 44 52 category__id__in = map(lambda x: x.id, categories) ).order_by( '-postdate' ) 53 54 return _year_month_filter(threads, year, month) 55 56 def _year_month_filter(threads, year=None, month=None): 57 """ 58 Filter a queryset containing a 'postdate' field by year/month. 59 """ 60 if month is not None and not 1 <= month <= 12: 61 return None 45 62 46 63 if year is not None: … … 100 117 101 118 threads = get_posts_queryset(group, category_info[0], year, month) 102 if not threads:103 return render_to_response('sphene/sphblog/nopost.html', {},104 context_instance = RequestContext(request))105 119 106 120 paged_threads = get_paged_objects(threads, page) … … 108 122 allowpostcategories = filter(Category.has_post_thread_permission, category_info[0]) 109 123 #blog_feed_url = reverse('sphblog-feeds', urlconf=get_current_urlconf(), args = ('latestposts',), kwargs = { 'groupName': group.name }) 110 blog_feed_url = reverse('sphblog-feeds', urlconf=get_current_urlconf(), kwargs = { 'url': 'latestposts' })124 blog_feed_url = sph_reverse('sphblog-feeds', kwargs = { 'url': 'latestposts' }) 111 125 add_rss_feed( blog_feed_url, 'Blog RSS Feed' ) 112 126 all_tags = get_tags_for_categories( category_info[0] ) lib/sct/sphenecoll/sphene/sphboard/categorytypes.py
r41 r146 2 2 from django.utils.safestring import mark_safe 3 3 4 from sphene.sphboard.models import ExtendedCategoryConfig 5 from sphene.sphboard. views importPostForm4 from sphene.sphboard.models import ExtendedCategoryConfig, PostRecipient 5 from sphene.sphboard.forms import PostForm, PrivatePostForm 6 6 from sphene.sphboard.categorytyperegistry import CategoryType 7 7 … … 55 55 56 56 57 class PrivateMessagesCategoryType(CategoryType): 58 name = "privatemessages" 59 60 label = "Private Messages" 61 62 def is_displayed(self): 63 return True 64 65 def get_show_thread_template(self): 66 return 'sphene/sphboard/showPrivateMessages.html' 67 68 def get_post_form_class(self, replypost, editpost): 69 return PrivatePostForm 70 71 def save_post(self, newpost, data): 72 super(PrivateMessagesCategoryType, self).save_post(newpost, data) 73 74 for user in data['to']: 75 rec = PostRecipient(post=newpost, user=user, type='TO') 76 rec.save() 77 78 57 79 class ExtendedCategoryType(CategoryType): 58 80 name = "extendedconfig" lib/sct/sphenecoll/sphene/sphboard/forms.py
r41 r146 17 17 from sphene.sphboard.renderers import describe_render_choices 18 18 from sphene.sphboard.models import POST_MARKUP_CHOICES, PostAttachment 19 from sphene.sphboard.widgets import UsersField, IconSelect 19 20 from sphene.sphboard import boardforms 20 21 … … 56 57 class PostForm(forms.Form): 57 58 subject = forms.CharField( label = _(u"Subject" ) ) 59 to = UsersField( label = _(u"To" ) ) 60 icon = forms.CharField(label=_(u"Post Icon"), widget = IconSelect()) 58 61 body = forms.CharField( label = _(u"Body"), 59 62 widget = forms.Textarea( attrs = { 'rows': 10, 'cols': 70 } ), … … 68 71 def __init__(self, *args, **kwargs): 69 72 super(PostForm, self).__init__(*args, **kwargs) 73 if not self.has_recipients(): 74 del self.fields['to'] 70 75 if not sphutils.has_captcha_support() or get_current_user().is_authenticated(): 71 76 del self.fields['captcha'] 72 77 if len( POST_MARKUP_CHOICES ) == 1: 73 78 del self.fields['markup'] 79 80 def has_recipients(self): 81 return False 74 82 75 83 def init_for_category_type(self, category_type, post): … … 82 90 """ 83 91 pass 92 93 94 class PrivatePostForm(PostForm): 95 def has_recipients(self): 96 return True 84 97 85 98 lib/sct/sphenecoll/sphene/sphboard/locale/en/LC_MESSAGES/django.po
r40 r83 365 365 msgstr "" 366 366 367 #: templates/sphene/sphboard/listCategories.html:96 368 msgid "Mark all as read" 369 msgstr "" 370 367 371 #: templates/sphene/sphboard/move.html:10 368 372 #, python-format … … 375 379 msgstr "" 376 380 381 #: templates/sphene/sphboard/new_post_email.txt:3 382 #, python-format 383 msgid "" 384 "\n" 385 "%(full_name)s just posted in a thread or forum you are monitoring:\n" 386 "\n" 387 "visit http://%(baseurl)s%(abs_url)s to view the post.\n" 388 msgstr "" 389 377 390 #: templates/sphene/sphboard/post.html:14 378 391 msgid "Editing post" … … 434 447 #: templates/sphene/sphboard/showThread.html:106 435 448 msgid "Attachments" 449 msgstr "" 450 451 #: templates/sphene/sphboard/showThread.html:141 452 msgid "Edit this poll" 436 453 msgstr "" 437 454 lib/sct/sphenecoll/sphene/sphboard/models.py
r41 r147 16 16 import sphene.community.signals 17 17 from sphene.community.middleware import get_current_request, get_current_user, get_current_group, get_current_session 18 from sphene.community.sphutils import sphpermalink as permalink, get_urlconf, get_sph_setting, get_method_by_name18 from sphene.community.sphutils import sphpermalink, get_urlconf, get_sph_setting, get_method_by_name 19 19 from sphene.community.signals import profile_edit_init_form, profile_edit_save_form, profile_display 20 20 from sphene.community.permissionutils import has_permission_flag … … 254 254 return self.allowthreads != 3 255 255 256 def is_private(self): 257 return self.category_type == 'privatemessages' 258 259 @property 260 def posts(self): 261 posts = self._posts 262 if self.is_private(): 263 user = get_current_user() 264 recps = PostRecipient.objects.filter(user=user).values('post').query 265 posts = posts.filter(Q(id__in=recps) | Q(author=user)) 266 267 return posts 268 256 269 def get_thread_list(self): 257 270 #return self.posts.filter( thread__isnull = True ) … … 259 272 # See http://code.djangoproject.com/ticket/4789 260 273 return self.threadinformation_set 261 return self.threadinformation_set.filter(root_post__is_hidden = 0).select_related( depth = 1 ) 274 qs = self.threadinformation_set.filter(root_post__is_hidden = 0).select_related( depth = 1 ) 275 276 if self.is_private(): 277 user = get_current_user() 278 recps = PostRecipient.objects.filter(user=user).values('post').query 279 qs = qs.filter(Q(latest_post__id__in=recps) | Q(root_post__author=user)) 280 print qs.query 281 282 return qs 262 283 263 284 def threadCount(self): … … 450 471 name = 'sphboard_show_category_without_slug' 451 472 return (name, (), kwargs) 452 _get_absolute_url = permalink(_get_absolute_url, get_current_request)473 _get_absolute_url = sphpermalink(_get_absolute_url) 453 474 454 475 def get_absolute_post_thread_url(self): 455 476 return ('sphboard_post_thread', (), { 'groupName': self.group.name, 'category_id': self.id }) 456 get_absolute_post_thread_url = permalink(get_absolute_post_thread_url, get_current_request)477 get_absolute_post_thread_url = sphpermalink(get_absolute_post_thread_url) 457 478 458 479 def get_absolute_url_rss_latest_threads(self): … … 465 486 def get_absolute_latest_url(self): 466 487 return ('sphboard_latest', (), { 'groupName': self.group.name, 'category_id': self.id, }) 467 get_absolute_latest_url = permalink(get_absolute_latest_url, get_current_request)488 get_absolute_latest_url = sphpermalink(get_absolute_latest_url) 468 489 469 490 def get_absolute_togglemonitor_url(self): 470 491 return ('sphene.sphboard.views.toggle_monitor', (), { 'groupName': self.group.name, 'monitortype': 'category', 'object_id': self.id, }) 471 get_absolute_togglemonitor_url = permalink(get_absolute_togglemonitor_url, get_current_request)492 get_absolute_togglemonitor_url = sphpermalink(get_absolute_togglemonitor_url) 472 493 473 494 def __unicode__(self): … … 544 565 """ 545 566 status = models.IntegerField(default = 0, editable = False ) 546 category = models.ForeignKey(Category, related_name = ' posts', editable = False )567 category = models.ForeignKey(Category, related_name = '_posts', editable = False ) 547 568 subject = models.CharField(max_length = 250) 569 icon = models.CharField(max_length=24, default='standard') 548 570 body = models.TextField() 549 571 thread = models.ForeignKey('self', null = True, editable = False ) 550 572 postdate = models.DateTimeField( auto_now_add = True, editable = False ) 551 573 author = models.ForeignKey(User, editable = False, null = True, blank = True, related_name = 'sphboard_post_author_set' ) 574 author_ip = models.CharField(max_length = 39, null = True, blank = True) 552 575 markup = models.CharField(max_length = 250, 553 576 null = True, … … 570 593 ( '2008-01-06 01', 'update', 'SET is_hidden = 0', ), 571 594 ( '2008-01-06 02', 'alter', 'ALTER is_hidden SET NOT NULL', ), 595 ( '2009-07-30 00', 'alter', 'ADD author_ip varchar(39) NULL', ), 572 596 ) 573 597 … … 686 710 687 711 def _allow_adminfunctionality(self, flag, user = None): 712 if self.is_private(): 713 return False 714 688 715 if user == None: 689 716 user = get_current_user() … … 711 738 return self._allow_adminfunctionality( 'sphboard_sticky', user ) 712 739 740 def has_view_permission(self, user = None): 741 if not user: 742 user = get_current_user() 743 744 if self.is_private(): 745 if self.author_id == user.id: 746 return True 747 748 for rec in self.recipient_set.all(): 749 if rec.user_id == user.id: 750 return True 751 752 return False 753 754 else: 755 return self.category.has_view_permission(user) 756 757 def is_private(self): 758 return self.category.is_private() 759 713 760 def __get_render_cachekey(self): 714 761 return 'sphboard_rendered_body_%s' % str(self.id) … … 882 929 #monitors = Monitor.objects.filter(myQ) 883 930 884 subject = ' New Forum Post in "%s": %s' % (self.category.name, self.subject,)931 subject = '%sNew Forum Post in "%s": %s' % (settings.EMAIL_SUBJECT_PREFIX, self.category.name, self.subject,) 885 932 group = get_current_group() or self.category.group 886 933 t = loader.get_template('sphene/sphboard/new_post_email.txt') … … 955 1002 name = 'sphboard_show_thread_without_slug' 956 1003 return (name, (), kwargs) 957 _get_absolute_url = permalink(_get_absolute_url, get_current_request)1004 _get_absolute_url = sphpermalink(_get_absolute_url) 958 1005 959 1006 def get_absolute_editurl(self): 960 1007 return ('sphene.sphboard.views.post', (), { 'groupName': self.category.group.name, 'category_id': self.category.id, 'post_id': self.id }) 961 get_absolute_editurl = permalink(get_absolute_editurl, get_current_request)1008 get_absolute_editurl = sphpermalink(get_absolute_editurl) 962 1009 963 1010 def get_absolute_postreplyurl(self): 964 1011 return ('sphene.sphboard.views.reply', (), { 'groupName': self.category.group.name, 'category_id': self.category.id, 'thread_id': self.get_thread().id }) 965 get_absolute_postreplyurl = permalink(get_absolute_postreplyurl, get_current_request)1012 get_absolute_postreplyurl = sphpermalink(get_absolute_postreplyurl) 966 1013 967 1014 def get_absolute_annotate_url(self): 968 1015 return ('sphene.sphboard.views.annotate', (), { 'groupName': self.category.group.name, 'post_id': self.id }) 969 get_absolute_annotate_url = permalink(get_absolute_annotate_url, get_current_request)1016 get_absolute_annotate_url = sphpermalink(get_absolute_annotate_url) 970 1017 971 1018 … … 1131 1178 return self.root_post.subject 1132 1179 1180 @property # to make thread and post interfaces uniform 1181 def icon(self): 1182 return self.root_post.icon 1183 1133 1184 def is_poll(self): 1134 1185 return self.root_post.is_poll() … … 1169 1220 kwargs['slug'] = slug 1170 1221 return (name, (), kwargs) 1171 _get_absolute_url = permalink(_get_absolute_url, get_current_request)1222 _get_absolute_url = sphpermalink(_get_absolute_url) 1172 1223 1173 1224 def __unicode__(self): … … 1292 1343 def get_absolute_editurl(self): 1293 1344 return ('sphboard_edit_poll', (), { 'poll_id': self.id, }) 1294 get_absolute_editurl = permalink(get_absolute_editurl, get_current_request)1345 get_absolute_editurl = sphpermalink(get_absolute_editurl) 1295 1346 1296 1347 … … 1482 1533 profile_edit_save_form.connect(board_profile_edit_save_form, sender = EditProfileForm) 1483 1534 profile_display.connect(board_profile_display) 1535 1536 1537 class PostRecipient(models.Model): 1538 """ 1539 The recipient of a private post. 1540 """ 1541 RECIPIENT_TYPE_CHOICES = ( 1542 (u'TO', _("To")), 1543 (u'CC', _("Cc")), 1544 (u'BCC', _("Bcc")), ) 1545 user = models.ForeignKey( User ) 1546 post = models.ForeignKey( Post, related_name = 'recipient_set' ) 1547 type = models.CharField( max_length = 4, choices = RECIPIENT_TYPE_CHOICES ) 1548 1549 __labels = dict(RECIPIENT_TYPE_CHOICES) 1550 1551 def label(self): 1552 return self.__labels.get(self.type, self.type) lib/sct/sphenecoll/sphene/sphboard/templates/sphene/sphboard/_displayPostForm.html
r41 r113 35 35 {% if bbcodewysiwyg %} 36 36 <script type="text/javascript"> 37 var emoticons_url = "{{ MEDIA_URL }}sphene/emoticons"; 37 38 var editor_static = "{{ MEDIA_URL }}sphene/sphboard"; 38 39 </script> lib/sct/sphenecoll/sphene/sphboard/templates/sphene/sphboard/base.html
r40 r183 5 5 <link rel="stylesheet" href="{{ MEDIA_URL }}sphene/sphboard/styles/base.css" /> 6 6 {% endblock %} 7 8 {# The sidebar content doesn't change in the whole forum #} 9 {# so don't fetching and rendering the sidebar for every thread #} 10 {% load cache %} 11 {% block left_hand_navigation %} 12 {% cache 300 lhnav_sphboard_base %} 13 {{ block.super }} 14 {% endcache %} 15 {% endblock %} 16 lib/sct/sphenecoll/sphene/sphboard/templates/sphene/sphboard/listCategories.html
r41 r117 52 52 {% block thread_list_header %} 53 53 <tr> 54 <th class="sphboard_mainhead" colspan="{% if sph_settings.board_count_views %} 5{% else %}4{% endif %}">{% trans "Threads" %}</th>54 <th class="sphboard_mainhead" colspan="{% if sph_settings.board_count_views %}6{% else %}5{% endif %}">{% trans "Threads" %}</th> 55 55 </tr> 56 56 <tr> 57 <th colspan=" 2">{% trans "Subject / Author" %}</th>57 <th colspan="3">{% trans "Subject / Author" %}</th> 58 58 {% if sph_settings.board_count_views %} 59 59 <th>{% trans "Views" %}</th> … … 66 66 <tr> 67 67 <td width="20px"><img src="{{ MEDIA_URL }}sphene/sphboard/icons/{% if thread.has_new_posts %}new{% endif %}folder.gif" width='16px' height='16px' title='Heat: {{ thread.heat }}' /></td> 68 <td width="20px">{% sphboard_displayPostIcon thread %}</td> 68 69 {% if thread.is_moved %} 69 70 <td colspan="4"><small> … … 83 84 {% endfor %} 84 85 <tr> 85 <td colspan="{% if sph_settings.board_count_views %} 5{% else %}4{% endif %}"><span class="board_threadcount">{% blocktrans %}{{ hits }} Threads in this category.{% endblocktrans %}</span><span class="board_pagination">{% sph_pagination pages page %}</span></td>86 <td colspan="{% if sph_settings.board_count_views %}6{% else %}5{% endif %}"><span class="board_threadcount">{% blocktrans %}{{ hits }} Threads in this category.{% endblocktrans %}</span><span class="board_pagination">{% sph_pagination pages page %}</span></td> 86 87 </tr> 87 88 </table> lib/sct/sphenecoll/sphene/sphboard/templates/sphene/sphboard/showThread.html
r41 r146 36 36 {% sphboard_displayBreadcrumbsForThread thread %} 37 37 {% endblock %} 38 {% block top_controls %} 38 39 <br/> 39 40 {% if perms.post.change_post %} … … 76 77 <br/><br/> 77 78 {% endif %} 79 {% endblock %} {# top_controls #} 78 80 {% block above_post_list %} 79 81 <p>{% sph_pagination pages page %}</p> 80 82 {% endblock %} 81 83 <table class="sphboard_post_list"> 84 {% if not post_list %} 85 <tr><td>{% trans "No message to display." %}</td></tr> 86 {% endif %} 82 87 {% for post in post_list %} 83 88 {% block post_list_element %} … … 87 92 </td> 88 93 <td class="sphboard_post_subject"> 89 <div class="board_postdate"><a name="post-{{ post.id }}"></a>{{ post.postdate|date:"Y-m-d H:i:s" }} - <strong>{{ post.subject|escape }}</strong></div>94 {% sphboard_post_header post %} 90 95 <div class="board_controls"> 91 96 {% if post.allow_annotating %} lib/sct/sphenecoll/sphene/sphboard/templatetags/sphboard_extras.py
r41 r146 1 from collections import defaultdict 2 1 3 from django import template 2 4 from django import forms 5 from django.conf import settings 3 6 from django.contrib.auth.models import User 4 7 from django.core.cache import cache … … 72 75 73 76 @register.inclusion_tag('sphene/sphboard/_displayUserName.html') 74 def sphboard_displayUserName( user ):75 return { 'user': user }77 def sphboard_displayUserName( user, suffix="" ): 78 return { 'user': user, 'suffix': suffix } 76 79 77 80 @register.inclusion_tag('sphene/sphboard/_displayPostForm.html') 78 81 def sphboard_quick_reply( thread ): 79 82 return { 'form': PostForm(initial={'subject': u'Re: ' + thread.subject} ), 'form_action': thread.get_absolute_postreplyurl() } 83 84 @register.inclusion_tag('sphene/sphboard/_displayPostIcon.html') 85 def sphboard_displayPostIcon( post ): 86 image_url = "%ssphene/emoticons/%s.png" % (settings.MEDIA_URL, post.icon or "standard") 87 return { 'image_url': image_url } 80 88 81 89 ### sphboard_displayPostForm is deprecated, there is a view function for this !! … … 147 155 148 156 157 @register.inclusion_tag('sphene/sphboard/_post_header.html') 158 def sphboard_post_header(post): 159 if post.is_private(): 160 recgroups = defaultdict(list) 161 for rec in post.recipient_set.all(): 162 recgroups[rec.type].append(rec) 163 recipients = [] 164 for k in ('TO','CC'): 165 if k in recgroups: 166 recs = recgroups[k] 167 recipients.append((recs[0].label(), recs)) 168 else: 169 recipients = () 170 171 return {'post': post, 'recipients': recipients } 172 149 173 def clear_cache_all_languages(user_id, group_id): 150 from django.conf import settings151 174 if not hasattr(settings, 'LANGUAGES'): 152 175 return lib/sct/sphenecoll/sphene/sphboard/views.py
r41 r184 20 20 21 21 22 def showCategory(request, group = None, category_id = None, showType = None, slug = None):22 def showCategory(request, group, category_id = None, showType = None, slug = None): 23 23 """ 24 24 displays either all root categories, or the contents of a category. … … 28 28 this function - this is is probably the oldest and ugliest in 29 29 the whole SCT source. 30 31 We no longer support having no group !! 30 32 """ 31 33 args = { … … 44 46 raise PermissionDenied() 45 47 categoryObject.touch(request.session, request.user) 46 blog_feed_url = reverse('sphboard-feeds', urlconf=get_current_urlconf(), args = (), kwargs = { 'url': 'latest/2'})48 blog_feed_url = sph_reverse('sphboard-feeds', kwargs = { 'url': 'latest/%s' % categoryObject.id }) 47 49 add_rss_feed( blog_feed_url, 'Latest Threads in %s RSS Feed' % categoryObject.name ) 48 50 … … 144 146 def showThread(request, thread_id, group = None, slug = None): 145 147 thread = get_object_or_404(Post.objects, pk = thread_id ) 146 if not thread. category.has_view_permission(request.user):148 if not thread.has_view_permission(request.user): 147 149 raise PermissionDenied() 148 150 thread.viewed( request.session, request.user ) … … 203 205 get_sph_setting('board_wysiwyg') 204 206 205 def post(request, group = None, category_id = None, post_id = None, thread_id = None): 207 def post(request, group = None, category_id = None, post_id = None, thread_id = None, 208 with_monitor=True, with_poll=True): 209 """ 210 View method to allow users to: 211 - create new threads (post_id and thread_id is None) 212 - reply to threads (post_id is None) 213 - edit posts (post_id is the post which should be edited, thread_id is None) 214 215 post_id and thread_id can either be passed in by URL (named parameters 216 to this method) or by request.REQUEST parameters. 217 """ 206 218 if 'type' in request.REQUEST and request.REQUEST['type'] == 'preview': 219 # If user just wants a preview, simply create a dummy post so it can be rendered. 207 220 previewpost = Post( body = request.REQUEST['body'], 208 221 markup = request.REQUEST.get('markup', None), ) 209 222 return HttpResponse( unicode(previewpost.body_escaped()) ) 210 223 211 224 225 # All available objects should be loaded from the _id variables. 212 226 post = None 213 227 thread = None … … 222 236 post_id = request.REQUEST['post_id'] 223 237 224 if post_id: 238 if post_id is not None: 239 # User wants to edit a post .. 225 240 try: 226 241 post = Post.allobjects.get( pk = post_id ) … … 231 246 raise PermissionDenied() 232 247 thread = post.thread 233 234 if 'thread' in request.REQUEST: 235 thread_id = request.REQUEST['thread'] 236 237 if thread_id: 238 try: 239 thread = Post.allobjects.get( pk = thread_id ) 240 except Post.DoesNotExist: 241 raise Http404 242 243 category = thread.category 244 context['thread'] = thread 248 category = post.category 249 250 else: 251 # User wants to create a new post (thread or reply) 252 if 'thread' in request.REQUEST: 253 thread_id = request.REQUEST['thread'] 254 255 if thread_id is not None: 256 # User is posting (replying) to a thread. 257 try: 258 thread = Post.allobjects.get( pk = thread_id ) 259 except Post.DoesNotExist: 260 raise Http404 261 262 category = thread.category 245 263 246 if not thread.allowPosting( request.user ): 247 raise PermissionDenied() 248 else: 249 category = get_object_or_404(Category, pk = category_id) 250 if not category.allowPostThread( request.user ): 251 raise PermissionDenied() 252 264 if not thread.allowPosting( request.user ): 265 raise PermissionDenied() 266 else: 267 # User is creating a new thread. 268 category = get_object_or_404(Category, pk = category_id) 269 if not category.allowPostThread( request.user ): 270 raise PermissionDenied() 271 272 context['thread'] = thread 253 273 context['category'] = category 254 274 … … 304 324 newpost = post 305 325 newpost.subject = data['subject'] 326 newpost.icon = data['icon'] 306 327 newpost.body = data['body'] 307 328 # make post visible … … 313 334 newpost = Post( category = category, 314 335 subject = data['subject'], 336 icon = data['icon'], 315 337 body = data['body'], 316 338 author = user, 317 thread = thread,339 thread = (thread is not None and not thread.is_private()) and thread or None, 318 340 ) 319 341 if 'markup' in data: … … 323 345 newpost.markup = POST_MARKUP_CHOICES[0][0] 324 346 347 newpost.author_ip = request.META.get('REMOTE_ADDR') 325 348 newpost.save(additional_data = data) 326 349 … … 329 352 330 353 # Creating monitor 331 if request.POST.get( 'addmonitor', False ):354 if with_monitor and request.POST.get( 'addmonitor', False ): 332 355 newpost.toggle_monitor() 333 356 334 357 335 if 'createpoll' in request.POST and request.POST['createpoll'] == '1':358 if with_poll and 'createpoll' in request.POST and request.POST['createpoll'] == '1': 336 359 newpost.set_poll( True ); 337 360 newpost.save() … … 374 397 if post: 375 398 postForm.fields['subject'].initial = post.subject 399 postForm.fields['icon'].initial = post.icon 376 400 postForm.fields['body'].initial = post.body 377 401 if 'markup' in postForm.fields: … … 379 403 context['post'] = post 380 404 context['thread'] = post.thread or post 381 elif 'quote' in request.REQUEST:382 quotepost = Post.objects.get( pk = request.REQUEST['quote'] )383 postForm.fields['subject'].initial = 'Re: %s' % thread.subject384 if quotepost.author == None:385 username = 'anonymous'386 else:387 username = quotepost.author.username388 postForm.fields['body'].initial = '[quote=%s;%s]\n%s\n[/quote]\n' % (username, quotepost.id, quotepost.body)389 405 elif thread: 390 406 postForm.fields['subject'].initial = 'Re: %s' % thread.subject 407 if postForm.has_recipients(): 408 postForm.fields['to'].initial = thread.author.username 409 if 'quote' in request.REQUEST: 410 quotepost = Post.objects.get( pk = request.REQUEST['quote'] ) 411 if quotepost.author == None: 412 username = 'anonymous' 413 else: 414 username = quotepost.author.username 415 postForm.fields['body'].initial = '[quote=%s;%s]\n%s\n[/quote]\n' % (username, quotepost.id, quotepost.body) 391 416 context['form'] = postForm 392 417 393 418 # Only allow polls if this is a new _thread_ (not a reply) 394 if (not thread and not post) or (post and post.is_new() and post.thread is None):419 if with_poll and (not thread and not post) or (post and post.is_new() and post.thread is None): 395 420 context['pollform'] = pollForm 396 421 context['attachmentForm'] = attachmentForm … … 583 608 584 609 585 return HttpResponseRedirect( '../../thread/%s/' % thread.id)610 return HttpResponseRedirect( thread.get_absolute_url() ) 586 611 587 612 def toggle_monitor(request, group, monitortype, object_id): 588 redirectview = 'show' 613 if not request.user.is_authenticated(): 614 raise PermissionDenied() 589 615 obj = None 590 616 if monitortype == 'group': … … 595 621 elif monitortype == 'thread': 596 622 obj = Post.objects.get( pk = object_id ) 597 redirectview = 'thread'598 623 599 624 if obj.toggle_monitor(): … … 604 629 if 'next' in request.GET: 605 630 return HttpResponseRedirect( request.GET['next'] ) 606 return HttpResponseRedirect( '../../%s/%s/' % (redirectview, object_id) ) 631 if monitortype == 'group': 632 return HttpResponseRedirect( sph_reverse( 'sphboard-index' ) ) 633 return HttpResponseRedirect( obj.get_absolute_url() ) 607 634 608 635 def catchup(request, group, category_id): lib/sct/sphenecoll/sphene/sphwiki/__init__.py
r40 r166 21 21 # This class is added to the <img> tag as well as to the <a> tag. 22 22 'wiki_macros_default_image_class': None, 23 24 # The language used in wiki pages. 25 # currently supported are: 'markdown', 'restructuredtext'. 26 'wiki_markup_language': 'markdown', 27 28 # Configuration for docutils used in wiki snip rendering 29 'wiki_docutils_settings': { 30 # Without this, the first title is always promoted to an h1; furthermore 31 # the body is split in ``body_pre_docinfo``, ``docinfo`` and ``fragment`` 32 # which then should be joined together 33 'doctitle_xform': False, 34 35 'initial_header_level': 2, 36 37 # Security-related settings 38 'file_insertion_enabled': False, 39 'raw_enabled': False, 40 'cloak_email_addresses': True, 41 }, 23 42 }) lib/sct/sphenecoll/sphene/sphwiki/models.py
r41 r179 1 1 from django.db import models 2 from django.core import exceptions 2 3 from django.core.urlresolvers import reverse 3 4 from django.contrib.auth.models import User … … 5 6 from django.utils.safestring import mark_safe 6 7 from django.utils.translation import ugettext, ugettext_lazy 8 from django.core.cache import cache 9 from django.db.models import signals 7 10 8 11 9 12 from sphene.community.templatetags.sph_extras import sph_markdown 10 13 #from django.db.models import permalink 11 from sphene.community.sphutils import sphpermalink as permalink, get_sph_setting14 from sphene.community.sphutils import sphpermalink, get_sph_setting, sph_reverse 12 15 13 16 from sphene.community.models import Group … … 19 22 import os 20 23 import re 21 22 """23 def permalink(func):24 from django.core.urlresolvers import reverse25 from django.conf import settings26 def inner(*args, **kwargs):27 bits = func(*args, **kwargs)28 viewname = bits[0]29 req = get_current_request()30 urlconf = getattr(req, 'urlconf', settings.ROOT_URLCONF)31 return reverse(bits[0], urlconf, *bits[1:3])32 return inner33 """34 24 35 25 WIKI_PERMISSIONS_ALLOWED_CHOICES = ( … … 56 46 ) 57 47 48 def _get_cache_key(self): 49 if self.id is not None: 50 return "__wiki_snip__%s" % self.id 51 else: 52 return None 53 58 54 def render(self): 55 # Assume the appearance of the rendered page is the same for all the users 56 key = self._get_cache_key() 57 if key is not None: 58 rv = cache.get(key) 59 if rv is not None: return rv 60 61 lang = get_sph_setting( 'wiki_markup_language' ) 62 meth = getattr(self, 'render_%s' % lang, None) 63 if meth is not None: 64 rv = meth() 65 if key is not None: 66 cache.set(key, rv) 67 return rv 68 69 raise exceptions.ImproperlyConfigured("unknown markup language: '%s'" % lang) 70 71 def render_markdown(self): 59 72 from sphene.sphwiki import wikimacros 60 73 return mark_safe(sph_markdown(self.body, … … 65 78 })) 66 79 80 def render_restructuredtext(self): 81 from docutils_extras import render_wiki_snip 82 # returning an empty string creates an infinite recursion downstream 83 return render_wiki_snip(self) or '\n' 84 67 85 def get_title(self): 68 86 return self.title or self.name … … 178 196 def get_absolute_url(self): 179 197 return ('sphene.sphwiki.views.showSnip', (), { 'groupName': self.group.name, 'snipName': self.name }) 180 get_absolute_url = permalink(get_absolute_url, get_current_request)198 get_absolute_url = sphpermalink(get_absolute_url) 181 199 182 200 def get_absolute_editurl(self): 183 201 return ('sphene.sphwiki.views.editSnip', (), { 'groupName': self.group.name, 'snipName': self.name }) 184 get_absolute_editurl = permalink(get_absolute_editurl, get_current_request)202 get_absolute_editurl = sphpermalink(get_absolute_editurl) 185 203 186 204 def get_absolute_attachmenturl(self): 187 205 return ('sphene.sphwiki.views.attachment', (), { 'groupName': self.group.name, 'snipName': self.name }) 188 get_absolute_attachmenturl = permalink(get_absolute_attachmenturl, get_current_request)206 get_absolute_attachmenturl = sphpermalink(get_absolute_attachmenturl) 189 207 190 208 def get_absolute_create_attachmenturl(self): 191 209 return ('sphene.sphwiki.views.attachmentCreate', (), { 'groupName': self.group.name, 'snipName': self.name }) 192 get_absolute_create_attachmenturl = permalink(get_absolute_create_attachmenturl, get_current_request)210 get_absolute_create_attachmenturl = sphpermalink(get_absolute_create_attachmenturl) 193 211 194 212 def get_absolute_historyurl(self): 195 213 return ('sphene.sphwiki.views.history', (), { 'groupName': self.group.name, 'snipName': self.name}) 196 get_absolute_historyurl = permalink(get_absolute_historyurl, get_current_request)214 get_absolute_historyurl = sphpermalink(get_absolute_historyurl) 197 215 198 216 def get_absolute_recentchangesurl(self): 199 217 return ('sphene.sphwiki.views.recentChanges', (), { 'groupName': self.group.name }) 200 get_absolute_recentchangesurl = permalink(get_absolute_recentchangesurl, get_current_request)218 get_absolute_recentchangesurl = sphpermalink(get_absolute_recentchangesurl) 201 219 202 220 def get_absolute_pdfurl(self): 203 221 return ('sphene.sphwiki.views.generatePDF', (), { 'groupName': self.group.name, 'snipName': self.name }) 204 get_absolute_pdfurl = permalink(get_absolute_pdfurl, get_current_request)222 get_absolute_pdfurl = sphpermalink(get_absolute_pdfurl) 205 223 206 224 def get_parent(self): … … 302 320 303 321 322 # Invalidate the cache when a snip is altered 323 def clear_cache_wiki_snip(sender, instance, **kwargs): 324 key = instance._get_cache_key() 325 if key is not None: 326 cache.delete(key) 327 328 signals.post_save.connect(clear_cache_wiki_snip, sender=WikiSnip) 329 330 304 331 class WikiSnipChange(models.Model): 305 332 snip = models.ForeignKey(WikiSnip) … … 338 365 def get_absolute_url(self): 339 366 return ('sphene.sphwiki.views.diff', (), { 'groupName': self.snip.group.name, 'snipName': self.snip.name, 'changeId': self.id}) 340 get_absolute_url = permalink(get_absolute_url, get_current_request)367 get_absolute_url = sphpermalink(get_absolute_url) 341 368 342 369 def get_absolute_editurl(self): 343 return reverse( 'sphwiki_editversion', 344 urlconf = getattr( get_current_request(), 'urlconf', None ), 345 kwargs = { 'snipName': self.snip.name, 346 'versionId': self.id } ); 370 return sph_reverse( 'sphwiki_editversion', 371 kwargs = { 'snipName': self.snip.name, 372 'versionId': self.id } ); 347 373 348 374 … … 364 390 def get_absolute_editurl(self): 365 391 return ('sphene.sphwiki.views.attachmentEdit', (), { 'groupName': self.snip.group.name, 'snipName': self.snip.name, 'attachmentId': self.id } ) 366 get_absolute_editurl = permalink(get_absolute_editurl, get_current_request)392 get_absolute_editurl = sphpermalink(get_absolute_editurl) 367 393 368 394 def save(self, force_insert=False, force_update=False): lib/sct/sphenecoll/sphene/sphwiki/urls.py
r40 r178 7 7 ) 8 8 9 snip = r'(?P<snipName>[ \w/:\-.]+?)'9 snip = r'(?P<snipName>[ \w/:\-.]+?)' 10 10 11 11 urlpatterns += patterns('sphene.sphwiki.views', lib/sct/static/sphene/emoticons/README.txt
r40 r110 1 These icons were copied from http://svn.zyons.python-hosting.com/trunk/zilbo/ 2 no idea who made them originally .. and i hope noone is bothered that i reuse 3 them ... 1 These icons are from the Tango Desktop Project, released to the Public Domain: 4 2 3 http://tango.freedesktop.org/Tango_Desktop_Project 5 4 5 We are extremely grateful to the Tango Desktop Project artists: 6 thank you for your patient and wonderful work! lib/sct/static/sphene/sphboard/js/editor.js
r41 r113 36 36 rep(/rgb\(128,\s?0,\s?128\)/gi,"purple"); 37 37 rep(/rgb\(0,\s?128,\s?128\)/gi,"teal"); 38 39 // __replace_start__: emoticons_html_to_bbcode 40 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/smile\.png\"?(\s[^<>]*)?\/?>/gi," :)"); 41 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/wink\.png\"?(\s[^<>]*)?\/?>/gi," ;)"); 42 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/thinking\.png\"?(\s[^<>]*)?\/?>/gi," :thinking:"); 43 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/dont-know\.png\"?(\s[^<>]*)?\/?>/gi," :dont-know:"); 44 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/eyeroll\.png\"?(\s[^<>]*)?\/?>/gi," :eyeroll:"); 45 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/neutral\.png\"?(\s[^<>]*)?\/?>/gi," :|"); 46 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/embarrassed\.png\"?(\s[^<>]*)?\/?>/gi," :embarrassed:"); 47 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/confused\.png\"?(\s[^<>]*)?\/?>/gi," :confused:"); 48 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/sarcastic\.png\"?(\s[^<>]*)?\/?>/gi," :sarcastic:"); 49 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/sad\.png\"?(\s[^<>]*)?\/?>/gi," :("); 50 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/crying\.png\"?(\s[^<>]*)?\/?>/gi," ;("); 51 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/angry\.png\"?(\s[^<>]*)?\/?>/gi," :angry:"); 52 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/shock\.png\"?(\s[^<>]*)?\/?>/gi," :O"); 53 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/good\.png\"?(\s[^<>]*)?\/?>/gi," :ok:"); 54 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/bad\.png\"?(\s[^<>]*)?\/?>/gi," :ko:"); 55 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/fingers-crossed\.png\"?(\s[^<>]*)?\/?>/gi," :fingers-crossed:"); 56 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/foot-in-mouth\.png\"?(\s[^<>]*)?\/?>/gi," :foot-in-mouth:"); 57 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/glasses-cool\.png\"?(\s[^<>]*)?\/?>/gi," :glasses-cool:"); 58 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/glasses-nerdy\.png\"?(\s[^<>]*)?\/?>/gi," 8)"); 59 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/highfive\.png\"?(\s[^<>]*)?\/?>/gi," :batti5:"); 60 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/hug-left\.png\"?(\s[^<>]*)?\/?>/gi," :hug-left:"); 61 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/hug-right\.png\"?(\s[^<>]*)?\/?>/gi," :hug-right:"); 62 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/kiss\.png\"?(\s[^<>]*)?\/?>/gi," :*"); 63 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/laugh\.png\"?(\s[^<>]*)?\/?>/gi," :D"); 64 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/party\.png\"?(\s[^<>]*)?\/?>/gi," :party:"); 65 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/question\.png\"?(\s[^<>]*)?\/?>/gi," :question:"); 66 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/quiet\.png\"?(\s[^<>]*)?\/?>/gi," :quiet:"); 67 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/secret\.png\"?(\s[^<>]*)?\/?>/gi," :segreto:"); 68 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/sick\.png\"?(\s[^<>]*)?\/?>/gi," :sick:"); 69 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/sleepy\.png\"?(\s[^<>]*)?\/?>/gi," :sleepy:"); 70 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/teeth\.png\"?(\s[^<>]*)?\/?>/gi," :teeth:"); 71 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/tongue\.png\"?(\s[^<>]*)?\/?>/gi," :P"); 72 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/vampire\.png\"?(\s[^<>]*)?\/?>/gi," :vampire:"); 73 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/angel\.png\"?(\s[^<>]*)?\/?>/gi," :angel:"); 74 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/devil\.png\"?(\s[^<>]*)?\/?>/gi," :devil:"); 75 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/beer\.png\"?(\s[^<>]*)?\/?>/gi," :birrame:"); 76 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/coffee\.png\"?(\s[^<>]*)?\/?>/gi," :caffÚ:"); 77 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\/static\/sphene\/emoticons\/pitoncino\.png\"?(\s[^<>]*)?\/?>/gi," :py:"); 78 // __replace_end__: emoticons_html_to_bbcode 38 79 39 80 rep(/<img\s[^<>]*?src=\"?([^<>]*?)\"?(\s[^<>]*)?\/?>/gi,"[img]$1[/img]"); … … 127 168 } 128 169 rep(/\[img\]([\s\S]*?)\[\/img\]/gi,"<img src=\"$1\" />"); 170 // __replace_start__: emoticons_bbcode_to_html 171 rep(/\:fingers\-crossed\:/g,"<img src=\"/static/sphene/emoticons/fingers-crossed.png\" alt=\":fingers-crossed:\" title=\":fingers-crossed:\"/>"); 172 rep(/\:foot\-in\-mouth\:/g,"<img src=\"/static/sphene/emoticons/foot-in-mouth.png\" alt=\":foot-in-mouth:\" title=\":foot-in-mouth:\"/>"); 173 rep(/\:glasses\-cool\:/g,"<img src=\"/static/sphene/emoticons/glasses-cool.png\" alt=\":glasses-cool:\" title=\":glasses-cool:\"/>"); 174 rep(/\:embarrassed\:/g,"<img src=\"/static/sphene/emoticons/embarrassed.png\" alt=\":embarrassed:\" title=\":embarrassed:\"/>"); 175 rep(/\:dont\-know\:/g,"<img src=\"/static/sphene/emoticons/dont-know.png\" alt=\":dont-know:\" title=\":dont-know:\"/>"); 176 rep(/\:sarcastic\:/g,"<img src=\"/static/sphene/emoticons/sarcastic.png\" alt=\":sarcastic:\" title=\":sarcastic:\"/>"); 177 rep(/\:hug\-right\:/g,"<img src=\"/static/sphene/emoticons/hug-right.png\" alt=\":hug-right:\" title=\":hug-right:\"/>"); 178 rep(/\:thinking\:/g,"<img src=\"/static/sphene/emoticons/thinking.png\" alt=\":thinking:\" title=\":thinking:\"/>"); 179 rep(/\:confused\:/g,"<img src=\"/static/sphene/emoticons/confused.png\" alt=\":confused:\" title=\":confused:\"/>"); 180 rep(/\:hug\-left\:/g,"<img src=\"/static/sphene/emoticons/hug-left.png\" alt=\":hug-left:\" title=\":hug-left:\"/>"); 181 rep(/\:question\:/g,"<img src=\"/static/sphene/emoticons/question.png\" alt=\":question:\" title=\":question:\"/>"); 182 rep(/\:eyeroll\:/g,"<img src=\"/static/sphene/emoticons/eyeroll.png\" alt=\":eyeroll:\" title=\":eyeroll:\"/>"); 183 rep(/\:segreto\:/g,"<img src=\"/static/sphene/emoticons/secret.png\" alt=\":segreto:\" title=\":segreto:\"/>"); 184 rep(/\:vampire\:/g,"<img src=\"/static/sphene/emoticons/vampire.png\" alt=\":vampire:\" title=\":vampire:\"/>"); 185 rep(/\:birrame\:/g,"<img src=\"/static/sphene/emoticons/beer.png\" alt=\":birrame:\" title=\":birrame:\"/>"); 186 rep(/\:batti5\:/g,"<img src=\"/static/sphene/emoticons/highfive.png\" alt=\":batti5:\" title=\":batti5:\"/>"); 187 rep(/\:sleepy\:/g,"<img src=\"/static/sphene/emoticons/sleepy.png\" alt=\":sleepy:\" title=\":sleepy:\"/>"); 188 rep(/\:angry\:/g,"<img src=\"/static/sphene/emoticons/angry.png\" alt=\":angry:\" title=\":angry:\"/>"); 189 rep(/\:party\:/g,"<img src=\"/static/sphene/emoticons/party.png\" alt=\":party:\" title=\":party:\"/>"); 190 rep(/\:quiet\:/g,"<img src=\"/static/sphene/emoticons/quiet.png\" alt=\":quiet:\" title=\":quiet:\"/>"); 191 rep(/\:teeth\:/g,"<img src=\"/static/sphene/emoticons/teeth.png\" alt=\":teeth:\" title=\":teeth:\"/>"); 192 rep(/\:angel\:/g,"<img src=\"/static/sphene/emoticons/angel.png\" alt=\":angel:\" title=\":angel:\"/>"); 193 rep(/\:devil\:/g,"<img src=\"/static/sphene/emoticons/devil.png\" alt=\":devil:\" title=\":devil:\"/>"); 194 rep(/:caffÚ:/g,"<img src=\"/static/sphene/emoticons/coffee.png\" alt=\":caffÚ:\" title=\":caffÚ:\"/>"); 195 rep(/\:sick\:/g,"<img src=\"/static/sphene/emoticons/sick.png\" alt=\":sick:\" title=\":sick:\"/>"); 196 rep(/\:ok\:/g,"<img src=\"/static/sphene/emoticons/good.png\" alt=\":ok:\" title=\":ok:\"/>"); 197 rep(/\:ko\:/g,"<img src=\"/static/sphene/emoticons/bad.png\" alt=\":ko:\" title=\":ko:\"/>"); 198 rep(/\:py\:/g,"<img src=\"/static/sphene/emoticons/pitoncino.png\" alt=\":py:\" title=\":py:\"/>"); 199 rep(/\:\)/g,"<img src=\"/static/sphene/emoticons/smile.png\" alt=\":)\" title=\":)\"/>"); 200 rep(/\;\)/g,"<img src=\"/static/sphene/emoticons/wink.png\" alt=\";)\" title=\";)\"/>"); 201 rep(/\:\|/g,"<img src=\"/static/sphene/emoticons/neutral.png\" alt=\":|\" title=\":|\"/>"); 202 rep(/\:\(/g,"<img src=\"/static/sphene/emoticons/sad.png\" alt=\":(\" title=\":(\"/>"); 203 rep(/\;\(/g,"<img src=\"/static/sphene/emoticons/crying.png\" alt=\";(\" title=\";(\"/>"); 204 rep(/\:O/g,"<img src=\"/static/sphene/emoticons/shock.png\" alt=\":O\" title=\":O\"/>"); 205 rep(/8\)/g,"<img src=\"/static/sphene/emoticons/glasses-nerdy.png\" alt=\"8)\" title=\"8)\"/>"); 206 rep(/\:\*/g,"<img src=\"/static/sphene/emoticons/kiss.png\" alt=\":*\" title=\":*\"/>"); 207 rep(/\:D/g,"<img src=\"/static/sphene/emoticons/laugh.png\" alt=\":D\" title=\":D\"/>"); 208 rep(/\:P/g,"<img src=\"/static/sphene/emoticons/tongue.png\" alt=\":P\" title=\":P\"/>"); 209 // __replace_end__: emoticons_bbcode_to_html 129 210 var sc; 130 211 do { … … 366 447 } 367 448 368 function insertSmiley(n ){449 function insertSmiley(name){ 369 450 ifm.contentWindow.focus(); 370 if(n<10){n = '0'+n.toString();}else{n = n.toString();} 371 myeditor.execCommand('InsertImage', false, editor_static + '/smilies/n0'+n+'.gif'); 451 myeditor.execCommand('InsertImage', false, emoticons_url + '/'+name+'.png'); 372 452 } 373 453 lib/sct/static/sphene/sphboard/js/inline.js
r41 r113 6 6 var alt = new Array("undo","redo","bold","italic","underline","clear","link","unlink","picture","quote","code"); 7 7 var c = new Array("black","red","blue","green","orange","fuchsia","aqua","lime","maroon","purple","teal"); 8 8 var smn = new Array( 9 // __replace_start__: smile_names 10 "smile","wink","thinking","dont-know","eyeroll","neutral","embarrassed","confused","sarcastic","sad","crying","angry","shock","good","bad","fingers-crossed","foot-in-mouth","glasses-cool","glasses-nerdy","highfive","hug-left","hug-right","kiss","laugh","party","question","quiet","secret","sick","sleepy","teeth","tongue","vampire","angel","devil","beer","coffee","pitoncino" 11 // __replace_end__: smile_names 12 ); 9 13 var str = "<table><tr>"; 10 14 for(i=0;i<11;i++) { … … 21 25 22 26 str = p.innerHTML + '<div id="smilies"><table>'; 23 for(i= 1;i<=24;i++) {24 if(i% 3==1) {25 str += '<tr align="center" height="36">';27 for(i=0;i<=smn.length;i++) { 28 if(i%4==0) { 29 str += '<tr align="center">'; 26 30 } 27 31 if(i<10){n = '0'+i.toString();}else{n = i.toString();} 28 str += '<td valign="middle"><div class="bn" onmouseover="switchBtn(this, 1)" onmouseout="switchBtn(this, 0)" onclick="insertSmiley( ' + i + ')" style="cursor:pointer;"><img src="'+editor_static+'/smilies/n0' + n + '.gif" width=30 border=0 height=30></div></td>';29 if( i%3==0) {32 str += '<td valign="middle"><div class="bn" onmouseover="switchBtn(this, 1)" onmouseout="switchBtn(this, 0)" onclick="insertSmiley(\'' + smn[i] + '\')" style="cursor:pointer;"><img src="'+emoticons_url+'/' + smn[i] + '.png" width=24 height=24 border=0></div></td>'; 33 if((i+1)%4==0) { 30 34 str += '</tr>'; 31 35 } lib/sct/static/sphene/sphboard/styles/base.css
r40 r146 148 148 float:right; 149 149 } 150 .board_postdate { 150 .board_posticon { 151 float:left; 152 margin-right: 5px; 153 } 154 .board_postheaders { 151 155 float:left; 152 156 } … … 207 211 max-height:20em; 208 212 } 213 img.sphboard_post_icon { 214 vertical-align: middle; 215 } 209 216 210 217 lib/sct/static/sphene/sphboard/styles/editor.css
r41 r109 1 body { 2 font-family: Arial, Verdana, Geneva, "Bitstream Vera Sans", Helvetica, sans-serif; 3 font-size: 100%; 4 } 1 5 2 6 .memberquote {
