Пример #1
0
def list_fragments(request):
    """Return metadata of all fragments owned by a user"""
    try:
        frags = Gene.objects.filter(owner=request.user)
    except ObjectDoesNotExist:
        return JsonResponse('Could not read fragments', ERROR)
    ret = []
    for f in frags:
        ret.append(read_meta(f))
    return JsonResponse(ret)
Пример #2
0
def part_import(request):
	"""API to import a part via AJAX"""
	if request.method == 'GET' and 'part' in request.GET:
		name = request.GET.get('part', '')
		try:
			part = Part(name)
			record = part.to_seq_record()
			Gene.add(record, 'BB', request.user)
		except Exception, e:
			return JsonResponse(e.message, ERROR)
		return JsonResponse('ok')
Пример #3
0
def set_features(request, fid):
    """Save a fragment's features"""
    if request.method == 'POST':
        try:
            g = get_gene(request.user, fid)
            feats = request.POST.get('features')
            if feats:
                write_features(g, feats)
                return JsonResponse('Done')
            return JsonResponse('No features provided', ERROR)
        except ObjectDoesNotExist:
            JsonResponse("Fragment with ID='%s' does not exist" % fid, ERROR)
    raise Http404
Пример #4
0
def get_fragment(request, fid):
    """Return a small amount of information about the fragment"""
    try:
        fid = int(fid)
    except ValueError:
        return JsonResponse("Invalid fragment id: %s" % fid, ERROR)
    g = get_gene(request.user, fid)
    return JsonResponse({
        'id': fid,
        'name': g.name,
        'desc': g.description,
        'length': g.length(),
    })
Пример #5
0
def get_sequence(request, fid):
	"""Stream the sequence in blocks of 1kB by default"""
	try:
		chunk_size = int(request.GET.get('chunk_size', 1024))
	except ValueError:
		return JsonResponse("ERROR: Invalid chunk_size '%s'." %
				request.GET.get('chunk_size', 1024), ERROR)

	pad_char = request.GET.get('pad_char', ' ')
	g = get_gene(request.user, fid)
	if g:
		resp = HttpResponse(chunk_sequence(g, chunk_size, pad_char), mimetype="text/plain")
		return resp
	return JsonResponse('Could Not Stream Sequence', ERROR)
Пример #6
0
def entrez_summary(request):
	"""	Handle JSON Entrez summary request"""
	if request.method == 'GET' and 'id' in request.GET:
		id = request.GET['id']
		db = request.GET.get('database', 'nucleotide') #assume nucleotide by default
		
		#fetch summary information for the id
		
		handle = Entrez.esummary(db=db, id=id)
		record = Entrez.read(handle)
		if record is None or len(record) < 1:
			return JsonResponse("Error: Could not get summary information for id '%s'" % id, ERROR)
		return JsonResponse(record[0]);	
	raise Http404
Пример #7
0
def fragment_remove(request, cid):
	con = get_construct(request.user, cid)
	#post = json.loads(request.raw_post_data)
	cfid = request.POST.get('cfid')
	if not cfid:
		return JsonResponse('No ConstructFragment ID specified', ERROR)
	if con:
		try:
			con.delete_cfragment(cfid)
		except ObjectDoesNotExist as e:
			return JsonResponse('No such fragment "%s" associated with construct "%s".' % (cfid, cid))
		
		return JsonResponse('OK');
	else:
		return JsonResponse('No such Construct ' + cid, ERROR)
Пример #8
0
def fragment_clipping(request, cid, cfid):
    con = get_construct(request.user, cid)
    if con:
        try:
            cf = con.cf.get(id=cfid)
        except:
            return JsonResponse('Could not find ConstructFragment(%s)' % cfid,
                                ERROR)
        t = loader.get_template('gibson/fragment_clipping.html')
        d = {
            'feature_list': cf.fragment.features.all(),
            'cfid': cfid,
            'from_absolute': not cf.start_is_relative(),
            'to_absolute': not cf.end_is_relative(),
            'length': cf.fragment.length(),
            'max': cf.fragment.length() - 1,
        }
        if cf.start_is_relative():
            d['start_feat'] = cf.start_feature.id
        d['start_offset'] = cf.start_offset
        if cf.end_is_relative():
            d['end_feat'] = cf.end_feature.id
        d['end_offset'] = cf.end_offset

        c = RequestContext(request, d)
        return HttpResponse(t.render(c))
    raise Http404
Пример #9
0
def manual_add(request):
	"""Add a fragment manually"""
	if request.method == 'GET':
		meta = MetaForm(request.GET)
		seq = SequenceForm(request.GET)
		if meta.is_valid() and seq.is_valid():
			record = SeqRecord(	seq.cleaned_data['seq'],
								name=meta.cleaned_data['name'], 
								id=meta.cleaned_data['name'],
								description=meta.cleaned_data['desc'])
			Gene.add(record, 'MN', request.user)
			return JsonResponse('OK');
		#figure out what the errors where
		errors = meta.errors
		errors.update(seq.errors)
		return JsonResponse(errors, ERROR)
	raise Http404
Пример #10
0
def get_features(request, fid):
    """Get a fragment's features"""
    g = get_gene(request.user, fid)
    return JsonResponse({
        'feats': read_features(g),
        'alpha': get_alphabet(),
        'length': len(g.sequence),
    })
Пример #11
0
def construct_delete(request, cid):
    con = get_construct(request.user, cid)
    if con:
        con.delete()
        if request.is_ajax():
            return JsonResponse('/gibthon')
        return HttpResponseRedirect('/gibthon')
    else:
        return HttpResponseNotFound()
Пример #12
0
def entrez_search(request):
	"""	Handle JSON Entrez search request"""
	if request.method == 'GET':# and request.is_ajax():
		query = request.GET.get('query', '');
		db = request.GET.get('database', 'nucleotide') #assume nucleotide by default
		if query != '' and query != None:
			#fetch a list of Ids which match
			handle = Entrez.esearch(db=db, term=query)
			record = Entrez.read(handle)
			ids = record['IdList']
			if len(ids) == 0:
				return JsonResponse("No results for search '%s' on database '%s'." % (query, db), ERROR)
			else:
				return JsonResponse(ids)
		else:
			return JsonResponse("Error: Blank search query", ERROR);
		
	raise Http404
Пример #13
0
def save_settings(request, cid):
	print 'update_settings request.method = %s' % request.method
	if request.method == 'POST':
		con = get_construct(request.user, cid)
		if not con:
			return JsonResponse({
				'errors': {
					'all':"Construct with id '%s' not found",
					},} % cid, ERROR)
		form = SettingsForm(request.POST, instance=con.settings)
		if form.is_valid():
			form.save()
			con.reset()
			data = {}
			for key,value in form.cleaned_data.items():
				data[key] = str(value);
			return JsonResponse({'modified': con.last_modified(), 'fields': data})
		return JsonResponse({'errors': form.errors,}, ERROR)
	raise Http404
Пример #14
0
def construct_add(request):
    if request.method == 'POST':
        rp = fix_request(request.POST)
        form = ConstructForm(rp)
        if form.is_valid():
            c = form.save()
            c.owner = request.user
            c.save()
            return JsonResponse({
                'url': '/gibthon/%s/' % c.id,
            })
        t = loader.get_template('gibson/constructform.html')
        con = Construct.objects.all().filter(owner=request.user)
        c = RequestContext(request, {
            'construct_form': form,
        })
        return JsonResponse({
            'html': t.render(c),
        }, ERROR)
    else:
        return HttpResponseNotFound()
Пример #15
0
def set_meta(request, fid):
	"""Update a fragment's metadata"""
	if request.method == 'POST':
		try:
			g = get_gene(request.user, fid)
			meta = {'name': request.POST.get('name'), 
							'desc': request.POST.get('desc'),
							}
			meta['annots'] = []
			for i in range(0, len(request.POST) -2):
				m = request.POST.getlist('annots[%s][]'%i)
				if m:
					meta['annots'].append(m)
			print 'meta = %s' % meta
			if meta:
				write_meta(g, meta)
				return get_meta(request, fid)
			return JsonResponse("No metadata supplied.", ERROR)			
		except ObjectDoesNotExist:
			return JsonResponse("Fragment with ID='%s' does not exist." % fid, ERROR)
	raise Http404
Пример #16
0
def entrez_import(request):
	"""Handle a request to import an ID"""
	if request.method == 'GET' and 'id' in request.GET:
		id = request.GET['id']
		db = request.GET.get('database', 'nucleotide') #assume nucleotide by default
		handle = Entrez.efetch(db=db, id=id, rettype="gb")
		records = SeqIO.parse(handle, 'gb')
		for r in records:
			if len(Gene.objects.filter(name=r.name, owner=request.user)) == 0:
				Gene.add(r, 'NT', request.user)
		return JsonResponse("Imported id '%s' from Entrez." % id)
		
	raise Http404
Пример #17
0
def save_order(request, cid):
	con = get_construct(request.user, cid)
	cfid = request.POST.getlist('cfid[]')
	direction = request.POST.getlist('direction[]')
	if not cfid:
		return JsonResponse('No cfids provided.', ERROR)
	if not direction:
		return JsonResponse('No directions provided', ERROR)
	if len(cfid) != len(con.cf.all()):
		return JsonResponse('Only %s ConstructFragments provided, %s required.' 
				% (len(cfid), len(con.cf.all())), ERROR)
	if len(direction) != len(con.cf.all()):
		return JsonResponse('Only %s directions provided, %s required.' 
				% (len(direction), len(con.cf.all())), ERROR)
	
	if con:
		dirs = []
		for d in direction:
			dirs.append(directions.get(d, ' '))
		con.reorder_cfragments(cfid, dirs)
		return JsonResponse({'modified': con.last_modified(),});
	else:
		return HttpResponseNotFound()
Пример #18
0
def get_info(request, cid):
	"""Get information about a construct"""
	try:
		c = get_construct(request.user, cid)
		cfs = []
		fs = []
		for cf in c.cf.all():
			cfs.append(cf2dict(cf));
			g = get_gene(request.user, cf.fragment.id)
			fs.append(read_meta(g))
			
		ret = {
            'id': cid,
			'name': c.name,
			'desc': c.description,
			'length': c.length(),
			'cfs': cfs,
			'fs': fs,
			'created': c.last_modified(),
		}
		return JsonResponse(ret)
	except ObjectDoesNotExist:
		return JsonResponse('Construct %s not found.' % s, ERROR)
	raise Http404
Пример #19
0
def save_meta(request, cid):
	"""	Save a construct's metadata
		Post Data, all optional
		name, desc
	"""
	if request.method == 'POST':
		con = get_construct(request.user, cid)
		if not con:
			return JsonResponse({'errors': 
				{'all': "Construct with id '%s' not found" % cid,}}, ERROR)
		name = request.POST.get('name', con.name)
		desc = request.POST.get('desc', con.description)
		if (name != con.name) or (desc != con.description):
			con.name = name
			con.description = desc
			try:
				con.save()
			except Exception as e:
				return JsonResponse('One or more fields are too long.', ERROR)
				
		return JsonResponse({'modified': con.last_modified(), 
			'fields': {'name': con.name, 'desc': con.description}});
		
	raise Http404
Пример #20
0
def construct_fragment(request, cid):
    con = get_construct(request.user, cid)
    if con and not request.is_ajax():
        t = loader.get_template('gibson/constructfragment.html')
        cf_list = con.cf.all()
        feature_list = [FeatureListForm(cf, con) for cf in cf_list]
        list = zip(cf_list, feature_list)
        c = RequestContext(request, {'list': list})
        return HttpResponse(t.render(c))
    if con and request.is_ajax():
        cf_list = con.cf.all()
        frag_list = [{
            'fid': cf.fragment.id,
            'cfid': cf.id,
            'name': cf.fragment.name,
            'desc': cf.fragment.description,
            'length': abs(cf.end() - cf.start()),
        } for cf in cf_list]
        return JsonResponse(frag_list)

    return HttpResponseNotFound()
Пример #21
0
def fragment_add(request, cid):
	con = get_construct(request.user, cid)
	if con:
		fid = request.POST.get('fid')
		
		if not fid:
			return JsonResponse("No fragment id provided", ERROR)
		f = get_fragment(request.user, fid)
		
		pos = request.POST.get('pos', 0);
		strand = request.POST.get('dir', 1);

		try:
			pos = int(pos)
		except ValueError as e:
			return JsonResponse('Position must be an integer, not "%s"' % pos, ERROR)
		try:
			strand = int(strand)
		except ValueError as e:
			return JsonResponse('Direction must be an integer, not "%s"' % strand,
					ERROR)
		if strand not in [-1, 1]:
			return JsonResponse('Strand must be 1 or -1, not "%s"' %strand, ERROR)
		
		direction = 'f'
		if strand == -1:
			direction = 'r'
		
		if f:
			cf = con.add_fragment(f, pos, direction)
			if cf:
				return JsonResponse(cf2dict(cf))
			else:
				return JsonResponse('Could not add fragment %s to construct %s' % (fid,
					cid), ERROR)
		else:
			if request.is_ajax():
				return JsonResponse('Could not find fragment "%s"' % fid, ERROR)
			return HttpResponseNotFound()
	else:
		return HttpResponseNotFound()
Пример #22
0
def apply_clipping(request, cid, cfid):
    con = get_construct(request.user, cid)
    if con:
        try:
            cf = con.cf.get(id=cfid)
        except:
            return JsonResponse('Could not find ConstructFragment(%s)' % cfid,
                                ERROR)

        try:
            f_type = request.POST['from_type'].lower()
            t_type = request.POST['to_type'].lower()

            if f_type == 'absolute':
                start = int(request.POST['from_abs'])
                if start < 0 or start > cf.fragment.length() - 1:
                    raise ValueError('"start" must be within range [0:%i]' %
                                     cf.fragment.length() - 1)
                if cf.start_offset != start or cf.start_feature != None:
                    cf.start_offset = start
                    cf.start_feature = None
                    con.processed = False
            elif f_type == 'relative':
                start = int(request.POST['from_rel'])
                start_fid = int(request.POST['start_feat'])
                print "available ids are %s" % [
                    feat.id for feat in cf.fragment.features.all()
                ]
                start_feature = cf.fragment.features.get(id=start_fid)
                if cf.start_offset != start or cf.start_feature != start_feature:
                    cf.start_offset = start
                    cf.start_feature = start_feature
                    con.processed = False
            else:
                raise ValueError('"f_type" must be "absolute" or "relative"')

            if t_type == 'absolute':
                end = int(request.POST['to_abs'])
                if end < 0 or end > cf.fragment.length() - 1:
                    raise ValueError('"end" must be within range [0:%i]' %
                                     cf.fragment.length() - 1)
                if cf.end_offset != end or cf.end_feature != None:
                    cf.end_offset = end
                    cf.end_feature = None
                    con.processed = False
            elif t_type == 'relative':
                end = int(request.POST['to_rel'])
                end_fid = int(request.POST['end_feat'])
                end_feature = cf.fragment.features.get(id=end_fid)
                if cf.end_offset != end or cf.end_feature != end_feature:
                    cf.end_offset = end
                    cf.end_feature = end_feature
                    con.processed = False
            else:
                raise ValueError('"t_type" must be "absolute" or "relative"')

        except KeyError as e:
            return JsonResponse('Value required for "%s"' % e.message, ERROR)
        except ValueError as e:
            return JsonResponse('ValueError: %s' % e.message, ERROR)
        except ObjectDoesNotExist as e:
            return JsonResponse(
                'DoesNotExist: %s (%s)' % (e.message, start_fid), ERROR)

        cf.save()
        con.save()
        return JsonResponse('OK')
    raise Http404
Пример #23
0
def get_meta(request, fid):
    """get a particular fragment's metadata"""
    g = get_gene(request.user, fid)
    return JsonResponse( read_meta(g))
Пример #24
0
def crop(request, fid):
	"""crop the fragment as specified"""
	try:
		fid = int(fid)
	except ValueError:
		return JsonResponse("Invalid fragment id: %s" % fid, ERROR)
	g = get_gene(request.user, fid)
	if not g:
		return JsonResponse('Could not get fragment %s'%fid, ERROR)
	try:
		start = int(request.POST.get('start'))
		end = int(request.POST.get('end'))
	except ValueError:
		return JsonResponse('Start and end must be valid integers', ERROR)
	
	try:
		f_internal = bool(int(request.POST.get('f_internal', 1)))
		f_all = bool(int(request.POST.get('f_all', 0)))
	except ValueError:
		return JsonResponse('f_internal and f_all must be 1 or 0', ERROR)
	if f_all and not f_internal:
		return JsonResponse(
			'Cannot keep all features without keeping internal ones', ERROR)
	result = request.POST.get('result', 'new')
	if result not in ['new', 'overwrite']:
		return JsonResponse(
			'Result type must be \'new\' or \'overwrite\', not %s' % result,
				ERROR)
	new_name = request.POST.get('new_name')
	new_desc = request.POST.get('new_desc')
	if (result == 'new') and not new_name:
		return JsonResponse(
			'Must specify non-empty new_name when result type is new', ERROR)

	#build a list of features we want to keep
	feats = []
	if f_internal:
		for f in g.features.all():
			#internal features
			if (f.start >= start) and (f.end <= end):
				feats.append(f)
			elif f_all:
				if ( ((f.start > start) and (f.start < end)) or #starts in selection 
						((f.end < end) and (f.end > start)) or #ends in selection
						((f.start < start) and (f.end > end)) ): #selection is subset
					feats.append(f)

	#get or make the target gene
	if result == 'new':
		target = Gene(owner=request.user,
			name=new_name,
			description=new_desc,
			sequence=g.sequence[start:end])
		target.save()
		#copy references
		for r in g.references.all():
			nr = Reference(gene=target,
				title=r.title,
				authors=r.authors,
				journal=r.journal,
				medline_id=r.medline_id,
				pubmed_id=r.pubmed_id)
			nr.save()
		#copy annotations
		for a in g.annotations.all():
			na = Annotation(gene=target,
				key=a.key,
				value=a.value)
			na.save()
	elif result == 'overwrite':
		target = g
		g.sequence = g.sequence[start:end]
		#clear out old features
		Feature.remove(g)

	#copy the features for adding onto the new fragment
	for f in feats:
		nf = Feature(gene=target,
			type=f.type,
			direction=f.direction,
			start=max(f.start - start, 0),
			end=min(f.end - start, end - start))
		nf.save()

	target.save()
	
	return JsonResponse(target.id)