Skip to content

Commit

Permalink
Added thumbnail but regrettably createdAt is not working
Browse files Browse the repository at this point in the history
  • Loading branch information
md-samsuzzoha-wdl committed Dec 23, 2023
1 parent d1db29d commit edf6c0c
Show file tree
Hide file tree
Showing 16 changed files with 227 additions and 213 deletions.
10 changes: 7 additions & 3 deletions client/components/article/Article.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@
</div>
</div>
</NuxtLink> -->
<NuxtLink rel="noopener noreferrer" v-bind:to="'http://localhost:3000/' + article.link" class="max-w-sm mx-auto group hover:no-underline focus:no-underline dark:bg-gray-900">
<img class="object-cover w-full rounded h-44 dark:bg-gray-500" src="https://source.unsplash.com/random/480x360?1" />
<NuxtLink rel="noopener noreferrer" v-bind:to="'http://localhost:3000/' + article.link"
class="max-w-sm mx-auto group hover:no-underline focus:no-underline dark:bg-gray-900">
<CldImage v-if="article.thumbnail && article.thumbnail !== ''" v-bind:src="article.thumbnail" width="200" height="200"
v-bind:alt="article.title" />
<img v-else class="object-cover w-full rounded h-44 dark:bg-gray-500"
src="https://source.unsplash.com/random/480x360?1" />
<div class="p-6 space-y-2">
<h3 class="text-2xl font-semibold group-hover:underline group-focus:underline">{{ article.title }}</h3>
<span class="text-xs dark:text-gray-400">{{ article.createdAt }}</span>
<!-- <span class="text-xs dark:text-gray-400">{{ article.createdAt }}</span> -->
<p>
{{ article.content }}
</p>
Expand Down
2 changes: 1 addition & 1 deletion client/components/home/Home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
id
title
content
createdAt
thumbnail
link
author {
id
Expand Down
2 changes: 1 addition & 1 deletion client/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default defineNuxtConfig({
typescript: {
strict: true,
},
modules: ["@nuxtjs/apollo", "@nuxtjs/tailwindcss", "@nuxt/devtools"],
modules: ["@nuxtjs/apollo", "@nuxtjs/tailwindcss", "@nuxt/devtools", "@nuxtjs/cloudinary"],
apollo: {
clients: {
default: {
Expand Down
296 changes: 101 additions & 195 deletions client/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"vue-tsc": "^1.8.22"
},
"dependencies": {
"@nuxtjs/cloudinary": "^2.5.1",
"@vueup/vue-quill": "^1.2.0"
}
}
8 changes: 8 additions & 0 deletions server/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Cloudinary
CLOUDINARY_API_SECRET=01IJQKbkaEl4ZMng8xzuSH0AAfs
CLOUDINARY_API_KEY=455739236686664
CLOUDINARY_CLOUD_NAME=shayon-cloud
CLOUDINARY_FOLDER_NAME="webdevlab"


DJANGO_SECRET="django-insecure-r8m94=*au9tiz3n-16kha-%&tw$zi!g3w+)q^^i3*0^b*1yo80"
Empty file added server/.env.example
Empty file.
19 changes: 19 additions & 0 deletions server/blog/migrations/0005_article_thumbnail.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 4.2.7 on 2023-12-23 03:33

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('blog', '0004_alter_article_link_alter_article_title'),
]

operations = [
migrations.AddField(
model_name='article',
name='thumbnail',
field=models.CharField(default='webdevlab/yxogymfppkjpdzuy8gpe', max_length=255),
preserve_default=False,
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 4.2.7 on 2023-12-23 03:41

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('blog', '0005_article_thumbnail'),
]

operations = [
migrations.AlterField(
model_name='article',
name='created_at',
field=models.DateTimeField(auto_now_add=True),
),
migrations.AlterField(
model_name='comment',
name='created_at',
field=models.DateTimeField(auto_now_add=True),
),
]
7 changes: 4 additions & 3 deletions server/blog/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@ def __str__(self):
class Article(models.Model):
title = models.CharField(max_length=200, blank=False, null=False, unique=True)
content = models.TextField()
# thumbnail
created_at = models.DateField()
thumbnail = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
link = models.CharField(max_length=255, unique=True)


def save(self, *args, **kwargs):
if not self.link:
self.link = slugify(self.title)
Expand All @@ -43,7 +44,7 @@ class Comment(models.Model):
author = models.CharField(max_length=100) # Who made the comment
email = models.EmailField()
text = models.TextField()
created_at = models.DateField()
created_at = models.DateTimeField(auto_now_add=True)

def __str__(self):
return self.comment_date
Expand Down
44 changes: 38 additions & 6 deletions server/blog/resolvers/mutations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
from graphene_django import DjangoObjectType
from ..models import Category, Article
from .queryTypes import CategoryType, ArticleType

from core.settings import cloudinary
from graphene_file_upload.scalars import Upload
from datetime import datetime
import os

class CategoryMutation(graphene.Mutation):
class Arguments:
Expand All @@ -26,32 +29,61 @@ class ArticleMutation(graphene.Mutation):
class Arguments:
title = graphene.String(required=True)
content = graphene.String(required=True)
created_at = graphene.Date()
thumbnail = Upload(required=True)
author_id = graphene.ID()
category_id = graphene.ID()
id = graphene.ID()

success = graphene.Boolean()
article = graphene.Field(ArticleType)

@classmethod
def mutate(cls, root, info, title, content, created_at, author_id, category_id, id=None):
def mutate(cls, root, info, title, content, thumbnail, author_id, category_id, id=None):

# Upload the image to Cloudinary
options = {
'folder': os.environ["CLOUDINARY_FOLDER_NAME"],
"width": 300, "height": 300, "crop": "thumb"
}
cloudinary_response = cloudinary.uploader.upload(thumbnail, **options)

# Get the URL of the uploaded image from the Cloudinary response
thumbnail_url = cloudinary_response['public_id']
# print({"thumbnail_url": thumbnail_url, "cloudinary_response": cloudinary_response})
# result = {'thumbnail_url': 'http://res.cloudinary.com/shayon-cloud/image/upload/v1703304728/kd1pcwdt1vyuzqoqmmst.jpg', 'cloudinary_response': {'asset_id': 'bc854fde83711cb4b1983764e884d7e0', 'public_id': 'kd1pcwdt1vyuzqoqmmst', 'version': 1703304728, 'version_id': '0cef85e7ba27804a7c6609db55035c20', 'signature': 'e12e6a78d6f4366f5cfba4da278df3c92b6f7b62', 'width': 3081, 'height': 4622, 'format': 'jpg', 'resource_type': 'image', 'created_at': '2023-12-23T04:12:08Z', 'tags': [], 'bytes': 506228, 'type': 'upload', 'etag': '400efc41ef8dc16183220bfa335a4b7e', 'placeholder': False, 'url': 'http://res.cloudinary.com/shayon-cloud/image/upload/v1703304728/kd1pcwdt1vyuzqoqmmst.jpg', 'secure_url': 'https://res.cloudinary.com/shayon-cloud/image/upload/v1703304728/kd1pcwdt1vyuzqoqmmst.jpg', 'folder': '', 'original_filename': 'pexels-blue-record-19397385', 'api_key': '455739236686664'}}

# Get the current date and time
current_date_time = datetime.now()

if id:
article = Article.objects.get(pk=id)
article.title = title
article.content = content
if created_at:
article.created_at = created_at
article.thumbnail = thumbnail_url
article.created_at = current_date_time
if author_id:
article.author_id = author_id
if category_id:
article.category_id = category_id
article.save()
else:
article = Article.objects.create(title=title, content=content, created_at=created_at, author_id=author_id,
article = Article.objects.create(title=title, content=content, thumbnail=thumbnail_url, created_at=current_date_time, author_id=author_id,
category_id=category_id)
return ArticleMutation(article=article)


class Mutation(graphene.ObjectType):
create_or_update_category = CategoryMutation.Field()
create_or_update_article = ArticleMutation.Field()


# {
# "query": "mutation ($title: String!, $content: String!, $thumbnail: Upload, $authorId: ID!, $categoryId: ID!, $id: ID) { createOrUpdateArticle(title: $title, content: $content, thumbnail: $thumbnail, authorId: $authorId, categoryId: $categoryId, id: $id) { article { id title content thumbnail author { id name } category { id name } } } }",
# "variables": {
# "title": "Test Article",
# "content": "This is a test article",
# "thumbnail": null,
# "authorId": "1",
# "categoryId": "1"
# }
# }
2 changes: 2 additions & 0 deletions server/blog/resolvers/queryTypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ class Meta:
class ArticleType(DjangoObjectType):
class Meta:
model = Article
exclude = ("created_at",)


class CommentType(DjangoObjectType):
class Meta:
model = Comment
exclude = ("created_at",)


class TagType(DjangoObjectType):
Expand Down
5 changes: 3 additions & 2 deletions server/blog/urls.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from django.urls import path
from graphene_django.views import GraphQLView
from django.views.decorators.csrf import csrf_exempt
from graphene_file_upload.django import FileUploadGraphQLView

urlpatterns = [
# ...
path("graphql/", csrf_exempt(GraphQLView.as_view(graphiql=True))),
path("graphql/", csrf_exempt(FileUploadGraphQLView.as_view(graphiql=True))),
# path("graphql/", csrf_exempt(GraphQLView.as_view(graphiql=True))),

]
16 changes: 15 additions & 1 deletion server/core/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,20 @@
"""

from pathlib import Path
import os
from dotenv import load_dotenv
load_dotenv() # loads the configs from .env

import cloudinary
import cloudinary.uploader
import cloudinary.api

cloudinary.config(
cloud_name = os.environ["CLOUDINARY_CLOUD_NAME"],
api_key = os.environ["CLOUDINARY_API_KEY"],
api_secret = os.environ["CLOUDINARY_API_SECRET"],
secure = True
)

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
Expand All @@ -20,7 +34,7 @@
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-r8m94=*au9tiz3n-16kha-%&tw$zi!g3w+)q^^i3*0^b*1yo80'
SECRET_KEY = os.environ["DJANGO_SECRET"]

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
Expand Down
Binary file modified server/db.sqlite3
Binary file not shown.
5 changes: 4 additions & 1 deletion server/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
Django==4.2.7
graphene-django==3.1.5
graphene-django==3.1.5
cloudinary==1.37.0
django-dotenv==1.4.2
graphene-file-upload==1.3.0

0 comments on commit edf6c0c

Please sign in to comment.