master
Nick Sergeant 2019-01-23 18:52:55 -05:00
parent 6af387be82
commit 39403a600c
49 changed files with 1464 additions and 1169 deletions

View File

@ -3,9 +3,9 @@ from django.contrib import admin
class UserProfileAdmin(admin.ModelAdmin):
list_display = ('user', 'is_pro', 'stripe_id', 'gittip_username',
'teams_beta_seen')
list_filter = ['teams_beta_seen', 'teams_beta_applied']
search_fields = ('user__username', 'gittip_username',)
list_display = ("user", "is_pro", "stripe_id", "gittip_username", "teams_beta_seen")
list_filter = ["teams_beta_seen", "teams_beta_applied"]
search_fields = ("user__username", "gittip_username")
admin.site.register(UserProfile, UserProfileAdmin)

View File

@ -14,9 +14,9 @@ class Command(BaseCommand):
self.stdout.write(u"Updating %s user passwords..." % users.count())
for user in users:
if user.password[0:3] == 'bc$':
if user.password[0:3] == "bc$":
pw = user.password
new_password = pw[0:3].replace('bc$', 'bcrypt$') + pw[3:]
new_password = pw[0:3].replace("bc$", "bcrypt$") + pw[3:]
user.password = new_password
user.save()

View File

@ -7,36 +7,115 @@ from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
dependencies = [migrations.swappable_dependency(settings.AUTH_USER_MODEL)]
operations = [
migrations.CreateModel(
name='UserProfile',
name="UserProfile",
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('is_pro', models.BooleanField(default=False)),
('teams_beta_seen', models.BooleanField(default=False)),
('teams_beta_applied', models.BooleanField(default=False)),
('pro_date', models.DateTimeField(null=True, blank=True)),
('stripe_id', models.CharField(max_length=100, null=True, blank=True)),
('has_gravatar', models.BooleanField(default=False)),
('list_view', models.CharField(default=b'N', max_length=1, choices=[(b'N', b'Normal'), (b'C', b'Compact')])),
('blog_title', models.CharField(max_length=250, null=True, blank=True)),
('blog_theme', models.CharField(default=b'A', max_length=1, choices=[(b'D', b'Default'), (b'A', b'Pro Adams')])),
('blog_domain', models.CharField(max_length=250, null=True, blank=True)),
('default_editor', models.CharField(default=b'C', max_length=250, choices=[(b'C', b'CodeMirror'), (b'T', b'Textarea')])),
('editor_theme', models.CharField(default=b'default', max_length=250, choices=[(b'default', b'Default'), (b'ambiance', b'Ambiance'), (b'blackboard', b'Blackboard'), (b'cobalt', b'Cobalt'), (b'eclipse', b'Eclipse'), (b'elegant', b'Elegant'), (b'erlang-dark', b'Erlang Dark'), (b'lesser-dark', b'Lesser Dark'), (b'monokai', b'Monokai'), (b'neat', b'Neat'), (b'night', b'Night'), (b'rubyblue', b'Ruby Blue'), (b'solarized dark', b'Solarized Dark'), (b'solarized light', b'Solarized Light'), (b'twilight', b'Twilight'), (b'vibrant-ink', b'Vibrant Ink'), (b'xq-dark', b'XQ Dark')])),
('gittip_username', models.CharField(max_length=250, null=True, blank=True)),
('disqus_shortname', models.CharField(max_length=250, null=True, blank=True)),
('google_analytics_tracking_id', models.CharField(max_length=250, null=True, blank=True)),
('gauges_site_id', models.CharField(max_length=250, null=True, blank=True)),
('google_ad_client', models.CharField(max_length=250, null=True, blank=True)),
('google_ad_slot', models.CharField(max_length=250, null=True, blank=True)),
('google_ad_width', models.CharField(max_length=250, null=True, blank=True)),
('google_ad_height', models.CharField(max_length=250, null=True, blank=True)),
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, unique=True)),
(
"id",
models.AutoField(
verbose_name="ID",
serialize=False,
auto_created=True,
primary_key=True,
),
),
("is_pro", models.BooleanField(default=False)),
("teams_beta_seen", models.BooleanField(default=False)),
("teams_beta_applied", models.BooleanField(default=False)),
("pro_date", models.DateTimeField(null=True, blank=True)),
("stripe_id", models.CharField(max_length=100, null=True, blank=True)),
("has_gravatar", models.BooleanField(default=False)),
(
"list_view",
models.CharField(
default=b"N",
max_length=1,
choices=[(b"N", b"Normal"), (b"C", b"Compact")],
),
),
("blog_title", models.CharField(max_length=250, null=True, blank=True)),
(
"blog_theme",
models.CharField(
default=b"A",
max_length=1,
choices=[(b"D", b"Default"), (b"A", b"Pro Adams")],
),
),
(
"blog_domain",
models.CharField(max_length=250, null=True, blank=True),
),
(
"default_editor",
models.CharField(
default=b"C",
max_length=250,
choices=[(b"C", b"CodeMirror"), (b"T", b"Textarea")],
),
),
(
"editor_theme",
models.CharField(
default=b"default",
max_length=250,
choices=[
(b"default", b"Default"),
(b"ambiance", b"Ambiance"),
(b"blackboard", b"Blackboard"),
(b"cobalt", b"Cobalt"),
(b"eclipse", b"Eclipse"),
(b"elegant", b"Elegant"),
(b"erlang-dark", b"Erlang Dark"),
(b"lesser-dark", b"Lesser Dark"),
(b"monokai", b"Monokai"),
(b"neat", b"Neat"),
(b"night", b"Night"),
(b"rubyblue", b"Ruby Blue"),
(b"solarized dark", b"Solarized Dark"),
(b"solarized light", b"Solarized Light"),
(b"twilight", b"Twilight"),
(b"vibrant-ink", b"Vibrant Ink"),
(b"xq-dark", b"XQ Dark"),
],
),
),
(
"gittip_username",
models.CharField(max_length=250, null=True, blank=True),
),
(
"disqus_shortname",
models.CharField(max_length=250, null=True, blank=True),
),
(
"google_analytics_tracking_id",
models.CharField(max_length=250, null=True, blank=True),
),
(
"gauges_site_id",
models.CharField(max_length=250, null=True, blank=True),
),
(
"google_ad_client",
models.CharField(max_length=250, null=True, blank=True),
),
(
"google_ad_slot",
models.CharField(max_length=250, null=True, blank=True),
),
(
"google_ad_width",
models.CharField(max_length=250, null=True, blank=True),
),
(
"google_ad_height",
models.CharField(max_length=250, null=True, blank=True),
),
("user", models.ForeignKey(to=settings.AUTH_USER_MODEL, unique=True)),
],
),
)
]

View File

@ -7,14 +7,12 @@ from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
('accounts', '0001_initial'),
]
dependencies = [("accounts", "0001_initial")]
operations = [
migrations.AlterField(
model_name='userprofile',
name='user',
model_name="userprofile",
name="user",
field=models.OneToOneField(to=settings.AUTH_USER_MODEL),
),
)
]

View File

@ -6,29 +6,59 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('accounts', '0002_auto_20150724_2010'),
]
dependencies = [("accounts", "0002_auto_20150724_2010")]
operations = [
migrations.AlterField(
model_name='userprofile',
name='blog_theme',
field=models.CharField(max_length=1, choices=[('D', 'Default'), ('A', 'Pro Adams')], default='A'),
model_name="userprofile",
name="blog_theme",
field=models.CharField(
max_length=1,
choices=[("D", "Default"), ("A", "Pro Adams")],
default="A",
),
),
migrations.AlterField(
model_name='userprofile',
name='default_editor',
field=models.CharField(max_length=250, choices=[('C', 'CodeMirror'), ('T', 'Textarea')], default='C'),
model_name="userprofile",
name="default_editor",
field=models.CharField(
max_length=250,
choices=[("C", "CodeMirror"), ("T", "Textarea")],
default="C",
),
),
migrations.AlterField(
model_name='userprofile',
name='editor_theme',
field=models.CharField(max_length=250, choices=[('default', 'Default'), ('ambiance', 'Ambiance'), ('blackboard', 'Blackboard'), ('cobalt', 'Cobalt'), ('eclipse', 'Eclipse'), ('elegant', 'Elegant'), ('erlang-dark', 'Erlang Dark'), ('lesser-dark', 'Lesser Dark'), ('monokai', 'Monokai'), ('neat', 'Neat'), ('night', 'Night'), ('rubyblue', 'Ruby Blue'), ('solarized dark', 'Solarized Dark'), ('solarized light', 'Solarized Light'), ('twilight', 'Twilight'), ('vibrant-ink', 'Vibrant Ink'), ('xq-dark', 'XQ Dark')], default='default'),
model_name="userprofile",
name="editor_theme",
field=models.CharField(
max_length=250,
choices=[
("default", "Default"),
("ambiance", "Ambiance"),
("blackboard", "Blackboard"),
("cobalt", "Cobalt"),
("eclipse", "Eclipse"),
("elegant", "Elegant"),
("erlang-dark", "Erlang Dark"),
("lesser-dark", "Lesser Dark"),
("monokai", "Monokai"),
("neat", "Neat"),
("night", "Night"),
("rubyblue", "Ruby Blue"),
("solarized dark", "Solarized Dark"),
("solarized light", "Solarized Light"),
("twilight", "Twilight"),
("vibrant-ink", "Vibrant Ink"),
("xq-dark", "XQ Dark"),
],
default="default",
),
),
migrations.AlterField(
model_name='userprofile',
name='list_view',
field=models.CharField(max_length=1, choices=[('N', 'Normal'), ('C', 'Compact')], default='N'),
model_name="userprofile",
name="list_view",
field=models.CharField(
max_length=1, choices=[("N", "Normal"), ("C", "Compact")], default="N"
),
),
]

View File

@ -9,39 +9,30 @@ from teams.models import Team
class UserProfile(models.Model):
LIST_VIEW_CHOICES = (
('N', 'Normal'),
('C', 'Compact'),
)
LIST_VIEW_CHOICES = (("N", "Normal"), ("C", "Compact"))
EDITOR_CHOICES = (
('C', 'CodeMirror'),
('T', 'Textarea'),
)
EDITOR_CHOICES = (("C", "CodeMirror"), ("T", "Textarea"))
THEME_CHOICES = (
('D', 'Default'),
('A', 'Pro Adams'),
)
THEME_CHOICES = (("D", "Default"), ("A", "Pro Adams"))
EDITOR_THEME_CHOICES = (
('default', 'Default'),
('ambiance', 'Ambiance'),
('blackboard', 'Blackboard'),
('cobalt', 'Cobalt'),
('eclipse', 'Eclipse'),
('elegant', 'Elegant'),
('erlang-dark', 'Erlang Dark'),
('lesser-dark', 'Lesser Dark'),
('monokai', 'Monokai'),
('neat', 'Neat'),
('night', 'Night'),
('rubyblue', 'Ruby Blue'),
('solarized dark', 'Solarized Dark'),
('solarized light', 'Solarized Light'),
('twilight', 'Twilight'),
('vibrant-ink', 'Vibrant Ink'),
('xq-dark', 'XQ Dark'),
("default", "Default"),
("ambiance", "Ambiance"),
("blackboard", "Blackboard"),
("cobalt", "Cobalt"),
("eclipse", "Eclipse"),
("elegant", "Elegant"),
("erlang-dark", "Erlang Dark"),
("lesser-dark", "Lesser Dark"),
("monokai", "Monokai"),
("neat", "Neat"),
("night", "Night"),
("rubyblue", "Ruby Blue"),
("solarized dark", "Solarized Dark"),
("solarized light", "Solarized Light"),
("twilight", "Twilight"),
("vibrant-ink", "Vibrant Ink"),
("xq-dark", "XQ Dark"),
)
# User
@ -52,27 +43,35 @@ class UserProfile(models.Model):
pro_date = models.DateTimeField(blank=True, null=True)
stripe_id = models.CharField(max_length=100, null=True, blank=True)
has_gravatar = models.BooleanField(default=False)
list_view = models.CharField(max_length=1, null=False, blank=False,
default='N', choices=LIST_VIEW_CHOICES)
list_view = models.CharField(
max_length=1, null=False, blank=False, default="N", choices=LIST_VIEW_CHOICES
)
# Blog
blog_title = models.CharField(max_length=250, null=True, blank=True)
blog_theme = models.CharField(max_length=1, null=False, blank=False,
default='A', choices=THEME_CHOICES)
blog_theme = models.CharField(
max_length=1, null=False, blank=False, default="A", choices=THEME_CHOICES
)
blog_domain = models.CharField(max_length=250, null=True, blank=True)
# Editor
default_editor = models.CharField(max_length=250, null=False, blank=False,
default='C', choices=EDITOR_CHOICES)
editor_theme = models.CharField(max_length=250, null=False, blank=False,
default='default',
choices=EDITOR_THEME_CHOICES)
default_editor = models.CharField(
max_length=250, null=False, blank=False, default="C", choices=EDITOR_CHOICES
)
editor_theme = models.CharField(
max_length=250,
null=False,
blank=False,
default="default",
choices=EDITOR_THEME_CHOICES,
)
# Services and Analytics
gittip_username = models.CharField(max_length=250, null=True, blank=True)
disqus_shortname = models.CharField(max_length=250, null=True, blank=True)
google_analytics_tracking_id = models.CharField(max_length=250, null=True,
blank=True)
google_analytics_tracking_id = models.CharField(
max_length=250, null=True, blank=True
)
gauges_site_id = models.CharField(max_length=250, null=True, blank=True)
# Google Ads
@ -82,36 +81,34 @@ class UserProfile(models.Model):
google_ad_height = models.CharField(max_length=250, null=True, blank=True)
def get_blog_posts(self):
return Snipt.objects.filter(user=self.user, blog_post=True,
public=True)
return Snipt.objects.filter(user=self.user, blog_post=True, public=True)
def get_primary_blog_domain(self):
if not self.blog_domain:
return None
else:
return self.blog_domain.split(' ')[0]
return self.blog_domain.split(" ")[0]
def get_user_profile_url(self):
# If the user has a blog domain, use that.
if self.blog_domain:
url = 'http://{}'.format(self.get_primary_blog_domain())
url = "http://{}".format(self.get_primary_blog_domain())
# Otherwise, if they have blog posts, use their Snipt blog URL.
elif self.get_blog_posts():
url = 'https://{}.snippets.siftie.com/'.format(self.user.username)
url = "https://{}.snippets.siftie.com/".format(self.user.username)
# Otherwise, use their regular Snipt profile page.
else:
url = 'https://snippets.siftie.com/{}/'.format(self.user.username)
url = "https://snippets.siftie.com/{}/".format(self.user.username)
return url
def has_public_snipts(self):
return True \
if Snipt.objects.filter(user=self,
public=True).count() > 0 \
else False
return (
True if Snipt.objects.filter(user=self, public=True).count() > 0 else False
)
@property
def is_a_team(self):
@ -127,14 +124,16 @@ class UserProfile(models.Model):
@property
def has_teams(self):
if (len(self.teams()) > 0):
if len(self.teams()) > 0:
return True
else:
return False
def get_account_age(self):
delta = datetime.now().replace(tzinfo=None) - \
self.user.date_joined.replace(tzinfo=None)
delta = datetime.now().replace(tzinfo=None) - self.user.date_joined.replace(
tzinfo=None
)
return delta.days
User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])

View File

@ -3,6 +3,6 @@ from django.conf.urls import url
urlpatterns = [
url(r'^stats/$', views.stats, name='account-stats'),
url(r'^', views.account, name='account-detail')
url(r"^stats/$", views.stats, name="account-stats"),
url(r"^", views.account, name="account-detail"),
]

View File

@ -5,17 +5,15 @@ from snipts.models import Snipt
@login_required
@render_to('account.html')
@render_to("account.html")
def account(request):
return {}
@login_required
@render_to('stats.html')
@render_to("stats.html")
def stats(request):
snipts = Snipt.objects.filter(user=request.user).order_by('-views')
snipts = Snipt.objects.filter(user=request.user).order_by("-views")
return {
'snipts': snipts
}
return {"snipts": snipts}

View File

@ -8,43 +8,43 @@ class BlogMiddleware:
def process_request(self, request):
request.blog_user = None
host = request.META.get('HTTP_HOST', '')
host_s = host.replace('www.', '').split('.')
host = request.META.get("HTTP_HOST", "")
host_s = host.replace("www.", "").split(".")
if host != 'snippets.siftie.com' and \
host != 'snipt.localhost' and \
host != 'local.snippets.siftie.com':
if (
host != "snippets.siftie.com"
and host != "snipt.localhost"
and host != "local.snippets.siftie.com"
):
if len(host_s) > 2:
if host_s[1] == 'snipt':
if host_s[1] == "snipt":
blog_user = ''.join(host_s[:-2])
blog_user = "".join(host_s[:-2])
if '-' in blog_user:
request.blog_user = \
get_object_or_None(User,
username__iexact=blog_user)
if "-" in blog_user:
request.blog_user = get_object_or_None(
User, username__iexact=blog_user
)
if request.blog_user is None:
request.blog_user = \
get_object_or_404(User,
username__iexact=blog_user
.replace('-', '_'))
request.blog_user = get_object_or_404(
User, username__iexact=blog_user.replace("-", "_")
)
else:
request.blog_user = \
get_object_or_404(User, username__iexact=blog_user)
request.blog_user = get_object_or_404(
User, username__iexact=blog_user
)
if request.blog_user is None:
pro_users = User.objects.filter(userprofile__is_pro=True)
for pro_user in pro_users:
if pro_user.profile.blog_domain:
if host in pro_user.profile.blog_domain.split(' '):
if host in pro_user.profile.blog_domain.split(" "):
request.blog_user = pro_user
if host != \
pro_user.profile.get_primary_blog_domain():
if host != pro_user.profile.get_primary_blog_domain():
return HttpResponseRedirect(
'http://' +
pro_user
.profile
.get_primary_blog_domain())
"http://"
+ pro_user.profile.get_primary_blog_domain()
)

View File

@ -2,4 +2,4 @@ from blogs import views
from django.conf.urls import url
urlpatterns = [url(r'^$', views.blog, name='blog')]
urlpatterns = [url(r"^$", views.blog, name="blog")]

View File

@ -4,10 +4,7 @@ from annoying.functions import get_object_or_None
from django.shortcuts import get_object_or_404, render
from snipts.models import Snipt
THEME_CHOICES = {
'D': 'blogs/themes/default/',
'A': 'blogs/themes/pro-adams/',
}
THEME_CHOICES = {"D": "blogs/themes/default/", "A": "blogs/themes/pro-adams/"}
def blog_list(request, username_or_custom_slug=None):
@ -15,83 +12,95 @@ def blog_list(request, username_or_custom_slug=None):
if username_or_custom_slug:
return blog_post(request, username_or_custom_slug)
snipts = Snipt.objects.filter(user=request.blog_user,
blog_post=True,
public=True,
publish_date__lte=datetime.datetime.now()) \
.order_by('-publish_date') \
.exclude(title__iexact='Homepage') \
.exclude(title__iexact='Work')
snipts = (
Snipt.objects.filter(
user=request.blog_user,
blog_post=True,
public=True,
publish_date__lte=datetime.datetime.now(),
)
.order_by("-publish_date")
.exclude(title__iexact="Homepage")
.exclude(title__iexact="Work")
)
normal_snipts = Snipt.objects.filter(blog_post=False,
user=request.blog_user,
public=True) \
.order_by('-created')
normal_snipts = normal_snipts.exclude(title__in=[''])
normal_snipts = normal_snipts.exclude(tags__name__in=['tmp'])
normal_snipts = Snipt.objects.filter(
blog_post=False, user=request.blog_user, public=True
).order_by("-created")
normal_snipts = normal_snipts.exclude(title__in=[""])
normal_snipts = normal_snipts.exclude(tags__name__in=["tmp"])
normal_snipts = normal_snipts[:3]
sidebar = get_object_or_None(Snipt, user=request.blog_user,
title='Sidebar', blog_post=True)
header = get_object_or_None(Snipt, user=request.blog_user, title='Header',
blog_post=True)
custom_css = get_object_or_None(Snipt, user=request.blog_user, title='CSS',
lexer='css', blog_post=True)
sidebar = get_object_or_None(
Snipt, user=request.blog_user, title="Sidebar", blog_post=True
)
header = get_object_or_None(
Snipt, user=request.blog_user, title="Header", blog_post=True
)
custom_css = get_object_or_None(
Snipt, user=request.blog_user, title="CSS", lexer="css", blog_post=True
)
context = {
'blog_user': request.blog_user,
'custom_css': custom_css,
'has_snipts': True,
'header': header,
'normal_snipts': normal_snipts,
'public': True,
'sidebar': sidebar,
'snipts': snipts,
"blog_user": request.blog_user,
"custom_css": custom_css,
"has_snipts": True,
"header": header,
"normal_snipts": normal_snipts,
"public": True,
"sidebar": sidebar,
"snipts": snipts,
}
if 'rss' in request.GET:
context['snipts'] = context['snipts'][:20]
if "rss" in request.GET:
context["snipts"] = context["snipts"][:20]
return rss(request, context)
template = THEME_CHOICES[request.blog_user.profile.blog_theme]
template = '{}/list.html'.format(template)
template = "{}/list.html".format(template)
return render(
request,
template,
context,
)
return render(request, template, context)
def blog_post(request, username_or_custom_slug):
snipt = get_object_or_404(Snipt, user=request.blog_user,
blog_post=True,
public=True,
publish_date__lte=datetime.datetime.now(),
slug=username_or_custom_slug)
snipt = get_object_or_404(
Snipt,
user=request.blog_user,
blog_post=True,
public=True,
publish_date__lte=datetime.datetime.now(),
slug=username_or_custom_slug,
)
snipts = Snipt.objects.filter(user=request.blog_user,
blog_post=True,
public=True,
publish_date__lte=datetime.datetime.now()) \
.order_by('-publish_date') \
.exclude(title__iexact='Homepage') \
.exclude(title__iexact='Work')
snipts = (
Snipt.objects.filter(
user=request.blog_user,
blog_post=True,
public=True,
publish_date__lte=datetime.datetime.now(),
)
.order_by("-publish_date")
.exclude(title__iexact="Homepage")
.exclude(title__iexact="Work")
)
sidebar = get_object_or_None(Snipt, user=request.blog_user,
title='Sidebar', blog_post=True)
header = get_object_or_None(Snipt, user=request.blog_user, title='Header',
blog_post=True)
custom_css = get_object_or_None(Snipt, user=request.blog_user, title='CSS',
lexer='css', blog_post=True)
sidebar = get_object_or_None(
Snipt, user=request.blog_user, title="Sidebar", blog_post=True
)
header = get_object_or_None(
Snipt, user=request.blog_user, title="Header", blog_post=True
)
custom_css = get_object_or_None(
Snipt, user=request.blog_user, title="CSS", lexer="css", blog_post=True
)
normal_snipts = Snipt.objects.filter(blog_post=False,
user=request.blog_user,
public=True).order_by('-created')
normal_snipts = normal_snipts.exclude(title__in=[''])
normal_snipts = normal_snipts.exclude(tags__name__in=['tmp'])
normal_snipts = Snipt.objects.filter(
blog_post=False, user=request.blog_user, public=True
).order_by("-created")
normal_snipts = normal_snipts.exclude(title__in=[""])
normal_snipts = normal_snipts.exclude(tags__name__in=["tmp"])
normal_snipts = normal_snipts[:3]
if snipt.user != request.user:
@ -99,25 +108,29 @@ def blog_post(request, username_or_custom_slug):
snipt.save()
context = {
'blog_user': request.blog_user,
'custom_css': custom_css,
'detail': True,
'has_snipts': True,
'header': header,
'normal_snipts': normal_snipts,
'public': True,
'sidebar': sidebar,
'snipt': snipt,
'snipts': snipts,
"blog_user": request.blog_user,
"custom_css": custom_css,
"detail": True,
"has_snipts": True,
"header": header,
"normal_snipts": normal_snipts,
"public": True,
"sidebar": sidebar,
"snipt": snipt,
"snipts": snipts,
}
template = THEME_CHOICES[request.blog_user.profile.blog_theme]
template = '{}/post.html'.format(template)
template = "{}/post.html".format(template)
return render(request, template, context)
def rss(request, context):
return render(request, 'blogs/themes/default/rss.xml', context,
content_type="application/rss+xml")
return render(
request,
"blogs/themes/default/rss.xml",
context,
content_type="application/rss+xml",
)

View File

@ -3,134 +3,132 @@ from urllib.parse import urlparse
import dj_database_url
import os
if 'DATABASE_URL' in os.environ:
DATABASES = {'default': dj_database_url.config()}
if "DATABASE_URL" in os.environ:
DATABASES = {"default": dj_database_url.config()}
ABSOLUTE_URL_OVERRIDES = {'auth.user': lambda u: "/%s/" % u.username}
ABSOLUTE_URL_OVERRIDES = {"auth.user": lambda u: "/%s/" % u.username}
ACCOUNT_ACTIVATION_DAYS = 0
ADMINS = (('Siftie', 'team@siftie.com'),)
ALLOWED_HOSTS = ['*']
AUTH_PROFILE_MODULE = 'accounts.UserProfile'
AUTHENTICATION_BACKENDS = ('utils.backends.EmailOrUsernameModelBackend',)
ADMINS = (("Siftie", "team@siftie.com"),)
ALLOWED_HOSTS = ["*"]
AUTH_PROFILE_MODULE = "accounts.UserProfile"
AUTHENTICATION_BACKENDS = ("utils.backends.EmailOrUsernameModelBackend",)
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
DEBUG = True if 'DEBUG' in os.environ else False
DEFAULT_FROM_EMAIL = os.environ.get('POSTMARK_EMAIL', 'support@siftie.com')
EMAIL_BACKEND = 'postmark.django_backend.EmailBackend'
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
INTERNAL_IPS = ('127.0.0.1',)
LANGUAGE_CODE = 'en-us'
LOGIN_REDIRECT_URL = '/login-redirect/'
LOGIN_URL = '/login/'
LOGOUT_URL = '/logout/'
DEBUG = True if "DEBUG" in os.environ else False
DEFAULT_FROM_EMAIL = os.environ.get("POSTMARK_EMAIL", "support@siftie.com")
EMAIL_BACKEND = "postmark.django_backend.EmailBackend"
HAYSTACK_SIGNAL_PROCESSOR = "haystack.signals.RealtimeSignalProcessor"
INTERNAL_IPS = ("127.0.0.1",)
LANGUAGE_CODE = "en-us"
LOGIN_REDIRECT_URL = "/login-redirect/"
LOGIN_URL = "/login/"
LOGOUT_URL = "/logout/"
MANAGERS = ADMINS
MEDIA_ROOT = os.path.join(BASE_PATH, 'media/uploads')
MEDIA_URL = '/media/uploads/'
MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'
MEDIA_ROOT = os.path.join(BASE_PATH, "media/uploads")
MEDIA_URL = "/media/uploads/"
MESSAGE_STORAGE = "django.contrib.messages.storage.cookie.CookieStorage"
PASSWORD_HASHERS = (
'django.contrib.auth.hashers.BCryptPasswordHasher',
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
'django.contrib.auth.hashers.SHA1PasswordHasher',
'django.contrib.auth.hashers.MD5PasswordHasher',
'django.contrib.auth.hashers.CryptPasswordHasher',
"django.contrib.auth.hashers.BCryptPasswordHasher",
"django.contrib.auth.hashers.BCryptSHA256PasswordHasher",
"django.contrib.auth.hashers.PBKDF2PasswordHasher",
"django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher",
"django.contrib.auth.hashers.SHA1PasswordHasher",
"django.contrib.auth.hashers.MD5PasswordHasher",
"django.contrib.auth.hashers.CryptPasswordHasher",
)
POSTMARK_API_KEY = os.environ.get('POSTMARK_API_KEY', '')
POSTMARK_API_KEY = os.environ.get("POSTMARK_API_KEY", "")
PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))
REGISTRATION_EMAIL_HTML = False
ROOT_URLCONF = 'urls'
SECRET_KEY = os.environ.get('SECRET_KEY', 'changeme')
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True if 'USE_SSL' in os.environ else False
ROOT_URLCONF = "urls"
SECRET_KEY = os.environ.get("SECRET_KEY", "changeme")
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
SECURE_SSL_REDIRECT = True if "USE_SSL" in os.environ else False
SEND_BROKEN_LINK_EMAILS = False
SERVER_EMAIL = os.environ.get('POSTMARK_EMAIL', 'support@siftie.com')
SERVER_EMAIL = os.environ.get("POSTMARK_EMAIL", "support@siftie.com")
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
STATICFILES_DIRS = (os.path.join(BASE_PATH, 'media'),)
STATICFILES_FINDERS = ('django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder')
STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'
STATIC_ROOT = os.path.join(BASE_PATH, 'static')
STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join(BASE_PATH, "media"),)
STATICFILES_FINDERS = (
"django.contrib.staticfiles.finders.FileSystemFinder",
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
)
STATICFILES_STORAGE = "whitenoise.django.GzipManifestStaticFilesStorage"
STATIC_ROOT = os.path.join(BASE_PATH, "static")
STATIC_URL = "/static/"
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
we'll help you out."""
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(PROJECT_PATH, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.template.context_processors.static',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [os.path.join(PROJECT_PATH, "templates")],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.template.context_processors.static",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
]
},
},
}
]
TIME_ZONE = 'America/New_York'
USE_HTTPS = True if 'USE_SSL' in os.environ else False
TIME_ZONE = "America/New_York"
USE_HTTPS = True if "USE_SSL" in os.environ else False
USE_I18N = True
USE_L10N = True
USE_TZ = True
INSTALLED_APPS = (
'accounts',
'blogs',
'corsheaders',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.humanize',
'django.contrib.messages',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.staticfiles',
'django_extensions',
'gunicorn',
'haystack',
'markdown_deux',
'pagination',
'postmark',
'registration',
'snipts',
'storages',
'taggit',
'tastypie',
'teams',
'user-admin',
'utils',
"accounts",
"blogs",
"corsheaders",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.humanize",
"django.contrib.messages",
"django.contrib.sessions",
"django.contrib.sites",
"django.contrib.staticfiles",
"django_extensions",
"gunicorn",
"haystack",
"markdown_deux",
"pagination",
"postmark",
"registration",
"snipts",
"storages",
"taggit",
"tastypie",
"teams",
"user-admin",
"utils",
)
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {},
'loggers': {}
"version": 1,
"disable_existing_loggers": False,
"filters": {"require_debug_false": {"()": "django.utils.log.RequireDebugFalse"}},
"handlers": {},
"loggers": {},
}
MIDDLEWARE_CLASSES = (
'django.middleware.security.SecurityMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'pagination.middleware.PaginationMiddleware',
'blogs.middleware.BlogMiddleware',
"django.middleware.security.SecurityMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"corsheaders.middleware.CorsMiddleware",
"django.middleware.common.CommonMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"pagination.middleware.PaginationMiddleware",
"blogs.middleware.BlogMiddleware",
)
try:

View File

@ -3,29 +3,42 @@ from snipts.models import Favorite, Snipt, SniptLogEntry
class SniptAdmin(admin.ModelAdmin):
readonly_fields = ('last_user_saved', 'user',)
list_display = ('title', 'slug', 'views', 'favs', 'user', 'lexer',
'public', 'blog_post', 'created', 'modified',
'publish_date')
list_filter = ('blog_post',)
search_fields = ('title', 'slug', 'user__username', 'lexer', 'id', 'key',)
ordering = ('-created',)
prepopulated_fields = {'slug': ('title',)}
readonly_fields = ("last_user_saved", "user")
list_display = (
"title",
"slug",
"views",
"favs",
"user",
"lexer",
"public",
"blog_post",
"created",
"modified",
"publish_date",
)
list_filter = ("blog_post",)
search_fields = ("title", "slug", "user__username", "lexer", "id", "key")
ordering = ("-created",)
prepopulated_fields = {"slug": ("title",)}
admin.site.register(Snipt, SniptAdmin)
class SniptLogEntryAdmin(admin.ModelAdmin):
readonly_fields = ('snipt', 'user',)
list_display = ('snipt_name', 'user', 'created', 'modified')
readonly_fields = ("snipt", "user")
list_display = ("snipt_name", "user", "created", "modified")
admin.site.register(SniptLogEntry, SniptLogEntryAdmin)
class FavoriteAdmin(admin.ModelAdmin):
readonly_fields = ('snipt', 'user',)
list_display = ('snipt', 'user', 'created',)
search_fields = ('snipt', 'user',)
ordering = ('-created',)
readonly_fields = ("snipt", "user")
list_display = ("snipt", "user", "created")
search_fields = ("snipt", "user")
ordering = ("-created",)
admin.site.register(Favorite, FavoriteAdmin)

View File

@ -139,11 +139,10 @@ class PrivateUserAuthorization(Authorization):
class FavoriteValidation(Validation):
def is_valid(self, bundle, request=None):
errors = {}
snipt = bundle.data['snipt']
snipt = bundle.data["snipt"]
if Favorite.objects.filter(user=bundle.request.user,
snipt=snipt).count():
errors = 'User has already favorited this snipt.'
if Favorite.objects.filter(user=bundle.request.user, snipt=snipt).count():
errors = "User has already favorited this snipt."
return errors
@ -152,8 +151,8 @@ class SniptValidation(Validation):
def is_valid(self, bundle, request=None):
errors = {}
if (len(bundle.data['title']) > 255):
errors = 'Title must be 255 characters or less.'
if len(bundle.data["title"]) > 255:
errors = "Title must be 255 characters or less."
return errors
@ -164,10 +163,12 @@ class UserProfileValidation(Validation):
for field in bundle.data:
if bundle.data[field]:
if not re.match('^[ A-Za-z0-9\/\@\._-]*$', bundle.data[field]):
errors[field] = ('Only spaces, letters, numbers, '
'underscores, dashes, periods, forward '
'slashes, and "at sign" are valid.')
if not re.match("^[ A-Za-z0-9\/\@\._-]*$", bundle.data[field]):
errors[field] = (
"Only spaces, letters, numbers, "
"underscores, dashes, periods, forward "
'slashes, and "at sign" are valid.'
)
return errors
@ -175,33 +176,33 @@ class UserProfileValidation(Validation):
class PublicUserResource(ModelResource):
class Meta:
queryset = User.objects.all()
resource_name = 'user'
fields = ['id', 'username']
resource_name = "user"
fields = ["id", "username"]
include_absolute_url = True
allowed_methods = ['get']
filtering = {'username': ['contains', 'exact']}
allowed_methods = ["get"]
filtering = {"username": ["contains", "exact"]}
max_limit = 200
cache = SimpleCache()
def dehydrate(self, bundle):
bundle.data['snipts'] = '/api/public/snipt/?user=%d' % bundle.obj.id
bundle.data['email_md5'] = hashlib \
.md5(bundle.obj.email.lower().encode('utf-8')) \
.hexdigest()
bundle.data['snipts_count'] = Snipt.objects.filter(user=bundle.obj.id,
public=True).count()
bundle.data["snipts"] = "/api/public/snipt/?user=%d" % bundle.obj.id
bundle.data["email_md5"] = hashlib.md5(
bundle.obj.email.lower().encode("utf-8")
).hexdigest()
bundle.data["snipts_count"] = Snipt.objects.filter(
user=bundle.obj.id, public=True
).count()
return bundle
class PublicTagResource(ModelResource):
class Meta:
queryset = Tag.objects.filter()
queryset = queryset.annotate(
count=models.Count('taggit_taggeditem_items__id'))
queryset = queryset.order_by('-count', 'name')
resource_name = 'tag'
fields = ['id', 'name']
allowed_methods = ['get']
queryset = queryset.annotate(count=models.Count("taggit_taggeditem_items__id"))
queryset = queryset.order_by("-count", "name")
resource_name = "tag"
fields = ["id", "name"]
allowed_methods = ["get"]
max_limit = 200
cache = SimpleCache()
@ -211,60 +212,74 @@ class PublicTagResource(ModelResource):
orm_filters = super(PublicTagResource, self).build_filters(filters)
if 'q' in filters:
orm_filters['slug'] = filters['q']
if "q" in filters:
orm_filters["slug"] = filters["q"]
return orm_filters
def dehydrate(self, bundle):
bundle.data['absolute_url'] = '/public/tag/%s/' % bundle.obj.slug
bundle.data['snipts'] = '/api/public/snipt/?tag=%d' % bundle.obj.id
bundle.data["absolute_url"] = "/public/tag/%s/" % bundle.obj.slug
bundle.data["snipts"] = "/api/public/snipt/?tag=%d" % bundle.obj.id
return bundle
class PublicSniptResource(ModelResource):
user = fields.ForeignKey(PublicUserResource, 'user', full=True)
tags = fields.ToManyField(PublicTagResource, 'tags', related_name='tag',
full=True)
user = fields.ForeignKey(PublicUserResource, "user", full=True)
tags = fields.ToManyField(PublicTagResource, "tags", related_name="tag", full=True)
class Meta:
queryset = Snipt.objects.filter(public=True).order_by('-created')
resource_name = 'snipt'
fields = ['id', 'title', 'slug', 'lexer', 'code', 'description',
'line_count', 'stylized', 'created', 'modified',
'publish_date', 'blog_post', 'meta']
queryset = Snipt.objects.filter(public=True).order_by("-created")
resource_name = "snipt"
fields = [
"id",
"title",
"slug",
"lexer",
"code",
"description",
"line_count",
"stylized",
"created",
"modified",
"publish_date",
"blog_post",
"meta",
]
include_absolute_url = True
allowed_methods = ['get']
filtering = {'user': 'exact', 'blog_post': 'exact'}
ordering = ['created', 'modified']
allowed_methods = ["get"]
filtering = {"user": "exact", "blog_post": "exact"}
ordering = ["created", "modified"]
max_limit = 200
cache = SimpleCache()
def dehydrate(self, bundle):
bundle.data['embed_url'] = bundle.obj.get_embed_url()
bundle.data['raw_url'] = bundle.obj.get_raw_url()
bundle.data['full_absolute_url'] = bundle.obj.get_full_absolute_url()
bundle.data['description_rendered'] = \
linebreaksbr(urlize(bundle.obj.description))
bundle.data["embed_url"] = bundle.obj.get_embed_url()
bundle.data["raw_url"] = bundle.obj.get_raw_url()
bundle.data["full_absolute_url"] = bundle.obj.get_full_absolute_url()
bundle.data["description_rendered"] = linebreaksbr(
urlize(bundle.obj.description)
)
log_entries = bundle.obj.sniptlogentry_set.all()
bundle_log_entries = []
for entry in log_entries:
bundle_log_entries.append({
'created': entry.created,
'user': entry.user,
'code': entry.code,
'diff': entry.diff
})
bundle_log_entries.append(
{
"created": entry.created,
"user": entry.user,
"code": entry.code,
"diff": entry.diff,
}
)
bundle.data['log_entries'] = bundle_log_entries
bundle.data["log_entries"] = bundle_log_entries
if 'omit_code' in bundle.request.GET:
del bundle.data['code']
if "omit_code" in bundle.request.GET:
del bundle.data["code"]
if 'omit_stylized' in bundle.request.GET:
del bundle.data['stylized']
if "omit_stylized" in bundle.request.GET:
del bundle.data["stylized"]
return bundle
@ -274,14 +289,14 @@ class PublicSniptResource(ModelResource):
orm_filters = super(PublicSniptResource, self).build_filters(filters)
if 'tag' in filters:
tag = Tag.objects.get(pk=filters['tag'])
if "tag" in filters:
tag = Tag.objects.get(pk=filters["tag"])
tagged_items = tag.taggit_taggeditem_items.all()
orm_filters['pk__in'] = [i.object_id for i in tagged_items]
orm_filters["pk__in"] = [i.object_id for i in tagged_items]
if 'q' in filters:
sqs = SearchQuerySet().auto_query(filters['q'])
orm_filters['pk__in'] = [i.pk for i in sqs]
if "q" in filters:
sqs = SearchQuerySet().auto_query(filters["q"])
orm_filters["pk__in"] = [i.pk for i in sqs]
return orm_filters
@ -289,11 +304,11 @@ class PublicSniptResource(ModelResource):
class PrivateUserProfileResource(ModelResource):
class Meta:
queryset = UserProfile.objects.all()
resource_name = 'profile'
excludes = ['is_pro']
resource_name = "profile"
excludes = ["is_pro"]
validation = UserProfileValidation()
include_absolute_url = False
allowed_methods = ['get', 'put']
allowed_methods = ["get", "put"]
list_allowed_methods = []
authentication = ApiKeyAuthentication()
authorization = PrivateUserProfileAuthorization()
@ -301,23 +316,22 @@ class PrivateUserProfileResource(ModelResource):
max_limit = 200
def dehydrate(self, bundle):
bundle.data['email'] = bundle.obj.user.email
bundle.data['username'] = bundle.obj.user.username
bundle.data['user_id'] = bundle.obj.user.id
bundle.data['api_key'] = bundle.obj.user.api_key.key
bundle.data["email"] = bundle.obj.user.email
bundle.data["username"] = bundle.obj.user.username
bundle.data["user_id"] = bundle.obj.user.id
bundle.data["api_key"] = bundle.obj.user.api_key.key
return bundle
class PrivateUserResource(ModelResource):
profile = fields.ForeignKey(PrivateUserProfileResource, 'profile',
full=False)
profile = fields.ForeignKey(PrivateUserProfileResource, "profile", full=False)
class Meta:
queryset = User.objects.all()
resource_name = 'user'
fields = ['id', 'username', 'email']
resource_name = "user"
fields = ["id", "username", "email"]
include_absolute_url = True
allowed_methods = ['get']
allowed_methods = ["get"]
list_allowed_methods = []
authentication = ApiKeyAuthentication()
authorization = PrivateUserAuthorization()
@ -326,155 +340,172 @@ class PrivateUserResource(ModelResource):
cache = SimpleCache()
def dehydrate(self, bundle):
bundle.data['email_md5'] = hashlib \
.md5(bundle.obj.email.lower().encode('utf-8')) \
.hexdigest()
bundle.data['stats'] = {
'public_snipts': Snipt.objects.filter(user=bundle.obj.id,
public=True).count(),
'private_snipts': Snipt.objects.filter(user=bundle.obj.id,
public=False).count(),
'total_snipts': Snipt.objects.filter(user=bundle.obj.id).count(),
'total_views': Snipt.objects.filter(user=bundle.obj.id).aggregate(
models.Sum('views'))['views__sum']
bundle.data["email_md5"] = hashlib.md5(
bundle.obj.email.lower().encode("utf-8")
).hexdigest()
bundle.data["stats"] = {
"public_snipts": Snipt.objects.filter(
user=bundle.obj.id, public=True
).count(),
"private_snipts": Snipt.objects.filter(
user=bundle.obj.id, public=False
).count(),
"total_snipts": Snipt.objects.filter(user=bundle.obj.id).count(),
"total_views": Snipt.objects.filter(user=bundle.obj.id).aggregate(
models.Sum("views")
)["views__sum"],
}
user_snipts = Snipt.objects.filter(user=bundle.obj)
user_tags = [
snipt['tags'] for snipt in user_snipts.values('tags').distinct()
]
user_tags = [snipt["tags"] for snipt in user_snipts.values("tags").distinct()]
tags = [
tag['name'] for tag in
Tag.objects.filter(id__in=user_tags).values('name').distinct()
tag["name"]
for tag in Tag.objects.filter(id__in=user_tags).values("name").distinct()
]
bundle.data['tags'] = tags
bundle.data["tags"] = tags
bundle.data['lexers'] = [
snipt['lexer'] for snipt in user_snipts
.values('lexer').distinct()]
bundle.data["lexers"] = [
snipt["lexer"] for snipt in user_snipts.values("lexer").distinct()
]
return bundle
class PrivateSniptResource(ModelResource):
user = fields.ForeignKey(PrivateUserResource, 'user', full=True)
last_user_saved = fields.ForeignKey(PrivateUserResource,
'last_user_saved',
null=True,
full=False)
user = fields.ForeignKey(PrivateUserResource, "user", full=True)
last_user_saved = fields.ForeignKey(
PrivateUserResource, "last_user_saved", null=True, full=False
)
tags_list = ListField()
tags = fields.ToManyField(PublicTagResource, 'tags', related_name='tag',
full=True)
tags = fields.ToManyField(PublicTagResource, "tags", related_name="tag", full=True)
class Meta:
queryset = Snipt.objects.all().order_by('-created')
resource_name = 'snipt'
fields = ['id', 'title', 'slug', 'lexer', 'code', 'description',
'line_count', 'stylized', 'key', 'public', 'secure',
'blog_post', 'created', 'modified', 'publish_date', 'meta']
queryset = Snipt.objects.all().order_by("-created")
resource_name = "snipt"
fields = [
"id",
"title",
"slug",
"lexer",
"code",
"description",
"line_count",
"stylized",
"key",
"public",
"secure",
"blog_post",
"created",
"modified",
"publish_date",
"meta",
]
include_absolute_url = True
detail_allowed_methods = ['get', 'patch', 'put', 'delete']
list_allowed_methods = ['get', 'post']
detail_allowed_methods = ["get", "patch", "put", "delete"]
list_allowed_methods = ["get", "post"]
authentication = ApiKeyAuthentication()
authorization = PrivateSniptAuthorization()
validation = SniptValidation()
ordering = ['created', 'modified']
ordering = ["created", "modified"]
always_return_data = True
max_limit = 200
cache = SimpleCache()
def dehydrate(self, bundle):
bundle.data['embed_url'] = bundle.obj.get_embed_url()
bundle.data['raw_url'] = bundle.obj.get_raw_url()
bundle.data['tags_list'] = edit_string_for_tags(bundle.obj.tags.all())
bundle.data['full_absolute_url'] = bundle.obj.get_full_absolute_url()
bundle.data['description_rendered'] = \
linebreaksbr(urlize(bundle.obj.description))
bundle.data['views'] = bundle.obj.views
bundle.data['favs'] = bundle.obj.favs()
bundle.data["embed_url"] = bundle.obj.get_embed_url()
bundle.data["raw_url"] = bundle.obj.get_raw_url()
bundle.data["tags_list"] = edit_string_for_tags(bundle.obj.tags.all())
bundle.data["full_absolute_url"] = bundle.obj.get_full_absolute_url()
bundle.data["description_rendered"] = linebreaksbr(
urlize(bundle.obj.description)
)
bundle.data["views"] = bundle.obj.views
bundle.data["favs"] = bundle.obj.favs()
if bundle.data['publish_date']:
bundle.data['publish_date'] = \
date(bundle.data['publish_date'], 'M d, Y \\a\\t h:i A')
if bundle.data["publish_date"]:
bundle.data["publish_date"] = date(
bundle.data["publish_date"], "M d, Y \\a\\t h:i A"
)
log_entries = bundle.obj.sniptlogentry_set.all()
bundle_log_entries = []
for entry in log_entries:
bundle_log_entries.append({
'created': entry.created,
'user': entry.user,
'code': entry.code,
'diff': entry.diff
})
bundle_log_entries.append(
{
"created": entry.created,
"user": entry.user,
"code": entry.code,
"diff": entry.diff,
}
)
bundle.data['log_entries'] = bundle_log_entries
bundle.data["log_entries"] = bundle_log_entries
return bundle
def obj_create(self, bundle, **kwargs):
bundle.data['last_user_saved'] = bundle.request.user
bundle.data['tags_list'] = bundle.data.get('tags')
bundle.data['tags'] = []
bundle.data["last_user_saved"] = bundle.request.user
bundle.data["tags_list"] = bundle.data.get("tags")
bundle.data["tags"] = []
if 'intended_user' in bundle.data:
bundle.data['user'] = \
User.objects.get(username=bundle.data['intended_user'])
if "intended_user" in bundle.data:
bundle.data["user"] = User.objects.get(
username=bundle.data["intended_user"]
)
else:
bundle.data['user'] = bundle.request.user
bundle.data["user"] = bundle.request.user
if 'blog_post' in bundle.data:
if "blog_post" in bundle.data:
bundle = self._clean_publish_date(bundle)
return super(PrivateSniptResource, self) \
.obj_create(bundle, **kwargs)
return super(PrivateSniptResource, self).obj_create(bundle, **kwargs)
def obj_update(self, bundle, **kwargs):
instance = Snipt.objects.get(pk=bundle.data['id'])
instance = Snipt.objects.get(pk=bundle.data["id"])
if (instance.user.profile.is_a_team):
if instance.user.profile.is_a_team:
user = instance.user
else:
user = bundle.request.user
bundle.data['created'] = None
bundle.data['last_user_saved'] = bundle.request.user
bundle.data['modified'] = None
bundle.data['user'] = user
bundle.data["created"] = None
bundle.data["last_user_saved"] = bundle.request.user
bundle.data["modified"] = None
bundle.data["user"] = user
if type(bundle.data['tags']) == str or type(bundle.data['tags']) == unicode:
bundle.data['tags_list'] = bundle.data['tags']
if type(bundle.data["tags"]) == str or type(bundle.data["tags"]) == unicode:
bundle.data["tags_list"] = bundle.data["tags"]
else:
bundle.data['tags_list'] = ''
bundle.data['tags'] = ''
bundle.data["tags_list"] = ""
bundle.data["tags"] = ""
if 'blog_post' in bundle.data:
if "blog_post" in bundle.data:
bundle = self._clean_publish_date(bundle)
return super(PrivateSniptResource, self) \
.obj_update(bundle, **kwargs)
return super(PrivateSniptResource, self).obj_update(bundle, **kwargs)
def _clean_publish_date(self, bundle):
if bundle.data['blog_post'] and 'publish_date' not in bundle.data:
bundle.data['publish_date'] = datetime.datetime.now()
elif bundle.data['publish_date'] == '':
bundle.data['publish_date'] = datetime.datetime.now()
elif bundle.data['blog_post']:
if bundle.data["blog_post"] and "publish_date" not in bundle.data:
bundle.data["publish_date"] = datetime.datetime.now()
elif bundle.data["publish_date"] == "":
bundle.data["publish_date"] = datetime.datetime.now()
elif bundle.data["blog_post"]:
c = pdt.Constants()
p = pdt.Calendar(c)
publish_date, result = p.parse(bundle.data['publish_date'])
publish_date, result = p.parse(bundle.data["publish_date"])
if result != 0:
publish_date = time.strftime('%Y-%m-%d %H:%M:%S', publish_date)
publish_date = time.strftime("%Y-%m-%d %H:%M:%S", publish_date)
else:
publish_date = datetime.datetime.now()
bundle.data['publish_date'] = publish_date
elif not bundle.data['blog_post']:
bundle.data['publish_date'] = None
bundle.data["publish_date"] = publish_date
elif not bundle.data["blog_post"]:
bundle.data["publish_date"] = None
return bundle
@ -484,51 +515,51 @@ class PrivateSniptResource(ModelResource):
orm_filters = super(PrivateSniptResource, self).build_filters(filters)
if 'tag' in filters:
tag = Tag.objects.get(pk=filters['tag'])
if "tag" in filters:
tag = Tag.objects.get(pk=filters["tag"])
tagged_items = tag.taggit_taggeditem_items.all()
orm_filters['pk__in'] = [i.object_id for i in tagged_items]
orm_filters["pk__in"] = [i.object_id for i in tagged_items]
if 'q' in filters:
user = User.objects.get(username=filters['username'])
sqs = SearchQuerySet().filter(author=user, content=filters['q'])
orm_filters['pk__in'] = [i.pk for i in sqs]
if "q" in filters:
user = User.objects.get(username=filters["username"])
sqs = SearchQuerySet().filter(author=user, content=filters["q"])
orm_filters["pk__in"] = [i.pk for i in sqs]
return orm_filters
def save_m2m(self, bundle):
tags = bundle.data.get('tags_list', [])
if tags != '':
tags = bundle.data.get("tags_list", [])
if tags != "":
bundle.obj.tags.set(*parse_tags(tags))
else:
bundle.obj.tags.set()
class PrivateFavoriteResource(ModelResource):
user = fields.ForeignKey(PrivateUserResource, 'user', full=True)
snipt = fields.ForeignKey(PrivateSniptResource, 'snipt', full=False)
user = fields.ForeignKey(PrivateUserResource, "user", full=True)
snipt = fields.ForeignKey(PrivateSniptResource, "snipt", full=False)
class Meta:
queryset = Favorite.objects.all().order_by('-created')
resource_name = 'favorite'
fields = ['id']
queryset = Favorite.objects.all().order_by("-created")
resource_name = "favorite"
fields = ["id"]
validation = FavoriteValidation()
detail_allowed_methods = ['get', 'post', 'delete']
list_allowed_methods = ['get', 'post']
detail_allowed_methods = ["get", "post", "delete"]
list_allowed_methods = ["get", "post"]
authentication = ApiKeyAuthentication()
authorization = PrivateFavoriteAuthorization()
ordering = ['created']
ordering = ["created"]
always_return_data = True
max_limit = 200
cache = SimpleCache()
def dehydrate(self, bundle):
bundle.data['snipt'] = '/api/public/snipt/{}/'.format(
bundle.obj.snipt.pk)
bundle.data["snipt"] = "/api/public/snipt/{}/".format(bundle.obj.snipt.pk)
return bundle
def obj_create(self, bundle, **kwargs):
bundle.data['user'] = bundle.request.user
bundle.data['snipt'] = Snipt.objects.get(pk=bundle.data['snipt'])
return super(PrivateFavoriteResource, self) \
.obj_create(bundle, user=bundle.request.user, **kwargs)
bundle.data["user"] = bundle.request.user
bundle.data["snipt"] = Snipt.objects.get(pk=bundle.data["snipt"])
return super(PrivateFavoriteResource, self).obj_create(
bundle, user=bundle.request.user, **kwargs
)

View File

@ -8,15 +8,22 @@ import requests
def get_snipts(api_key, from_username, url=None, snipts=[]):
path = url or '/api/private/snipt/?limit=50&api_key={}&username={}&format=json'.format(api_key, from_username)
res = requests.get('https://snippets.siftie.com' + path)
path = (
url
or "/api/private/snipt/?limit=50&api_key={}&username={}&format=json".format(
api_key, from_username
)
)
res = requests.get("https://snippets.siftie.com" + path)
json = res.json()
print(u"Fetched snipts {} through {} of {}".format(
json["meta"]["offset"],
json["meta"]["offset"] + json["meta"]["limit"],
json["meta"]["total_count"]
))
print(
u"Fetched snipts {} through {} of {}".format(
json["meta"]["offset"],
json["meta"]["offset"] + json["meta"]["limit"],
json["meta"]["total_count"],
)
)
snipts.extend(json["objects"])
@ -30,14 +37,14 @@ class Command(BaseCommand):
help = u"Import snipts from Siftie Snippets."
def add_arguments(self, parser):
parser.add_argument('api_key', nargs='+', type=str)
parser.add_argument('from_username', nargs='+', type=str)
parser.add_argument('to_username', nargs='+', type=str)
parser.add_argument("api_key", nargs="+", type=str)
parser.add_argument("from_username", nargs="+", type=str)
parser.add_argument("to_username", nargs="+", type=str)
def handle(self, *args, **options):
api_key = options['api_key'][0]
from_username = options['from_username'][0]
to_username = options['to_username'][0]
api_key = options["api_key"][0]
from_username = options["from_username"][0]
to_username = options["to_username"][0]
to_user = User.objects.get(username=to_username)
print(u"Fetching snipts...")
@ -62,7 +69,7 @@ class Command(BaseCommand):
stylized=snipt["stylized"],
title=snipt["title"],
user=to_user,
views=snipt["views"]
views=snipt["views"],
)
s.created = snipt["created"]

View File

@ -9,53 +9,90 @@ import taggit.managers
class Migration(migrations.Migration):
dependencies = [
('taggit', '0001_initial'),
("taggit", "0001_initial"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Favorite',
name="Favorite",
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('created', models.DateTimeField(auto_now_add=True)),
('modified', models.DateTimeField(auto_now=True)),
(
"id",
models.AutoField(
verbose_name="ID",
serialize=False,
auto_created=True,
primary_key=True,
),
),
("created", models.DateTimeField(auto_now_add=True)),
("modified", models.DateTimeField(auto_now=True)),
],
),
migrations.CreateModel(
name='Snipt',
name="Snipt",
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('title', models.CharField(default=b'Untitled', max_length=255, null=True, blank=True)),
('slug', models.SlugField(max_length=255, blank=True)),
('custom_slug', models.SlugField(max_length=255, blank=True)),
('lexer', models.CharField(max_length=50)),
('code', models.TextField()),
('meta', models.TextField(null=True, blank=True)),
('description', models.TextField(null=True, blank=True)),
('stylized', models.TextField(null=True, blank=True)),
('stylized_min', models.TextField(null=True, blank=True)),
('embedded', models.TextField(null=True, blank=True)),
('line_count', models.IntegerField(default=None, null=True, blank=True)),
('key', models.CharField(max_length=100, null=True, blank=True)),
('public', models.BooleanField(default=False)),
('blog_post', models.BooleanField(default=False)),
('views', models.IntegerField(default=0)),
('created', models.DateTimeField(auto_now_add=True)),
('modified', models.DateTimeField(auto_now=True)),
('publish_date', models.DateTimeField(null=True, blank=True)),
('tags', taggit.managers.TaggableManager(to='taggit.Tag', through='taggit.TaggedItem', help_text='A comma-separated list of tags.', verbose_name='Tags')),
('user', models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, null=True)),
(
"id",
models.AutoField(
verbose_name="ID",
serialize=False,
auto_created=True,
primary_key=True,
),
),
(
"title",
models.CharField(
default=b"Untitled", max_length=255, null=True, blank=True
),
),
("slug", models.SlugField(max_length=255, blank=True)),
("custom_slug", models.SlugField(max_length=255, blank=True)),
("lexer", models.CharField(max_length=50)),
("code", models.TextField()),
("meta", models.TextField(null=True, blank=True)),
("description", models.TextField(null=True, blank=True)),
("stylized", models.TextField(null=True, blank=True)),
("stylized_min", models.TextField(null=True, blank=True)),
("embedded", models.TextField(null=True, blank=True)),
(
"line_count",
models.IntegerField(default=None, null=True, blank=True),
),
("key", models.CharField(max_length=100, null=True, blank=True)),
("public", models.BooleanField(default=False)),
("blog_post", models.BooleanField(default=False)),
("views", models.IntegerField(default=0)),
("created", models.DateTimeField(auto_now_add=True)),
("modified", models.DateTimeField(auto_now=True)),
("publish_date", models.DateTimeField(null=True, blank=True)),
(
"tags",
taggit.managers.TaggableManager(
to="taggit.Tag",
through="taggit.TaggedItem",
help_text="A comma-separated list of tags.",
verbose_name="Tags",
),
),
(
"user",
models.ForeignKey(
blank=True, to=settings.AUTH_USER_MODEL, null=True
),
),
],
),
migrations.AddField(
model_name='favorite',
name='snipt',
field=models.ForeignKey(to='snipts.Snipt'),
model_name="favorite",
name="snipt",
field=models.ForeignKey(to="snipts.Snipt"),
),
migrations.AddField(
model_name='favorite',
name='user',
model_name="favorite",
name="user",
field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
),
]

View File

@ -9,20 +9,28 @@ class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('snipts', '0001_initial'),
("snipts", "0001_initial"),
]
operations = [
migrations.CreateModel(
name='SniptLogEntry',
name="SniptLogEntry",
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('code', models.TextField()),
('diff', models.TextField()),
('created', models.DateTimeField(auto_now_add=True)),
('modified', models.DateTimeField(auto_now=True)),
('snipt', models.ForeignKey(to='snipts.Snipt')),
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
(
"id",
models.AutoField(
verbose_name="ID",
serialize=False,
auto_created=True,
primary_key=True,
),
),
("code", models.TextField()),
("diff", models.TextField()),
("created", models.DateTimeField(auto_now_add=True)),
("modified", models.DateTimeField(auto_now=True)),
("snipt", models.ForeignKey(to="snipts.Snipt")),
("user", models.ForeignKey(to=settings.AUTH_USER_MODEL)),
],
),
)
]

View File

@ -9,13 +9,18 @@ class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('snipts', '0002_sniptlogentry'),
("snipts", "0002_sniptlogentry"),
]
operations = [
migrations.AddField(
model_name='snipt',
name='last_user_saved',
field=models.ForeignKey(related_name='last_user_saved', blank=True, to=settings.AUTH_USER_MODEL, null=True),
),
model_name="snipt",
name="last_user_saved",
field=models.ForeignKey(
related_name="last_user_saved",
blank=True,
to=settings.AUTH_USER_MODEL,
null=True,
),
)
]

View File

@ -6,19 +6,17 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('snipts', '0003_snipt_last_user_saved'),
]
dependencies = [("snipts", "0003_snipt_last_user_saved")]
operations = [
migrations.AddField(
model_name='snipt',
name='secure',
field=models.BooleanField(default=False),
model_name="snipt", name="secure", field=models.BooleanField(default=False)
),
migrations.AlterField(
model_name='snipt',
name='title',
field=models.CharField(max_length=255, blank=True, null=True, default='Untitled'),
model_name="snipt",
name="title",
field=models.CharField(
max_length=255, blank=True, null=True, default="Untitled"
),
),
]

View File

@ -9,18 +9,26 @@ class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('snipts', '0004_auto_20160512_1058'),
("snipts", "0004_auto_20160512_1058"),
]
operations = [
migrations.CreateModel(
name='SniptSecureView',
name="SniptSecureView",
fields=[
('id', models.AutoField(serialize=False, primary_key=True, auto_created=True, verbose_name='ID')),
('created', models.DateTimeField(auto_now_add=True)),
('modified', models.DateTimeField(auto_now=True)),
('snipt', models.ForeignKey(to='snipts.Snipt')),
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
(
"id",
models.AutoField(
serialize=False,
primary_key=True,
auto_created=True,
verbose_name="ID",
),
),
("created", models.DateTimeField(auto_now_add=True)),
("modified", models.DateTimeField(auto_now=True)),
("snipt", models.ForeignKey(to="snipts.Snipt")),
("user", models.ForeignKey(to=settings.AUTH_USER_MODEL)),
],
),
)
]

View File

@ -23,14 +23,15 @@ class Snipt(models.Model):
"""An individual Snipt."""
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.DO_NOTHING)
last_user_saved = models.ForeignKey(User,
blank=True,
null=True,
related_name='last_user_saved',
on_delete=models.DO_NOTHING)
last_user_saved = models.ForeignKey(
User,
blank=True,
null=True,
related_name="last_user_saved",
on_delete=models.DO_NOTHING,
)
title = models.CharField(max_length=255, blank=True, null=True,
default='Untitled')
title = models.CharField(max_length=255, blank=True, null=True, default="Untitled")
slug = models.SlugField(max_length=255, blank=True)
custom_slug = models.SlugField(max_length=255, blank=True)
tags = TaggableManager()
@ -61,7 +62,7 @@ class Snipt(models.Model):
diff = difflib.unified_diff(expected, actual)
return ''.join(diff)
return "".join(diff)
def __init__(self, *args, **kwargs):
super(Snipt, self).__init__(*args, **kwargs)
@ -73,92 +74,101 @@ class Snipt(models.Model):
self.slug = slugify_uniquely(self.title, Snipt)
if not self.key:
self.key = hashlib.md5((self.slug +
str(datetime.datetime.now()) +
str(random.random())).encode('utf-8')).hexdigest()
self.key = hashlib.md5(
(
self.slug + str(datetime.datetime.now()) + str(random.random())
).encode("utf-8")
).hexdigest()
if self.lexer == 'markdown':
self.stylized = markdown(self.code, 'default')
if self.lexer == "markdown":
self.stylized = markdown(self.code, "default")
# Snippet embeds
for match in re.findall('\[\[(\w{32})\]\]', self.stylized):
self.stylized = self.stylized.replace('[[' + str(match) + ']]',
"""
for match in re.findall("\[\[(\w{32})\]\]", self.stylized):
self.stylized = self.stylized.replace(
"[[" + str(match) + "]]",
"""
<script type="text/javascript"
src="https://snippets.siftie.com/embed/{}/?snipt">
</script>
<div id="snipt-embed-{}"></div>""".format(match, match))
<div id="snipt-embed-{}"></div>""".format(
match, match
),
)
# YouTube embeds
for match in re.findall('\[\[youtube-(\w{11})\-(\d+)x(\d+)\]\]',
self.stylized):
self.stylized = self.stylized \
.replace('[[youtube-{}-{}x{}]]'.format(
str(match[0]),
str(match[1]),
str(match[2])),
"""<iframe width="{}" height="{}"
for match in re.findall(
"\[\[youtube-(\w{11})\-(\d+)x(\d+)\]\]", self.stylized
):
self.stylized = self.stylized.replace(
"[[youtube-{}-{}x{}]]".format(
str(match[0]), str(match[1]), str(match[2])
),
"""<iframe width="{}" height="{}"
src="https://www.youtube.com/embed/{}"
frameborder="0" allowfullscreen></iframe>"""
.format(match[1], match[2], match[0]))
frameborder="0" allowfullscreen></iframe>""".format(
match[1], match[2], match[0]
),
)
# Vimeo embeds
for match in re.findall('\[\[vimeo-(\d+)\-(\d+)x(\d+)\]\]',
self.stylized):
self.stylized = self.stylized \
.replace('[[vimeo-{}-{}x{}]]'.format(
str(match[0]),
str(match[1]),
str(match[2])),
"""<iframe src="https://player.vimeo.com/video/{}"
for match in re.findall("\[\[vimeo-(\d+)\-(\d+)x(\d+)\]\]", self.stylized):
self.stylized = self.stylized.replace(
"[[vimeo-{}-{}x{}]]".format(
str(match[0]), str(match[1]), str(match[2])
),
"""<iframe src="https://player.vimeo.com/video/{}"
width="{}" height="{}" frameborder="0"
webkitAllowFullScreen mozallowfullscreen
allowFullScreen></iframe>"""
.format(match[0], match[1], match[2]))
allowFullScreen></iframe>""".format(
match[0], match[1], match[2]
),
)
# Tweet embeds
for match in re.findall('\[\[tweet-(\d+)\]\]', self.stylized):
self.stylized = self.stylized \
.replace(
'[[tweet-{}]]'.format(str(match)),
'<div class="embedded-tweet" data-tweet-id="{}"></div>'
.format(str(match)))
for match in re.findall("\[\[tweet-(\d+)\]\]", self.stylized):
self.stylized = self.stylized.replace(
"[[tweet-{}]]".format(str(match)),
'<div class="embedded-tweet" data-tweet-id="{}"></div>'.format(
str(match)
),
)
# Parse usernames
for match in re.findall('@(\w+) ', self.stylized):
for match in re.findall("@(\w+) ", self.stylized):
# Try and get the user by username.
user = get_object_or_None(User, username=match)
if user:
url = user.profile.get_user_profile_url()
self.stylized = self.stylized \
.replace('@{} '.format(str(match)),
'<a href="{}">@{}</a> '.format(url, match))
self.stylized = self.stylized.replace(
"@{} ".format(str(match)),
'<a href="{}">@{}</a> '.format(url, match),
)
else:
self.stylized = highlight(self.code,
get_lexer_by_name(self.lexer,
encoding='UTF-8'),
HtmlFormatter(linenos='table',
anchorlinenos=True,
lineanchors='L',
linespans='L',
))
self.line_count = len(self.code.split('\n'))
self.stylized = highlight(
self.code,
get_lexer_by_name(self.lexer, encoding="UTF-8"),
HtmlFormatter(
linenos="table", anchorlinenos=True, lineanchors="L", linespans="L"
),
)
self.line_count = len(self.code.split("\n"))
if self.lexer == 'markdown':
lexer_for_embedded = 'text'
if self.lexer == "markdown":
lexer_for_embedded = "text"
else:
lexer_for_embedded = self.lexer
embedded = highlight(self.code,
get_lexer_by_name(lexer_for_embedded,
encoding='UTF-8'),
HtmlFormatter(
style='native',
noclasses=True,
prestyles="""
embedded = highlight(
self.code,
get_lexer_by_name(lexer_for_embedded, encoding="UTF-8"),
HtmlFormatter(
style="native",
noclasses=True,
prestyles="""
background-color: #1C1C1C;
border-radius: 5px;
color: #D0D0D0;
@ -169,22 +179,25 @@ class Snipt(models.Model):
padding: 15px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
"""))
embedded = (embedded.replace("\\\"", "\\\\\"")
.replace('\'', '\\\'')
.replace("\\", "\\\\")
.replace('background: #202020', ''))
""",
),
)
embedded = (
embedded.replace('\\"', '\\\\"')
.replace("'", "\\'")
.replace("\\", "\\\\")
.replace("background: #202020", "")
)
self.embedded = embedded
snipt = super(Snipt, self).save(*args, **kwargs)
diff = self._unidiff_output(self.original_code or '', self.code)
diff = self._unidiff_output(self.original_code or "", self.code)
if (diff != ''):
log_entry = SniptLogEntry(user=self.last_user_saved,
snipt=self,
code=self.code,
diff=diff)
if diff != "":
log_entry = SniptLogEntry(
user=self.last_user_saved, snipt=self, code=self.code, diff=diff
)
log_entry.save()
return snipt
@ -197,52 +210,52 @@ class Snipt(models.Model):
def get_stylized_min(self):
if self.stylized_min is None:
if self.lexer == 'markdown':
self.stylized_min = markdown(self.code[:1000], 'default')
if self.lexer == "markdown":
self.stylized_min = markdown(self.code[:1000], "default")
else:
self.stylized_min = highlight(
self.code[:1000],
get_lexer_by_name(self.lexer, encoding='UTF-8'),
HtmlFormatter(linenos='table',
linenospecial=1,
lineanchors='line'))
get_lexer_by_name(self.lexer, encoding="UTF-8"),
HtmlFormatter(linenos="table", linenospecial=1, lineanchors="line"),
)
return self.stylized_min
def get_absolute_url(self):
if self.blog_post:
if self.user.profile.blog_domain:
return u'http://{}/{}/'.format(
self.user.profile.blog_domain.split(' ')[0], self.slug)
return u"http://{}/{}/".format(
self.user.profile.blog_domain.split(" ")[0], self.slug
)
else:
return u'https://{}.snippets.siftie.com/{}/'.format(
self.user.username.replace('_', '-'), self.slug)
return u"https://{}.snippets.siftie.com/{}/".format(
self.user.username.replace("_", "-"), self.slug
)
if self.custom_slug:
return u'/{}/'.format(self.custom_slug)
return u"/{}/".format(self.custom_slug)
if self.public:
return u'/{}/{}/'.format(self.user.username, self.slug)
return u"/{}/{}/".format(self.user.username, self.slug)
else:
return u'/{}/{}/?key={}'.format(
self.user.username, self.slug, self.key)
return u"/{}/{}/?key={}".format(self.user.username, self.slug, self.key)
def get_full_absolute_url(self):
if self.blog_post:
if self.user.profile.blog_domain:
return u'http://{}/{}/'.format(
self.user.profile.blog_domain.split(' ')[0], self.slug)
return u"http://{}/{}/".format(
self.user.profile.blog_domain.split(" ")[0], self.slug
)
else:
return u'https://{}.snippets.siftie.com/{}/'.format(
self.user.username, self.slug)
return u"https://{}.snippets.siftie.com/{}/".format(
self.user.username, self.slug
)
if self.public:
return u'/{}/{}/'.format(self.user.username, self.slug)
return u"/{}/{}/".format(self.user.username, self.slug)
else:
return u'/{}/{}/?key={}'.format(self.user.username,
self.slug,
self.key)
return u"/{}/{}/?key={}".format(self.user.username, self.slug, self.key)
def get_download_url(self):
@ -252,30 +265,30 @@ class Snipt(models.Model):
lexer_obj = None
if lexer_obj and lexer_obj.filenames:
filename = lexer_obj.filenames[0].replace('*', self.slug)
filename = lexer_obj.filenames[0].replace("*", self.slug)
else:
if self.lexer == 'markdown':
filename = u'{}.md'.format(self.slug)
if self.lexer == "markdown":
filename = u"{}.md".format(self.slug)
else:
filename = u'{}.txt'.format(self.slug)
filename = u"{}.txt".format(self.slug)
return u'/download/{}/{}'.format(self.key, filename)
return u"/download/{}/{}".format(self.key, filename)
def get_embed_url(self):
if settings.DEBUG:
root = 'http://local.snippets.siftie.com'
root = "http://local.snippets.siftie.com"
else:
root = 'https://snippets.siftie.com'
root = "https://snippets.siftie.com"
return '{}/embed/{}/'.format(root, self.key)
return "{}/embed/{}/".format(root, self.key)
def get_raw_url(self):
return '/raw/{}/'.format(self.key)
return "/raw/{}/".format(self.key)
@property
def sorted_tags(self):
return self.tags.all().order_by('name')
return self.tags.all().order_by("name")
@property
def tags_list(self):
@ -283,8 +296,8 @@ class Snipt(models.Model):
@property
def lexer_name(self):
if self.lexer == 'markdown':
return 'Markdown'
if self.lexer == "markdown":
return "Markdown"
else:
return get_lexer_by_name(self.lexer).name
@ -311,7 +324,7 @@ class SniptLogEntry(models.Model):
@property
def snipt_name(self):
return self.snipt.title or 'Untitled'
return self.snipt.title or "Untitled"
class SniptSecureView(models.Model):
@ -325,7 +338,7 @@ class SniptSecureView(models.Model):
@property
def snipt_name(self):
return self.snipt.title or 'Untitled'
return self.snipt.title or "Untitled"
class Favorite(models.Model):
@ -336,5 +349,4 @@ class Favorite(models.Model):
modified = models.DateTimeField(auto_now=True, editable=False)
def __unicode__(self):
return u'{} favorited by {}'.format(self.snipt.title,
self.user.username)
return u"{} favorited by {}".format(self.snipt.title, self.user.username)

View File

@ -6,15 +6,14 @@ from snipts.models import Snipt
class SniptIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
author = indexes.CharField(model_attr='user')
pub_date = indexes.DateTimeField(model_attr='created')
public = indexes.BooleanField(model_attr='public')
typ = indexes.CharField(model_attr='lexer')
author = indexes.CharField(model_attr="user")
pub_date = indexes.DateTimeField(model_attr="created")
public = indexes.BooleanField(model_attr="public")
typ = indexes.CharField(model_attr="lexer")
def get_model(self):
return Snipt
def index_queryset(self, **kwargs):
"""Used when the entire index for model is updated."""
return self.get_model().objects.filter(
created__lte=datetime.datetime.now())
return self.get_model().objects.filter(created__lte=datetime.datetime.now())

View File

@ -10,11 +10,11 @@ from templatetag_sugar.register import tag
register = template.Library()
@tag(register, [Constant('as'), Variable()])
@tag(register, [Constant("as"), Variable()])
def snipt_is_favorited_by_user(context, asvar):
user = context['request'].user
snipt = context['snipt']
user = context["request"].user
snipt = context["snipt"]
is_favorited = False
@ -27,37 +27,37 @@ def snipt_is_favorited_by_user(context, asvar):
context[asvar] = is_favorited
return ''
return ""
@tag(register, [])
def snipts_count_for_user(context):
user = context['request'].user
user = context["request"].user
if user.is_authenticated():
snipts = Snipt.objects.filter(user=user).values('id').count()
snipts = Snipt.objects.filter(user=user).values("id").count()
else:
snipts = 0
return snipts
@tag(register, [Constant('as'), Variable()])
@tag(register, [Constant("as"), Variable()])
def signup_enabled(context, asvar):
context[asvar] = os.environ.get("DISABLE_SIGNUP") != "true"
return ''
return ""
@tag(register, [Constant('as'), Variable()])
@tag(register, [Constant("as"), Variable()])
def get_lexers(context, asvar):
context[asvar] = get_lexers_list()
return ''
return ""
@tag(register, [Constant('for'), Variable()])
@tag(register, [Constant("for"), Variable()])
def generate_line_numbers(context, line_numbers):
html = ''
html = ""
for i in range(1, line_numbers + 1):
html = html + '<span class="special">{}</span>'.format(i)
@ -67,7 +67,7 @@ def generate_line_numbers(context, line_numbers):
@register.filter
def md5(string):
return hashlib.md5(string.lower().encode('utf-8')).hexdigest()
return hashlib.md5(string.lower().encode("utf-8")).hexdigest()
@register.filter

View File

@ -5,107 +5,113 @@ from tastypie.test import ResourceTestCase
class SniptResourceTest(ResourceTestCase):
fixtures = ['test_entries.json']
fixtures = ["test_entries.json"]
def setUp(self):
super(SniptResourceTest, self).setUp()
# Johnny
self.johnny = User.objects.create_user('johnny', 'johnny@siftie.com',
'password')
self.johnny = User.objects.create_user(
"johnny", "johnny@siftie.com", "password"
)
ApiKey.objects.get_or_create(user=self.johnny)
self.johnny_auth = self.create_apikey(self.johnny,
self.johnny.api_key.key)
self.johnny_private = Snipt(title='Private snippet for Johnny',
lexer='text',
public=False,
user=self.johnny)
self.johnny_public = Snipt(title='Public snippet for Johnny',
lexer='text',
public=True,
user=self.johnny)
self.johnny_auth = self.create_apikey(self.johnny, self.johnny.api_key.key)
self.johnny_private = Snipt(
title="Private snippet for Johnny",
lexer="text",
public=False,
user=self.johnny,
)
self.johnny_public = Snipt(
title="Public snippet for Johnny",
lexer="text",
public=True,
user=self.johnny,
)
self.johnny_private.save()
self.johnny_public.save()
# Bob
self.bob = User.objects.create_user('bob', 'bob@siftie.com', 'password')
self.bob = User.objects.create_user("bob", "bob@siftie.com", "password")
ApiKey.objects.get_or_create(user=self.bob)
self.bob_auth = self.create_apikey(self.bob, self.bob.api_key.key)
self.bob_private = Snipt(title='Private snippet for Bob',
lexer='text',
public=False,
user=self.bob)
self.bob_public = Snipt(title='Public snippet for Bob',
lexer='text',
public=True,
user=self.bob)
self.bob_private = Snipt(
title="Private snippet for Bob", lexer="text", public=False, user=self.bob
)
self.bob_public = Snipt(
title="Public snippet for Bob", lexer="text", public=True, user=self.bob
)
self.bob_private.save()
self.bob_public.save()
def test_get_private_list(self):
resp = self.api_client.get('/api/private/snipt/', format='json',
authentication=self.johnny_auth)
resp = self.api_client.get(
"/api/private/snipt/", format="json", authentication=self.johnny_auth
)
self.assertHttpOK(resp)
self.assertValidJSONResponse(resp)
self.assertEqual(len(self.deserialize(resp)['objects']), 2)
self.assertEqual(len(self.deserialize(resp)["objects"]), 2)
def test_get_private_detail(self):
resp = self.api_client.get(
'/api/private/snipt/{}/'.format(self.johnny_private.pk),
format='json',
authentication=self.johnny_auth)
"/api/private/snipt/{}/".format(self.johnny_private.pk),
format="json",
authentication=self.johnny_auth,
)
self.assertHttpOK(resp)
self.assertValidJSONResponse(resp)
self.assertEqual(self.deserialize(resp)['key'],
self.johnny_private.key)
self.assertEqual(self.deserialize(resp)["key"], self.johnny_private.key)
# Unauthenticated request.
resp = self.api_client.get(
'/api/private/snipt/{}/'.format(self.johnny_private.pk),
format='json')
"/api/private/snipt/{}/".format(self.johnny_private.pk), format="json"
)
self.assertHttpUnauthorized(resp)
# Unauthorized request.
resp = self.api_client.get(
'/api/private/snipt/{}/'.format(self.johnny_private.pk),
format='json',
authentication=self.bob_auth)
"/api/private/snipt/{}/".format(self.johnny_private.pk),
format="json",
authentication=self.bob_auth,
)
self.assertHttpUnauthorized(resp)
def test_post_private_list(self):
new_snipt = {
'title': 'A new private snippet.',
'lexer': 'text',
'public': False,
"title": "A new private snippet.",
"lexer": "text",
"public": False,
}
resp = self.api_client.post('/api/private/snipt/',
data=new_snipt,
format='json',
authentication=self.johnny_auth)
resp = self.api_client.post(
"/api/private/snipt/",
data=new_snipt,
format="json",
authentication=self.johnny_auth,
)
self.assertHttpCreated(resp)
self.assertEqual(Snipt.objects.count(), 5)
resp = self.api_client.get('/api/private/snipt/',
format='json',
authentication=self.johnny_auth)
self.assertEqual(len(self.deserialize(resp)['objects']), 3)
resp = self.api_client.get(
"/api/private/snipt/", format="json", authentication=self.johnny_auth
)
self.assertEqual(len(self.deserialize(resp)["objects"]), 3)
resp = self.api_client.get('/api/public/snipt/', format='json')
self.assertEqual(len(self.deserialize(resp)['objects']), 2)
resp = self.api_client.get("/api/public/snipt/", format="json")
self.assertEqual(len(self.deserialize(resp)["objects"]), 2)
def test_get_public_list(self):
self.assertEqual(Snipt.objects.count(), 4)
resp = self.api_client.get('/api/public/snipt/', format='json')
resp = self.api_client.get("/api/public/snipt/", format="json")
self.assertHttpOK(resp)
self.assertValidJSONResponse(resp)
self.assertEqual(len(self.deserialize(resp)['objects']), 2)
self.assertEqual(len(self.deserialize(resp)["objects"]), 2)

View File

@ -3,45 +3,36 @@ from snipts import views
urlpatterns = [
url(r'^s/(?P<snipt_key>[^/]+)/(?P<lexer>[^\?]+)?$',
views.redirect_snipt, name='redirect-snipt'),
url(r'^(?P<username>[^/]+)/feed/$',
views.redirect_user_feed,
name='redirect-feed'),
url(r'^public/tag/(?P<tag_slug>[^/]+)/feed/$',
url(
r"^s/(?P<snipt_key>[^/]+)/(?P<lexer>[^\?]+)?$",
views.redirect_snipt,
name="redirect-snipt",
),
url(r"^(?P<username>[^/]+)/feed/$", views.redirect_user_feed, name="redirect-feed"),
url(
r"^public/tag/(?P<tag_slug>[^/]+)/feed/$",
views.redirect_public_tag_feed,
name='redirect-public-tag-feed'),
url(r'^(?P<username>[^/]+)/tag/(?P<tag_slug>[^/]+)/feed/$',
name="redirect-public-tag-feed",
),
url(
r"^(?P<username>[^/]+)/tag/(?P<tag_slug>[^/]+)/feed/$",
views.redirect_user_tag_feed,
name='redirect-user-tag-feed'),
url(r'^public/$',
views.list_public,
name='list-public'),
url(r'^public/tag/(?P<tag_slug>[^/]+)/$',
views.list_public,
name='list-public-tag'),
url(r'^download/(?P<snipt_key>[^/]+).*$',
views.download,
name='download'),
url(r'^embed/(?P<snipt_key>[^/]+)/$',
views.embed,
name='embed'),
url(r'^raw/(?P<snipt_key>[^/]+)/(?P<lexer>[^\?]+)?$',
views.raw,
name='raw'),
url(r'^(?P<username_or_custom_slug>[^/]+)/$',
name="redirect-user-tag-feed",
),
url(r"^public/$", views.list_public, name="list-public"),
url(
r"^public/tag/(?P<tag_slug>[^/]+)/$", views.list_public, name="list-public-tag"
),
url(r"^download/(?P<snipt_key>[^/]+).*$", views.download, name="download"),
url(r"^embed/(?P<snipt_key>[^/]+)/$", views.embed, name="embed"),
url(r"^raw/(?P<snipt_key>[^/]+)/(?P<lexer>[^\?]+)?$", views.raw, name="raw"),
url(r"^(?P<username_or_custom_slug>[^/]+)/$", views.list_user, name="list-user"),
url(
r"^(?P<username_or_custom_slug>[^/]+)/tag/(?P<tag_slug>[^/]+)/$",
views.list_user,
name='list-user'),
url(r'^(?P<username_or_custom_slug>[^/]+)/tag/(?P<tag_slug>[^/]+)/$',
views.list_user,
name='list-user-tag'),
url(r'^(?P<username>[^/]+)/favorites/$',
views.favorites,
name='favorites'),
url(r'^(?P<username>[^/]+)/blog-posts/$',
views.blog_posts,
name='blog-posts'),
url(r'^(?P<username>[^/]+)/(?P<snipt_slug>[^/]+)/$',
views.detail,
name='detail')
]
name="list-user-tag",
),
url(r"^(?P<username>[^/]+)/favorites/$", views.favorites, name="favorites"),
url(r"^(?P<username>[^/]+)/blog-posts/$", views.blog_posts, name="blog-posts"),
url(r"^(?P<username>[^/]+)/(?P<snipt_slug>[^/]+)/$", views.detail, name="detail"),
]

View File

@ -18,12 +18,13 @@ def slugify_uniquely(value, model, slugfield="slug"):
potential = str(suffix)
if not model.objects.filter(**{slugfield: potential}).count():
return potential
suffix = str(uuid.uuid4()).split('-')[0]
suffix = str(uuid.uuid4()).split("-")[0]
def activate_user(user, request, **kwargs):
user = authenticate(username=request.POST['username'],
password=request.POST['password1'])
user = authenticate(
username=request.POST["username"], password=request.POST["password1"]
)
login(request, user)
@ -31,12 +32,13 @@ def get_lexers_list():
lexers = list(get_all_lexers())
for l in lexers:
if l[0] == 'ANTLR With Java Target':
if l[0] == "ANTLR With Java Target":
lexers.remove(l)
lexers.append(('Markdown', ('markdown',),))
lexers.append(("Markdown", ("markdown",)))
lexers = sorted(lexers)
return lexers
user_registered.connect(activate_user)

View File

@ -7,7 +7,12 @@ from django.core.mail import send_mail
from django.core.paginator import Paginator, InvalidPage
from django.db.models import Count
from django.db.models import Q
from django.http import Http404, HttpResponse, HttpResponseRedirect, HttpResponseBadRequest
from django.http import (
Http404,
HttpResponse,
HttpResponseRedirect,
HttpResponseBadRequest,
)
from django.shortcuts import get_object_or_404, render
from django.template import RequestContext
from django.views.decorators.cache import never_cache
@ -21,25 +26,25 @@ from teams.models import Team
import os
RESULTS_PER_PAGE = getattr(settings, 'HAYSTACK_SEARCH_RESULTS_PER_PAGE', 20)
RESULTS_PER_PAGE = getattr(settings, "HAYSTACK_SEARCH_RESULTS_PER_PAGE", 20)
@render_to('snipts/detail.html')
@render_to("snipts/detail.html")
def detail(request, username, snipt_slug):
snipt = get_object_or_404(Snipt, user__username=username, slug=snipt_slug)
user = snipt.user
if snipt.lexer != 'markdown':
if 'linenos' not in snipt.stylized:
if snipt.lexer != "markdown":
if "linenos" not in snipt.stylized:
snipt.save()
if user != request.user:
if not snipt.public:
if 'key' not in request.GET:
if "key" not in request.GET:
raise Http404
else:
if request.GET.get('key') != snipt.key:
if request.GET.get("key") != snipt.key:
raise Http404
if snipt.secure and not request.user.is_authenticated():
@ -61,35 +66,37 @@ def detail(request, username, snipt_slug):
tags = tags.filter(snipt__user=user, snipt__public=True)
public = True
tags = tags.annotate(count=Count('taggit_taggeditem_items__id'))
tags = tags.order_by('-count', 'name')
tags = tags.annotate(count=Count("taggit_taggeditem_items__id"))
tags = tags.order_by("-count", "name")
return {
'detail': True,
'has_snipts': True,
'public': public,
'snipt': snipt,
'tags': tags,
'user': user,
"detail": True,
"has_snipts": True,
"public": public,
"snipt": snipt,
"tags": tags,
"user": user,
}
def download(request, snipt_key):
snipt = get_object_or_404(Snipt, key=snipt_key)
return HttpResponse(snipt.code, content_type='application/x-download')
return HttpResponse(snipt.code, content_type="application/x-download")
def embed(request, snipt_key):
snipt = get_object_or_404(Snipt, key=snipt_key)
lines = snipt.embedded.split('\n')
return render(request,
'snipts/embed.html',
{'lines': lines, 'snipt': snipt},
content_type='application/javascript')
lines = snipt.embedded.split("\n")
return render(
request,
"snipts/embed.html",
{"lines": lines, "snipt": snipt},
content_type="application/javascript",
)
@render_to('snipts/list-user.html')
@render_to("snipts/list-user.html")
def blog_posts(request, username):
if request.blog_user:
@ -106,29 +113,28 @@ def blog_posts(request, username):
public_user = True
user = get_object_or_404(User, username=username)
snipts = Snipt.objects.filter(blog_post=True, user=user, public=True)
tags = Tag.objects.filter(snipt__user=user,
snipt__public=True).distinct()
tags = Tag.objects.filter(snipt__user=user, snipt__public=True).distinct()
tags = tags.order_by('name')
snipts = snipts.order_by('-created')
tags = tags.order_by("name")
snipts = snipts.order_by("-created")
context = {
'has_snipts': True,
'public': public,
'public_user': public_user,
'snipts': snipts,
'tags': tags,
'user': user,
"has_snipts": True,
"public": public,
"public_user": public_user,
"snipts": snipts,
"tags": tags,
"user": user,
}
if 'rss' in request.GET:
context['snipts'] = context['snipts'][:20]
if "rss" in request.GET:
context["snipts"] = context["snipts"][:20]
return rss(request, context)
return context
@render_to('snipts/list-user.html')
@render_to("snipts/list-user.html")
def favorites(request, username):
if request.user.username != username:
@ -139,39 +145,39 @@ def favorites(request, username):
public = False
favorites = Favorite.objects.filter(user=request.user).values('snipt')
favorites = [f['snipt'] for f in favorites]
favorites = Favorite.objects.filter(user=request.user).values("snipt")
favorites = [f["snipt"] for f in favorites]
snipts = Snipt.objects.filter(Q(pk__in=favorites))
tags = Tag.objects.filter(snipt__user=request.user).distinct()
tags = tags.order_by('name')
snipts = snipts.order_by('-created')
tags = tags.order_by("name")
snipts = snipts.order_by("-created")
context = {
'favorites': favorites,
'has_snipts': True,
'public': public,
'public_user': False,
'snipts': snipts,
'tags': tags,
'user': request.user,
"favorites": favorites,
"has_snipts": True,
"public": public,
"public_user": False,
"snipts": snipts,
"tags": tags,
"user": request.user,
}
if 'rss' in request.GET:
context['snipts'] = context['snipts'][:20]
if "rss" in request.GET:
context["snipts"] = context["snipts"][:20]
return rss(request, context)
return context
@render_to('snipts/list-public.html')
@render_to("snipts/list-public.html")
def list_public(request, tag_slug=None):
if request.blog_user:
return blog_list(request)
snipts = Snipt.objects.filter(public=True).order_by('-created')
snipts = Snipt.objects.filter(public=True).order_by("-created")
if tag_slug:
snipts = snipts.filter(tags__slug__in=[tag_slug])
@ -179,21 +185,16 @@ def list_public(request, tag_slug=None):
else:
tag = None
context = {
'has_snipts': True,
'public': True,
'snipts': snipts,
'tag': tag,
}
context = {"has_snipts": True, "public": True, "snipts": snipts, "tag": tag}
if 'rss' in request.GET:
context['snipts'] = context['snipts'][:20]
if "rss" in request.GET:
context["snipts"] = context["snipts"][:20]
return rss(request, context)
return context
@render_to('snipts/list-user.html')
@render_to("snipts/list-user.html")
def list_user(request, username_or_custom_slug, tag_slug=None):
if request.blog_user:
@ -208,15 +209,16 @@ def list_user(request, username_or_custom_slug, tag_slug=None):
tags = Tag.objects
snipts = Snipt.objects
if user == request.user or \
(request.GET.get('api_key') == user.api_key.key) or \
(user.profile.is_a_team and
user.team.user_is_member(request.user)):
if (
user == request.user
or (request.GET.get("api_key") == user.api_key.key)
or (user.profile.is_a_team and user.team.user_is_member(request.user))
):
public = False
favorites = Favorite.objects.filter(user=user).values('snipt')
favorites = [f['snipt'] for f in favorites]
favorites = Favorite.objects.filter(user=user).values("snipt")
favorites = [f["snipt"] for f in favorites]
snipts = snipts.filter(Q(user=user) | Q(pk__in=favorites))
tags = tags.filter(snipt__user=user).distinct()
@ -226,8 +228,8 @@ def list_user(request, username_or_custom_slug, tag_slug=None):
snipts = snipts.filter(user=user, public=True)
public = True
tags = tags.order_by('name')
snipts = snipts.order_by('-created')
tags = tags.order_by("name")
snipts = snipts.order_by("-created")
if tag_slug:
snipts = snipts.filter(tags__slug__in=[tag_slug])
@ -236,21 +238,21 @@ def list_user(request, username_or_custom_slug, tag_slug=None):
tag = None
if tag is None:
snipts = snipts.exclude(tags__name__in=['tmp'])
snipts = snipts.exclude(tags__name__in=["tmp"])
context = {
'has_snipts': True,
'public': public,
'public_user': (public and user),
'snipts': snipts,
'tags': tags,
'tag': tag,
'user': user,
'users_for_full_page': ['robertbanh'],
"has_snipts": True,
"public": public,
"public_user": (public and user),
"snipts": snipts,
"tags": tags,
"tag": tag,
"user": user,
"users_for_full_page": ["robertbanh"],
}
if 'rss' in request.GET:
context['snipts'] = context['snipts'][:20]
if "rss" in request.GET:
context["snipts"] = context["snipts"][:20]
return rss(request, context)
return context
@ -261,7 +263,7 @@ def raw(request, snipt_key, lexer=None):
if request.user == snipt.user:
if lexer:
lexer = lexer.strip('/')
lexer = lexer.strip("/")
if lexer != snipt.lexer:
@ -274,67 +276,73 @@ def raw(request, snipt_key, lexer=None):
snipt.lexer = lexer
snipt.save()
content_type = 'text/plain'
content_type = "text/plain"
if 'nice' in request.GET:
content_type = 'text/html'
if "nice" in request.GET:
content_type = "text/html"
return render(request,
'snipts/raw.html',
{'snipt': snipt},
content_type=content_type)
return render(
request, "snipts/raw.html", {"snipt": snipt}, content_type=content_type
)
def rss(request, context):
return render(request,
'rss.xml',
context,
content_type="application/rss+xml")
return render(request, "rss.xml", context, content_type="application/rss+xml")
@never_cache
def search(request, template='search/search.html', load_all=True,
form_class=ModelSearchForm, searchqueryset=None,
context_class=RequestContext, extra_context=None,
results_per_page=None):
def search(
request,
template="search/search.html",
load_all=True,
form_class=ModelSearchForm,
searchqueryset=None,
context_class=RequestContext,
extra_context=None,
results_per_page=None,
):
query = ''
query = ""
results = EmptySearchQuerySet()
if request.GET.get('q'):
if request.GET.get("q"):
searchqueryset = SearchQuerySet() \
.filter(Q(public=True) | Q(author=request.user)) \
.order_by('-pub_date')
searchqueryset = (
SearchQuerySet()
.filter(Q(public=True) | Q(author=request.user))
.order_by("-pub_date")
)
if request.user.is_authenticated() and \
'mine-only' in request.GET:
searchqueryset = SearchQuerySet().filter(author=request.user) \
.order_by('-pub_date')
if request.user.is_authenticated() and "mine-only" in request.GET:
searchqueryset = (
SearchQuerySet().filter(author=request.user).order_by("-pub_date")
)
elif request.user.is_authenticated() and \
('author' in request.GET and
request.GET.get('author')):
elif request.user.is_authenticated() and (
"author" in request.GET and request.GET.get("author")
):
author = request.GET.get('author')
author = request.GET.get("author")
if author == request.user.username:
searchqueryset = SearchQuerySet().filter(author=request.user) \
.order_by('-pub_date')
searchqueryset = (
SearchQuerySet().filter(author=request.user).order_by("-pub_date")
)
else:
team = get_object_or_None(Team, slug=author)
if team and team.user_is_member(request.user):
searchqueryset = SearchQuerySet().filter(author=team) \
.order_by('-pub_date')
searchqueryset = (
SearchQuerySet().filter(author=team).order_by("-pub_date")
)
form = ModelSearchForm(request.GET,
searchqueryset=searchqueryset,
load_all=load_all)
form = ModelSearchForm(
request.GET, searchqueryset=searchqueryset, load_all=load_all
)
if form.is_valid():
query = form.cleaned_data['q']
query = form.cleaned_data["q"]
results = form.search()
else:
form = form_class(searchqueryset=searchqueryset, load_all=load_all)
@ -342,21 +350,21 @@ def search(request, template='search/search.html', load_all=True,
paginator = Paginator(results, results_per_page or RESULTS_PER_PAGE)
try:
page = paginator.page(int(request.GET.get('page', 1)))
page = paginator.page(int(request.GET.get("page", 1)))
except InvalidPage:
raise Http404("No such page of results!")
context = {
'form': form,
'has_snipts': True,
'page': page,
'paginator': paginator,
'query': query,
'suggestion': None,
"form": form,
"has_snipts": True,
"page": page,
"paginator": paginator,
"query": query,
"suggestion": None,
}
if results.query.backend.include_spelling:
context['suggestion'] = form.get_suggestion()
context["suggestion"] = form.get_suggestion()
if extra_context:
context.update(extra_context)
@ -370,13 +378,13 @@ def redirect_snipt(request, snipt_key, lexer=None):
def redirect_public_tag_feed(request, tag_slug):
return HttpResponseRedirect('/public/tag/{}/?rss'.format(tag_slug))
return HttpResponseRedirect("/public/tag/{}/?rss".format(tag_slug))
def redirect_user_feed(request, username):
user = get_object_or_404(User, username=username)
return HttpResponseRedirect(user.get_absolute_url() + '?rss')
return HttpResponseRedirect(user.get_absolute_url() + "?rss")
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))

View File

@ -3,7 +3,8 @@ from teams.models import Team
class TeamAdmin(admin.ModelAdmin):
list_display = ('name', 'owner', 'created', 'modified')
ordering = ('-created',)
list_display = ("name", "owner", "created", "modified")
ordering = ("-created",)
admin.site.register(Team, TeamAdmin)

View File

@ -7,22 +7,38 @@ from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
dependencies = [migrations.swappable_dependency(settings.AUTH_USER_MODEL)]
operations = [
migrations.CreateModel(
name='Team',
name="Team",
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('name', models.CharField(max_length=255)),
('slug', models.SlugField(max_length=255, blank=True)),
('created', models.DateTimeField(auto_now_add=True)),
('modified', models.DateTimeField(auto_now=True)),
('members', models.ManyToManyField(related_name='member', to=settings.AUTH_USER_MODEL)),
('owner', models.ForeignKey(related_name='owner', to=settings.AUTH_USER_MODEL)),
('user', models.OneToOneField(to=settings.AUTH_USER_MODEL)),
(
"id",
models.AutoField(
verbose_name="ID",
serialize=False,
auto_created=True,
primary_key=True,
),
),
("name", models.CharField(max_length=255)),
("slug", models.SlugField(max_length=255, blank=True)),
("created", models.DateTimeField(auto_now_add=True)),
("modified", models.DateTimeField(auto_now=True)),
(
"members",
models.ManyToManyField(
related_name="member", to=settings.AUTH_USER_MODEL
),
),
(
"owner",
models.ForeignKey(
related_name="owner", to=settings.AUTH_USER_MODEL
),
),
("user", models.OneToOneField(to=settings.AUTH_USER_MODEL)),
],
),
)
]

View File

@ -6,15 +6,13 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('teams', '0001_initial'),
]
dependencies = [("teams", "0001_initial")]
operations = [
migrations.AddField(
model_name='team',
name='email',
field=models.EmailField(default='nick@siftie.com', max_length=255),
model_name="team",
name="email",
field=models.EmailField(default="nick@siftie.com", max_length=255),
preserve_default=False,
),
)
]

View File

@ -7,14 +7,14 @@ from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
('teams', '0002_team_email'),
]
dependencies = [("teams", "0002_team_email")]
operations = [
migrations.AlterField(
model_name='team',
name='user',
field=models.OneToOneField(null=True, blank=True, to=settings.AUTH_USER_MODEL),
),
model_name="team",
name="user",
field=models.OneToOneField(
null=True, blank=True, to=settings.AUTH_USER_MODEL
),
)
]

View File

@ -7,14 +7,14 @@ from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
('teams', '0003_auto_20150818_0057'),
]
dependencies = [("teams", "0003_auto_20150818_0057")]
operations = [
migrations.AlterField(
model_name='team',
name='members',
field=models.ManyToManyField(related_name='member', to=settings.AUTH_USER_MODEL, blank=True),
),
model_name="team",
name="members",
field=models.ManyToManyField(
related_name="member", to=settings.AUTH_USER_MODEL, blank=True
),
)
]

View File

@ -6,19 +6,15 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('teams', '0004_auto_20150930_1526'),
]
dependencies = [("teams", "0004_auto_20150930_1526")]
operations = [
migrations.AddField(
model_name='team',
name='stripe_id',
model_name="team",
name="stripe_id",
field=models.CharField(max_length=100, null=True, blank=True),
),
migrations.AlterField(
model_name='team',
name='name',
field=models.CharField(max_length=30),
model_name="team", name="name", field=models.CharField(max_length=30)
),
]

View File

@ -6,14 +6,25 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('teams', '0005_auto_20150930_2124'),
]
dependencies = [("teams", "0005_auto_20150930_2124")]
operations = [
migrations.AddField(
model_name='team',
name='plan',
field=models.CharField(default=b'snipt-teams-25-monthly', max_length=100, choices=[(b'snipt-teams-25-monthly', b'25 users, monthly'), (b'snipt-teams-100-monthly', b'100 users, monthly'), (b'snipt-teams-250-monthly', b'250 users, monthly'), (b'snipt-teams-unlimited-monthly', b'Unlimited users, monthly'), (b'snipt-teams-25-yearly', b'25 users, yearly'), (b'snipt-teams-100-yearly', b'100 users, yearly'), (b'snipt-teams-250-yearly', b'250 users, yearly'), (b'snipt-teams-unlimited-yearly', b'Unlimited users, yearly')]),
),
model_name="team",
name="plan",
field=models.CharField(
default=b"snipt-teams-25-monthly",
max_length=100,
choices=[
(b"snipt-teams-25-monthly", b"25 users, monthly"),
(b"snipt-teams-100-monthly", b"100 users, monthly"),
(b"snipt-teams-250-monthly", b"250 users, monthly"),
(b"snipt-teams-unlimited-monthly", b"Unlimited users, monthly"),
(b"snipt-teams-25-yearly", b"25 users, yearly"),
(b"snipt-teams-100-yearly", b"100 users, yearly"),
(b"snipt-teams-250-yearly", b"250 users, yearly"),
(b"snipt-teams-unlimited-yearly", b"Unlimited users, yearly"),
],
),
)
]

View File

@ -6,14 +6,10 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('teams', '0006_team_plan'),
]
dependencies = [("teams", "0006_team_plan")]
operations = [
migrations.AddField(
model_name='team',
name='disabled',
field=models.BooleanField(default=False),
),
model_name="team", name="disabled", field=models.BooleanField(default=False)
)
]

View File

@ -6,14 +6,27 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('teams', '0007_team_disabled'),
]
dependencies = [("teams", "0007_team_disabled")]
operations = [
migrations.AlterField(
model_name='team',
name='plan',
field=models.CharField(default=b'snipt-teams-25-monthly', max_length=100, null=True, blank=True, choices=[(b'snipt-teams-25-monthly', b'25 users, monthly'), (b'snipt-teams-100-monthly', b'100 users, monthly'), (b'snipt-teams-250-monthly', b'250 users, monthly'), (b'snipt-teams-unlimited-monthly', b'Unlimited users, monthly'), (b'snipt-teams-25-yearly', b'25 users, yearly'), (b'snipt-teams-100-yearly', b'100 users, yearly'), (b'snipt-teams-250-yearly', b'250 users, yearly'), (b'snipt-teams-unlimited-yearly', b'Unlimited users, yearly')]),
),
model_name="team",
name="plan",
field=models.CharField(
default=b"snipt-teams-25-monthly",
max_length=100,
null=True,
blank=True,
choices=[
(b"snipt-teams-25-monthly", b"25 users, monthly"),
(b"snipt-teams-100-monthly", b"100 users, monthly"),
(b"snipt-teams-250-monthly", b"250 users, monthly"),
(b"snipt-teams-unlimited-monthly", b"Unlimited users, monthly"),
(b"snipt-teams-25-yearly", b"25 users, yearly"),
(b"snipt-teams-100-yearly", b"100 users, yearly"),
(b"snipt-teams-250-yearly", b"250 users, yearly"),
(b"snipt-teams-unlimited-yearly", b"Unlimited users, yearly"),
],
),
)
]

View File

@ -6,14 +6,27 @@ from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('teams', '0008_auto_20151018_2053'),
]
dependencies = [("teams", "0008_auto_20151018_2053")]
operations = [
migrations.AlterField(
model_name='team',
name='plan',
field=models.CharField(max_length=100, choices=[('snipt-teams-25-monthly', '25 users, monthly'), ('snipt-teams-100-monthly', '100 users, monthly'), ('snipt-teams-250-monthly', '250 users, monthly'), ('snipt-teams-unlimited-monthly', 'Unlimited users, monthly'), ('snipt-teams-25-yearly', '25 users, yearly'), ('snipt-teams-100-yearly', '100 users, yearly'), ('snipt-teams-250-yearly', '250 users, yearly'), ('snipt-teams-unlimited-yearly', 'Unlimited users, yearly')], blank=True, null=True, default='snipt-teams-25-monthly'),
),
model_name="team",
name="plan",
field=models.CharField(
max_length=100,
choices=[
("snipt-teams-25-monthly", "25 users, monthly"),
("snipt-teams-100-monthly", "100 users, monthly"),
("snipt-teams-250-monthly", "250 users, monthly"),
("snipt-teams-unlimited-monthly", "Unlimited users, monthly"),
("snipt-teams-25-yearly", "25 users, yearly"),
("snipt-teams-100-yearly", "100 users, yearly"),
("snipt-teams-250-yearly", "250 users, yearly"),
("snipt-teams-unlimited-yearly", "Unlimited users, yearly"),
],
blank=True,
null=True,
default="snipt-teams-25-monthly",
),
)
]

View File

@ -6,25 +6,32 @@ from snipts.utils import slugify_uniquely
class Team(models.Model):
PLANS = (
('snipt-teams-25-monthly', '25 users, monthly'),
('snipt-teams-100-monthly', '100 users, monthly'),
('snipt-teams-250-monthly', '250 users, monthly'),
('snipt-teams-unlimited-monthly', 'Unlimited users, monthly'),
('snipt-teams-25-yearly', '25 users, yearly'),
('snipt-teams-100-yearly', '100 users, yearly'),
('snipt-teams-250-yearly', '250 users, yearly'),
('snipt-teams-unlimited-yearly', 'Unlimited users, yearly'),
("snipt-teams-25-monthly", "25 users, monthly"),
("snipt-teams-100-monthly", "100 users, monthly"),
("snipt-teams-250-monthly", "250 users, monthly"),
("snipt-teams-unlimited-monthly", "Unlimited users, monthly"),
("snipt-teams-25-yearly", "25 users, yearly"),
("snipt-teams-100-yearly", "100 users, yearly"),
("snipt-teams-250-yearly", "250 users, yearly"),
("snipt-teams-unlimited-yearly", "Unlimited users, yearly"),
)
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)
owner = models.ForeignKey(User, related_name='owner', on_delete=models.DO_NOTHING)
owner = models.ForeignKey(User, related_name="owner", on_delete=models.DO_NOTHING)
slug = models.SlugField(max_length=255, blank=True)
stripe_id = models.CharField(max_length=100, null=True, blank=True)
user = models.OneToOneField(User, blank=True, null=True, on_delete=models.DO_NOTHING)
plan = models.CharField(max_length=100, default='snipt-teams-25-monthly',
choices=PLANS, blank=True, null=True)
user = models.OneToOneField(
User, blank=True, null=True, on_delete=models.DO_NOTHING
)
plan = models.CharField(
max_length=100,
default="snipt-teams-25-monthly",
choices=PLANS,
blank=True,
null=True,
)
disabled = models.BooleanField(default=False)
created = models.DateTimeField(auto_now_add=True, editable=False)
@ -32,7 +39,7 @@ class Team(models.Model):
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify_uniquely(self.name, User, 'username')
self.slug = slugify_uniquely(self.name, User, "username")
return super(Team, self).save(*args, **kwargs)
def __unicode__(self):
@ -49,18 +56,18 @@ class Team(models.Model):
return 0
plan_map = {
'snipt-teams-25-monthly': 25,
'snipt-teams-100-monthly': 100,
'snipt-teams-250-monthly': 250,
'snipt-teams-unlimited-monthly': float('inf'),
'snipt-teams-25-yearly': 25,
'snipt-teams-100-yearly': 100,
'snipt-teams-250-yearly': 250,
'snipt-teams-unlimited-yearly': float('inf')
"snipt-teams-25-monthly": 25,
"snipt-teams-100-monthly": 100,
"snipt-teams-250-monthly": 250,
"snipt-teams-unlimited-monthly": float("inf"),
"snipt-teams-25-yearly": 25,
"snipt-teams-100-yearly": 100,
"snipt-teams-250-yearly": 250,
"snipt-teams-unlimited-yearly": float("inf"),
}
if plan_map[self.plan] == float('inf'):
return 'Unlimited'
if plan_map[self.plan] == float("inf"):
return "Unlimited"
else:
return plan_map[self.plan]

View File

@ -3,15 +3,17 @@ from teams import views
urlpatterns = [
url(r'^for-teams/$', views.for_teams),
url(r'^for-teams/complete/$', views.for_teams_complete),
url(r'^(?P<username>[^/]+)/members/remove/(?P<member>[^/]+)/$',
views.remove_team_member,
name='remove-team-member'),
url(r'^(?P<username>[^/]+)/members/add/(?P<member>[^/]+)/$',
views.add_team_member,
name='add-team-member'),
url(r'^(?P<username>[^/]+)/members/$',
views.team_members,
name='team-members')
]
url(r"^for-teams/$", views.for_teams),
url(r"^for-teams/complete/$", views.for_teams_complete),
url(
r"^(?P<username>[^/]+)/members/remove/(?P<member>[^/]+)/$",
views.remove_team_member,
name="remove-team-member",
),
url(
r"^(?P<username>[^/]+)/members/add/(?P<member>[^/]+)/$",
views.add_team_member,
name="add-team-member",
),
url(r"^(?P<username>[^/]+)/members/$", views.team_members, name="team-members"),
]

View File

@ -8,7 +8,7 @@ from django.shortcuts import get_object_or_404
from teams.models import Team
@render_to('teams/for-teams.html')
@render_to("teams/for-teams.html")
def for_teams(request):
if request.user.is_authenticated():
profile = request.user.profile
@ -18,38 +18,34 @@ def for_teams(request):
@login_required
@render_to('teams/for-teams-complete.html')
@render_to("teams/for-teams-complete.html")
def for_teams_complete(request):
if request.method == 'POST' and request.user.is_authenticated():
if request.method == "POST" and request.user.is_authenticated():
team = Team(name=request.POST['team-name'],
email=request.POST['email'],
owner=request.user)
team = Team(
name=request.POST["team-name"],
email=request.POST["email"],
owner=request.user,
)
team.save()
user = User.objects.create_user(team.slug,
team.email,
str(uuid.uuid4()))
user = User.objects.create_user(team.slug, team.email, str(uuid.uuid4()))
team.user = user
team.save()
return {
'team': team
}
return {"team": team}
else:
return HttpResponseBadRequest()
@login_required
@render_to('teams/team-members.html')
@render_to("teams/team-members.html")
def team_members(request, username):
team = get_object_or_404(Team, slug=username, disabled=False)
if not team.user_is_member(request.user):
raise Http404
return {
'team': team
}
return {"team": team}
@login_required
@ -57,15 +53,14 @@ def add_team_member(request, username, member):
team = get_object_or_404(Team, slug=username, disabled=False)
user = get_object_or_404(User, username=member)
if (team.owner != request.user):
if team.owner != request.user:
raise Http404
if ((team.members.all().count() + 1) > team.member_limit):
return HttpResponseRedirect('/' + team.slug +
'/members/?limit-reached')
if (team.members.all().count() + 1) > team.member_limit:
return HttpResponseRedirect("/" + team.slug + "/members/?limit-reached")
else:
team.members.add(user)
return HttpResponseRedirect('/' + team.slug + '/members/')
return HttpResponseRedirect("/" + team.slug + "/members/")
@login_required
@ -73,9 +68,9 @@ def remove_team_member(request, username, member):
team = get_object_or_404(Team, slug=username, disabled=False)
user = get_object_or_404(User, username=member)
if (team.owner != request.user):
if team.owner != request.user:
raise Http404
team.members.remove(user)
return HttpResponseRedirect('/' + team.slug + '/members/')
return HttpResponseRedirect("/" + team.slug + "/members/")

78
urls.py
View File

@ -6,21 +6,25 @@ from django.contrib.auth.views import login
from django.http import HttpResponseRedirect
from django.views.generic import TemplateView
from django.views.static import serve
from snipts.api import (PublicSniptResource,
PublicUserResource, PrivateSniptResource,
PrivateFavoriteResource, PrivateUserProfileResource,
PrivateUserResource, PublicTagResource)
from snipts.api import (
PublicSniptResource,
PublicUserResource,
PrivateSniptResource,
PrivateFavoriteResource,
PrivateUserProfileResource,
PrivateUserResource,
PublicTagResource,
)
from snipts.views import search
from tastypie.api import Api
from views import (homepage, lexers, login_redirect,
tags, user_api_key)
from views import homepage, lexers, login_redirect, tags, user_api_key
public_api = Api(api_name='public')
public_api = Api(api_name="public")
public_api.register(PublicSniptResource())
public_api.register(PublicTagResource())
public_api.register(PublicUserResource())
private_api = Api(api_name='private')
private_api = Api(api_name="private")
private_api.register(PrivateSniptResource())
private_api.register(PrivateUserResource())
private_api.register(PrivateFavoriteResource())
@ -30,37 +34,39 @@ urlpatterns = []
if os.environ.get("DISABLE_SIGNUP") == "true":
urlpatterns += [
url(r'^register/?$', lambda x: HttpResponseRedirect('/404/')),
url(r'^signup/?$', lambda x: HttpResponseRedirect('/404/')),
url(r"^register/?$", lambda x: HttpResponseRedirect("/404/")),
url(r"^signup/?$", lambda x: HttpResponseRedirect("/404/")),
]
else:
urlpatterns += [
url(r'^signup/?$', lambda x: HttpResponseRedirect('/register/')),
]
urlpatterns += [url(r"^signup/?$", lambda x: HttpResponseRedirect("/register/"))]
urlpatterns += [
url(r'^$', homepage),
url(r'', include('registration.backends.simple.urls')),
url(r'^login/?$', login, name='login'),
url(r'^login-redirect/$', login_redirect),
url(r'^admin/', include(admin.site.urls)),
url(r'^404/$', TemplateView.as_view(template_name='404.html')),
url(r'^500/$', TemplateView.as_view(template_name='500.html')),
url(r'^robots.txt$', TemplateView.as_view(template_name='robots.txt')),
url(r'^tags/$', tags),
url(r'^account/', include('accounts.urls')),
url(r'^api/public/lexer/$', lexers),
url(r'^api/private/key/$', user_api_key),
url(r'^api/', include(public_api.urls)),
url(r'^api/', include(private_api.urls)),
url(r'^search/$', search),
url(r'^', include('teams.urls')),
url(r'^', include('snipts.urls')),
url(r'^(?P<path>favicon\.ico)$', serve, {
'document_root': os.path.join(os.path.dirname(__file__), 'static/img')
}),
url(r'^static/(?P<path>.*)$', serve, {
'document_root': os.path.join(os.path.dirname(__file__), 'media')
})
url(r"^$", homepage),
url(r"", include("registration.backends.simple.urls")),
url(r"^login/?$", login, name="login"),
url(r"^login-redirect/$", login_redirect),
url(r"^admin/", include(admin.site.urls)),
url(r"^404/$", TemplateView.as_view(template_name="404.html")),
url(r"^500/$", TemplateView.as_view(template_name="500.html")),
url(r"^robots.txt$", TemplateView.as_view(template_name="robots.txt")),
url(r"^tags/$", tags),
url(r"^account/", include("accounts.urls")),
url(r"^api/public/lexer/$", lexers),
url(r"^api/private/key/$", user_api_key),
url(r"^api/", include(public_api.urls)),
url(r"^api/", include(private_api.urls)),
url(r"^search/$", search),
url(r"^", include("teams.urls")),
url(r"^", include("snipts.urls")),
url(
r"^(?P<path>favicon\.ico)$",
serve,
{"document_root": os.path.join(os.path.dirname(__file__), "static/img")},
),
url(
r"^static/(?P<path>.*)$",
serve,
{"document_root": os.path.join(os.path.dirname(__file__), "media")},
),
]

View File

@ -4,11 +4,20 @@ from django.contrib.auth.models import User
class UserAdmin(UserAdmin):
list_display = ['username', 'email', 'first_name', 'last_name',
'last_login', 'date_joined', 'is_active', 'is_staff',
'api_key']
list_filter = ['is_staff', 'is_superuser', 'is_active']
ordering = ['-date_joined']
list_display = [
"username",
"email",
"first_name",
"last_name",
"last_login",
"date_joined",
"is_active",
"is_staff",
"api_key",
]
list_filter = ["is_staff", "is_superuser", "is_active"]
ordering = ["-date_joined"]
admin.site.unregister(User)
admin.site.register(User, UserAdmin)

View File

@ -3,10 +3,10 @@ from django.contrib.auth.models import User
class EmailOrUsernameModelBackend(object):
def authenticate(self, username=None, password=None):
if '@' in username:
kwargs = {'email': username}
if "@" in username:
kwargs = {"email": username}
else:
kwargs = {'username': username}
kwargs = {"username": username}
try:
user = User.objects.get(**kwargs)
if user.check_password(password):

View File

@ -9,34 +9,36 @@ class SniptRegistrationForm(RegistrationForm):
Subclass of ``RegistrationForm`` which enforces uniqueness of
email addresses and further restricts usernames.
"""
def clean_username(self):
"""
Validate that the username is alphanumeric and is not already
in use.
"""
existing = User.objects.filter(
username__iexact=self.cleaned_data['username'])
existing = User.objects.filter(username__iexact=self.cleaned_data["username"])
if existing.exists():
raise forms.ValidationError(
_("A user with that username already exists."))
raise forms.ValidationError(_("A user with that username already exists."))
elif '@' in self.cleaned_data['username']:
elif "@" in self.cleaned_data["username"]:
raise forms.ValidationError(_("Cannot have '@' in username."))
elif '.' in self.cleaned_data['username']:
elif "." in self.cleaned_data["username"]:
raise forms.ValidationError(_("Cannot have '.' in username."))
elif '+' in self.cleaned_data['username']:
elif "+" in self.cleaned_data["username"]:
raise forms.ValidationError(_("Cannot have '+' in username."))
else:
return self.cleaned_data['username']
return self.cleaned_data["username"]
def clean_email(self):
"""
Validate that the supplied email address is unique for the
site.
"""
if User.objects.filter(email__iexact=self.cleaned_data['email']):
if User.objects.filter(email__iexact=self.cleaned_data["email"]):
raise forms.ValidationError(
_("""This email address is already in use. Please supply a
different email address."""))
return self.cleaned_data['email']
_(
"""This email address is already in use. Please supply a
different email address."""
)
)
return self.cleaned_data["email"]

View File

@ -8,11 +8,10 @@ register = template.Library()
@register.filter
def pygmentize(text):
return highlight(text,
get_lexer_by_name('diff',
encoding='UTF-8'),
HtmlFormatter(linenos='table',
anchorlinenos=True,
lineanchors='L',
linespans='L',
))
return highlight(
text,
get_lexer_by_name("diff", encoding="UTF-8"),
HtmlFormatter(
linenos="table", anchorlinenos=True, lineanchors="L", linespans="L"
),
)

View File

@ -5,4 +5,4 @@ register = template.Library()
@register.filter
def truncate_lines(text):
return '\n'.join(text.split('\n')[:300])
return "\n".join(text.split("\n")[:300])

View File

@ -17,7 +17,6 @@ register = template.Library()
class VerbatimNode(template.Node):
def __init__(self, text):
self.text = text
@ -30,15 +29,15 @@ def verbatim(parser, token):
text = []
while 1:
token = parser.tokens.pop(0)
if token.contents == 'endverbatim':
if token.contents == "endverbatim":
break
if token.token_type == template.TOKEN_VAR:
text.append('{{')
text.append("{{")
elif token.token_type == template.TOKEN_BLOCK:
text.append('{%')
text.append("{%")
text.append(token.contents)
if token.token_type == template.TOKEN_VAR:
text.append('}}')
text.append("}}")
elif token.token_type == template.TOKEN_BLOCK:
text.append('%}')
return VerbatimNode(''.join(text))
text.append("%}")
return VerbatimNode("".join(text))

View File

@ -6,10 +6,11 @@ class SniptRegistrationView(RegistrationView):
"""
Custom registration view that uses our custom form.
"""
form_class = SniptRegistrationForm
def dispatch(self, request, *args, **kwargs):
return super(RegistrationView, self).dispatch(request, *args, **kwargs)
def get_success_url(self, request):
return '/login-redirect'
return "/login-redirect"

View File

@ -6,7 +6,7 @@ from snipts.utils import get_lexers_list
from taggit.models import Tag
@render_to('homepage.html')
@render_to("homepage.html")
def homepage(request):
if request.blog_user:
@ -32,39 +32,32 @@ def lexers(request):
except IndexError:
mimetypes = []
objects.append({
'name': l[0],
'lexers': l[1],
'filters': filters,
'mimetypes': mimetypes
})
objects.append(
{"name": l[0], "lexers": l[1], "filters": filters, "mimetypes": mimetypes}
)
return {'objects': objects}
return {"objects": objects}
def login_redirect(request):
if request.user.is_authenticated():
return HttpResponseRedirect('/' + request.user.username + '/')
return HttpResponseRedirect("/" + request.user.username + "/")
else:
return HttpResponseRedirect('/')
return HttpResponseRedirect("/")
@render_to('tags.html')
@render_to("tags.html")
def tags(request):
all_tags = Tag.objects.filter(snipt__public=True).order_by('name')
all_tags = all_tags.annotate(count=Count('taggit_taggeditem_items__id'))
all_tags = Tag.objects.filter(snipt__public=True).order_by("name")
all_tags = all_tags.annotate(count=Count("taggit_taggeditem_items__id"))
popular_tags = Tag.objects.filter(snipt__public=True)
popular_tags = popular_tags.annotate(
count=Count('taggit_taggeditem_items__id'))
popular_tags = popular_tags.order_by('-count')[:20]
popular_tags = popular_tags.annotate(count=Count("taggit_taggeditem_items__id"))
popular_tags = popular_tags.order_by("-count")[:20]
popular_tags = sorted(popular_tags, key=lambda tag: tag.name)
return {
'all_tags': all_tags,
'tags': popular_tags
}
return {"all_tags": all_tags, "tags": popular_tags}
@ajax_request
@ -73,6 +66,4 @@ def user_api_key(request):
if not request.user.is_authenticated():
return HttpResponseBadRequest()
return {
'api_key': request.user.api_key.key
}
return {"api_key": request.user.api_key.key}