def __init__(self, vctx, location, matcher_desc): self.matcher_desc = matcher_desc validate_struct( vctx, location, matcher_desc, required_attrs=(("type", str), ("value", (int, float, str))), allowed_attrs=(("rtol", (int, float, str)), ("atol", (int, float, str))), ) try: self.matcher_desc.value = float_or_sympy_evalf(matcher_desc.value) except: raise ValidationError(string_concat("%s: 'value' ", _("does not provide a valid float literal")) % location) if hasattr(matcher_desc, "rtol"): try: self.matcher_desc.rtol = float_or_sympy_evalf(matcher_desc.rtol) except: raise ValidationError( string_concat("%s: 'rtol' ", _("does not provide a valid float literal")) % location ) if hasattr(matcher_desc, "atol"): try: self.matcher_desc.atol = float_or_sympy_evalf(matcher_desc.atol) except: raise ValidationError( string_concat("%s: 'atol' ", _("does not provide a valid float literal")) % location ) if not hasattr(matcher_desc, "atol") and not hasattr(matcher_desc, "rtol") and vctx is not None: vctx.add_warning( location, _("Float match should have either rtol or atol--" "otherwise it will match any number") )
def validate_session_access_rule(ctx, location, arule, tags): validate_struct( ctx, location, arule, required_attrs=[ ("permissions", list), ], allowed_attrs=[ ("if_after", datespec_types), ("if_before", datespec_types), ("if_has_role", list), ("if_in_facility", str), ("if_has_tag", (six.string_types, type(None))), ("if_in_progress", bool), ("if_completed_before", datespec_types), ("if_expiration_mode", str), ("if_session_duration_shorter_than_minutes", (int, float)), ("message", datespec_types), ] ) if hasattr(arule, "if_after"): ctx.encounter_datespec(location, arule.if_after) if hasattr(arule, "if_before"): ctx.encounter_datespec(location, arule.if_before) if hasattr(arule, "if_completed_before"): ctx.encounter_datespec(location, arule.if_completed_before) if hasattr(arule, "if_has_role"): for j, role in enumerate(arule.if_has_role): validate_role( "%s, role %d" % (location, j+1), role) if hasattr(arule, "if_in_facility"): validate_facility(ctx, location, arule.if_in_facility) if hasattr(arule, "if_has_tag"): if not (arule.if_has_tag is None or arule.if_has_tag in tags): raise ValidationError( string_concat( "%(location)s: ", _("invalid tag '%(tag)s'")) % {'location': location, 'tag': arule.if_has_tag}) if hasattr(arule, "if_expiration_mode"): from course.constants import FLOW_SESSION_EXPIRATION_MODE_CHOICES if arule.if_expiration_mode not in dict( FLOW_SESSION_EXPIRATION_MODE_CHOICES): raise ValidationError( string_concat("%(location)s: ", _("invalid expiration mode '%(expiremode)s'")) % { 'location': location, 'expiremode': arule.if_expiration_mode}) for j, perm in enumerate(arule.permissions): validate_flow_permission( ctx, "%s, permission %d" % (location, j+1), perm)
def __init__(self, target_state, required_roles=None, help_text=None, **kw): self.target_state = target_state assert not 'required' in kw assert not 'required_roles' in kw new_required = set(self.required_roles) if required_roles is not None: new_required |= required_roles if target_state.name: m = getattr(target_state.choicelist, 'allow_transition', None) if m is not None: raise Exception("20150621 was allow_transition still used?!") assert not 'allowed' in required_roles def allow(action, user, obj, state): return m(obj, user, target_state) new_required.update(allow=allow) kw.update(required_roles=new_required) if self.help_text is None: if help_text is None: # help_text = string_format( # _("Mark this as {0}"), target_state.text) help_text = string_concat( _("Mark this as"), ' ', target_state.text) kw.update(help_text=help_text) super(ChangeStateAction, self).__init__(**kw) #~ logger.info('20120930 ChangeStateAction %s %s', actor,target_state) if self.icon_name: self.help_text = string_concat(self.label, '. ', self.help_text)
def update_controller_field(cls, verbose_name=None, **kwargs): """Update attributes of the :attr:`owner` field and its underlying fields :attr:`owner_id` and :attr:`owner_type`. This can be used to make the controller optional (i.e. specify whether the :attr:`owner` field may be NULL). Example:: class MyModel(Controllable): .... MyModel.update_controller_field(blank=False, null=False) When `verbose_name` is specified, all three fields will be updated, appending " (object)" and " (type)" to :attr:`owner_id` and :attr:`owner_type` respectively. """ if verbose_name is not None: dd.update_field(cls, 'owner', verbose_name=verbose_name) kwargs.update( verbose_name=string_concat( verbose_name, ' ', _('(object)'))) dd.update_field(cls, 'owner_id', **kwargs) if verbose_name is not None: kwargs.update( verbose_name=string_concat( verbose_name, ' ', _('(type)'))) dd.update_field(cls, 'owner_type', **kwargs)
def get_generated_url(self, obj): gen_url = "" if '?' in obj.placement_url: str_start = '&' else: str_start = '?' gen_url = string_concat(gen_url, obj.placement_url, str_start, "utm_campaign=", obj.tactic.tactic_key, "&utm_source=", obj.source, "&utm_medium=", obj.medium, "&utm_content=", obj.placement_id) if obj.catid is not None: gen_url = string_concat(gen_url, "&catid=", obj.catid) gen_url = string_concat(gen_url, "&c3placement=", obj.placement_id) if (obj.page_id is not None and obj.page_id != "") and \ (obj.page_cat is not None and obj.page_cat != ""): gen_url = string_concat(gen_url, "&Category=", obj.page_cat, "&Page_ID=", obj.page_id) if obj.promo_uid is not None and obj.promo_uid != "": gen_url = string_concat(gen_url, "&PromoUID=", obj.promo_uid) return gen_url
def get_auto_feedback(correctness): # type: (Optional[float]) -> Text if correctness is None: return six.text_type(_("No information on correctness of answer.")) elif correctness == 0: return six.text_type(_("Your answer is not correct.")) elif correctness == 1: return six.text_type(_("Your answer is correct.")) elif correctness > 1: return six.text_type( string_concat( _("Your answer is correct and earned bonus points."), " (%.1f %%)") % (100*correctness)) elif correctness > 0.5: return six.text_type( string_concat( _("Your answer is mostly correct."), " (%.1f %%)") % (100*correctness)) else: return six.text_type( string_concat( _("Your answer is somewhat correct. "), "(%.1f%%)") % (100*correctness))
def get_matcher_class(location, matcher_type, pattern_type): for matcher_class in TEXT_ANSWER_MATCHER_CLASSES: if matcher_class.type == matcher_type: if matcher_class.pattern_type != pattern_type: raise ValidationError( string_concat( "%(location)s: ", # Translators: a "matcher" is used to determine # if the answer to text question (blank filling # question) is correct. _("%(matcherclassname)s only accepts " "'%(matchertype)s' patterns")) % { 'location': location, 'matcherclassname': matcher_class.__name__, 'matchertype': matcher_class.pattern_type}) return matcher_class raise ValidationError( string_concat( "%(location)s: ", _("unknown match type '%(matchertype)s'")) % { 'location': location, 'matchertype': matcher_type})
def _post_formfield(self, field, db_field): field.widget.attrs['data-required'] = int(field.required) if issubclass(db_field.__class__, models.ManyToManyField): msg = _('Hold down "Control", or "Command" on a Mac, to select ' 'more than one.') msg = unicode(string_concat(' ', msg)) if field.help_text.endswith(msg): field.help_text = field.help_text[:-len(msg)] if (isinstance(field, forms.ChoiceField) and hasattr(field, 'queryset')): model = field.queryset.model if isinstance(field, forms.MultipleChoiceField): msg = string_concat(_("Choose some "), model._meta.verbose_name_plural, "...") else: msg = string_concat(_("Choose a "), model._meta.verbose_name, "...") field.widget.attrs['data-placeholder'] = msg for riff in self.riff.base_riff.riffs: if getattr(riff, 'model', None) == model: if riff.has_add_permission(self.request): field.widget = AddWrapper(field.widget, riff) break return field
def add_buttons_to_form(form, fpctx, flow_session, permissions): from crispy_forms.layout import Submit form.helper.add_input(Submit("save", _("Save answer"), css_class="col-lg-offset-2 relate-save-button")) if will_receive_feedback(permissions): if flow_permission.change_answer in permissions: form.helper.add_input( Submit("submit", _("Submit answer for grading"), accesskey="g", css_class="relate-save-button") ) else: form.helper.add_input(Submit("submit", _("Submit final answer"), css_class="relate-save-button")) else: # Only offer 'save and move on' if student will receive no feedback if fpctx.page_data.ordinal + 1 < flow_session.page_count: form.helper.add_input( Submit( "save_and_next", mark_safe_lazy(string_concat(_("Save answer and move on"), " »")), css_class="relate-save-button", ) ) else: form.helper.add_input( Submit( "save_and_finish", mark_safe_lazy(string_concat(_("Save answer and finish"), " »")), css_class="relate-save-button", ) ) return form
def __init__(self, vctx, location, page_desc): super(ChoiceQuestion, self).__init__(vctx, location, page_desc) correct_choice_count = 0 for choice_idx, choice in enumerate(page_desc.choices): try: choice = str(choice) except: raise ValidationError( string_concat( "%(location)s, ", _("choice %(idx)d: unable to convert to string") ) % {'location': location, 'idx': choice_idx+1}) if choice.startswith(self.CORRECT_TAG): correct_choice_count += 1 if vctx is not None: validate_markup(vctx, location, remove_prefix(self.CORRECT_TAG, choice)) if correct_choice_count < 1: raise ValidationError( string_concat( "%(location)s: ", "one or more correct answer(s) " "expected, %(n_correct)d found") % { 'location': location, 'n_correct': correct_choice_count})
def render(self, name, value, attrs=None): if attrs is None: attrs = {} attrs["class"] = "vTextField nullable_text" attrs["onchange"] = "NullableText.input_event(this)" checked = "" if value is None: checked = ' checked="checked"' checkbox = format_html("") widget_name = "id_" + name + "_isnull" if self.isnull: checkbox = string_concat( ' <input type="checkbox" onchange="NullableText.null_event(this)" name="', widget_name, '" id="', widget_name, '" value="1"', checked, '><label class="vCheckboxLabel" for="', widget_name, '">', _("Not specified"), "</label>", ) return mark_safe(string_concat(super(TextInput, self).render(name, value, attrs), checkbox))
def __init__(self, vctx, location, page_desc): super(MultipleChoiceQuestion, self).__init__(vctx, location, page_desc) pd = self.page_desc if hasattr(pd, "credit_mode"): credit_mode = pd.credit_mode if ( hasattr(pd, "allow_partial_credit") or hasattr(pd, "allow_partial_credit_subset_only")): raise ValidationError( string_concat( "%(location)s: ", _("'allow_partial_credit' or " "'allow_partial_credit_subset_only' may not be specified" "at the same time as 'credit_mode'")) % {'location': location}) else: partial = getattr(pd, "allow_partial_credit", False) partial_subset = getattr(pd, "allow_partial_credit_subset_only", False) if not partial and not partial_subset: credit_mode = "exact" elif partial and not partial_subset: credit_mode = "proportional" elif not partial and partial_subset: credit_mode = "proportional_correct" elif partial and partial_subset: raise ValidationError( string_concat( "%(location)s: ", _("'allow_partial_credit' and " "'allow_partial_credit_subset_only' are not allowed to " "coexist when both attribute are 'True'")) % {'location': location}) else: assert False if credit_mode not in [ "exact", "proportional", "proportional_correct"]: raise ValidationError( string_concat( "%(location)s: ", _("unrecognized credit_mode '%(credit_mode)s'")) % {'location': location, "credit_mode": credit_mode}) if vctx is not None and not hasattr(pd, "credit_mode"): vctx.add_warning(location, _("'credit_mode' will be required on multi-select choice " "questions in a future version. set " "'credit_mode: {}' to match current behavior.") .format(credit_mode)) self.credit_mode = credit_mode
def load_choices(codes): _State_Division_Choices = [] _District_Choices = [] _Township_or_town_Choices = [] _Sub_code_No_Choices = [(ANY_HOSPITAL_CODE, string_concat(_(u"1"), CODE_DELIMITER, _(u"Any hospital")))] for state_division_list in codes: _State_Division_Choices.append(choice_from_tuple(state_division_list[0])) _District_Choices.append((label_from_tuple(state_division_list[0]), [])) for districts in state_division_list[1]: _District_Choices[-1][-1].append(choice_from_tuple(districts[0])) _Township_or_town_Choices.append((label_from_tuple(districts[0]), [])) for township_or_town in districts[1]: _Township_or_town_Choices[-1][-1].append(choice_from_three_tuple(township_or_town)) if len(township_or_town) > 3: hospitals = [choice_from_tuple(hospital, True) for hospital in township_or_town[3:]] if not isinstance(hospitals, list): hospitals = [hospitals] _Sub_code_No_Choices.append( ( label_from_three_tuple(township_or_town), hospitals ) ) _Sub_code_No_Choices.append((YANGON_HOSPITAL_NOT_MENTIONED_CODE, string_concat(_(u"99"), CODE_DELIMITER, _(u"Not mentioned")))) return _State_Division_Choices, _District_Choices, _Township_or_town_Choices, _Sub_code_No_Choices
def __init__(self, vctx, location, page_desc): super(TextQuestion, self).__init__(vctx, location, page_desc) if len(page_desc.answers) == 0: raise ValidationError( string_concat( "%s: ", _("at least one answer must be provided")) % location) self.matchers = [ parse_matcher( vctx, "%s, answer %d" % (location, i+1), answer) for i, answer in enumerate(page_desc.answers)] if not any(matcher.correct_answer_text() is not None for matcher in self.matchers): raise ValidationError( string_concat( "%s: ", _("no matcher is able to provide a plain-text " "correct answer")) % location)
def contribute_to_class(self, cls, name): cls._meta = self # First, construct the default values for these options. self.object_name = cls.__name__ self.module_name = self.object_name.lower() self.verbose_name = get_verbose_name(self.object_name) self.resource_path = self.module_name # Next, apply any overridden values from 'class Meta'. if self.meta: meta_attrs = self.meta.__dict__.copy() for name in self.meta.__dict__: # Ignore any private attributes that Django doesn't care about. # NOTE: We can't modify a dictionary's contents while looping # over it, so we loop over the *original* dictionary instead. if name.startswith('_'): del meta_attrs[name] for attr_name in DEFAULT_NAMES: if attr_name in meta_attrs: setattr(self, attr_name, meta_attrs.pop(attr_name)) elif hasattr(self.meta, attr_name): setattr(self, attr_name, getattr(self.meta, attr_name)) # verbose_name_plural is a special case because it uses a 's' # by default. setattr(self, 'verbose_name_plural', meta_attrs.pop('verbose_name_plural', string_concat(self.verbose_name, 's'))) # Any leftover attributes must be invalid. if meta_attrs != {}: raise TypeError("'class Meta' got invalid attribute(s): %s" % ','.join(meta_attrs.keys())) else: self.verbose_name_plural = string_concat(self.verbose_name, 's') del self.meta
def clean(self, value): #todo: this field must be adapted to work with Chinese, etc. #for that we'll have to count characters instead of words if value is None: value = '' value = value.strip() word_count = len(value.split()) if word_count < self.min_words: msg = ungettext_lazy( 'must be > %d word', 'must be > %d words', self.min_words - 1 ) % (self.min_words - 1) #todo - space is not used in Chinese raise forms.ValidationError( string_concat(self.field_name, ' ', msg) ) if word_count > self.max_words: msg = ungettext_lazy( 'must be < %d word', 'must be < %d words', self.max_words + 1 ) % (self.max_words + 1) raise forms.ValidationError( string_concat(self.field_name, ' ', msg) ) return value
def validate_flow_page(vctx, location, page_desc): if not hasattr(page_desc, "id"): raise ValidationError( string_concat( "%s: ", ugettext("flow page has no ID")) % location) validate_identifier(vctx, location, page_desc.id) from course.content import get_flow_page_class try: class_ = get_flow_page_class(vctx.repo, page_desc.type, vctx.commit_sha) class_(vctx, location, page_desc) except ValidationError: raise except: tp, e, __ = sys.exc_info() from traceback import format_exc raise ValidationError( string_concat( "%(location)s: ", _("could not instantiate flow page"), ": %(err_type)s: " "%(err_str)s<br><pre>%(format_exc)s</pre>") % { 'location': location, "err_type": tp.__name__, "err_str": str(e), 'format_exc': format_exc()})
def bounce_email(email, subject, reason=None, body_text=None): """sends a bounce email at address ``email``, with the subject line ``subject``, accepts several reasons for the bounce: * ``'problem_posting'``, ``unknown_user`` and ``permission_denied`` * ``body_text`` in an optional parameter that allows to append extra text to the message """ if reason == "problem_posting": error_message = _( "<p>Sorry, there was an error posting your question " "please contact the %(site)s administrator</p>" ) % {"site": askbot_settings.APP_SHORT_NAME} error_message = string_concat(error_message, USAGE) elif reason == "unknown_user": error_message = _( "<p>Sorry, in order to post questions on %(site)s " 'by email, please <a href="%(url)s">register first</a></p>' ) % {"site": askbot_settings.APP_SHORT_NAME, "url": url_utils.get_login_url()} elif reason == "permission_denied": error_message = _( "<p>Sorry, your question could not be posted " "due to insufficient privileges of your user account</p>" ) else: raise ValueError('unknown reason to bounce an email: "%s"' % reason) if body_text != None: error_message = string_concat(error_message, body_text) # print 'sending email' # print email # print subject # print error_message mail.send_mail(recipient_list=(email,), subject_line="Re: " + subject, body_text=error_message)
def contribute_to_class(self, cls, name): from django.db import connection from django.db.backends.util import truncate_name self.cls = cls cls._meta = self self.installed = re.sub('\.models$', '', cls.__module__) in settings.INSTALLED_APPS # First, construct the default values for these options. self.object_name = cls.__name__ self.module_name = self.object_name.lower() self._verbose_name = CAMEL_CASE_RE.sub(' \\1', self.object_name).lower().strip() # Next, apply any overridden values from 'class Meta'. if self.meta: meta_attrs = self.meta.__dict__.copy() for name in self.meta.__dict__: # Ignore any private attributes that Django doesn't care about. # NOTE: We can't modify a dictionary's contents while looping # over it, so we loop over the *original* dictionary instead. if name.startswith('_'): del meta_attrs[name] for attr_name in DEFAULT_NAMES: if attr_name in meta_attrs: setattr(self, attr_name, meta_attrs.pop(attr_name)) elif hasattr(self.meta, attr_name): setattr(self, attr_name, getattr(self.meta, attr_name)) for attr_name in DEPRECATED_NAMES: if attr_name in meta_attrs: warnings.warn("%(cls)s: Meta.%(attr_name)s is deprecated. Use a " "verbose_names() classmethod in the model " "instead." % {'cls': cls, 'attr_name': attr_name}, PendingDeprecationWarning) setattr(self, '_%s' % attr_name, meta_attrs.pop(attr_name)) # unique_together can be either a tuple of tuples, or a single # tuple of two strings. Normalize it to a tuple of tuples, so that # calling code can uniformly expect that. ut = meta_attrs.pop('unique_together', self.unique_together) if ut and not isinstance(ut[0], (tuple, list)): ut = (ut,) self.unique_together = ut # verbose_name_plural is a special case because it uses a 's' # by default. if self._verbose_name_plural is None: self._verbose_name_plural = string_concat(self._verbose_name, 's') # Any leftover attributes must be invalid. if meta_attrs != {}: raise TypeError("'class Meta' got invalid attribute(s): %s" % ','.join(meta_attrs.keys())) else: self._verbose_name_plural = string_concat(self._verbose_name, 's') del self.meta # If the db_table wasn't provided, use the app_label + module_name. if not self.db_table: self.db_table = "%s_%s" % (self.app_label, self.module_name) self.db_table = truncate_name(self.db_table, connection.ops.max_name_length())
def parse_validator(vctx, location, validator_desc): if not isinstance(validator_desc, Struct): raise ValidationError(string_concat("%s: ", _("must be struct or string")) % location) if not hasattr(validator_desc, "type"): raise ValidationError(string_concat("%s: ", "matcher must supply 'type'") % location) return get_validator_class(location, validator_desc.type)(vctx, location, validator_desc)
def contribute_to_class(self, cls, name, installed_apps={}): from django.db import connection from django.db.backends.util import truncate_name cls._meta = self self.model = cls self.installed = re.sub("\.models$", "", cls.__module__) in installed_apps # First, construct the default values for these options. self.object_name = cls.__name__ self.model_name = self.object_name.lower() self.verbose_name = get_verbose_name(self.object_name) # Store the original user-defined values for each option, # for use when serializing the model definition self.original_attrs = {} # Next, apply any overridden values from 'class Meta'. if self.meta: meta_attrs = self.meta.__dict__.copy() for name in self.meta.__dict__: # Ignore any private attributes that Django doesn't care about. # NOTE: We can't modify a dictionary's contents while looping # over it, so we loop over the *original* dictionary instead. if name.startswith("_"): del meta_attrs[name] for attr_name in DEFAULT_NAMES: if attr_name in meta_attrs: setattr(self, attr_name, meta_attrs.pop(attr_name)) self.original_attrs[attr_name] = getattr(self, attr_name) elif hasattr(self.meta, attr_name): setattr(self, attr_name, getattr(self.meta, attr_name)) self.original_attrs[attr_name] = getattr(self, attr_name) # unique_together can be either a tuple of tuples, or a single # tuple of two strings. Normalize it to a tuple of tuples, so that # calling code can uniformly expect that. ut = meta_attrs.pop("unique_together", self.unique_together) if ut and not isinstance(ut[0], (tuple, list)): ut = (ut,) self.unique_together = ut # verbose_name_plural is a special case because it uses a 's' # by default. if self.verbose_name_plural is None: self.verbose_name_plural = string_concat(self.verbose_name, "s") # Any leftover attributes must be invalid. if meta_attrs != {}: raise TypeError("'class Meta' got invalid attribute(s): %s" % ",".join(meta_attrs.keys())) else: self.verbose_name_plural = string_concat(self.verbose_name, "s") del self.meta # If the db_table wasn't provided, use the app_label + model_name. if not self.db_table: self.db_table = "%s_%s" % (self.app_label, self.model_name) self.db_table = truncate_name(self.db_table, connection.ops.max_name_length())
def __init__(self, vctx, location, name, answers_desc): super(ChoicesAnswer, self).__init__( vctx, location, name, answers_desc) validate_struct( vctx, location, answers_desc, required_attrs=( ("type", str), ("choices", list) ), allowed_attrs=( ("weight", (int, float)), ("hint", str), ("hint_title", str), ("required", bool), ), ) self.weight = getattr(answers_desc, "weight", 0) correct_choice_count = 0 for choice_idx, choice in enumerate(answers_desc.choices): try: choice = str(choice) except: raise ValidationError( string_concat( "%(location)s: '%(answer_name)s' ", _("choice %(idx)d: unable to convert to string") ) % {'location': location, 'answer_name': self.name, 'idx': choice_idx+1}) if choice.startswith(self.CORRECT_TAG): correct_choice_count += 1 if vctx is not None: validate_markup(vctx, location, remove_prefix(self.CORRECT_TAG, choice)) if correct_choice_count < 1: raise ValidationError( string_concat( "%(location)s: ", _("one or more correct answer(s) expected " " for question '%(question_name)s', " "%(n_correct)d found")) % { 'location': location, 'question_name': self.name, 'n_correct': correct_choice_count}) self.hint = getattr(self.answers_desc, "hint", "") self.width = 0
def create_recurring_events(pctx): if not pctx.has_permission(pperm.edit_events): raise PermissionDenied(_("may not edit events")) request = pctx.request if request.method == "POST": form = RecurringEventForm(request.POST, request.FILES) if form.is_valid(): if form.cleaned_data["starting_ordinal"] is not None: starting_ordinal = form.cleaned_data["starting_ordinal"] starting_ordinal_specified = True else: starting_ordinal = 1 starting_ordinal_specified = False while True: try: _create_recurring_events_backend( course=pctx.course, time=form.cleaned_data["time"], kind=form.cleaned_data["kind"], starting_ordinal=starting_ordinal, interval=form.cleaned_data["interval"], count=form.cleaned_data["count"], duration_in_minutes=(form.cleaned_data["duration_in_minutes"]), ) except EventAlreadyExists as e: if starting_ordinal_specified: messages.add_message( request, messages.ERROR, string_concat("%(err_type)s: %(err_str)s. ", _("No events created.")) % {"err_type": type(e).__name__, "err_str": str(e)}, ) else: starting_ordinal += 10 continue except Exception as e: messages.add_message( request, messages.ERROR, string_concat("%(err_type)s: %(err_str)s. ", _("No events created.")) % {"err_type": type(e).__name__, "err_str": str(e)}, ) else: messages.add_message(request, messages.SUCCESS, _("Events created.")) break else: form = RecurringEventForm() return render_course_page( pctx, "course/generic-course-form.html", {"form": form, "form_description": _("Create recurring events")} )
def __init__(self, model, bases): try: self.app_label = model.__module__.split(".")[-2] except IndexError: raise ValueError( "Django expects models (here: %s.%s) to be defined in their own apps!" % (model.__module__, model.__name__) ) self.parents = [b for b in bases if issubclass(b, db.Model)] self.object_name = model.__name__ self.module_name = self.object_name.lower() self.verbose_name = get_verbose_name(self.object_name) self.ordering = () self.abstract = model is db.Model self.model = model self.unique_together = () self.installed = model.__module__.rsplit(".", 1)[0] in settings.INSTALLED_APPS self.permissions = [] meta = model.__dict__.get("Meta") if meta: meta_attrs = meta.__dict__.copy() for name in meta.__dict__: # Ignore any private attributes that Django doesn't care about. # NOTE: We can't modify a dictionary's contents while looping # over it, so we loop over the *original* dictionary instead. if name.startswith("_"): del meta_attrs[name] for attr_name in DEFAULT_NAMES: if attr_name in meta_attrs: setattr(self, attr_name, meta_attrs.pop(attr_name)) elif hasattr(meta, attr_name): setattr(self, attr_name, getattr(meta, attr_name)) # verbose_name_plural is a special case because it uses a 's' # by default. setattr( self, "verbose_name_plural", meta_attrs.pop("verbose_name_plural", string_concat(self.verbose_name, "s")), ) # Any leftover attributes must be invalid. if meta_attrs != {}: raise TypeError, "'class Meta' got invalid attribute(s): %s" % ",".join(meta_attrs.keys()) else: self.verbose_name_plural = self.verbose_name + "s" if not self.abstract: self.permissions.extend( [ ("add_%s" % self.object_name.lower(), string_concat("Can add ", self.verbose_name)), ("change_%s" % self.object_name.lower(), string_concat("Can change ", self.verbose_name)), ("delete_%s" % self.object_name.lower(), string_concat("Can delete ", self.verbose_name)), ] )
def bounce_email(email, subject, reason=None, body_text=None, reply_to=None): """sends a bounce email at address ``email``, with the subject line ``subject``, accepts several reasons for the bounce: * ``'problem_posting'``, ``unknown_user`` and ``permission_denied`` * ``body_text`` in an optional parameter that allows to append extra text to the message """ if reason == "problem_posting": error_message = _( "<p>Sorry, there was an error posting your question " "please contact the %(site)s administrator</p>" ) % {"site": askbot_settings.APP_SHORT_NAME} if askbot_settings.TAGS_ARE_REQUIRED: error_message = string_concat( INSTRUCTIONS_PREAMBLE, "<ul>", QUESTION_TITLE_INSTRUCTION, REQUIRED_TAGS_INSTRUCTION, QUESTION_DETAILS_INSTRUCTION, "</ul>", TAGS_INSTRUCTION_FOOTNOTE, ) else: error_message = string_concat( INSTRUCTIONS_PREAMBLE, "<ul>", QUESTION_TITLE_INSTRUCTION, QUESTION_DETAILS_INSTRUCTION, OPTIONAL_TAGS_INSTRUCTION, "</ul>", TAGS_INSTRUCTION_FOOTNOTE, ) elif reason == "unknown_user": error_message = _( "<p>Sorry, in order to post questions on %(site)s " 'by email, please <a href="%(url)s">register first</a></p>' ) % {"site": askbot_settings.APP_SHORT_NAME, "url": url_utils.get_login_url()} elif reason == "permission_denied" and body_text is None: error_message = _( "<p>Sorry, your question could not be posted " "due to insufficient privileges of your user account</p>" ) elif body_text: error_message = body_text else: raise ValueError('unknown reason to bounce an email: "%s"' % reason) # print 'sending email' # print email # print subject # print error_message headers = {} if reply_to: headers["Reply-To"] = reply_to send_mail(recipient_list=(email,), subject_line="Re: " + subject, body_text=error_message, headers=headers)
def handle_uploaded_file2(f,g,h,i,s): s1 = string_concat(s,".wav") destination = open('/home/mayank/Desktop/bep/bep/bep_users/static/story_audio/'+unicode(s1), 'wb+') for chunk in g.chunks(): destination.write(chunk) destination.close() s1 = string_concat(s,".wav") b = audio_story(title=i,date_submission=datetime.now(),user_submit=h,file_name=unicode(s1)) b.save();
def algorithm(self): if self.choice == DISCOUNT_NOREFUND: return string_concat(_('No refund tariff'), self.quantities) elif self.choice == DISCOUNT_EARLY: return string_concat(_('Booking, earlier than %s day(days) before arrival') % self.days, self.quantities) elif self.choice == DISCOUNT_LATER: return string_concat(_('Booking, later than %s day(days) before arrival') % self.days, self.quantities) elif self.choice == DISCOUNT_PERIOD: return string_concat(_('Booking at least %s day(days)') % self.days, self.quantities) elif self.choice == DISCOUNT_PACKAGE: return _('Package: booking %(days)s day(days) at price of %(price_days)s day(days)') % \ dict(days=self.days, price_days=self.at_price_days) elif self.choice == DISCOUNT_HOLIDAY: return string_concat(_('Booking in holidays/weekend'), self.quantities) elif self.choice == DISCOUNT_SPECIAL: return string_concat(_('Special discount'), self.quantities) elif self.choice == DISCOUNT_LAST_MINUTE: return string_concat(_('Booking after standard arrival time, over the time %(time_from)s - %(time_to)s') % dict(time_from=date(self.time_on, 'H:i'), time_to=date(self.time_off, 'H:i')), self.quantities) elif self.choice == DISCOUNT_CREDITCARD: return string_concat(_('Booking with creditcard'), self.quantities) elif self.choice == DISCOUNT_NORMAL: return string_concat(_('Simple discount'), self.quantities) else: return None
def parse_matcher(vctx, location, matcher_desc): if isinstance(matcher_desc, six.string_types): return parse_matcher_string(vctx, location, matcher_desc) else: if not isinstance(matcher_desc, Struct): raise ValidationError(string_concat("%s: ", _("must be struct or string")) % location) if not hasattr(matcher_desc, "type"): raise ValidationError(string_concat("%s: ", _("matcher must supply 'type'")) % location) return get_matcher_class(location, matcher_desc.type, "struct")(vctx, location, matcher_desc)
def contribute_to_class(self, cls, name): from django.db import connection from django.db.backends.utils import truncate_name cls._meta = self self.model = cls # First, construct the default values for these options. self.object_name = cls.__name__ self.model_name = self.object_name.lower() self.verbose_name = camel_case_to_spaces(self.object_name) # Store the original user-defined values for each option, # for use when serializing the model definition self.original_attrs = {} # Next, apply any overridden values from 'class Meta'. if self.meta: meta_attrs = self.meta.__dict__.copy() for name in self.meta.__dict__: # Ignore any private attributes that Django doesn't care about. # NOTE: We can't modify a dictionary's contents while looping # over it, so we loop over the *original* dictionary instead. if name.startswith('_'): del meta_attrs[name] for attr_name in DEFAULT_NAMES: if attr_name in meta_attrs: setattr(self, attr_name, meta_attrs.pop(attr_name)) self.original_attrs[attr_name] = getattr(self, attr_name) elif hasattr(self.meta, attr_name): setattr(self, attr_name, getattr(self.meta, attr_name)) self.original_attrs[attr_name] = getattr(self, attr_name) ut = meta_attrs.pop('unique_together', self.unique_together) self.unique_together = normalize_together(ut) it = meta_attrs.pop('index_together', self.index_together) self.index_together = normalize_together(it) # verbose_name_plural is a special case because it uses a 's' # by default. if self.verbose_name_plural is None: self.verbose_name_plural = string_concat(self.verbose_name, 's') # Any leftover attributes must be invalid. if meta_attrs != {}: raise TypeError("'class Meta' got invalid attribute(s): %s" % ','.join(meta_attrs.keys())) else: self.verbose_name_plural = string_concat(self.verbose_name, 's') del self.meta # If the db_table wasn't provided, use the app_label + model_name. if not self.db_table: self.db_table = "%s_%s" % (self.app_label, self.model_name) self.db_table = truncate_name(self.db_table, connection.ops.max_name_length())
def validate_flow_group(vctx, location, grp): validate_struct( vctx, location, grp, required_attrs=[ ("id", str), ("pages", list), ], allowed_attrs=[ ("shuffle", bool), ("max_page_count", int), ] ) for i, page_desc in enumerate(grp.pages): validate_flow_page( vctx, "%s, page %d ('%s')" % (location, i+1, getattr(page_desc, "id", None)), page_desc) if len(grp.pages) == 0: raise ValidationError( string_concat( "%(location)s, ", _("group '%(group_id)s': group is empty")) % {'location': location, 'group_id': grp.id}) if hasattr(grp, "max_page_count") and grp.max_page_count <= 0: raise ValidationError( string_concat( "%(location)s, ", _("group '%(group_id)s': " "max_page_count is not positive")) % {'location': location, 'group_id': grp.id}) # {{{ check page id uniqueness page_ids = set() for page_desc in grp.pages: if page_desc.id in page_ids: raise ValidationError( string_concat( "%(location)s: ", _("page id '%(page_desc_id)s' not unique")) % {'location': location, 'page_desc_id': page_desc.id}) page_ids.add(page_desc.id) # }}} validate_identifier(vctx, location, grp.id)
def choice_from_three_tuple(state_division): return state_division[0], string_concat("%02d" % state_division[1], CODE_DELIMITER, state_division[2])
def label_from_three_tuple(state_division_list): return string_concat("%02d" % state_division_list[1], CODE_DELIMITER, state_division_list[2])
def enroll_view(request, course_identifier): # type: (http.HttpRequest, str) -> http.HttpResponse course = get_object_or_404(Course, identifier=course_identifier) participation = get_participation_for_request(request, course) if participation is not None: messages.add_message(request, messages.ERROR, _("Already enrolled. Cannot re-renroll.")) return redirect("relate-course_page", course_identifier) if not course.accepts_enrollment: messages.add_message(request, messages.ERROR, _("Course is not accepting enrollments.")) return redirect("relate-course_page", course_identifier) if request.method != "POST": # This can happen if someone tries to refresh the page, or switches to # desktop view on mobile. messages.add_message(request, messages.ERROR, _("Can only enroll using POST request")) return redirect("relate-course_page", course_identifier) user = request.user if (course.enrollment_required_email_suffix and user.status != user_status.active): messages.add_message( request, messages.ERROR, _("Your email address is not yet confirmed. " "Confirm your email to continue.")) return redirect("relate-course_page", course_identifier) preapproval = None if request.user.email: try: preapproval = ParticipationPreapproval.objects.get( course=course, email__iexact=request.user.email) except ParticipationPreapproval.DoesNotExist: if user.institutional_id: if not (course.preapproval_require_verified_inst_id and not user.institutional_id_verified): try: preapproval = ParticipationPreapproval.objects.get( course=course, institutional_id__iexact=user.institutional_id) except ParticipationPreapproval.DoesNotExist: pass pass if (preapproval is None and course.enrollment_required_email_suffix and not user.email.endswith(course.enrollment_required_email_suffix)): messages.add_message( request, messages.ERROR, _("Enrollment not allowed. Please use your '%s' email to " "enroll.") % course.enrollment_required_email_suffix) return redirect("relate-course_page", course_identifier) roles = ParticipationRole.objects.filter( course=course, is_default_for_new_participants=True) if preapproval is not None: roles = list(preapproval.roles.all()) try: if course.enrollment_approval_required and preapproval is None: participation = handle_enrollment_request( course, user, participation_status.requested, roles, request) with translation.override(settings.RELATE_ADMIN_EMAIL_LOCALE): from django.template.loader import render_to_string message = render_to_string( "course/enrollment-request-email.txt", { "user": user, "course": course, "admin_uri": mark_safe( request.build_absolute_uri( reverse("relate-edit_participation", args=(course.identifier, participation.id)))) }) from django.core.mail import EmailMessage msg = EmailMessage( string_concat("[%s] ", _("New enrollment request")) % course_identifier, message, settings.ROBOT_EMAIL_FROM, [course.notify_email]) from relate.utils import get_outbound_mail_connection msg.connection = get_outbound_mail_connection("robot") msg.send() messages.add_message( request, messages.INFO, _("Enrollment request sent. You will receive notifcation " "by email once your request has been acted upon.")) else: handle_enrollment_request(course, user, participation_status.active, roles, request) messages.add_message(request, messages.SUCCESS, _("Successfully enrolled.")) except IntegrityError: messages.add_message( request, messages.ERROR, _("A participation already exists. Enrollment attempt aborted.")) return redirect("relate-course_page", course_identifier)
from django.utils.crypto import get_random_string from django.http import HttpResponseBadRequest from django.contrib.auth import authenticate, login from oauth2client.client import OAuth2WebServerFlow logger = logging.getLogger(__name__) flow = OAuth2WebServerFlow( client_id=settings.CLIENT_ID, client_secret=settings.CLIENT_SECRET, scope=settings.DEFAULT_SCOPE, auth_uri=settings.AUTHORIZATION_URL, token_uri=settings.ACCESS_TOKEN_URL, # routes are not yet known when views are initialized: that's why reverse_lazy and string_concat are used redirect_uri=string_concat(settings.REDIRECT_BASE.rstrip('/'), reverse_lazy('accounts:oauth_callback'))) class RedirectToAuthProvider(RedirectView): http_method_names = ['get'] def get_redirect_url(self, *args, **kwargs): # generate random nonce to protect against CSRF state_nonce = get_random_string(32) # the nonce is saved inside the session self.request.session['oauth2_nonce'] = state_nonce # the user is then redirected to the auth provider with the right parameters return flow.step1_get_authorize_url(state=state_nonce)
except Exception, e: return HttpResponseBadRequest( string_concat(['<error>', _(e), '</error>'])) for received_concept in received_data: concept = None try: concept = Concept.objects.get(concept=concept_name) concept.adaptor = received_concept['adaptor'] concept.save() except Concept.DoesNotExist: return HttpResponseBadRequest( string_concat([ '<error>', _(u"Concept doesn't exist. You must use POST HTTP method in this case" ), '</error>' ])) cname = ConceptName(name=received_concept['name'], concept=concept) cname.save() return HttpResponse('ok') @transaction.commit_on_success def delete(self, request, user_name, concept_name): user = user_authentication(user_name) concept = get_object_or_404(Concept, concept=concept_name) ConceptName.objects.filter(concept=concept).delete() concept.delete() return HttpResponse('ok')
def verbose_name(self): vn = super().verbose_name vn = string_concat(vn, ' ', _('Externo ao SAPL')) return vn
def validate_flow_desc(ctx, location, flow_desc): validate_struct(ctx, location, flow_desc, required_attrs=[ ("title", str), ("description", "markup"), ], allowed_attrs=[ ("completion_text", "markup"), ("rules", Struct), ("groups", list), ("pages", list), ]) if hasattr(flow_desc, "rules"): validate_flow_rules(ctx, location, flow_desc.rules) # {{{ check for presence of 'groups' or 'pages' if ((not hasattr(flow_desc, "groups") and not hasattr(flow_desc, "pages")) or (hasattr(flow_desc, "groups") and hasattr(flow_desc, "pages"))): raise ValidationError( string_concat("%(location)s: ", _("must have either 'groups' or 'pages'")) % {'location': location}) # }}} if hasattr(flow_desc, "pages"): from course.content import normalize_flow_desc flow_desc = normalize_flow_desc(flow_desc) assert not hasattr(flow_desc, "pages") assert hasattr(flow_desc, "groups") # {{{ check for non-emptiness flow_has_page = False for i, grp in enumerate(flow_desc.groups): group_has_page = False for page in grp.pages: group_has_page = flow_has_page = True break if not group_has_page: raise ValidationError( string_concat( "%(location)s, ", _("group %(group_index)d ('%(group_id)d'): " "no pages found")) % { 'location': location, 'group_index': i + 1, 'group_id': grp.id }) if not flow_has_page: raise ValidationError(_("%s: no pages found") % location) # }}} # {{{ check group id uniqueness group_ids = set() for grp in flow_desc.groups: if grp.id in group_ids: raise ValidationError( string_concat("%(location)s: ", _("group id '%(group_id)s' not unique")) % { 'location': location, 'group_id': grp.id }) group_ids.add(grp.id) # }}} for i, grp in enumerate(flow_desc.groups): validate_flow_group(ctx, "%s, group %d ('%s')" % (location, i + 1, grp.id), grp) validate_markup(ctx, location, flow_desc.description) if hasattr(flow_desc, "completion_text"): validate_markup(ctx, location, flow_desc.completion_text)
def concat_messages(message1, message2): if message1: message = string_concat(message1, ', ') return string_concat(message, message2) else: return message2
'MEDIAWIKI_SITE_ICON', default='/images/jquery-openid/mediawiki.png', description=_('MediaWiki login button image'), url_resolver=skin_utils.get_media_url)) settings.register( livesettings.BooleanValue( LOGIN_PROVIDERS, 'MEDIAWIKI_ONE_CLICK_REGISTRATION_ENABLED', default=False, description=_('MediaWiki - enable one click registration'), help_text=string_concat( _('Allows skipping the registration page after the wiki authentication.' ), ' ', settings.get_related_settings_info( ('EMAIL', 'BLANK_EMAIL_ALLOWED', True, _('Must be enabled')), ('ACCESS_CONTROL', 'REQUIRE_VALID_EMAIL_FOR', True, _('Must be not be required')), )), )) if provider == 'local': #add Google settings here as one-off settings.register( livesettings.StringValue( LOGIN_PROVIDERS, 'SIGNIN_GOOGLE_METHOD', default='disabled', choices=GOOGLE_METHOD_CHOICES, description=_('Google login'),
class Controllable(dd.Model): """Mixin for models that are "controllable" by another database object. Defines three fields :attr:`owned_type`, :attr:`owned_id` and :attr:`owned`. And a class attribute :attr:`owner_label`. For example in :mod:`lino.modlibs.cal`, the owner of a Task or Event is some other database object that caused the task's or event's creation. Or in :mod:`lino.modlib.sales` and :mod:`lino.modlib.purchases`, an invoice may cause one or several Tasks to be automatically generated when a certain payment mode is specified. Controllable objects are "governed" or "controlled" by their controller (stored in a field called :attr:`owner`): If the controller gets modified, it may decide to delete or modify some or all of her controlled objects. Non-automatic tasks always have an empty :attr:`owner` field. Some fields are read-only on an automatic Task because it makes no sense to modify them. .. attribute:: owner .. attribute:: owner_id .. attribute:: owner_type """ # Translators: will also be concatenated with '(type)' '(object)' owner_label = _('Controlled by') """Deprecated. This is (and always was) being ignored. Use :meth:`update_controller_field` instead. The labels (`verbose_name`) of the fields `owned_type`, `owned_id` and `owned` are derived from this attribute which may be overridden by subclasses. """ controller_is_optional = True """Deprecated. This is (and always was) being ignored. Use :meth:`update_controller_field` instead. """ class Meta(object): abstract = True owner_type = dd.ForeignKey(ContentType, editable=True, blank=True, null=True, verbose_name=string_concat( owner_label, ' ', _('(type)'))) owner_id = GenericForeignKeyIdField(owner_type, editable=True, blank=True, null=True, verbose_name=string_concat( owner_label, ' ', _('(object)'))) owner = GenericForeignKey('owner_type', 'owner_id', verbose_name=owner_label) @classmethod def update_controller_field(cls, verbose_name=None, **kwargs): """Update attributes of the :attr:`owner` field and its underlying fields :attr:`owner_id` and :attr:`owner_type`. This can be used to make the controller optional (i.e. specify whether the :attr:`owner` field may be NULL). Example:: class MyModel(Controllable): .... MyModel.update_controller_field(blank=False, null=False) When `verbose_name` is specified, all three fields will be updated, appending " (object)" and " (type)" to :attr:`owner_id` and :attr:`owner_type` respectively. """ if verbose_name is not None: dd.update_field(cls, 'owner', verbose_name=verbose_name) kwargs.update( verbose_name=string_concat(verbose_name, ' ', _('(object)'))) dd.update_field(cls, 'owner_id', **kwargs) if verbose_name is not None: kwargs.update( verbose_name=string_concat(verbose_name, ' ', _('(type)'))) dd.update_field(cls, 'owner_type', **kwargs) def update_owned_instance(self, controllable): """If this (acting as a controller) is itself controlled, forward the call to the controller. """ if self.owner: self.owner.update_owned_instance(controllable) super(Controllable, self).update_owned_instance(controllable) def save(self, *args, **kw): if settings.SITE.loading_from_dump: super(Controllable, self).save(*args, **kw) else: if self.owner: self.owner.update_owned_instance(self) super(Controllable, self).save(*args, **kw) if self.owner: self.owner.after_update_owned_instance(self)
# add-on by another. discopane_items = { 'default': [ # 'Spring is Here' theme. DiscoItem( addon_id=368421, type=amo.ADDON_PERSONA, addon_name=u'Spring is Here'), # Facebook Container DiscoItem( addon_id=954390, heading=_(u'Stop Facebook tracking {start_sub_heading}with ' u'{addon_name}{end_sub_heading}'), description=string_concat( '<blockquote>', _(u'Isolate your Facebook identity into a separate ' u'"container" that makes it harder for Facebook to track ' u'your movements around the web.'), '</blockquote>')), # Swift Selection Search DiscoItem( addon_id=587410, heading=_(u'Simplify search {start_sub_heading}with ' u'{addon_name}{end_sub_heading}'), description=string_concat( '<blockquote>', _(u'Just highlight text on any web page to search the phrase ' u'from an array of engines.'), '</blockquote>')), # 'Dream of Waves' theme
livesettings.IntegerValue( EMAIL, 'MAX_ACCEPT_ANSWER_REMINDERS', default=5, description=_( 'Max. number of reminders to send to accept the best answer'))) settings.register( livesettings.BooleanValue( EMAIL, 'BLANK_EMAIL_ALLOWED', default=False, description=_('Allow blank email'), help_text=string_concat( _('DANGER: makes impossible account recovery by email.'), ' ', settings.get_related_settings_info( ('ACCESS_CONTROL', 'REQUIRE_VALID_EMAIL_FOR', True, _('Must be not be required')), )))) settings.register( livesettings.StringValue( EMAIL, 'ANONYMOUS_USER_EMAIL', default='*****@*****.**', description=_('Fake email for anonymous user'), help_text=_( 'Use this setting to control gravatar for email-less user'))) settings.register( livesettings.BooleanValue( EMAIL,
def grade(self, page_context, page_data, answer_data, grade_data): if answer_data is None: return AnswerFeedback(correctness=0, feedback=_("No answer provided.")) user_code = answer_data["answer"] # {{{ request run run_req = {"compile_only": False, "user_code": user_code} def transfer_attr(name): if hasattr(self.page_desc, name): run_req[name] = getattr(self.page_desc, name) transfer_attr("setup_code") transfer_attr("names_for_user") transfer_attr("names_from_user") if hasattr(self.page_desc, "test_code"): run_req["test_code"] = self.get_test_code() if hasattr(self.page_desc, "data_files"): run_req["data_files"] = {} from course.content import get_repo_blob for data_file in self.page_desc.data_files: from base64 import b64encode run_req["data_files"][data_file] = \ b64encode( get_repo_blob( page_context.repo, data_file, page_context.commit_sha).data).decode() try: response_dict = request_python_run_with_retries( run_req, run_timeout=self.page_desc.timeout) except: from traceback import format_exc response_dict = { "result": "uncaught_error", "message": "Error connecting to container", "traceback": "".join(format_exc()), } # }}} feedback_bits = [] # {{{ send email if the grading code broke if response_dict["result"] in [ "uncaught_error", "setup_compile_error", "setup_error", "test_compile_error", "test_error" ]: error_msg_parts = ["RESULT: %s" % response_dict["result"]] for key, val in sorted(response_dict.items()): if (key not in ["result", "figures"] and val and isinstance(val, six.string_types)): error_msg_parts.append( "-------------------------------------") error_msg_parts.append(key) error_msg_parts.append( "-------------------------------------") error_msg_parts.append(val) error_msg_parts.append("-------------------------------------") error_msg_parts.append("user code") error_msg_parts.append("-------------------------------------") error_msg_parts.append(user_code) error_msg_parts.append("-------------------------------------") error_msg = "\n".join(error_msg_parts) with translation.override(settings.RELATE_ADMIN_EMAIL_LOCALE): from django.template.loader import render_to_string message = render_to_string( "course/broken-code-question-email.txt", { "page_id": self.page_desc.id, "course": page_context.course, "error_message": error_msg, }) if (not page_context.in_sandbox and not is_nuisance_failure(response_dict)): try: from django.core.mail import send_mail send_mail( "".join( ["[%s] ", _("code question execution failed")]) % page_context.course.identifier, message, settings.ROBOT_EMAIL_FROM, recipient_list=[page_context.course.notify_email]) except Exception: from traceback import format_exc feedback_bits.append( six.text_type( string_concat( "<p>", _("Both the grading code and the attempt to " "notify course staff about the issue failed. " "Please contact the course or site staff and " "inform them of this issue, mentioning this " "entire error message:"), "</p>", "<p>", _("Sending an email to the course staff about the " "following failure failed with " "the following error message:"), "<pre>", "".join(format_exc()), "</pre>", _("The original failure message follows:"), "</p>"))) # }}} from relate.utils import dict_to_struct response = dict_to_struct(response_dict) bulk_feedback_bits = [] if hasattr(response, "points"): correctness = response.points feedback_bits.append("<p><b>%s</b></p>" % get_auto_feedback(correctness)) else: correctness = None if response.result == "success": pass elif response.result in [ "uncaught_error", "setup_compile_error", "setup_error", "test_compile_error", "test_error" ]: feedback_bits.append("".join([ "<p>", _("The grading code failed. Sorry about that. " "The staff has been informed, and if this problem is " "due to an issue with the grading code, " "it will be fixed as soon as possible. " "In the meantime, you'll see a traceback " "below that may help you figure out what went wrong."), "</p>" ])) elif response.result == "timeout": feedback_bits.append("".join([ "<p>", _("Your code took too long to execute. The problem " "specifies that your code may take at most %s seconds " "to run. " "It took longer than that and was aborted."), "</p>" ]) % self.page_desc.timeout) correctness = 0 elif response.result == "user_compile_error": feedback_bits.append("".join([ "<p>", _("Your code failed to compile. An error message is " "below."), "</p>" ])) correctness = 0 elif response.result == "user_error": feedback_bits.append("".join([ "<p>", _("Your code failed with an exception. " "A traceback is below."), "</p>" ])) correctness = 0 else: raise RuntimeError("invalid runpy result: %s" % response.result) if hasattr(response, "feedback") and response.feedback: feedback_bits.append("".join([ "<p>", _("Here is some feedback on your code"), ":" "<ul>%s</ul></p>" ]) % "".join("<li>%s</li>" % escape(fb_item) for fb_item in response.feedback)) if hasattr(response, "traceback") and response.traceback: feedback_bits.append("".join([ "<p>", _("This is the exception traceback"), ":" "<pre>%s</pre></p>" ]) % escape(response.traceback)) if hasattr(response, "stdout") and response.stdout: bulk_feedback_bits.append("".join([ "<p>", _("Your code printed the following output"), ":" "<pre>%s</pre></p>" ]) % escape(response.stdout)) if hasattr(response, "stderr") and response.stderr: bulk_feedback_bits.append("".join([ "<p>", _("Your code printed the following error messages"), ":" "<pre>%s</pre></p>" ]) % escape(response.stderr)) if hasattr(response, "figures") and response.figures: fig_lines = [ "".join([ "<p>", _("Your code produced the following plots"), ":</p>" ]), '<dl class="result-figure-list">', ] for nr, mime_type, b64data in response.figures: fig_lines.extend([ "".join(["<dt>", _("Figure"), "%d<dt>"]) % nr, '<dd><img alt="Figure %d" src="data:%s;base64,%s"></dd>' % (nr, mime_type, b64data) ]) fig_lines.append("</dl>") bulk_feedback_bits.extend(fig_lines) return AnswerFeedback(correctness=correctness, feedback="\n".join(feedback_bits), bulk_feedback="\n".join(bulk_feedback_bits))
def choice_from_tuple(state_division, inverted=False): if not inverted: return state_division[0], string_concat("%02d" % state_division[0], CODE_DELIMITER, state_division[1]) else: return state_division[1], string_concat("%02d" % state_division[1], CODE_DELIMITER, state_division[0])
def validate_struct(ctx, location, obj, required_attrs, allowed_attrs): """ :arg required_attrs: an attribute validation list (see below) :arg allowed_attrs: an attribute validation list (see below) An attribute validation list is a list of elements, where each element is either a string (the name of the attribute), in which case the type of each attribute is not checked, or a tuple *(name, type)*, where type is valid as a second argument to :func:`isinstance`. """ if not isinstance(obj, Struct): raise ValidationError("%s: not a key-value map" % location) present_attrs = set(name for name in dir(obj) if not name.startswith("_")) for required, attr_list in [ (True, required_attrs), (False, allowed_attrs), ]: for attr_rec in attr_list: if isinstance(attr_rec, tuple): attr, allowed_types = attr_rec else: attr = attr_rec allowed_types = None if attr not in present_attrs: if required: raise ValidationError( string_concat("%(location)s: ", _("attribute '%(attr)s' missing")) % { 'location': location, 'attr': attr }) else: present_attrs.remove(attr) val = getattr(obj, attr) is_markup = False if allowed_types == "markup": allowed_types = str is_markup = True if allowed_types == str: # Love you, too, Python 2. allowed_types = (str, unicode) if not isinstance(val, allowed_types): raise ValidationError( string_concat( "%(location)s: ", _("attribute '%(attr)s' has " "wrong type: got '%(name)s', " "expected '%(allowed)s'")) % { 'location': location, 'attr': attr, 'name': type(val).__name__, 'allowed': escape(str(allowed_types)) }) if is_markup: validate_markup(ctx, "%s: attribute %s" % (location, attr), val) if present_attrs: raise ValidationError( string_concat("%(location)s: ", _("extraneous attribute(s) '%(attr)s'")) % { 'location': location, 'attr': ",".join(present_attrs) })
def get_label(cls): if cls.arguments: return string_concat(cls.label, ': ', ', '.join(cls.arguments)) else: return cls.label
def validate_session_grading_rule(ctx, location, grule, tags): """ :returns: whether the rule only applies conditionally """ validate_struct(ctx, location, grule, required_attrs=[ ("grade_identifier", (type(None), str)), ], allowed_attrs=[ ("if_has_role", list), ("if_has_tag", (str, unicode, type(None))), ("if_completed_before", datespec_types), ("credit_percent", (int, float)), ("due", datespec_types), ("grade_aggregation_strategy", str), ("description", str), ]) has_conditionals = False if hasattr(grule, "if_completed_before"): ctx.encounter_datespec(location, grule.if_completed_before) has_conditionals = True if hasattr(grule, "if_has_role"): for j, role in enumerate(grule.if_has_role): validate_role("%s, role %d" % (location, j + 1), role) has_conditionals = True if hasattr(grule, "if_has_tag"): if not (grule.if_has_tag is None or grule.if_has_tag in tags): raise ValidationError( string_concat("%(locatioin)s: ", _("invalid tag '%(tag)s'")) % { 'location': location, 'tag': grule.if_has_tag }) has_conditionals = True if hasattr(grule, "due"): ctx.encounter_datespec(location, grule.due) if grule.grade_identifier: validate_identifier(ctx, "%s: grade_identifier" % location, grule.grade_identifier) if not hasattr(grule, "grade_aggregation_strategy"): raise ValidationError( string_concat( "%(location)s: ", _("grading rule that have a grade " "identifier (%(type)s: %(identifier)s) " "must have a grade_aggregation_strategy")) % { 'location': location, 'type': type(grule.grade_identifier), 'identifier': grule.grade_identifier }) from course.constants import GRADE_AGGREGATION_STRATEGY_CHOICES if grule.grade_aggregation_strategy not in \ dict(GRADE_AGGREGATION_STRATEGY_CHOICES): raise ValidationError( string_concat("%s: ", _("invalid grade aggregation strategy")) % location) return has_conditionals
# are used instead of slugs to prevent any accidental replacement of a deleted # add-on by another. discopane_items = { 'default': [ # 'abstract colorful owl' theme. DiscoItem( addon_id=677612, type=amo.ADDON_PERSONA), # Forget Me Not DiscoItem( addon_id=884014, heading=_(u'Leave a clean digital trail {start_sub_heading}' u'with {addon_name}{end_sub_heading}'), description=string_concat( '<blockquote>', _(u'Make Firefox forget website data like cookies and local ' u'storage, but only for domains you choose.'), '</blockquote>')), # Enhancer for YouTube DiscoItem( addon_id=700308, heading=_(u'Improve videos {start_sub_heading}with ' u'{addon_name} {end_sub_heading}'), description=string_concat( '<blockquote>', _(u'Enjoy a suite of new YouTube features, like cinema mode, ' u'ad blocking, auto-play, and more.'), '</blockquote>')), # 'Strands of Gold' theme
DEFAULT_HOME_ACTIVITY_TABS, DEFAULT_SEASONS, ) from magi.utils import tourldash from bang.utils import bangGlobalContext, randomArtForCharacter from bang import models ############################################################ # License, game and site settings SITE_NAME = 'Bandori Party' SITE_EMOJIS = [u'★', u'🎸', u'🤘'] SITE_IMAGE = 'share/bandori_party.png' SITE_LOGO = 'logo/bandori_party.png' GAME_NAME = string_concat(_('BanG Dream!'), ' ', _('Girls Band Party')) GAME_URL = 'https://bang-dream.bushimo.jp/' COLOR = '#E40046' SECONDARY_COLOR = '#F2B141' ############################################################ # Images CORNER_POPUP_IMAGE = 'chibi_kanae.png' ABOUT_PHOTO = 'deby.jpg' EMPTY_IMAGE = 'stars_with_white.png' SITE_NAV_LOGO = 'star.png' ############################################################ # Settings per languages
_( 'Save, then <a href="http://validator.w3.org/">' 'use HTML validator</a> on the "privacy" page to check your input.' ) ) ) settings.register( LongStringValue( FLATPAGES, 'TERMS', description=_('Terms and conditions'), localized=True, help_text=string_concat( _('Save, then <a href="http://validator.w3.org/">' 'use HTML validator</a> on the "terms" page to check your input.' ), ' ', settings.get_related_settings_info( ('LOGIN_PROVIDERS', 'TERMS_ACCEPTANCE_REQUIRED', False))))) #todo: merge this with mandatory tags settings.register( #this field is not editable manually LongStringValue( FLATPAGES, 'CATEGORY_TREE', description='Category tree', #no need to translate localized=True, default='[["dummy",[]]]', #empty array of arrays in json help_text=_('Do not edit this field manually!!!') #hidden = True ))
def get_participant(self, obj): if obj.flow_session.participation: return obj.flow_session.participation.user else: return string_concat("(", _("anonymous"), ")")
class Resource(object): """ A collection of views that facilitate for common features. :attribute model: A reference to a model. :attribute form: A reference to a form, or ``None`` to generate one automatically. """ model = None form = None @route( regex = lambda prefix: string_concat('^', prefix, '(?:$|', _('index'), templates.format, '$)'), method = 'GET', name = lambda views: pluralize(cc2us(views.model.__name__)) ) def index(self, request): """Render a list of objects.""" objects = self.model.objects.all() return self._render( request = request, template = 'index', context = { cc2us(pluralize(self.model.__name__)): objects, }, status = 200 ) @route( regex = lambda prefix: string_concat('^', prefix, '(?P<id>[0-9]+)', templates.format, '$'), method = 'GET', name = lambda views: cc2us(views.model.__name__) ) def show(self, request, id): """Render a single object.""" try: object = self.model.objects.get(id=id) except self.model.DoesNotExist: return self._render( request = request, template = '404', context = { 'error': 'The %s could not be found.' % self.model.__name__.lower() }, status = 404, prefix_template_path = False ) return self._render( request = request, template = 'show', context = { cc2us(self.model.__name__): object }, status = 200 ) @route( regex = lambda prefix: string_concat('^', prefix, _('new'), templates.format, '$'), method = 'GET', name = lambda views: 'new_%s' % cc2us(views.model.__name__) ) def new(self, request): """Render a form to create a new object.""" form = (self.form or generate_form(self.model))() return self._render( request = request, template = 'new', context = { 'form': form }, status = 200 ) @route( regex = lambda prefix: string_concat('^', prefix, '(?:$|', _('index'), templates.format, '$)'), method = 'POST', name = lambda views: pluralize(cc2us(views.model.__name__)) ) def create(self, request): """Create a new object.""" form = (self.form or generate_form(self.model))(request.POST) if form.is_valid(): object = form.save() return self._render( request = request, template = 'show', context = { cc2us(self.model.__name__): object }, status = 201 ) else: return self._render( request = request, template = 'new', context = { 'form': form }, status = 400 ) @route( regex = lambda prefix: string_concat('^', prefix, '(?P<id>[0-9]+)/', _('edit'), templates.format, '$'), method = 'GET', name = lambda views: 'edit_%s' % cc2us(views.model.__name__) ) def edit(self, request, id): """Render a form to edit an object.""" try: object = self.model.objects.get(id=id) except self.model.DoesNotExist: return self._render( request = request, template = '404', context = { 'error': 'The %s could not be found.' % self.model.__name__.lower() }, status = 404, prefix_template_path = False ) form = (self.form or generate_form(self.model))(instance=object) # Add "_method" field to override request method to PUT form.fields['_method'] = CharField(required=True, initial='PUT', widget=HiddenInput) return self._render( request = request, template = 'edit', context = { cc2us(self.model.__name__): object, 'form': form }, status = 200 ) @route( regex = lambda prefix: string_concat('^', prefix, '(?P<id>[0-9]+)%s$' % templates.format), method = 'PATCH', name = lambda views: cc2us(views.model.__name__) ) def update(self, request, id): """Update an object.""" try: object = self.model.objects.get(id=id) except self.model.DoesNotExist: return self._render( request = request, template = '404', context = { 'error': 'The %s could not be found.' % self.model.__name__.lower() }, status = 404, prefix_template_path = False ) fields = [] for field in request.PATCH: try: self.model._meta.get_field_by_name(field) except FieldDoesNotExist: continue else: fields.append(field) Form = generate_form( model = self.model, form = self.form, fields = fields ) form = Form(request.PATCH, instance=object) if form.is_valid(): object = form.save() return self.show(request, id) else: return self._render( request = request, template = 'edit', context = { 'form': form }, status = 400 ) @route( regex = lambda prefix: string_concat('^', prefix, '(?P<id>[0-9]+)%s$' % templates.format), method = 'PUT', name = lambda views: cc2us(views.model.__name__) ) def replace(self, request, id): """Replace an object.""" try: object = self.model.objects.get(id=id) except self.model.DoesNotExist: return self._render( request = request, template = '404', context = { 'error': 'The %s could not be found.' % self.model.__name__.lower() }, status = 404, prefix_template_path = False ) form = (self.form or generate_form(self.model))(request.PUT, instance=object) if form.is_valid(): object = form.save() return self.show(request, id) else: return self._render( request = request, template = 'edit', context = { 'form': form }, status = 400 ) @route( regex = lambda prefix: string_concat('^', prefix, '(?P<id>[0-9]+)%s$' % templates.format), method = 'DELETE', name = lambda views: cc2us(views.model.__name__) ) def destroy(self, request, id): """Delete an object.""" try: object = self.model.objects.get(id=id) object.delete() except self.model.DoesNotExist: return self._render( request = request, template = '404', context = { 'error': 'The %s could not be found.' % self.model.__name__.lower() }, status = 404, prefix_template_path = False ) return self._render( request = request, template = 'destroy', status = 200 ) routes = [ index.route, show.route, new.route, create.route, edit.route, update.route, replace.route, destroy.route ]
def __str__(self): return string_concat(self.lc_key, " - ", self.p_key)
self.addon_id = kwargs.get('addon_id') self.heading = kwargs.get('heading') self.description = kwargs.get('description') # At the moment the disco pane items are hardcoded in this file in the repos, # which allows us to integrate in our translation workflow easily. discopane_items = [ DiscoItem(addon_id=362876), DiscoItem( addon_id=1865, heading=_(u'Block ads {start_sub_heading}with {addon_name}' '{end_sub_heading}'), description=string_concat( '<blockquote>', _(u'Remove blaring ads and make the Web run smoother! Adblock ' u'Plus can also mitigate tracking mechanisms and malware.'), '</blockquote>')), DiscoItem( addon_id=287841, heading=_(u'Take screenshots {start_sub_heading}with {addon_name}' '{end_sub_heading}'), description=string_concat( '<blockquote>', _(u'So much more than just a screenshot tool, this add-on also ' u'lets you edit, annotate, and share images.'), '</blockquote>')), DiscoItem(addon_id=111435), DiscoItem( addon_id=511962, heading=_(u'Up your emoji game {start_sub_heading}with {addon_name}'
# -*- coding: utf-8 -*- from functools import partial from django.db import models from django.utils.translation import ugettext_lazy as _, string_concat from django.conf import settings from cms.models import CMSPlugin GRID_CONFIG = {'COLUMNS': 24, 'TOTAL_WIDTH': 960, 'GUTTER': 20} GRID_CONFIG.update(getattr(settings, 'ALDRYN_GRID_FOUNDATION_CONFIG', {})) ALDRYN_GRID_FOUNDATION_CHOICES = [(i, string_concat(str(i), ' ', _('columns'))) for i in range(1, GRID_CONFIG['COLUMNS'] + 1) ] ColumnSizeField = partial(models.IntegerField, default=0, choices=ALDRYN_GRID_FOUNDATION_CHOICES, null=True, blank=True) class GridFoundation(CMSPlugin): custom_classes = models.CharField(_('custom classes'), max_length=200, blank=True) def __unicode__(self): return _(u"%s columns") % self.cmsplugin_set.all().count()
def create_proxy_permissions(app_config, verbosity=2, interactive=True, using=DEFAULT_DB_ALIAS, **kwargs): if not app_config.models_module: return logger = logging.getLogger(__name__) # print(app_config) try: logger.info("Tentando obter modelo de permissão do app.") Permission = apps.get_model('auth', 'Permission') except LookupError as e: logger.error(str(e)) return if not router.allow_migrate_model(using, Permission): return from django.contrib.contenttypes.models import ContentType permission_name_max_length = Permission._meta.get_field('name').max_length # This will hold the permissions we're looking for as # (content_type, (codename, name)) searched_perms = list() # The codenames and ctypes that should exist. ctypes = set() for klass in list(app_config.get_models()): opts = klass._meta permissions = ( ("list_" + opts.model_name, string_concat(_('Visualizaçao da lista de'), ' ', opts.verbose_name_plural)), ("detail_" + opts.model_name, string_concat(_('Visualização dos detalhes de'), ' ', opts.verbose_name_plural)), ) opts.permissions = tuple( set(list(permissions) + list(opts.permissions))) if opts.proxy: # Force looking up the content types in the current database # before creating foreign keys to them. app_label, model = opts.app_label, opts.model_name try: logger.info("Tentando obter db_manager.") ctype = ContentType.objects.db_manager( using).get_by_natural_key(app_label, model) except Exception as e: logger.error(str(e)) ctype = ContentType.objects.db_manager(using).create( app_label=app_label, model=model) else: ctype = ContentType.objects.db_manager(using).get_for_model(klass) ctypes.add(ctype) # FIXME: Retirar try except quando sapl passar a usar django 1.11 try: logger.info("_get_all_permissions") # Função não existe mais em Django 1.11 # como sapl ainda não foi para Django 1.11 # esta excessão foi adicionada para caso o # Sapl esteja rodando em um projeto 1.11 não ocorra erros _all_perms_of_klass = _get_all_permissions(klass._meta, ctype) except Exception as e: logger.error(str(e)) # Nova função usada em projetos com Django 1.11 e o sapl é uma app _all_perms_of_klass = _get_all_permissions(klass._meta) for perm in _all_perms_of_klass: searched_perms.append((ctype, perm)) # Find all the Permissions that have a content_type for a model we're # looking for. We don't need to check for codenames since we already have # a list of the ones we're going to create. all_perms = set( Permission.objects.using(using).filter( content_type__in=ctypes, ).values_list("content_type", "codename")) perms = [ Permission(codename=codename, name=name, content_type=ct) for ct, (codename, name) in searched_perms if (ct.pk, codename) not in all_perms ] # Validate the permissions before bulk_creation to avoid cryptic database # error when the name is longer than 255 characters for perm in perms: if len(perm.name) > permission_name_max_length: logger.error("The permission name %s of %s.%s " "is longer than %s characters" % ( perm.name, perm.content_type.app_label, perm.content_type.model, permission_name_max_length, )) raise exceptions.ValidationError('The permission name %s of %s.%s ' 'is longer than %s characters' % ( perm.name, perm.content_type.app_label, perm.content_type.model, permission_name_max_length, )) Permission.objects.using(using).bulk_create(perms) if verbosity >= 2: for perm in perms: print("Adding permission '%s'" % perm)
def run_course_update_command(request, repo, content_repo, pctx, command, new_sha, may_update, prevent_discarding_revisions): if command.startswith("fetch"): if command != "fetch": command = command[6:] if not pctx.course.git_source: raise RuntimeError(_("no git source URL specified")) client, remote_path = \ get_dulwich_client_and_remote_path_from_course(pctx.course) remote_refs = client.fetch(remote_path, repo) transfer_remote_refs(repo, remote_refs) remote_head = remote_refs[b"HEAD"] if (prevent_discarding_revisions and is_parent_commit( repo, repo[remote_head], repo[b"HEAD"], max_history_check_size=20)): raise RuntimeError(_("fetch would discard commits, refusing")) repo[b"HEAD"] = remote_head messages.add_message(request, messages.SUCCESS, _("Fetch successful.")) new_sha = remote_head if command == "fetch": return if command == "end_preview": messages.add_message(request, messages.INFO, _("Preview ended.")) pctx.participation.preview_git_commit_sha = None pctx.participation.save() return # {{{ validate from course.validation import validate_course_content, ValidationError try: warnings = validate_course_content(content_repo, pctx.course.course_file, pctx.course.events_file, new_sha, course=pctx.course) except ValidationError as e: messages.add_message( request, messages.ERROR, _("Course content did not validate successfully. (%s) " "Update not applied.") % str(e)) return else: if not warnings: messages.add_message(request, messages.SUCCESS, _("Course content validated successfully.")) else: messages.add_message( request, messages.WARNING, string_concat( _("Course content validated OK, with warnings: "), "<ul>%s</ul>") % ("".join("<li><i>%(location)s</i>: %(warningtext)s</li>" % { 'location': w.location, 'warningtext': w.text } for w in warnings))) # }}} if command == "preview": messages.add_message(request, messages.INFO, _("Preview activated.")) pctx.participation.preview_git_commit_sha = new_sha.decode() pctx.participation.save() elif command == "update" and may_update: pctx.course.active_git_commit_sha = new_sha.decode() pctx.course.save() messages.add_message(request, messages.SUCCESS, _("Update applied. ")) else: raise RuntimeError(_("invalid command"))
def update_course(pctx): if pctx.role not in [ participation_role.instructor, participation_role.teaching_assistant ]: raise PermissionDenied(_("must be instructor or TA to update course")) course = pctx.course request = pctx.request content_repo = pctx.repo from course.content import SubdirRepoWrapper if isinstance(content_repo, SubdirRepoWrapper): repo = content_repo.repo else: repo = content_repo participation = pctx.participation previewing = bool(participation is not None and participation.preview_git_commit_sha) may_update = pctx.role == participation_role.instructor response_form = None if request.method == "POST": form = GitUpdateForm(may_update, previewing, repo, request.POST, request.FILES) commands = [ "fetch", "fetch_update", "update", "fetch_preview", "preview", "end_preview" ] command = None for cmd in commands: if cmd in form.data: command = cmd break if command is None: raise SuspiciousOperation(_("invalid command")) if form.is_valid(): new_sha = form.cleaned_data["new_sha"].encode() try: run_course_update_command( request, repo, content_repo, pctx, command, new_sha, may_update, prevent_discarding_revisions=form. cleaned_data["prevent_discarding_revisions"]) except Exception as e: import traceback traceback.print_exc() messages.add_message( pctx.request, messages.ERROR, string_concat( pgettext("Starting of Error message", "Error"), ": %(err_type)s %(err_str)s") % { "err_type": type(e).__name__, "err_str": str(e) }) else: response_form = form if response_form is None: previewing = bool(participation is not None and participation.preview_git_commit_sha) form = GitUpdateForm(may_update, previewing, repo, { "new_sha": repo.head(), "prevent_discarding_revisions": True, }) if six.PY2: from cgi import escape else: from html import escape text_lines = [ "<table class='table'>", string_concat("<tr><th>", ugettext("Git Source URL"), "</th><td><tt>%(git_source)s</tt></td></tr>") % { 'git_source': pctx.course.git_source }, string_concat("<tr><th>", ugettext("Public active git SHA"), "</th><td> %(commit)s (%(message)s)</td></tr>") % { 'commit': course.active_git_commit_sha, 'message': (escape(repo[course.active_git_commit_sha.encode()]. message.strip().decode(errors="replace"))) }, string_concat("<tr><th>", ugettext("Current git HEAD"), "</th><td>%(commit)s (%(message)s)</td></tr>") % { 'commit': repo.head().decode(), 'message': escape(repo[repo.head()].message.strip().decode(errors="replace")) }, ] if participation is not None and participation.preview_git_commit_sha: text_lines.append( string_concat("<tr><th>", ugettext("Current preview git SHA"), "</th><td>%(commit)s (%(message)s)</td></tr>") % { 'commit': participation.preview_git_commit_sha, 'message': (escape(repo[participation.preview_git_commit_sha.encode()]. message.strip().decode(errors="replace"))), }) else: text_lines.append("".join([ "<tr><th>", ugettext("Current preview git SHA"), "</th><td>", ugettext("None"), "</td></tr>", ])) text_lines.append("</table>") return render_course_page( pctx, "course/generic-course-form.html", { "form": form, "form_text": "".join("<p>%s</p>" % line for line in text_lines), "form_description": ugettext("Update Course Revision"), })
def set_up_new_course(request): if not request.user.is_staff: raise PermissionDenied(_("only staff may create courses")) if request.method == "POST": form = CourseCreationForm(request.POST) if form.is_valid(): new_course = form.save(commit=False) from course.content import get_course_repo_path repo_path = get_course_repo_path(new_course) try: import os os.makedirs(repo_path) repo = None try: with transaction.atomic(): from dulwich.repo import Repo repo = Repo.init(repo_path) client, remote_path = \ get_dulwich_client_and_remote_path_from_course( new_course) remote_refs = client.fetch(remote_path, repo) transfer_remote_refs(repo, remote_refs) new_sha = repo[b"HEAD"] = remote_refs[b"HEAD"] vrepo = repo if new_course.course_root_path: from course.content import SubdirRepoWrapper vrepo = SubdirRepoWrapper( vrepo, new_course.course_root_path) from course.validation import validate_course_content validate_course_content(vrepo, new_course.course_file, new_course.events_file, new_sha) del repo del vrepo new_course.active_git_commit_sha = new_sha.decode() new_course.save() # {{{ set up a participation for the course creator part = Participation() part.user = request.user part.course = new_course part.role = participation_role.instructor part.status = participation_status.active part.save() # }}} messages.add_message( request, messages.INFO, _("Course content validated, creation " "succeeded.")) except: # Don't coalesce this handler with the one below. We only want # to delete the directory if we created it. Trust me. # Work around read-only files on Windows. # https://docs.python.org/3.5/library/shutil.html#rmtree-example import os import stat import shutil # Make sure files opened for 'repo' above are actually closed. if repo is not None: # noqa repo.close() # noqa def remove_readonly(func, path, _): # noqa "Clear the readonly bit and reattempt the removal" os.chmod(path, stat.S_IWRITE) func(path) try: shutil.rmtree(repo_path, onerror=remove_readonly) except OSError: messages.add_message( request, messages.WARNING, ugettext("Failed to delete unused " "repository directory '%s'.") % repo_path) raise except Exception as e: from traceback import print_exc print_exc() messages.add_message( request, messages.ERROR, string_concat(_("Course creation failed"), ": %(err_type)s: %(err_str)s") % { "err_type": type(e).__name__, "err_str": str(e) }) else: return redirect("relate-course_page", new_course.identifier) else: form = CourseCreationForm() return render(request, "generic-form.html", { "form_description": _("Set up new course"), "form": form })
def index(self, request): """The view for showing all the results in the Haystack index. Emulates the standard Django ChangeList mostly. :param request: the current request. :type request: WSGIRequest :return: A template rendered into an HttpReponse """ page_var = self.get_paginator_var(request) form = PreSelectedModelSearchForm(request.GET or None, load_all=False) # Make sure there are some models indexed available_models = model_choices() if len(available_models) <= 0: raise Search404('No search indexes bound via Haystack') # We've not selected any models, so we're going to redirect and select # all of them. This will bite me in the ass if someone searches for a string # but no models, but I don't know WTF they'd expect to return, anyway. # Note that I'm only doing this to sidestep this issue: # https://gist.github.com/3766607 if 'models' not in request.GET.keys(): # TODO: make this betterererer. new_qs = ['&models=%s' % x[0] for x in available_models] # if we're in haystack2, we probably want to provide the 'default' # connection so that it behaves as if "initial" were in place. if form.has_multiple_connections(): new_qs.append('&connection=' + form.fields['connection'].initial) new_qs = ''.join(new_qs) qs = self.get_current_query_string(request, remove=['p']) return HttpResponseRedirect(request.path_info + qs + new_qs) try: sqs = form.search() try: page_no = int(request.GET.get(PAGE_VAR, 0)) except ValueError: page_no = 0 #page_no = int(request.GET.get(page_var, 1)) results_per_page = self.get_results_per_page(request) paginator = Paginator(sqs, results_per_page) page = paginator.page(page_no + 1) except (InvalidPage, ValueError): # paginator.page may raise InvalidPage if we've gone too far # meanwhile, casting the querystring parameter may raise ValueError # if it's None, or '', or other silly input. raise Search404("Invalid page") query = request.GET.get(self.get_search_var(request), None) connection = request.GET.get('connection', None) title = self.model._meta.verbose_name_plural if query: title = string_concat(self.model._meta.verbose_name_plural, ' for "', query, '"') if connection: title = string_concat(title, ' using "', connection, '" connection') context = { 'results': self.get_wrapped_search_results(page.object_list), 'pagination_required': page.has_other_pages(), # this may be expanded into xrange(*page_range) to copy what # the paginator would yield. This prevents 50000+ pages making # the page slow to render because of django-debug-toolbar. 'page_range': (1, paginator.num_pages + 1), 'page_num': page.number, 'result_count': paginator.count, 'opts': self.model._meta, 'title': force_text(title), 'root_path': getattr(self.admin_site, 'root_path', None), 'app_label': self.model._meta.app_label, 'filtered': True, 'form': form, 'query_string': self.get_current_query_string(request, remove=['p']), 'search_model_count': len(request.GET.getlist('models')), 'search_facet_count': len(request.GET.getlist('possible_facets')), 'search_var': self.get_search_var(request), 'page_var': page_var, 'facets': FacetWrapper(sqs.facet_counts()), 'module_name': force_text(self.model._meta.verbose_name_plural), 'cl': FakeChangeListForPaginator(request, page, results_per_page, self.model._meta), 'haystack_version': _haystack_version, # Note: the empty Media object isn't specficially required for the # standard Django admin, but is apparently a pre-requisite for # things like Grappelli. # See #1 (https://github.com/kezabelle/django-haystackbrowser/pull/1) 'media': Media() } return render_to_response('admin/haystackbrowser/result_list.html', context, context_instance=RequestContext(request))