def create_user_profile(sender, **kwargs): """ signal handler: creating user profile, after a new user created. """ user = kwargs["instance"] userprofile, created = UserProfile.objects.get_or_create(user=user) if created: failsafe_message("UserProfile entry for user '%s' created." % user)
def clean_fields(self, exclude): message_dict = {} if not self.mimetype and self.filepath: # Set mimetype by guess type from filepath self.mimetype = self.auto_mimetype() if "mimetype" not in exclude: all_mimetypes = set(mimetypes.types_map.values()) if self.mimetype not in all_mimetypes: failsafe_message( "Warning: Mimetype %(mimetype)r for headfile %(headfile)r unknown!" % { "mimetype": self.mimetype, "headfile": self.filepath } ) if "filepath" not in exclude: try: # "validate" the filepath with the url re. reverse('PyLucid-send_head_file', kwargs={"filepath": self.filepath}) except NoReverseMatch, err: message_dict["filepath"] = [_( "filepath %(filepath)r contains invalid characters!" " (Original error: %(err)s)" % { "filepath": self.filepath, "err": err, } )]
def reverse(self, plugin_name, viewname, args=(), kwargs={}): """ reverse a plugin url. Please note: this will always use the first PluginPage entry as url prefix! """ # get the app label from plugin_instance = PYLUCID_PLUGINS[plugin_name] app_label = plugin_instance.installed_apps_string # Get the first PluginPage entry for this plugin queryset = PluginPage.objects.all() queryset = queryset.filter(pagetree__site=Site.objects.get_current()) queryset = queryset.filter(app_label=app_label) try: plugin_page = queryset[0] except (IndexError, KeyError): msg = "Can't get a PluginPage for plugin %r, please create one." % plugin_name if settings.DEBUG: msg += " (app_label: %r)" % app_label failsafe_message(msg) raise urlresolvers.NoReverseMatch(msg) url_prefix = plugin_page.get_absolute_url() plugin_url_resolver = plugin_instance.get_plugin_url_resolver(url_prefix, plugin_page.urls_filename) return plugin_url_resolver.reverse(viewname, *args, **kwargs)
def get_languages(self, request): """ Create a list of all languages sorted by client accept language priority. added to request.PYLUCID.languages Cache key: The language entry can have a permitViewGroup, so we must use different caches for different user groups. """ if hasattr(request, "PYLUCID") and hasattr(request.PYLUCID, "languages"): if settings.PYLUCID.I18N_DEBUG: messages.debug(request, "return request.PYLUCID.languages: %r" % request.PYLUCID.languages ) return request.PYLUCID.languages user = request.user languages = self.get_cached_languages(user) if settings.PYLUCID.I18N_DEBUG: failsafe_message("all accessible languages: %r" % languages) accept_lang_codes, unsupported_lang_codes, fallback_lang_codes = self._get_language_codes(request) if settings.PYLUCID.I18N_DEBUG: messages.debug(request, "accept_lang_codes: %r" % accept_lang_codes) messages.debug(request, "unsupported_lang_codes: %r" % unsupported_lang_codes) messages.debug(request, "fallback_lang_codes: %r" % fallback_lang_codes) # XXX: Test QuerySet order # language_codes.sort() # language_codes.sort(reverse=True) # sort the language in the same order than language_codes list was. # XXX: It there a better way to do this? language_list = [] for language_code in accept_lang_codes: for index, language in enumerate(languages): if language.code.lower() == language_code.lower(): if language not in language_list: language_list.append(language) del(languages[index]) break if languages: # The Client has not all existing languages in his HTTP_ACCEPT_LANGUAGE # Append the rest if settings.PYLUCID.I18N_DEBUG: messages.info(request, "client not accepted languages to append: %s" % ", ".join([l.code for l in languages]) ) language_list += languages if settings.PYLUCID.I18N_DEBUG: messages.info(request, "language_list: %s" % ", ".join([l.code for l in language_list])) return language_list
def set_sha_login_password(self, raw_password): """ create salt+checksum for JS-SHA-Login. see also: http://www.pylucid.org/_goto/8/JS-SHA-Login/ """ raw_password = str(raw_password) salt, sha_checksum = crypt.make_sha_checksum2(raw_password) self.sha_login_salt = salt self.sha_login_checksum = sha_checksum failsafe_message("SHA Login salt+checksum set for user '%s'." % self.user)
def __init__(self, attrs=None): super(StaticPathWidget, self).__init__(attrs) self._base_path = os.path.abspath(os.path.normpath(settings.STATIC_ROOT)) try: self.choices = self._get_path_choices() except OSError, err: self.choices = [] if settings.DEBUG: failsafe_message("Can't read STATIC_ROOT: %s" % err)
def __init__(self, attrs=None): super(StaticPathWidget, self).__init__(attrs) self._base_path = os.path.abspath(os.path.normpath(settings.STATIC_ROOT)) try: self.choices = self._get_path_choices() except OSError as err: self.choices = [] if settings.DEBUG: failsafe_message("Can't read STATIC_ROOT: %s" % err)
def delete_cachefile(self, colorscheme=None): cachepath = self.get_cachepath(colorscheme) if not os.path.isfile(cachepath): if settings.DEBUG: failsafe_message("No need to delete cache file %s, it doesn't exist, yet." % cachepath) return try: os.remove(cachepath) except Exception, err: failsafe_message("Can't delete '%(path)s': %(err)s" % { "path": cachepath, "err": err })
def get_url(self): """ reverse the url name. Create error message if NoReverseMatch and return None. e.g.: Plugin deleted in filesystem, but still exist in database. FIXME: Can we get it faster and not with resolve the url? """ try: url = urlresolvers.reverse(self.url_name) except urlresolvers.NoReverseMatch, err: msg = ("Can't resolve url %r for plugin %r: %s" " - (To fix this: run 'install plugins' again.)") % ( self.url_name, self.name, err) failsafe_message(msg)
def __init__(self, attrs=None): super(MediaPathWidget, self).__init__(attrs) self._base_path = os.path.abspath(os.path.normpath( settings.MEDIA_ROOT)) try: self.choices = self._get_path_choices() except OSError as err: self.choices = [] if settings.DEBUG: failsafe_message("Can't read MEDIA_ROOT: %s" % err) warnings.warn( "MediaPathWidget is deprecated and will removed in the future!" " Please use StaticPathWidget.", PendingDeprecationWarning)
class SiteAuthBackend(ModelBackend): """ Normal username/plaintext password authentication, but we limit user to sites. """ def authenticate(self, username=None, password=None): try: user = User.objects.get(username=username) if not user.check_password(password): if settings.DEBUG or LOCAL_DEBUG: failsafe_message("Wrong password!") return except User.DoesNotExist, err: msg = _("User %(username)s doesn't exist: %(err)s") % {"username": username, "err":err} LogEntry.objects.log_action( app_label="pylucid", action="auth_backends", message=msg, ) if LOCAL_DEBUG: raise if settings.DEBUG: failsafe_message() return if LOCAL_DEBUG: failsafe_message("Username %s and password ok." % username) # Limit the access to UserProfile <-> site relationship if can_access_site(user) == True: return user
def set_password(user, raw_password): #print "set_password() debug:", user, raw_password if user.id == None: # It is a new user. We must save the django user accound first to get a # existing user object with a ID and then the JS-SHA-Login Data can assign to it. user.save() # Use the original method to set the django User password: orig_set_password(user, raw_password) userprofile, created = UserProfile.objects.get_or_create(user=user) if created: failsafe_message("UserProfile entry for user '%s' created." % user) # Save the password for the JS-SHA-Login: userprofile.set_sha_login_password(raw_password) userprofile.save()
def get_or_create_default(self, request): """ return Language instance with code from settings.LANGUAGE_CODE Create if not exist. """ if self.default_lang_entry is None: language_code = settings.LANGUAGE_CODE self.default_lang_entry = self.get_from_code(request, language_code) if self.default_lang_entry is None: failsafe_message("Default language entry not in language list?") self.default_lang_entry, created = self.get_or_create( code=language_code, defaults={'description': language_code} ) if created: failsafe_message("Default language entry %r created." % self.default_lang_entry) return self.default_lang_entry
def __init__(self, attrs=None): super(MediaPathWidget, self).__init__(attrs) self._base_path = os.path.abspath(os.path.normpath(settings.MEDIA_ROOT)) try: self.choices = self._get_path_choices() except OSError as err: self.choices = [] if settings.DEBUG: failsafe_message("Can't read MEDIA_ROOT: %s" % err) warnings.warn( "MediaPathWidget is deprecated and will removed in the future!" " Please use StaticPathWidget.", PendingDeprecationWarning )
def get_or_create_default(self, request): """ return Language instance with code from settings.LANGUAGE_CODE Create if not exist. """ if self.default_lang_entry is None: language_code = settings.LANGUAGE_CODE self.default_lang_entry = self.get_from_code(request, language_code) if self.default_lang_entry is None: failsafe_message("Default language entry not in language list?") self.default_lang_entry, created = self.get_or_create( code=language_code, defaults={"description": language_code} ) if created: failsafe_message("Default language entry %r created." % self.default_lang_entry) return self.default_lang_entry
def get_url(self): """ reverse the url name. Create error message if NoReverseMatch and return None. e.g.: Plugin deleted in filesystem, but still exist in database. FIXME: Can we get it faster and not with resolve the url? """ try: url = urlresolvers.reverse(self.url_name) except urlresolvers.NoReverseMatch, err: msg = ( "Can't resolve url %r for plugin %r: %s" " - (To fix this: run 'install plugins' again.)" ) % (self.url_name, self.name, err) failsafe_message(msg)
def authenticate(self, username=None, password=None): try: user = User.objects.get(username=username) if not user.check_password(password): if settings.DEBUG or LOCAL_DEBUG: failsafe_message("Wrong password!") return except User.DoesNotExist, err: msg = _("User %(username)s doesn't exist: %(err)s") % {"username": username, "err":err} LogEntry.objects.log_action( app_label="pylucid", action="auth_backends", message=msg, ) if LOCAL_DEBUG: raise if settings.DEBUG: failsafe_message() return
def authenticate(self, user=None, challenge=None, sha_a=None, sha_b=None, sha_checksum=None, loop_count=None, cnonce=None): if user == None: # Nothing to do: Normal auth? return try: check = crypt.check_js_sha_checksum(challenge, sha_a, sha_b, sha_checksum, loop_count, cnonce) except crypt.SaltHashError, err: # Wrong password LogEntry.objects.log_action( app_label="pylucid", action="auth_backends", message="User %r check_js_sha_checksum error: %s" % (user, err), ) if LOCAL_DEBUG: raise if settings.DEBUG: failsafe_message(err, level=messages.ERROR) return None
def authenticate(self, user=None, challenge=None, sha_a2=None, sha_b=None, sha_checksum=None): if user == None: # Nothing to do: Normal auth? return try: check = crypt.check_js_sha_checksum(challenge, sha_a2, sha_b, sha_checksum) except crypt.SaltHashError, err: # Wrong password LogEntry.objects.log_action( app_label="pylucid", action="auth_backends", message="User %r check_js_sha_checksum error: %s" % (user, err), ) if LOCAL_DEBUG: raise if settings.DEBUG: failsafe_message(err) return None
def get_by_plugin_name(self, plugin_name): """ return PluginPage instance by plugin_name """ plugin_instance = PYLUCID_PLUGINS[plugin_name] app_label = plugin_instance.installed_apps_string queryset = self.queryset_by_app_label(app_label) try: # Get the first PluginPage entry for this plugin plugin_page = queryset[0] except (IndexError, KeyError): msg = "Can't get a PluginPage for plugin %r, please create one." % plugin_name if settings.DEBUG: msg += " (app_label: %r)" % app_label failsafe_message(msg) raise urlresolvers.NoReverseMatch(msg) return plugin_page
def save(self, *args, **kwargs): """ Automatic current site, if not exist. I don't know why default=[settings.SITE_ID] is not enough, see also: http://www.python-forum.de/viewtopic.php?t=21022 (de) """ if self.pk == None: # instance needs to have a primary key value before a many-to-many relationship can be used. super(AutoSiteM2M, self).save(*args, **kwargs) if "force_insert" in kwargs: # we can't pass force insert to the real save method, because we # have save it yet. del kwargs["force_insert"] if self.sites.count() == 0: if settings.DEBUG: failsafe_message("Automatic add site id '%s' to %r" % (settings.SITE_ID, self)) self.sites.add(settings.SITE_ID) super(AutoSiteM2M, self).save(*args, **kwargs)
def _save_cache_file(auto_create_dir=True): if colorscheme: rendered_content = self.get_rendered(colorscheme) else: rendered_content = self.content try: f = codecs.open(cachepath, "w", "utf8") f.write(rendered_content) f.close() except IOError, err: if auto_create_dir and err.errno == errno.ENOENT: # No 2: No such file or directory # Try to create the out dir and save the cache file path = os.path.dirname(cachepath) if not os.path.isdir(path): # Try to create cache path and save file os.makedirs(path) msg = "Cache path %s created" % path # print msg failsafe_message(msg) _save_cache_file(auto_create_dir=False) return raise
def rename_color(self, new_name, old_name): """ Rename a color in headfile content. called e.g. from Color model """ # Replace color name in headfile content old_content = self.content new_content = replace_css_name(old_name, new_name, old_content) if old_content == new_content: if settings.DEBUG: failsafe_message( 'Color "{{ %s }}" not exist in headfile "%s"' % (old_name, self.filepath) ) return False else: self.content = new_content self.save() if settings.DEBUG: failsafe_message( "change color name from '%s' to '%s' in %r" % (old_name, new_name, self.filepath) ) return True
def can_access_site(user): """ Check if the user can access the current site. Use the UserProfile <-> site relationship. Skip check for all superusers. """ if user.is_superuser: if LOCAL_DEBUG: failsafe_message("Superuser can access all sites.") return True else: if LOCAL_DEBUG: failsafe_message("No superuser -> check UserProfile.") try: user_profile = user.get_profile() except Exception, err: msg = _("Error getting user profile: %s") % err LogEntry.objects.log_action(app_label="pylucid", action="auth_backends", message=msg) failsafe_message(msg) return
from django.contrib.auth.models import User from django.utils.translation import ugettext as _ from dbpreferences.forms import DBPreferencesBaseForm from django_tools.utils.messages import failsafe_message try: forms.EmailField().clean(settings.DEFAULT_FROM_EMAIL) except forms.ValidationError, err: msg = ( "Please change 'DEFAULT_FROM_EMAIL' in your settings.py," " current value is: %s (Org.Error: %s)" ) % (settings.DEFAULT_FROM_EMAIL, err) failsafe_message(msg) class KursAnmeldungPrefForm(DBPreferencesBaseForm): notify = forms.CharField( initial="\n".join( [i["email"] \ for i in User.objects.filter(is_superuser=True).values("email")] ), required=False, help_text=_( "Notify these email addresses if a new comment submited" " (seperated by newline!)" ), widget=forms.Textarea(attrs={'rows': '5'}), )
from django.contrib.auth.backends import ModelBackend from django.contrib.auth.models import User from django.contrib.sites.models import Site from django.utils.translation import ugettext as _ from django_tools.utils.messages import failsafe_message from pylucid_project.utils import crypt from pylucid_project.apps.pylucid.models import LogEntry #LOCAL_DEBUG = True LOCAL_DEBUG = False if LOCAL_DEBUG: failsafe_message("Debug mode in auth_backends is on!", UserWarning) def can_access_site(user): """ Check if the user can access the current site. Use the UserProfile <-> site relationship. Skip check for all superusers. """ if user.is_superuser: if LOCAL_DEBUG: failsafe_message("Superuser can access all sites.") return True else: if LOCAL_DEBUG: failsafe_message("No superuser -> check UserProfile.")
def save(self, *args, **kwargs): if kwargs.pop("skip_renaming", False): # Other color was renamed in the past, we are here inner # renaming process, don't check renaming here, becuase we must # skip a closed renaming loop ;) super(Color, self).save(*args, **kwargs) return new_name = old_name = self.name try: old_name = Color.objects.get(id=self.id).name except Color.DoesNotExist: # New color pass if new_name != old_name: # Color name has been changed. from pylucid_project.apps.pylucid.models import Design changed_headfiles = [] processed_headfiles = [] changed_colorschemes = [self.colorscheme] # process every headfile witch has the same colorscheme designs = Design.objects.all().filter(colorscheme=self.colorscheme) for design in designs: headfiles = design.headfiles.all().filter(render=True) for headfile in headfiles: if headfile in processed_headfiles: continue processed_headfiles.append(headfile) changed = headfile.rename_color(new_name, old_name) if changed: changed_headfiles.append(headfile) # process every colorscheme from the processed headfiles designs = Design.objects.all().exclude( colorscheme=self.colorscheme) for design in designs: colorscheme = design.colorscheme if colorscheme in changed_colorschemes: continue headfiles = design.headfiles.all().filter(render=True) for headfile in headfiles: if headfile in processed_headfiles: color = Color.objects.get(colorscheme=colorscheme, name=old_name) color.name = new_name color.save(skip_renaming=True) changed_colorschemes.append(colorscheme) break failsafe_message( _('Color "%(old_name)s" renamed to "%(new_name)s":' 'Headfiles %(headfiles)s and colorschemes %(schemes)s updated.' ) % { "old_name": old_name, "new_name": new_name, "headfiles": ", ".join(['"%s"' % h.filepath for h in changed_headfiles]), "schemes": ", ".join(['"%s"' % s.name for s in changed_colorschemes]), }) super(Color, self).save(*args, **kwargs)
_save_cache_file(auto_create_dir=False) return raise try: _save_cache_file() except (IOError, OSError), err: msg = "Can't cache EditableHtmlHeadFile into %r: %s" % (cachepath, err) msg += ''' You should set settings.PYLUCID.CACHE_DIR="", if cachen can't be used!''' # print msg failsafe_message(msg) else: if settings.DEBUG: msg = "EditableHtmlHeadFile cached successful into: %r" % cachepath # print msg failsafe_message(msg) def iter_colorschemes(self, skip_colorschemes=None): """ TODO: Optimizes this """ if skip_colorschemes is None: skip_colorschemes = [] designs = Design.objects.all().filter() for design in designs: colorscheme = design.colorscheme if colorscheme in skip_colorschemes: continue headfiles = design.headfiles.filter(pk=self.pk) for headfile in headfiles: if headfile == self: skip_colorschemes.append(colorscheme)
def save(self, *args, **kwargs): if kwargs.pop("skip_renaming", False): # Other color was renamed in the past, we are here inner # renaming process, don't check renaming here, becuase we must # skip a closed renaming loop ;) super(Color, self).save(*args, **kwargs) return new_name = old_name = self.name try: old_name = Color.objects.get(id=self.id).name except Color.DoesNotExist: # New color pass if new_name != old_name: # Color name has been changed. from pylucid_project.apps.pylucid.models import Design changed_headfiles = [] processed_headfiles = [] changed_colorschemes = [self.colorscheme] # process every headfile witch has the same colorscheme designs = Design.objects.all().filter(colorscheme=self.colorscheme) for design in designs: headfiles = design.headfiles.all().filter(render=True) for headfile in headfiles: if headfile in processed_headfiles: continue processed_headfiles.append(headfile) changed = headfile.rename_color(new_name, old_name) if changed: changed_headfiles.append(headfile) # process every colorscheme from the processed headfiles designs = Design.objects.all().exclude(colorscheme=self.colorscheme) for design in designs: colorscheme = design.colorscheme if colorscheme in changed_colorschemes: continue headfiles = design.headfiles.all().filter(render=True) for headfile in headfiles: if headfile in processed_headfiles: color = Color.objects.get(colorscheme=colorscheme, name=old_name) color.name = new_name color.save(skip_renaming=True) changed_colorschemes.append(colorscheme) break failsafe_message( _( 'Color "%(old_name)s" renamed to "%(new_name)s":' 'Headfiles %(headfiles)s and colorschemes %(schemes)s updated.' ) % { "old_name": old_name, "new_name": new_name, "headfiles": ", ".join(['"%s"' % h.filepath for h in changed_headfiles]), "schemes": ", ".join(['"%s"' % s.name for s in changed_colorschemes]), } ) super(Color, self).save(*args, **kwargs)
def update_colorscheme(self): """ merge colors from headfiles with the colorscheme. """ if not self.render: # No CSS ColorScheme entries in the content -> do nothing return # Get all existing color values from content content, content_colors = unify_spelling(self.content) # Find the most appropriate entry that has the most match colors. best_score = None best_colorscheme = None tested_colorschemes = 0 for colorscheme in self.iter_colorschemes(): tested_colorschemes += 1 score = colorscheme.score_match(content_colors) if score > best_score: best_colorscheme = colorscheme best_score = score if best_colorscheme is None: failsafe_message( _('No existing colorscheme to merge colors found, ok. (tested %s colorschemes)') % tested_colorschemes ) best_colorscheme_dict = {} values2colors = {} colorschemes_data = {} else: failsafe_message( _('Merge colors with colorscheme "%(name)s" (score: %(score)s, tested %(count)s colorschemes)') % { "name": best_colorscheme.name, "score": best_score, "count": tested_colorschemes, } ) best_colorscheme_dict = best_colorscheme.get_color_dict() values2colors = dict([(v, k) for k, v in best_colorscheme_dict.iteritems()]) colorschemes_data = {best_colorscheme:best_colorscheme_dict} existing_color_names = set(best_colorscheme_dict.keys()) if settings.DEBUG: failsafe_message("Use existing colors: %r" % existing_color_names) # Check witch colors are not exist in best colorscheme, yet: best_colorscheme_values = best_colorscheme_dict.values() new_color_values = [] for color_value in content_colors: if color_value not in best_colorscheme_values: new_color_values.append(color_value) # Collect color information from all other colorschemes witch used this headfile: for colorscheme in self.iter_colorschemes(skip_colorschemes=colorschemes_data.keys()): color_dict = colorscheme.get_color_dict() colorschemes_data[colorscheme] = color_dict for color_name, color_value in color_dict.iteritems(): existing_color_names.add(color_name) if color_value not in values2colors: values2colors[color_value] = color_name # Create all new colors in any other colorscheme witch used this headfile: for new_color_value in new_color_values: if new_color_value in values2colors: # Use color name from a other colorscheme color_name = values2colors[new_color_value] else: # this color value doesn't exist in any colorscheme, give it a unique name color_name = unique_color_name(existing_color_names, new_color_value) values2colors[new_color_value] = color_name existing_color_names.add(color_name) # Replace colors in content and create not existing in every colorscheme update_info = {} for color_value, color_name in values2colors.iteritems(): # Replace colors with django template placeholders content = content.replace("#%s;" % color_value, "{{ %s }};" % color_name) # Create new colors for colorscheme in self.iter_colorschemes(): color_dict = colorschemes_data[colorscheme] if color_name in color_dict: # This color exist in this colorscheme continue color, created = Color.objects.get_or_create( colorscheme=colorscheme, name=color_name, defaults={"value": color_value} ) color.save() if created: if colorscheme not in update_info: update_info[colorscheme] = [] update_info[colorscheme].append(color) # Create page messages for colorscheme, created_colors in update_info.iteritems(): msg = _('Colors %(colors)s created in colorscheme "%(scheme)s"') % { "colors": ", ".join(['"%s:%s"' % (c.name, c.value) for c in created_colors]), "scheme": colorscheme.name, } failsafe_message(msg) self.content = content