add unfo/foing request

This commit is contained in:
Tan, Kian-ting 2022-11-26 05:01:20 +08:00
parent 0b1b077feb
commit c5a762a646
7 changed files with 190 additions and 48 deletions

View file

@ -52,6 +52,15 @@ class User(AbstractUser):
class Following(models.Model):
follower = models.ForeignKey(User, on_delete=models.CASCADE, related_name="follower")
followee = models.ForeignKey(User, on_delete=models.CASCADE, related_name="followee")
IS_DECIDED = [
('undecided', 'undecided'),
('yes', 'yes'),
]
isapproved = models.CharField(
max_length=9,
choices=IS_DECIDED,
default='undecided',
)
class Post(models.Model):

View file

@ -32,6 +32,7 @@ urlpatterns = [
path('api/get_latest_posts', views.api_get_latest_posts),
path('api/get_previous_posts', views.api_get_previous_posts),
path('user/<username>', views.user_timeline),
path('api/follow_request/<request_value>/<dest_username>', views.follow_request)
]
if settings.DEBUG:

View file

@ -1,5 +1,5 @@
import json
from django.http import HttpResponse
from django.http import HttpResponse, HttpResponseNotAllowed
from django.template import loader
from .models import User, Post, Following
from django.utils import timezone
@ -24,7 +24,19 @@ def api_get_previous_posts(request):
post_body_json = json.loads(post_body_orig)
oldest_time = post_body_json["oldest_time"]
oldest_datetime_object = datetime.strptime(oldest_time, '%Y-%m-%d %H:%M:%S.%f%z')
older_posts = Post.objects.filter(post_time__lt=oldest_datetime_object).order_by('-id')[:20]
note = post_body_json["request_note"]
if note["type"] == "home":
all_i_follow = Following.objects.filter(follower=request.user.id).filter(isapproved="yes")
all_i_follow_and_me = User.objects.filter(Q(id__in = all_i_follow) | Q(id=request.user.id))
older_posts = Post.objects.filter(post_time__lt=oldest_datetime_object).filter(poster__in = all_i_follow_and_me).order_by('-id')[:20]
elif note["type"] == "user":
username = note["arg"]
poster = User.objects.get(username=username)
older_posts = Post.objects.filter(post_time__lt=oldest_datetime_object).filter(poster=poster).order_by('-id')[:20]
else:
pass
older_posts_list = [{"id" : o.pk,
"post_time" : datetime.strftime(o.post_time, "%Y-%m-%d %H:%M:%S.%f%z"),
"poster_username" : o.poster.username,
@ -37,6 +49,8 @@ def api_get_previous_posts(request):
oldest_time = oldest_time
return JsonResponse({'older_posts':older_posts_list,
'oldest_time': oldest_time})
else:
return HttpResponseNotAllowed('POST')
@ -46,7 +60,18 @@ def api_get_latest_posts(request):
post_body_json = json.loads(post_body_orig)
latest_time = post_body_json["latest_time"]
latest_datetime_object = datetime.strptime(latest_time, '%Y-%m-%d %H:%M:%S.%f%z')
newer_posts = Post.objects.filter(post_time__gte=latest_datetime_object)
note = post_body_json["request_note"]
if note["type"] == "home":
all_i_follow = Following.objects.filter(follower=request.user.id).filter(isapproved="yes")
all_i_follow_and_me = User.objects.filter(Q(id__in = all_i_follow) | Q(id=request.user.id))
newer_posts = Post.objects.filter(post_time__gt=latest_datetime_object).filter(poster__in = all_i_follow_and_me).order_by('-id')[:20]
elif note["type"] == "user":
username = note["arg"]
poster = User.objects.get(username=username)
newer_posts = Post.objects.filter(post_time__gt=latest_datetime_object).filter(poster=poster).order_by('-id')[:20]
newer_posts_list = [{"id" : o.pk,
"post_time" : datetime.strftime(o.post_time, "%Y-%m-%d %H:%M:%S.%f%z"),
"poster_username" : o.poster.username,
@ -54,6 +79,8 @@ def api_get_latest_posts(request):
"text": o.text}
for o in newer_posts]
return JsonResponse({'newer_posts':newer_posts_list})
else:
return HttpResponseNotAllowed('POST')
def api_get_recent_posts_counter(request):
if request.method == 'POST':
@ -61,8 +88,28 @@ def api_get_recent_posts_counter(request):
post_body_json = json.loads(post_body_orig)
latest_time = post_body_json["latest_time"]
latest_datetime_object = datetime.strptime(latest_time, '%Y-%m-%d %H:%M:%S.%f%z')
newer_posts_len = Post.objects.filter(post_time__gte=latest_datetime_object).exclude(Q(poster=request.user) & Q(post_time=latest_datetime_object)).__len__()
note = post_body_json["request_note"]
if note["type"] == "home":
all_i_follow = Following.objects.filter(follower=request.user.id).filter(isapproved="yes")
all_i_follow_and_me = User.objects.filter(Q(id__in = all_i_follow) | Q(id=request.user.id))
newer_posts_len = Post.objects.filter(post_time__gte=latest_datetime_object) \
.filter(poster__in = all_i_follow_and_me) \
.exclude(Q(poster=request.user) & Q(post_time=latest_datetime_object)) \
.__len__()
elif note["type"] == "user":
username = note["arg"]
poster = User.objects.get(username=username)
newer_posts_len = Post.objects.filter(post_time__gte=latest_datetime_object) \
.filter(poster=poster) \
.exclude(Q(post_time=latest_datetime_object)) \
.__len__()
return JsonResponse({'newer_posts_num':newer_posts_len})
else:
return HttpResponseNotAllowed('POST')
@ -82,6 +129,8 @@ def api_post(request):
post_time = timezone.now())
a_post.save()
return HttpResponse(200, str(post_text))
else:
return HttpResponseNotAllowed('POST')
def signup(request):
small_letters_a_to_z = string.ascii_letters
@ -170,8 +219,9 @@ def user_config(request):
class Meta:
model = User
fields = ('shown_name', 'avatar', 'desc', 'email')
fields = ('shown_name', 'desc', 'avatar', 'email')
avatar = forms.ImageField(required = False)
if request.user == AnonymousUser():
@ -186,9 +236,13 @@ def user_config(request):
if form.is_valid():
print(old_image_path)
image_path = os.path.abspath(f"./media/{current_user.avatar.name}")
try:
avatar_path_in_form = form.cleaned_data['avatar'].path
except AttributeError:
avatar_path_in_form = form.cleaned_data['avatar']
if os.path.exists(old_image_path) and (old_image_path != os.path.abspath("./media/static/default_avatar.png")):
if avatar_path_in_form != old_image_path and is_custom_avatar_path(old_image_path):
a = os.remove(old_image_path)
print(a)
@ -209,14 +263,54 @@ def user_config(request):
pass
current_user = User.objects.get(id=request.user.id)
form = UserConfigForm(initial={'shown_name': request.user.shown_name,
'desc' : request.user.desc,
'url' : request.user.url,
'email' : request.user.email})
form = UserConfigForm(initial={'shown_name': current_user.shown_name,
'desc' : current_user.desc,
'url' : current_user.url,
'email' : current_user.email})
template = loader.get_template('user_config.html')
return HttpResponse(template.render({'form': form, 'avatar': current_user.avatar}, request))
def is_custom_avatar_path(old_image_path):
return os.path.exists(old_image_path) and (old_image_path != os.path.abspath("./media/static/default_avatar.png"))
def follow_request(request, request_value, dest_username):
if request.method != "POST":
return HttpResponseNotAllowed('POST')
else:
current_user = User.objects.get(id=request.user.id)
dest_user = User.objects.get(username=dest_username)
if request_value == "send-following-request":
following_status = Following(follower=current_user, followee= dest_user, isapproved="undecided")
following_status.save()
return JsonResponse({'status': "request sent"})
elif request_value == "cancel-following-request":
following_status = Following.objects.get(follower=current_user.id, followee= dest_user.id)
following_status.delete()
return JsonResponse({'status': "request cancelled"})
elif request_value == "unfollow":
following_status = Following.objects.get(follower=current_user.id, followee= dest_user.id)
following_status.delete()
return JsonResponse({'status': "unfollowed"})
else:
return JsonResponse({'status': "other"})
def user_timeline(request, username):
user_id = User.objects.get(username=username).id
user_following_number = Following.objects.filter(follower=user_id).filter(isapproved="yes").__len__()
user_follower_number = Following.objects.filter(followee=user_id).filter(isapproved="yes").__len__()
following_relationship = Following.objects.filter(follower=request.user.id).filter(followee=user_id)
following_status = ""
if following_relationship.__len__() == 0:
following_status = "unfollowed"
else:
following_status = following_relationship[0].isapproved
viewed_user = User.objects.get(username=username)
if Following.objects.filter(follower = request.user.id).filter(followee=viewed_user.id) or request.user.id == viewed_user.id:
@ -235,6 +329,9 @@ def user_timeline(request, username):
context = {
'username' : username,
'user_shown_name' : viewed_user.shown_name,
'following_status': following_status,
'user_following_number' : user_following_number,
'user_follower_number': user_follower_number,
'latest_received_time' : latest_received_time,
'oldest_received_time' : oldest_received_time,
'viewed_timeline_list': viewed_timeline_list,
@ -246,7 +343,9 @@ def home(request):
if request.user == AnonymousUser():
return redirect('/account/login') # redirect to main page
public_timeline_list = Post.objects.filter(privilage = 'public').order_by('-id')[:20]
all_i_follow = Following.objects.filter(follower=request.user.id).filter(isapproved="yes")
all_i_follow_and_me = User.objects.filter(Q(id__in = all_i_follow) | Q(id=request.user.id))
public_timeline_list = Post.objects.filter(poster__in = all_i_follow_and_me).order_by('-id')[:20]
latest_received_time = timezone.now()

View file

@ -15,6 +15,15 @@ x => timezoneChangingOne(x)
);
}
var requestNote = {"type" : "home", "arg" : ""};
var pathName = window.location.pathname;
var homePattern = /[/]home[/]/;
var userPagePattern = /[/]user[/]([^/]+)/;
var userIdName = "";
if (pathName.match(userPagePattern)){
userIdName = pathName.match(userPagePattern)[1];
requestNote = {"type" : "user", "arg" : userIdName};
}
@ -25,7 +34,8 @@ csrf_token = $("_token").content;
var httpRequest;
$("submit_post").addEventListener('click', make_req);
async function make_req() {
@ -44,7 +54,8 @@ headers: {
},
body: JSON.stringify({
"privilage" : post_privilage,
"text": post_text,
"text" : post_text,
"request_note" : requestNote,
})
}).then(response => {if (response.ok == true)
@ -83,10 +94,11 @@ headers: {
},
body: JSON.stringify({
"latest_time" : latest_time_string,
"request_note" : requestNote,
})
}).then(response => response.json())
.then(the_json => {console.log(the_json);let newer_posts_num = the_json['newer_posts_num'];
.then(the_json => {let newer_posts_num = the_json['newer_posts_num'];
if (newer_posts_num == 1)
{ $("new_post_notifier").style.display = "block";
$("new_post_notifier").innerHTML = `1 new post`}
@ -117,6 +129,8 @@ headers: {
},
body: JSON.stringify({
"oldest_time" : oldest_time_string,
"request_note" : requestNote,
}) }).then(response => response.json())
.then(item => {new_oldest_time_raw = item['oldest_time'];
new_oldest_time = new_oldest_time_raw.substring(0,10) + " " + new_oldest_time_raw.substring(11,26) + "+0000";
@ -128,6 +142,31 @@ body: JSON.stringify({
}
async function make_follow_req(){
requestValue = $("follow-user-button").value;
await fetch(`/api/follow_request/${requestValue}/${userIdName}`, {
method: 'POST',
headers: {
"X-CSRFToken": csrf_token,
'Content-Type': 'application/json',
},
body : ""
}).then(response => response.json())
.then(
item =>{
returnValue = item["status"];
if (returnValue == "request sent"){
$("follow-user-button").value = "cancel-following-request";
$("follow-user-button").innerHTML = "Cancel Following Request";
}
else if(returnValue == "request cancelled" || returnValue == "unfollowed"){
$("follow-user-button").value = "send-following-request";
$("follow-user-button").innerHTML = "Follow";
}
}
)
}
async function getLatestPosts(){
latest_time_string = $("latest_time").innerHTML;
await fetch('/api/get_latest_posts', {
@ -138,7 +177,9 @@ headers: {
},
body: JSON.stringify({
"latest_time" : latest_time_string,
}) }).then(response => response.json())
"request_note" : requestNote,
}) })
.then(response => response.json())
.then(item => item['newer_posts'])
.then(posts => {posts.forEach(post => addPostToTheBeginning(post));
$('new_post_notifier').style.display = "none";
@ -153,7 +194,6 @@ var new_div = document.createElement("div");
new_div.id = `post-${post.id}`;
new_div.className = "post";
post_text_replaced = post.text.replace(/(\r\n|\n\r|\r|\n)/g, "<br>" );
console.log(post_text_replaced);
new_div.innerHTML = `<a href="/user/${post.poster_username}">${post.poster_shown_name}</a>
at <a href="/post/${post.id}" class="post-time">${post.post_time}</a><br>
${post_text_replaced}<br>
@ -181,5 +221,10 @@ $("new_post_notifier").addEventListener('click', getLatestPosts);
$("previous_post_loader").addEventListener('click', getPreviousPosts);
adjust_post_text();
if (requestNote["type"] == "home"){
$("submit_post").addEventListener('click', make_req);
adjust_post_text();
}
if (requestNote["type"] == "user"){
$("follow-user-button").addEventListener('click', make_follow_req);
}

View file

@ -5,13 +5,13 @@
{% block meta%}
{% endblock %}
<meta charset="utf-8">
{% block title %}<title>Local Library</title>
{% block title %}<title>Khaikang</title>
<link type="text/css" rel="stylesheet" href="{% static 'generic.css' %}"></style>
{% endblock %}
</head>
<body>
<h1 id="title">{%block title}Kianting.social{%endblock title}</h1>
<h1 id="title">{%block maintitle %}Kianting.social{% endblock %}</h1>
<div id="headbar">{% block headbar %}{% endblock headbar%}</div>
<div id="sidebar">{% block sidebar %}<!-- insert default navigation text for every page -->{% endblock %}</div>
<div id="content">{% block content %}<!-- default content text (typically empty) -->{% endblock %}</div>

View file

@ -14,7 +14,6 @@
<form method="POST" id="posting-form">
{% csrf_token %}
<div class="posting-form-group">
<label>Post</label>
<textarea id="post_text" name="post_text" placeholder="What do you want to post?"
maxlength="500" style="resize: none;" oninput="auto_expand(this)"></textarea>
@ -30,7 +29,7 @@
<option value="private">Private</option>
</select>
<button id="submit_post" type="button" class="btn">Post!</button>
<button id="submit_post" type="button" class="btn">Kóng!</button>
</form>
<div id="public_timeline">

View file

@ -11,28 +11,18 @@
{% endblock %}
{% block content %}
<form method="POST" id="posting-form">
{% csrf_token %}
<div class="posting-form-group">
<label>Post</label>
<div id="intro"><div id="intro-shown-name">{{user_shown_name}}</div><div id="intro-id-name">{{username}}</div>
{% if username == request.user.username %}
My account<br>
{% endif %}
{% if username != request.user.username %}
{% if following_status == "unfollowed" %}<button value="send-following-request" id="follow-user-button">Follow</button><br>{% endif %}
{% if following_status == "undecided" %}<button value="cancel-following-request" id="follow-user-button">Cancel Following Request</button><br>{% endif %}
{% if following_status == "yes" %}<button value="unfollow" id="follow-user-button">Unfollow</button><br>{% endif %}
<textarea id="post_text" name="post_text" placeholder="What do you want to post?"
maxlength="500" style="resize: none;" oninput="auto_expand(this)"></textarea>
</div>
{% endif %}
Following: <span class="fo-number">{{user_following_number}}</span> Follower: <span class="fo-number">{{user_follower_number}}</span></div>
{% csrf_token %}
<label for="privilege">Privileges:</label>
<select name="privilege" id="privil_choosing">
<option value="public" selected>Public Timeline</option>
<option value="unpublic">Not in Public Timeline</option>
<option value="private">Private</option>
</select>
<button id="submit_post" type="button" class="btn">Post!</button>
</form>
<div id="intro">{{user_shown_name}}<br>{{username}}</div>
<div id="public_timeline">
<div id="new_post_notifier" value=""></div>
<div id="latest_time" style="display: block;">{{latest_received_time|date:"Y-m-d H:i:s.u"}}+0000</div>
@ -52,8 +42,7 @@
</div>
<pre> % static 'timeline.js' 要修改
</pre>
<script type="text/javascript" src="{% static 'timeline.js' %}">