Merge branch 'staging' of https://github.com/WDI-Ideas/goodtimes into feature/module_9_coupons

This commit is contained in:
rizwanisready
2024-08-06 12:48:30 +05:30
17 changed files with 701 additions and 61 deletions

View File

@@ -1,5 +1,7 @@
import random
import requests
import googlemaps
import tweepy
from django.conf import settings
from django.core.files.uploadedfile import UploadedFile
from django.core.mail import EmailMessage
@@ -745,7 +747,7 @@ class GoogleMapsservice:
def get_place_id_from_coordinates(self, latitude, longitude):
"""
Get the place ID of the given coordinates.
:param latitude: Latitude of the location
:param longitude: Longitude of the location
:return: Place ID
@@ -804,16 +806,287 @@ class GoogleMapsservice:
if element["status"] == "OK" and element["distance"]["value"] <= radius_km * 1000 # Convert km to meters
}
print(f"distance is {distances} and distances key is {distances.keys()}")
# Filter the queryset to include only events within the specified radius
queryset = queryset.filter(id__in=distances.keys())
# # Sort the event IDs by their distances in ascending order
# event_ids_by_distance = sorted(distances, key=distances.get)
print(f"query set after distance filter {queryset}")
# # Create a Case/When expression to preserve the order of events by distance
# preserved_order = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(event_ids_by_distance)])
# print(f"preserved_order is {preserved_order}")
# # Order the queryset based on the preserved order
# queryset = queryset.order_by(preserved_order)
# Sort the event IDs by their distances in ascending order
event_ids_by_distance = sorted(distances, key=distances.get)
print(f"sort event by it distance {event_ids_by_distance}")
# Create a Case/When expression to preserve the order of events by distance
preserved_order = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(event_ids_by_distance)])
print(f"preserved_order is {preserved_order}")
# Order the queryset based on the preserved order
queryset = queryset.order_by(preserved_order)
for data in queryset:
print(f"queryset after preserverd order {data.id}")
return queryset
class TwitterAPI:
def __init__(self):
self.api_key = settings.TWITTER_API_KEY
self.api_secret_key = settings.TWITTER_API_SECRET_KEY
self.access_token = settings.TWITTER_ACCESS_TOKEN
self.access_token_secret = settings.TWITTER_ACCESS_TOKEN_SECRET
self.client, self.api = self._setup_api()
def _setup_api(self):
client = tweepy.Client(
consumer_key=self.api_key,
consumer_secret=self.api_secret_key,
access_token=self.access_token,
access_token_secret=self.access_token_secret,
)
auth = tweepy.OAuth1UserHandler(
self.api_key,
self.api_secret_key,
self.access_token,
self.access_token_secret,
)
api = tweepy.API(auth, wait_on_rate_limit=True)
return client, api
def post_text_tweet(self, caption):
tweet = self.client.create_tweet(text=caption)
return tweet
def post_image_with_caption(self, image_url, caption):
media = self.api.media_upload(image_url)
tweet = self.client.create_tweet(text=caption, media_ids=[media.media_id])
return tweet
class TwitterPoster:
def __init__(self, twitter_api):
self.twitter_api = twitter_api
def post_text_tweet(self, caption):
try:
tweet = self.twitter_api.post_text_tweet(caption)
return {'success': True, 'message': 'Tweet posted successfully!'}
except tweepy.TweepyException as e:
return {'success': False, 'message': f'Error posting tweet: {e}'}
def post_image_with_caption(self, image_url, caption):
try:
tweet = self.twitter_api.post_image_with_caption(image_url, caption)
return {'success': True, 'message': 'Tweet posted successfully!'}
except tweepy.TweepyException as e:
return {'success': False, 'message': f'Error posting tweet: {e}'}
class FacebookAPI:
def __init__(self):
self.app_id = settings.FACEBOOK_APP_ID
self.app_secret = settings.FACEBOOK_APP_SECRET
self.page_id = settings.FACEBOOK_PAGE_ID
self.page_access_token = None
def _get_short_lived_user_access_token(self):
try:
url = f"https://graph.facebook.com/oauth/access_token?grant_type=client_credentials&client_id={self.app_id}&client_secret={self.app_secret}"
response = requests.get(url)
# response.raise_for_status()
print(f"short lived token {response.json()}")
return response.json()['access_token']
except requests.exceptions.RequestException as e:
print(f"Error getting short-lived user access token: {e}")
return None
def _get_long_lived_user_access_token(self, short_lived_token):
try:
url = f"https://graph.facebook.com/v20.0/oauth/access_token?grant_type=fb_exchange_token&client_id={self.app_id}&client_secret={self.app_secret}&fb_exchange_token={short_lived_token}"
response = requests.get(url)
# response.raise_for_status()
print(f"long lived access token : {response.json()}")
return response.json()['access_token']
except requests.exceptions.RequestException as e:
print(f"Error getting long-lived user access token: {e}")
return None
def _get_page_access_token(self, long_lived_token):
url = f"https://graph.facebook.com/{self.page_id}?fields=access_token&access_token={long_lived_token}"
response = requests.get(url)
# response.raise_for_status()
print(f"page access token is {response.json()}")
# self.page_access_token = response.json()["access_token"]
def authenticate(self):
# short_lived_token = self._get_short_lived_user_access_token()
# if not short_lived_token:
# return False
# long_lived_token = self._get_long_lived_user_access_token(short_lived_token)
# if not long_lived_token:
# return False
# self._get_page_access_token(short_lived_token)
self.page_access_token = settings.FACEBOOK_ACCESS_TOKEN
return True
def post_photo(self, image_url, caption):
if not self.page_access_token:
print("Page access token not obtained. Call authenticate() first.")
return False
try:
url = f"https://graph.facebook.com/v20.0/{self.page_id}/photos"
params = {
"message": caption,
"url": image_url,
"access_token": self.page_access_token,
}
response = requests.post(url, params=params)
# response.raise_for_status()
result = response.json()
if "id" not in result:
print(f"Error posting photo: {result}")
return False
print(f"Data posted successfully. Post Id: {result['id']}")
return True
except Exception as e:
print(f"Error posting photo: {e}")
return False
class FacebookPoster:
def __init__(self, facebook_api):
self.facebook_api = facebook_api
def post_photo(self, image_url, caption):
if not self.facebook_api.authenticate():
print("Authentication failed. Please try again.")
return {'success': False, 'message': 'Error posting photo. Authenticate failed'}
result = self.facebook_api.post_photo(image_url, caption)
if not result:
return {'success': False, 'message': 'Error posting photo in Facebook'}
return {'success': True, 'message': 'Photo posted successfully'}
# import requests
# app_id = "YOUR_APP_ID"
# app_secret = "YOUR_APP_SECRET"
# page_id = "YOUR_PAGE_ID" # You need to specify the page ID
# # Step 1: Get an App Access Token
# response = requests.get(f"https://graph.facebook.com/oauth/access_token?client_id={app_id}&client_secret={app_secret}&grant_type=client_credentials")
# app_access_token = response.json()["access_token"]
# # Step 2: Get a Page Access Token
# response = requests.get(f"https://graph.facebook.com/{page_id}?fields=access_token&access_token={app_access_token}")
# page_access_token = response.json()["access_token"]
# # Use the Page Access Token to query the Page node
# response = requests.get(f"https://graph.facebook.com/{page_id}?access_token={page_access_token}")
# page_data = response.json()
# print(page_data)
class InstagramAPI:
def __init__(self):
self.app_id = settings.FACEBOOK_APP_ID
self.app_secret = settings.FACEBOOK_APP_SECRET
self.page_id = settings.INSTAGRAM_PAGE_ID
self.page_access_token = None
def _get_short_lived_user_access_token(self):
try:
url = f"https://graph.facebook.com/oauth/access_token"
params = {
"grant_type": "client_credentials",
"client_id": self.app_id,
"client_secret": self.app_secret
}
response = requests.get(url, params=params)
response.raise_for_status()
print(f"Short-lived token: {response.json()}")
return response.json()['access_token']
except requests.exceptions.RequestException as e:
print(f"Error getting short-lived user access token: {e}")
return None
def _get_long_lived_user_access_token(self, short_lived_token):
try:
url = f"https://graph.facebook.com/v20.0/oauth/access_token"
params = {
"grant_type": "fb_exchange_token",
"client_id": self.app_id,
"client_secret": self.app_secret,
"fb_exchange_token": short_lived_token
}
response = requests.get(url, params=params)
response.raise_for_status()
print(f"Long-lived access token: {response.json()}")
return response.json()['access_token']
except requests.exceptions.RequestException as e:
print(f"Error getting long-lived user access token: {e}")
return None
def _get_page_access_token(self, long_lived_token):
try:
url = f"https://graph.facebook.com/{self.page_id}"
params = {
"fields": "access_token",
"access_token": long_lived_token
}
response = requests.get(url, params=params)
response.raise_for_status()
print(f"Page access token: {response.json()}")
return response.json()["access_token"]
except Exception as e:
print(f"Error getting page access token: {e}")
return None
def authenticate(self):
# short_lived_token = self._get_short_lived_user_access_token()
# if not short_lived_token:
# return False
# long_lived_token = self._get_long_lived_user_access_token(short_lived_token)
# if not long_lived_token:
# return False
# self.page_access_token = self._get_page_access_token(long_lived_token)
self.page_access_token = settings.FACEBOOK_ACCESS_TOKEN
return True
def post_image_with_caption(self, image_path, caption):
if not self.page_access_token:
print("Page access token not obtained. Call Authenticate() first.")
return False
try:
url = f"https://graph.facebook.com/v20.0/{self.page_id}/media"
params = {
"caption": caption,
"image_url": image_path,
"access_token": self.page_access_token
}
response = requests.post(url, data=params)
# response.raise_for_status()
result = response.json()
print(f"Post image with caption result: {result}")
url = f"https://graph.facebook.com/v20.0/{self.page_id}/media_publish"
params = {
"creation_id": result["id"],
"access_token": self.page_access_token
}
response = requests.post(url, params=params)
# response.raise_for_status()
result = response.json()
return True
except Exception as e:
print(f"Error posting photo on instagram: {e}")
return False
class InstagramPoster:
def __init__(self, instagram_api):
self.instagram_api = instagram_api
def post_image_with_caption(self, image_path, caption):
if not self.instagram_api.authenticate():
print("Instagram API authentication failed.")
return {'success': False, 'message': 'Error posting photo. Authenticate failed'}
result = self.instagram_api.post_image_with_caption(image_path, caption)
if not result:
return {'success': False, 'message': 'Error posting photo in Instagram.'}
return {'success': True, 'message': 'Photo posted successfully'}

View File

@@ -343,3 +343,18 @@ PLACES_MAPS_API_KEY = env.str("GOOGLE_MAPS_API_KEY")
PLACES_MAP_WIDGET_HEIGHT = 480
PLACES_MAP_OPTIONS = '{"center": { "lat": 38.971584, "lng": -95.235072 }, "zoom": 10}'
PLACES_MARKER_OPTIONS = '{"draggable": true}'
# twitter keys
TWITTER_API_KEY = env.str("TWITTER_API_KEY")
TWITTER_API_SECRET_KEY = env.str("TWITTER_API_SECRET_KEY")
TWITTER_ACCESS_TOKEN = env.str("TWITTER_ACCESS_TOKEN")
TWITTER_ACCESS_TOKEN_SECRET = env.str("TWITTER_ACCESS_TOKEN_SECRET")
# facebook keys
FACEBOOK_APP_ID = env.str("FACEBOOK_APP_ID")
FACEBOOK_APP_SECRET = env.str("FACEBOOK_APP_SECRET")
FACEBOOK_PAGE_ID = env.str("FACEBOOK_PAGE_ID")
FACEBOOK_ACCESS_TOKEN = env.str("FACEBOOK_ACCESS_TOKEN")
# Instagram Key
INSTAGRAM_PAGE_ID = env.str('INSTAGRAM_PAGE_ID')

View File

@@ -59,8 +59,6 @@ class JsonResponseUtil:
response_data["errors"] = errors
return JsonResponse(response_data, status=status)
class RandomGenerator:
@staticmethod
def number(start, end):

View File

@@ -31,4 +31,10 @@ class EventFilter(filters.FilterSet):
def filter_category(self, queryset, name, value):
category = value.split(',')
return queryset.filter(category__title__in=category)
return queryset.filter(category__title__in=category)
# def filter_queryset(self, queryset):
# queryset = super().filter_queryset(queryset)
# if 'price_from' in self.data or 'price_to' in self.data:
# queryset = queryset.order_by('entry_fee')
# return queryset

View File

@@ -50,6 +50,18 @@ class EventCategorySerializer(serializers.ModelSerializer):
model = EventCategory
fields = ["id", "title", "image", "description", "video_url"]
def get_image_url(self, obj, field_name, request):
image_field = getattr(obj, field_name)
if image_field:
return request.build_absolute_uri(image_field.url)
return ""
def to_representation(self, instance):
data = super().to_representation(instance)
request = self.context.get("request")
data["image"] = self.get_image_url(instance, "image", request)
return data
class AgeGroupsSerializer(serializers.ModelSerializer):
class Meta:
model = AgeGroups

View File

@@ -586,7 +586,7 @@ class EventPreferencesView(APIView):
def get(self, request, *args, **kwargs):
"""Get all event categories for the authenticated user."""
obj = self.model.objects.filter(active=True, deleted=False)
serializer = self.serializer_class(obj, many=True)
serializer = self.serializer_class(obj, many=True, context={"request": request})
return ApiResponse.success(
data=serializer.data, message=constants.SUCCESS, status=status.HTTP_200_OK
)
@@ -1004,65 +1004,77 @@ class AgeGroupListView(APIView):
class EventListView(generics.ListAPIView):
authentication_classes = [JWTAuthentication]
permission_classes = [IsAuthenticated]
queryset = Event.objects.filter(active=True, draft=False, deleted=False, end_date__gte=timezone.now().date())
serializer_class = EventListSerializer
filter_backends = [DjangoFilterBackend]
filterset_class = EventFilter
def apply_popularity_latest(self, queryset, ordering):
# Split the ordering fields and remove any leading '-' characters
ordering_fields = [field.lstrip("-") for field in ordering.split(",")]
# Check if 'nearest' is in the ordering fields and remove it as nearest work only for lat and longitude
if "nearest" in ordering_fields:
ordering.replace("nearest", "")
ordering_fields.remove("nearest")
# Annotate the queryset with popularity if 'popularity' is in the ordering fields
if "popularity" in ordering_fields:
queryset = queryset.annotate(popularity=Count("interaction_event"))
# Replace 'latest' with '-created_on' in the ordering fields
ordering = ",".join(
"start_date" if field == "latest" else f"-{field}"
for field in ordering_fields
def get_queryset(self):
# Base queryset filtering active, non-draft, non-deleted events with end date in the future
queryset = Event.objects.filter(
active=True,
draft=False,
deleted=False,
end_date__gte=timezone.now().date()
)
# If ordering is empty, set a default ordering
if not ordering:
ordering = "-start_date"
if not self.request.query_params:
preferences = PrincipalPreference.objects.get(principal=self.request.user)
preferred_categories_ids = preferences.preferred_categories.values_list(
"id", flat=True
)
queryset = queryset.filter(category__in=preferred_categories_ids).order_by("start_date")
print(f"++++++++++++++++++++++++++++++++ordering data in populatirn flow {ordering}")
# Apply the ordering to the queryset
return queryset.order_by(*ordering.split(","))
return queryset
def get_queryset(self):
queryset = super().get_queryset()
def filter_queryset(self, queryset):
queryset = super().filter_queryset(queryset)
# Sort by nearest location if latitude and longitude are provided
latitude = self.request.query_params.get("latitude")
longitude = self.request.query_params.get("longitude")
ordering = self.request.query_params.get("ordering", "")
# Get query parameters
latitude = self.request.query_params.get("latitude", "")
longitude = self.request.query_params.get("longitude", "")
ordering = self.request.query_params.get("sort", "")
# Handle nearest location sorting
if latitude and longitude and "nearest" in ordering:
print("latitude fucntion called")
gmaps_service = GoogleMapsservice()
queryset = gmaps_service.get_nearest_events(queryset, float(latitude), float(longitude))
queryset = self.apply_nearest_filter(queryset, latitude, longitude)
print(f"=======orderring data is {ordering}")
# Handle popularity and latest sorting
queryset = self.apply_sorting(queryset, ordering)
return queryset
def apply_nearest_filter(self, queryset, latitude, longitude):
gmaps_service = GoogleMapsservice()
return gmaps_service.get_nearest_events(queryset, float(latitude), float(longitude))
def apply_sorting(self, queryset, ordering):
# Split ordering fields and process each field
ordering_fields = [field.lstrip("-") for field in ordering.split(",")]
# Remove 'nearest' from ordering as it's handled separately
if "nearest" in ordering_fields:
ordering_fields.remove("nearest")
ordering = ordering.replace("nearest", "")
# Annotate with popularity and order it if requested
if "popularity" in ordering_fields:
queryset = queryset.annotate(popularity=Count("interaction_event")).order_by("-popularity")
# order latest record and by default sorting
if "latest" in ordering_fields:
queryset = queryset.order_by("start_date")
if "price" in ordering_fields:
queryset = queryset.order_by('entry_fee')
# Apply popularity annotation and ordering if requested
if ordering:
queryset = self.apply_popularity_latest(queryset, ordering)
return queryset
def get(self, request, *args, **kwargs):
print(f"getquery set data is {self.get_queryset()}")
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
data = self.get_paginated_response(serializer.data)
return ApiResponse.success(message=constants.SUCCESS, data=data)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return ApiResponse.success(message=constants.SUCCESS, data=serializer.data)

View File

@@ -0,0 +1,30 @@
import os
from django.conf import settings
from django.core.management.base import BaseCommand
from goodtimes.services import FacebookAPI, FacebookPoster
from ...models import Event
class Command(BaseCommand):
help = 'Test facebook posting functionality'
def handle(self, *args, **kwargs):
event = Event.objects.get(id=20)
if not event:
self.stdout.write(self.style.ERROR("No event found."))
if not event.image:
self.stdout.write(self.style.ERROR("No image found."))
image_path = f"{settings.BASE_DOMAIN}{event.image.url}"
print(f"complete path of image {image_path}")
caption = f"{event.title}\nDuration: {event.start_date} to {event.end_date}\nAddress: {event.venue.address}"
facebook_api = FacebookAPI()
facebook_poster = FacebookPoster(facebook_api)
response = facebook_poster.post_photo(image_path, caption)
if response['success']:
self.stdout.write(self.style.SUCCESS(response['message']))
else:
self.stdout.write(self.style.ERROR(response['message']))

View File

@@ -0,0 +1,33 @@
import os
from django.conf import settings
from django.core.management.base import BaseCommand
from goodtimes.services import InstagramAPI, InstagramPoster
from ...models import Event
import urllib.request
class Command(BaseCommand):
help = 'Test Instagram posting functionality'
def handle(self, *args, **kwargs):
event = Event.objects.get(id=20)
if not event:
self.stdout.write(self.style.ERROR("No event found."))
if not event.image:
self.stdout.write(self.style.ERROR("No image found."))
image_path = f"{settings.BASE_DOMAIN}{event.image.url}"
# image_path = event.image.url
print(f"complete path of image {image_path}")
caption = f"{event.title}\nDuration: {event.start_date} to {event.end_date}\nAddress: {event.venue.address}"
instagram_api = InstagramAPI()
instagram_poster = InstagramPoster(instagram_api)
response = instagram_poster.post_image_with_caption(image_path, caption)
if response['success']:
self.stdout.write(self.style.SUCCESS(response['message']))
else:
self.stdout.write(self.style.ERROR(response['message']))

View File

@@ -0,0 +1,28 @@
import os
from django.core.management.base import BaseCommand
from goodtimes.services import TwitterAPI, TwitterPoster
from ...models import Event
class Command(BaseCommand):
help = 'Test Twitter posting functionality'
def handle(self, *args, **kwargs):
event = Event.objects.get(id=19)
if not event:
self.stdout.write(self.style.ERROR("No event found."))
if not event.image:
self.stdout.write(self.style.ERROR("No image found."))
image_path = event.image.path
caption = f"{event.title}\nDuration: {event.start_date} to {event.end_date}\nAddress: {event.venue.address}"
twitter_api = TwitterAPI()
twitter_poster = TwitterPoster(twitter_api)
response = twitter_poster.post_image_with_caption(image_path, caption)
if response['success']:
self.stdout.write(self.style.SUCCESS(response['message']))
else:
self.stdout.write(self.style.ERROR(response['message']))

View File

@@ -99,4 +99,6 @@ urlpatterns = [
views.GenerateEventReportView.as_view(),
name="generate_event_report",
),
path("post-to-social-media/<int:id>/<str:platform>/", views.SocialMediaPostView.as_view(), name="social_media_post")
]

View File

@@ -1,5 +1,6 @@
from django.shortcuts import get_object_or_404, redirect, render
from accounts import resource_action
from goodtimes.services import FacebookAPI, FacebookPoster, InstagramAPI, InstagramPoster, TwitterAPI, TwitterPoster
from goodtimes.utils import JsonResponseUtil
from manage_events.api.serializers import VenueSerializer, VenueShortSerializer
from manage_events.forms import (
@@ -532,7 +533,7 @@ class CustomerVenueFilterView(LoginRequiredMixin, generic.View):
User = get_user_model()
from .report import generate_event_report, generate_event_report_pdf_three
from django.http import HttpResponse
from django.http import HttpResponse, JsonResponse
class GenerateEventReportView(generic.View):
@@ -553,3 +554,77 @@ class GenerateEventReportView(generic.View):
response["Content-Disposition"] = f'attachment; filename="{filename}"'
return response
class SocialMediaPostView(generic.View):
def get(self, request, *args, **kwargs):
platform = kwargs.get("platform")
event_id = kwargs.get("id")
print(platform, event_id)
errors = []
success_messages = []
try:
event = Event.objects.get(id=event_id)
except Event.DoesNotExist:
errors.append("Event does not exist")
return JsonResponse({
'message': "Error in posting to social media",
'errors': errors,
'success_messages': success_messages
}, status=400)
if not event.active:
errors.append("Event is not active")
return JsonResponse({
'message': "Error in posting to social media",
'errors': errors,
'success_messages': success_messages
}, status=400)
caption = f"{event.title}\nDuration: {event.start_date} to {event.end_date}\nAddress: {event.venue.address}"
if platform in ['instagram', 'facebook', 'twitter', 'all']:
if platform in ['twitter', 'all']:
image_url = event.image.path
twitter_api = TwitterAPI()
twitter_poster = TwitterPoster(twitter_api)
result = twitter_poster.post_image_with_caption(image_url, caption)
if result['success']:
success_messages.append("Posted to Twitter successfully")
else:
errors.append("Fail to post on Twitter")
image_url = request.build_absolute_uri(event.image.url)
if platform in ['facebook', 'all']:
facebook_api = FacebookAPI()
facebook_poster = FacebookPoster(facebook_api)
result = facebook_poster.post_photo(image_url, caption)
if result["success"]:
success_messages.append("Posted to Facebook successfully")
else:
errors.append("Fail to post on Facebook")
if platform in ['instagram', 'all']:
instagram_api = InstagramAPI()
instagram_poster = InstagramPoster(instagram_api)
result = instagram_poster.post_image_with_caption(image_url, caption)
if result["success"]:
success_messages.append("Posted to Instagram successfully")
else:
errors.append("Fail to post on Instagram")
if not errors:
return JsonResponse({'message': 'Post Successful', 'errors': errors, 'success_messages': success_messages})
if errors and success_messages:
return JsonResponse({
'message': 'Some posts succeeded while others failed',
'errors': errors,
'success_messages': success_messages
}, status=200)
return JsonResponse({
'message': 'Error in posting to social media',
'errors': errors,
'success_messages': success_messages
}, status=400)

View File

@@ -69,8 +69,9 @@ sniffio==1.3.1
sqlparse==0.4.4
stripe==8.2.0
tqdm==4.66.2
tweepy==4.14.0
Twisted==23.10.0
# twisted-iocpsupport==1.0.4
twisted-iocpsupport==1.0.4
txaio==23.1.1
typing_extensions==4.9.0
tzdata==2024.1

BIN
static/img/facebook.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

BIN
static/img/instagram.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
static/img/x_twitter.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -2,12 +2,48 @@
{% load static %}
{% block stylesheet %}
<!-- include required css cdn link through html here -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
{% include "cdn_through_html/filepond_cdn_css.html" %}
{% include "cdn_through_html/quill_cdn_css.html" %}
{% include "cdn_through_html/tagify_cdn_css.html" %}
{% include "cdn_through_html/sweetalert2_cdn_css.html" %}
{{form.media}}
<style>
.social-circle {
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
}
.logos{
text-align:center;
margin-bottom:-390px;
}
.x{
margin:5px;
cursor: pointer;
}
.x_twitter{
width:50px;
height:50px;
}
.forward_all{
width:50px;
height:50px;
}
.instalogo{
width:50px;
height:50px;
}
.facelogo{
width:50px;
height:50px;
}
</style>
{% endblock %}
{% block content %}
@@ -25,15 +61,41 @@
{% endif %}
</div>
<div class="card mb-3" style="border-radius: 20px; box-shadow: 0 4px 8px rgba(0,0,0,.1);">
<div class="card-body">
<h2 class="card-title">{{ event.brand.title }}</h2>
<h3 class="card-title">{{ event.title }}</h3>
<p class="card-text"><strong>Description:</strong> {{ event.description }}</p>
<p class="card-text"><strong>Created By:</strong> {{ event.created_by }}</p>
<div class="row">
<div class="col-md-8">
<div class="card mb-3" style="border-radius: 20px; box-shadow: 0 4px 8px rgba(0,0,0,.1);">
<div class="card-body">
<h2 class="card-title">{{ event.brand.title }}</h2>
<h3 class="card-title">{{ event.title }}</h3>
<p class="card-text"><strong>Description:</strong> {{ event.description }}</p>
<p class="card-text"><strong>Created By:</strong> {{ event.created_by }}</p>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card mb-3" style="border-radius: 20px; box-shadow: 0 4px 8px rgba(0,0,0,.1);">
<div class="card-body">
<div class="social-circle">
<a data-platform="instagram" class="social-icon" data-toggle="tooltip" title="Post to Instagram">
<img src="{% static 'img/instagram.png'%}" class="x instalogo">
</a>
<a data-platform="facebook" class="social-icon" data-toggle="tooltip" title="Post to Facebook">
<img src="{% static 'img/facebook.png'%}" class="x facelogo">
</a>
<a data-platform="twitter" class="social-icon" data-toggle="tooltip" title="Post to Twitter">
<img src="{% static 'img/x_twitter.png'%}" class="x x_twitter">
</a>
<a data-platform="all" class="social-icon" data-toggle="tooltip" title="Post to All">
<img src="{% static 'img/forward_all_icon.png'%}" class="x forward_all">
</a>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="card mb-3" style="border-radius: 20px; box-shadow: 0 4px 8px rgba(0,0,0,.1);">
@@ -145,4 +207,97 @@
</div>
{% endblock content %}
{% endblock content %}
{% block javascript %}
<!-- include required css cdn link through html here -->
{% include "cdn_through_html/sweetalert2_cdn_js.html" %}
<script>
$(document).ready(function() {
// Initialize tooltips
$('[data-toggle="tooltip"]').tooltip();
$(".social-icon").on("click", function(e) {
console.log("social icon clicked");
e.preventDefault();
var platform = $(this).data("platform");
var eventId = "{{ event.id }}";
var platform_url = "{% url 'manage_events:social_media_post' id=0 platform='dummy' %}"
.replace('/0/', '/' + eventId + '/')
.replace('dummy', platform);
console.log(platform_url);
Swal.fire({
title: "Are you sure you want to post this event on " + platform + "?",
showCancelButton: true,
confirmButtonText: 'Yes',
cancelButtonText: 'No',
allowOutsideClick: false
}).then((result) => {
if (result.isConfirmed) {
Swal.fire({
title: 'Posting...',
allowOutsideClick: false,
didOpen: () => {
Swal.showLoading();
}
});
$.ajax({
url: platform_url,
type: "GET",
success: function(response) {
console.log(response);
Swal.close();
if (response.success_messages && response.errors && response.errors.length === 0) {
let successMessages = response.success_messages.join("<br>");
Swal.fire({
icon: "success",
title: "Success",
html: response.message + "<br>" + successMessages
});
} else if (response.errors && response.success_messages) {
let errorMessages = response.errors.join("<br>");
let successMessages = response.success_messages.join("<br>");
Swal.fire({
icon: "warning",
title: "Partial Success",
html: response.message + "<br>Successes:<br>" + successMessages + "<br>Failures:<br>" + errorMessages
});
} else if (response.errors) {
let errorMessages = response.errors.join("<br>");
Swal.fire({
icon: "error",
title: "Failures",
html: response.message + "<br>" + errorMessages
});
} else {
Swal.fire({
icon: "error",
title: "Error",
text: "Unknown error occurred"
});
}
},
error: function(xhr, status, error) {
Swal.close();
var errorMessage = xhr.responseJSON && xhr.responseJSON.message ? xhr.responseJSON.message : "Something went wrong. Please try again later.";
Swal.fire({
icon: "error",
title: "Error",
text: errorMessage
});
}
});
}
});
});
});
</script>
{%endblock javascript%}