Black.
parent
6af387be82
commit
39403a600c
|
@ -3,9 +3,9 @@ from django.contrib import admin
|
||||||
|
|
||||||
|
|
||||||
class UserProfileAdmin(admin.ModelAdmin):
|
class UserProfileAdmin(admin.ModelAdmin):
|
||||||
list_display = ('user', 'is_pro', 'stripe_id', 'gittip_username',
|
list_display = ("user", "is_pro", "stripe_id", "gittip_username", "teams_beta_seen")
|
||||||
'teams_beta_seen')
|
list_filter = ["teams_beta_seen", "teams_beta_applied"]
|
||||||
list_filter = ['teams_beta_seen', 'teams_beta_applied']
|
search_fields = ("user__username", "gittip_username")
|
||||||
search_fields = ('user__username', 'gittip_username',)
|
|
||||||
|
|
||||||
admin.site.register(UserProfile, UserProfileAdmin)
|
admin.site.register(UserProfile, UserProfileAdmin)
|
||||||
|
|
|
@ -14,9 +14,9 @@ class Command(BaseCommand):
|
||||||
self.stdout.write(u"Updating %s user passwords..." % users.count())
|
self.stdout.write(u"Updating %s user passwords..." % users.count())
|
||||||
|
|
||||||
for user in users:
|
for user in users:
|
||||||
if user.password[0:3] == 'bc$':
|
if user.password[0:3] == "bc$":
|
||||||
pw = user.password
|
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.password = new_password
|
||||||
user.save()
|
user.save()
|
||||||
|
|
||||||
|
|
|
@ -7,36 +7,115 @@ from django.conf import settings
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [migrations.swappable_dependency(settings.AUTH_USER_MODEL)]
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='UserProfile',
|
name="UserProfile",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
(
|
||||||
('is_pro', models.BooleanField(default=False)),
|
"id",
|
||||||
('teams_beta_seen', models.BooleanField(default=False)),
|
models.AutoField(
|
||||||
('teams_beta_applied', models.BooleanField(default=False)),
|
verbose_name="ID",
|
||||||
('pro_date', models.DateTimeField(null=True, blank=True)),
|
serialize=False,
|
||||||
('stripe_id', models.CharField(max_length=100, null=True, blank=True)),
|
auto_created=True,
|
||||||
('has_gravatar', models.BooleanField(default=False)),
|
primary_key=True,
|
||||||
('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')])),
|
("is_pro", models.BooleanField(default=False)),
|
||||||
('blog_domain', models.CharField(max_length=250, null=True, blank=True)),
|
("teams_beta_seen", models.BooleanField(default=False)),
|
||||||
('default_editor', models.CharField(default=b'C', max_length=250, choices=[(b'C', b'CodeMirror'), (b'T', b'Textarea')])),
|
("teams_beta_applied", models.BooleanField(default=False)),
|
||||||
('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')])),
|
("pro_date", models.DateTimeField(null=True, blank=True)),
|
||||||
('gittip_username', models.CharField(max_length=250, null=True, blank=True)),
|
("stripe_id", models.CharField(max_length=100, null=True, blank=True)),
|
||||||
('disqus_shortname', models.CharField(max_length=250, null=True, blank=True)),
|
("has_gravatar", models.BooleanField(default=False)),
|
||||||
('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)),
|
"list_view",
|
||||||
('google_ad_client', models.CharField(max_length=250, null=True, blank=True)),
|
models.CharField(
|
||||||
('google_ad_slot', models.CharField(max_length=250, null=True, blank=True)),
|
default=b"N",
|
||||||
('google_ad_width', models.CharField(max_length=250, null=True, blank=True)),
|
max_length=1,
|
||||||
('google_ad_height', models.CharField(max_length=250, null=True, blank=True)),
|
choices=[(b"N", b"Normal"), (b"C", b"Compact")],
|
||||||
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, unique=True)),
|
),
|
||||||
|
),
|
||||||
|
("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)),
|
||||||
],
|
],
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,12 @@ from django.conf import settings
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("accounts", "0001_initial")]
|
||||||
('accounts', '0001_initial'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='userprofile',
|
model_name="userprofile",
|
||||||
name='user',
|
name="user",
|
||||||
field=models.OneToOneField(to=settings.AUTH_USER_MODEL),
|
field=models.OneToOneField(to=settings.AUTH_USER_MODEL),
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,29 +6,59 @@ from django.db import models, migrations
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("accounts", "0002_auto_20150724_2010")]
|
||||||
('accounts', '0002_auto_20150724_2010'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='userprofile',
|
model_name="userprofile",
|
||||||
name='blog_theme',
|
name="blog_theme",
|
||||||
field=models.CharField(max_length=1, choices=[('D', 'Default'), ('A', 'Pro Adams')], default='A'),
|
field=models.CharField(
|
||||||
|
max_length=1,
|
||||||
|
choices=[("D", "Default"), ("A", "Pro Adams")],
|
||||||
|
default="A",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='userprofile',
|
model_name="userprofile",
|
||||||
name='default_editor',
|
name="default_editor",
|
||||||
field=models.CharField(max_length=250, choices=[('C', 'CodeMirror'), ('T', 'Textarea')], default='C'),
|
field=models.CharField(
|
||||||
|
max_length=250,
|
||||||
|
choices=[("C", "CodeMirror"), ("T", "Textarea")],
|
||||||
|
default="C",
|
||||||
|
),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='userprofile',
|
model_name="userprofile",
|
||||||
name='editor_theme',
|
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'),
|
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(
|
migrations.AlterField(
|
||||||
model_name='userprofile',
|
model_name="userprofile",
|
||||||
name='list_view',
|
name="list_view",
|
||||||
field=models.CharField(max_length=1, choices=[('N', 'Normal'), ('C', 'Compact')], default='N'),
|
field=models.CharField(
|
||||||
|
max_length=1, choices=[("N", "Normal"), ("C", "Compact")], default="N"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -9,39 +9,30 @@ from teams.models import Team
|
||||||
|
|
||||||
class UserProfile(models.Model):
|
class UserProfile(models.Model):
|
||||||
|
|
||||||
LIST_VIEW_CHOICES = (
|
LIST_VIEW_CHOICES = (("N", "Normal"), ("C", "Compact"))
|
||||||
('N', 'Normal'),
|
|
||||||
('C', 'Compact'),
|
|
||||||
)
|
|
||||||
|
|
||||||
EDITOR_CHOICES = (
|
EDITOR_CHOICES = (("C", "CodeMirror"), ("T", "Textarea"))
|
||||||
('C', 'CodeMirror'),
|
|
||||||
('T', 'Textarea'),
|
|
||||||
)
|
|
||||||
|
|
||||||
THEME_CHOICES = (
|
THEME_CHOICES = (("D", "Default"), ("A", "Pro Adams"))
|
||||||
('D', 'Default'),
|
|
||||||
('A', 'Pro Adams'),
|
|
||||||
)
|
|
||||||
|
|
||||||
EDITOR_THEME_CHOICES = (
|
EDITOR_THEME_CHOICES = (
|
||||||
('default', 'Default'),
|
("default", "Default"),
|
||||||
('ambiance', 'Ambiance'),
|
("ambiance", "Ambiance"),
|
||||||
('blackboard', 'Blackboard'),
|
("blackboard", "Blackboard"),
|
||||||
('cobalt', 'Cobalt'),
|
("cobalt", "Cobalt"),
|
||||||
('eclipse', 'Eclipse'),
|
("eclipse", "Eclipse"),
|
||||||
('elegant', 'Elegant'),
|
("elegant", "Elegant"),
|
||||||
('erlang-dark', 'Erlang Dark'),
|
("erlang-dark", "Erlang Dark"),
|
||||||
('lesser-dark', 'Lesser Dark'),
|
("lesser-dark", "Lesser Dark"),
|
||||||
('monokai', 'Monokai'),
|
("monokai", "Monokai"),
|
||||||
('neat', 'Neat'),
|
("neat", "Neat"),
|
||||||
('night', 'Night'),
|
("night", "Night"),
|
||||||
('rubyblue', 'Ruby Blue'),
|
("rubyblue", "Ruby Blue"),
|
||||||
('solarized dark', 'Solarized Dark'),
|
("solarized dark", "Solarized Dark"),
|
||||||
('solarized light', 'Solarized Light'),
|
("solarized light", "Solarized Light"),
|
||||||
('twilight', 'Twilight'),
|
("twilight", "Twilight"),
|
||||||
('vibrant-ink', 'Vibrant Ink'),
|
("vibrant-ink", "Vibrant Ink"),
|
||||||
('xq-dark', 'XQ Dark'),
|
("xq-dark", "XQ Dark"),
|
||||||
)
|
)
|
||||||
|
|
||||||
# User
|
# User
|
||||||
|
@ -52,27 +43,35 @@ class UserProfile(models.Model):
|
||||||
pro_date = models.DateTimeField(blank=True, null=True)
|
pro_date = models.DateTimeField(blank=True, null=True)
|
||||||
stripe_id = models.CharField(max_length=100, null=True, blank=True)
|
stripe_id = models.CharField(max_length=100, null=True, blank=True)
|
||||||
has_gravatar = models.BooleanField(default=False)
|
has_gravatar = models.BooleanField(default=False)
|
||||||
list_view = models.CharField(max_length=1, null=False, blank=False,
|
list_view = models.CharField(
|
||||||
default='N', choices=LIST_VIEW_CHOICES)
|
max_length=1, null=False, blank=False, default="N", choices=LIST_VIEW_CHOICES
|
||||||
|
)
|
||||||
|
|
||||||
# Blog
|
# Blog
|
||||||
blog_title = models.CharField(max_length=250, null=True, blank=True)
|
blog_title = models.CharField(max_length=250, null=True, blank=True)
|
||||||
blog_theme = models.CharField(max_length=1, null=False, blank=False,
|
blog_theme = models.CharField(
|
||||||
default='A', choices=THEME_CHOICES)
|
max_length=1, null=False, blank=False, default="A", choices=THEME_CHOICES
|
||||||
|
)
|
||||||
blog_domain = models.CharField(max_length=250, null=True, blank=True)
|
blog_domain = models.CharField(max_length=250, null=True, blank=True)
|
||||||
|
|
||||||
# Editor
|
# Editor
|
||||||
default_editor = models.CharField(max_length=250, null=False, blank=False,
|
default_editor = models.CharField(
|
||||||
default='C', choices=EDITOR_CHOICES)
|
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',
|
editor_theme = models.CharField(
|
||||||
choices=EDITOR_THEME_CHOICES)
|
max_length=250,
|
||||||
|
null=False,
|
||||||
|
blank=False,
|
||||||
|
default="default",
|
||||||
|
choices=EDITOR_THEME_CHOICES,
|
||||||
|
)
|
||||||
|
|
||||||
# Services and Analytics
|
# Services and Analytics
|
||||||
gittip_username = models.CharField(max_length=250, null=True, blank=True)
|
gittip_username = models.CharField(max_length=250, null=True, blank=True)
|
||||||
disqus_shortname = 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,
|
google_analytics_tracking_id = models.CharField(
|
||||||
blank=True)
|
max_length=250, null=True, blank=True
|
||||||
|
)
|
||||||
gauges_site_id = models.CharField(max_length=250, null=True, blank=True)
|
gauges_site_id = models.CharField(max_length=250, null=True, blank=True)
|
||||||
|
|
||||||
# Google Ads
|
# Google Ads
|
||||||
|
@ -82,36 +81,34 @@ class UserProfile(models.Model):
|
||||||
google_ad_height = models.CharField(max_length=250, null=True, blank=True)
|
google_ad_height = models.CharField(max_length=250, null=True, blank=True)
|
||||||
|
|
||||||
def get_blog_posts(self):
|
def get_blog_posts(self):
|
||||||
return Snipt.objects.filter(user=self.user, blog_post=True,
|
return Snipt.objects.filter(user=self.user, blog_post=True, public=True)
|
||||||
public=True)
|
|
||||||
|
|
||||||
def get_primary_blog_domain(self):
|
def get_primary_blog_domain(self):
|
||||||
if not self.blog_domain:
|
if not self.blog_domain:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return self.blog_domain.split(' ')[0]
|
return self.blog_domain.split(" ")[0]
|
||||||
|
|
||||||
def get_user_profile_url(self):
|
def get_user_profile_url(self):
|
||||||
|
|
||||||
# If the user has a blog domain, use that.
|
# If the user has a blog domain, use that.
|
||||||
if self.blog_domain:
|
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.
|
# Otherwise, if they have blog posts, use their Snipt blog URL.
|
||||||
elif self.get_blog_posts():
|
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.
|
# Otherwise, use their regular Snipt profile page.
|
||||||
else:
|
else:
|
||||||
url = 'https://snippets.siftie.com/{}/'.format(self.user.username)
|
url = "https://snippets.siftie.com/{}/".format(self.user.username)
|
||||||
|
|
||||||
return url
|
return url
|
||||||
|
|
||||||
def has_public_snipts(self):
|
def has_public_snipts(self):
|
||||||
return True \
|
return (
|
||||||
if Snipt.objects.filter(user=self,
|
True if Snipt.objects.filter(user=self, public=True).count() > 0 else False
|
||||||
public=True).count() > 0 \
|
)
|
||||||
else False
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_a_team(self):
|
def is_a_team(self):
|
||||||
|
@ -127,14 +124,16 @@ class UserProfile(models.Model):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def has_teams(self):
|
def has_teams(self):
|
||||||
if (len(self.teams()) > 0):
|
if len(self.teams()) > 0:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_account_age(self):
|
def get_account_age(self):
|
||||||
delta = datetime.now().replace(tzinfo=None) - \
|
delta = datetime.now().replace(tzinfo=None) - self.user.date_joined.replace(
|
||||||
self.user.date_joined.replace(tzinfo=None)
|
tzinfo=None
|
||||||
|
)
|
||||||
return delta.days
|
return delta.days
|
||||||
|
|
||||||
|
|
||||||
User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])
|
User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])
|
||||||
|
|
|
@ -3,6 +3,6 @@ from django.conf.urls import url
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^stats/$', views.stats, name='account-stats'),
|
url(r"^stats/$", views.stats, name="account-stats"),
|
||||||
url(r'^', views.account, name='account-detail')
|
url(r"^", views.account, name="account-detail"),
|
||||||
]
|
]
|
||||||
|
|
|
@ -5,17 +5,15 @@ from snipts.models import Snipt
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@render_to('account.html')
|
@render_to("account.html")
|
||||||
def account(request):
|
def account(request):
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@render_to('stats.html')
|
@render_to("stats.html")
|
||||||
def stats(request):
|
def stats(request):
|
||||||
|
|
||||||
snipts = Snipt.objects.filter(user=request.user).order_by('-views')
|
snipts = Snipt.objects.filter(user=request.user).order_by("-views")
|
||||||
|
|
||||||
return {
|
return {"snipts": snipts}
|
||||||
'snipts': snipts
|
|
||||||
}
|
|
||||||
|
|
|
@ -8,43 +8,43 @@ class BlogMiddleware:
|
||||||
def process_request(self, request):
|
def process_request(self, request):
|
||||||
request.blog_user = None
|
request.blog_user = None
|
||||||
|
|
||||||
host = request.META.get('HTTP_HOST', '')
|
host = request.META.get("HTTP_HOST", "")
|
||||||
host_s = host.replace('www.', '').split('.')
|
host_s = host.replace("www.", "").split(".")
|
||||||
|
|
||||||
if host != 'snippets.siftie.com' and \
|
if (
|
||||||
host != 'snipt.localhost' and \
|
host != "snippets.siftie.com"
|
||||||
host != 'local.snippets.siftie.com':
|
and host != "snipt.localhost"
|
||||||
|
and host != "local.snippets.siftie.com"
|
||||||
|
):
|
||||||
if len(host_s) > 2:
|
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:
|
if "-" in blog_user:
|
||||||
request.blog_user = \
|
request.blog_user = get_object_or_None(
|
||||||
get_object_or_None(User,
|
User, username__iexact=blog_user
|
||||||
username__iexact=blog_user)
|
)
|
||||||
|
|
||||||
if request.blog_user is None:
|
if request.blog_user is None:
|
||||||
request.blog_user = \
|
request.blog_user = get_object_or_404(
|
||||||
get_object_or_404(User,
|
User, username__iexact=blog_user.replace("-", "_")
|
||||||
username__iexact=blog_user
|
)
|
||||||
.replace('-', '_'))
|
|
||||||
else:
|
else:
|
||||||
request.blog_user = \
|
request.blog_user = get_object_or_404(
|
||||||
get_object_or_404(User, username__iexact=blog_user)
|
User, username__iexact=blog_user
|
||||||
|
)
|
||||||
|
|
||||||
if request.blog_user is None:
|
if request.blog_user is None:
|
||||||
pro_users = User.objects.filter(userprofile__is_pro=True)
|
pro_users = User.objects.filter(userprofile__is_pro=True)
|
||||||
|
|
||||||
for pro_user in pro_users:
|
for pro_user in pro_users:
|
||||||
if pro_user.profile.blog_domain:
|
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
|
request.blog_user = pro_user
|
||||||
|
|
||||||
if host != \
|
if host != pro_user.profile.get_primary_blog_domain():
|
||||||
pro_user.profile.get_primary_blog_domain():
|
|
||||||
return HttpResponseRedirect(
|
return HttpResponseRedirect(
|
||||||
'http://' +
|
"http://"
|
||||||
pro_user
|
+ pro_user.profile.get_primary_blog_domain()
|
||||||
.profile
|
)
|
||||||
.get_primary_blog_domain())
|
|
||||||
|
|
|
@ -2,4 +2,4 @@ from blogs import views
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [url(r'^$', views.blog, name='blog')]
|
urlpatterns = [url(r"^$", views.blog, name="blog")]
|
||||||
|
|
163
blogs/views.py
163
blogs/views.py
|
@ -4,10 +4,7 @@ from annoying.functions import get_object_or_None
|
||||||
from django.shortcuts import get_object_or_404, render
|
from django.shortcuts import get_object_or_404, render
|
||||||
from snipts.models import Snipt
|
from snipts.models import Snipt
|
||||||
|
|
||||||
THEME_CHOICES = {
|
THEME_CHOICES = {"D": "blogs/themes/default/", "A": "blogs/themes/pro-adams/"}
|
||||||
'D': 'blogs/themes/default/',
|
|
||||||
'A': 'blogs/themes/pro-adams/',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def blog_list(request, username_or_custom_slug=None):
|
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:
|
if username_or_custom_slug:
|
||||||
return blog_post(request, username_or_custom_slug)
|
return blog_post(request, username_or_custom_slug)
|
||||||
|
|
||||||
snipts = Snipt.objects.filter(user=request.blog_user,
|
snipts = (
|
||||||
blog_post=True,
|
Snipt.objects.filter(
|
||||||
public=True,
|
user=request.blog_user,
|
||||||
publish_date__lte=datetime.datetime.now()) \
|
blog_post=True,
|
||||||
.order_by('-publish_date') \
|
public=True,
|
||||||
.exclude(title__iexact='Homepage') \
|
publish_date__lte=datetime.datetime.now(),
|
||||||
.exclude(title__iexact='Work')
|
)
|
||||||
|
.order_by("-publish_date")
|
||||||
|
.exclude(title__iexact="Homepage")
|
||||||
|
.exclude(title__iexact="Work")
|
||||||
|
)
|
||||||
|
|
||||||
normal_snipts = Snipt.objects.filter(blog_post=False,
|
normal_snipts = Snipt.objects.filter(
|
||||||
user=request.blog_user,
|
blog_post=False, user=request.blog_user, public=True
|
||||||
public=True) \
|
).order_by("-created")
|
||||||
.order_by('-created')
|
normal_snipts = normal_snipts.exclude(title__in=[""])
|
||||||
normal_snipts = normal_snipts.exclude(title__in=[''])
|
normal_snipts = normal_snipts.exclude(tags__name__in=["tmp"])
|
||||||
normal_snipts = normal_snipts.exclude(tags__name__in=['tmp'])
|
|
||||||
normal_snipts = normal_snipts[:3]
|
normal_snipts = normal_snipts[:3]
|
||||||
|
|
||||||
sidebar = get_object_or_None(Snipt, user=request.blog_user,
|
sidebar = get_object_or_None(
|
||||||
title='Sidebar', blog_post=True)
|
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)
|
header = get_object_or_None(
|
||||||
custom_css = get_object_or_None(Snipt, user=request.blog_user, title='CSS',
|
Snipt, user=request.blog_user, title="Header", blog_post=True
|
||||||
lexer='css', blog_post=True)
|
)
|
||||||
|
custom_css = get_object_or_None(
|
||||||
|
Snipt, user=request.blog_user, title="CSS", lexer="css", blog_post=True
|
||||||
|
)
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'blog_user': request.blog_user,
|
"blog_user": request.blog_user,
|
||||||
'custom_css': custom_css,
|
"custom_css": custom_css,
|
||||||
'has_snipts': True,
|
"has_snipts": True,
|
||||||
'header': header,
|
"header": header,
|
||||||
'normal_snipts': normal_snipts,
|
"normal_snipts": normal_snipts,
|
||||||
'public': True,
|
"public": True,
|
||||||
'sidebar': sidebar,
|
"sidebar": sidebar,
|
||||||
'snipts': snipts,
|
"snipts": snipts,
|
||||||
}
|
}
|
||||||
|
|
||||||
if 'rss' in request.GET:
|
if "rss" in request.GET:
|
||||||
context['snipts'] = context['snipts'][:20]
|
context["snipts"] = context["snipts"][:20]
|
||||||
return rss(request, context)
|
return rss(request, context)
|
||||||
|
|
||||||
template = THEME_CHOICES[request.blog_user.profile.blog_theme]
|
template = THEME_CHOICES[request.blog_user.profile.blog_theme]
|
||||||
|
|
||||||
template = '{}/list.html'.format(template)
|
template = "{}/list.html".format(template)
|
||||||
|
|
||||||
return render(
|
return render(request, template, context)
|
||||||
request,
|
|
||||||
template,
|
|
||||||
context,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def blog_post(request, username_or_custom_slug):
|
def blog_post(request, username_or_custom_slug):
|
||||||
|
|
||||||
snipt = get_object_or_404(Snipt, user=request.blog_user,
|
snipt = get_object_or_404(
|
||||||
blog_post=True,
|
Snipt,
|
||||||
public=True,
|
user=request.blog_user,
|
||||||
publish_date__lte=datetime.datetime.now(),
|
blog_post=True,
|
||||||
slug=username_or_custom_slug)
|
public=True,
|
||||||
|
publish_date__lte=datetime.datetime.now(),
|
||||||
|
slug=username_or_custom_slug,
|
||||||
|
)
|
||||||
|
|
||||||
snipts = Snipt.objects.filter(user=request.blog_user,
|
snipts = (
|
||||||
blog_post=True,
|
Snipt.objects.filter(
|
||||||
public=True,
|
user=request.blog_user,
|
||||||
publish_date__lte=datetime.datetime.now()) \
|
blog_post=True,
|
||||||
.order_by('-publish_date') \
|
public=True,
|
||||||
.exclude(title__iexact='Homepage') \
|
publish_date__lte=datetime.datetime.now(),
|
||||||
.exclude(title__iexact='Work')
|
)
|
||||||
|
.order_by("-publish_date")
|
||||||
|
.exclude(title__iexact="Homepage")
|
||||||
|
.exclude(title__iexact="Work")
|
||||||
|
)
|
||||||
|
|
||||||
sidebar = get_object_or_None(Snipt, user=request.blog_user,
|
sidebar = get_object_or_None(
|
||||||
title='Sidebar', blog_post=True)
|
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)
|
header = get_object_or_None(
|
||||||
custom_css = get_object_or_None(Snipt, user=request.blog_user, title='CSS',
|
Snipt, user=request.blog_user, title="Header", blog_post=True
|
||||||
lexer='css', 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,
|
normal_snipts = Snipt.objects.filter(
|
||||||
user=request.blog_user,
|
blog_post=False, user=request.blog_user, public=True
|
||||||
public=True).order_by('-created')
|
).order_by("-created")
|
||||||
normal_snipts = normal_snipts.exclude(title__in=[''])
|
normal_snipts = normal_snipts.exclude(title__in=[""])
|
||||||
normal_snipts = normal_snipts.exclude(tags__name__in=['tmp'])
|
normal_snipts = normal_snipts.exclude(tags__name__in=["tmp"])
|
||||||
normal_snipts = normal_snipts[:3]
|
normal_snipts = normal_snipts[:3]
|
||||||
|
|
||||||
if snipt.user != request.user:
|
if snipt.user != request.user:
|
||||||
|
@ -99,25 +108,29 @@ def blog_post(request, username_or_custom_slug):
|
||||||
snipt.save()
|
snipt.save()
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'blog_user': request.blog_user,
|
"blog_user": request.blog_user,
|
||||||
'custom_css': custom_css,
|
"custom_css": custom_css,
|
||||||
'detail': True,
|
"detail": True,
|
||||||
'has_snipts': True,
|
"has_snipts": True,
|
||||||
'header': header,
|
"header": header,
|
||||||
'normal_snipts': normal_snipts,
|
"normal_snipts": normal_snipts,
|
||||||
'public': True,
|
"public": True,
|
||||||
'sidebar': sidebar,
|
"sidebar": sidebar,
|
||||||
'snipt': snipt,
|
"snipt": snipt,
|
||||||
'snipts': snipts,
|
"snipts": snipts,
|
||||||
}
|
}
|
||||||
|
|
||||||
template = THEME_CHOICES[request.blog_user.profile.blog_theme]
|
template = THEME_CHOICES[request.blog_user.profile.blog_theme]
|
||||||
|
|
||||||
template = '{}/post.html'.format(template)
|
template = "{}/post.html".format(template)
|
||||||
|
|
||||||
return render(request, template, context)
|
return render(request, template, context)
|
||||||
|
|
||||||
|
|
||||||
def rss(request, context):
|
def rss(request, context):
|
||||||
return render(request, 'blogs/themes/default/rss.xml', context,
|
return render(
|
||||||
content_type="application/rss+xml")
|
request,
|
||||||
|
"blogs/themes/default/rss.xml",
|
||||||
|
context,
|
||||||
|
content_type="application/rss+xml",
|
||||||
|
)
|
||||||
|
|
194
settings.py
194
settings.py
|
@ -3,134 +3,132 @@ from urllib.parse import urlparse
|
||||||
import dj_database_url
|
import dj_database_url
|
||||||
import os
|
import os
|
||||||
|
|
||||||
if 'DATABASE_URL' in os.environ:
|
if "DATABASE_URL" in os.environ:
|
||||||
DATABASES = {'default': dj_database_url.config()}
|
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
|
ACCOUNT_ACTIVATION_DAYS = 0
|
||||||
ADMINS = (('Siftie', 'team@siftie.com'),)
|
ADMINS = (("Siftie", "team@siftie.com"),)
|
||||||
ALLOWED_HOSTS = ['*']
|
ALLOWED_HOSTS = ["*"]
|
||||||
AUTH_PROFILE_MODULE = 'accounts.UserProfile'
|
AUTH_PROFILE_MODULE = "accounts.UserProfile"
|
||||||
AUTHENTICATION_BACKENDS = ('utils.backends.EmailOrUsernameModelBackend',)
|
AUTHENTICATION_BACKENDS = ("utils.backends.EmailOrUsernameModelBackend",)
|
||||||
BASE_PATH = os.path.dirname(__file__)
|
BASE_PATH = os.path.dirname(__file__)
|
||||||
CSRF_COOKIE_SECURE = True if 'USE_SSL' in os.environ else False
|
CSRF_COOKIE_SECURE = True if "USE_SSL" in os.environ else False
|
||||||
CORS_ORIGIN_ALLOW_ALL = True
|
CORS_ORIGIN_ALLOW_ALL = True
|
||||||
DEBUG = True if 'DEBUG' in os.environ else False
|
DEBUG = True if "DEBUG" in os.environ else False
|
||||||
DEFAULT_FROM_EMAIL = os.environ.get('POSTMARK_EMAIL', 'support@siftie.com')
|
DEFAULT_FROM_EMAIL = os.environ.get("POSTMARK_EMAIL", "support@siftie.com")
|
||||||
EMAIL_BACKEND = 'postmark.django_backend.EmailBackend'
|
EMAIL_BACKEND = "postmark.django_backend.EmailBackend"
|
||||||
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
|
HAYSTACK_SIGNAL_PROCESSOR = "haystack.signals.RealtimeSignalProcessor"
|
||||||
INTERNAL_IPS = ('127.0.0.1',)
|
INTERNAL_IPS = ("127.0.0.1",)
|
||||||
LANGUAGE_CODE = 'en-us'
|
LANGUAGE_CODE = "en-us"
|
||||||
LOGIN_REDIRECT_URL = '/login-redirect/'
|
LOGIN_REDIRECT_URL = "/login-redirect/"
|
||||||
LOGIN_URL = '/login/'
|
LOGIN_URL = "/login/"
|
||||||
LOGOUT_URL = '/logout/'
|
LOGOUT_URL = "/logout/"
|
||||||
MANAGERS = ADMINS
|
MANAGERS = ADMINS
|
||||||
MEDIA_ROOT = os.path.join(BASE_PATH, 'media/uploads')
|
MEDIA_ROOT = os.path.join(BASE_PATH, "media/uploads")
|
||||||
MEDIA_URL = '/media/uploads/'
|
MEDIA_URL = "/media/uploads/"
|
||||||
MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'
|
MESSAGE_STORAGE = "django.contrib.messages.storage.cookie.CookieStorage"
|
||||||
PASSWORD_HASHERS = (
|
PASSWORD_HASHERS = (
|
||||||
'django.contrib.auth.hashers.BCryptPasswordHasher',
|
"django.contrib.auth.hashers.BCryptPasswordHasher",
|
||||||
'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
|
"django.contrib.auth.hashers.BCryptSHA256PasswordHasher",
|
||||||
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
|
"django.contrib.auth.hashers.PBKDF2PasswordHasher",
|
||||||
'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
|
"django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher",
|
||||||
'django.contrib.auth.hashers.SHA1PasswordHasher',
|
"django.contrib.auth.hashers.SHA1PasswordHasher",
|
||||||
'django.contrib.auth.hashers.MD5PasswordHasher',
|
"django.contrib.auth.hashers.MD5PasswordHasher",
|
||||||
'django.contrib.auth.hashers.CryptPasswordHasher',
|
"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__))
|
PROJECT_PATH = os.path.abspath(os.path.dirname(__file__))
|
||||||
REGISTRATION_EMAIL_HTML = False
|
REGISTRATION_EMAIL_HTML = False
|
||||||
ROOT_URLCONF = 'urls'
|
ROOT_URLCONF = "urls"
|
||||||
SECRET_KEY = os.environ.get('SECRET_KEY', 'changeme')
|
SECRET_KEY = os.environ.get("SECRET_KEY", "changeme")
|
||||||
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
|
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
|
||||||
SECURE_SSL_REDIRECT = True if 'USE_SSL' in os.environ else False
|
SECURE_SSL_REDIRECT = True if "USE_SSL" in os.environ else False
|
||||||
SEND_BROKEN_LINK_EMAILS = False
|
SEND_BROKEN_LINK_EMAILS = False
|
||||||
SERVER_EMAIL = os.environ.get('POSTMARK_EMAIL', 'support@siftie.com')
|
SERVER_EMAIL = os.environ.get("POSTMARK_EMAIL", "support@siftie.com")
|
||||||
SESSION_COOKIE_AGE = 15801100
|
SESSION_COOKIE_AGE = 15801100
|
||||||
SESSION_COOKIE_SECURE = True if 'USE_SSL' in os.environ else False
|
SESSION_COOKIE_SECURE = True if "USE_SSL" in os.environ else False
|
||||||
SITE_ID = 1
|
SITE_ID = 1
|
||||||
STATICFILES_DIRS = (os.path.join(BASE_PATH, 'media'),)
|
STATICFILES_DIRS = (os.path.join(BASE_PATH, "media"),)
|
||||||
STATICFILES_FINDERS = ('django.contrib.staticfiles.finders.FileSystemFinder',
|
STATICFILES_FINDERS = (
|
||||||
'django.contrib.staticfiles.finders.AppDirectoriesFinder')
|
"django.contrib.staticfiles.finders.FileSystemFinder",
|
||||||
STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'
|
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
|
||||||
STATIC_ROOT = os.path.join(BASE_PATH, 'static')
|
)
|
||||||
STATIC_URL = '/static/'
|
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
|
TASTYPIE_CANNED_ERROR = """There was an error with your request. The site
|
||||||
developers have a record of this error, please email support@siftie.com and
|
developers have a record of this error, please email support@siftie.com and
|
||||||
we'll help you out."""
|
we'll help you out."""
|
||||||
|
|
||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||||
'DIRS': [os.path.join(PROJECT_PATH, 'templates')],
|
"DIRS": [os.path.join(PROJECT_PATH, "templates")],
|
||||||
'APP_DIRS': True,
|
"APP_DIRS": True,
|
||||||
'OPTIONS': {
|
"OPTIONS": {
|
||||||
'context_processors': [
|
"context_processors": [
|
||||||
'django.template.context_processors.debug',
|
"django.template.context_processors.debug",
|
||||||
'django.template.context_processors.request',
|
"django.template.context_processors.request",
|
||||||
'django.template.context_processors.static',
|
"django.template.context_processors.static",
|
||||||
'django.contrib.auth.context_processors.auth',
|
"django.contrib.auth.context_processors.auth",
|
||||||
'django.contrib.messages.context_processors.messages',
|
"django.contrib.messages.context_processors.messages",
|
||||||
],
|
]
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
TIME_ZONE = 'America/New_York'
|
TIME_ZONE = "America/New_York"
|
||||||
USE_HTTPS = True if 'USE_SSL' in os.environ else False
|
USE_HTTPS = True if "USE_SSL" in os.environ else False
|
||||||
USE_I18N = True
|
USE_I18N = True
|
||||||
USE_L10N = True
|
USE_L10N = True
|
||||||
USE_TZ = True
|
USE_TZ = True
|
||||||
|
|
||||||
INSTALLED_APPS = (
|
INSTALLED_APPS = (
|
||||||
'accounts',
|
"accounts",
|
||||||
'blogs',
|
"blogs",
|
||||||
'corsheaders',
|
"corsheaders",
|
||||||
'django.contrib.admin',
|
"django.contrib.admin",
|
||||||
'django.contrib.auth',
|
"django.contrib.auth",
|
||||||
'django.contrib.contenttypes',
|
"django.contrib.contenttypes",
|
||||||
'django.contrib.humanize',
|
"django.contrib.humanize",
|
||||||
'django.contrib.messages',
|
"django.contrib.messages",
|
||||||
'django.contrib.sessions',
|
"django.contrib.sessions",
|
||||||
'django.contrib.sites',
|
"django.contrib.sites",
|
||||||
'django.contrib.staticfiles',
|
"django.contrib.staticfiles",
|
||||||
'django_extensions',
|
"django_extensions",
|
||||||
'gunicorn',
|
"gunicorn",
|
||||||
'haystack',
|
"haystack",
|
||||||
'markdown_deux',
|
"markdown_deux",
|
||||||
'pagination',
|
"pagination",
|
||||||
'postmark',
|
"postmark",
|
||||||
'registration',
|
"registration",
|
||||||
'snipts',
|
"snipts",
|
||||||
'storages',
|
"storages",
|
||||||
'taggit',
|
"taggit",
|
||||||
'tastypie',
|
"tastypie",
|
||||||
'teams',
|
"teams",
|
||||||
'user-admin',
|
"user-admin",
|
||||||
'utils',
|
"utils",
|
||||||
)
|
)
|
||||||
LOGGING = {
|
LOGGING = {
|
||||||
'version': 1,
|
"version": 1,
|
||||||
'disable_existing_loggers': False,
|
"disable_existing_loggers": False,
|
||||||
'filters': {
|
"filters": {"require_debug_false": {"()": "django.utils.log.RequireDebugFalse"}},
|
||||||
'require_debug_false': {
|
"handlers": {},
|
||||||
'()': 'django.utils.log.RequireDebugFalse'
|
"loggers": {},
|
||||||
}
|
|
||||||
},
|
|
||||||
'handlers': {},
|
|
||||||
'loggers': {}
|
|
||||||
}
|
}
|
||||||
MIDDLEWARE_CLASSES = (
|
MIDDLEWARE_CLASSES = (
|
||||||
'django.middleware.security.SecurityMiddleware',
|
"django.middleware.security.SecurityMiddleware",
|
||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
"django.middleware.csrf.CsrfViewMiddleware",
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||||
'corsheaders.middleware.CorsMiddleware',
|
"corsheaders.middleware.CorsMiddleware",
|
||||||
'django.middleware.common.CommonMiddleware',
|
"django.middleware.common.CommonMiddleware",
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
"django.contrib.messages.middleware.MessageMiddleware",
|
||||||
'pagination.middleware.PaginationMiddleware',
|
"pagination.middleware.PaginationMiddleware",
|
||||||
'blogs.middleware.BlogMiddleware',
|
"blogs.middleware.BlogMiddleware",
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -3,29 +3,42 @@ from snipts.models import Favorite, Snipt, SniptLogEntry
|
||||||
|
|
||||||
|
|
||||||
class SniptAdmin(admin.ModelAdmin):
|
class SniptAdmin(admin.ModelAdmin):
|
||||||
readonly_fields = ('last_user_saved', 'user',)
|
readonly_fields = ("last_user_saved", "user")
|
||||||
list_display = ('title', 'slug', 'views', 'favs', 'user', 'lexer',
|
list_display = (
|
||||||
'public', 'blog_post', 'created', 'modified',
|
"title",
|
||||||
'publish_date')
|
"slug",
|
||||||
list_filter = ('blog_post',)
|
"views",
|
||||||
search_fields = ('title', 'slug', 'user__username', 'lexer', 'id', 'key',)
|
"favs",
|
||||||
ordering = ('-created',)
|
"user",
|
||||||
prepopulated_fields = {'slug': ('title',)}
|
"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)
|
admin.site.register(Snipt, SniptAdmin)
|
||||||
|
|
||||||
|
|
||||||
class SniptLogEntryAdmin(admin.ModelAdmin):
|
class SniptLogEntryAdmin(admin.ModelAdmin):
|
||||||
readonly_fields = ('snipt', 'user',)
|
readonly_fields = ("snipt", "user")
|
||||||
list_display = ('snipt_name', 'user', 'created', 'modified')
|
list_display = ("snipt_name", "user", "created", "modified")
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(SniptLogEntry, SniptLogEntryAdmin)
|
admin.site.register(SniptLogEntry, SniptLogEntryAdmin)
|
||||||
|
|
||||||
|
|
||||||
class FavoriteAdmin(admin.ModelAdmin):
|
class FavoriteAdmin(admin.ModelAdmin):
|
||||||
readonly_fields = ('snipt', 'user',)
|
readonly_fields = ("snipt", "user")
|
||||||
list_display = ('snipt', 'user', 'created',)
|
list_display = ("snipt", "user", "created")
|
||||||
search_fields = ('snipt', 'user',)
|
search_fields = ("snipt", "user")
|
||||||
ordering = ('-created',)
|
ordering = ("-created",)
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(Favorite, FavoriteAdmin)
|
admin.site.register(Favorite, FavoriteAdmin)
|
||||||
|
|
399
snipts/api.py
399
snipts/api.py
|
@ -139,11 +139,10 @@ class PrivateUserAuthorization(Authorization):
|
||||||
class FavoriteValidation(Validation):
|
class FavoriteValidation(Validation):
|
||||||
def is_valid(self, bundle, request=None):
|
def is_valid(self, bundle, request=None):
|
||||||
errors = {}
|
errors = {}
|
||||||
snipt = bundle.data['snipt']
|
snipt = bundle.data["snipt"]
|
||||||
|
|
||||||
if Favorite.objects.filter(user=bundle.request.user,
|
if Favorite.objects.filter(user=bundle.request.user, snipt=snipt).count():
|
||||||
snipt=snipt).count():
|
errors = "User has already favorited this snipt."
|
||||||
errors = 'User has already favorited this snipt.'
|
|
||||||
|
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
|
@ -152,8 +151,8 @@ class SniptValidation(Validation):
|
||||||
def is_valid(self, bundle, request=None):
|
def is_valid(self, bundle, request=None):
|
||||||
errors = {}
|
errors = {}
|
||||||
|
|
||||||
if (len(bundle.data['title']) > 255):
|
if len(bundle.data["title"]) > 255:
|
||||||
errors = 'Title must be 255 characters or less.'
|
errors = "Title must be 255 characters or less."
|
||||||
|
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
|
@ -164,10 +163,12 @@ class UserProfileValidation(Validation):
|
||||||
|
|
||||||
for field in bundle.data:
|
for field in bundle.data:
|
||||||
if bundle.data[field]:
|
if bundle.data[field]:
|
||||||
if not re.match('^[ A-Za-z0-9\/\@\._-]*$', bundle.data[field]):
|
if not re.match("^[ A-Za-z0-9\/\@\._-]*$", bundle.data[field]):
|
||||||
errors[field] = ('Only spaces, letters, numbers, '
|
errors[field] = (
|
||||||
'underscores, dashes, periods, forward '
|
"Only spaces, letters, numbers, "
|
||||||
'slashes, and "at sign" are valid.')
|
"underscores, dashes, periods, forward "
|
||||||
|
'slashes, and "at sign" are valid.'
|
||||||
|
)
|
||||||
|
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
|
@ -175,33 +176,33 @@ class UserProfileValidation(Validation):
|
||||||
class PublicUserResource(ModelResource):
|
class PublicUserResource(ModelResource):
|
||||||
class Meta:
|
class Meta:
|
||||||
queryset = User.objects.all()
|
queryset = User.objects.all()
|
||||||
resource_name = 'user'
|
resource_name = "user"
|
||||||
fields = ['id', 'username']
|
fields = ["id", "username"]
|
||||||
include_absolute_url = True
|
include_absolute_url = True
|
||||||
allowed_methods = ['get']
|
allowed_methods = ["get"]
|
||||||
filtering = {'username': ['contains', 'exact']}
|
filtering = {"username": ["contains", "exact"]}
|
||||||
max_limit = 200
|
max_limit = 200
|
||||||
cache = SimpleCache()
|
cache = SimpleCache()
|
||||||
|
|
||||||
def dehydrate(self, bundle):
|
def dehydrate(self, bundle):
|
||||||
bundle.data['snipts'] = '/api/public/snipt/?user=%d' % bundle.obj.id
|
bundle.data["snipts"] = "/api/public/snipt/?user=%d" % bundle.obj.id
|
||||||
bundle.data['email_md5'] = hashlib \
|
bundle.data["email_md5"] = hashlib.md5(
|
||||||
.md5(bundle.obj.email.lower().encode('utf-8')) \
|
bundle.obj.email.lower().encode("utf-8")
|
||||||
.hexdigest()
|
).hexdigest()
|
||||||
bundle.data['snipts_count'] = Snipt.objects.filter(user=bundle.obj.id,
|
bundle.data["snipts_count"] = Snipt.objects.filter(
|
||||||
public=True).count()
|
user=bundle.obj.id, public=True
|
||||||
|
).count()
|
||||||
return bundle
|
return bundle
|
||||||
|
|
||||||
|
|
||||||
class PublicTagResource(ModelResource):
|
class PublicTagResource(ModelResource):
|
||||||
class Meta:
|
class Meta:
|
||||||
queryset = Tag.objects.filter()
|
queryset = Tag.objects.filter()
|
||||||
queryset = queryset.annotate(
|
queryset = queryset.annotate(count=models.Count("taggit_taggeditem_items__id"))
|
||||||
count=models.Count('taggit_taggeditem_items__id'))
|
queryset = queryset.order_by("-count", "name")
|
||||||
queryset = queryset.order_by('-count', 'name')
|
resource_name = "tag"
|
||||||
resource_name = 'tag'
|
fields = ["id", "name"]
|
||||||
fields = ['id', 'name']
|
allowed_methods = ["get"]
|
||||||
allowed_methods = ['get']
|
|
||||||
max_limit = 200
|
max_limit = 200
|
||||||
cache = SimpleCache()
|
cache = SimpleCache()
|
||||||
|
|
||||||
|
@ -211,60 +212,74 @@ class PublicTagResource(ModelResource):
|
||||||
|
|
||||||
orm_filters = super(PublicTagResource, self).build_filters(filters)
|
orm_filters = super(PublicTagResource, self).build_filters(filters)
|
||||||
|
|
||||||
if 'q' in filters:
|
if "q" in filters:
|
||||||
orm_filters['slug'] = filters['q']
|
orm_filters["slug"] = filters["q"]
|
||||||
|
|
||||||
return orm_filters
|
return orm_filters
|
||||||
|
|
||||||
def dehydrate(self, bundle):
|
def dehydrate(self, bundle):
|
||||||
bundle.data['absolute_url'] = '/public/tag/%s/' % bundle.obj.slug
|
bundle.data["absolute_url"] = "/public/tag/%s/" % bundle.obj.slug
|
||||||
bundle.data['snipts'] = '/api/public/snipt/?tag=%d' % bundle.obj.id
|
bundle.data["snipts"] = "/api/public/snipt/?tag=%d" % bundle.obj.id
|
||||||
return bundle
|
return bundle
|
||||||
|
|
||||||
|
|
||||||
class PublicSniptResource(ModelResource):
|
class PublicSniptResource(ModelResource):
|
||||||
user = fields.ForeignKey(PublicUserResource, 'user', full=True)
|
user = fields.ForeignKey(PublicUserResource, "user", full=True)
|
||||||
tags = fields.ToManyField(PublicTagResource, 'tags', related_name='tag',
|
tags = fields.ToManyField(PublicTagResource, "tags", related_name="tag", full=True)
|
||||||
full=True)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
queryset = Snipt.objects.filter(public=True).order_by('-created')
|
queryset = Snipt.objects.filter(public=True).order_by("-created")
|
||||||
resource_name = 'snipt'
|
resource_name = "snipt"
|
||||||
fields = ['id', 'title', 'slug', 'lexer', 'code', 'description',
|
fields = [
|
||||||
'line_count', 'stylized', 'created', 'modified',
|
"id",
|
||||||
'publish_date', 'blog_post', 'meta']
|
"title",
|
||||||
|
"slug",
|
||||||
|
"lexer",
|
||||||
|
"code",
|
||||||
|
"description",
|
||||||
|
"line_count",
|
||||||
|
"stylized",
|
||||||
|
"created",
|
||||||
|
"modified",
|
||||||
|
"publish_date",
|
||||||
|
"blog_post",
|
||||||
|
"meta",
|
||||||
|
]
|
||||||
include_absolute_url = True
|
include_absolute_url = True
|
||||||
allowed_methods = ['get']
|
allowed_methods = ["get"]
|
||||||
filtering = {'user': 'exact', 'blog_post': 'exact'}
|
filtering = {"user": "exact", "blog_post": "exact"}
|
||||||
ordering = ['created', 'modified']
|
ordering = ["created", "modified"]
|
||||||
max_limit = 200
|
max_limit = 200
|
||||||
cache = SimpleCache()
|
cache = SimpleCache()
|
||||||
|
|
||||||
def dehydrate(self, bundle):
|
def dehydrate(self, bundle):
|
||||||
bundle.data['embed_url'] = bundle.obj.get_embed_url()
|
bundle.data["embed_url"] = bundle.obj.get_embed_url()
|
||||||
bundle.data['raw_url'] = bundle.obj.get_raw_url()
|
bundle.data["raw_url"] = bundle.obj.get_raw_url()
|
||||||
bundle.data['full_absolute_url'] = bundle.obj.get_full_absolute_url()
|
bundle.data["full_absolute_url"] = bundle.obj.get_full_absolute_url()
|
||||||
bundle.data['description_rendered'] = \
|
bundle.data["description_rendered"] = linebreaksbr(
|
||||||
linebreaksbr(urlize(bundle.obj.description))
|
urlize(bundle.obj.description)
|
||||||
|
)
|
||||||
|
|
||||||
log_entries = bundle.obj.sniptlogentry_set.all()
|
log_entries = bundle.obj.sniptlogentry_set.all()
|
||||||
bundle_log_entries = []
|
bundle_log_entries = []
|
||||||
|
|
||||||
for entry in log_entries:
|
for entry in log_entries:
|
||||||
bundle_log_entries.append({
|
bundle_log_entries.append(
|
||||||
'created': entry.created,
|
{
|
||||||
'user': entry.user,
|
"created": entry.created,
|
||||||
'code': entry.code,
|
"user": entry.user,
|
||||||
'diff': entry.diff
|
"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:
|
if "omit_code" in bundle.request.GET:
|
||||||
del bundle.data['code']
|
del bundle.data["code"]
|
||||||
|
|
||||||
if 'omit_stylized' in bundle.request.GET:
|
if "omit_stylized" in bundle.request.GET:
|
||||||
del bundle.data['stylized']
|
del bundle.data["stylized"]
|
||||||
|
|
||||||
return bundle
|
return bundle
|
||||||
|
|
||||||
|
@ -274,14 +289,14 @@ class PublicSniptResource(ModelResource):
|
||||||
|
|
||||||
orm_filters = super(PublicSniptResource, self).build_filters(filters)
|
orm_filters = super(PublicSniptResource, self).build_filters(filters)
|
||||||
|
|
||||||
if 'tag' in filters:
|
if "tag" in filters:
|
||||||
tag = Tag.objects.get(pk=filters['tag'])
|
tag = Tag.objects.get(pk=filters["tag"])
|
||||||
tagged_items = tag.taggit_taggeditem_items.all()
|
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:
|
if "q" in filters:
|
||||||
sqs = SearchQuerySet().auto_query(filters['q'])
|
sqs = SearchQuerySet().auto_query(filters["q"])
|
||||||
orm_filters['pk__in'] = [i.pk for i in sqs]
|
orm_filters["pk__in"] = [i.pk for i in sqs]
|
||||||
|
|
||||||
return orm_filters
|
return orm_filters
|
||||||
|
|
||||||
|
@ -289,11 +304,11 @@ class PublicSniptResource(ModelResource):
|
||||||
class PrivateUserProfileResource(ModelResource):
|
class PrivateUserProfileResource(ModelResource):
|
||||||
class Meta:
|
class Meta:
|
||||||
queryset = UserProfile.objects.all()
|
queryset = UserProfile.objects.all()
|
||||||
resource_name = 'profile'
|
resource_name = "profile"
|
||||||
excludes = ['is_pro']
|
excludes = ["is_pro"]
|
||||||
validation = UserProfileValidation()
|
validation = UserProfileValidation()
|
||||||
include_absolute_url = False
|
include_absolute_url = False
|
||||||
allowed_methods = ['get', 'put']
|
allowed_methods = ["get", "put"]
|
||||||
list_allowed_methods = []
|
list_allowed_methods = []
|
||||||
authentication = ApiKeyAuthentication()
|
authentication = ApiKeyAuthentication()
|
||||||
authorization = PrivateUserProfileAuthorization()
|
authorization = PrivateUserProfileAuthorization()
|
||||||
|
@ -301,23 +316,22 @@ class PrivateUserProfileResource(ModelResource):
|
||||||
max_limit = 200
|
max_limit = 200
|
||||||
|
|
||||||
def dehydrate(self, bundle):
|
def dehydrate(self, bundle):
|
||||||
bundle.data['email'] = bundle.obj.user.email
|
bundle.data["email"] = bundle.obj.user.email
|
||||||
bundle.data['username'] = bundle.obj.user.username
|
bundle.data["username"] = bundle.obj.user.username
|
||||||
bundle.data['user_id'] = bundle.obj.user.id
|
bundle.data["user_id"] = bundle.obj.user.id
|
||||||
bundle.data['api_key'] = bundle.obj.user.api_key.key
|
bundle.data["api_key"] = bundle.obj.user.api_key.key
|
||||||
return bundle
|
return bundle
|
||||||
|
|
||||||
|
|
||||||
class PrivateUserResource(ModelResource):
|
class PrivateUserResource(ModelResource):
|
||||||
profile = fields.ForeignKey(PrivateUserProfileResource, 'profile',
|
profile = fields.ForeignKey(PrivateUserProfileResource, "profile", full=False)
|
||||||
full=False)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
queryset = User.objects.all()
|
queryset = User.objects.all()
|
||||||
resource_name = 'user'
|
resource_name = "user"
|
||||||
fields = ['id', 'username', 'email']
|
fields = ["id", "username", "email"]
|
||||||
include_absolute_url = True
|
include_absolute_url = True
|
||||||
allowed_methods = ['get']
|
allowed_methods = ["get"]
|
||||||
list_allowed_methods = []
|
list_allowed_methods = []
|
||||||
authentication = ApiKeyAuthentication()
|
authentication = ApiKeyAuthentication()
|
||||||
authorization = PrivateUserAuthorization()
|
authorization = PrivateUserAuthorization()
|
||||||
|
@ -326,155 +340,172 @@ class PrivateUserResource(ModelResource):
|
||||||
cache = SimpleCache()
|
cache = SimpleCache()
|
||||||
|
|
||||||
def dehydrate(self, bundle):
|
def dehydrate(self, bundle):
|
||||||
bundle.data['email_md5'] = hashlib \
|
bundle.data["email_md5"] = hashlib.md5(
|
||||||
.md5(bundle.obj.email.lower().encode('utf-8')) \
|
bundle.obj.email.lower().encode("utf-8")
|
||||||
.hexdigest()
|
).hexdigest()
|
||||||
bundle.data['stats'] = {
|
bundle.data["stats"] = {
|
||||||
'public_snipts': Snipt.objects.filter(user=bundle.obj.id,
|
"public_snipts": Snipt.objects.filter(
|
||||||
public=True).count(),
|
user=bundle.obj.id, public=True
|
||||||
'private_snipts': Snipt.objects.filter(user=bundle.obj.id,
|
).count(),
|
||||||
public=False).count(),
|
"private_snipts": Snipt.objects.filter(
|
||||||
'total_snipts': Snipt.objects.filter(user=bundle.obj.id).count(),
|
user=bundle.obj.id, public=False
|
||||||
'total_views': Snipt.objects.filter(user=bundle.obj.id).aggregate(
|
).count(),
|
||||||
models.Sum('views'))['views__sum']
|
"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_snipts = Snipt.objects.filter(user=bundle.obj)
|
||||||
user_tags = [
|
user_tags = [snipt["tags"] for snipt in user_snipts.values("tags").distinct()]
|
||||||
snipt['tags'] for snipt in user_snipts.values('tags').distinct()
|
|
||||||
]
|
|
||||||
|
|
||||||
tags = [
|
tags = [
|
||||||
tag['name'] for tag in
|
tag["name"]
|
||||||
Tag.objects.filter(id__in=user_tags).values('name').distinct()
|
for tag in Tag.objects.filter(id__in=user_tags).values("name").distinct()
|
||||||
]
|
]
|
||||||
|
|
||||||
bundle.data['tags'] = tags
|
bundle.data["tags"] = tags
|
||||||
|
|
||||||
bundle.data['lexers'] = [
|
bundle.data["lexers"] = [
|
||||||
snipt['lexer'] for snipt in user_snipts
|
snipt["lexer"] for snipt in user_snipts.values("lexer").distinct()
|
||||||
.values('lexer').distinct()]
|
]
|
||||||
|
|
||||||
return bundle
|
return bundle
|
||||||
|
|
||||||
|
|
||||||
class PrivateSniptResource(ModelResource):
|
class PrivateSniptResource(ModelResource):
|
||||||
user = fields.ForeignKey(PrivateUserResource, 'user', full=True)
|
user = fields.ForeignKey(PrivateUserResource, "user", full=True)
|
||||||
last_user_saved = fields.ForeignKey(PrivateUserResource,
|
last_user_saved = fields.ForeignKey(
|
||||||
'last_user_saved',
|
PrivateUserResource, "last_user_saved", null=True, full=False
|
||||||
null=True,
|
)
|
||||||
full=False)
|
|
||||||
tags_list = ListField()
|
tags_list = ListField()
|
||||||
tags = fields.ToManyField(PublicTagResource, 'tags', related_name='tag',
|
tags = fields.ToManyField(PublicTagResource, "tags", related_name="tag", full=True)
|
||||||
full=True)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
queryset = Snipt.objects.all().order_by('-created')
|
queryset = Snipt.objects.all().order_by("-created")
|
||||||
resource_name = 'snipt'
|
resource_name = "snipt"
|
||||||
fields = ['id', 'title', 'slug', 'lexer', 'code', 'description',
|
fields = [
|
||||||
'line_count', 'stylized', 'key', 'public', 'secure',
|
"id",
|
||||||
'blog_post', 'created', 'modified', 'publish_date', 'meta']
|
"title",
|
||||||
|
"slug",
|
||||||
|
"lexer",
|
||||||
|
"code",
|
||||||
|
"description",
|
||||||
|
"line_count",
|
||||||
|
"stylized",
|
||||||
|
"key",
|
||||||
|
"public",
|
||||||
|
"secure",
|
||||||
|
"blog_post",
|
||||||
|
"created",
|
||||||
|
"modified",
|
||||||
|
"publish_date",
|
||||||
|
"meta",
|
||||||
|
]
|
||||||
include_absolute_url = True
|
include_absolute_url = True
|
||||||
detail_allowed_methods = ['get', 'patch', 'put', 'delete']
|
detail_allowed_methods = ["get", "patch", "put", "delete"]
|
||||||
list_allowed_methods = ['get', 'post']
|
list_allowed_methods = ["get", "post"]
|
||||||
authentication = ApiKeyAuthentication()
|
authentication = ApiKeyAuthentication()
|
||||||
authorization = PrivateSniptAuthorization()
|
authorization = PrivateSniptAuthorization()
|
||||||
validation = SniptValidation()
|
validation = SniptValidation()
|
||||||
ordering = ['created', 'modified']
|
ordering = ["created", "modified"]
|
||||||
always_return_data = True
|
always_return_data = True
|
||||||
max_limit = 200
|
max_limit = 200
|
||||||
cache = SimpleCache()
|
cache = SimpleCache()
|
||||||
|
|
||||||
def dehydrate(self, bundle):
|
def dehydrate(self, bundle):
|
||||||
bundle.data['embed_url'] = bundle.obj.get_embed_url()
|
bundle.data["embed_url"] = bundle.obj.get_embed_url()
|
||||||
bundle.data['raw_url'] = bundle.obj.get_raw_url()
|
bundle.data["raw_url"] = bundle.obj.get_raw_url()
|
||||||
bundle.data['tags_list'] = edit_string_for_tags(bundle.obj.tags.all())
|
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["full_absolute_url"] = bundle.obj.get_full_absolute_url()
|
||||||
bundle.data['description_rendered'] = \
|
bundle.data["description_rendered"] = linebreaksbr(
|
||||||
linebreaksbr(urlize(bundle.obj.description))
|
urlize(bundle.obj.description)
|
||||||
bundle.data['views'] = bundle.obj.views
|
)
|
||||||
bundle.data['favs'] = bundle.obj.favs()
|
bundle.data["views"] = bundle.obj.views
|
||||||
|
bundle.data["favs"] = bundle.obj.favs()
|
||||||
|
|
||||||
if bundle.data['publish_date']:
|
if bundle.data["publish_date"]:
|
||||||
bundle.data['publish_date'] = \
|
bundle.data["publish_date"] = date(
|
||||||
date(bundle.data['publish_date'], 'M d, Y \\a\\t h:i A')
|
bundle.data["publish_date"], "M d, Y \\a\\t h:i A"
|
||||||
|
)
|
||||||
|
|
||||||
log_entries = bundle.obj.sniptlogentry_set.all()
|
log_entries = bundle.obj.sniptlogentry_set.all()
|
||||||
bundle_log_entries = []
|
bundle_log_entries = []
|
||||||
|
|
||||||
for entry in log_entries:
|
for entry in log_entries:
|
||||||
bundle_log_entries.append({
|
bundle_log_entries.append(
|
||||||
'created': entry.created,
|
{
|
||||||
'user': entry.user,
|
"created": entry.created,
|
||||||
'code': entry.code,
|
"user": entry.user,
|
||||||
'diff': entry.diff
|
"code": entry.code,
|
||||||
})
|
"diff": entry.diff,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
bundle.data['log_entries'] = bundle_log_entries
|
bundle.data["log_entries"] = bundle_log_entries
|
||||||
|
|
||||||
return bundle
|
return bundle
|
||||||
|
|
||||||
def obj_create(self, bundle, **kwargs):
|
def obj_create(self, bundle, **kwargs):
|
||||||
bundle.data['last_user_saved'] = bundle.request.user
|
bundle.data["last_user_saved"] = bundle.request.user
|
||||||
bundle.data['tags_list'] = bundle.data.get('tags')
|
bundle.data["tags_list"] = bundle.data.get("tags")
|
||||||
bundle.data['tags'] = []
|
bundle.data["tags"] = []
|
||||||
|
|
||||||
if 'intended_user' in bundle.data:
|
if "intended_user" in bundle.data:
|
||||||
bundle.data['user'] = \
|
bundle.data["user"] = User.objects.get(
|
||||||
User.objects.get(username=bundle.data['intended_user'])
|
username=bundle.data["intended_user"]
|
||||||
|
)
|
||||||
else:
|
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)
|
bundle = self._clean_publish_date(bundle)
|
||||||
|
|
||||||
return super(PrivateSniptResource, self) \
|
return super(PrivateSniptResource, self).obj_create(bundle, **kwargs)
|
||||||
.obj_create(bundle, **kwargs)
|
|
||||||
|
|
||||||
def obj_update(self, 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
|
user = instance.user
|
||||||
else:
|
else:
|
||||||
user = bundle.request.user
|
user = bundle.request.user
|
||||||
|
|
||||||
bundle.data['created'] = None
|
bundle.data["created"] = None
|
||||||
bundle.data['last_user_saved'] = bundle.request.user
|
bundle.data["last_user_saved"] = bundle.request.user
|
||||||
bundle.data['modified'] = None
|
bundle.data["modified"] = None
|
||||||
bundle.data['user'] = user
|
bundle.data["user"] = user
|
||||||
|
|
||||||
if type(bundle.data['tags']) == str or type(bundle.data['tags']) == unicode:
|
if type(bundle.data["tags"]) == str or type(bundle.data["tags"]) == unicode:
|
||||||
bundle.data['tags_list'] = bundle.data['tags']
|
bundle.data["tags_list"] = bundle.data["tags"]
|
||||||
else:
|
else:
|
||||||
bundle.data['tags_list'] = ''
|
bundle.data["tags_list"] = ""
|
||||||
bundle.data['tags'] = ''
|
bundle.data["tags"] = ""
|
||||||
|
|
||||||
if 'blog_post' in bundle.data:
|
if "blog_post" in bundle.data:
|
||||||
bundle = self._clean_publish_date(bundle)
|
bundle = self._clean_publish_date(bundle)
|
||||||
|
|
||||||
return super(PrivateSniptResource, self) \
|
return super(PrivateSniptResource, self).obj_update(bundle, **kwargs)
|
||||||
.obj_update(bundle, **kwargs)
|
|
||||||
|
|
||||||
def _clean_publish_date(self, bundle):
|
def _clean_publish_date(self, bundle):
|
||||||
if bundle.data['blog_post'] and 'publish_date' not in bundle.data:
|
if bundle.data["blog_post"] and "publish_date" not in bundle.data:
|
||||||
bundle.data['publish_date'] = datetime.datetime.now()
|
bundle.data["publish_date"] = datetime.datetime.now()
|
||||||
elif bundle.data['publish_date'] == '':
|
elif bundle.data["publish_date"] == "":
|
||||||
bundle.data['publish_date'] = datetime.datetime.now()
|
bundle.data["publish_date"] = datetime.datetime.now()
|
||||||
elif bundle.data['blog_post']:
|
elif bundle.data["blog_post"]:
|
||||||
c = pdt.Constants()
|
c = pdt.Constants()
|
||||||
p = pdt.Calendar(c)
|
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:
|
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:
|
else:
|
||||||
publish_date = datetime.datetime.now()
|
publish_date = datetime.datetime.now()
|
||||||
|
|
||||||
bundle.data['publish_date'] = publish_date
|
bundle.data["publish_date"] = publish_date
|
||||||
elif not bundle.data['blog_post']:
|
elif not bundle.data["blog_post"]:
|
||||||
bundle.data['publish_date'] = None
|
bundle.data["publish_date"] = None
|
||||||
|
|
||||||
return bundle
|
return bundle
|
||||||
|
|
||||||
|
@ -484,51 +515,51 @@ class PrivateSniptResource(ModelResource):
|
||||||
|
|
||||||
orm_filters = super(PrivateSniptResource, self).build_filters(filters)
|
orm_filters = super(PrivateSniptResource, self).build_filters(filters)
|
||||||
|
|
||||||
if 'tag' in filters:
|
if "tag" in filters:
|
||||||
tag = Tag.objects.get(pk=filters['tag'])
|
tag = Tag.objects.get(pk=filters["tag"])
|
||||||
tagged_items = tag.taggit_taggeditem_items.all()
|
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:
|
if "q" in filters:
|
||||||
user = User.objects.get(username=filters['username'])
|
user = User.objects.get(username=filters["username"])
|
||||||
sqs = SearchQuerySet().filter(author=user, content=filters['q'])
|
sqs = SearchQuerySet().filter(author=user, content=filters["q"])
|
||||||
orm_filters['pk__in'] = [i.pk for i in sqs]
|
orm_filters["pk__in"] = [i.pk for i in sqs]
|
||||||
|
|
||||||
return orm_filters
|
return orm_filters
|
||||||
|
|
||||||
def save_m2m(self, bundle):
|
def save_m2m(self, bundle):
|
||||||
tags = bundle.data.get('tags_list', [])
|
tags = bundle.data.get("tags_list", [])
|
||||||
if tags != '':
|
if tags != "":
|
||||||
bundle.obj.tags.set(*parse_tags(tags))
|
bundle.obj.tags.set(*parse_tags(tags))
|
||||||
else:
|
else:
|
||||||
bundle.obj.tags.set()
|
bundle.obj.tags.set()
|
||||||
|
|
||||||
|
|
||||||
class PrivateFavoriteResource(ModelResource):
|
class PrivateFavoriteResource(ModelResource):
|
||||||
user = fields.ForeignKey(PrivateUserResource, 'user', full=True)
|
user = fields.ForeignKey(PrivateUserResource, "user", full=True)
|
||||||
snipt = fields.ForeignKey(PrivateSniptResource, 'snipt', full=False)
|
snipt = fields.ForeignKey(PrivateSniptResource, "snipt", full=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
queryset = Favorite.objects.all().order_by('-created')
|
queryset = Favorite.objects.all().order_by("-created")
|
||||||
resource_name = 'favorite'
|
resource_name = "favorite"
|
||||||
fields = ['id']
|
fields = ["id"]
|
||||||
validation = FavoriteValidation()
|
validation = FavoriteValidation()
|
||||||
detail_allowed_methods = ['get', 'post', 'delete']
|
detail_allowed_methods = ["get", "post", "delete"]
|
||||||
list_allowed_methods = ['get', 'post']
|
list_allowed_methods = ["get", "post"]
|
||||||
authentication = ApiKeyAuthentication()
|
authentication = ApiKeyAuthentication()
|
||||||
authorization = PrivateFavoriteAuthorization()
|
authorization = PrivateFavoriteAuthorization()
|
||||||
ordering = ['created']
|
ordering = ["created"]
|
||||||
always_return_data = True
|
always_return_data = True
|
||||||
max_limit = 200
|
max_limit = 200
|
||||||
cache = SimpleCache()
|
cache = SimpleCache()
|
||||||
|
|
||||||
def dehydrate(self, bundle):
|
def dehydrate(self, bundle):
|
||||||
bundle.data['snipt'] = '/api/public/snipt/{}/'.format(
|
bundle.data["snipt"] = "/api/public/snipt/{}/".format(bundle.obj.snipt.pk)
|
||||||
bundle.obj.snipt.pk)
|
|
||||||
return bundle
|
return bundle
|
||||||
|
|
||||||
def obj_create(self, bundle, **kwargs):
|
def obj_create(self, bundle, **kwargs):
|
||||||
bundle.data['user'] = bundle.request.user
|
bundle.data["user"] = bundle.request.user
|
||||||
bundle.data['snipt'] = Snipt.objects.get(pk=bundle.data['snipt'])
|
bundle.data["snipt"] = Snipt.objects.get(pk=bundle.data["snipt"])
|
||||||
return super(PrivateFavoriteResource, self) \
|
return super(PrivateFavoriteResource, self).obj_create(
|
||||||
.obj_create(bundle, user=bundle.request.user, **kwargs)
|
bundle, user=bundle.request.user, **kwargs
|
||||||
|
)
|
||||||
|
|
|
@ -8,15 +8,22 @@ import requests
|
||||||
|
|
||||||
|
|
||||||
def get_snipts(api_key, from_username, url=None, snipts=[]):
|
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)
|
path = (
|
||||||
res = requests.get('https://snippets.siftie.com' + 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()
|
json = res.json()
|
||||||
|
|
||||||
print(u"Fetched snipts {} through {} of {}".format(
|
print(
|
||||||
json["meta"]["offset"],
|
u"Fetched snipts {} through {} of {}".format(
|
||||||
json["meta"]["offset"] + json["meta"]["limit"],
|
json["meta"]["offset"],
|
||||||
json["meta"]["total_count"]
|
json["meta"]["offset"] + json["meta"]["limit"],
|
||||||
))
|
json["meta"]["total_count"],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
snipts.extend(json["objects"])
|
snipts.extend(json["objects"])
|
||||||
|
|
||||||
|
@ -30,14 +37,14 @@ class Command(BaseCommand):
|
||||||
help = u"Import snipts from Siftie Snippets."
|
help = u"Import snipts from Siftie Snippets."
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
parser.add_argument('api_key', nargs='+', type=str)
|
parser.add_argument("api_key", nargs="+", type=str)
|
||||||
parser.add_argument('from_username', nargs='+', type=str)
|
parser.add_argument("from_username", nargs="+", type=str)
|
||||||
parser.add_argument('to_username', nargs='+', type=str)
|
parser.add_argument("to_username", nargs="+", type=str)
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
api_key = options['api_key'][0]
|
api_key = options["api_key"][0]
|
||||||
from_username = options['from_username'][0]
|
from_username = options["from_username"][0]
|
||||||
to_username = options['to_username'][0]
|
to_username = options["to_username"][0]
|
||||||
to_user = User.objects.get(username=to_username)
|
to_user = User.objects.get(username=to_username)
|
||||||
|
|
||||||
print(u"Fetching snipts...")
|
print(u"Fetching snipts...")
|
||||||
|
@ -62,7 +69,7 @@ class Command(BaseCommand):
|
||||||
stylized=snipt["stylized"],
|
stylized=snipt["stylized"],
|
||||||
title=snipt["title"],
|
title=snipt["title"],
|
||||||
user=to_user,
|
user=to_user,
|
||||||
views=snipt["views"]
|
views=snipt["views"],
|
||||||
)
|
)
|
||||||
|
|
||||||
s.created = snipt["created"]
|
s.created = snipt["created"]
|
||||||
|
|
|
@ -9,53 +9,90 @@ import taggit.managers
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('taggit', '0001_initial'),
|
("taggit", "0001_initial"),
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Favorite',
|
name="Favorite",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
(
|
||||||
('created', models.DateTimeField(auto_now_add=True)),
|
"id",
|
||||||
('modified', models.DateTimeField(auto_now=True)),
|
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(
|
migrations.CreateModel(
|
||||||
name='Snipt',
|
name="Snipt",
|
||||||
fields=[
|
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)),
|
"id",
|
||||||
('slug', models.SlugField(max_length=255, blank=True)),
|
models.AutoField(
|
||||||
('custom_slug', models.SlugField(max_length=255, blank=True)),
|
verbose_name="ID",
|
||||||
('lexer', models.CharField(max_length=50)),
|
serialize=False,
|
||||||
('code', models.TextField()),
|
auto_created=True,
|
||||||
('meta', models.TextField(null=True, blank=True)),
|
primary_key=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)),
|
"title",
|
||||||
('line_count', models.IntegerField(default=None, null=True, blank=True)),
|
models.CharField(
|
||||||
('key', models.CharField(max_length=100, null=True, blank=True)),
|
default=b"Untitled", max_length=255, null=True, blank=True
|
||||||
('public', models.BooleanField(default=False)),
|
),
|
||||||
('blog_post', models.BooleanField(default=False)),
|
),
|
||||||
('views', models.IntegerField(default=0)),
|
("slug", models.SlugField(max_length=255, blank=True)),
|
||||||
('created', models.DateTimeField(auto_now_add=True)),
|
("custom_slug", models.SlugField(max_length=255, blank=True)),
|
||||||
('modified', models.DateTimeField(auto_now=True)),
|
("lexer", models.CharField(max_length=50)),
|
||||||
('publish_date', models.DateTimeField(null=True, blank=True)),
|
("code", models.TextField()),
|
||||||
('tags', taggit.managers.TaggableManager(to='taggit.Tag', through='taggit.TaggedItem', help_text='A comma-separated list of tags.', verbose_name='Tags')),
|
("meta", models.TextField(null=True, blank=True)),
|
||||||
('user', models.ForeignKey(blank=True, to=settings.AUTH_USER_MODEL, null=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(
|
migrations.AddField(
|
||||||
model_name='favorite',
|
model_name="favorite",
|
||||||
name='snipt',
|
name="snipt",
|
||||||
field=models.ForeignKey(to='snipts.Snipt'),
|
field=models.ForeignKey(to="snipts.Snipt"),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='favorite',
|
model_name="favorite",
|
||||||
name='user',
|
name="user",
|
||||||
field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
|
field=models.ForeignKey(to=settings.AUTH_USER_MODEL),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -9,20 +9,28 @@ class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
('snipts', '0001_initial'),
|
("snipts", "0001_initial"),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='SniptLogEntry',
|
name="SniptLogEntry",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
(
|
||||||
('code', models.TextField()),
|
"id",
|
||||||
('diff', models.TextField()),
|
models.AutoField(
|
||||||
('created', models.DateTimeField(auto_now_add=True)),
|
verbose_name="ID",
|
||||||
('modified', models.DateTimeField(auto_now=True)),
|
serialize=False,
|
||||||
('snipt', models.ForeignKey(to='snipts.Snipt')),
|
auto_created=True,
|
||||||
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
|
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)),
|
||||||
],
|
],
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -9,13 +9,18 @@ class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
('snipts', '0002_sniptlogentry'),
|
("snipts", "0002_sniptlogentry"),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='snipt',
|
model_name="snipt",
|
||||||
name='last_user_saved',
|
name="last_user_saved",
|
||||||
field=models.ForeignKey(related_name='last_user_saved', blank=True, to=settings.AUTH_USER_MODEL, null=True),
|
field=models.ForeignKey(
|
||||||
),
|
related_name="last_user_saved",
|
||||||
|
blank=True,
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,19 +6,17 @@ from django.db import models, migrations
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("snipts", "0003_snipt_last_user_saved")]
|
||||||
('snipts', '0003_snipt_last_user_saved'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='snipt',
|
model_name="snipt", name="secure", field=models.BooleanField(default=False)
|
||||||
name='secure',
|
|
||||||
field=models.BooleanField(default=False),
|
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='snipt',
|
model_name="snipt",
|
||||||
name='title',
|
name="title",
|
||||||
field=models.CharField(max_length=255, blank=True, null=True, default='Untitled'),
|
field=models.CharField(
|
||||||
|
max_length=255, blank=True, null=True, default="Untitled"
|
||||||
|
),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -9,18 +9,26 @@ class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
('snipts', '0004_auto_20160512_1058'),
|
("snipts", "0004_auto_20160512_1058"),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='SniptSecureView',
|
name="SniptSecureView",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(serialize=False, primary_key=True, auto_created=True, verbose_name='ID')),
|
(
|
||||||
('created', models.DateTimeField(auto_now_add=True)),
|
"id",
|
||||||
('modified', models.DateTimeField(auto_now=True)),
|
models.AutoField(
|
||||||
('snipt', models.ForeignKey(to='snipts.Snipt')),
|
serialize=False,
|
||||||
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
|
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)),
|
||||||
],
|
],
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
240
snipts/models.py
240
snipts/models.py
|
@ -23,14 +23,15 @@ class Snipt(models.Model):
|
||||||
"""An individual Snipt."""
|
"""An individual Snipt."""
|
||||||
|
|
||||||
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.DO_NOTHING)
|
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.DO_NOTHING)
|
||||||
last_user_saved = models.ForeignKey(User,
|
last_user_saved = models.ForeignKey(
|
||||||
blank=True,
|
User,
|
||||||
null=True,
|
blank=True,
|
||||||
related_name='last_user_saved',
|
null=True,
|
||||||
on_delete=models.DO_NOTHING)
|
related_name="last_user_saved",
|
||||||
|
on_delete=models.DO_NOTHING,
|
||||||
|
)
|
||||||
|
|
||||||
title = models.CharField(max_length=255, blank=True, null=True,
|
title = models.CharField(max_length=255, blank=True, null=True, default="Untitled")
|
||||||
default='Untitled')
|
|
||||||
slug = models.SlugField(max_length=255, blank=True)
|
slug = models.SlugField(max_length=255, blank=True)
|
||||||
custom_slug = models.SlugField(max_length=255, blank=True)
|
custom_slug = models.SlugField(max_length=255, blank=True)
|
||||||
tags = TaggableManager()
|
tags = TaggableManager()
|
||||||
|
@ -61,7 +62,7 @@ class Snipt(models.Model):
|
||||||
|
|
||||||
diff = difflib.unified_diff(expected, actual)
|
diff = difflib.unified_diff(expected, actual)
|
||||||
|
|
||||||
return ''.join(diff)
|
return "".join(diff)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(Snipt, self).__init__(*args, **kwargs)
|
super(Snipt, self).__init__(*args, **kwargs)
|
||||||
|
@ -73,92 +74,101 @@ class Snipt(models.Model):
|
||||||
self.slug = slugify_uniquely(self.title, Snipt)
|
self.slug = slugify_uniquely(self.title, Snipt)
|
||||||
|
|
||||||
if not self.key:
|
if not self.key:
|
||||||
self.key = hashlib.md5((self.slug +
|
self.key = hashlib.md5(
|
||||||
str(datetime.datetime.now()) +
|
(
|
||||||
str(random.random())).encode('utf-8')).hexdigest()
|
self.slug + str(datetime.datetime.now()) + str(random.random())
|
||||||
|
).encode("utf-8")
|
||||||
|
).hexdigest()
|
||||||
|
|
||||||
if self.lexer == 'markdown':
|
if self.lexer == "markdown":
|
||||||
self.stylized = markdown(self.code, 'default')
|
self.stylized = markdown(self.code, "default")
|
||||||
|
|
||||||
# Snippet embeds
|
# Snippet embeds
|
||||||
for match in re.findall('\[\[(\w{32})\]\]', self.stylized):
|
for match in re.findall("\[\[(\w{32})\]\]", self.stylized):
|
||||||
self.stylized = self.stylized.replace('[[' + str(match) + ']]',
|
self.stylized = self.stylized.replace(
|
||||||
"""
|
"[[" + str(match) + "]]",
|
||||||
|
"""
|
||||||
<script type="text/javascript"
|
<script type="text/javascript"
|
||||||
src="https://snippets.siftie.com/embed/{}/?snipt">
|
src="https://snippets.siftie.com/embed/{}/?snipt">
|
||||||
</script>
|
</script>
|
||||||
<div id="snipt-embed-{}"></div>""".format(match, match))
|
<div id="snipt-embed-{}"></div>""".format(
|
||||||
|
match, match
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
# YouTube embeds
|
# YouTube embeds
|
||||||
for match in re.findall('\[\[youtube-(\w{11})\-(\d+)x(\d+)\]\]',
|
for match in re.findall(
|
||||||
self.stylized):
|
"\[\[youtube-(\w{11})\-(\d+)x(\d+)\]\]", self.stylized
|
||||||
self.stylized = self.stylized \
|
):
|
||||||
.replace('[[youtube-{}-{}x{}]]'.format(
|
self.stylized = self.stylized.replace(
|
||||||
str(match[0]),
|
"[[youtube-{}-{}x{}]]".format(
|
||||||
str(match[1]),
|
str(match[0]), str(match[1]), str(match[2])
|
||||||
str(match[2])),
|
),
|
||||||
"""<iframe width="{}" height="{}"
|
"""<iframe width="{}" height="{}"
|
||||||
src="https://www.youtube.com/embed/{}"
|
src="https://www.youtube.com/embed/{}"
|
||||||
frameborder="0" allowfullscreen></iframe>"""
|
frameborder="0" allowfullscreen></iframe>""".format(
|
||||||
.format(match[1], match[2], match[0]))
|
match[1], match[2], match[0]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
# Vimeo embeds
|
# Vimeo embeds
|
||||||
for match in re.findall('\[\[vimeo-(\d+)\-(\d+)x(\d+)\]\]',
|
for match in re.findall("\[\[vimeo-(\d+)\-(\d+)x(\d+)\]\]", self.stylized):
|
||||||
self.stylized):
|
self.stylized = self.stylized.replace(
|
||||||
self.stylized = self.stylized \
|
"[[vimeo-{}-{}x{}]]".format(
|
||||||
.replace('[[vimeo-{}-{}x{}]]'.format(
|
str(match[0]), str(match[1]), str(match[2])
|
||||||
str(match[0]),
|
),
|
||||||
str(match[1]),
|
"""<iframe src="https://player.vimeo.com/video/{}"
|
||||||
str(match[2])),
|
|
||||||
"""<iframe src="https://player.vimeo.com/video/{}"
|
|
||||||
width="{}" height="{}" frameborder="0"
|
width="{}" height="{}" frameborder="0"
|
||||||
webkitAllowFullScreen mozallowfullscreen
|
webkitAllowFullScreen mozallowfullscreen
|
||||||
allowFullScreen></iframe>"""
|
allowFullScreen></iframe>""".format(
|
||||||
.format(match[0], match[1], match[2]))
|
match[0], match[1], match[2]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
# Tweet embeds
|
# Tweet embeds
|
||||||
for match in re.findall('\[\[tweet-(\d+)\]\]', self.stylized):
|
for match in re.findall("\[\[tweet-(\d+)\]\]", self.stylized):
|
||||||
self.stylized = self.stylized \
|
self.stylized = self.stylized.replace(
|
||||||
.replace(
|
"[[tweet-{}]]".format(str(match)),
|
||||||
'[[tweet-{}]]'.format(str(match)),
|
'<div class="embedded-tweet" data-tweet-id="{}"></div>'.format(
|
||||||
'<div class="embedded-tweet" data-tweet-id="{}"></div>'
|
str(match)
|
||||||
.format(str(match)))
|
),
|
||||||
|
)
|
||||||
|
|
||||||
# Parse usernames
|
# 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.
|
# Try and get the user by username.
|
||||||
user = get_object_or_None(User, username=match)
|
user = get_object_or_None(User, username=match)
|
||||||
|
|
||||||
if user:
|
if user:
|
||||||
url = user.profile.get_user_profile_url()
|
url = user.profile.get_user_profile_url()
|
||||||
self.stylized = self.stylized \
|
self.stylized = self.stylized.replace(
|
||||||
.replace('@{} '.format(str(match)),
|
"@{} ".format(str(match)),
|
||||||
'<a href="{}">@{}</a> '.format(url, match))
|
'<a href="{}">@{}</a> '.format(url, match),
|
||||||
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.stylized = highlight(self.code,
|
self.stylized = highlight(
|
||||||
get_lexer_by_name(self.lexer,
|
self.code,
|
||||||
encoding='UTF-8'),
|
get_lexer_by_name(self.lexer, encoding="UTF-8"),
|
||||||
HtmlFormatter(linenos='table',
|
HtmlFormatter(
|
||||||
anchorlinenos=True,
|
linenos="table", anchorlinenos=True, lineanchors="L", linespans="L"
|
||||||
lineanchors='L',
|
),
|
||||||
linespans='L',
|
)
|
||||||
))
|
self.line_count = len(self.code.split("\n"))
|
||||||
self.line_count = len(self.code.split('\n'))
|
|
||||||
|
|
||||||
if self.lexer == 'markdown':
|
if self.lexer == "markdown":
|
||||||
lexer_for_embedded = 'text'
|
lexer_for_embedded = "text"
|
||||||
else:
|
else:
|
||||||
lexer_for_embedded = self.lexer
|
lexer_for_embedded = self.lexer
|
||||||
|
|
||||||
embedded = highlight(self.code,
|
embedded = highlight(
|
||||||
get_lexer_by_name(lexer_for_embedded,
|
self.code,
|
||||||
encoding='UTF-8'),
|
get_lexer_by_name(lexer_for_embedded, encoding="UTF-8"),
|
||||||
HtmlFormatter(
|
HtmlFormatter(
|
||||||
style='native',
|
style="native",
|
||||||
noclasses=True,
|
noclasses=True,
|
||||||
prestyles="""
|
prestyles="""
|
||||||
background-color: #1C1C1C;
|
background-color: #1C1C1C;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
color: #D0D0D0;
|
color: #D0D0D0;
|
||||||
|
@ -169,22 +179,25 @@ class Snipt(models.Model):
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
-webkit-border-radius: 5px;
|
-webkit-border-radius: 5px;
|
||||||
-moz-border-radius: 5px;
|
-moz-border-radius: 5px;
|
||||||
"""))
|
""",
|
||||||
embedded = (embedded.replace("\\\"", "\\\\\"")
|
),
|
||||||
.replace('\'', '\\\'')
|
)
|
||||||
.replace("\\", "\\\\")
|
embedded = (
|
||||||
.replace('background: #202020', ''))
|
embedded.replace('\\"', '\\\\"')
|
||||||
|
.replace("'", "\\'")
|
||||||
|
.replace("\\", "\\\\")
|
||||||
|
.replace("background: #202020", "")
|
||||||
|
)
|
||||||
self.embedded = embedded
|
self.embedded = embedded
|
||||||
|
|
||||||
snipt = super(Snipt, self).save(*args, **kwargs)
|
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 != ''):
|
if diff != "":
|
||||||
log_entry = SniptLogEntry(user=self.last_user_saved,
|
log_entry = SniptLogEntry(
|
||||||
snipt=self,
|
user=self.last_user_saved, snipt=self, code=self.code, diff=diff
|
||||||
code=self.code,
|
)
|
||||||
diff=diff)
|
|
||||||
log_entry.save()
|
log_entry.save()
|
||||||
|
|
||||||
return snipt
|
return snipt
|
||||||
|
@ -197,52 +210,52 @@ class Snipt(models.Model):
|
||||||
|
|
||||||
def get_stylized_min(self):
|
def get_stylized_min(self):
|
||||||
if self.stylized_min is None:
|
if self.stylized_min is None:
|
||||||
if self.lexer == 'markdown':
|
if self.lexer == "markdown":
|
||||||
self.stylized_min = markdown(self.code[:1000], 'default')
|
self.stylized_min = markdown(self.code[:1000], "default")
|
||||||
else:
|
else:
|
||||||
self.stylized_min = highlight(
|
self.stylized_min = highlight(
|
||||||
self.code[:1000],
|
self.code[:1000],
|
||||||
get_lexer_by_name(self.lexer, encoding='UTF-8'),
|
get_lexer_by_name(self.lexer, encoding="UTF-8"),
|
||||||
HtmlFormatter(linenos='table',
|
HtmlFormatter(linenos="table", linenospecial=1, lineanchors="line"),
|
||||||
linenospecial=1,
|
)
|
||||||
lineanchors='line'))
|
|
||||||
return self.stylized_min
|
return self.stylized_min
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
|
|
||||||
if self.blog_post:
|
if self.blog_post:
|
||||||
if self.user.profile.blog_domain:
|
if self.user.profile.blog_domain:
|
||||||
return u'http://{}/{}/'.format(
|
return u"http://{}/{}/".format(
|
||||||
self.user.profile.blog_domain.split(' ')[0], self.slug)
|
self.user.profile.blog_domain.split(" ")[0], self.slug
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
return u'https://{}.snippets.siftie.com/{}/'.format(
|
return u"https://{}.snippets.siftie.com/{}/".format(
|
||||||
self.user.username.replace('_', '-'), self.slug)
|
self.user.username.replace("_", "-"), self.slug
|
||||||
|
)
|
||||||
|
|
||||||
if self.custom_slug:
|
if self.custom_slug:
|
||||||
return u'/{}/'.format(self.custom_slug)
|
return u"/{}/".format(self.custom_slug)
|
||||||
|
|
||||||
if self.public:
|
if self.public:
|
||||||
return u'/{}/{}/'.format(self.user.username, self.slug)
|
return u"/{}/{}/".format(self.user.username, self.slug)
|
||||||
else:
|
else:
|
||||||
return u'/{}/{}/?key={}'.format(
|
return u"/{}/{}/?key={}".format(self.user.username, self.slug, self.key)
|
||||||
self.user.username, self.slug, self.key)
|
|
||||||
|
|
||||||
def get_full_absolute_url(self):
|
def get_full_absolute_url(self):
|
||||||
|
|
||||||
if self.blog_post:
|
if self.blog_post:
|
||||||
if self.user.profile.blog_domain:
|
if self.user.profile.blog_domain:
|
||||||
return u'http://{}/{}/'.format(
|
return u"http://{}/{}/".format(
|
||||||
self.user.profile.blog_domain.split(' ')[0], self.slug)
|
self.user.profile.blog_domain.split(" ")[0], self.slug
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
return u'https://{}.snippets.siftie.com/{}/'.format(
|
return u"https://{}.snippets.siftie.com/{}/".format(
|
||||||
self.user.username, self.slug)
|
self.user.username, self.slug
|
||||||
|
)
|
||||||
|
|
||||||
if self.public:
|
if self.public:
|
||||||
return u'/{}/{}/'.format(self.user.username, self.slug)
|
return u"/{}/{}/".format(self.user.username, self.slug)
|
||||||
else:
|
else:
|
||||||
return u'/{}/{}/?key={}'.format(self.user.username,
|
return u"/{}/{}/?key={}".format(self.user.username, self.slug, self.key)
|
||||||
self.slug,
|
|
||||||
self.key)
|
|
||||||
|
|
||||||
def get_download_url(self):
|
def get_download_url(self):
|
||||||
|
|
||||||
|
@ -252,30 +265,30 @@ class Snipt(models.Model):
|
||||||
lexer_obj = None
|
lexer_obj = None
|
||||||
|
|
||||||
if lexer_obj and lexer_obj.filenames:
|
if lexer_obj and lexer_obj.filenames:
|
||||||
filename = lexer_obj.filenames[0].replace('*', self.slug)
|
filename = lexer_obj.filenames[0].replace("*", self.slug)
|
||||||
else:
|
else:
|
||||||
if self.lexer == 'markdown':
|
if self.lexer == "markdown":
|
||||||
filename = u'{}.md'.format(self.slug)
|
filename = u"{}.md".format(self.slug)
|
||||||
else:
|
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):
|
def get_embed_url(self):
|
||||||
|
|
||||||
if settings.DEBUG:
|
if settings.DEBUG:
|
||||||
root = 'http://local.snippets.siftie.com'
|
root = "http://local.snippets.siftie.com"
|
||||||
else:
|
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):
|
def get_raw_url(self):
|
||||||
return '/raw/{}/'.format(self.key)
|
return "/raw/{}/".format(self.key)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def sorted_tags(self):
|
def sorted_tags(self):
|
||||||
return self.tags.all().order_by('name')
|
return self.tags.all().order_by("name")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tags_list(self):
|
def tags_list(self):
|
||||||
|
@ -283,8 +296,8 @@ class Snipt(models.Model):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def lexer_name(self):
|
def lexer_name(self):
|
||||||
if self.lexer == 'markdown':
|
if self.lexer == "markdown":
|
||||||
return 'Markdown'
|
return "Markdown"
|
||||||
else:
|
else:
|
||||||
return get_lexer_by_name(self.lexer).name
|
return get_lexer_by_name(self.lexer).name
|
||||||
|
|
||||||
|
@ -311,7 +324,7 @@ class SniptLogEntry(models.Model):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def snipt_name(self):
|
def snipt_name(self):
|
||||||
return self.snipt.title or 'Untitled'
|
return self.snipt.title or "Untitled"
|
||||||
|
|
||||||
|
|
||||||
class SniptSecureView(models.Model):
|
class SniptSecureView(models.Model):
|
||||||
|
@ -325,7 +338,7 @@ class SniptSecureView(models.Model):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def snipt_name(self):
|
def snipt_name(self):
|
||||||
return self.snipt.title or 'Untitled'
|
return self.snipt.title or "Untitled"
|
||||||
|
|
||||||
|
|
||||||
class Favorite(models.Model):
|
class Favorite(models.Model):
|
||||||
|
@ -336,5 +349,4 @@ class Favorite(models.Model):
|
||||||
modified = models.DateTimeField(auto_now=True, editable=False)
|
modified = models.DateTimeField(auto_now=True, editable=False)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return u'{} favorited by {}'.format(self.snipt.title,
|
return u"{} favorited by {}".format(self.snipt.title, self.user.username)
|
||||||
self.user.username)
|
|
||||||
|
|
|
@ -6,15 +6,14 @@ from snipts.models import Snipt
|
||||||
|
|
||||||
class SniptIndex(indexes.SearchIndex, indexes.Indexable):
|
class SniptIndex(indexes.SearchIndex, indexes.Indexable):
|
||||||
text = indexes.CharField(document=True, use_template=True)
|
text = indexes.CharField(document=True, use_template=True)
|
||||||
author = indexes.CharField(model_attr='user')
|
author = indexes.CharField(model_attr="user")
|
||||||
pub_date = indexes.DateTimeField(model_attr='created')
|
pub_date = indexes.DateTimeField(model_attr="created")
|
||||||
public = indexes.BooleanField(model_attr='public')
|
public = indexes.BooleanField(model_attr="public")
|
||||||
typ = indexes.CharField(model_attr='lexer')
|
typ = indexes.CharField(model_attr="lexer")
|
||||||
|
|
||||||
def get_model(self):
|
def get_model(self):
|
||||||
return Snipt
|
return Snipt
|
||||||
|
|
||||||
def index_queryset(self, **kwargs):
|
def index_queryset(self, **kwargs):
|
||||||
"""Used when the entire index for model is updated."""
|
"""Used when the entire index for model is updated."""
|
||||||
return self.get_model().objects.filter(
|
return self.get_model().objects.filter(created__lte=datetime.datetime.now())
|
||||||
created__lte=datetime.datetime.now())
|
|
||||||
|
|
|
@ -10,11 +10,11 @@ from templatetag_sugar.register import tag
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
@tag(register, [Constant('as'), Variable()])
|
@tag(register, [Constant("as"), Variable()])
|
||||||
def snipt_is_favorited_by_user(context, asvar):
|
def snipt_is_favorited_by_user(context, asvar):
|
||||||
|
|
||||||
user = context['request'].user
|
user = context["request"].user
|
||||||
snipt = context['snipt']
|
snipt = context["snipt"]
|
||||||
|
|
||||||
is_favorited = False
|
is_favorited = False
|
||||||
|
|
||||||
|
@ -27,37 +27,37 @@ def snipt_is_favorited_by_user(context, asvar):
|
||||||
|
|
||||||
context[asvar] = is_favorited
|
context[asvar] = is_favorited
|
||||||
|
|
||||||
return ''
|
return ""
|
||||||
|
|
||||||
|
|
||||||
@tag(register, [])
|
@tag(register, [])
|
||||||
def snipts_count_for_user(context):
|
def snipts_count_for_user(context):
|
||||||
|
|
||||||
user = context['request'].user
|
user = context["request"].user
|
||||||
|
|
||||||
if user.is_authenticated():
|
if user.is_authenticated():
|
||||||
snipts = Snipt.objects.filter(user=user).values('id').count()
|
snipts = Snipt.objects.filter(user=user).values("id").count()
|
||||||
else:
|
else:
|
||||||
snipts = 0
|
snipts = 0
|
||||||
|
|
||||||
return snipts
|
return snipts
|
||||||
|
|
||||||
|
|
||||||
@tag(register, [Constant('as'), Variable()])
|
@tag(register, [Constant("as"), Variable()])
|
||||||
def signup_enabled(context, asvar):
|
def signup_enabled(context, asvar):
|
||||||
context[asvar] = os.environ.get("DISABLE_SIGNUP") != "true"
|
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):
|
def get_lexers(context, asvar):
|
||||||
context[asvar] = get_lexers_list()
|
context[asvar] = get_lexers_list()
|
||||||
return ''
|
return ""
|
||||||
|
|
||||||
|
|
||||||
@tag(register, [Constant('for'), Variable()])
|
@tag(register, [Constant("for"), Variable()])
|
||||||
def generate_line_numbers(context, line_numbers):
|
def generate_line_numbers(context, line_numbers):
|
||||||
html = ''
|
html = ""
|
||||||
|
|
||||||
for i in range(1, line_numbers + 1):
|
for i in range(1, line_numbers + 1):
|
||||||
html = html + '<span class="special">{}</span>'.format(i)
|
html = html + '<span class="special">{}</span>'.format(i)
|
||||||
|
@ -67,7 +67,7 @@ def generate_line_numbers(context, line_numbers):
|
||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def md5(string):
|
def md5(string):
|
||||||
return hashlib.md5(string.lower().encode('utf-8')).hexdigest()
|
return hashlib.md5(string.lower().encode("utf-8")).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
|
|
106
snipts/tests.py
106
snipts/tests.py
|
@ -5,107 +5,113 @@ from tastypie.test import ResourceTestCase
|
||||||
|
|
||||||
|
|
||||||
class SniptResourceTest(ResourceTestCase):
|
class SniptResourceTest(ResourceTestCase):
|
||||||
fixtures = ['test_entries.json']
|
fixtures = ["test_entries.json"]
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(SniptResourceTest, self).setUp()
|
super(SniptResourceTest, self).setUp()
|
||||||
|
|
||||||
# Johnny
|
# Johnny
|
||||||
self.johnny = User.objects.create_user('johnny', 'johnny@siftie.com',
|
self.johnny = User.objects.create_user(
|
||||||
'password')
|
"johnny", "johnny@siftie.com", "password"
|
||||||
|
)
|
||||||
ApiKey.objects.get_or_create(user=self.johnny)
|
ApiKey.objects.get_or_create(user=self.johnny)
|
||||||
self.johnny_auth = self.create_apikey(self.johnny,
|
self.johnny_auth = self.create_apikey(self.johnny, self.johnny.api_key.key)
|
||||||
self.johnny.api_key.key)
|
self.johnny_private = Snipt(
|
||||||
self.johnny_private = Snipt(title='Private snippet for Johnny',
|
title="Private snippet for Johnny",
|
||||||
lexer='text',
|
lexer="text",
|
||||||
public=False,
|
public=False,
|
||||||
user=self.johnny)
|
user=self.johnny,
|
||||||
self.johnny_public = Snipt(title='Public snippet for Johnny',
|
)
|
||||||
lexer='text',
|
self.johnny_public = Snipt(
|
||||||
public=True,
|
title="Public snippet for Johnny",
|
||||||
user=self.johnny)
|
lexer="text",
|
||||||
|
public=True,
|
||||||
|
user=self.johnny,
|
||||||
|
)
|
||||||
self.johnny_private.save()
|
self.johnny_private.save()
|
||||||
self.johnny_public.save()
|
self.johnny_public.save()
|
||||||
|
|
||||||
# Bob
|
# 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)
|
ApiKey.objects.get_or_create(user=self.bob)
|
||||||
self.bob_auth = self.create_apikey(self.bob, self.bob.api_key.key)
|
self.bob_auth = self.create_apikey(self.bob, self.bob.api_key.key)
|
||||||
self.bob_private = Snipt(title='Private snippet for Bob',
|
self.bob_private = Snipt(
|
||||||
lexer='text',
|
title="Private snippet for Bob", lexer="text", public=False, user=self.bob
|
||||||
public=False,
|
)
|
||||||
user=self.bob)
|
self.bob_public = Snipt(
|
||||||
self.bob_public = Snipt(title='Public snippet for Bob',
|
title="Public snippet for Bob", lexer="text", public=True, user=self.bob
|
||||||
lexer='text',
|
)
|
||||||
public=True,
|
|
||||||
user=self.bob)
|
|
||||||
self.bob_private.save()
|
self.bob_private.save()
|
||||||
self.bob_public.save()
|
self.bob_public.save()
|
||||||
|
|
||||||
def test_get_private_list(self):
|
def test_get_private_list(self):
|
||||||
|
|
||||||
resp = self.api_client.get('/api/private/snipt/', format='json',
|
resp = self.api_client.get(
|
||||||
authentication=self.johnny_auth)
|
"/api/private/snipt/", format="json", authentication=self.johnny_auth
|
||||||
|
)
|
||||||
|
|
||||||
self.assertHttpOK(resp)
|
self.assertHttpOK(resp)
|
||||||
self.assertValidJSONResponse(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):
|
def test_get_private_detail(self):
|
||||||
|
|
||||||
resp = self.api_client.get(
|
resp = self.api_client.get(
|
||||||
'/api/private/snipt/{}/'.format(self.johnny_private.pk),
|
"/api/private/snipt/{}/".format(self.johnny_private.pk),
|
||||||
format='json',
|
format="json",
|
||||||
authentication=self.johnny_auth)
|
authentication=self.johnny_auth,
|
||||||
|
)
|
||||||
|
|
||||||
self.assertHttpOK(resp)
|
self.assertHttpOK(resp)
|
||||||
self.assertValidJSONResponse(resp)
|
self.assertValidJSONResponse(resp)
|
||||||
self.assertEqual(self.deserialize(resp)['key'],
|
self.assertEqual(self.deserialize(resp)["key"], self.johnny_private.key)
|
||||||
self.johnny_private.key)
|
|
||||||
|
|
||||||
# Unauthenticated request.
|
# Unauthenticated request.
|
||||||
resp = self.api_client.get(
|
resp = self.api_client.get(
|
||||||
'/api/private/snipt/{}/'.format(self.johnny_private.pk),
|
"/api/private/snipt/{}/".format(self.johnny_private.pk), format="json"
|
||||||
format='json')
|
)
|
||||||
self.assertHttpUnauthorized(resp)
|
self.assertHttpUnauthorized(resp)
|
||||||
|
|
||||||
# Unauthorized request.
|
# Unauthorized request.
|
||||||
resp = self.api_client.get(
|
resp = self.api_client.get(
|
||||||
'/api/private/snipt/{}/'.format(self.johnny_private.pk),
|
"/api/private/snipt/{}/".format(self.johnny_private.pk),
|
||||||
format='json',
|
format="json",
|
||||||
authentication=self.bob_auth)
|
authentication=self.bob_auth,
|
||||||
|
)
|
||||||
self.assertHttpUnauthorized(resp)
|
self.assertHttpUnauthorized(resp)
|
||||||
|
|
||||||
def test_post_private_list(self):
|
def test_post_private_list(self):
|
||||||
|
|
||||||
new_snipt = {
|
new_snipt = {
|
||||||
'title': 'A new private snippet.',
|
"title": "A new private snippet.",
|
||||||
'lexer': 'text',
|
"lexer": "text",
|
||||||
'public': False,
|
"public": False,
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = self.api_client.post('/api/private/snipt/',
|
resp = self.api_client.post(
|
||||||
data=new_snipt,
|
"/api/private/snipt/",
|
||||||
format='json',
|
data=new_snipt,
|
||||||
authentication=self.johnny_auth)
|
format="json",
|
||||||
|
authentication=self.johnny_auth,
|
||||||
|
)
|
||||||
|
|
||||||
self.assertHttpCreated(resp)
|
self.assertHttpCreated(resp)
|
||||||
self.assertEqual(Snipt.objects.count(), 5)
|
self.assertEqual(Snipt.objects.count(), 5)
|
||||||
|
|
||||||
resp = self.api_client.get('/api/private/snipt/',
|
resp = self.api_client.get(
|
||||||
format='json',
|
"/api/private/snipt/", format="json", authentication=self.johnny_auth
|
||||||
authentication=self.johnny_auth)
|
)
|
||||||
self.assertEqual(len(self.deserialize(resp)['objects']), 3)
|
self.assertEqual(len(self.deserialize(resp)["objects"]), 3)
|
||||||
|
|
||||||
resp = self.api_client.get('/api/public/snipt/', format='json')
|
resp = self.api_client.get("/api/public/snipt/", format="json")
|
||||||
self.assertEqual(len(self.deserialize(resp)['objects']), 2)
|
self.assertEqual(len(self.deserialize(resp)["objects"]), 2)
|
||||||
|
|
||||||
def test_get_public_list(self):
|
def test_get_public_list(self):
|
||||||
|
|
||||||
self.assertEqual(Snipt.objects.count(), 4)
|
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.assertHttpOK(resp)
|
||||||
self.assertValidJSONResponse(resp)
|
self.assertValidJSONResponse(resp)
|
||||||
self.assertEqual(len(self.deserialize(resp)['objects']), 2)
|
self.assertEqual(len(self.deserialize(resp)["objects"]), 2)
|
||||||
|
|
|
@ -3,45 +3,36 @@ from snipts import views
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^s/(?P<snipt_key>[^/]+)/(?P<lexer>[^\?]+)?$',
|
url(
|
||||||
views.redirect_snipt, name='redirect-snipt'),
|
r"^s/(?P<snipt_key>[^/]+)/(?P<lexer>[^\?]+)?$",
|
||||||
url(r'^(?P<username>[^/]+)/feed/$',
|
views.redirect_snipt,
|
||||||
views.redirect_user_feed,
|
name="redirect-snipt",
|
||||||
name='redirect-feed'),
|
),
|
||||||
url(r'^public/tag/(?P<tag_slug>[^/]+)/feed/$',
|
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,
|
views.redirect_public_tag_feed,
|
||||||
name='redirect-public-tag-feed'),
|
name="redirect-public-tag-feed",
|
||||||
url(r'^(?P<username>[^/]+)/tag/(?P<tag_slug>[^/]+)/feed/$',
|
),
|
||||||
|
url(
|
||||||
|
r"^(?P<username>[^/]+)/tag/(?P<tag_slug>[^/]+)/feed/$",
|
||||||
views.redirect_user_tag_feed,
|
views.redirect_user_tag_feed,
|
||||||
name='redirect-user-tag-feed'),
|
name="redirect-user-tag-feed",
|
||||||
url(r'^public/$',
|
),
|
||||||
views.list_public,
|
url(r"^public/$", views.list_public, name="list-public"),
|
||||||
name='list-public'),
|
url(
|
||||||
url(r'^public/tag/(?P<tag_slug>[^/]+)/$',
|
r"^public/tag/(?P<tag_slug>[^/]+)/$", views.list_public, name="list-public-tag"
|
||||||
views.list_public,
|
),
|
||||||
name='list-public-tag'),
|
url(r"^download/(?P<snipt_key>[^/]+).*$", views.download, name="download"),
|
||||||
url(r'^download/(?P<snipt_key>[^/]+).*$',
|
url(r"^embed/(?P<snipt_key>[^/]+)/$", views.embed, name="embed"),
|
||||||
views.download,
|
url(r"^raw/(?P<snipt_key>[^/]+)/(?P<lexer>[^\?]+)?$", views.raw, name="raw"),
|
||||||
name='download'),
|
url(r"^(?P<username_or_custom_slug>[^/]+)/$", views.list_user, name="list-user"),
|
||||||
url(r'^embed/(?P<snipt_key>[^/]+)/$',
|
url(
|
||||||
views.embed,
|
r"^(?P<username_or_custom_slug>[^/]+)/tag/(?P<tag_slug>[^/]+)/$",
|
||||||
name='embed'),
|
|
||||||
url(r'^raw/(?P<snipt_key>[^/]+)/(?P<lexer>[^\?]+)?$',
|
|
||||||
views.raw,
|
|
||||||
name='raw'),
|
|
||||||
url(r'^(?P<username_or_custom_slug>[^/]+)/$',
|
|
||||||
views.list_user,
|
views.list_user,
|
||||||
name='list-user'),
|
name="list-user-tag",
|
||||||
url(r'^(?P<username_or_custom_slug>[^/]+)/tag/(?P<tag_slug>[^/]+)/$',
|
),
|
||||||
views.list_user,
|
url(r"^(?P<username>[^/]+)/favorites/$", views.favorites, name="favorites"),
|
||||||
name='list-user-tag'),
|
url(r"^(?P<username>[^/]+)/blog-posts/$", views.blog_posts, name="blog-posts"),
|
||||||
url(r'^(?P<username>[^/]+)/favorites/$',
|
url(r"^(?P<username>[^/]+)/(?P<snipt_slug>[^/]+)/$", views.detail, name="detail"),
|
||||||
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')
|
|
||||||
]
|
|
||||||
|
|
|
@ -18,12 +18,13 @@ def slugify_uniquely(value, model, slugfield="slug"):
|
||||||
potential = str(suffix)
|
potential = str(suffix)
|
||||||
if not model.objects.filter(**{slugfield: potential}).count():
|
if not model.objects.filter(**{slugfield: potential}).count():
|
||||||
return potential
|
return potential
|
||||||
suffix = str(uuid.uuid4()).split('-')[0]
|
suffix = str(uuid.uuid4()).split("-")[0]
|
||||||
|
|
||||||
|
|
||||||
def activate_user(user, request, **kwargs):
|
def activate_user(user, request, **kwargs):
|
||||||
user = authenticate(username=request.POST['username'],
|
user = authenticate(
|
||||||
password=request.POST['password1'])
|
username=request.POST["username"], password=request.POST["password1"]
|
||||||
|
)
|
||||||
login(request, user)
|
login(request, user)
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,12 +32,13 @@ def get_lexers_list():
|
||||||
lexers = list(get_all_lexers())
|
lexers = list(get_all_lexers())
|
||||||
|
|
||||||
for l in lexers:
|
for l in lexers:
|
||||||
if l[0] == 'ANTLR With Java Target':
|
if l[0] == "ANTLR With Java Target":
|
||||||
lexers.remove(l)
|
lexers.remove(l)
|
||||||
|
|
||||||
lexers.append(('Markdown', ('markdown',),))
|
lexers.append(("Markdown", ("markdown",)))
|
||||||
lexers = sorted(lexers)
|
lexers = sorted(lexers)
|
||||||
|
|
||||||
return lexers
|
return lexers
|
||||||
|
|
||||||
|
|
||||||
user_registered.connect(activate_user)
|
user_registered.connect(activate_user)
|
||||||
|
|
260
snipts/views.py
260
snipts/views.py
|
@ -7,7 +7,12 @@ from django.core.mail import send_mail
|
||||||
from django.core.paginator import Paginator, InvalidPage
|
from django.core.paginator import Paginator, InvalidPage
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
from django.db.models import Q
|
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.shortcuts import get_object_or_404, render
|
||||||
from django.template import RequestContext
|
from django.template import RequestContext
|
||||||
from django.views.decorators.cache import never_cache
|
from django.views.decorators.cache import never_cache
|
||||||
|
@ -21,25 +26,25 @@ from teams.models import Team
|
||||||
import os
|
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):
|
def detail(request, username, snipt_slug):
|
||||||
|
|
||||||
snipt = get_object_or_404(Snipt, user__username=username, slug=snipt_slug)
|
snipt = get_object_or_404(Snipt, user__username=username, slug=snipt_slug)
|
||||||
user = snipt.user
|
user = snipt.user
|
||||||
|
|
||||||
if snipt.lexer != 'markdown':
|
if snipt.lexer != "markdown":
|
||||||
if 'linenos' not in snipt.stylized:
|
if "linenos" not in snipt.stylized:
|
||||||
snipt.save()
|
snipt.save()
|
||||||
|
|
||||||
if user != request.user:
|
if user != request.user:
|
||||||
if not snipt.public:
|
if not snipt.public:
|
||||||
if 'key' not in request.GET:
|
if "key" not in request.GET:
|
||||||
raise Http404
|
raise Http404
|
||||||
else:
|
else:
|
||||||
if request.GET.get('key') != snipt.key:
|
if request.GET.get("key") != snipt.key:
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
if snipt.secure and not request.user.is_authenticated():
|
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)
|
tags = tags.filter(snipt__user=user, snipt__public=True)
|
||||||
public = True
|
public = True
|
||||||
|
|
||||||
tags = tags.annotate(count=Count('taggit_taggeditem_items__id'))
|
tags = tags.annotate(count=Count("taggit_taggeditem_items__id"))
|
||||||
tags = tags.order_by('-count', 'name')
|
tags = tags.order_by("-count", "name")
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'detail': True,
|
"detail": True,
|
||||||
'has_snipts': True,
|
"has_snipts": True,
|
||||||
'public': public,
|
"public": public,
|
||||||
'snipt': snipt,
|
"snipt": snipt,
|
||||||
'tags': tags,
|
"tags": tags,
|
||||||
'user': user,
|
"user": user,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def download(request, snipt_key):
|
def download(request, snipt_key):
|
||||||
snipt = get_object_or_404(Snipt, key=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):
|
def embed(request, snipt_key):
|
||||||
snipt = get_object_or_404(Snipt, key=snipt_key)
|
snipt = get_object_or_404(Snipt, key=snipt_key)
|
||||||
|
|
||||||
lines = snipt.embedded.split('\n')
|
lines = snipt.embedded.split("\n")
|
||||||
return render(request,
|
return render(
|
||||||
'snipts/embed.html',
|
request,
|
||||||
{'lines': lines, 'snipt': snipt},
|
"snipts/embed.html",
|
||||||
content_type='application/javascript')
|
{"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):
|
def blog_posts(request, username):
|
||||||
|
|
||||||
if request.blog_user:
|
if request.blog_user:
|
||||||
|
@ -106,29 +113,28 @@ def blog_posts(request, username):
|
||||||
public_user = True
|
public_user = True
|
||||||
user = get_object_or_404(User, username=username)
|
user = get_object_or_404(User, username=username)
|
||||||
snipts = Snipt.objects.filter(blog_post=True, user=user, public=True)
|
snipts = Snipt.objects.filter(blog_post=True, user=user, public=True)
|
||||||
tags = Tag.objects.filter(snipt__user=user,
|
tags = Tag.objects.filter(snipt__user=user, snipt__public=True).distinct()
|
||||||
snipt__public=True).distinct()
|
|
||||||
|
|
||||||
tags = tags.order_by('name')
|
tags = tags.order_by("name")
|
||||||
snipts = snipts.order_by('-created')
|
snipts = snipts.order_by("-created")
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'has_snipts': True,
|
"has_snipts": True,
|
||||||
'public': public,
|
"public": public,
|
||||||
'public_user': public_user,
|
"public_user": public_user,
|
||||||
'snipts': snipts,
|
"snipts": snipts,
|
||||||
'tags': tags,
|
"tags": tags,
|
||||||
'user': user,
|
"user": user,
|
||||||
}
|
}
|
||||||
|
|
||||||
if 'rss' in request.GET:
|
if "rss" in request.GET:
|
||||||
context['snipts'] = context['snipts'][:20]
|
context["snipts"] = context["snipts"][:20]
|
||||||
return rss(request, context)
|
return rss(request, context)
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
@render_to('snipts/list-user.html')
|
@render_to("snipts/list-user.html")
|
||||||
def favorites(request, username):
|
def favorites(request, username):
|
||||||
|
|
||||||
if request.user.username != username:
|
if request.user.username != username:
|
||||||
|
@ -139,39 +145,39 @@ def favorites(request, username):
|
||||||
|
|
||||||
public = False
|
public = False
|
||||||
|
|
||||||
favorites = Favorite.objects.filter(user=request.user).values('snipt')
|
favorites = Favorite.objects.filter(user=request.user).values("snipt")
|
||||||
favorites = [f['snipt'] for f in favorites]
|
favorites = [f["snipt"] for f in favorites]
|
||||||
snipts = Snipt.objects.filter(Q(pk__in=favorites))
|
snipts = Snipt.objects.filter(Q(pk__in=favorites))
|
||||||
|
|
||||||
tags = Tag.objects.filter(snipt__user=request.user).distinct()
|
tags = Tag.objects.filter(snipt__user=request.user).distinct()
|
||||||
|
|
||||||
tags = tags.order_by('name')
|
tags = tags.order_by("name")
|
||||||
snipts = snipts.order_by('-created')
|
snipts = snipts.order_by("-created")
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'favorites': favorites,
|
"favorites": favorites,
|
||||||
'has_snipts': True,
|
"has_snipts": True,
|
||||||
'public': public,
|
"public": public,
|
||||||
'public_user': False,
|
"public_user": False,
|
||||||
'snipts': snipts,
|
"snipts": snipts,
|
||||||
'tags': tags,
|
"tags": tags,
|
||||||
'user': request.user,
|
"user": request.user,
|
||||||
}
|
}
|
||||||
|
|
||||||
if 'rss' in request.GET:
|
if "rss" in request.GET:
|
||||||
context['snipts'] = context['snipts'][:20]
|
context["snipts"] = context["snipts"][:20]
|
||||||
return rss(request, context)
|
return rss(request, context)
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
@render_to('snipts/list-public.html')
|
@render_to("snipts/list-public.html")
|
||||||
def list_public(request, tag_slug=None):
|
def list_public(request, tag_slug=None):
|
||||||
|
|
||||||
if request.blog_user:
|
if request.blog_user:
|
||||||
return blog_list(request)
|
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:
|
if tag_slug:
|
||||||
snipts = snipts.filter(tags__slug__in=[tag_slug])
|
snipts = snipts.filter(tags__slug__in=[tag_slug])
|
||||||
|
@ -179,21 +185,16 @@ def list_public(request, tag_slug=None):
|
||||||
else:
|
else:
|
||||||
tag = None
|
tag = None
|
||||||
|
|
||||||
context = {
|
context = {"has_snipts": True, "public": True, "snipts": snipts, "tag": tag}
|
||||||
'has_snipts': True,
|
|
||||||
'public': True,
|
|
||||||
'snipts': snipts,
|
|
||||||
'tag': tag,
|
|
||||||
}
|
|
||||||
|
|
||||||
if 'rss' in request.GET:
|
if "rss" in request.GET:
|
||||||
context['snipts'] = context['snipts'][:20]
|
context["snipts"] = context["snipts"][:20]
|
||||||
return rss(request, context)
|
return rss(request, context)
|
||||||
|
|
||||||
return 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):
|
def list_user(request, username_or_custom_slug, tag_slug=None):
|
||||||
|
|
||||||
if request.blog_user:
|
if request.blog_user:
|
||||||
|
@ -208,15 +209,16 @@ def list_user(request, username_or_custom_slug, tag_slug=None):
|
||||||
tags = Tag.objects
|
tags = Tag.objects
|
||||||
snipts = Snipt.objects
|
snipts = Snipt.objects
|
||||||
|
|
||||||
if user == request.user or \
|
if (
|
||||||
(request.GET.get('api_key') == user.api_key.key) or \
|
user == request.user
|
||||||
(user.profile.is_a_team and
|
or (request.GET.get("api_key") == user.api_key.key)
|
||||||
user.team.user_is_member(request.user)):
|
or (user.profile.is_a_team and user.team.user_is_member(request.user))
|
||||||
|
):
|
||||||
|
|
||||||
public = False
|
public = False
|
||||||
|
|
||||||
favorites = Favorite.objects.filter(user=user).values('snipt')
|
favorites = Favorite.objects.filter(user=user).values("snipt")
|
||||||
favorites = [f['snipt'] for f in favorites]
|
favorites = [f["snipt"] for f in favorites]
|
||||||
snipts = snipts.filter(Q(user=user) | Q(pk__in=favorites))
|
snipts = snipts.filter(Q(user=user) | Q(pk__in=favorites))
|
||||||
|
|
||||||
tags = tags.filter(snipt__user=user).distinct()
|
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)
|
snipts = snipts.filter(user=user, public=True)
|
||||||
public = True
|
public = True
|
||||||
|
|
||||||
tags = tags.order_by('name')
|
tags = tags.order_by("name")
|
||||||
snipts = snipts.order_by('-created')
|
snipts = snipts.order_by("-created")
|
||||||
|
|
||||||
if tag_slug:
|
if tag_slug:
|
||||||
snipts = snipts.filter(tags__slug__in=[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
|
tag = None
|
||||||
|
|
||||||
if tag is None:
|
if tag is None:
|
||||||
snipts = snipts.exclude(tags__name__in=['tmp'])
|
snipts = snipts.exclude(tags__name__in=["tmp"])
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'has_snipts': True,
|
"has_snipts": True,
|
||||||
'public': public,
|
"public": public,
|
||||||
'public_user': (public and user),
|
"public_user": (public and user),
|
||||||
'snipts': snipts,
|
"snipts": snipts,
|
||||||
'tags': tags,
|
"tags": tags,
|
||||||
'tag': tag,
|
"tag": tag,
|
||||||
'user': user,
|
"user": user,
|
||||||
'users_for_full_page': ['robertbanh'],
|
"users_for_full_page": ["robertbanh"],
|
||||||
}
|
}
|
||||||
|
|
||||||
if 'rss' in request.GET:
|
if "rss" in request.GET:
|
||||||
context['snipts'] = context['snipts'][:20]
|
context["snipts"] = context["snipts"][:20]
|
||||||
return rss(request, context)
|
return rss(request, context)
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
@ -261,7 +263,7 @@ def raw(request, snipt_key, lexer=None):
|
||||||
|
|
||||||
if request.user == snipt.user:
|
if request.user == snipt.user:
|
||||||
if lexer:
|
if lexer:
|
||||||
lexer = lexer.strip('/')
|
lexer = lexer.strip("/")
|
||||||
|
|
||||||
if lexer != snipt.lexer:
|
if lexer != snipt.lexer:
|
||||||
|
|
||||||
|
@ -274,67 +276,73 @@ def raw(request, snipt_key, lexer=None):
|
||||||
snipt.lexer = lexer
|
snipt.lexer = lexer
|
||||||
snipt.save()
|
snipt.save()
|
||||||
|
|
||||||
content_type = 'text/plain'
|
content_type = "text/plain"
|
||||||
|
|
||||||
if 'nice' in request.GET:
|
if "nice" in request.GET:
|
||||||
content_type = 'text/html'
|
content_type = "text/html"
|
||||||
|
|
||||||
return render(request,
|
return render(
|
||||||
'snipts/raw.html',
|
request, "snipts/raw.html", {"snipt": snipt}, content_type=content_type
|
||||||
{'snipt': snipt},
|
)
|
||||||
content_type=content_type)
|
|
||||||
|
|
||||||
|
|
||||||
def rss(request, context):
|
def rss(request, context):
|
||||||
return render(request,
|
return render(request, "rss.xml", context, content_type="application/rss+xml")
|
||||||
'rss.xml',
|
|
||||||
context,
|
|
||||||
content_type="application/rss+xml")
|
|
||||||
|
|
||||||
|
|
||||||
@never_cache
|
@never_cache
|
||||||
def search(request, template='search/search.html', load_all=True,
|
def search(
|
||||||
form_class=ModelSearchForm, searchqueryset=None,
|
request,
|
||||||
context_class=RequestContext, extra_context=None,
|
template="search/search.html",
|
||||||
results_per_page=None):
|
load_all=True,
|
||||||
|
form_class=ModelSearchForm,
|
||||||
|
searchqueryset=None,
|
||||||
|
context_class=RequestContext,
|
||||||
|
extra_context=None,
|
||||||
|
results_per_page=None,
|
||||||
|
):
|
||||||
|
|
||||||
query = ''
|
query = ""
|
||||||
results = EmptySearchQuerySet()
|
results = EmptySearchQuerySet()
|
||||||
|
|
||||||
if request.GET.get('q'):
|
if request.GET.get("q"):
|
||||||
|
|
||||||
searchqueryset = SearchQuerySet() \
|
searchqueryset = (
|
||||||
.filter(Q(public=True) | Q(author=request.user)) \
|
SearchQuerySet()
|
||||||
.order_by('-pub_date')
|
.filter(Q(public=True) | Q(author=request.user))
|
||||||
|
.order_by("-pub_date")
|
||||||
|
)
|
||||||
|
|
||||||
if request.user.is_authenticated() and \
|
if request.user.is_authenticated() and "mine-only" in request.GET:
|
||||||
'mine-only' in request.GET:
|
searchqueryset = (
|
||||||
searchqueryset = SearchQuerySet().filter(author=request.user) \
|
SearchQuerySet().filter(author=request.user).order_by("-pub_date")
|
||||||
.order_by('-pub_date')
|
)
|
||||||
|
|
||||||
elif request.user.is_authenticated() and \
|
elif request.user.is_authenticated() and (
|
||||||
('author' in request.GET and
|
"author" in request.GET and request.GET.get("author")
|
||||||
request.GET.get('author')):
|
):
|
||||||
|
|
||||||
author = request.GET.get('author')
|
author = request.GET.get("author")
|
||||||
|
|
||||||
if author == request.user.username:
|
if author == request.user.username:
|
||||||
searchqueryset = SearchQuerySet().filter(author=request.user) \
|
searchqueryset = (
|
||||||
.order_by('-pub_date')
|
SearchQuerySet().filter(author=request.user).order_by("-pub_date")
|
||||||
|
)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
team = get_object_or_None(Team, slug=author)
|
team = get_object_or_None(Team, slug=author)
|
||||||
|
|
||||||
if team and team.user_is_member(request.user):
|
if team and team.user_is_member(request.user):
|
||||||
searchqueryset = SearchQuerySet().filter(author=team) \
|
searchqueryset = (
|
||||||
.order_by('-pub_date')
|
SearchQuerySet().filter(author=team).order_by("-pub_date")
|
||||||
|
)
|
||||||
|
|
||||||
form = ModelSearchForm(request.GET,
|
form = ModelSearchForm(
|
||||||
searchqueryset=searchqueryset,
|
request.GET, searchqueryset=searchqueryset, load_all=load_all
|
||||||
load_all=load_all)
|
)
|
||||||
|
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
query = form.cleaned_data['q']
|
query = form.cleaned_data["q"]
|
||||||
results = form.search()
|
results = form.search()
|
||||||
else:
|
else:
|
||||||
form = form_class(searchqueryset=searchqueryset, load_all=load_all)
|
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)
|
paginator = Paginator(results, results_per_page or RESULTS_PER_PAGE)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
page = paginator.page(int(request.GET.get('page', 1)))
|
page = paginator.page(int(request.GET.get("page", 1)))
|
||||||
except InvalidPage:
|
except InvalidPage:
|
||||||
raise Http404("No such page of results!")
|
raise Http404("No such page of results!")
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'form': form,
|
"form": form,
|
||||||
'has_snipts': True,
|
"has_snipts": True,
|
||||||
'page': page,
|
"page": page,
|
||||||
'paginator': paginator,
|
"paginator": paginator,
|
||||||
'query': query,
|
"query": query,
|
||||||
'suggestion': None,
|
"suggestion": None,
|
||||||
}
|
}
|
||||||
|
|
||||||
if results.query.backend.include_spelling:
|
if results.query.backend.include_spelling:
|
||||||
context['suggestion'] = form.get_suggestion()
|
context["suggestion"] = form.get_suggestion()
|
||||||
|
|
||||||
if extra_context:
|
if extra_context:
|
||||||
context.update(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):
|
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):
|
def redirect_user_feed(request, username):
|
||||||
user = get_object_or_404(User, username=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):
|
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))
|
||||||
|
|
|
@ -3,7 +3,8 @@ from teams.models import Team
|
||||||
|
|
||||||
|
|
||||||
class TeamAdmin(admin.ModelAdmin):
|
class TeamAdmin(admin.ModelAdmin):
|
||||||
list_display = ('name', 'owner', 'created', 'modified')
|
list_display = ("name", "owner", "created", "modified")
|
||||||
ordering = ('-created',)
|
ordering = ("-created",)
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(Team, TeamAdmin)
|
admin.site.register(Team, TeamAdmin)
|
||||||
|
|
|
@ -7,22 +7,38 @@ from django.conf import settings
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [migrations.swappable_dependency(settings.AUTH_USER_MODEL)]
|
||||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='Team',
|
name="Team",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
(
|
||||||
('name', models.CharField(max_length=255)),
|
"id",
|
||||||
('slug', models.SlugField(max_length=255, blank=True)),
|
models.AutoField(
|
||||||
('created', models.DateTimeField(auto_now_add=True)),
|
verbose_name="ID",
|
||||||
('modified', models.DateTimeField(auto_now=True)),
|
serialize=False,
|
||||||
('members', models.ManyToManyField(related_name='member', to=settings.AUTH_USER_MODEL)),
|
auto_created=True,
|
||||||
('owner', models.ForeignKey(related_name='owner', to=settings.AUTH_USER_MODEL)),
|
primary_key=True,
|
||||||
('user', models.OneToOneField(to=settings.AUTH_USER_MODEL)),
|
),
|
||||||
|
),
|
||||||
|
("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)),
|
||||||
],
|
],
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,15 +6,13 @@ from django.db import models, migrations
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("teams", "0001_initial")]
|
||||||
('teams', '0001_initial'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='team',
|
model_name="team",
|
||||||
name='email',
|
name="email",
|
||||||
field=models.EmailField(default='nick@siftie.com', max_length=255),
|
field=models.EmailField(default="nick@siftie.com", max_length=255),
|
||||||
preserve_default=False,
|
preserve_default=False,
|
||||||
),
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,14 @@ from django.conf import settings
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("teams", "0002_team_email")]
|
||||||
('teams', '0002_team_email'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='team',
|
model_name="team",
|
||||||
name='user',
|
name="user",
|
||||||
field=models.OneToOneField(null=True, blank=True, to=settings.AUTH_USER_MODEL),
|
field=models.OneToOneField(
|
||||||
),
|
null=True, blank=True, to=settings.AUTH_USER_MODEL
|
||||||
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -7,14 +7,14 @@ from django.conf import settings
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("teams", "0003_auto_20150818_0057")]
|
||||||
('teams', '0003_auto_20150818_0057'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='team',
|
model_name="team",
|
||||||
name='members',
|
name="members",
|
||||||
field=models.ManyToManyField(related_name='member', to=settings.AUTH_USER_MODEL, blank=True),
|
field=models.ManyToManyField(
|
||||||
),
|
related_name="member", to=settings.AUTH_USER_MODEL, blank=True
|
||||||
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,19 +6,15 @@ from django.db import models, migrations
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("teams", "0004_auto_20150930_1526")]
|
||||||
('teams', '0004_auto_20150930_1526'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='team',
|
model_name="team",
|
||||||
name='stripe_id',
|
name="stripe_id",
|
||||||
field=models.CharField(max_length=100, null=True, blank=True),
|
field=models.CharField(max_length=100, null=True, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='team',
|
model_name="team", name="name", field=models.CharField(max_length=30)
|
||||||
name='name',
|
|
||||||
field=models.CharField(max_length=30),
|
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,14 +6,25 @@ from django.db import models, migrations
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("teams", "0005_auto_20150930_2124")]
|
||||||
('teams', '0005_auto_20150930_2124'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='team',
|
model_name="team",
|
||||||
name='plan',
|
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')]),
|
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"),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,14 +6,10 @@ from django.db import models, migrations
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("teams", "0006_team_plan")]
|
||||||
('teams', '0006_team_plan'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='team',
|
model_name="team", name="disabled", field=models.BooleanField(default=False)
|
||||||
name='disabled',
|
)
|
||||||
field=models.BooleanField(default=False),
|
|
||||||
),
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,14 +6,27 @@ from django.db import models, migrations
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("teams", "0007_team_disabled")]
|
||||||
('teams', '0007_team_disabled'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='team',
|
model_name="team",
|
||||||
name='plan',
|
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')]),
|
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"),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,14 +6,27 @@ from django.db import models, migrations
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [("teams", "0008_auto_20151018_2053")]
|
||||||
('teams', '0008_auto_20151018_2053'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='team',
|
model_name="team",
|
||||||
name='plan',
|
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'),
|
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",
|
||||||
|
),
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,25 +6,32 @@ from snipts.utils import slugify_uniquely
|
||||||
class Team(models.Model):
|
class Team(models.Model):
|
||||||
|
|
||||||
PLANS = (
|
PLANS = (
|
||||||
('snipt-teams-25-monthly', '25 users, monthly'),
|
("snipt-teams-25-monthly", "25 users, monthly"),
|
||||||
('snipt-teams-100-monthly', '100 users, monthly'),
|
("snipt-teams-100-monthly", "100 users, monthly"),
|
||||||
('snipt-teams-250-monthly', '250 users, monthly'),
|
("snipt-teams-250-monthly", "250 users, monthly"),
|
||||||
('snipt-teams-unlimited-monthly', 'Unlimited users, monthly'),
|
("snipt-teams-unlimited-monthly", "Unlimited users, monthly"),
|
||||||
('snipt-teams-25-yearly', '25 users, yearly'),
|
("snipt-teams-25-yearly", "25 users, yearly"),
|
||||||
('snipt-teams-100-yearly', '100 users, yearly'),
|
("snipt-teams-100-yearly", "100 users, yearly"),
|
||||||
('snipt-teams-250-yearly', '250 users, yearly'),
|
("snipt-teams-250-yearly", "250 users, yearly"),
|
||||||
('snipt-teams-unlimited-yearly', 'Unlimited users, yearly'),
|
("snipt-teams-unlimited-yearly", "Unlimited users, yearly"),
|
||||||
)
|
)
|
||||||
|
|
||||||
email = models.EmailField(max_length=255)
|
email = models.EmailField(max_length=255)
|
||||||
members = models.ManyToManyField(User, related_name='member', blank=True)
|
members = models.ManyToManyField(User, related_name="member", blank=True)
|
||||||
name = models.CharField(max_length=30)
|
name = models.CharField(max_length=30)
|
||||||
owner = models.ForeignKey(User, related_name='owner', on_delete=models.DO_NOTHING)
|
owner = models.ForeignKey(User, related_name="owner", on_delete=models.DO_NOTHING)
|
||||||
slug = models.SlugField(max_length=255, blank=True)
|
slug = models.SlugField(max_length=255, blank=True)
|
||||||
stripe_id = models.CharField(max_length=100, null=True, blank=True)
|
stripe_id = models.CharField(max_length=100, null=True, blank=True)
|
||||||
user = models.OneToOneField(User, blank=True, null=True, on_delete=models.DO_NOTHING)
|
user = models.OneToOneField(
|
||||||
plan = models.CharField(max_length=100, default='snipt-teams-25-monthly',
|
User, blank=True, null=True, on_delete=models.DO_NOTHING
|
||||||
choices=PLANS, blank=True, null=True)
|
)
|
||||||
|
plan = models.CharField(
|
||||||
|
max_length=100,
|
||||||
|
default="snipt-teams-25-monthly",
|
||||||
|
choices=PLANS,
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
)
|
||||||
disabled = models.BooleanField(default=False)
|
disabled = models.BooleanField(default=False)
|
||||||
|
|
||||||
created = models.DateTimeField(auto_now_add=True, editable=False)
|
created = models.DateTimeField(auto_now_add=True, editable=False)
|
||||||
|
@ -32,7 +39,7 @@ class Team(models.Model):
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
if not self.slug:
|
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)
|
return super(Team, self).save(*args, **kwargs)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
|
@ -49,18 +56,18 @@ class Team(models.Model):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
plan_map = {
|
plan_map = {
|
||||||
'snipt-teams-25-monthly': 25,
|
"snipt-teams-25-monthly": 25,
|
||||||
'snipt-teams-100-monthly': 100,
|
"snipt-teams-100-monthly": 100,
|
||||||
'snipt-teams-250-monthly': 250,
|
"snipt-teams-250-monthly": 250,
|
||||||
'snipt-teams-unlimited-monthly': float('inf'),
|
"snipt-teams-unlimited-monthly": float("inf"),
|
||||||
'snipt-teams-25-yearly': 25,
|
"snipt-teams-25-yearly": 25,
|
||||||
'snipt-teams-100-yearly': 100,
|
"snipt-teams-100-yearly": 100,
|
||||||
'snipt-teams-250-yearly': 250,
|
"snipt-teams-250-yearly": 250,
|
||||||
'snipt-teams-unlimited-yearly': float('inf')
|
"snipt-teams-unlimited-yearly": float("inf"),
|
||||||
}
|
}
|
||||||
|
|
||||||
if plan_map[self.plan] == float('inf'):
|
if plan_map[self.plan] == float("inf"):
|
||||||
return 'Unlimited'
|
return "Unlimited"
|
||||||
else:
|
else:
|
||||||
return plan_map[self.plan]
|
return plan_map[self.plan]
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,17 @@ from teams import views
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^for-teams/$', views.for_teams),
|
url(r"^for-teams/$", views.for_teams),
|
||||||
url(r'^for-teams/complete/$', views.for_teams_complete),
|
url(r"^for-teams/complete/$", views.for_teams_complete),
|
||||||
url(r'^(?P<username>[^/]+)/members/remove/(?P<member>[^/]+)/$',
|
url(
|
||||||
views.remove_team_member,
|
r"^(?P<username>[^/]+)/members/remove/(?P<member>[^/]+)/$",
|
||||||
name='remove-team-member'),
|
views.remove_team_member,
|
||||||
url(r'^(?P<username>[^/]+)/members/add/(?P<member>[^/]+)/$',
|
name="remove-team-member",
|
||||||
views.add_team_member,
|
),
|
||||||
name='add-team-member'),
|
url(
|
||||||
url(r'^(?P<username>[^/]+)/members/$',
|
r"^(?P<username>[^/]+)/members/add/(?P<member>[^/]+)/$",
|
||||||
views.team_members,
|
views.add_team_member,
|
||||||
name='team-members')
|
name="add-team-member",
|
||||||
]
|
),
|
||||||
|
url(r"^(?P<username>[^/]+)/members/$", views.team_members, name="team-members"),
|
||||||
|
]
|
||||||
|
|
|
@ -8,7 +8,7 @@ from django.shortcuts import get_object_or_404
|
||||||
from teams.models import Team
|
from teams.models import Team
|
||||||
|
|
||||||
|
|
||||||
@render_to('teams/for-teams.html')
|
@render_to("teams/for-teams.html")
|
||||||
def for_teams(request):
|
def for_teams(request):
|
||||||
if request.user.is_authenticated():
|
if request.user.is_authenticated():
|
||||||
profile = request.user.profile
|
profile = request.user.profile
|
||||||
|
@ -18,38 +18,34 @@ def for_teams(request):
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@render_to('teams/for-teams-complete.html')
|
@render_to("teams/for-teams-complete.html")
|
||||||
def for_teams_complete(request):
|
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'],
|
team = Team(
|
||||||
email=request.POST['email'],
|
name=request.POST["team-name"],
|
||||||
owner=request.user)
|
email=request.POST["email"],
|
||||||
|
owner=request.user,
|
||||||
|
)
|
||||||
team.save()
|
team.save()
|
||||||
|
|
||||||
user = User.objects.create_user(team.slug,
|
user = User.objects.create_user(team.slug, team.email, str(uuid.uuid4()))
|
||||||
team.email,
|
|
||||||
str(uuid.uuid4()))
|
|
||||||
|
|
||||||
team.user = user
|
team.user = user
|
||||||
team.save()
|
team.save()
|
||||||
|
|
||||||
return {
|
return {"team": team}
|
||||||
'team': team
|
|
||||||
}
|
|
||||||
else:
|
else:
|
||||||
return HttpResponseBadRequest()
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@render_to('teams/team-members.html')
|
@render_to("teams/team-members.html")
|
||||||
def team_members(request, username):
|
def team_members(request, username):
|
||||||
team = get_object_or_404(Team, slug=username, disabled=False)
|
team = get_object_or_404(Team, slug=username, disabled=False)
|
||||||
if not team.user_is_member(request.user):
|
if not team.user_is_member(request.user):
|
||||||
raise Http404
|
raise Http404
|
||||||
return {
|
return {"team": team}
|
||||||
'team': team
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -57,15 +53,14 @@ def add_team_member(request, username, member):
|
||||||
team = get_object_or_404(Team, slug=username, disabled=False)
|
team = get_object_or_404(Team, slug=username, disabled=False)
|
||||||
user = get_object_or_404(User, username=member)
|
user = get_object_or_404(User, username=member)
|
||||||
|
|
||||||
if (team.owner != request.user):
|
if team.owner != request.user:
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
if ((team.members.all().count() + 1) > team.member_limit):
|
if (team.members.all().count() + 1) > team.member_limit:
|
||||||
return HttpResponseRedirect('/' + team.slug +
|
return HttpResponseRedirect("/" + team.slug + "/members/?limit-reached")
|
||||||
'/members/?limit-reached')
|
|
||||||
else:
|
else:
|
||||||
team.members.add(user)
|
team.members.add(user)
|
||||||
return HttpResponseRedirect('/' + team.slug + '/members/')
|
return HttpResponseRedirect("/" + team.slug + "/members/")
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -73,9 +68,9 @@ def remove_team_member(request, username, member):
|
||||||
team = get_object_or_404(Team, slug=username, disabled=False)
|
team = get_object_or_404(Team, slug=username, disabled=False)
|
||||||
user = get_object_or_404(User, username=member)
|
user = get_object_or_404(User, username=member)
|
||||||
|
|
||||||
if (team.owner != request.user):
|
if team.owner != request.user:
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
team.members.remove(user)
|
team.members.remove(user)
|
||||||
|
|
||||||
return HttpResponseRedirect('/' + team.slug + '/members/')
|
return HttpResponseRedirect("/" + team.slug + "/members/")
|
||||||
|
|
78
urls.py
78
urls.py
|
@ -6,21 +6,25 @@ from django.contrib.auth.views import login
|
||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.views.generic import TemplateView
|
from django.views.generic import TemplateView
|
||||||
from django.views.static import serve
|
from django.views.static import serve
|
||||||
from snipts.api import (PublicSniptResource,
|
from snipts.api import (
|
||||||
PublicUserResource, PrivateSniptResource,
|
PublicSniptResource,
|
||||||
PrivateFavoriteResource, PrivateUserProfileResource,
|
PublicUserResource,
|
||||||
PrivateUserResource, PublicTagResource)
|
PrivateSniptResource,
|
||||||
|
PrivateFavoriteResource,
|
||||||
|
PrivateUserProfileResource,
|
||||||
|
PrivateUserResource,
|
||||||
|
PublicTagResource,
|
||||||
|
)
|
||||||
from snipts.views import search
|
from snipts.views import search
|
||||||
from tastypie.api import Api
|
from tastypie.api import Api
|
||||||
from views import (homepage, lexers, login_redirect,
|
from views import homepage, lexers, login_redirect, tags, user_api_key
|
||||||
tags, user_api_key)
|
|
||||||
|
|
||||||
public_api = Api(api_name='public')
|
public_api = Api(api_name="public")
|
||||||
public_api.register(PublicSniptResource())
|
public_api.register(PublicSniptResource())
|
||||||
public_api.register(PublicTagResource())
|
public_api.register(PublicTagResource())
|
||||||
public_api.register(PublicUserResource())
|
public_api.register(PublicUserResource())
|
||||||
|
|
||||||
private_api = Api(api_name='private')
|
private_api = Api(api_name="private")
|
||||||
private_api.register(PrivateSniptResource())
|
private_api.register(PrivateSniptResource())
|
||||||
private_api.register(PrivateUserResource())
|
private_api.register(PrivateUserResource())
|
||||||
private_api.register(PrivateFavoriteResource())
|
private_api.register(PrivateFavoriteResource())
|
||||||
|
@ -30,37 +34,39 @@ urlpatterns = []
|
||||||
|
|
||||||
if os.environ.get("DISABLE_SIGNUP") == "true":
|
if os.environ.get("DISABLE_SIGNUP") == "true":
|
||||||
urlpatterns += [
|
urlpatterns += [
|
||||||
url(r'^register/?$', lambda x: HttpResponseRedirect('/404/')),
|
url(r"^register/?$", lambda x: HttpResponseRedirect("/404/")),
|
||||||
url(r'^signup/?$', lambda x: HttpResponseRedirect('/404/')),
|
url(r"^signup/?$", lambda x: HttpResponseRedirect("/404/")),
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
urlpatterns += [
|
urlpatterns += [url(r"^signup/?$", lambda x: HttpResponseRedirect("/register/"))]
|
||||||
url(r'^signup/?$', lambda x: HttpResponseRedirect('/register/')),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
urlpatterns += [
|
urlpatterns += [
|
||||||
url(r'^$', homepage),
|
url(r"^$", homepage),
|
||||||
url(r'', include('registration.backends.simple.urls')),
|
url(r"", include("registration.backends.simple.urls")),
|
||||||
url(r'^login/?$', login, name='login'),
|
url(r"^login/?$", login, name="login"),
|
||||||
url(r'^login-redirect/$', login_redirect),
|
url(r"^login-redirect/$", login_redirect),
|
||||||
url(r'^admin/', include(admin.site.urls)),
|
url(r"^admin/", include(admin.site.urls)),
|
||||||
url(r'^404/$', TemplateView.as_view(template_name='404.html')),
|
url(r"^404/$", TemplateView.as_view(template_name="404.html")),
|
||||||
url(r'^500/$', TemplateView.as_view(template_name='500.html')),
|
url(r"^500/$", TemplateView.as_view(template_name="500.html")),
|
||||||
url(r'^robots.txt$', TemplateView.as_view(template_name='robots.txt')),
|
url(r"^robots.txt$", TemplateView.as_view(template_name="robots.txt")),
|
||||||
url(r'^tags/$', tags),
|
url(r"^tags/$", tags),
|
||||||
url(r'^account/', include('accounts.urls')),
|
url(r"^account/", include("accounts.urls")),
|
||||||
url(r'^api/public/lexer/$', lexers),
|
url(r"^api/public/lexer/$", lexers),
|
||||||
url(r'^api/private/key/$', user_api_key),
|
url(r"^api/private/key/$", user_api_key),
|
||||||
url(r'^api/', include(public_api.urls)),
|
url(r"^api/", include(public_api.urls)),
|
||||||
url(r'^api/', include(private_api.urls)),
|
url(r"^api/", include(private_api.urls)),
|
||||||
url(r'^search/$', search),
|
url(r"^search/$", search),
|
||||||
url(r'^', include('teams.urls')),
|
url(r"^", include("teams.urls")),
|
||||||
url(r'^', include('snipts.urls')),
|
url(r"^", include("snipts.urls")),
|
||||||
url(r'^(?P<path>favicon\.ico)$', serve, {
|
url(
|
||||||
'document_root': os.path.join(os.path.dirname(__file__), 'static/img')
|
r"^(?P<path>favicon\.ico)$",
|
||||||
}),
|
serve,
|
||||||
url(r'^static/(?P<path>.*)$', serve, {
|
{"document_root": os.path.join(os.path.dirname(__file__), "static/img")},
|
||||||
'document_root': os.path.join(os.path.dirname(__file__), 'media')
|
),
|
||||||
})
|
url(
|
||||||
|
r"^static/(?P<path>.*)$",
|
||||||
|
serve,
|
||||||
|
{"document_root": os.path.join(os.path.dirname(__file__), "media")},
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
|
@ -4,11 +4,20 @@ from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
|
||||||
class UserAdmin(UserAdmin):
|
class UserAdmin(UserAdmin):
|
||||||
list_display = ['username', 'email', 'first_name', 'last_name',
|
list_display = [
|
||||||
'last_login', 'date_joined', 'is_active', 'is_staff',
|
"username",
|
||||||
'api_key']
|
"email",
|
||||||
list_filter = ['is_staff', 'is_superuser', 'is_active']
|
"first_name",
|
||||||
ordering = ['-date_joined']
|
"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.unregister(User)
|
||||||
admin.site.register(User, UserAdmin)
|
admin.site.register(User, UserAdmin)
|
||||||
|
|
|
@ -3,10 +3,10 @@ from django.contrib.auth.models import User
|
||||||
|
|
||||||
class EmailOrUsernameModelBackend(object):
|
class EmailOrUsernameModelBackend(object):
|
||||||
def authenticate(self, username=None, password=None):
|
def authenticate(self, username=None, password=None):
|
||||||
if '@' in username:
|
if "@" in username:
|
||||||
kwargs = {'email': username}
|
kwargs = {"email": username}
|
||||||
else:
|
else:
|
||||||
kwargs = {'username': username}
|
kwargs = {"username": username}
|
||||||
try:
|
try:
|
||||||
user = User.objects.get(**kwargs)
|
user = User.objects.get(**kwargs)
|
||||||
if user.check_password(password):
|
if user.check_password(password):
|
||||||
|
|
|
@ -9,34 +9,36 @@ class SniptRegistrationForm(RegistrationForm):
|
||||||
Subclass of ``RegistrationForm`` which enforces uniqueness of
|
Subclass of ``RegistrationForm`` which enforces uniqueness of
|
||||||
email addresses and further restricts usernames.
|
email addresses and further restricts usernames.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def clean_username(self):
|
def clean_username(self):
|
||||||
"""
|
"""
|
||||||
Validate that the username is alphanumeric and is not already
|
Validate that the username is alphanumeric and is not already
|
||||||
in use.
|
in use.
|
||||||
"""
|
"""
|
||||||
existing = User.objects.filter(
|
existing = User.objects.filter(username__iexact=self.cleaned_data["username"])
|
||||||
username__iexact=self.cleaned_data['username'])
|
|
||||||
if existing.exists():
|
if existing.exists():
|
||||||
raise forms.ValidationError(
|
raise forms.ValidationError(_("A user with that username already exists."))
|
||||||
_("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."))
|
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."))
|
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."))
|
raise forms.ValidationError(_("Cannot have '+' in username."))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return self.cleaned_data['username']
|
return self.cleaned_data["username"]
|
||||||
|
|
||||||
def clean_email(self):
|
def clean_email(self):
|
||||||
"""
|
"""
|
||||||
Validate that the supplied email address is unique for the
|
Validate that the supplied email address is unique for the
|
||||||
site.
|
site.
|
||||||
"""
|
"""
|
||||||
if User.objects.filter(email__iexact=self.cleaned_data['email']):
|
if User.objects.filter(email__iexact=self.cleaned_data["email"]):
|
||||||
raise forms.ValidationError(
|
raise forms.ValidationError(
|
||||||
_("""This email address is already in use. Please supply a
|
_(
|
||||||
different email address."""))
|
"""This email address is already in use. Please supply a
|
||||||
return self.cleaned_data['email']
|
different email address."""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return self.cleaned_data["email"]
|
||||||
|
|
|
@ -8,11 +8,10 @@ register = template.Library()
|
||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def pygmentize(text):
|
def pygmentize(text):
|
||||||
return highlight(text,
|
return highlight(
|
||||||
get_lexer_by_name('diff',
|
text,
|
||||||
encoding='UTF-8'),
|
get_lexer_by_name("diff", encoding="UTF-8"),
|
||||||
HtmlFormatter(linenos='table',
|
HtmlFormatter(
|
||||||
anchorlinenos=True,
|
linenos="table", anchorlinenos=True, lineanchors="L", linespans="L"
|
||||||
lineanchors='L',
|
),
|
||||||
linespans='L',
|
)
|
||||||
))
|
|
||||||
|
|
|
@ -5,4 +5,4 @@ register = template.Library()
|
||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def truncate_lines(text):
|
def truncate_lines(text):
|
||||||
return '\n'.join(text.split('\n')[:300])
|
return "\n".join(text.split("\n")[:300])
|
||||||
|
|
|
@ -17,7 +17,6 @@ register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
class VerbatimNode(template.Node):
|
class VerbatimNode(template.Node):
|
||||||
|
|
||||||
def __init__(self, text):
|
def __init__(self, text):
|
||||||
self.text = text
|
self.text = text
|
||||||
|
|
||||||
|
@ -30,15 +29,15 @@ def verbatim(parser, token):
|
||||||
text = []
|
text = []
|
||||||
while 1:
|
while 1:
|
||||||
token = parser.tokens.pop(0)
|
token = parser.tokens.pop(0)
|
||||||
if token.contents == 'endverbatim':
|
if token.contents == "endverbatim":
|
||||||
break
|
break
|
||||||
if token.token_type == template.TOKEN_VAR:
|
if token.token_type == template.TOKEN_VAR:
|
||||||
text.append('{{')
|
text.append("{{")
|
||||||
elif token.token_type == template.TOKEN_BLOCK:
|
elif token.token_type == template.TOKEN_BLOCK:
|
||||||
text.append('{%')
|
text.append("{%")
|
||||||
text.append(token.contents)
|
text.append(token.contents)
|
||||||
if token.token_type == template.TOKEN_VAR:
|
if token.token_type == template.TOKEN_VAR:
|
||||||
text.append('}}')
|
text.append("}}")
|
||||||
elif token.token_type == template.TOKEN_BLOCK:
|
elif token.token_type == template.TOKEN_BLOCK:
|
||||||
text.append('%}')
|
text.append("%}")
|
||||||
return VerbatimNode(''.join(text))
|
return VerbatimNode("".join(text))
|
||||||
|
|
|
@ -6,10 +6,11 @@ class SniptRegistrationView(RegistrationView):
|
||||||
"""
|
"""
|
||||||
Custom registration view that uses our custom form.
|
Custom registration view that uses our custom form.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
form_class = SniptRegistrationForm
|
form_class = SniptRegistrationForm
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
return super(RegistrationView, self).dispatch(request, *args, **kwargs)
|
return super(RegistrationView, self).dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
def get_success_url(self, request):
|
def get_success_url(self, request):
|
||||||
return '/login-redirect'
|
return "/login-redirect"
|
||||||
|
|
37
views.py
37
views.py
|
@ -6,7 +6,7 @@ from snipts.utils import get_lexers_list
|
||||||
from taggit.models import Tag
|
from taggit.models import Tag
|
||||||
|
|
||||||
|
|
||||||
@render_to('homepage.html')
|
@render_to("homepage.html")
|
||||||
def homepage(request):
|
def homepage(request):
|
||||||
|
|
||||||
if request.blog_user:
|
if request.blog_user:
|
||||||
|
@ -32,39 +32,32 @@ def lexers(request):
|
||||||
except IndexError:
|
except IndexError:
|
||||||
mimetypes = []
|
mimetypes = []
|
||||||
|
|
||||||
objects.append({
|
objects.append(
|
||||||
'name': l[0],
|
{"name": l[0], "lexers": l[1], "filters": filters, "mimetypes": mimetypes}
|
||||||
'lexers': l[1],
|
)
|
||||||
'filters': filters,
|
|
||||||
'mimetypes': mimetypes
|
|
||||||
})
|
|
||||||
|
|
||||||
return {'objects': objects}
|
return {"objects": objects}
|
||||||
|
|
||||||
|
|
||||||
def login_redirect(request):
|
def login_redirect(request):
|
||||||
if request.user.is_authenticated():
|
if request.user.is_authenticated():
|
||||||
return HttpResponseRedirect('/' + request.user.username + '/')
|
return HttpResponseRedirect("/" + request.user.username + "/")
|
||||||
else:
|
else:
|
||||||
return HttpResponseRedirect('/')
|
return HttpResponseRedirect("/")
|
||||||
|
|
||||||
|
|
||||||
@render_to('tags.html')
|
@render_to("tags.html")
|
||||||
def tags(request):
|
def tags(request):
|
||||||
|
|
||||||
all_tags = Tag.objects.filter(snipt__public=True).order_by('name')
|
all_tags = Tag.objects.filter(snipt__public=True).order_by("name")
|
||||||
all_tags = all_tags.annotate(count=Count('taggit_taggeditem_items__id'))
|
all_tags = all_tags.annotate(count=Count("taggit_taggeditem_items__id"))
|
||||||
|
|
||||||
popular_tags = Tag.objects.filter(snipt__public=True)
|
popular_tags = Tag.objects.filter(snipt__public=True)
|
||||||
popular_tags = popular_tags.annotate(
|
popular_tags = popular_tags.annotate(count=Count("taggit_taggeditem_items__id"))
|
||||||
count=Count('taggit_taggeditem_items__id'))
|
popular_tags = popular_tags.order_by("-count")[:20]
|
||||||
popular_tags = popular_tags.order_by('-count')[:20]
|
|
||||||
popular_tags = sorted(popular_tags, key=lambda tag: tag.name)
|
popular_tags = sorted(popular_tags, key=lambda tag: tag.name)
|
||||||
|
|
||||||
return {
|
return {"all_tags": all_tags, "tags": popular_tags}
|
||||||
'all_tags': all_tags,
|
|
||||||
'tags': popular_tags
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@ajax_request
|
@ajax_request
|
||||||
|
@ -73,6 +66,4 @@ def user_api_key(request):
|
||||||
if not request.user.is_authenticated():
|
if not request.user.is_authenticated():
|
||||||
return HttpResponseBadRequest()
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
return {
|
return {"api_key": request.user.api_key.key}
|
||||||
'api_key': request.user.api_key.key
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue