def manage_task_weekly(): # check over quota cases and send quota warning emails as needed hs_internal_zone = "hydroshare" if not QuotaMessage.objects.exists(): QuotaMessage.objects.create() qmsg = QuotaMessage.objects.first() users = User.objects.filter(is_active=True).filter(is_superuser=False).all() for u in users: uq = UserQuota.objects.filter(user__username=u.username, zone=hs_internal_zone).first() if uq: used_percent = uq.used_percent if used_percent >= qmsg.soft_limit_percent: if used_percent >= 100 and used_percent < qmsg.hard_limit_percent: if uq.remaining_grace_period < 0: # triggers grace period counting uq.remaining_grace_period = qmsg.grace_period elif uq.remaining_grace_period > 0: # reduce remaining_grace_period by one day uq.remaining_grace_period -= 1 elif used_percent >= qmsg.hard_limit_percent: # set grace period to 0 when user quota exceeds hard limit uq.remaining_grace_period = 0 uq.save() if u.first_name and u.last_name: sal_name = '{} {}'.format(u.first_name, u.last_name) elif u.first_name: sal_name = u.first_name elif u.last_name: sal_name = u.last_name else: sal_name = u.username msg_str = 'Dear ' + sal_name + ':\n\n' ori_qm = get_quota_message(u) # make embedded settings.DEFAULT_SUPPORT_EMAIL clickable with subject auto-filled replace_substr = "<a href='mailto:{0}?subject=Request more quota'>{0}</a>".format( settings.DEFAULT_SUPPORT_EMAIL) new_qm = ori_qm.replace(settings.DEFAULT_SUPPORT_EMAIL, replace_substr) msg_str += new_qm msg_str += '\n\nHydroShare Support' subject = 'Quota warning' try: # send email for people monitoring and follow-up as needed send_mail(subject, '', settings.DEFAULT_FROM_EMAIL, [u.email, settings.DEFAULT_SUPPORT_EMAIL], html_message=msg_str) except Exception as ex: logger.debug("Failed to send quota warning email: " + ex.message) else: if uq.remaining_grace_period >= 0: # turn grace period off now that the user is below quota soft limit uq.remaining_grace_period = -1 uq.save() else: logger.debug('user ' + u.username + ' does not have UserQuota foreign key relation')
def manage_task_weekly(): # check over quota cases and send quota warning emails as needed hs_internal_zone = "hydroshare" if not QuotaMessage.objects.exists(): QuotaMessage.objects.create() qmsg = QuotaMessage.objects.first() users = User.objects.filter(is_active=True).filter(is_superuser=False).all() for u in users: uq = UserQuota.objects.filter(user__username=u.username, zone=hs_internal_zone).first() if uq: used_percent = uq.used_percent if used_percent >= qmsg.soft_limit_percent: if used_percent >= 100 and used_percent < qmsg.hard_limit_percent: if uq.remaining_grace_period < 0: # triggers grace period counting uq.remaining_grace_period = qmsg.grace_period elif uq.remaining_grace_period > 0: # reduce remaining_grace_period by one day uq.remaining_grace_period -= 1 elif used_percent >= qmsg.hard_limit_percent: # set grace period to 0 when user quota exceeds hard limit uq.remaining_grace_period = 0 uq.save() if u.first_name and u.last_name: sal_name = '{} {}'.format(u.first_name, u.last_name) elif u.first_name: sal_name = u.first_name elif u.last_name: sal_name = u.last_name else: sal_name = u.username msg_str = 'Dear ' + sal_name + ':\n\n' ori_qm = get_quota_message(u) # make embedded settings.DEFAULT_SUPPORT_EMAIL clickable with subject auto-filled replace_substr = "<a href='mailto:{0}?subject=Request more quota'>{0}</a>".format( settings.DEFAULT_SUPPORT_EMAIL) new_qm = ori_qm.replace(settings.DEFAULT_SUPPORT_EMAIL, replace_substr) msg_str += new_qm msg_str += '\n\nHydroShare Support' subject = 'Quota warning' try: # send email for people monitoring and follow-up as needed send_mail(subject, '', settings.DEFAULT_FROM_EMAIL, [u.email, settings.DEFAULT_SUPPORT_EMAIL], html_message=msg_str) except Exception as ex: logger.debug("Failed to send quota warning email: " + ex.message) else: if uq.remaining_grace_period >= 0: # turn grace period off now that the user is below quota soft limit uq.remaining_grace_period = -1 uq.save() else: logger.debug('user ' + u.username + ' does not have UserQuota foreign key relation')
def get_context_data(self, **kwargs): u = User.objects.none() if 'user' in kwargs: try: u = User.objects.get(pk=int(kwargs['user'])) except: u = User.objects.get(username=kwargs['user']) elif self.request.GET.get('user', False): try: u = User.objects.get(pk=int(self.request.GET['user'])) except: u = User.objects.get(username=self.request.GET['user']) elif not self.request.user.is_anonymous(): # if the user is logged in and no user is specified, show logged in user u = User.objects.get(pk=int(self.request.user.id)) # get all resources the profile user owns resources = u.uaccess.owned_resources # get a list of groupmembershiprequests group_membership_requests = GroupMembershipRequest.objects.filter( invitation_to=u).all() # if requesting user is not the profile user, then show only resources that the requesting user has access if self.request.user != u: if self.request.user.is_authenticated(): if self.request.user.is_superuser: # admin can see all resources owned by profile user pass else: # filter out any resources the requesting user doesn't have access resources = resources.filter( Q(pk__in=self.request.user.uaccess.view_resources) | Q(raccess__public=True) | Q(raccess__discoverable=True)) else: # for anonymous requesting user show only resources that are either public or discoverable resources = resources.filter( Q(raccess__public=True) | Q(raccess__discoverable=True)) return { 'profile_user': u, 'resources': resources, 'quota_message': get_quota_message(u), 'group_membership_requests': group_membership_requests, }
def handle(self, *args, **options): unames = options['username'] for uname in unames: if User.objects.filter(username=uname).exists(): user = User.objects.filter(username=uname).first() uemail = user.email uqs = user.quotas.all() msg_str = '' if uqs: msg_str = 'Dear ' + uname + ':\n\n' msg_str += get_quota_message(user) if msg_str: msg_str += '\n\nHydroShare Support' subject = 'HydroShare Quota warning' # send email for people monitoring and follow-up as needed send_mail(subject, msg_str, settings.DEFAULT_FROM_EMAIL, [uemail])
def login(request, template="accounts/account_login.html", form_class=LoginForm, extra_context=None): """ Login form - customized from Mezzanine login form so that quota warning message can be displayed when the user is logged in. """ form = form_class(request.POST or None) if request.method == "POST" and form.is_valid(): login_msg = "Successfully logged in" authenticated_user = form.save() add_msg = get_quota_message(authenticated_user) if add_msg: login_msg += ' - ' + add_msg info(request, _(login_msg)) auth_login(request, authenticated_user) return login_redirect(request) context = {"form": form, "title": _("Log in")} context.update(extra_context or {}) return TemplateResponse(request, template, context)
def login(request, template="accounts/account_login.html", form_class=LoginForm, extra_context=None): """ Login form - customized from Mezzanine login form so that quota warning message can be displayed when the user is logged in. """ form = form_class(request.POST or None) if request.method == "POST" and form.is_valid(): login_msg = "Successfully logged in" authenticated_user = form.save() add_msg = get_quota_message(authenticated_user) if add_msg: login_msg += ' - ' + add_msg info(request, _(login_msg)) auth_login(request, authenticated_user) return login_redirect(request) context = {"form": form, "title": _("Log in")} context.update(extra_context or {}) return TemplateResponse(request, template, context)
def get_context_data(self, **kwargs): u = User.objects.none() if 'user' in kwargs: try: u = User.objects.get(pk=int(kwargs['user'])) except: u = User.objects.get(username=kwargs['user']) elif self.request.GET.get('user', False): try: u = User.objects.get(pk=int(self.request.GET['user'])) except: u = User.objects.get(username=self.request.GET['user']) elif not self.request.user.is_anonymous(): # if the user is logged in and no user is specified, show logged in user u = User.objects.get(pk=int(self.request.user.id)) # get all resources the profile user owns resources = u.uaccess.owned_resources # get a list of groupmembershiprequests group_membership_requests = GroupMembershipRequest.objects.filter( invitation_to=u).all() # if requesting user is not the profile user, then show only resources that the # requesting user has access if self.request.user != u: if self.request.user.is_authenticated(): if self.request.user.is_superuser: # admin can see all resources owned by profile user pass else: # filter out any resources the requesting user doesn't have access resources = resources.filter( Q(pk__in=self.request.user.uaccess.view_resources) | Q(raccess__public=True) | Q(raccess__discoverable=True)) else: # for anonymous requesting user show only resources that are either public or # discoverable resources = resources.filter( Q(raccess__public=True) | Q(raccess__discoverable=True)) # get resource attributes used in profile page resources = resources.only('title', 'resource_type', 'created') # prefetch resource metadata elements meta_contenttypes = get_metadata_contenttypes() for ct in meta_contenttypes: # get a list of resources having metadata that is an instance of a specific # metadata class (e.g., CoreMetaData) res_list = [res for res in resources if res.content_type == ct] prefetch_related_objects(res_list, Prefetch('content_object__creators'), Prefetch('content_object___description'), Prefetch('content_object___title')) return { 'profile_user': u, 'resources': resources, 'quota_message': get_quota_message(u), 'group_membership_requests': group_membership_requests, }
def handle(self, *args, **options): with open(options['input_file_name_with_path'], 'r') as csvfile: freader = csv.reader(csvfile) if not QuotaMessage.objects.exists(): QuotaMessage.objects.create() qmsg = QuotaMessage.objects.first() for row in freader: try: if len(row) < 3: # some fields are empty, ignore this row continue uname = row[input_fields.user_name] if not uname: # user name is empty, ignore this row continue uname = uname.strip() if not uname: # user name is empty after stripping, ignore this row continue used_val = row[input_fields.used_value] if not used_val: # used_value is empty, ignore this row continue used_val = used_val.strip() if not used_val: # used_val is empty after stripping, ignore this row continue used_val = int(used_val) zone = row[input_fields.storage_zone] if not zone: # zone is empty, ignore this row continue zone = zone.strip() if not zone: # zone is empty after stripping, ignore this row continue uq = UserQuota.objects.filter(user__username=uname, zone=zone).first() if uq is None: # the quota row does not exist in Django continue uq.update_used_value(used_val) used_percent = uq.used_percent if used_percent >= qmsg.soft_limit_percent: if used_percent >= 100 and used_percent < qmsg.hard_limit_percent: if uq.remaining_grace_period < 0: # triggers grace period counting uq.remaining_grace_period = qmsg.grace_period elif uq.remaining_grace_period > 0: # reduce remaining_grace_period by one day uq.remaining_grace_period -= 1 elif used_percent >= qmsg.hard_limit_percent: # set grace period to 0 when user quota exceeds hard limit uq.remaining_grace_period = 0 uq.save() user = uq.user uemail = user.email msg_str = 'Dear ' + uname + ':\n\n' msg_str += get_quota_message(user) msg_str += '\n\nCommonsShare Support' subject = 'Quota warning' # send email for people monitoring and follow-up as needed send_mail(subject, msg_str, settings.DEFAULT_FROM_EMAIL, [uemail]) else: if uq.remaining_grace_period >= 0: # turn grace period off now that the user is below quota soft limit uq.remaining_grace_period = -1 uq.save() except ValueError as ex: # header row, continue print "Skip the header row:" + ex.message continue
def manage_task_nightly(): # The nightly running task do DOI activation check and over-quota check # Check DOI activation on failed and pending resources and send email. msg_lst = [] # retrieve all published resources with failed metadata deposition with CrossRef if any and # retry metadata deposition failed_resources = BaseResource.objects.filter(raccess__published=True, doi__contains='failure') for res in failed_resources: if res.metadata.dates.all().filter(type='published'): pub_date = res.metadata.dates.all().filter(type='published')[0] pub_date = pub_date.start_date.strftime('%m/%d/%Y') act_doi = get_activated_doi(res.doi) response = deposit_res_metadata_with_crossref(res) if response.status_code == status.HTTP_200_OK: # retry of metadata deposition succeeds, change resource flag from failure # to pending res.doi = get_resource_doi(act_doi, 'pending') res.save() else: # retry of metadata deposition failed again, notify admin msg_lst.append( "Metadata deposition with CrossRef for the published resource " "DOI {res_doi} failed again after retry with first metadata " "deposition requested since {pub_date}.".format( res_doi=act_doi, pub_date=pub_date)) logger.debug(response.content) else: msg_lst.append( "{res_id} does not have published date in its metadata.". format(res_id=res.short_id)) pending_resources = BaseResource.objects.filter(raccess__published=True, doi__contains='pending') for res in pending_resources: if res.metadata.dates.all().filter(type='published'): pub_date = res.metadata.dates.all().filter(type='published')[0] pub_date = pub_date.start_date.strftime('%m/%d/%Y') act_doi = get_activated_doi(res.doi) main_url = get_crossref_url() req_str = '{MAIN_URL}servlet/submissionDownload?usr={USERNAME}&pwd=' \ '{PASSWORD}&doi_batch_id={DOI_BATCH_ID}&type={TYPE}' response = requests.get( req_str.format(MAIN_URL=main_url, USERNAME=settings.CROSSREF_LOGIN_ID, PASSWORD=settings.CROSSREF_LOGIN_PWD, DOI_BATCH_ID=res.short_id, TYPE='result')) root = ElementTree.fromstring(response.content) rec_cnt_elem = root.find('.//record_count') failure_cnt_elem = root.find('.//failure_count') success = False if rec_cnt_elem is not None and failure_cnt_elem is not None: rec_cnt = int(rec_cnt_elem.text) failure_cnt = int(failure_cnt_elem.text) if rec_cnt > 0 and failure_cnt == 0: res.doi = act_doi res.save() success = True if not success: msg_lst.append( "Published resource DOI {res_doi} is not yet activated with request " "data deposited since {pub_date}.".format( res_doi=act_doi, pub_date=pub_date)) logger.debug(response.content) else: msg_lst.append( "{res_id} does not have published date in its metadata.". format(res_id=res.short_id)) if msg_lst: email_msg = '\n'.join(msg_lst) subject = 'Notification of pending DOI deposition/activation of published resources' # send email for people monitoring and follow-up as needed send_mail(subject, email_msg, settings.DEFAULT_FROM_EMAIL, [settings.DEFAULT_SUPPORT_EMAIL]) # check over quota cases and send quota warning emails as needed hs_internal_zone = "hydroshare" if not QuotaMessage.objects.exists(): QuotaMessage.objects.create() qmsg = QuotaMessage.objects.first() users = User.objects.filter(is_active=True).all() for u in users: uq = UserQuota.objects.filter(user__username=u.username, zone=hs_internal_zone).first() used_percent = uq.used_percent if used_percent >= qmsg.soft_limit_percent: if used_percent >= 100 and used_percent < qmsg.hard_limit_percent: if uq.remaining_grace_period < 0: # triggers grace period counting uq.remaining_grace_period = qmsg.grace_period elif uq.remaining_grace_period > 0: # reduce remaining_grace_period by one day uq.remaining_grace_period -= 1 elif used_percent >= qmsg.hard_limit_percent: # set grace period to 0 when user quota exceeds hard limit uq.remaining_grace_period = 0 uq.save() uemail = u.email msg_str = 'Dear ' + u.username + ':\n\n' ori_qm = get_quota_message(u) # make embedded settings.DEFAULT_SUPPORT_EMAIL clickable with subject auto-filled replace_substr = "<a href='mailto:{0}?subject=Request more quota'>{0}</a>".format( settings.DEFAULT_SUPPORT_EMAIL) new_qm = ori_qm.replace(settings.DEFAULT_SUPPORT_EMAIL, replace_substr) msg_str += new_qm msg_str += '\n\nHydroShare Support' subject = 'Quota warning' # send email for people monitoring and follow-up as needed send_mail(subject, '', settings.DEFAULT_FROM_EMAIL, [uemail, settings.DEFAULT_SUPPORT_EMAIL], html_message=msg_str) else: if uq.remaining_grace_period >= 0: # turn grace period off now that the user is below quota soft limit uq.remaining_grace_period = -1 uq.save()
def get_context_data(self, **kwargs): u = User.objects.none() if 'user' in kwargs: try: u = User.objects.get(pk=int(kwargs['user'])) except: u = User.objects.get(username=kwargs['user']) elif self.request.GET.get('user', False): try: u = User.objects.get(pk=int(self.request.GET['user'])) except: u = User.objects.get(username=self.request.GET['user']) elif not self.request.user.is_anonymous(): # if the user is logged in and no user is specified, show logged in user u = User.objects.get(pk=int(self.request.user.id)) # get all resources the profile user owns resources = u.uaccess.owned_resources # get a list of groupmembershiprequests group_membership_requests = GroupMembershipRequest.objects.filter(invitation_to=u).all() # if requesting user is not the profile user, then show only resources that the # requesting user has access if self.request.user != u: if self.request.user.is_authenticated(): if self.request.user.is_superuser: # admin can see all resources owned by profile user pass else: # filter out any resources the requesting user doesn't have access resources = resources.filter( Q(pk__in=self.request.user.uaccess.view_resources) | Q(raccess__public=True) | Q(raccess__discoverable=True)) else: # for anonymous requesting user show only resources that are either public or # discoverable resources = resources.filter(Q(raccess__public=True) | Q(raccess__discoverable=True)) # get resource attributes used in profile page resources = resources.only('title', 'resource_type', 'created') # prefetch resource metadata elements meta_contenttypes = get_metadata_contenttypes() for ct in meta_contenttypes: # get a list of resources having metadata that is an instance of a specific # metadata class (e.g., CoreMetaData) res_list = [res for res in resources if res.content_type == ct] prefetch_related_objects(res_list, Prefetch('content_object__creators'), Prefetch('content_object___description'), Prefetch('content_object___title') ) return { 'profile_user': u, 'resources': resources, 'quota_message': get_quota_message(u), 'group_membership_requests': group_membership_requests, }