def handle(self, *args, **options): # filename = args['filename'] subfields = True filename = options["from"] items = [] db = WFItem.get_db() orig_item = WFItem.view("couchflow/item_names", include_docs=True)["libro"].first() org_json_item = orig_item.to_json() counter = 0 i = 0 for record in iter_iso_records(filename, subfields): i += 1 json_item = clone_json(org_json_item) json_item["fields_properties"]["99989"]["list"][0]["exec_value"] = ["catalogado"] copies = [] has_isbn = False for key, fields in record.iteritems(): key = "%03d" % int(key) if key == "020": has_isbn = True if key == "852": copies = fields continue add_field(key, fields, json_item) if not has_isbn and options["fake_isbn"]: json_item["fields_properties"]["1020"]["list"][0]["subfields"]["a"]["exec_value"] = [uuid.uuid4().hex] items.append(json_item) # add existences for field in copies: json_item = clone_json(json_item) add_field("852", [field], json_item) add_field("1111", [{"_": "existencia"}], json_item) items.append(json_item) if len(items) >= options["per_iter"]: if not options["dry_run"]: db.bulk_save(items, use_uuids=False) counter += len(items) items = [] print "%s %s items (total %s)" % ( "Parsed" if options["dry_run"] else "Inserted", options["per_iter"], counter, ) if items and not options["dry_run"]: db.bulk_save(items, use_uuids=False) counter += len(items) print print "Done, %s items" % counter print ""
def user_loans(request, user_id): """ Returns the user loans as a json object """ # use custom wrapper here, becouse default don't let you access to view keys loans = WFItem.view('circulation/loans', include_docs=True, wrapper=WFItem.wrap, startkey=[user_id], endkey=[user_id, {}, {}]) reserves = WFItem.view('circulation/reserves', include_docs=True, wrapper=WFItem.wrap, startkey=[user_id], endkey=[user_id, {}, {}]) start = int(request.POST['iDisplayStart']) length = int(request.POST['iDisplayLength']) secho = int(request.POST['sEcho']) + 1 count = len(loans) + len(reserves) columns = [] for loan in loans: user_id, start, end = loan['_doc']['key'] start, end = format_date(start), format_date(end) start = start.strftime("%d/%m/%Y") end = end.strftime("%d/%m/%Y") columns.append([ loan._id, loan.inventory_nbr, "prestamo", loan.title, start, end, "" ]) for reserve in reserves: user_id, start, end = reserve['_doc']['key'] start, end = format_date(start), format_date(end) start = start.strftime("%d/%m/%Y") end = end.strftime("%d/%m/%Y") columns.append([ reserve._id, reserve.inventory_nbr, "reserva", reserve.title, start, end, "" ]) return_dict = { "sEcho": secho, "iTotalRecords": count, "iTotalDisplayRecords": count, "aaData": columns } return jsonfy(**return_dict)
def delete_loan(request, what, item_id): """ Remove a loan from an item by item_id """ item = WFItem.get(item_id) # item must have a loan if what == "loan" and not item.loan.start: return jsonfy(error='no existe el prestamo') # item must have a reserve elif what == "reserve" and not item.reserves: return jsonfy(error='no existe la reserve') if what == "loan": CirculationLog(type='return', item_id=item_id, item_type=item.item_type, user_id=item.loan.user_id, loan_type=item.loan.type).save() item.loan = Loan() else: # don't support pop #item.reserves.pop() del (item.reserves[0]) item.save() return jsonfy(item=item_id, status='loan removed', what=what)
def renew_loan(request, item_id): item = WFItem.get(item_id) # TODO: get days from config days = 7 start = item.loan.end end = get_business_day(start + datetime.timedelta(days=days)) actual_days = (end - start).days if item.reserves and item.reserves[0].start < end: return jsonfy(item=item_id, error="Se encuentra reservado") old_end = item.loan.end item.loan.end = end if not item.loan.renew_count: item.loan.renew_count = 0 item.loan.renew_count += 1 item.save() CirculationLog(type='renew', date=old_end, length=actual_days, item_id=item_id, item_type=item.item_type, loan_type=item.loan.type, user_id=item.loan.user_id).save() return jsonfy(item=item_id, status='loan renewed')
def gen_authorize_csv(request): if not (request.user.is_superuser or AUTHORIZE_GROUP in request.user.group_names): return HttpResponseForbidden('403 Forbidden') filename = time.strftime(CSV_FILENAME) response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename=%s' % filename csvfile = csv.writer(response) csvfile.writerow([z for (x, y, z) in CSV_COLUMNS]) db = WFItem.get_db() items = db.view('couchflow/filter_items', include_docs=True)[AUTHORIZE_STATE] def get_field_utf8(*args): """thank you python2""" retval = (get_field(*args) or [''])[0] if type(retval) == unicode: return retval.encode("utf-8", "replace") return retval for item in items: csvfile.writerow([get_field_utf8(item['doc'], x, y) for (x, y, z) in CSV_COLUMNS]) return response
def catalog_items(status, user): if status.endswith('libro'): wfname = 'procesos_tecnicos' elif status.endswith('revista'): wfname = 'hemeroteca' else: raise Exception, 'revista or libro' filter_items = WFItem.view('couchflow/filter_items') items_query = filter_items[status] selected_items = [item['id'] for item in items_query] if not selected_items: return workflows = WorkFlow.view("couchflow/orig_workflows", include_docs=True) workflows = workflows[wfname] workflow = workflows.one() clone = clone_this_wf(workflow._id, user._id) clone.set_enabled() try: clone.save() except Exception, error: print error
def update_1(self): """ change exec_value of fields that are not list as a list """ db = WFItem.get_db() docs = list(db.view('couchflow/items_cloned', include_docs=True).all()) print 'Updating %s items' % len(docs), invalid = 0 update_docs = [] for rdoc in docs: doc = rdoc['value'] if 'fields_properties' not in doc: print 'have not fields_properties', doc['_id'] continue for _id, prop in doc['fields_properties'].iteritems(): for field in prop['list']: if not 'exec_value' in field or not field['exec_value']: field['exec_value'] = [] invalid += 1 if type(field['exec_value']) is not list: field['exec_value'] = [field['exec_value']] invalid += 1 update_docs.append(doc) db.bulk_save(update_docs) print ' [DONE]' print 'updated %s invalid fields' % invalid print 'Successfully Updated db'
def index(request): user = request.user if not user.is_staff: return HttpResponseRedirect("/circulation/user/me") filter_wflows(user) if user.is_superuser: user = None tasks = get_tasks(user=user) status_tasks = get_status(user=user) modules = ['estado', 'pendientes'] context = {'tasks': tasks, 'modules': modules, 'status_tasks': status_tasks, 'module_name': 'Inicio'} context['can_authorize'] = False # "not user" means "is admin" here if not user or AUTHORIZE_GROUP in request.user.group_names: db = WFItem.get_db() items_to_authorize = len(db.view('couchflow/filter_items', include_docs=True)[AUTHORIZE_STATE]) if items_to_authorize: context['can_authorize'] = True context['items_to_authorize'] = items_to_authorize return render_to_response('staticviews/adquisition.html', context, context_instance=RequestContext(request))
def loan_ticket(request, item_id): item = WFItem.get(item_id) user = User.get(item.loan.user_id) context = { "user": user, "item": item, "end": item.loan.end.strftime("%d/%m/%Y"), } return render_to_response('circulation/loan_ticket.html', context)
def admin(request): user = request.user context = {"user": user} wf_items = list(WFItem.view("couchflow/items", include_docs=True)) save_config(request, wf_items) settings = Config.get_or_create("search_settings") default_type = settings.values.get('default_type', '') if request.method == "POST": post_default_type = request.POST.get('default_type', '') if post_default_type != default_type: settings.values['default_type'] = post_default_type.lower() settings.save() default_type = post_default_type items = [] for item in wf_items: fields = {} for _id, ifields in item.fields_properties.iteritems(): # Just marc fields if int(ifields['id']) > 1000: continue field_name = ifields['id'] if ifields['list'][0].subfields: default_field = { 'id': ifields['id'], 'name': ifields['field_name'], 'subfields': {} } subfields = fields.setdefault(field_name, default_field)["subfields"] for subfield in ifields['list'][0].subfields.values(): sfield_name = '%s_%s' % (ifields['id'], subfield.field_name) sfield = subfields.setdefault(sfield_name, {}) sfield['name'] = subfield.field_name fields[field_name]['subfields'] = sorted(subfields.items()) else: fields.setdefault(field_name, {})['id'] = field_name fields[field_name]['name'] = ifields.field_name items.append((item.name, item._id, sorted(fields.items()))) context['items'] = items context['default_type'] = default_type.lower() return render_to_response('search/admin.html', context)
def admin(request): user = request.user context = {"user": user} wf_items = list(WFItem.view("couchflow/items", include_docs=True)) save_config(request, wf_items) settings = Config.get_or_create("search_settings") default_type = settings.values.get('default_type', '') if request.method == "POST": post_default_type = request.POST.get('default_type', '') if post_default_type != default_type: settings.values['default_type'] = post_default_type.lower() settings.save() default_type = post_default_type items = [] for item in wf_items: fields = {} for _id, ifields in item.fields_properties.iteritems(): # Just marc fields if int(ifields['id']) > 1000: continue field_name = ifields['id'] if ifields['list'][0].subfields: default_field = {'id': ifields['id'], 'name': ifields['field_name'], 'subfields': {}} subfields = fields.setdefault(field_name, default_field)["subfields"] for subfield in ifields['list'][0].subfields.values(): sfield_name = '%s_%s' % (ifields['id'], subfield.field_name) sfield = subfields.setdefault(sfield_name, {}) sfield['name'] = subfield.field_name fields[field_name]['subfields'] = sorted(subfields.items()) else: fields.setdefault(field_name ,{})['id'] = field_name fields[field_name]['name'] = ifields.field_name items.append((item.name, item._id, sorted(fields.items()))) context['items'] = items context['default_type'] = default_type.lower() return render_to_response('search/admin.html', context)
def return_loan_ticket(request, user_id, item_id): item = WFItem.get(item_id) now = datetime.datetime.now() user = User.get(user_id) context = { "user": user, "item": item, "end": now.strftime("%d/%m/%Y"), } return render_to_response('circulation/return_loan_ticket.html', context)
def get_item_inventory(request, item_id): """ Returns the list of inventory items """ # TODO: Should this functiong get urn instead item_id? try: item = WFItem.get(item_id) except ResourceNotFound: return jsonfy(error='ResourceNotFound') urn = item.urn if not urn: return jsonfy(error='InvalidItem') items = WFItem.view('couchflow/by_urn', include_docs=True, startkey=urn, endkey=urn).all() return jsonfy(items=[item.inventory_nbr for item in items])
def filter_wflows(user): for i in ('libro', 'revista'): catalog_items('a catalogar %s' % i, user) # TODO return db = FilterWFItems.get_db() wf_tasks = db.view("couchflow/wf_by_first_task_type", include_docs=True)["FilterWFItems":"FilterWFItems"] tasks = {} wflows = [] wf_tasks = wf_tasks.all() for value in wf_tasks: if value["doc"]["doc_type"] == "WorkFlow": wflows.append(WorkFlow.wrap(value["doc"])) elif value["doc"]["doc_type"] == "FilterWFItems": task = FilterWFItems.wrap(value["doc"]) tasks[task._id] = task for wf in wflows: task = tasks.get(wf.first_task_id, None) if not task: raise Exception, "Check" field = task.item_fields.get("99989", None) print "Filter by", field if not field: print "cant get status field" continue filter_items = WFItem.view('couchflow/filter_items') items_query = filter_items[field] selected_items = [item['id'] for item in items_query] if not selected_items: continue clone = clone_this_wf(wf._id, user._id) clone.set_enabled() try: clone.save() except Exception, error: print error tasks = Task.view("couchflow/activetask", include_docs=True) tasks = tasks[clone._id] task = tasks.one() task.wfitems_ids = selected_items task.save() task.active_conector()
def get_reserves_item(self, item_id): start = datetime.date.today() end = start + datetime.timedelta(days=7) requested_item = WFItem.get(item_id) urn = requested_item.urn if not urn: return jsonfy(error='invalid urn') items = WFItem.view('couchflow/by_urn', include_docs=True, startkey=urn, endkey=urn).all() loanable = False loanable_item = None for item in items: if not item.inventory_nbr: print "inventory_nbr is None" continue if not item.loan.start: loanable = True for reserve in item.reserves: if end >= reserve.start: print "item unlonable:" print "start:%s end: %s" % (start, end) print reserve print loanable = False break if loanable: loanable_item = item break
def return_loan(request, nro_inv=None): """ Returns a loan by inventory number """ context = {"user": request.user} if not request.method == "POST": return render_to_response('circulation/return_loan.html', context) nro_inv = request.POST.get("inventory_nbr", None) if not nro_inv: context["status"] = "Debe ingresar el numero de inventario" return render_to_response('circulation/return_loan.html', context) items = WFItem.view('couchflow/by_inventory_nbr', include_docs=True, startkey=nro_inv, endkey=nro_inv) if len(items) > 1: print "should only be one item" item = items.first() if not item: context["status"] = "Ese item no existe" return render_to_response('circulation/return_loan.html', context) if not item.loan.start: context["status"] = "Ese item no se encuentra prestado" return render_to_response('circulation/return_loan.html', context) # remove loan old_loan_type = item.loan.type old_loan_user = item.loan.user_id item.loan = Loan() item.save() CirculationLog(type='return', item_id=item._id, item_type=item.item_type, user_id=old_loan_user, loan_type=old_loan_type).save() context["status"] = 'El item "%s" ha sido devuelto exitosamente.' % nro_inv return render_to_response('circulation/return_loan.html', context)
def authorize_clear(request): if request.method != 'POST' or not (request.user.is_superuser or AUTHORIZE_GROUP in request.user.group_names): return HttpResponseForbidden('403 Forbidden') db = WFItem.get_db() items = db.view('couchflow/filter_items', include_docs=True)[AUTHORIZE_STATE] docs = [] for item in items: doc = item['doc'] try: doc["fields_properties"]["99989"]["list"][0]["exec_value"][0] = \ AUTHORIZE_STATE_AFTER except (KeyError, IndexError), e: print "Error changing state of document: %s %s" % (type(e), e) else: docs.append(doc)
def reserve_to_loan(request, item_id): item = WFItem.get(item_id) reserve = item.reserves.pop() item.loan = Loan.wrap(reserve.to_json()) item.save() parse_date = lambda x: datetime.datetime.strptime(x, "%Y-%m-%d") length = (parse_date(item.loan.end) - parse_date(item.loan.start)).days CirculationLog(type='loan', date=item.loan.start, length=length, item_type=item.item_type, loan_type=item.loan.type, item_id=item._id, user_id=item.loan.user_id).save() return jsonfy(item=item_id, status='loan removed')
def update_0(self): """ add support to repeteable fields with subfields """ db = WFItem.get_db() docs = list(db.view('couchflow/item_names', include_docs=True).all()) docs += list(db.view('couchflow/items_cloned', include_docs=True).all()) doc_key_values = {'indicator1': '', 'indicator2':'', 'subfields':{}, 'exec_value':[]} print 'Updating %s items' % len(docs), update_docs = [] for rdoc in docs: doc = rdoc['value'] if 'fields_properties' not in doc: print 'have not fields_properties', doc['_id'] continue for _id, prop in doc['fields_properties'].iteritems(): prop['doc_type'] = 'Fields' new_field = {'doc_type': 'Field'} for key, value in doc_key_values.iteritems(): new_field[key] = prop.get(key, value) if key in prop: del(prop[key]) prop['list'] = [new_field] update_docs.append(doc) db.bulk_save(update_docs) print ' [DONE]' print 'Successfully Updated db'
def handle(self, *args, **options): if len(args) != 2: raise CommandError("Usage: mass_field_type_change " + self.args) field_type, field_id = args subfield_id = None if '_' in field_id: field_id, subfield_id = field_id.split('_', 1) db = WFItem.get_db() docs = list(db.view('couchflow/item_names', include_docs=True).all()) docs += list(db.view('couchflow/items_cloned', include_docs=True).all()) print 'Updating %s items' % len(docs) error_count = 0 unchanged_count = 0 update_docs = [] old_types = {} def update(target): if target['type'] == field_type: return False else: old_types.setdefault(target['type'], 0) old_types[target['type']] += 1 target['type'] = field_type return True for rdoc in docs: doc = rdoc['value'] try: field = doc['fields_properties'][field_id] changed = False if subfield_id: for field_i in field['list']: changed = changed or \ update(field_i['subfields'][subfield_id]) else: changed = changed or update(field) if changed: update_docs.append(doc) else: unchanged_count += 1 except KeyError: error_count += 1 print "KeyError count: %s" % error_count print "Unchanged docs: %s" % unchanged_count if len(update_docs): print "Old types:" print " %s" % '\n '.join(['%s: %s' % x for x in old_types.items()]) print "Number of documents to update: %s" % len(update_docs) print "Doing bulk save..." db.bulk_save(update_docs) print "Done" else: raise CommandError("No documents to update")
def handle(self, *args, **options): if len(args) != 2: raise CommandError("Usage: mass_field_type_change " + self.args) field_type, field_id = args subfield_id = None if '_' in field_id: field_id, subfield_id = field_id.split('_', 1) db = WFItem.get_db() docs = list(db.view('couchflow/item_names', include_docs=True).all()) docs += list( db.view('couchflow/items_cloned', include_docs=True).all()) print 'Updating %s items' % len(docs) error_count = 0 unchanged_count = 0 update_docs = [] old_types = {} def update(target): if target['type'] == field_type: return False else: old_types.setdefault(target['type'], 0) old_types[target['type']] += 1 target['type'] = field_type return True for rdoc in docs: doc = rdoc['value'] try: field = doc['fields_properties'][field_id] changed = False if subfield_id: for field_i in field['list']: changed = changed or \ update(field_i['subfields'][subfield_id]) else: changed = changed or update(field) if changed: update_docs.append(doc) else: unchanged_count += 1 except KeyError: error_count += 1 print "KeyError count: %s" % error_count print "Unchanged docs: %s" % unchanged_count if len(update_docs): print "Old types:" print " %s" % '\n '.join( ['%s: %s' % x for x in old_types.items()]) print "Number of documents to update: %s" % len(update_docs) print "Doing bulk save..." db.bulk_save(update_docs) print "Done" else: raise CommandError("No documents to update")
def loan(request, what, user_id, item_id, loan_type=None): """ Make a loan/reserve """ # If date it's a reserve else it's a loan date = request.GET.get("date", None) user = User.get(user_id) if not user: return jsonfy(error='user not found') # TODO: get days from config days = 7 if loan_type == 'room': days = 1 if date: date = format_date(date, '%d/%m/%Y') start = get_business_day(date) start = get_business_day(datetime.date.today()) end = get_business_day(start + datetime.timedelta(days=days)) actual_days = (end - start).days requested_item = WFItem.get(item_id) # TODO: re do everything to use one item #urn = requested_item.urn #if not urn: # return jsonfy(error='invalid urn') #items = WFItem.view('couchflow/by_urn', # include_docs=True, startkey=urn, endkey=urn).all() items = [requested_item] loanable_items = [] for item in items: if not item.inventory_nbr: print "inventory_nbr is None" continue # it's a reserve and item have a reserve # and it only must support 1 reserve per item if date and item.reserves: print 'No se puede reservar un item reservado' continue # it's a loan and item have a loan if not date and item.loan.start: print 'No se puede prestar un item prestado' continue # if nave no reserve and no loan it can # be given to anyone, so empty the list # and make it the only option if not item.reserves and not item.loan.start: loanable_items = [item] print "ideal, se puede prestar o reservar" break # if it's a loan, and item has not a loan and if (date and not item.reserves): loanable_items.append(item) # if it's a loan, and item has not a loan and # no fit in start and reserve if (not date and not item.loan.start): item_days = (item.reserves[0].start, item.reserves[0].end) new_start, new_end = get_hole([item_days], start, days) if new_start != start and new_end != end: loanable_items = [item] break # TODO: return json error # can't loan a item that is loaned if not loanable_items: all_dates = [] for item in items: if item.loan.start and not item.reserves: all_dates.append(item.loan.end) elif item.reserves: all_dates.append(item.reserves[0].end) if not all_dates: return jsonfy(item=item_id, error="no se encuentra disponible") max_date = get_business_day(min(all_dates) + datetime.timedelta(1)) max_date = max_date.strftime("%d/%m/%Y") error = 'No se pudo encontrar disponibilidad, '\ 'se calcula disponibilidad para el "%s"' % max_date return jsonfy(item=item_id, error=error) # if its a loan and there is only one # nothing else needed, dates and item is set if not date and len(loanable_items): item = loanable_items[0] # reserve an just one item elif date and len(loanable_items) == 1: item = loanable_items[0] # if there's a loan get the closest date if item.loan.start: item_days = (item.loan.start, item.loan.end) start, end = get_hole([item_days], start, days) # else you can make the reserve when asked else: print item.loan print item.reserves print 'IDEAL!' # there are more than one posible reserve, get the best else: loanable_dates = [] for loanable in loanable_items: item_days = (loanable.loan.start, loanable.loan.end) new_start, new_end = get_hole([item_days], start, days) loanable_dates.append((new_start, new_end, loanable)) loanable_dates.sort(key=lambda i: i[0]) start, end, item = loanable_dates[0] if not date: loan = Loan(start=start, end=end, user_id=user_id, type=loan_type) item.loan = loan CirculationLog(type='loan', date=start, length=actual_days, item_type=item.item_type, loan_type=loan_type, item_id=item._id, user_id=user_id).save() else: reserve = Reserve(start=start, end=end, user_id=user_id) item.reserves.append(reserve) item.save() return jsonfy(item=item._id, status='loaned')
def remove_reserve(request, item_id, start, end): """ Remove a reserve """ item = WFItem.get(item_id)
def handle(self, *args, **options): #filename = args['filename'] subfields = True filename = options['from'] items = [] db = WFItem.get_db() orig_item = WFItem.view('couchflow/item_names', include_docs=True)['libro'].first() org_json_item = orig_item.to_json() counter = 0 i = 0 for record in iter_iso_records(filename, subfields): i += 1 json_item = clone_json(org_json_item) json_item["fields_properties"]['99989']['list'][0][ 'exec_value'] = ['catalogado'] copies = [] has_isbn = False for key, fields in record.iteritems(): key = "%03d" % int(key) if key == '020': has_isbn = True if key == "852": copies = fields continue add_field(key, fields, json_item) if not has_isbn and options['fake_isbn']: json_item["fields_properties"]['1020']['list'][0] \ ['subfields']['a']['exec_value'] = [uuid.uuid4().hex] items.append(json_item) # add existences for field in copies: json_item = clone_json(json_item) add_field("852", [field], json_item) add_field("1111", [{"_": "existencia"}], json_item) items.append(json_item) if len(items) >= options['per_iter']: if not options['dry_run']: db.bulk_save(items, use_uuids=False) counter += len(items) items = [] print '%s %s items (total %s)' % ( 'Parsed' if options['dry_run'] else 'Inserted', options['per_iter'], counter) if items and not options['dry_run']: db.bulk_save(items, use_uuids=False) counter += len(items) print print "Done, %s items" % counter print ""