Homepage and report spam.
parent
1102cdfcac
commit
19474c44dc
|
@ -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)
|
||||||
|
|
|
@ -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 = [
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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="“{{ snipt.title }}” 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="“{{ snipt.title }}” on @SiftieSnippets">Tweet</a>
|
||||||
|
|
|
@ -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"),
|
||||||
|
|
|
@ -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.""")
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 %}
|
||||||
|
|
31
views.py
31
views.py
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue