Skip to content
This repository was archived by the owner on Aug 26, 2024. It is now read-only.

Commit 71e3b03

Browse files
committed
fix merge conflicts
2 parents df3b000 + 80d1d71 commit 71e3b03

File tree

8 files changed

+156
-130
lines changed

8 files changed

+156
-130
lines changed

.gitignore

+5-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
# $GIT_DIR/info/exclude or the core.excludesFile configuration variable as
33
# described in https://git-scm.com/docs/gitignore
44
settings_local.py
5-
credentials.json
5+
Pipfile
6+
Pipfile.lock
7+
68
# Byte-compiled / optimized / DLL files
79
__pycache__/
810
*.py[cod]
@@ -21,5 +23,5 @@ logs/*
2123
.vscode
2224

2325
# Google Calendar creds
24-
scripts/credentials.json
25-
google_api_token.pickle
26+
credentials.json
27+
token.json

aldryn_newsblog/views.py

+10-7
Original file line numberDiff line numberDiff line change
@@ -243,13 +243,16 @@ def get_queryset(self):
243243
qs = super(ArticleList, self).get_queryset()
244244
# exclude featured articles from queryset, to allow featured article
245245
# plugin on the list view page without duplicate entries in page qs.
246-
exclude_count = self.config.exclude_featured
247-
if exclude_count:
248-
featured_qs = Article.objects.all().filter(is_featured=True)
249-
if not self.edit_mode:
250-
featured_qs = featured_qs.published()
251-
exclude_featured = featured_qs[:exclude_count].values_list('pk')
252-
qs = qs.exclude(pk__in=exclude_featured)
246+
try:
247+
exclude_count = self.config.exclude_featured
248+
if exclude_count:
249+
featured_qs = Article.objects.all().filter(is_featured=True)
250+
if not self.edit_mode:
251+
featured_qs = featured_qs.published()
252+
exclude_featured = featured_qs[:exclude_count].values_list('pk')
253+
qs = qs.exclude(pk__in=exclude_featured)
254+
except Exception:
255+
pass
253256
return qs
254257

255258

blogs_list/feeds.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ def get_object(self, request):
146146
articles = list(articles_all[start_index:end_index])
147147
return articles
148148
else:
149-
raise ObjectDoesNotExist
149+
return []
150150

151151
def feed_extra_kwargs(self, obj):
152152
return {

docs/README.md

+10
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@ Default student users are `student-1`, `student-2`, `student-3` and `student-4`
3636
## Contributing
3737
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
3838

39+
## Google OAuth
40+
- Go to https://console.cloud.google.com/ and create a new project
41+
- Enable Google Calendar API and create an OAuth 2.0 client ID
42+
- add following on the Authorised redirect URIs of OAuth client ID
43+
```bash
44+
http://localhost/
45+
```
46+
- Download the JSON file and rename it to `credentials.json`
47+
- Move the file to the root folder of the project
48+
3949
## Virtualenv
4050

4151
A virtual environment is a tool that helps to keep dependencies required by different projects separate by creating isolated python virtual environments for them. This means that each project can have its own dependencies, regardless of what dependencies every other project has. We use a module named `virtualenv` which is a tool to create isolated Python environments. `virtualenv` creates a folder which contains all the necessary executables to use the packages that a Python project would need.

gsoc/forms.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import re
12
from PIL import Image
23

34
from .models import (
@@ -51,7 +52,7 @@ class Meta:
5152
class BlogPostDueDateForm(forms.ModelForm):
5253
class Meta:
5354
model = BlogPostDueDate
54-
fields = ("title", "date", "category")
55+
fields = ("category", "date", "title")
5556

5657

5758
class EventForm(forms.ModelForm):
@@ -121,8 +122,12 @@ def clean(self):
121122

122123
if not suborg and suborg_name:
123124
suborg = SubOrg.objects.filter(suborg_name=suborg_name)
124-
if len(suborg) > 0:
125+
if suborg:
125126
cd["suborg"] = suborg.first()
127+
else:
128+
regex = r'^[ a-zA-Z\-]*$'
129+
if not re.match(regex, suborg_name):
130+
raise ValidationError("Invalid suborg name.")
126131
elif suborg and not suborg_name:
127132
cd["suborg_name"] = suborg.suborg_name
128133
elif suborg and suborg_name:

gsoc/management/commands/googleapiauth.py

-25
This file was deleted.

gsoc/models.py

+123-78
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import datetime
44
import uuid
55
import json
6-
import pickle
76
import bleach
87
from urllib.parse import urljoin
98

@@ -43,6 +42,11 @@
4342
from gsoc.settings import PROPOSALS_PATH, BASE_DIR
4443
from settings_local import ADMINS
4544

45+
from google.auth.transport.requests import Request
46+
from google.oauth2.credentials import Credentials
47+
from google_auth_oauthlib.flow import InstalledAppFlow
48+
49+
SCOPES = ['https://www.googleapis.com/auth/calendar']
4650

4751
# Util Functions
4852

@@ -51,6 +55,27 @@ def gen_uuid_str():
5155
return str(uuid.uuid4())
5256

5357

58+
def getCreds():
59+
creds = None
60+
if os.path.exists(os.path.join(BASE_DIR, 'token.json')):
61+
creds = Credentials.from_authorized_user_file(
62+
os.path.join(BASE_DIR, 'token.json'),
63+
SCOPES
64+
)
65+
if not creds or not creds.valid:
66+
if creds and creds.expired and creds.refresh_token:
67+
creds.refresh(Request())
68+
else:
69+
flow = InstalledAppFlow.from_client_secrets_file(
70+
os.path.join(BASE_DIR, 'credentials.json'),
71+
SCOPES
72+
)
73+
creds = flow.run_local_server(port=0)
74+
with open(os.path.join(BASE_DIR, 'token.json'), 'w') as token:
75+
token.write(creds.to_json())
76+
return creds
77+
78+
5479
# Patching
5580

5681
NewsBlogConfig.__str__ = lambda self: self.app_title
@@ -559,14 +584,12 @@ class Timeline(models.Model):
559584

560585
def add_calendar(self):
561586
if not self.calendar_id:
562-
tpath = os.path.join(BASE_DIR, "google_api_token.pickle")
563-
with open(tpath, "rb") as token:
564-
creds = pickle.load(token)
565-
service = build("calendar", "v3", credentials=creds)
566-
calendar = {"summary": "GSoC @ PSF Calendar", "timezone": "UTC"}
567-
calendar = service.calendars().insert(body=calendar).execute()
568-
self.calendar_id = calendar.get("id")
569-
self.save()
587+
creds = getCreds()
588+
service = build("calendar", "v3", credentials=creds, cache_discovery=False)
589+
calendar = {"summary": "GSoC @ PSF Calendar", "timezone": "UTC"}
590+
calendar = service.calendars().insert(body=calendar).execute()
591+
self.calendar_id = calendar.get("id")
592+
self.save()
570593

571594

572595
class Builder(models.Model):
@@ -602,51 +625,45 @@ class Event(models.Model):
602625
@property
603626
def calendar_link(self):
604627
if self.event_id:
605-
tpath = os.path.join(BASE_DIR, "google_api_token.pickle")
606-
with open(tpath, "rb") as token:
607-
creds = pickle.load(token)
608-
service = build("calendar", "v3", credentials=creds)
609-
event = (
610-
service.events()
611-
.get(calendarId=self.timeline.calendar_id, eventId=self.event_id)
612-
.execute()
613-
)
614-
return event.get("htmlLink", None)
628+
creds = getCreds()
629+
service = build("calendar", "v3", credentials=creds, cache_discovery=False)
630+
event = (
631+
service.events()
632+
.get(calendarId=self.timeline.calendar_id, eventId=self.event_id)
633+
.execute()
634+
)
635+
return event.get("htmlLink", None)
615636
return None
616637

617638
def add_to_calendar(self):
618-
tpath = os.path.join(BASE_DIR, "google_api_token.pickle")
619-
with open(tpath, "rb") as token:
620-
creds = pickle.load(token)
621-
service = build("calendar", "v3", credentials=creds)
622-
event = {
623-
"summary": self.title,
624-
"start": {"date": self.start_date.strftime("%Y-%m-%d")},
625-
"end": {"date": self.end_date.strftime("%Y-%m-%d")},
626-
}
627-
cal_id = self.timeline.calendar_id if self.timeline else "primary"
628-
if not self.event_id:
629-
event = (
630-
service.events()
631-
.insert(calendarId=cal_id, body=event)
632-
.execute()
633-
)
634-
self.event_id = event.get("id")
635-
self.save()
636-
else:
637-
service.events().update(
638-
calendarId=cal_id, eventId=self.event_id, body=event
639-
).execute()
639+
creds = getCreds()
640+
service = build("calendar", "v3", credentials=creds, cache_discovery=False)
641+
event = {
642+
"summary": self.title,
643+
"start": {"date": self.start_date.strftime("%Y-%m-%d")},
644+
"end": {"date": self.end_date.strftime("%Y-%m-%d")},
645+
}
646+
cal_id = self.timeline.calendar_id if self.timeline else "primary"
647+
if not self.event_id:
648+
event = (
649+
service.events()
650+
.insert(calendarId=cal_id, body=event)
651+
.execute()
652+
)
653+
self.event_id = event.get("id")
654+
self.save()
655+
else:
656+
service.events().update(
657+
calendarId=cal_id, eventId=self.event_id, body=event
658+
).execute()
640659

641660
def delete_from_calendar(self):
642661
if self.event_id:
643-
tpath = os.path.join(BASE_DIR, "google_api_token.pickle")
644-
with open(tpath, "rb") as token:
645-
creds = pickle.load(token)
646-
service = build("calendar", "v3", credentials=creds)
647-
service.events().delete(
648-
calendarId=self.timeline.calendar_id, eventId=self.event_id
649-
).execute()
662+
creds = getCreds()
663+
service = build("calendar", "v3", credentials=creds, cache_discovery=False)
664+
service.events().delete(
665+
calendarId=self.timeline.calendar_id, eventId=self.event_id
666+
).execute()
650667

651668
def save(self, *args, **kwargs):
652669
if not self.end_date:
@@ -666,7 +683,7 @@ class BlogPostDueDate(models.Model):
666683
class Meta:
667684
ordering = ["date"]
668685

669-
title = models.CharField(max_length=100, default="Weekly Blog Post Due")
686+
title = models.CharField(max_length=100, default="Loading...")
670687
date = models.DateField()
671688
timeline = models.ForeignKey(
672689
Timeline,
@@ -692,38 +709,34 @@ class Meta:
692709
category = models.IntegerField(choices=categories, null=True, blank=True)
693710

694711
def add_to_calendar(self):
695-
tpath = os.path.join(BASE_DIR, "google_api_token.pickle")
696-
with open(tpath, "rb") as token:
697-
creds = pickle.load(token)
698-
service = build("calendar", "v3", credentials=creds)
699-
event = {
700-
"summary": self.title,
701-
"start": {"date": self.date.strftime("%Y-%m-%d")},
702-
"end": {"date": self.date.strftime("%Y-%m-%d")},
703-
}
704-
cal_id = self.timeline.calendar_id if self.timeline else "primary"
705-
if not self.event_id:
706-
event = (
707-
service.events()
708-
.insert(calendarId=cal_id, body=event)
709-
.execute()
710-
)
711-
self.event_id = event.get("id")
712-
self.save()
713-
else:
714-
service.events().update(
715-
calendarId=cal_id, eventId=self.event_id, body=event
716-
).execute()
712+
creds = getCreds()
713+
service = build("calendar", "v3", credentials=creds, cache_discovery=False)
714+
event = {
715+
"summary": self.title,
716+
"start": {"date": self.date.strftime("%Y-%m-%d")},
717+
"end": {"date": self.date.strftime("%Y-%m-%d")},
718+
}
719+
cal_id = self.timeline.calendar_id if self.timeline else "primary"
720+
if not self.event_id:
721+
event = (
722+
service.events()
723+
.insert(calendarId=cal_id, body=event)
724+
.execute()
725+
)
726+
self.event_id = event.get("id")
727+
self.save()
728+
else:
729+
service.events().update(
730+
calendarId=cal_id, eventId=self.event_id, body=event
731+
).execute()
717732

718733
def delete_from_calendar(self):
719734
if self.event_id:
720-
tpath = os.path.join(BASE_DIR, "google_api_token.pickle")
721-
with open(tpath, "rb") as token:
722-
creds = pickle.load(token)
723-
service = build("calendar", "v3", credentials=creds)
724-
service.events().delete(
725-
calendarId=self.timeline.calendar_id, eventId=self.event_id
726-
).execute()
735+
creds = getCreds()
736+
service = build("calendar", "v3", credentials=creds, cache_discovery=False)
737+
service.events().delete(
738+
calendarId=self.timeline.calendar_id, eventId=self.event_id
739+
).execute()
727740

728741
def create_scheduler(self):
729742
if not BLOG_POST_DUE_REMINDER.disabled:
@@ -794,6 +807,18 @@ def save(self, *args, **kwargs):
794807
post2.save()
795808
except Exception:
796809
pass
810+
811+
# update title
812+
gsoc_year = GsocYear.objects.latest('gsoc_year')
813+
timeline = Timeline.objects.get(gsoc_year=gsoc_year)
814+
items = BlogPostDueDate.objects.filter(timeline=timeline)
815+
if self.category == 0:
816+
num = sum([1 for item in items if "Weekly Check-in Due" in item.title])
817+
self.title = f"Weekly Check-in Due {num}"
818+
else:
819+
num = sum([1 for item in items if "Weekly Blog Post Due" in item.title])
820+
self.title = f"Weekly Blog Post Due {num}"
821+
797822
super(BlogPostDueDate, self).save(*args, **kwargs)
798823

799824

@@ -1530,3 +1555,23 @@ def add_review(sender, instance, **kwargs):
15301555
@receiver(models.signals.post_save, sender=Article)
15311556
def add_history(sender, instance, **kwargs):
15321557
BlogPostHistory.objects.create(article=instance, content=instance.lead_in)
1558+
1559+
1560+
# Delete add_blog_counter scheduler when BlopPostDueDate object is deleted
1561+
@receiver(models.signals.post_delete, sender=BlogPostDueDate)
1562+
def delete_add_blog_counter_scheduler(sender, instance, **kwargs):
1563+
try:
1564+
Scheduler.objects.get(id=instance.add_counter_scheduler.id).delete()
1565+
except Scheduler.DoesNotExist:
1566+
pass
1567+
1568+
1569+
# Update add_blog_counter scheduler when BlopPostDueDate object is changed
1570+
@receiver(models.signals.post_save, sender=BlogPostDueDate)
1571+
def update_add_blog_counter_scheduler(sender, instance, **kwargs):
1572+
try:
1573+
scheduler = Scheduler.objects.get(id=instance.add_counter_scheduler.id)
1574+
scheduler.activation_date = instance.date + datetime.timedelta(days=-6)
1575+
scheduler.save()
1576+
except Scheduler.DoesNotExist:
1577+
pass

0 commit comments

Comments
 (0)