-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8a98fa9
commit a8a1b2d
Showing
10 changed files
with
225 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,8 @@ | ||
.idea | ||
.DS_Store | ||
__pycache__ | ||
*.pickle | ||
*.pickle | ||
/smtp/creads.py | ||
/pop/creads.py | ||
/api/vk_token.py | ||
/pop/attachments/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# VK Friends | ||
|
||
Cервер на FastAPI для просмотра списока друзей ВКонтакте | ||
|
||
## Зависимости | ||
|
||
```bash | ||
pip install fastapi uvicorn requests | ||
``` | ||
|
||
## Запуск | ||
|
||
1. Зайти в папку api | ||
|
||
```bash | ||
cd api | ||
``` | ||
|
||
2. В файле token.py написать свой токен от вк | ||
|
||
|
||
3. Запустить сервер: | ||
``` | ||
uvicorn vk_friends:app --reload | ||
``` | ||
|
||
4. Перейти по адресу http://localhost:8000/ |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
from fastapi import FastAPI | ||
from fastapi.responses import HTMLResponse | ||
import requests | ||
|
||
from vk_token import VK_API_KEY | ||
|
||
|
||
app = FastAPI() | ||
|
||
|
||
@app.get("/", response_class=HTMLResponse) | ||
async def read_root(): | ||
return """ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>VK User Friends</title> | ||
<script> | ||
async function getFriends() { | ||
const inputField = document.getElementById("vkID"); | ||
const vkID = inputField.value; | ||
const response = await fetch("/friends/" + vkID); | ||
const friends = await response.json(); | ||
let friendsList = document.getElementById("friendsList"); | ||
friendsList.innerHTML = ""; // clear existing list | ||
for (let friend of friends) { | ||
let friendItem = document.createElement("li"); | ||
friendItem.innerHTML = `<a href="https://vk.com/id${friend.id}"> | ||
<img src="${friend.photo_50}" alt="Avatar"> | ||
${friend.first_name} ${friend.last_name} | ||
</a>`; | ||
friendsList.appendChild(friendItem); | ||
} | ||
} | ||
</script> | ||
</head> | ||
<body> | ||
<input id="vkID" type="text" placeholder="Enter VK id or username"> | ||
<button onclick="getFriends()">Get Friends</button> | ||
<ul id="friendsList"></ul> | ||
</body> | ||
</html> | ||
""" | ||
|
||
|
||
@app.get("/friends/{vk_id}") | ||
async def get_friends(vk_id: str): | ||
if not vk_id.isdigit(): | ||
url = f"https://api.vk.com/method/users.get?user_ids={vk_id}&access_token={VK_API_KEY}&v=5.130" | ||
response = requests.get(url) | ||
vk_id = response.json()["response"][0]["id"] | ||
url = f"https://api.vk.com/method/friends.get?user_id={vk_id}&fields=first_name,last_name,photo_50&access_token={VK_API_KEY}&v=5.130" | ||
response = requests.get(url) | ||
return response.json()["response"]["items"] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import poplib | ||
import email | ||
import os | ||
import re | ||
from email.header import decode_header | ||
|
||
from creads import PASSWORD, EMAIL_ADDRESS | ||
|
||
|
||
def parse_email(msg): | ||
data = {} | ||
subject = decode_header(msg.get('Subject'))[0] | ||
if subject[1]: | ||
data['subject'] = subject[0].decode(subject[1]) | ||
else: | ||
data['subject'] = subject[0] | ||
|
||
from_ = decode_header(msg.get('From'))[0] | ||
if from_[1]: | ||
data['from'] = from_[0].decode(from_[1]) | ||
else: | ||
data['from'] = from_[0] | ||
|
||
date = decode_header(msg.get('Date'))[0] | ||
if date[1]: | ||
data['date'] = date[0].decode(date[1]) | ||
else: | ||
data['date'] = date[0] | ||
|
||
if msg.is_multipart(): | ||
for part in msg.walk(): | ||
if part.get_content_type() == "text/plain": | ||
body = part.get_payload(decode=True) | ||
data['body'] = body.decode() | ||
|
||
if part.get_content_type() == "application/octet-stream": | ||
file_name = decode_header(part.get("Content-Disposition"))[0][0].split(';')[1].split('=')[1] | ||
if file_name: | ||
os.makedirs('attachments', exist_ok=True) | ||
filepath = os.path.join('attachments', file_name).replace("\"", "") | ||
with open(filepath, 'wb') as f: | ||
f.write(part.get_payload(decode=True)) | ||
else: | ||
data['body'] = msg.get_payload(decode=True) | ||
|
||
return data | ||
|
||
|
||
def pretty_print_email(email_data): | ||
# if isinstance(email_data['body'], bytes): | ||
# email_data['body'] = email_data['body'].decode('utf-8') | ||
email_data['body'] = re.sub('[\n\t ]{2,}', '\n', email_data['body']) | ||
|
||
print('Subject:', email_data['subject']) | ||
print('From:', email_data['from']) | ||
print('Date:', email_data['date']) | ||
print('Body:', email_data['body']) | ||
|
||
|
||
def connect_pop3_server(user, password, server, port): | ||
pop_server = poplib.POP3_SSL(server, port) | ||
pop_server.user(user) | ||
pop_server.pass_(password) | ||
|
||
num_messages = len(pop_server.list()[1]) | ||
|
||
if num_messages < 1: | ||
print("No messages in mailbox.") | ||
return None | ||
|
||
raw_email = pop_server.retr(num_messages)[1] | ||
raw_email = b'\n'.join(raw_email) | ||
message = email.message_from_bytes(raw_email) | ||
pop_server.quit() | ||
return message | ||
|
||
|
||
if __name__ == "__main__": | ||
user = EMAIL_ADDRESS | ||
password = PASSWORD | ||
server = 'pop.yandex.com' | ||
port = 995 | ||
|
||
message = connect_pop3_server(user, password, server, port) | ||
if message: | ||
email_data = parse_email(message) | ||
pretty_print_email(email_data) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
recipient: "[email protected]" | ||
subject: "Тема письма" | ||
attachments: ["image.png"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
ВНИМАНИЕ! Важно про онлайн-курсы! | ||
|
||
Учебный отдел УрФУ просил напомнить, что 4 июня 2023 истекают сроки работы с заданиями онлайн-курсов и онлайн-майноров УрФУ. | ||
Рассылка была проведена по всем слушателям курсов, но практика показывает, что студенты не проверяют корпоративную почту. | ||
|
||
Продления дедлайнов не будет ни под каким предлогом! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import smtplib | ||
from email.mime.multipart import MIMEMultipart | ||
from email.mime.text import MIMEText | ||
from email.mime.base import MIMEBase | ||
from email import encoders | ||
from pathlib import Path | ||
|
||
import yaml | ||
import os | ||
|
||
from creads import PASSWORD, EMAIL_ADDRESS | ||
|
||
|
||
MAIL_INFO_DIR = Path('mail_info') | ||
with open(MAIL_INFO_DIR / 'config.yml') as file: | ||
config = yaml.load(file, Loader=yaml.FullLoader) | ||
|
||
with open(MAIL_INFO_DIR / 'message.txt') as file: | ||
source_message = file.read() | ||
|
||
|
||
msg = MIMEMultipart() | ||
msg['From'] = EMAIL_ADDRESS | ||
msg['To'] = config['recipient'] | ||
msg['Subject'] = config['subject'] | ||
|
||
msg.attach(MIMEText(source_message, 'plain')) | ||
|
||
for attachment_file in config['attachments']: | ||
with open(MAIL_INFO_DIR / attachment_file, 'rb') as file: | ||
attachment = MIMEBase('application', 'octet-stream') | ||
attachment.set_payload(file.read()) | ||
encoders.encode_base64(attachment) | ||
attachment.add_header('Content-Disposition', f'attachment; filename={os.path.basename(attachment_file)}') | ||
msg.attach(attachment) | ||
|
||
server = smtplib.SMTP('smtp.yandex.ru', 587) | ||
server.starttls() | ||
server.login(EMAIL_ADDRESS, PASSWORD) | ||
server.sendmail(EMAIL_ADDRESS, config['recipient'], msg.as_string()) | ||
server.quit() |