-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Added feature for sending abandoned project mail #3722
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
bb6e9b7
f8b862b
38ef44d
a4974af
543e3e6
8e2f573
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# -*- coding: utf-8 -*- | ||
# Generated by Django 1.9.12 on 2018-03-04 09:24 | ||
from __future__ import unicode_literals | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
('projects', '0023_migrate-alias-slug'), | ||
] | ||
|
||
operations = [ | ||
migrations.AddField( | ||
model_name='project', | ||
name='abandoned_mail_sent', | ||
field=models.BooleanField(default=False), | ||
), | ||
|
||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ | |
import logging | ||
import os | ||
from builtins import object # pylint: disable=redefined-builtin | ||
from datetime import datetime, timedelta | ||
|
||
from django.conf import settings | ||
from django.contrib.auth.models import User | ||
|
@@ -82,6 +83,7 @@ class Project(models.Model): | |
related_name='projects') | ||
name = models.CharField(_('Name'), max_length=255) | ||
slug = models.SlugField(_('Slug'), max_length=255, unique=True) | ||
abandoned_mail_sent = models.BooleanField(default=False) | ||
description = models.TextField(_('Description'), blank=True, | ||
help_text=_('The reStructuredText ' | ||
'description of the project')) | ||
|
@@ -558,6 +560,27 @@ def conf_dir(self, version=LATEST): | |
if conf_file: | ||
return os.path.dirname(conf_file) | ||
|
||
@property | ||
def is_abandoned(self): | ||
"""Is project abandoned.""" | ||
if self.has_good_build: | ||
latest_build = self.get_latest_build() | ||
if latest_build: | ||
latest_build_date = latest_build.date | ||
today = datetime.today() | ||
diff = today - latest_build_date | ||
# Latest build a year ago. | ||
if diff > timedelta(days=365): | ||
return True | ||
return False | ||
return False | ||
return True | ||
|
||
@property | ||
def is_abandoned_mail_sent(self): | ||
"""Is abandoned mail sent.""" | ||
return self.abandoned_mail_sent | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't believe this is necessary, you can just use |
||
|
||
@property | ||
def is_type_sphinx(self): | ||
"""Is project type Sphinx.""" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,10 @@ | |
private.project_manage, | ||
name='projects_manage'), | ||
|
||
url(r'^(?P<project_slug>[-\w]+)/send_mail/$', | ||
private.send_mail, | ||
name='send_mail'), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should have a more explicit name & URL, |
||
|
||
url(r'^(?P<project_slug>[-\w]+)/comments_moderation/$', | ||
private.project_comments_moderation, | ||
name='projects_comments_moderation'), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,7 +26,8 @@ | |
from readthedocs.builds.forms import AliasForm, VersionForm | ||
from readthedocs.builds.models import Version, VersionAlias | ||
from readthedocs.core.mixins import ListViewWithForm, LoginRequiredMixin | ||
from readthedocs.core.utils import broadcast, trigger_build | ||
from readthedocs.core.utils import broadcast, trigger_build, send_email | ||
from readthedocs.core.permissions import AdminPermission | ||
from readthedocs.integrations.models import HttpExchange, Integration | ||
from readthedocs.oauth.services import registry | ||
from readthedocs.oauth.utils import attach_webhook, update_webhook | ||
|
@@ -264,6 +265,28 @@ def is_advanced(self): | |
return data.get('advanced', True) | ||
|
||
|
||
@login_required | ||
def send_mail(request, project_slug): | ||
"""Sends abandoned project email.""" | ||
project = Project.objects.get(slug=project_slug) | ||
proj_name = project_slug | ||
for user in project.users.all(): | ||
if AdminPermission.is_admin(user, project): | ||
email = user.email | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this be done on another way (not sure how we can decide to which owner send the email)? Probably a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also I think this is insecure, since any logged in user can send a request here, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I made this button to be visible only to a superuser in the html template. Does that look fine? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, I have added a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, but any user could do a manual request, so probably is worth to check for the superuser here. I'm not sure what is the best way of do it anyway, probably the Maybe @humitos can help us here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure @stsewd! Thanks 😄 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @stsewd I tested this on my local instance and it works as expected! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ericholscher Can you please guide me here! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks like it is checking for project owners who are admins. We just want to send the email to all project owners, but only let admins do it. We should be doing a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The button for sending mail is only visible to the admins i.e. I have done a |
||
break | ||
context = {'proj_name': proj_name} | ||
subject = 'Rename request for abandoned project' | ||
send_email( | ||
recipient=email, | ||
subject=subject, | ||
template='projects/email/abandon_project.txt', | ||
template_html='projects/email/abandon_project.html', | ||
context=context) | ||
project.abandoned_mail_sent = True | ||
project.save() | ||
return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) | ||
|
||
|
||
class ImportDemoView(PrivateViewMixin, View): | ||
|
||
"""View to pass request on to import form to import demo project.""" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{% extends "core/email/common.html" %} | ||
|
||
{% load i18n %} | ||
|
||
{% block content %} | ||
<p> | ||
We've had a request from one of our users for the project name {{proj_name}} on Read the Docs. You are the current owner, and we wanted to reach out to you in accordance with our Abandoned Project policy (http://docs.readthedocs.io/en/latest/abandoned-projects.html). | ||
</p> | ||
|
||
<p> | ||
Please reply at [email protected] either allowing or disallowing the transfer of the name on Read the Docs within 6 weeks, otherwise we will take the action of *initiating the transfer to a new owner* by default. | ||
</p> | ||
{% endblock %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{% extends "core/email/common.txt" %} | ||
|
||
{% load i18n %} | ||
|
||
{% block content %} | ||
We've had a request from one of our users for the project name {{proj_name}} on Read the Docs. You are the current owner, and we wanted to reach out to you in accordance with our Abandoned Project policy (http://docs.readthedocs.io/en/latest/abandoned-projects.html). | ||
|
||
Please reply at [email protected] either allowing or disallowing the transfer of the name on Read the Docs within 6 weeks, otherwise we will take the action of *initiating the transfer to a new owner* by default. | ||
{% endblock %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need to check for abandoned, we should just always link to the project here.