def search(request): form = SearchForm(request.GET) if not form.is_valid(): return HttpResponseBadRequest(toJson(form.errors), content_type='application/json') logger.debug("parameters: %s", form.cleaned_data) collection = request.specify_collection express_search_config = get_express_search_config(collection, request.specify_user) terms = parse_search_str(collection, form.cleaned_data['q']) specific_table = form.cleaned_data['name'].lower() limit = form.cleaned_data['limit'] offset = form.cleaned_data['offset'] with models.session_context() as session: results = [ run_primary_search(session, searchtable, terms, collection, limit, offset) for searchtable in express_search_config.findall( 'tables/searchtable') if specific_table == "" or searchtable.find('tableName').text.lower() == specific_table ] result = {k: v for r in results for (k, v) in r.items()} return HttpResponse(toJson(result), content_type='application/json')
def related_search(request): from . import related_searches form = RelatedSearchForm(request.GET) if not form.is_valid(): return HttpResponseBadRequest(toJson(form.errors), content_type='application/json') logger.debug("parameters: %s", form.cleaned_data) related_search = getattr(related_searches, form.cleaned_data['name']) config = get_express_search_config(request.specify_collection, request.specify_user) terms = parse_search_str(request.specify_collection, form.cleaned_data['q']) with models.session_context() as session: result = related_search.execute(session, config, terms, collection=request.specify_collection, user=request.specify_user, offset=form.cleaned_data['offset'], limit=form.cleaned_data['limit']) return HttpResponse(toJson(result), content_type='application/json')
def load_gt_61_cols(wb_id): logger.info("load_gt_61_cols") cursor = connection.cursor() cursor.execute( """ select workbenchtemplateid from workbench where workbenchid = %s """, [wb_id]) wbtm = cursor.fetchone()[0] sql = """ select r.workbenchrowid, celldata from workbenchrow r join workbenchtemplatemappingitem mi on mi.workbenchtemplateid = %s left outer join workbenchdataitem i on i.workbenchrowid = r.workbenchrowid and mi.workbenchtemplatemappingitemid = i.workbenchtemplatemappingitemid where workbenchid = %s order by r.rownumber, vieworder """ cursor = connection.cursor() cursor.execute(sql, [wbtm, wb_id]) rows = list(group_rows(cursor.fetchall())) return http.HttpResponse(toJson(rows), content_type='application/json')
def preps_available_ids(request): # make sure the field is actually a field in the collection object table try: id_fld = Collectionobject._meta.get_field( request.POST['id_fld'].lower()).db_column except FieldDoesNotExist as e: raise http.Http404(e) co_ids = json.loads(request.POST['co_ids']) sql = """ select co.CatalogNumber, t.FullName, p.preparationid, pt.name, p.countAmt, sum(lp.quantity-lp.quantityreturned) Loaned, sum(gp.quantity) Gifted, sum(ep.quantity) Exchanged, p.countAmt - coalesce(sum(lp.quantity-lp.quantityresolved),0) - coalesce(sum(gp.quantity),0) - coalesce(sum(ep.quantity),0) Available from preparation p left join loanpreparation lp on lp.preparationid = p.preparationid left join giftpreparation gp on gp.preparationid = p.preparationid left join exchangeoutprep ep on ep.PreparationID = p.PreparationID inner join collectionobject co on co.CollectionObjectID = p.CollectionObjectID inner join preptype pt on pt.preptypeid = p.preptypeid left join determination d on d.CollectionObjectID = co.CollectionObjectID left join taxon t on t.TaxonID = d.TaxonID where pt.isloanable and p.collectionmemberid = %s and (d.IsCurrent or d.DeterminationID is null) and co.{id_fld} in ({params}) group by 1,2,3,4,5 order by 1; """.format(id_fld=id_fld, params=",".join("%s" for __ in co_ids)) cursor = connection.cursor() cursor.execute(sql, [int(request.specify_collection.id)] + co_ids) rows = cursor.fetchall() return http.HttpResponse(toJson(rows), content_type='application/json')
def preps_available_ids(request): # make sure the field is actually a field in the collection object table try: id_fld = Collectionobject._meta.get_field(request.POST['id_fld'].lower()).db_column except FieldDoesNotExist as e: raise http.Http404(e) co_ids = json.loads(request.POST['co_ids']) sql = """ select co.CatalogNumber, t.FullName, p.preparationid, pt.name, p.countAmt, sum(lp.quantity-lp.quantityreturned) Loaned, sum(gp.quantity) Gifted, sum(ep.quantity) Exchanged, p.countAmt - coalesce(sum(lp.quantity-lp.quantityresolved),0) - coalesce(sum(gp.quantity),0) - coalesce(sum(ep.quantity),0) Available from preparation p left join loanpreparation lp on lp.preparationid = p.preparationid left join giftpreparation gp on gp.preparationid = p.preparationid left join exchangeoutprep ep on ep.PreparationID = p.PreparationID inner join collectionobject co on co.CollectionObjectID = p.CollectionObjectID inner join preptype pt on pt.preptypeid = p.preptypeid left join determination d on d.CollectionObjectID = co.CollectionObjectID left join taxon t on t.TaxonID = d.TaxonID where pt.isloanable and p.collectionmemberid = %s and (d.IsCurrent or d.DeterminationID is null) and co.{id_fld} in ({params}) group by 1,2,3,4,5 order by 1; """.format(id_fld=id_fld, params=",".join("%s" for __ in co_ids)) cursor = connection.cursor() cursor.execute(sql, [int(request.specify_collection.id)] + co_ids) rows = cursor.fetchall() return http.HttpResponse(toJson(rows), content_type='application/json')
def load(wb_id): wb = get_object_or_404(models.Workbench, id=wb_id) wbtmis = models.Workbenchtemplatemappingitem.objects.filter( workbenchtemplate=wb.workbenchtemplate).order_by('vieworder') if wbtmis.count() > 60: # mysql won't join more than 61 tables. # but the following is slower so only use in that case. return load_gt_61_cols(wb_id) select_fields = ["r.workbenchrowid"] for wbtmi in wbtmis: select_fields.append("cell%d.celldata" % wbtmi.vieworder) from_clause = ["workbenchrow r"] for wbtmi in wbtmis: from_clause.append("left join workbenchdataitem cell%(vieworder)d " "on cell%(vieworder)d.workbenchrowid = r.workbenchrowid " "and cell%(vieworder)d.workbenchtemplatemappingitemid = %(wbtmi_id)d" % {'vieworder': wbtmi.vieworder, 'wbtmi_id': wbtmi.id}) sql = '\n'.join([ "select", ",\n".join(select_fields), "from", "\n".join(from_clause), "where workbenchid = %s", "order by r.rownumber", ]) cursor = connection.cursor() cursor.execute(sql, [wb_id]) rows = cursor.fetchall() return http.HttpResponse(toJson(rows), content_type='application/json')
def taxon_bar(request): cursor = connection.cursor() cursor.execute(""" SELECT t.TaxonID, t.RankID, t.ParentID, t.Name, (SELECT COUNT(*) FROM determination d WHERE t.TaxonID = d.TaxonID AND d.IsCurrent = 1) FROM taxon t WHERE t.TaxonTreeDefID = %s """, [request.specify_collection.discipline.taxontreedef_id]) # SELECT d.TaxonID, COUNT(DISTINCT d.CollectionObjectID), t.ParentID # FROM determination d # INNER JOIN taxon t ON t.TaxonID = d.TaxonID # WHERE d.CollectionMemberID = %s # AND d.IsCurrent = 1 # GROUP BY d.TaxonId # ORDER BY d.TaxonId # """, [request.specify_collection.id]) result = toJson(cursor.fetchall()) # session = Session() # query = session.query( # Determination.TaxonID, # func.count(distinct(Determination.CollectionObjectID)), # Taxon.ParentID) \ # .join(Taxon, Determination.TaxonID == Taxon.taxonId) \ # .filter(Determination.collectionMemberId == request.specify_collection.id) \ # .filter(Determination.isCurrent == True) \ # .group_by(Determination.TaxonID).order_by(Determination.TaxonID) # result = toJson(list(query)) # session.close() return HttpResponse(result, content_type='application/json')
def run(request): if settings.REPORT_RUNNER_HOST == '': raise ReportException("Report service is not configured.") port = settings.REPORT_RUNNER_PORT if port == '': port = 80 report_data = run_query(request.specify_collection, request.specify_user, request.POST['query']) if len(report_data['rows']) < 1: return HttpResponse("The report query returned no results.", content_type="text/plain") r = requests.post("http://%s:%s/report" % (settings.REPORT_RUNNER_HOST, port), data={ 'report': request.POST['report'], 'parameters': request.POST['parameters'], 'data': toJson(report_data) }) if r.status_code == 200: return HttpResponse(r.content, content_type="application/pdf") else: raise ReportException(r.text)
def ephemeral(request): try: spquery = json.load(request) except ValueError as e: return HttpResponseBadRequest(e) data = run_ephemeral_query(request.specify_collection, request.specify_user, spquery) return HttpResponse(toJson(data), content_type='application/json')
def taxon_bar(request): cursor = connection.cursor() cursor.execute( """ SELECT t.TaxonID, t.RankID, t.ParentID, t.Name, (SELECT COUNT(*) FROM determination d WHERE t.TaxonID = d.TaxonID AND d.IsCurrent = 1) FROM taxon t WHERE t.TaxonTreeDefID = %s """, [request.specify_collection.discipline.taxontreedef_id]) # SELECT d.TaxonID, COUNT(DISTINCT d.CollectionObjectID), t.ParentID # FROM determination d # INNER JOIN taxon t ON t.TaxonID = d.TaxonID # WHERE d.CollectionMemberID = %s # AND d.IsCurrent = 1 # GROUP BY d.TaxonId # ORDER BY d.TaxonId # """, [request.specify_collection.id]) result = toJson(cursor.fetchall()) # session = Session() # query = session.query( # Determination.TaxonID, # func.count(distinct(Determination.CollectionObjectID)), # Taxon.ParentID) \ # .join(Taxon, Determination.TaxonID == Taxon.taxonId) \ # .filter(Determination.collectionMemberId == request.specify_collection.id) \ # .filter(Determination.isCurrent == True) \ # .group_by(Determination.TaxonID).order_by(Determination.TaxonID) # result = toJson(list(query)) # session.close() return HttpResponse(result, content_type='application/json')
def loan_return_all_items(request): if 'returnedDate' in request.POST: returned_date = unicode(request.POST['returnedDate']) else: returned_date = date.today() discipline_id = request.specify_collection.discipline.id returned_by_id = int(request.POST.get('returnedById', request.specify_user_agent.id)) current_user_agent_id = int(request.specify_user_agent.id) record_set_id = request.POST.get('recordSetId', None) if 'loanNumbers' in request.POST: loan_nos = json.loads(request.POST['loanNumbers']) else: loan_nos = None cursor = connection.cursor() insert_loanreturnpreps(cursor, returned_date, discipline_id, returned_by_id, current_user_agent_id, record_set_id=record_set_id, loan_nos=loan_nos) prepsReturned = resolve_loanpreps(cursor, current_user_agent_id, record_set_id=record_set_id, loan_nos=loan_nos) loansClosed = close_loan(cursor, current_user_agent_id, returned_date, record_set_id=record_set_id, loan_nos=loan_nos) return http.HttpResponse(toJson([prepsReturned, loansClosed]), content_type='application/json')
def user(request): """Return json representation of the currently logged in SpecifyUser.""" from specifyweb.specify.api import obj_to_data, toJson data = obj_to_data(request.specify_user) data['isauthenticated'] = request.user.is_authenticated() if settings.RO_MODE or not request.user.is_authenticated(): data['usertype'] = "readonly" return HttpResponse(toJson(data), content_type='application/json')
def upload_status(request, wb_id): log_fnames = glob( os.path.join(settings.WB_UPLOAD_LOG_DIR, '%s_%s_*' % ( settings.DATABASE_NAME, wb_id, ))) status = status_from_log(log_fnames[0]) if len(log_fnames) > 0 else None return http.HttpResponse(toJson(status), content_type='application/json')
def user(request): """Return json representation of the currently logged in SpecifyUser.""" from specifyweb.specify.api import obj_to_data, toJson data = obj_to_data(request.specify_user) data['isauthenticated'] = request.user.is_authenticated data['available_collections'] = users_collections(connection.cursor(), request.specify_user.id) data['agent'] = obj_to_data(request.specify_user_agent) if settings.RO_MODE or not request.user.is_authenticated: data['usertype'] = "readonly" return HttpResponse(toJson(data), content_type='application/json')
def get_reports(request): reports = Spappresource.objects.filter( mimetype__startswith="jrxml", spappresourcedir__discipline=request.specify_collection.discipline) \ .filter( Q(spappresourcedir__collection=None) | Q(spappresourcedir__collection=request.specify_collection)) \ .filter( Q(spappresourcedir__specifyuser=request.specify_user) | Q(spappresourcedir__ispersonal=False)) data = objs_to_data(reports) return HttpResponse(toJson(data), content_type="application/json")
def query(request, id): limit = int(request.GET.get('limit', 20)) offset = int(request.GET.get('offset', 0)) with models.session_context() as session: sp_query = session.query(models.SpQuery).get(int(id)) distinct = sp_query.selectDistinct tableid = sp_query.contextTableId count_only = sp_query.countOnly field_specs = [QueryField.from_spqueryfield(field, value_from_request(field, request.GET)) for field in sorted(sp_query.fields, key=lambda field: field.position)] data = execute(session, request.specify_collection, request.specify_user, tableid, distinct, count_only, field_specs, limit, offset) return HttpResponse(toJson(data), content_type='application/json')
def querycbx_search(request, modelname): table = datamodel.get_table(modelname) model = getattr(models, table.name) fields = [ table.get_field(fieldname, strict=True) for fieldname in request.GET if fieldname not in ('limit', 'offset', 'forcecollection') ] if 'forcecollection' in request.GET: collection = Collection.objects.get(pk=request.GET['forcecollection']) else: collection = request.specify_collection filters = [] for field in fields: filters_for_field = [] terms = parse_search_str(collection, request.GET[field.name.lower()]) logger.debug("found terms: %s for %s", terms, field) for term in terms: filter_for_term = term.create_filter(table, field) if filter_for_term is not None: filters_for_field.append(filter_for_term) logger.debug("filtering %s with %s", field, filters_for_field) if len(filters_for_field) > 0: filters.append(reduce(or_, filters_for_field)) if len(filters) > 0: with models.session_context() as session: combined = reduce(and_, filters) query = session.query(getattr(model, table.idFieldName)).filter(combined) query = filter_by_collection(model, query, collection).limit(10) ids = [id for (id, ) in query] else: ids = [] from specifyweb.specify.api import get_model_or_404, obj_to_data specify_model = get_model_or_404(modelname) qs = specify_model.objects.filter(id__in=ids) results = [obj_to_data(obj) for obj in qs] return HttpResponse(toJson(results), content_type='application/json')
def run(request): if settings.REPORT_RUNNER_HOST == '': raise ReportException("Report service is not configured.") port = settings.REPORT_RUNNER_PORT if port == '': port = 80 report_data = run_query(request.specify_collection, request.specify_user, request.POST['query']) if len(report_data['rows']) < 1: return HttpResponse("The report query returned no results.", content_type="text/plain") r = requests.post("http://%s:%s/report" % (settings.REPORT_RUNNER_HOST, port), data={'report': request.POST['report'], 'parameters': request.POST['parameters'], 'data': toJson(report_data)}) if r.status_code == 200: return HttpResponse(r.content, content_type="application/pdf") else: raise ReportException(r.text)
def preps_available_rs(request, recordset_id): cursor = connection.cursor() cursor.execute(""" select co.CatalogNumber, t.FullName, p.preparationid, pt.name, p.countAmt, sum(lp.quantity-lp.quantityreturned) Loaned, sum(gp.quantity) Gifted, sum(ep.quantity) Exchanged, p.countAmt - coalesce(sum(lp.quantity-lp.quantityresolved),0) - coalesce(sum(gp.quantity),0) - coalesce(sum(ep.quantity),0) Available from preparation p left join loanpreparation lp on lp.preparationid = p.preparationid left join giftpreparation gp on gp.preparationid = p.preparationid left join exchangeoutprep ep on ep.PreparationID = p.PreparationID inner join collectionobject co on co.CollectionObjectID = p.CollectionObjectID inner join preptype pt on pt.preptypeid = p.preptypeid left join determination d on d.CollectionObjectID = co.CollectionObjectID left join taxon t on t.TaxonID = d.TaxonID where pt.isloanable and p.collectionmemberid = %s and (d.IsCurrent or d.DeterminationID is null) and p.collectionobjectid in ( select recordid from recordsetitem where recordsetid=%s ) group by 1,2,3,4,5 order by 1; """, [request.specify_collection.id, recordset_id]) rows = cursor.fetchall() return http.HttpResponse(toJson(rows), content_type='application/json')
def prep_interactions(request): cursor = connection.cursor() sql = """ select p.preparationid, group_concat(distinct concat(lp.loanid,'>|<', l.loannumber)), group_concat(distinct concat(gp.giftid, '>|<', g.giftnumber)), group_concat(distinct concat(ep.exchangeoutid, '>|<', e.exchangeoutnumber)) from preparation p left join loanpreparation lp on lp.preparationid = p.preparationid left join giftpreparation gp on gp.preparationid = p.preparationid left join exchangeoutprep ep on ep.preparationid = p.preparationid left join loan l on l.loanid = lp.loanid left join gift g on g.giftid = gp.giftid left join exchangeout e on e.exchangeoutid = ep.exchangeoutid where (lp.loanpreparationid is null or not lp.isresolved) and p.preparationid in(%s) group by 1; """ cursor.execute(sql, [unicode(request.POST['prepIds'])]) rows = cursor.fetchall() return http.HttpResponse(toJson(rows), content_type='application/json')
def loan_return_all_items(request): if 'returnedDate' in request.POST: returned_date = unicode(request.POST['returnedDate']) else: returned_date = date.today() discipline_id = request.specify_collection.discipline.id returned_by_id = int( request.POST.get('returnedById', request.specify_user_agent.id)) current_user_agent_id = int(request.specify_user_agent.id) record_set_id = request.POST.get('recordSetId', None) if 'loanNumbers' in request.POST: loan_nos = json.loads(request.POST['loanNumbers']) else: loan_nos = None cursor = connection.cursor() insert_loanreturnpreps(cursor, returned_date, discipline_id, returned_by_id, current_user_agent_id, record_set_id=record_set_id, loan_nos=loan_nos) prepsReturned = resolve_loanpreps(cursor, current_user_agent_id, record_set_id=record_set_id, loan_nos=loan_nos) loansClosed = close_loan(cursor, current_user_agent_id, returned_date, record_set_id=record_set_id, loan_nos=loan_nos) return http.HttpResponse(toJson([prepsReturned, loansClosed]), content_type='application/json')
def preps_available_rs(request, recordset_id): cursor = connection.cursor() cursor.execute( """ select co.CatalogNumber, t.FullName, p.preparationid, pt.name, p.countAmt, sum(lp.quantity-lp.quantityreturned) Loaned, sum(gp.quantity) Gifted, sum(ep.quantity) Exchanged, p.countAmt - coalesce(sum(lp.quantity-lp.quantityresolved),0) - coalesce(sum(gp.quantity),0) - coalesce(sum(ep.quantity),0) Available from preparation p left join loanpreparation lp on lp.preparationid = p.preparationid left join giftpreparation gp on gp.preparationid = p.preparationid left join exchangeoutprep ep on ep.PreparationID = p.PreparationID inner join collectionobject co on co.CollectionObjectID = p.CollectionObjectID inner join preptype pt on pt.preptypeid = p.preptypeid left join determination d on d.CollectionObjectID = co.CollectionObjectID left join taxon t on t.TaxonID = d.TaxonID where pt.isloanable and p.collectionmemberid = %s and (d.IsCurrent or d.DeterminationID is null) and p.collectionobjectid in ( select recordid from recordsetitem where recordsetid=%s ) group by 1,2,3,4,5 order by 1; """, [request.specify_collection.id, recordset_id]) rows = cursor.fetchall() return http.HttpResponse(toJson(rows), content_type='application/json')
def query(request, id): limit = int(request.GET.get('limit', 20)) offset = int(request.GET.get('offset', 0)) with models.session_context() as session: sp_query = session.query(models.SpQuery).get(int(id)) distinct = sp_query.selectDistinct tableid = sp_query.contextTableId count_only = sp_query.countOnly field_specs = [ QueryField.from_spqueryfield( field, value_from_request(field, request.GET)) for field in sorted(sp_query.fields, key=lambda field: field.position) ] data = execute(session, request.specify_collection, request.specify_user, tableid, distinct, count_only, field_specs, limit, offset) return HttpResponse(toJson(data), content_type='application/json')
def load_gt_61_cols(wb_id): cursor = connection.cursor() cursor.execute(""" select workbenchtemplateid from workbench where workbenchid = %s """, [wb_id]) wbtm = cursor.fetchone()[0] sql = """ select r.workbenchrowid, celldata from workbenchrow r join workbenchtemplatemappingitem mi on mi.workbenchtemplateid = %s left outer join workbenchdataitem i on i.workbenchrowid = r.workbenchrowid and mi.workbenchtemplatemappingitemid = i.workbenchtemplatemappingitemid where workbenchid = %s order by r.rownumber, vieworder """ cursor = connection.cursor() cursor.execute(sql, [wbtm, wb_id]) rows = list(group_rows(cursor.fetchall())) return http.HttpResponse(toJson(rows), content_type='application/json')
def prep_availability(request, prep_id, iprep_id=None, iprep_name=None): args = [prep_id] sql = """select p.countAmt - coalesce(sum(lp.quantity-lp.quantityresolved),0) - coalesce(sum(gp.quantity),0) - coalesce(sum(ep.quantity),0) from preparation p left join loanpreparation lp on lp.preparationid = p.preparationid left join giftpreparation gp on gp.preparationid = p.preparationid left join exchangeoutprep ep on ep.PreparationID = p.PreparationID where p.preparationid = %s """ if iprep_id is not None: from specifyweb.specify import models keyfld = models.datamodel.get_table(iprep_name).idFieldName sql += " and " + keyfld + " != %s " args.append(iprep_id) sql += " group by p.preparationid" print(sql) cursor = connection.cursor() cursor.execute(sql, args) row = cursor.fetchone() return http.HttpResponse(toJson(row), content_type='application/json')
def prep_availability(request, prep_id, iprep_id=None, iprep_name=None): args = [prep_id]; sql = """select p.countAmt - coalesce(sum(lp.quantity-lp.quantityresolved),0) - coalesce(sum(gp.quantity),0) - coalesce(sum(ep.quantity),0) from preparation p left join loanpreparation lp on lp.preparationid = p.preparationid left join giftpreparation gp on gp.preparationid = p.preparationid left join exchangeoutprep ep on ep.PreparationID = p.PreparationID where p.preparationid = %s """ if iprep_id is not None: from specifyweb.specify import models keyfld = models.datamodel.get_table(iprep_name).idFieldName sql += " and " + keyfld + " != %s " args.append(iprep_id) sql += " group by p.preparationid" print(sql) cursor = connection.cursor() cursor.execute(sql, args) row = cursor.fetchone() return http.HttpResponse(toJson(row), content_type='application/json')
def get_status(request): resp = {'available': settings.REPORT_RUNNER_HOST != ''} return HttpResponse(toJson(resp), content_type="application/json")
def upload_status(request, wb_id): log_fnames = glob(os.path.join(settings.WB_UPLOAD_LOG_DIR, '%s_%s_*' % (settings.DATABASE_NAME, wb_id,))) status = status_from_log(log_fnames[0]) if len(log_fnames) > 0 else None return http.HttpResponse(toJson(status), content_type='application/json')