Homepage and report spam.

master
Nick Sergeant 2019-03-11 16:45:49 -04:00
parent 1102cdfcac
commit 19474c44dc
9 changed files with 115 additions and 24 deletions

View File

@ -36,7 +36,7 @@ class UserProfile(models.Model):
) )
# User # User
user = models.OneToOneField(User, on_delete=models.DO_NOTHING) user = models.OneToOneField(User, on_delete=models.CASCADE)
is_pro = models.BooleanField(default=False) is_pro = models.BooleanField(default=False)
teams_beta_seen = models.BooleanField(default=False) teams_beta_seen = models.BooleanField(default=False)
teams_beta_applied = models.BooleanField(default=False) teams_beta_applied = models.BooleanField(default=False)

View File

@ -16,7 +16,7 @@ BASE_PATH = os.path.dirname(__file__)
CSRF_COOKIE_SECURE = True if "USE_SSL" in os.environ else False CSRF_COOKIE_SECURE = True if "USE_SSL" in os.environ else False
CORS_ORIGIN_ALLOW_ALL = True CORS_ORIGIN_ALLOW_ALL = True
DEBUG = True if "DEBUG" in os.environ else False DEBUG = True if "DEBUG" in os.environ else False
DEFAULT_FROM_EMAIL = os.environ.get("POSTMARK_EMAIL", "support@siftie.com") DEFAULT_FROM_EMAIL = os.environ.get("POSTMARK_EMAIL", "team@siftie.com")
EMAIL_BACKEND = "postmark.django_backend.EmailBackend" EMAIL_BACKEND = "postmark.django_backend.EmailBackend"
# HAYSTACK_CONNECTIONS = { # HAYSTACK_CONNECTIONS = {
# "default": { # "default": {
@ -52,7 +52,7 @@ SECRET_KEY = os.environ.get("SECRET_KEY", "changeme")
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
SECURE_SSL_REDIRECT = True if "USE_SSL" in os.environ else False SECURE_SSL_REDIRECT = True if "USE_SSL" in os.environ else False
SEND_BROKEN_LINK_EMAILS = False SEND_BROKEN_LINK_EMAILS = False
SERVER_EMAIL = os.environ.get("POSTMARK_EMAIL", "support@siftie.com") SERVER_EMAIL = os.environ.get("POSTMARK_EMAIL", "team@siftie.com")
SESSION_COOKIE_AGE = 15801100 SESSION_COOKIE_AGE = 15801100
SESSION_COOKIE_SECURE = True if "USE_SSL" in os.environ else False SESSION_COOKIE_SECURE = True if "USE_SSL" in os.environ else False
SITE_ID = 1 SITE_ID = 1
@ -65,7 +65,7 @@ STATICFILES_STORAGE = "whitenoise.django.GzipManifestStaticFilesStorage"
STATIC_ROOT = os.path.join(BASE_PATH, "static") STATIC_ROOT = os.path.join(BASE_PATH, "static")
STATIC_URL = "/static/" STATIC_URL = "/static/"
TASTYPIE_CANNED_ERROR = """There was an error with your request. The site TASTYPIE_CANNED_ERROR = """There was an error with your request. The site
developers have a record of this error, please email support@siftie.com and developers have a record of this error, please email team@siftie.com and
we'll help you out.""" we'll help you out."""
TEMPLATES = [ TEMPLATES = [

View File

@ -22,13 +22,13 @@ from teams.models import Team
class Snipt(models.Model): class Snipt(models.Model):
"""An individual Snipt.""" """An individual Snipt."""
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.DO_NOTHING) user = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE)
last_user_saved = models.ForeignKey( last_user_saved = models.ForeignKey(
User, User,
blank=True, blank=True,
null=True, null=True,
related_name="last_user_saved", related_name="last_user_saved",
on_delete=models.DO_NOTHING, on_delete=models.CASCADE,
) )
title = models.CharField(max_length=255, blank=True, null=True, default="Untitled") title = models.CharField(max_length=255, blank=True, null=True, default="Untitled")
@ -313,8 +313,8 @@ class Snipt(models.Model):
class SniptLogEntry(models.Model): class SniptLogEntry(models.Model):
"""An individual log entry for a snippet changeset.""" """An individual log entry for a snippet changeset."""
user = models.ForeignKey(User, on_delete=models.DO_NOTHING) user = models.ForeignKey(User, on_delete=models.CASCADE)
snipt = models.ForeignKey(Snipt, on_delete=models.DO_NOTHING) snipt = models.ForeignKey(Snipt, on_delete=models.CASCADE)
code = models.TextField() code = models.TextField()
diff = models.TextField() diff = models.TextField()
@ -330,8 +330,8 @@ class SniptLogEntry(models.Model):
class SniptSecureView(models.Model): class SniptSecureView(models.Model):
"""A single view to a secure snippet.""" """A single view to a secure snippet."""
user = models.ForeignKey(User, on_delete=models.DO_NOTHING) user = models.ForeignKey(User, on_delete=models.CASCADE)
snipt = models.ForeignKey(Snipt, on_delete=models.DO_NOTHING) snipt = models.ForeignKey(Snipt, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True, editable=False) created = models.DateTimeField(auto_now_add=True, editable=False)
modified = models.DateTimeField(auto_now=True, editable=False) modified = models.DateTimeField(auto_now=True, editable=False)
@ -342,8 +342,8 @@ class SniptSecureView(models.Model):
class Favorite(models.Model): class Favorite(models.Model):
snipt = models.ForeignKey(Snipt, on_delete=models.DO_NOTHING) snipt = models.ForeignKey(Snipt, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.DO_NOTHING) user = models.ForeignKey(User, on_delete=models.CASCADE)
created = models.DateTimeField(auto_now_add=True, editable=False) created = models.DateTimeField(auto_now_add=True, editable=False)
modified = models.DateTimeField(auto_now=True, editable=False) modified = models.DateTimeField(auto_now=True, editable=False)

View File

@ -206,6 +206,11 @@
/ <a href="/api/public/snipt/{{ snipt.id }}/?format=json">API</a> / <a href="/api/public/snipt/{{ snipt.id }}/?format=json">API</a>
{% endif %} {% endif %}
</li> </li>
{% if snipt.user != request.user %}
<li class="report-spam">
<a target="_blank" href="/report-spam/{{ snipt.id }}/">Report Spam</a>
</li>
{% endif %}
{% if detail and snipt.public %} {% if detail and snipt.public %}
<li class="tweet"> <li class="tweet">
<a href="https://twitter.com/share" class="twitter-share-button" data-dnt="true" data-count="none" data-url="{{ snipt.get_full_absolute_url }}" data-text="&ldquo;{{ snipt.title }}&rdquo; on @SiftieSnippets">Tweet</a> <a href="https://twitter.com/share" class="twitter-share-button" data-dnt="true" data-count="none" data-url="{{ snipt.get_full_absolute_url }}" data-text="&ldquo;{{ snipt.title }}&rdquo; on @SiftieSnippets">Tweet</a>

View File

@ -23,6 +23,7 @@ urlpatterns = [
url( url(
r"^public/tag/(?P<tag_slug>[^/]+)/$", views.list_public, name="list-public-tag" r"^public/tag/(?P<tag_slug>[^/]+)/$", views.list_public, name="list-public-tag"
), ),
url(r'^report-spam/(?P<snipt_id>[^/]+)/$', views.report_spam, name='report-spam'),
url(r"^download/(?P<snipt_key>[^/]+).*$", views.download, name="download"), url(r"^download/(?P<snipt_key>[^/]+).*$", views.download, name="download"),
url(r"^embed/(?P<snipt_key>[^/]+)/$", views.embed, name="embed"), url(r"^embed/(?P<snipt_key>[^/]+)/$", views.embed, name="embed"),
url(r"^raw/(?P<snipt_key>[^/]+)/(?P<lexer>[^\?]+)?$", views.raw, name="raw"), url(r"^raw/(?P<snipt_key>[^/]+)/(?P<lexer>[^\?]+)?$", views.raw, name="raw"),

View File

@ -388,3 +388,18 @@ def redirect_user_feed(request, username):
def redirect_user_tag_feed(request, username, tag_slug): def redirect_user_tag_feed(request, username, tag_slug):
return HttpResponseRedirect(u"/{}/tag/{}/?rss".format(username, tag_slug)) return HttpResponseRedirect(u"/{}/tag/{}/?rss".format(username, tag_slug))
def report_spam(request, snipt_id):
snipt = get_object_or_404(Snipt, pk=snipt_id)
send_mail('[Snipt] Spam reported',
"""
Snipt: https://snippets.siftie.com/admin/snipts/snipt/{}/
User: https://snippets.siftie.com/admin/auth/user/{}/delete/
""".format(snipt.id, snipt.user.id),
'team@siftie.com',
['nick@siftie.com'],
fail_silently=False)
return HttpResponse("""Thanks! Your report has been
submitted to the site admins.""")

View File

@ -19,11 +19,11 @@ class Team(models.Model):
email = models.EmailField(max_length=255) email = models.EmailField(max_length=255)
members = models.ManyToManyField(User, related_name="member", blank=True) members = models.ManyToManyField(User, related_name="member", blank=True)
name = models.CharField(max_length=30) name = models.CharField(max_length=30)
owner = models.ForeignKey(User, related_name="owner", on_delete=models.DO_NOTHING) owner = models.ForeignKey(User, related_name="owner", on_delete=models.CASCADE)
slug = models.SlugField(max_length=255, blank=True) slug = models.SlugField(max_length=255, blank=True)
stripe_id = models.CharField(max_length=100, null=True, blank=True) stripe_id = models.CharField(max_length=100, null=True, blank=True)
user = models.OneToOneField( user = models.OneToOneField(
User, blank=True, null=True, on_delete=models.DO_NOTHING User, blank=True, null=True, on_delete=models.CASCADE
) )
plan = models.CharField( plan = models.CharField(
max_length=100, max_length=100,

View File

@ -26,15 +26,12 @@
<ul> <ul>
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<li> <li>
<a href="/{{ request.user.username }}/">My snippets</a> <a href="/{{ request.user.username }}/">My snipts</a>
</li> </li>
{% endif %} {% endif %}
<li> <li>
<a href="/public/">Public snippets</a> <a href="/public/">Public snipts</a>
</li> </li>
<!-- <li> -->
<!-- <a href="/search/">Search</a> -->
<!-- </li> -->
{% if not request.user.is_authenticated %} {% if not request.user.is_authenticated %}
<li> <li>
<a class="button" href="/login/">Log in</a> <a class="button" href="/login/">Log in</a>
@ -57,14 +54,60 @@
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="span12"> <div class="span12">
<h4>This is a private instance of <a href="https://github.com/siftie/snippets">Siftie Snippets</a>.</h4> <h4>{{ users_count|intcomma }} coders in over 120 countries have stored {{ snipts_count|intcomma }} snipts, in 145 languages.</h4>
</div> </div>
</div> </div>
</div> </div>
{% if request.user.is_authenticated %} {% if request.user.is_authenticated %}
<a href="/{{ request.user.username }}/" class="button">My snippets</a> <a href="/{{ request.user.username }}/" class="button">My snipts</a>
{% else %} {% else %}
<a href="/login/" class="button">Log in</a> <a href="/signup/" class="button">Sign up</a>
{% endif %} {% endif %}
<div class="faces group">
<div class="inner">
{% for coder in coders %}
<a href="/{{ coder.username }}/" title="{{ coder.username }}">
<img alt="{{ coder.username }}" title="{{ coder.username }}" src="https://secure.gravatar.com/avatar/{{ coder.email_md5 }}?s=50" />
</a>
{% endfor %}
</div>
</div>
</section>
<section class="features">
<div class="container">
<div class="row">
<header class="span4 offset4">
<h1>For teams or individuals</h1>
</header>
</div>
<div class="feature row share">
<div class="inner">
<h2>Team accounts</h2>
<p>
Create a <a href="/for-teams/">Team</a> account and allow your team members to create and
edit private and public code snippets. Search through all your team's snippets, and
view detailed diffs of changes to each snippet.
</p>
</div>
</div>
<div class="feature row blog">
<div class="inner">
<h2>Personal accounts</h2>
<p>
Individuals can post public and <code>private</code> snippets, making them perfect
for storing and organizing code you never want to forget.
</p>
</div>
</div>
<div class="feature row store" style="margin-bottom: 200px;">
<div class="inner">
<h2>Code-focused blogs</h2>
<p>
<a href="/blogging/">A full blog in seconds</a>: mark a snipt as "Blog Post", and it'll
appear on <code>{your-username}.snipt.net</code>. Markdown support built-in. Your domain, or ours.
</p>
</div>
</div>
</div>
</section> </section>
{% endblock %} {% endblock %}

View File

@ -1,18 +1,45 @@
import hashlib
from accounts.models import UserProfile
from annoying.decorators import ajax_request, render_to from annoying.decorators import ajax_request, render_to
from blogs.views import blog_list from blogs.views import blog_list
from django.contrib.auth.models import User
from django.db.models import Count from django.db.models import Count
from django.http import HttpResponseRedirect, HttpResponseBadRequest from django.http import HttpResponseRedirect, HttpResponseBadRequest
from snipts.models import Snipt
from snipts.utils import get_lexers_list from snipts.utils import get_lexers_list
from taggit.models import Tag from taggit.models import Tag
@render_to("homepage.html") @render_to('homepage.html')
def homepage(request): def homepage(request):
if request.blog_user: if request.blog_user:
return blog_list(request) return blog_list(request)
return {} coders = []
users_with_gravatars = User.objects.filter(
userprofile__in=UserProfile.objects.filter(has_gravatar=True)
).order_by('?')
for user in users_with_gravatars:
public_snipts_count = Snipt.objects.filter(
user=user, public=True).values('pk').count()
if public_snipts_count:
user.email_md5 = hashlib.md5(user.email.lower().encode('utf-8')) \
.hexdigest()
coders.append(user)
if len(coders) == 35:
break
return {
'coders': coders,
'snipts_count': Snipt.objects.all().count(),
'users_count': User.objects.all().count(),
}
@ajax_request @ajax_request