def loadCSVfile(self, model, file): errorcount = 0 warningcount = 0 datafile = EncodedCSVReader(file, delimiter=self.delimiter) try: with transaction.atomic(using=self.database): for error in parseCSVdata( model, datafile, user=self.user, database=self.database ): if error[0] == logging.ERROR: logger.error( "%s Error: %s%s%s%s" % ( datetime.now().replace(microsecond=0), "Row %s: " % error[1] if error[1] else "", "field %s: " % error[2] if error[2] else "", "%s: " % error[3] if error[3] else "", error[4], ) ) errorcount += 1 elif error[0] == logging.WARNING: logger.warning( "%s Warning: %s%s%s%s" % ( datetime.now().replace(microsecond=0), "Row %s: " % error[1] if error[1] else "", "field %s: " % error[2] if error[2] else "", "%s: " % error[3] if error[3] else "", error[4], ) ) warningcount += 1 else: logger.info( "%s %s%s%s%s" % ( datetime.now().replace(microsecond=0), "Row %s: " % error[1] if error[1] else "", "field %s: " % error[2] if error[2] else "", "%s: " % error[3] if error[3] else "", error[4], ) ) # Records are committed. Launch notification generator now. NotificationFactory.launchWorker(database=self.database, url=None) except Exception: errorcount += 1 logger.error( "%s Error: Invalid data format - skipping the file \n" % datetime.now().replace(microsecond=0) ) return [errorcount, warningcount]
def loadExcelfile(self, model, file): errorcount = 0 warningcount = 0 try: with transaction.atomic(using=self.database): wb = load_workbook(filename=file, read_only=True, data_only=True) for ws_name in wb.sheetnames: ws = wb[ws_name] for error in parseExcelWorksheet( model, ws, user=self.user, database=self.database ): if error[0] == logging.ERROR: logger.error( "%s Error: %s%s%s%s" % ( datetime.now().replace(microsecond=0), "Row %s: " % error[1] if error[1] else "", "field %s: " % error[2] if error[2] else "", "%s: " % error[3] if error[3] else "", error[4], ) ) errorcount += 1 elif error[0] == logging.WARNING: logger.warning( "%s Warning: %s%s%s%s" % ( datetime.now().replace(microsecond=0), "Row %s: " % error[1] if error[1] else "", "field %s: " % error[2] if error[2] else "", "%s: " % error[3] if error[3] else "", error[4], ) ) warningcount += 1 else: logger.info( "%s %s%s%s%s" % ( datetime.now().replace(microsecond=0), "Row %s: " % error[1] if error[1] else "", "field %s: " % error[2] if error[2] else "", "%s: " % error[3] if error[3] else "", error[4], ) ) # Records are committed. Launch notification generator now. NotificationFactory.launchWorker(database=self.database, url=None) except Exception: errorcount += 1 logger.error( "%s Error: Invalid data format - skipping the file \n" % datetime.now().replace(microsecond=0) ) return [errorcount, warningcount]
def test_follow_item(self): sleep(3) user = User.objects.create_user( username="******", email="*****@*****.**", password="******", ) user.user_permissions.add(*Permission.objects.filter( codename__in=("view_item", "view_supplier", "view_purchaseorder"))) Follower( user=user, content_type=ContentType.objects.get(model="item"), object_pk="test item", ).save() for _ in parseCSVdata( Item, [["name", "category"], ["test item", "test category"]], user=user): pass for _ in parseCSVdata( Item, [["name", "category"], ["test item", "new test category"]], user=user): pass for _ in parseCSVdata(Supplier, [["name"], ["test supplier"]], user=user): pass for _ in parseCSVdata( ItemSupplier, [["supplier", "item"], ["test supplier", "test item"]], user=user, ): pass for _ in parseCSVdata( PurchaseOrder, [ ["reference", "supplier", "item", "quantity", "enddate"], ["PO 1", "test supplier", "test item", "10", "2020-12-31"], ], user=user, ): pass item = Item.objects.get(name="test item") Comment( content_object=item, object_repr=str(item)[:200], user=user, comment="test comment", type="comment", ).save() # Check what notifications we got Notification.wait() NotificationFactory.start() self.assertEqual(Notification.objects.count(), 4)
def render(self, context): from django.db.models.options import Options from django.contrib.contenttypes.models import ContentType try: # Look up the admin class to use model = Variable(self.model).resolve(context) pk = Variable(self.pk).resolve(context) request = Variable("request").resolve(context) if not model or not pk: context[self.var] = None return mark_safe("") if isinstance(model, Options): ct = ContentType.objects.get(app_label=model.app_label, model=model.object_name.lower()) elif isinstance(model, models.Model): ct = ContentType.objects.get_for_model(model) else: model = model.split(".") ct = ContentType.objects.get(app_label=model[0], model=model[1]) context[self.var] = NotificationFactory.getFollower( object_pk=pk, content_type=ct, user=request.user, database=request.database, ) except Exception: context[self.var] = None return mark_safe("")
def follow(request): if request.is_ajax() and request.method == "POST": # Updating followers posted in the format: # [{ # 'object_pk': "my product", 'model': 'input.item', # 'users': ['me', 'you'], # 'models': ['input.item', 'input.distributionorder', 'input.itemdistribution'] # }] errors = False for rec in json.JSONDecoder().decode( request.body.decode(request.encoding or settings.DEFAULT_CHARSET) ): try: object_pk = rec.get("object_pk", None) model = rec.get("model", None) if not object_pk or not model: continue app_and_model = model.split(".") ct = ContentType.objects.get( app_label=app_and_model[0], model=app_and_model[1] ) followers = { f.user.username: f for f in Follower.objects.using(request.database).filter( content_type=ct.pk, object_pk=object_pk ) } for username, type in rec.get("users", {}).items(): user = User.objects.using(request.database).get(username=username) if username not in followers: # New follower Follower( content_type_id=ct.pk, object_pk=object_pk, user=user, type="M" if type == "email" else "O", ).save(using=request.database) Comment( user_id=request.user.id, content_type_id=ct.pk, object_pk=object_pk, object_repr=object_pk, type="follower", comment="Added follower %s" % username, ).save(using=request.database) else: # Update follower followers[username].type = "M" if type == "email" else "O" followers[username].save(using=request.database) for username, flw in followers.items(): if ( username not in rec.get("users", {}) and username != request.user.username ): # Delete a follower flw.delete(using=request.database) Comment( user_id=request.user.id, content_type_id=ct.pk, object_pk=object_pk, object_repr=object_pk, type="follower", comment="Deleted follower %s" % username, ).save(using=request.database) myfollow = followers.get(request.user.username) models = rec.get("models", None) if myfollow: if models: # Update existing follower myfollow.args["sub"] = models if "type" in rec: myfollow.type = "M" if rec.get("type") == "email" else "O" myfollow.save(using=request.database) else: # Delete follower myfollow.delete(using=request.database) elif models: # New follower Follower( content_type_id=ct.pk, object_pk=object_pk, user=request.user, type="M" if rec.get("type") == "email" else "O", args={"sub": models}, ).save(using=request.database) except Exception as e: logger.error("Error processing follower POST %s: %s" % (rec, e)) errors = True if errors: return HttpResponse(content="NOT OK", status=400) else: return HttpResponse(content="OK") elif request.is_ajax() and request.method == "GET": # Return follower information for an object try: object_pk = request.GET.get("object_pk", None) model = request.GET.get("model", None) if object_pk and model: app_and_model = model.split(".") ct = ContentType.objects.get( app_label=app_and_model[0], model=app_and_model[1] ) return JsonResponse( NotificationFactory.getAllFollowers( content_type=ct, object_pk=object_pk, user=request.user, database=request.database, ) ) except Exception as e: logger.error("Error processing follower GET: %s" % e) return HttpResponse(content="NOT OK", status=400) else: return HttpResponseNotAllowed( ["post", "get"], content="Only ajax GET and POST requests are allowed" )