Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Nilanchal Panigrahy committed Oct 21, 2023
1 parent 305c9df commit 4372c9d
Show file tree
Hide file tree
Showing 338 changed files with 21,136 additions and 0 deletions.
37 changes: 37 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Secret Key hash
SITE_URL=https://stacktips.com
SECRET_KEY=
DEBUG=True
ALLOWED_HOSTS=127.0.0.1,localhost
DEVELOPMENT_MODE=False

# Your database configruation details
DB_NAME=bloggify
DB_USER=root
DB_PASSWORD=
DB_HOST=127.0.0.1
DB_PORT=3306

# Media configurations
USE_SPACES=False
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_STORAGE_BUCKET_NAME=
AWS_S3_ENDPOINT_URL=

# Other site configruations
GOOGLE_RECAPTHCA_SECRET_KEY=

# SEO Related
PING_INDEX_NOW_POST_UPDATE=False
PING_GOOGLE_POST_UPDATE=False
INDEX_NOW_API_KEY=

#Sends emails using an SMTP server
EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend
EMAIL_HOST=
EMAIL_PORT=587
EMAIL_HOST_USER=
EMAIL_HOST_PASSWORD=
EMAIL_USE_TLS=True
DEFAULT_FROM_EMAIL=
82 changes: 82 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
.env
.env.production

/venv/*
/venv
/bloggy/frontend/node_modules/
/site-content/uploads/
/.idea/
/venv/
/env/
__pycache__/*
/bloggy_api/__pycache__/*
/bloggy/__pycache__/*
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
__pycache__
/bloggy/media/uploads/*
/bloggy/media/uploads/*.*

# C extensions
*.so

# Distribution / packaging
bin/
build/
develop-eggs/
eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
.tox/
.coverage
.cache
nosetests.xml
coverage.xml

# Translations
*.mo

# Mr Developer
.mr.developer.cfg
.project
.pydevproject

# Rope
.ropeproject

# Django stuff:
*.log
*.pot
*.__pycache__
**.pyc

# Sphinx documentation
docs/_build/
/frontend/node_modules/
/bloggy/static
/bloggy/static/debug_toolbar
/bloggy/static/hitcount
/bloggy/static/media
/bloggy/static/rest_framework
/bloggy/static/summernote
/bloggy/static/colorfield
/bloggy/static/admin/
media/uploads/default_avatar.png
media/uploads/articles/*
media/uploads/categories/*
media/uploads/course/*
media/uploads/quiz/*
media/uploads/user/*
73 changes: 73 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Bloggy - Django Powered Blog

Checkout the code from our git repository

git clone [email protected]:StackTipsLab/bloggy.git

Create a virtual env

```shell
python3 -m venv .venv
source .venv/bin/activate
```

Install python dependencies

```shell
pip3 install -r requirements.txt
```

Rename the `.env.example` file to `.env` and provide all te configurations details including Database, Email Configurations.

Create and apply database migrations

```shell
python3 manage.py makemigrations
python3 manage.py migrate
```

Create superuser

```shell
python3 manage.py createsuperuser
```


Collect static files before publishing or development.

```shell
python manage.py collectstatic
```

Start the application

```shell
python3 manage.py runserver
```


## Bloggy Frontend Module

For building frontend code, you will need the following node version.

```shell
node -v
v12.22.12

npm -v
6.14.16
```

Once you have the above node version installed, install node dependencies using the following command.

```shell
npm install

```

Now, you can build

```shell
npm run start
npm run build # to generate production build
```
5 changes: 5 additions & 0 deletions bloggy/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import pymysql

pymysql.install_as_MySQLdb()

default_app_config = 'bloggy.apps.MyAppConfig'
7 changes: 7 additions & 0 deletions bloggy/admin/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from .misc_admin import *
from .article_admin import *
from .category_admin import *
from .course_admin import *
from .quiz_admin import *
from .user_admin import *
from .subscriber_admin import *
174 changes: 174 additions & 0 deletions bloggy/admin/article_admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
from django import forms
from django.contrib import admin
from django.contrib.auth import get_user_model
from django.db.models import TextField
from django.forms import Textarea, BaseInlineFormSet
from django.urls import reverse
from django.utils import timezone
from django.utils.html import format_html
from django.utils.safestring import mark_safe
from django_summernote.admin import SummernoteModelAdmin

from bloggy.admin.misc_admin import publish, unpublish
from bloggy.models import Article, PostMeta


class ArticleForm(forms.ModelForm):
excerpt = forms.CharField(widget=forms.Textarea(attrs={'rows': 2, 'cols': 100}))
title = forms.CharField(widget=forms.TextInput(attrs={'size': 105}))
model = Article
keywords = forms.CharField(widget=forms.Textarea(attrs={'rows': 2, 'cols': 100}))


class PostMetaInlineFormSet(BaseInlineFormSet):
def __init__(self, *args, **kwargs):
self.initial = [
{'meta_key': 'template_type', 'meta_value': "standard"},
{'meta_key': 'seo_title', 'meta_value': ""},
{'meta_key': 'seo_description', 'meta_value': ""},
{'meta_key': 'seo_keywords', 'meta_value': ""},
]
super(PostMetaInlineFormSet, self).__init__(*args, **kwargs)


class PostMetaInline(admin.TabularInline):
model = PostMeta
extra = 0
formfield_overrides = {
TextField: {'widget': Textarea(attrs={'rows': 1, 'cols': 105})},
}
formset = PostMetaInlineFormSet


@admin.register(Article)
class ArticleAdmin(SummernoteModelAdmin):
def get_form(self, request, obj=None, **kwargs):
form = super(ArticleAdmin, self).get_form(request, obj, **kwargs)
form.base_fields["author"].queryset = get_user_model().objects.filter(is_staff=True)
return form

prepopulated_fields = {"slug": ("title",)}
list_display = (
'id',
'title',
'category_display',
'post_type',
'template_type',
'is_published',
'author_link',
'display_order',
'published_date_display',
'updated_date_display'
)
list_filter = (
'publish_status',
('post_type', admin.ChoicesFieldListFilter),
('template_type', admin.ChoicesFieldListFilter),
("category", admin.RelatedOnlyFieldListFilter),
("author", admin.RelatedOnlyFieldListFilter),
("course", admin.RelatedOnlyFieldListFilter),
'is_featured',
("video_id", admin.BooleanFieldListFilter),
)

fieldsets = (
(None, {
'fields': ('title', 'excerpt', 'keywords', 'slug', 'content', 'thumbnail', 'author', 'category',)
}),
('Publication options', {
'fields': ('publish_status', 'published_date',),
}),
('Advanced options', {
'fields': ('post_type', 'template_type', 'course', 'duration', 'difficulty', 'video_id', 'is_featured',
'display_order'),
}),
)

search_fields = ['title']
summernote_fields = ('content',)
readonly_fields = ['updated_date', 'created_date']
date_hierarchy = 'published_date'
form = ArticleForm
ordering = ('-created_date',)
list_display_links = ['title']
list_per_page = 50
actions = [publish, unpublish]
inlines = [PostMetaInline]

def published_date_display(self, obj):
return format_html(
'<small>{}</small>'.format(obj.published_date.strftime("%m/%d/%Y") if obj.published_date else "-"))

published_date_display.short_description = "Published on"

def has_video(self, obj):
return self.videoId

def updated_date_display(self, obj):
return format_html(
'<small>{}</small>'.format(obj.updated_date.strftime("%m/%d/%Y") if obj.published_date else "-"))

updated_date_display.short_description = "Updated on"

def category_display(self, obj):
tags = "</br>".join([
"<span class='tags-list'>" + cat.title + "</span></br>" for cat in obj.category.all()
])
return format_html(tags)

category_display.short_description = "Categories"

def author_link(self, obj):
url = reverse("admin:bloggy_myuser_change", args=[obj.author.id])
if obj.author.name:
link = '<a href="%s">%s</a>' % (url, obj.author.name)
else:
link = '<a href="%s">%s</a>' % (url, obj.author.username)
return mark_safe(link)

author_link.short_description = 'Author'

def view_on_site(self, obj):
url = reverse('article_single', kwargs={'slug': obj.slug})
return url + "?context=preview"

def save_model(self, request, obj, form, change):
if "publish_status" in form.changed_data and obj.publish_status == "LIVE" and not obj.published_date:
obj.published_date = timezone.now()
if not obj.pk:
obj.author = request.user

super().save_model(request, obj, form, change)

def live_category(self, queryset):
if queryset.publish_status == 'LIVE':
return True
return False

def is_published(self, queryset):
if queryset.publish_status == 'LIVE':
return True
return False

is_published.boolean = True
is_published.short_description = "Status"

def has_excerpt(self, queryset):
if queryset.excerpt is None:
return False
return True

has_excerpt.boolean = True


@admin.register(PostMeta)
class PostMetaAdmin(admin.ModelAdmin):
list_display = ['id', 'article_link', 'meta_key', 'meta_value']
list_filter = ['meta_key']

def article_link(self, obj):
url = reverse("admin:bloggy_article_change", args=[obj.article.id])
link = '<a href="%s">%s</a>' % (url, obj.article.title)
return mark_safe(link)

article_link.short_description = 'Author'
Loading

0 comments on commit 4372c9d

Please sign in to comment.