def __setitem__(self, name, value): self.__load() from tuit.ticket.models import Property if name in self.data: p=Property.objects.get(name=name) p.value=to_json(value) p.save() else: Property(name=name, value=to_json(value)).save() self.data[name] = value;
def issue_by_id(request): q = [] try : id_query = request.GET['query'] except: pass if len(id_query)!=0: text = request.GET['query'].split(' ') ids = [] for i in text: try: int(i) ids.append(i) except: pass if len(ids)!=0: q = Issue.objects.filter(id__in = ids).order_by('-id') print q tot_count = len(q) u = {'ResultSet':{'totalResultsAvailable':tot_count, 'totalResultsReturned':len(q), 'Result':map(lambda issue: {'name':issue.subject,'description':'hejsan','url':'/tuit/ticket/view/%d'%issue.id}, q) }} return HttpResponse(to_json(u))
def session(request): """ Returns a json object containing session information. Fixme: Should we also include e.g. login time? """ res = "null" if request.user.is_authenticated(): res = to_json({'username':request.user.username, 'first_name':request.user.first_name, 'last_name':request.user.last_name, 'email':request.user.email, 'groups':map(lambda x:x.name, request.user.groups.all()) }) return HttpResponse(res)
def results(request): """ Display search results. Or rather, display a page containing javescript that will download and display the search results. :-/ """ vars = {'get':request.GET} vars['title'] = _("Search") vars['has_advanced']=False for it in ('from_date','priority','status'): if it in request.GET: if it == 'status': try: vars[it] = int(request[it]) except: vars[it] = request[it] else: vars[it] = request[it] vars['has_advanced']=True vars['status_all'] = Status.objects.all() locations = filter(lambda x:check_permission(x.permission,request.user), SearchType.objects.all().order_by('view_order')) if 'freetext' in request.GET: results = [] for typ in locations: url = typ.url % ModelDict(request.GET) #content = fetch_url(url) results.append({'url':url,'id':typ.id}) vars['results']=to_json(results) vars['types'] = locations #vars = request.GET#dict(request.GET) return tuit_render('search.html', vars, request)
def autofill(request): """ Returns the location data for the specified username as a json dict. """ try: field = request.GET['field'] if field == 'requester': username = request.GET['value'] p = User.objects.get(username=username).get_profile() res=p.__dict__ else: value = request.GET['value'] val_arr = value.split(' ') if len(val_arr) > 2 and val_arr[1] == '-': value= val_arr[0] print 'f,d', field, value data = GenericFillItem.objects.filter(condition_name__name = field, condition_value = value) res = list(data) return HttpResponse(to_json(res)) except: raise
def i18n(request): """ Send gettext-translated data in javascript format for various UI components. """ regular = [gettext_noop('Comments'),gettext_noop('Send'),gettext_noop('No comments posted yet')] trans={'$.dpText.TEXT_CHOOSE_DATE': _('Choose date'), '$.dpText.TEXT_PREV_MONTH': _('Previous month'), '$.dpText.TEXT_PREV_YEAR': _('Previous year'), '$.dpText.TEXT_NEXT_MONTH': _('Next month'), '$.dpText.TEXT_NEXT_YEAR': _('Next year'), '$.dpText.TEXT_CLOSE': _('Close'), 'Date.dayNames': [_('Sunday'),_('Monday'),_('Tuesday'),_('Wednesday'),_('Thursday'),_('Friday'),_('Saturday'),], 'Date.monthNames': [_('January'), _('February'), _('March'), _('April'), _('May'), _('June'), _('July'), _('August'), _('September'), _('October'), _('November'), _('December')], } for i in regular: trans["tuit.translations[" + to_json(i)+"]"] = _(i) # Cache-Control: private, max-age=3600, must-revalidate return tuit_render('i18n.js', {'strings':trans}, request)
def user_complete(request): query = request.GET['query'] q = make_Q(query, ('username','first_name','last_name','email',)) q = User.objects.filter(q).order_by('username') if 'search' in request.GET: u = {'ResultSet':{'totalResultsAvailable':len(q), 'totalResultsReturned':len(q), 'firstResultPosition':0, 'Result':map(lambda user: {'name': "%s - %s %s" % (user.username, user.first_name, user.last_name), 'description':'hejsan', 'url':'/tuit/account/%s'%escape_recursive(user.username)}, q) } } else: u = map(lambda user: "******" % (user.username, user.first_name, user.last_name), q) if 'contacts' in request.GET: q2 = make_Q(query, ('name','email',)) q2 = Contact.objects.filter(q2).order_by('name') u2 = map(lambda user: user.format, q2) u.extend(u2) return HttpResponse(to_json(u))
def issue_complete(request, is_complete=True): """ Used for autocompleting issues and for searching for issues. Uses text format for autocompletion, and the json based Yahoo search format for searches. """ query = request.GET['query'] offset = 0 if 'offset' in request.GET: offset = int(request.GET['offset']) q = make_Q(query, ('subject','description','issueupdate__comment','requester__username','requester__first_name','requester__last_name','location'), is_complete) q = Issue.objects.filter(q) if not request.user.is_staff: q = q.filter(requester=request.user) if 'status' in request.GET and request.GET['status'] != '': try: status = request.GET['status'] if status == 'all': # No filtering! pass else: q=q.filter(current_status = int(status)) except: #Incorrect status. Ignore... pass else: # Default: show only non-open tickets status_closed = properties['issue_closed_id'] if not hasattr(status_closed,'__iter__'): status_closed=[status_closed] q=q.exclude(current_status__in = status_closed) q = q.distinct().order_by('-creation_date') # This will fetch the items into a list that we can use map on... q=q[:] # FIXME: This filter can be moved to the database for higher speed if 'from_date' in request.GET: try: from_date = request.GET['from_date'].strip() from_date = datetime.datetime.strptime(from_date,properties['date_format']) q = filter(lambda x:x.last_update_date > from_date, q) except: #Incorrect date. Ignore... pass # FIXME: This filter is pretty tricky to move to the database, # because priority is not a field, it is the sum of two other # fields, but it should be possible to use extra_fields to make it # work. if 'priority' in request.GET and request.GET['priority'] != '': try: prios = re.match(r'^ *([0-9]+) *(\.\. *([0-9]+)|) *$', request.GET['priority']).groups() if prios[2] is None: prio = int(prios[0]) q = filter(lambda x:x.priority == prio, q) else: prio_min = int(prios[0]) prio_max = int(prios[2]) q = filter(lambda x:x.priority >= prio_min and x.priority <=prio_max, q) except: #Incorrect priority. Ignore... pass if 'search' in request.GET: tot_count = len(q) # q = q[offset:min(len(q),offset+100)] u = {'ResultSet':{'totalResultsAvailable':tot_count, 'totalResultsReturned':len(q), 'firstResultPosition':offset, 'Result':map(lambda issue: {'name':issue.subject,'description':'hejsan','url':'/tuit/ticket/view/%d'%issue.id}, q) }} else: u = map(lambda issue: "%s - %s" % (issue.id, issue.subject), q) return HttpResponse(to_json(u))
def view(request,id=None): """ This is the main issue viewing view. It shows an issue, and provides the option to send an issue update as well. """ if id is None: id = request.GET['id'] try: i=Issue.objects.get(id=id) except: return tuit_render('ticket_view.html', {}, request) if not request.user.is_staff and i.requester != request.user: return tuit_render('ticket_view.html', {}, request) keys = request.POST.copy() keys['messages'] = "" keys['update']=None keys['show_internal'] = request.user.has_perm('ticket.view_internal') keys['file_count'] = 0 keys['dependencies'] = parse_issue_dependencies(i) if request.method == 'POST': # If the form has been submitted... # # That means we're makinnng an issue update. So exciting. events = i.apply_post(request.POST) iu = IssueUpdate(issue=i, internal = 'internal' in request.POST, comment=request.POST['comment'], user=request.user, description_data={}) errors = i.validate() for name, value_list in iu.validate().iteritems(): if name in errors: errors[name].extend(value_list) else: errors[name]=value_list if not errors: Event.fire(['web_update','update'], i, iu) errors = i.validate() if not errors: iu.save() events.extend(handle_files(i, iu, request.FILES, request.POST)) events.extend(send_email('web_update', request.POST, i, iu)) iu.description_data={'type':'web','events':events,'by':request.user.username} i.save() iu.save() if 'update_dependants' in request.POST: try: update_dependants(i, iu, request.POST, set()) except: pass return HttpResponseRedirect('/tuit/ticket/view/%d' % i.id) # Redirect after successfull POST # We failed. Show errors! logging.getLogger('ticket').error('Tried to create issue update, but got the following errors: %s' % str(errors)); keys['errors'] = errors keys['update']=iu keys['dependencies'] = parse_post_dependencies(request.POST) keys['files'] = handle_files_error(i, None, request.FILES, request.POST) keys['file_count'] = len(keys['files']) keys['messages'] += format_errors(errors) keys['internal_default_mail_json'] = to_json(properties['web_internal_default_mail']) keys['external_default_mail_json'] = to_json(properties['web_external_default_mail']) keys['title'] = _('Viewing %(issue_type)s "%(id)d - %(subject)s"')% {'id': i.id, 'issue_type':i.type.name, 'subject':i.subject} keys['issue'] = i keys['kb_name'] = studly(i.subject) insert_view_data(keys, request, properties['web_external_default_mail']) return tuit_render('ticket_view.html', keys, request)
def new(request, type_name=None): """ View for creating a new ticket """ # Do a copy to get a real dict, not a weird django-style query-dict # with their pseudo-list interface. keys = request.POST.copy() keys['quick_fill'] = QuickFill.objects.all() keys['quick_fill_json'] = to_json(QuickFill.objects.all()) keys['field_fill_json'] = to_json(set(map(lambda x: x.condition_name.name, GenericFillItem.objects.filter()))) keys['status'] = Status.objects.all() keys['errors'] = {} keys['messages'] = "" type = None if type_name is None and 'type' in request.GET: type_name=request.GET['type'] if not type_name is None: type = IssueType.objects.get(name=type_name) elif 'type_id' in request.GET: type = IssueType.objects.get(id=int(request.GET['type_id'])) if not type is None: keys['title'] = _('New %s') % type.name keys['type'] = type else: keys['title'] = _('New issue') keys['ticket_new'] = True keys['file_count'] = 0 i = Issue() keys['dependencies'] = [] i.creator = request.user if request.method == 'POST': # If the form has been submitted... # We can't save more than half of the issue before getting an id for the line, so we do it in two phases # Phase 1 i.type = IssueType.objects.get(id=request.POST['type_id']) events = i.apply_post(keys) i.create_description = '[]' errors = i.validate() # FIXME: Ugly hack to get field names trasnslated in error # messages. Drop when we have fully dynamic forms in R2. name_lookup = dict(map(lambda i:(i.name, i.short_description),IssueField.objects.all())) print name_lookup formated_errors = {} for key, value in errors.iteritems(): if key in name_lookup: formated_errors[name_lookup[key]] = value elif key + "_string" in name_lookup: formated_errors[name_lookup[key+"_string"]] = value else: formated_errors[key] = value errors = formated_errors if not errors: i.save() # Phase 2 events.extend(i.apply_post(keys)) for el in ('subject', 'description'): setattr(i,el,request.POST[el]) errors = i.validate() if not errors: events.extend(handle_files(i, None, request.FILES, request.POST)) events.extend(send_email('web_create', request.POST, i, None)) i.description_data={'type':'web','events':events, 'by':request.user.username} # Fire of event handler Event.fire(['web_create','create'], i) errors = i.validate() if not errors: i.save() # If everything went ok with form submission, this is where we return logging.getLogger('ticket').info('Created issue with id %d' % i.id) url = '/tuit/ticket/view/%d' % i.id if 'continue' in request.POST: url = '/tuit/ticket/new/?type=' + cgi.escape(i.type.name) elif 'new_url' in request.POST: url = request.POST['new_url'] return HttpResponseRedirect(url) # This code is only reached oif we get an error while processing the form logging.getLogger('ticket').error('Tried to create issue, but got the following errors: %s' % str(errors)); keys['errors'] = errors keys['messages'] += format_errors(errors) keys['files'] = handle_files_error(i, None, request.FILES, request.POST) keys['file_count'] = len(keys['files']) keys['dependencies'] = parse_post_dependencies(request.POST) i=ModelWrapper(i, request.POST) else: # This is not a form submission, show an empty form if not type is None: i.type = type i.current_status = Status.objects.get(id=properties['issue_default_status']) # But wait! It should not be empty, it should be a copy of an already existing ticket if 'copy' in request.GET: template = Issue.objects.get(id=int(request.GET['copy'])) wrap_dict={} for it in ('subject','description','category','impact_string','urgency_string','requester_string','assigned_to_string','cc_string','co_responsible_string'): wrap_dict[it] =getattr(template, it) i=ModelWrapper(i, wrap_dict) else: for mail_checkbox in properties['web_create_default_mail']: keys[mail_checkbox + "_email"] = "yes" keys['types'] = IssueType.objects.all() keys['issue'] = i keys['issue_default_type'] = properties['issue_default_type'] insert_view_data(keys, request, properties['web_create_default_mail']) template = 'ticket_new.html' if 'partial' in request.GET: template = 'ticket_new_form.html' return tuit_render(template, keys, request)