Commit 0a8c44ae authored by dasunx's avatar dasunx

Telegram connect backend

parent c0aaece6
...@@ -3,6 +3,7 @@ const jwtDecode = require('jwt-decode'); ...@@ -3,6 +3,7 @@ const jwtDecode = require('jwt-decode');
const { body, validationResult } = require('express-validator'); const { body, validationResult } = require('express-validator');
const { createToken, hashPassword, verifyPassword } = require('../utils/authentication'); const { createToken, hashPassword, verifyPassword } = require('../utils/authentication');
const { create6DigitCode } = require('../utils/telegram');
exports.signup = async (req, res) => { exports.signup = async (req, res) => {
const result = validationResult(req); const result = validationResult(req);
...@@ -90,8 +91,8 @@ exports.authenticate = async (req, res) => { ...@@ -90,8 +91,8 @@ exports.authenticate = async (req, res) => {
const token = createToken(user); const token = createToken(user);
const decodedToken = jwtDecode(token); const decodedToken = jwtDecode(token);
const expiresAt = decodedToken.exp; const expiresAt = decodedToken.exp;
const { username, role, id, created, profilePhoto } = user; const { username, role, id, created, profilePhoto, isTelegramConnected } = user;
const userInfo = { username, role, id, created, profilePhoto }; const userInfo = { username, role, id, created, profilePhoto, isTelegramConnected };
res.json({ res.json({
message: 'Authentication successful!', message: 'Authentication successful!',
...@@ -139,6 +140,124 @@ exports.find = async (req, res, next) => { ...@@ -139,6 +140,124 @@ exports.find = async (req, res, next) => {
} }
}; };
exports.createTelegramValidateCode = async (req, res, next) => {
try {
const { username } = req.body;
const user = await User.findOne({ username });
if (!user) {
return res.status(400).json({
message: 'User not found.'
});
}
if (user.isTelegramConnected) {
return res.status(400).json({ message: 'Telegram already connected.' });
}
const telegramValidationCode = create6DigitCode();
user.telegramConnectionCode = telegramValidationCode;
await user.save();
return res.status(200).json({ user: user });
} catch (error) {
next(error);
}
};
exports.connectWithTelegram = async (req, res, next) => {
try {
const { username, telegramValidationCode, telegramId } = req.body;
console.log(username);
const user = await User.findOne({ username });
if (!user) {
return res.status(400).json({
message: 'User not found.'
});
}
if (user.isTelegramConnected) {
return res.status(400).json({ message: 'Telegram already connected.' });
}
if (user.telegramConnectionCode !== telegramValidationCode) {
return res.status(400).json({
message: 'Wrong validation code.'
});
}
user.telegramConnectionCode = '';
user.isTelegramConnected = true;
user.telegramId = telegramId;
await user.save();
return res.status(200).json({ user: user });
} catch (error) {
next(error);
}
};
exports.verifyTelegramConnection = async (req, res, next) => {
try {
const { username } = req.body;
const user = await User.findOne({ username });
if (!user) {
return res.status(400).json({
message: 'User not found.'
});
}
if (!user.isTelegramConnected) {
return res.status(400).json({
message: 'Telegram not connected.'
});
}
return res.status(200).json({ user: user });
} catch (error) {
next(error);
}
};
exports.verifyTelegramUsername = async (req, res, next) => {
try {
const { username, telegramId } = req.body;
const user = await User.findOne({ username });
if (!user) {
return res.status(400).json({
message: 'User not found.'
});
}
if (!user.isTelegramConnected) {
return res.status(400).json({
message: 'Telegram not connected.'
});
}
if (user.telegramId !== telegramId) {
return res.status(400).json({
message: 'Wrong telegram id.'
});
}
const token = createToken(user);
return res.status(200).json({ user: user, token });
} catch (error) {
next(error);
}
};
exports.disconnectTelegram = async (req, res, next) => {
try {
const { username } = req.body;
const user = await User.findOne({ username });
if (!user) {
return res.status(400).json({
message: 'User not found.'
});
}
user.isTelegramConnected = false;
user.telegramId = '';
await user.save();
return res.status(200).json({ user: user });
} catch (error) {
next(error);
}
};
exports.validateUser = [ exports.validateUser = [
body('username') body('username')
.exists() .exists()
......
...@@ -11,6 +11,9 @@ const userModel = new Schema({ ...@@ -11,6 +11,9 @@ const userModel = new Schema({
return `https://secure.gravatar.com/ad/${this._id}?s=90&d=monsterid`; return `https://secure.gravatar.com/ad/${this._id}?s=90&d=monsterid`;
} }
}, },
isTelegramConnected: { type: Boolean, default: false },
telegramId: { type: String, default: '' },
telegramConnectionCode: { type: Number, default: 111111 },
created: { type: Date, default: Date.now } created: { type: Date, default: Date.now }
}); });
......
...@@ -47,7 +47,6 @@ class DevTo: ...@@ -47,7 +47,6 @@ class DevTo:
for url in validUrls: for url in validUrls:
try: try:
vset = {} vset = {}
print(url)
username = re.search(r"https://dev.to/([^/?]+)", url).group(1) username = re.search(r"https://dev.to/([^/?]+)", url).group(1)
tag = re.search(r"https://dev.to/([^/?]+)/([^/?]+)", url).group(2) tag = re.search(r"https://dev.to/([^/?]+)/([^/?]+)", url).group(2)
vset["username"] = username vset["username"] = username
...@@ -84,12 +83,16 @@ class DevTo: ...@@ -84,12 +83,16 @@ class DevTo:
get content of the valid urls get content of the valid urls
return the content of valid dev.to articles return the content of valid dev.to articles
""" """
links = self.google(f"site:dev.to {self.title} after:2020-01-01") try:
validUrls = self.get_valid_urls(links) links = self.google(f"site:dev.to {self.title} after:2020-01-01")
validSets = self.get_valid_sets(validUrls) validUrls = self.get_valid_urls(links)
blogs = [] validSets = self.get_valid_sets(validUrls)
for validset in validSets: blogs = []
blog = self.get_blogs(validset["username"], validset["tag"]) for validset in validSets:
if bool(blog): blog = self.get_blogs(validset["username"], validset["tag"])
blogs.append(blog) if bool(blog):
return {"blogs": blogs, "resources": validUrls} blogs.append(blog)
return {"blogs": blogs, "resources": validUrls}
except Exception as e:
print(e)
return {"blogs": [], "resources": []}
\ No newline at end of file
...@@ -52,7 +52,6 @@ class Medium: ...@@ -52,7 +52,6 @@ class Medium:
for url in validUrls: for url in validUrls:
try: try:
vset = {} vset = {}
print(url)
username = re.search(r"https://medium.com/([^/?]+)", url).group(1) username = re.search(r"https://medium.com/([^/?]+)", url).group(1)
tag = re.search(r"https://medium.com/([^/?]+)/([^/?]+)", url).group(2) tag = re.search(r"https://medium.com/([^/?]+)/([^/?]+)", url).group(2)
vset["username"] = username vset["username"] = username
...@@ -85,12 +84,16 @@ class Medium: ...@@ -85,12 +84,16 @@ class Medium:
""" """
return a list of articles and/or resources return a list of articles and/or resources
""" """
links = self.google(f"site:medium.com {self.title} after:2020-01-01") try:
validUrls = self.getValidUrls(links) links = self.google(f"site:medium.com {self.title} after:2020-01-01")
validSets = self.getValidSets(validUrls) validUrls = self.getValidUrls(links)
blogs = [] validSets = self.getValidSets(validUrls)
for validset in validSets: blogs = []
blog = self.getBlogs(validset["username"], validset["tag"]) for validset in validSets:
if bool(blog): blog = self.getBlogs(validset["username"], validset["tag"])
blogs.append(blog) if bool(blog):
return {"blogs": blogs, "resources": validUrls} blogs.append(blog)
return {"blogs": blogs, "resources": validUrls}
except Exception as e:
print(e)
return {"blogs": [], "resources": []}
...@@ -67,11 +67,15 @@ class GithubData: ...@@ -67,11 +67,15 @@ class GithubData:
:param query: The search query. :param query: The search query.
:return: The repos found. :return: The repos found.
""" """
google_query = "site:github.com {}".format(query) try:
search_args = (google_query, 1) google_query = "site:github.com {}".format(query)
gsearch = GoogleSearch() search_args = (google_query, 1)
gresults = gsearch.search(*search_args) gsearch = GoogleSearch()
return gresults["links"] gresults = gsearch.search(*search_args)
return gresults["links"]
except Exception as e:
print(e)
return []
def get_valid_urls(self, links): def get_valid_urls(self, links):
""" """
...@@ -80,7 +84,10 @@ class GithubData: ...@@ -80,7 +84,10 @@ class GithubData:
validUrls = [] validUrls = []
for i in links: for i in links:
if "github.com" in i: if "github.com" in i:
uriTrimmed = re.match(r"^.*?\&sa=", i[29:]).group(0) try:
ur = uriTrimmed.replace("&sa=", "") uriTrimmed = re.match(r"^.*?\&sa=", i[29:]).group(0)
validUrls.append(ur) ur = uriTrimmed.replace("&sa=", "")
validUrls.append(ur)
except Exception as e:
print(e)
return validUrls return validUrls
\ No newline at end of file
...@@ -30,18 +30,20 @@ def saveAnswer(ans_id, stackoverflow, videos, medium_r, dev_r, github_r): ...@@ -30,18 +30,20 @@ def saveAnswer(ans_id, stackoverflow, videos, medium_r, dev_r, github_r):
} }
}, },
) )
except NameError as err: except NameError as err:
print("ERRORRR") print("ERRORRR")
print(err) print(err)
if __name__ == "__main__": if __name__ == "__main__":
# title = input("Enter question title: ") # title = "How to center a div verticly"
title = sys.argv[1] title = sys.argv[1]
# "what are the benefits of using java for mobile app development over flutter" # "what are the benefits of using java for mobile app development over flutter"
tags = sys.argv[2] # ["flutter","java"] tags = sys.argv[2]
AUTO_ANS_ID = sys.argv[3] # "611feaff2c4db730e56d78e8" # tags = ["flutter", "java"]
AUTO_ANS_ID = sys.argv[3]
# AUTO_ANS_ID = "60de81bf85684c45442aba3d"
stack = STOF(title) stack = STOF(title)
medium = Medium(title, tags) medium = Medium(title, tags)
......
...@@ -2,6 +2,7 @@ import requests ...@@ -2,6 +2,7 @@ import requests
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
import re import re
from lxml import etree from lxml import etree
from search_engine_parser import GoogleSearch
class STOF: class STOF:
...@@ -12,6 +13,13 @@ class STOF: ...@@ -12,6 +13,13 @@ class STOF:
self.urls = [] self.urls = []
def searchQuestion(self): def searchQuestion(self):
# query = f"site:stackoverflow.com {self.title}"
# search_args = (query, 1)
# gsearch = GoogleSearch()
# gresults = gsearch.search(*search_args)
# for result in gresults["links"]:
# return gresults["links"]
html_page = requests.get( html_page = requests.get(
f"https://google.com/search?q=site%3Astackoverflow.com+{self.qtitle}" f"https://google.com/search?q=site%3Astackoverflow.com+{self.qtitle}"
) )
...@@ -38,12 +46,14 @@ class STOF: ...@@ -38,12 +46,14 @@ class STOF:
answers_count = dom.xpath('//*[@id="answers-header"]/div/div[1]/h2')[ answers_count = dom.xpath('//*[@id="answers-header"]/div/div[1]/h2')[
0 0
].text.strip() ].text.strip()
print("answers_count")
print(answers_count)
answer = {"url": url} answer = {"url": url}
if answers_count != "": if answers_count != "":
try: try:
verified_answer = dom.xpath( verified_answer = dom.xpath(
'//*[@class="answer accepted-answer"]/div/div[2]/div[1]' '//*[@class="answer js-answer accepted-answer"]/div/div[2]/div[1]'
)[0] )[0]
answer["content"] = etree.tostring(verified_answer).decode("utf-8") answer["content"] = etree.tostring(verified_answer).decode("utf-8")
answer["status"] = "Verified" answer["status"] = "Verified"
...@@ -53,7 +63,7 @@ class STOF: ...@@ -53,7 +63,7 @@ class STOF:
except: except:
try: try:
first_answer = dom.xpath('//*[@class="answer"]/div/div[2]/div[1]')[ first_answer = dom.xpath('//*[@class="answer js-answer"]/div/div[2]/div[1]')[
0 0
] ]
answer["content"] = etree.tostring(first_answer).decode("utf-8") answer["content"] = etree.tostring(first_answer).decode("utf-8")
...@@ -81,6 +91,6 @@ class STOF: ...@@ -81,6 +91,6 @@ class STOF:
def get_clean_url(url): def get_clean_url(url):
import re import re
pattern = r"^.*?\&sa=" pattern = r"^.*?\&sa="
return re.match(pattern, url).group(0) return re.match(pattern, url).group(0)
...@@ -27,4 +27,4 @@ class Youtube: ...@@ -27,4 +27,4 @@ class Youtube:
videos.append(i["link"]) videos.append(i["link"])
print(i["link"]) print(i["link"])
return videos return videos
\ No newline at end of file
bson==0.5.10 beautifulsoup4>=4.9.1
beautifulsoup4==4.9.3 dnspython>=2.1.0
dnspython==2.1.0 lxml>=4.5.2
lxml==4.6.1 pymongo>=3.12.1
pymongo==3.11.4 regex>=2020.7.14
regex==2020.7.14 requests>=2.24.0
requests==2.24.0 requests-html>=0.10.0
requests-html==0.10.0 scipy>=1.5.4
scipy==1.5.4 search-engine-parser>=0.6.2
search-engine-parser==0.6.2 youtube-search-python>=1.4.6
youtube-search-python==1.4.6
...@@ -4,7 +4,12 @@ const { ...@@ -4,7 +4,12 @@ const {
authenticate, authenticate,
listUsers, listUsers,
search, search,
find find,
createTelegramValidateCode,
connectWithTelegram,
verifyTelegramConnection,
disconnectTelegram,
verifyTelegramUsername
} = require('./controllers/users'); } = require('./controllers/users');
const { const {
loadQuestions, loadQuestions,
...@@ -42,7 +47,11 @@ router.post('/authenticate', validateUser, authenticate); ...@@ -42,7 +47,11 @@ router.post('/authenticate', validateUser, authenticate);
router.get('/users', listUsers); router.get('/users', listUsers);
router.get('/users/:search', search); router.get('/users/:search', search);
router.get('/user/:username', find); router.get('/user/:username', find);
router.post('/user/createtgcode', requireAuth, createTelegramValidateCode);
router.post('/user/connect-telegram', connectWithTelegram);
router.post('/user/verify-telegram-connection', verifyTelegramConnection);
router.delete('/user/disconnect-telegram', disconnectTelegram);
router.post('/user/verify-telegram-id', verifyTelegramUsername);
//questions //questions
router.param('question', loadQuestions); router.param('question', loadQuestions);
router.post('/questions', [requireAuth, questionValidate], createQuestion); router.post('/questions', [requireAuth, questionValidate], createQuestion);
......
const create6DigitCode = () => {
return Math.floor(Math.random() * 900000) + 100000;
};
module.exports = {
create6DigitCode
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment