-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
150 lines (111 loc) · 4.91 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import os
import math
import random
import datetime
import requests
import instagrapi
from instagrapi.types import StoryLink
from PIL import Image, ImageDraw, ImageFont, ImageEnhance, ImageFilter
from dotenv import load_dotenv
load_dotenv()
WORKING_DIRECTORY_PATH = os.getenv('WORKING_DIRECTORY_PATH')
if WORKING_DIRECTORY_PATH:
if WORKING_DIRECTORY_PATH[-1] != '/':
WORKING_DIRECTORY_PATH += '/'
INSTAGRAM_USERNAME = os.getenv('INSTAGRAM_USERNAME')
if not INSTAGRAM_USERNAME:
raise Exception("INSTAGRAM_USERNAME not set!")
INSTAGRAM_PASSWORD = os.getenv('INSTAGRAM_PASSWORD')
if not INSTAGRAM_PASSWORD:
raise Exception("INSTAGRAM_PASSWORD not set!")
INSTAGRAM_2FA_SEED = os.getenv('INSTAGRAM_2FA_SEED')
def getDuck(duckid: int):
url = "https://random-d.uk/api/{}.jpg".format(duckid)
response = requests.get(url)
if response.status_code == 200:
duckPath = WORKING_DIRECTORY_PATH + 'duck.jpg'
open(duckPath, "wb").write(response.content)
return duckPath
raise Exception("Error getting duck: {}".format(response.status_code))
def formatImage(duckpath: str):
base = Image.new('RGB', (1080,1920), (255,255,0))
duck = Image.open(duckpath)
originalDuck = duck.copy()
#~ Resize and spawn multiple image of duck in the background
wPercent = (216/float(originalDuck.size[0]))
hSize = int((float(originalDuck.size[1])*float(wPercent)))
smallDuck = originalDuck.resize((216,hSize), Image.Resampling.LANCZOS)
#~ Reduce brightness & blur, goal is to put in foreground the main duck
smallDuck = ImageEnhance.Brightness(smallDuck).enhance(.75)
smallDuck = smallDuck.filter(ImageFilter.GaussianBlur(4))
for i in range( math.ceil(base.size[1]/hSize) ):
for j in range( math.ceil(base.size[0]/smallDuck.size[0]) ):
base.paste(smallDuck, (j*smallDuck.size[0],i*smallDuck.size[1]))
#~ Resize the image to fit, if it's too large (>1000) or too small (<800)
if duck.size[0] > 1000 or duck.size[0] < 800:
wPercent = (1000/float(duck.size[0]))
hSize = int((float(duck.size[1])*float(wPercent)))
duck = duck.resize((1000,hSize), Image.Resampling.LANCZOS)
wPos = int((1080-duck.size[0])/2)
hPos = int((1920-duck.size[1])/2)
base.paste(duck, (wPos, hPos))
base.save(duckpath, quality=95)
def addCaption(duckpath: str, caption: str):
duck = Image.open(duckpath)
draw = ImageDraw.Draw(duck)
font = ImageFont.truetype(WORKING_DIRECTORY_PATH + 'captionFont.ttf', 80)
#~ Determine text size & position
_,_, wText, hText = draw.textbbox((0,0), caption, font=font)
wPos = (duck.size[0]-wText)/2
#~ Draw caption background
#~ Vertical placement (top/bottom) is random
onTop = random.randint(0,1) == 0
if onTop:
hPos = (duck.size[1]-hText)/6
draw.rounded_rectangle((wPos*0.90, hPos*0.95, wPos*1.10+wText, hPos*1.10+hText), fill=(0,0,0), radius=20)
else:
hPos = (duck.size[1]-hText)/1.1
draw.rounded_rectangle((wPos*0.90, hPos*0.985, wPos*1.10+wText, hPos*1.025+hText), fill=(0,0,0), radius=20) # Bottom
#~ Write caption
draw.text((wPos, hPos), caption, font=font, fill=(255,255,255))
duck.save(duckpath)
def main():
code = ''
dayOfTheYear = datetime.datetime.now().timetuple().tm_yday
print("Day #{} | Logging in...".format(dayOfTheYear))
client = instagrapi.Client()
try:
client.load_settings(WORKING_DIRECTORY_PATH + 'ig.session')
except:
print("Day #{} | WARNING: Settings not found!".format(dayOfTheYear))
if INSTAGRAM_2FA_SEED:
code = client.totp_generate_code(INSTAGRAM_2FA_SEED)
print("Day #{} | Generated 2FA code".format(dayOfTheYear))
client.login(INSTAGRAM_USERNAME, INSTAGRAM_PASSWORD, verification_code=code)
client.dump_settings(WORKING_DIRECTORY_PATH + 'ig.session')
print("Day #{} | Logged in!".format(dayOfTheYear))
# Obtain the duck picture
duckPath = getDuck(dayOfTheYear)
print("Day #{} | Duck obtained!".format(dayOfTheYear))
# Format the picture to fit
formatImage(duckPath)
addCaption(duckPath, 'Duck #{}'.format(dayOfTheYear))
print("Day #{} | Story formatted!".format(dayOfTheYear))
# Post the picture in an Instagram story
duckStory = client.photo_upload_to_story(
duckPath,
# links=[
# StoryLink(
# webUri="https://random-d.uk/api/{}.jpg".format(dayOfTheYear)
# )
# ]
)
print("Day #{} | Duck posted!".format(dayOfTheYear))
# Check if user as an highlight named "Ducks" (Feel free to change this)
for userHighlight in client.user_highlights(client.user_id):
if userHighlight.title == "Ducks":
# Add the story to highlights
client.highlight_add_stories(userHighlight.pk, [duckStory.pk])
print("Day #{} | Added story to highlight".format(dayOfTheYear))
if __name__ == "__main__":
main()