def check_cache(app_configs, **kwargs): """Check for sane caching""" errors = [] cache = settings.CACHES['default']['BACKEND'].split('.')[-1] if cache not in GOOD_CACHE: errors.append( Critical( 'The configured cache backend will lead to serious ' 'performance or consistency issues.', hint=get_doc_url('admin/install', 'production-cache'), id='weblate.E007', ) ) if settings.ENABLE_AVATARS and 'avatar' not in settings.CACHES: errors.append( Error( 'Please configure separate avatar caching to reduce pressure ' 'on the default cache', hint=get_doc_url('admin/install', 'production-cache-avatar'), id='weblate.E008', ) ) return errors
def get_view_description(view_cls, html=False): """ Given a view class, return a textual description to represent the view. This name is used in the browsable API, and in OPTIONS responses. This function is the default for the `VIEW_DESCRIPTION_FUNCTION` setting. """ description = view_cls.__doc__ or '' description = formatting.dedent(smart_text(description)) if hasattr(getattr(view_cls, 'serializer_class', 'None'), 'Meta'): doc_url = get_doc_url( 'api', '{0}s'.format( view_cls.serializer_class.Meta.model.__name__.lower() ) ) else: doc_url = get_doc_url('api') if html: return ( formatting.markup_description(description) + mark_safe(DOC_TEXT.format(doc_url)) ) return description
def check_settings(app_configs, **kwargs): """Check for sane settings""" errors = [] if (not settings.ADMINS or '*****@*****.**' in [x[1] for x in settings.ADMINS]): errors.append( Error( 'The site admins seem to be wrongly configured', hint=get_doc_url('admin/install', 'production-admins'), id='weblate.E011', ) ) if settings.SERVER_EMAIL in DEFAULT_MAILS: errors.append( Critical( 'The server email has default value', hint=get_doc_url('admin/install', 'production-email'), id='weblate.E012', ) ) if settings.DEFAULT_FROM_EMAIL in DEFAULT_MAILS: errors.append( Critical( 'The default from email has default value', hint=get_doc_url('admin/install', 'production-email'), id='weblate.E013', ) ) if settings.SECRET_KEY == settings_example.SECRET_KEY: errors.append( Critical( 'The cookie secret key has default value', hint=get_doc_url('admin/install', 'production-secret'), id='weblate.E014', ) ) if not settings.ALLOWED_HOSTS: errors.append( Critical( 'The allowed hosts are not configured', hint=get_doc_url('admin/install', 'production-hosts'), id='weblate.E015', ) ) return errors
def check_perms(app_configs=None, **kwargs): """Check we can write to data dir.""" errors = [] uid = os.getuid() message = 'Path {} is not writable, check your DATA_DIR settings.' for dirpath, dirnames, filenames in os.walk(settings.DATA_DIR): for name in chain(dirnames, filenames): path = os.path.join(dirpath, name) try: stat = os.lstat(path) except OSError as error: # File was removed meanwhile if error.errno == errno.ENOENT: continue raise if stat.st_uid != uid: errors.append( Critical( message.format(path), hint=get_doc_url('admin/install', 'file-permissions'), id='weblate.E002', ) ) return errors
def check_templates(app_configs, **kwargs): """Check for sane settings""" errors = [] if settings.TEMPLATES: loaders = settings.TEMPLATES[0].get( 'OPTIONS', {} ).get( 'loaders', [['']] ) else: loaders = settings.TEMPLATE_LOADERS if isinstance(loaders[0], six.string_types): loader = loaders[0] else: loader = loaders[0][0] if 'cached.Loader' not in loader: errors.append( Error( 'Configure cached template loader for better performance', hint=get_doc_url('admin/install', 'production-templates'), id='weblate.E016', ) ) return errors
def check_data_writable(app_configs=None, **kwargs): """Check we can write to data dir.""" errors = [] dirs = [ settings.DATA_DIR, data_dir('home'), data_dir('whoosh'), data_dir('ssh'), data_dir('vcs'), data_dir('memory'), data_dir('celery'), data_dir('backups'), ] message = 'Path {} is not writable, check your DATA_DIR settings.' for path in dirs: if not os.path.exists(path): os.makedirs(path) elif not os.access(path, os.W_OK): errors.append( Critical( message.format(path), hint=get_doc_url('admin/install', 'file-permissions'), id='weblate.E002', ) ) return errors
def __init__(self, *args, **kwargs): super(CheckFlagsForm, self).__init__(*args, **kwargs) self.fields['flags'].help_text = ugettext( 'Please enter a comma separated list of check flags, ' 'see <a href="{url}">documentation</a> for more details.' ).format( url=get_doc_url('admin/checks', 'custom-checks') )
def check_doc_link(docid, strict=False): while docid.count(".") > 1: docid = docid.rsplit(".", 1)[0] try: return get_doc_url(*DOC_LINKS[docid]) except KeyError: if strict: raise return None
def form_field_doc_link(context, form, field): if hasattr(form, "get_field_doc"): return { "right": False, "doc_url": get_doc_url(*form.get_field_doc(field), user=context["user"]), } return {}
def check_celery(app_configs, **kwargs): errors = [] if settings.CELERY_TASK_ALWAYS_EAGER: errors.append( Error( 'Celery is configured in the eager mode', hint=get_doc_url('admin/install', 'celery'), id='weblate.E005', ) ) else: if get_queue_length() > 50 or get_queue_length('search') > 10000: errors.append( Critical( 'The Celery tasks queue is too long, either the worker ' 'is not running or is too slow.', hint=get_doc_url('admin/install', 'celery'), id='weblate.E009', ) ) result = ping.delay() try: result.get(timeout=10, disable_sync_subtasks=False) except TimeoutError: errors.append( Critical( 'The Celery does not process tasks or is too slow ' 'in processing them.', hint=get_doc_url('admin/install', 'celery'), id='weblate.E019', ) ) except NotImplementedError: errors.append( Critical( 'The Celery is not configured to store results, ' 'CELERY_RESULT_BACKEND is probably not set.', hint=get_doc_url('admin/install', 'celery'), id='weblate.E020', ) ) return errors
def check_settings(app_configs, **kwargs): """Check for sane settings""" errors = [] if not settings.ADMINS or '*****@*****.**' in ( x[1] for x in settings.ADMINS): errors.append( Error( 'The site admins seem to be wrongly configured', hint=get_doc_url('admin/install', 'production-admins'), id='weblate.E011', )) if settings.SERVER_EMAIL in DEFAULT_MAILS: errors.append( Critical( 'The server email has default value', hint=get_doc_url('admin/install', 'production-email'), id='weblate.E012', )) if settings.DEFAULT_FROM_EMAIL in DEFAULT_MAILS: errors.append( Critical( 'The default from email has default value', hint=get_doc_url('admin/install', 'production-email'), id='weblate.E013', )) if settings.SECRET_KEY == settings_example.SECRET_KEY: errors.append( Critical( 'The cookie secret key has default value', hint=get_doc_url('admin/install', 'production-secret'), id='weblate.E014', )) if not settings.ALLOWED_HOSTS: errors.append( Critical( 'The allowed hosts are not configured', hint=get_doc_url('admin/install', 'production-hosts'), id='weblate.E015', )) return errors
def check_celery(app_configs, **kwargs): errors = [] if settings.CELERY_TASK_ALWAYS_EAGER: errors.append( Error( 'Celery is configured in the eager mode', hint=get_doc_url('admin/install', 'celery'), id='weblate.E005', ) ) else: if get_queue_length() > 50 or get_queue_length('search') > 10000: errors.append( Critical( 'The Celery tasks queue is too long, either the worker ' 'is not running or is too slow.', hint=get_doc_url('admin/install', 'celery'), id='weblate.E009', ) ) result = ping.delay() try: result.get(timeout=10, disable_sync_subtasks=False) except TimeoutError: errors.append( Critical( 'The Celery does not process tasks or is too slow ' 'in processing them.', hint=get_doc_url('admin/install', 'celery'), id='weblate.E019', ) ) except NotImplementedError: errors.append( Critical( 'The Celery is not configured to store results, ' 'CELERY_RESULT_BACKEND is probably not set.', hint=get_doc_url('admin/install', 'celery'), id='weblate.E020', ) ) return errors
def check_settings(app_configs, **kwargs): """Check for sane settings.""" errors = [] if not settings.ADMINS or "*****@*****.**" in ( x[1] for x in settings.ADMINS): errors.append( Error( "The site admins seem to be wrongly configured", hint=get_doc_url("admin/install", "production-admins"), id="weblate.E011", )) if settings.SERVER_EMAIL in DEFAULT_MAILS: errors.append( Critical( "The server email has default value", hint=get_doc_url("admin/install", "production-email"), id="weblate.E012", )) if settings.DEFAULT_FROM_EMAIL in DEFAULT_MAILS: errors.append( Critical( "The default from email has default value", hint=get_doc_url("admin/install", "production-email"), id="weblate.E013", )) if settings.SECRET_KEY == settings_example.SECRET_KEY: errors.append( Critical( "The cookie secret key has default value", hint=get_doc_url("admin/install", "production-secret"), id="weblate.E014", )) if not settings.ALLOWED_HOSTS: errors.append( Critical( "The allowed hosts are not configured", hint=get_doc_url("admin/install", "production-hosts"), id="weblate.E015", )) return errors
def check_git_backend(app_configs, **kwargs): if find_git_http_backend() is None: return [ Critical( "Failed to find git-http-backend, " "the git exporter will not work.", hint=get_doc_url("admin/optionals", "git-exporter"), id="weblate.E022", ) ] return []
def check_database(app_configs, **kwargs): errors = [] if 'sqlite' in settings.DATABASES['default']['ENGINE']: errors.append( Error( 'SQLite is not a good database backend for production use', hint=get_doc_url('admin/install', 'production-database'), id='weblate.E006', )) return errors
def check_celery(app_configs, **kwargs): errors = [] if settings.CELERY_TASK_ALWAYS_EAGER: errors.append( Error( 'Celery is configured in the eager mode', hint=get_doc_url('admin/install', 'celery'), id='weblate.E005', )) if get_queue_length() > 1000: errors.append( Error( 'Celery tasks queue is too long, is worker running?', hint=get_doc_url('admin/install', 'celery'), id='weblate.E009', )) return errors
def check_git_backend(app_configs, **kwargs): if find_git_http_backend() is None: return [ Critical( 'Failed to find git-http-backend, ' 'the git exporter will not work.', hint=get_doc_url('admin/optionals', 'git-exporter'), id='weblate.E022', ) ] return []
def check_errors(app_configs=None, **kwargs): """Check there is error collection configured.""" if hasattr(settings, 'ROLLBAR') or hasattr(settings, 'RAVEN_CONFIG'): return [] return [ Info( 'Error collection is not configured, it is highly recommended for production use', hint=get_doc_url('admin/install', 'collecting-errors'), id='weblate.I021', ) ]
def check_database(app_configs, **kwargs): errors = [] if 'sqlite' in settings.DATABASES['default']['ENGINE']: errors.append( Error( 'SQLite is not a good database backend for production use', hint=get_doc_url('admin/install', 'production-database'), id='weblate.E006', ) ) return errors
def check_link(check): url = None if check.hint and check.hint.startswith('https:'): url = check.hint elif check.id in DOC_LINKS: url = get_doc_url(*DOC_LINKS[check.id]) if url: return mark_safe( '<a href="{}">{}</a>'.format(url, _('Documentation')) ) return ''
def get_view_description(view_cls, html=False): """Given a view class, return a textual description to represent the view. This name is used in the browsable API, and in OPTIONS responses. This function is the default for the `VIEW_DESCRIPTION_FUNCTION` setting. """ description = view_cls.__doc__ or "" description = formatting.dedent(smart_str(description)) if hasattr(getattr(view_cls, "serializer_class", "None"), "Meta"): doc_url = get_doc_url( "api", "{0}s".format( view_cls.serializer_class.Meta.model.__name__.lower())) else: doc_url = get_doc_url("api") if html: return formatting.markup_description(description) + mark_safe( DOC_TEXT.format(doc_url)) return description
def check_git_backend(app_configs, **kwargs): if find_git_http_backend() is None: return [ Critical( 'Failed to find git-http-backend, ' 'the git exporter will not work.', hint=get_doc_url('admin/optionals', 'git-exporter'), id='weblate.E022', ) ] return []
def check_errors(app_configs=None, **kwargs): """Check there is error collection configured.""" if hasattr(settings, 'ROLLBAR') or hasattr(settings, 'RAVEN_CONFIG'): return [] return [ Info( 'Error collection is not configured, it is highly recommended for production use', hint=get_doc_url('admin/install', 'collecting-errors'), id='weblate.I021', ) ]
def check_link(check): url = None if check.hint and check.hint.startswith('https:'): url = check.hint elif check.id in DOC_LINKS: url = get_doc_url(*DOC_LINKS[check.id]) if url: return mark_safe( '<a href="{}">{}</a>'.format(url, _('Documentation')) ) return ''
def check_site(app_configs, **kwargs): from weblate.utils.site import get_site_domain, check_domain errors = [] if not check_domain(get_site_domain()): errors.append( Critical( 'Configure correct site domain', hint=get_doc_url('admin/install', 'production-site'), id='weblate.E017', )) return errors
def check_formats(app_configs, **kwargs): from weblate.formats.models import FILE_FORMATS message = "Failure in loading handler for {} file format: {}" return [ Warning( message.format(key, value.strip()), hint=get_doc_url("admin/install", "optional-deps"), id="weblate.W025.{}".format(key), ) for key, value in FILE_FORMATS.errors.items() ]
def check_site(app_configs, **kwargs): from weblate.utils.site import get_site_domain, check_domain errors = [] if not check_domain(get_site_domain()): errors.append( Critical( 'Configure correct site domain', hint=get_doc_url('admin/install', 'production-site'), id='weblate.E017', ) ) return errors
def check_encoding(app_configs=None, **kwargs): """Check there is encoding is utf-8.""" if sys.getfilesystemencoding() == "utf-8" and sys.getdefaultencoding( ) == "utf-8": return [] return [ Critical( "System encoding is not utf-8, processing non-ASCII strings will break", hint=get_doc_url("admin/install", "production-encoding"), id="weblate.C023", ) ]
def check_database(app_configs, **kwargs): if settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql': return [] return [ Error( 'Please migrate your database to use PostgreSQL. ' 'Support for other database backends will be dropped in Weblate 4.0 ' 'currently sheduled on April 2020.', hint=get_doc_url('admin/install', 'production-database'), id='weblate.E006', ) ]
def check_database(app_configs, **kwargs): if settings.DATABASES["default"]["ENGINE"] == "django.db.backends.postgresql": return [] return [ Error( "Please migrate your database to use PostgreSQL. " "Support for other database backends will be dropped in Weblate 4.0 " "currently sheduled on April 2020.", hint=get_doc_url("admin/install", "production-database"), id="weblate.E006", ) ]
def check_python(app_configs=None, **kwargs): """Early warning for users needing to migrate to Python 3.""" if six.PY3: return [] return [ Error( 'Please upgrade your installation to Python 3. ' 'Python 2 support will be dropped in Weblate 4.0 ' 'currently sheduled on April 2020.', hint=get_doc_url('admin/upgrade', 'py3'), id='weblate.W023', ) ]
def check_python(app_configs=None, **kwargs): """Early warning for users needing to migrate to Python 3.""" if six.PY3: return [] return [ Error( 'Please upgrade your installation to Python 3. ' 'Python 2 support will be dropped in Weblate 4.0 ' 'currently sheduled on April 2020.', hint=get_doc_url('admin/updare', 'py3'), id='weblate.W023', ) ]
def get_view_description(view_cls, html=False): """ Given a view class, return a textual description to represent the view. This name is used in the browsable API, and in OPTIONS responses. This function is the default for the `VIEW_DESCRIPTION_FUNCTION` setting. """ description = view_cls.__doc__ or '' description = formatting.dedent(smart_text(description)) if hasattr(view_cls, 'serializer_class'): doc_url = get_doc_url( 'api', '{0}s'.format( view_cls.serializer_class.Meta.model.__name__.lower())) else: doc_url = get_doc_url('api') description = '\n\n'.join((description, DOC_TEXT.format(doc_url))) if html: return formatting.markup_description(description) return description
def check_errors(app_configs=None, **kwargs): """Check there is error collection configured.""" if (hasattr(settings, "ROLLBAR") or hasattr(settings, "RAVEN_CONFIG") or settings.SENTRY_DSN): return [] return [ Info( "Error collection is not configured, " "it is highly recommended for production use", hint=get_doc_url("admin/install", "collecting-errors"), id="weblate.I021", ) ]
def check_fonts(app_configs=None, **kwargs): """Check font rendering.""" try: render_size("DejaVu Sans", Pango.Weight.NORMAL, 11, 0, "test") return [] except Exception as error: return [ Critical( "Failed to use Pango: {}".format(error), hint=get_doc_url("admin/install", "pangocairo"), id="weblate.C024", ) ]
def check_cache(app_configs, **kwargs): """Check for sane caching""" errors = [] cache = settings.CACHES['default']['BACKEND'].split('.')[-1] if cache not in GOOD_CACHE: errors.append( Error( 'Please choose better cache backend such as redis', hint=get_doc_url('admin/install', 'production-cache'), id='weblate.E007', )) if settings.ENABLE_AVATARS and 'avatar' not in settings.CACHES: errors.append( Error( 'Please configure avatar caching', hint=get_doc_url('admin/install', 'production-cache-avatar'), id='weblate.E008', )) return errors
def check_celery(app_configs, **kwargs): errors = [] if settings.CELERY_TASK_ALWAYS_EAGER: errors.append( Error( "Celery is configured in the eager mode", hint=get_doc_url("admin/install", "celery"), id="weblate.E005", )) elif settings.CELERY_BROKER_URL == "memory://": errors.append( Critical( "Celery is configured to store queue in local memory", hint=get_doc_url("admin/install", "celery"), id="weblate.E026", )) else: if is_celery_queue_long(): errors.append( Critical( "The Celery tasks queue is too long, either the worker " "is not running or is too slow.", hint=get_doc_url("admin/install", "celery"), id="weblate.E009", )) result = ping.delay() try: result.get(timeout=10, disable_sync_subtasks=False) except TimeoutError: errors.append( Critical( "The Celery does not process tasks or is too slow " "in processing them.", hint=get_doc_url("admin/install", "celery"), id="weblate.E019", )) except NotImplementedError: errors.append( Critical( "The Celery is not configured to store results, " "CELERY_RESULT_BACKEND is probably not set.", hint=get_doc_url("admin/install", "celery"), id="weblate.E020", )) heartbeat = cache.get("celery_heartbeat") loaded = cache.get("celery_loaded") now = time.time() if loaded and now - loaded > 60 and (not heartbeat or now - heartbeat > 600): errors.append( Critical( "The Celery beats scheduler is not executing periodic tasks " "in a timely manner.", hint=get_doc_url("admin/install", "celery"), id="weblate.C030", )) return errors
def check_celery(app_configs, **kwargs): errors = [] if settings.CELERY_TASK_ALWAYS_EAGER: errors.append( Error( 'Celery is configured in the eager mode', hint=get_doc_url('admin/install', 'celery'), id='weblate.E005', )) elif settings.CELERY_BROKER_URL == 'memory://': errors.append( Critical( 'Celery is configured to store queue in local memory', hint=get_doc_url('admin/install', 'celery'), id='weblate.E026', )) else: stats = get_queue_stats() if stats['celery'] > 50 or stats['search'] > 10000: errors.append( Critical( 'The Celery tasks queue is too long, either the worker ' 'is not running or is too slow.', hint=get_doc_url('admin/install', 'celery'), id='weblate.E009', )) result = ping.delay() try: result.get(timeout=10, disable_sync_subtasks=False) except TimeoutError: errors.append( Critical( 'The Celery does not process tasks or is too slow ' 'in processing them.', hint=get_doc_url('admin/install', 'celery'), id='weblate.E019', )) except NotImplementedError: errors.append( Critical( 'The Celery is not configured to store results, ' 'CELERY_RESULT_BACKEND is probably not set.', hint=get_doc_url('admin/install', 'celery'), id='weblate.E020', )) heartbeat = cache.get('celery_heartbeat') if not heartbeat or time.time() - heartbeat > 600: errors.append( Critical( 'The Celery beats scheduler is not executing periodic tasks ' 'in a timely manner.', hint=get_doc_url('admin/install', 'celery'), id='weblate.C030', )) return errors
def check_cache(app_configs, **kwargs): """Check for sane caching""" errors = [] cache = settings.CACHES['default']['BACKEND'].split('.')[-1] if cache not in GOOD_CACHE: errors.append( Critical( 'The configured cache backend will lead to serious ' 'performance or consistency issues.', hint=get_doc_url('admin/install', 'production-cache'), id='weblate.E007', )) if settings.ENABLE_AVATARS and 'avatar' not in settings.CACHES: errors.append( Error( 'Please configure separate avatar caching to reduce pressure ' 'on the default cache', hint=get_doc_url('admin/install', 'production-cache-avatar'), id='weblate.E008', )) return errors
def check_cache(app_configs, **kwargs): """Check for sane caching.""" errors = [] cache_backend = settings.CACHES["default"]["BACKEND"].split(".")[-1] if cache_backend not in GOOD_CACHE: errors.append( Critical( "The configured cache backend will lead to serious " "performance or consistency issues.", hint=get_doc_url("admin/install", "production-cache"), id="weblate.E007", )) if settings.ENABLE_AVATARS and "avatar" not in settings.CACHES: errors.append( Error( "Please configure separate avatar caching to reduce pressure " "on the default cache", hint=get_doc_url("admin/install", "production-cache-avatar"), id="weblate.E008", )) return errors
def check_requirements(app_configs, **kwargs): """Perform check on requirements and raises an exception on error.""" versions = get_versions() + get_optional_versions() errors = [] message = '{0} <{1}> is too old. Installed version {2}, required {3}.' for name, url, version, expected in versions: if check_version(version, expected): errors.append( Error( message.format(name, url, version, expected), hint=get_doc_url('admin/install', 'requirements'), id='weblate.E001', )) return errors
def check_mail_connection(app_configs, **kwargs): errors = [] try: connection = get_connection() connection.open() connection.close() except Exception as error: message = 'Can not send email ({}), please check EMAIL_* settings.' errors.append( Critical( message.format(error), hint=get_doc_url('admin/install', 'out-mail'), id='weblate.E003', )) return errors
def check_avatars(app_configs, **kwargs): from weblate.auth.models import get_anonymous from weblate.accounts.avatar import download_avatar_image if not settings.ENABLE_AVATARS: return [] try: download_avatar_image(get_anonymous(), 32) return [] except (IOError, CertificateError) as error: return [ Critical( 'Failed to download avatar: {}'.format(error), hint=get_doc_url('admin/optionals', 'avatars'), id='weblate.E018', ) ]
def perform_suggestion(unit, form, request): """Handle suggesion saving.""" if form.cleaned_data['target'][0] == '': messages.error(request, _('Your suggestion is empty!')) # Stay on same entry return False elif not request.user.has_perm('suggestion.add', unit.translation): # Need privilege to add messages.error(request, _('You don\'t have privileges to add suggestions!')) # Stay on same entry return False elif not request.user.is_authenticated: # Spam check if is_spam('\n'.join(form.cleaned_data['target']), request): messages.error(request, _('Your suggestion has been identified as spam!')) return False # Invite user to become translator if there is nobody else # and the project is accepting translations translation = unit.translation if (not translation.component.suggestion_voting or not translation.component.suggestion_autoaccept): recent_changes = Change.objects.content(True).filter( translation=translation, ).exclude(user=None) if not recent_changes.exists(): messages.info( request, _('There is currently no active translator for this ' 'translation, please consider becoming a translator ' 'as your suggestion might otherwise remain unreviewed.')) messages.info( request, mark_safe('<a href="{0}">{1}</a>'.format( escape(get_doc_url('user/translating')), escape( _('See our documentation for more information ' 'on translating using Weblate.')), ))) # Create the suggestion result = Suggestion.objects.add( unit, join_plural(form.cleaned_data['target']), request, request.user.has_perm('suggestion.vote', unit)) if not result: messages.error(request, _('Your suggestion already exists!')) return result
def check_requirements(app_configs, **kwargs): """Perform check on requirements and raises an exception on error.""" versions = get_versions() + get_optional_versions() errors = [] message = '{0} <{1}> is too old. Installed version {2}, required {3}.' for name, url, version, expected in versions: if check_version(version, expected): errors.append( Error( message.format(name, url, version, expected), hint=get_doc_url('admin/install', 'requirements'), id='weblate.E001', ) ) return errors
def check_mail_connection(app_configs, **kwargs): errors = [] try: connection = get_connection() connection.open() connection.close() except Exception as error: message = 'Can not send email ({}), please check EMAIL_* settings.' errors.append( Critical( message.format(error), hint=get_doc_url('admin/install', 'out-mail'), id='weblate.E003', ) ) return errors
def check_perms(app_configs=None, **kwargs): """Check we can write to data dir.""" errors = [] uid = os.getuid() message = 'Path {} is not writable, check your DATA_DIR settings.' for dirpath, dirnames, filenames in os.walk(settings.DATA_DIR): for name in chain(dirnames, filenames): path = os.path.join(dirpath, name) if os.lstat(path).st_uid != uid: errors.append( Critical( message.format(path), hint=get_doc_url('admin/install', 'file-permissions'), id='weblate.E002', ) ) return errors
def check_fonts(app_configs, **kwargs): """Perform check on requirements and raises an exception on error.""" errors = [] failures = set() for args in product((True, False), repeat=2): try: get_font(11, *args) except IOError as error: if error.font in failures: continue failures.add(error.font) errors.append( Error( 'Failed to load font {}: {}'.format(error.font, error), hint=get_doc_url('admin/config', 'ttf-path'), id='weblate.E004', ) ) return errors
def documentation(page, anchor=''): """Return link to Weblate documentation.""" return get_doc_url(page, anchor)
def get_doc_url(self): """Return link to documentation.""" return get_doc_url('user/checks', self.doc_id)
def render(self, name, value, attrs=None, renderer=None, **kwargs): """Render all textareas with correct plural labels.""" unit = value values = unit.get_target_plurals() lang = unit.translation.language plural = unit.translation.plural tabindex = self.attrs['tabindex'] # Need to add extra class attrs['class'] = 'translation-editor form-control' attrs['tabindex'] = tabindex attrs['lang'] = lang.code attrs['dir'] = lang.direction attrs['rows'] = 3 attrs['maxlength'] = unit.get_max_length() # Okay we have more strings ret = [] base_id = 'id_{0}'.format(unit.checksum) for idx, val in enumerate(values): # Generate ID fieldname = '{0}_{1}'.format(name, idx) fieldid = '{0}_{1}'.format(base_id, idx) attrs['id'] = fieldid attrs['tabindex'] = tabindex + idx # Render textare textarea = super(PluralTextarea, self).render( fieldname, val, attrs, renderer, **kwargs ) # Label for plural if len(values) == 1: if unit.translation.is_template: label = ugettext('Source') else: label = ugettext('Translation') else: label = plural.get_plural_label(idx) if (not unit.translation.is_template and get_language() != lang.code): label += ' <span class="badge">{}</span>'.format(lang) ret.append( EDITOR_TEMPLATE.format( self.get_toolbar(lang, fieldid, unit, idx), fieldid, label, textarea ) ) # Show plural equation for more strings if len(values) > 1: ret.append( PLURALS_TEMPLATE.format( get_doc_url('user/translating', 'plurals'), ugettext('Documentation for plurals.'), '<abbr title="{0}">{1}</abbr>: {2}'.format( ugettext( 'This equation identifies which plural form ' 'will be used based on given count (n).' ), ugettext('Plural equation'), plural.equation ) ) ) # Join output return mark_safe(''.join(ret))
def documentation_icon(page, anchor='', right=False): return { 'right': right, 'doc_url': get_doc_url(page, anchor), }