Commit 447e96bd authored by soheib's avatar soheib
Browse files

update calculate result proccess from scratch

parent 857df234
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -21,17 +21,20 @@
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@nestjs/common": "^7.6.15",
"@nestjs/core": "^7.6.15",
"@nestjs/common": "^8.0.6",
"@nestjs/core": "^8.0.6",
"@nestjs/mongoose": "^8.0.0",
"@nestjs/platform-express": "^7.6.15",
"@nestjs/platform-express": "^8.0.6",
"@nestjs/swagger": "^5.0.9",
"class-validator": "^0.13.1",
"instagram-private-api": "^1.45.1",
"instagram-web-api": "^2.2.2",
"lodash": "^4.17.21",
"mongoose": "^5.13.3",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^6.6.6"
"rxjs": "^6.6.6",
"swagger-ui-express": "^4.1.6"
},
"devDependencies": {
"@nestjs/cli": "^7.6.0",
......
......@@ -11,6 +11,7 @@ import { LikeSchema } from './instagram/models/like.schema'
import { CommentSchema } from './instagram/models/comment.schema'
import { LottoryResultSchema } from './instagram/models/LottoryResult.schema'
import { PostSchema } from './instagram/models/post.schema'
import { StoryMentionSchema } from './instagram/models/storyMention.schema'
@Module({
imports: [
......@@ -35,6 +36,11 @@ import { PostSchema } from './instagram/models/post.schema'
MongooseModule.forFeature([
{ name: 'Post', schema: PostSchema },
]),
MongooseModule.forFeature([
{ name: 'StoryMention', schema: StoryMentionSchema },
]),
InstagramModule,
LotteryModule,
......
import { ApiProperty } from "@nestjs/swagger"
export class AddStoryDataDto {
@ApiProperty({ example: [{username: "soheib", count: 5},{username: "sohasd.eib", count: 4} ] })
story_mentions: Array<{username: string, count: number}>
}
\ No newline at end of file
import { ApiProperty } from "@nestjs/swagger"
import { IsNotEmpty } from "class-validator"
export class GetCommentsDto{
@ApiProperty({ example: "kakasrm"})
@IsNotEmpty()
username: string
@ApiProperty({ example: "aasdnasj45"})
@IsNotEmpty()
password: string
@ApiProperty({ example: "azadi.gold"})
@IsNotEmpty()
profile: string
@ApiProperty({ example: 'CSCUev0swJO' })
@IsNotEmpty()
post_short_code: string
}
\ No newline at end of file
import { ApiProperty } from "@nestjs/swagger"
import { IsNotEmpty } from "class-validator"
export class GetFollowersDto{
@ApiProperty({ example: "kakasrm"})
@IsNotEmpty()
username: string
@ApiProperty({ example: "aasdnasj45"})
@IsNotEmpty()
password: string
@ApiProperty({ example: "azadi.gold"})
@IsNotEmpty()
profile: string
}
\ No newline at end of file
import { ApiProperty } from "@nestjs/swagger"
import { IsNotEmpty } from "class-validator"
export class GetLikesDto{
@ApiProperty({ example: "kakasrm"})
@IsNotEmpty()
username: string
@ApiProperty({ example: "aasdnasj45"})
@IsNotEmpty()
password: string
@ApiProperty({ example: "azadi.gold"})
@IsNotEmpty()
profile: string
@ApiProperty({ example: 'GKCUev0s5dJO' })
@IsNotEmpty()
post_short_code: string
}
\ No newline at end of file
import { Body, Controller, Get, Param, Post } from '@nestjs/common';
import { Body, Controller, Get, Param, Post } from '@nestjs/common'
import { ApiBody, ApiTags } from '@nestjs/swagger'
import { AddStoryDataDto } from './dto/add-story-data-dto'
import { GetCommentsDto } from './dto/get-comments-dto'
import { GetFollowersDto } from './dto/get-followers-dto'
import { GetLikesDto } from './dto/get-likes-dto'
......@@ -9,29 +11,43 @@ export class InstagramController {
constructor(private instagramService: InstagramService) { }
@Get('get-json-followers')
async getJsonDataFollowers() {
await this.instagramService.getFollowersFromJsonData()
return "proccess started successfully"
return "proccess started successfully"
}
@ApiBody({ type: GetFollowersDto })
@ApiTags('Instagram')
@Post('get-followers')
async getFollowers(@Body() getFollowers: GetFollowersDto) {
return await this.instagramService.getFollowersFromInstaLoader(getFollowers.username,
getFollowers.password,getFollowers.profile)
return await this.instagramService.getFollowersFromInstaLoader(getFollowers.username,
getFollowers.password, getFollowers.profile)
}
@ApiBody({ type: GetLikesDto })
@ApiTags('Instagram')
@Post('get-likes')
async getLikes(@Body() getLikes: GetLikesDto) {
return this.instagramService.getLikesFromInstaLoader(getLikes.username,
getLikes.password,getLikes.post_short_code ,getLikes.profile)
getLikes.password, getLikes.post_short_code, getLikes.profile)
}
@ApiBody({ type: GetCommentsDto })
@ApiTags('Instagram')
@Post('get-comments')
async getComments(@Body() getComments: GetCommentsDto) {
return await this.instagramService.getCommentsFromInstaLoader(getComments.username,
getComments.password,getComments.post_short_code ,getComments.profile
return await this.instagramService.getCommentsFromInstaLoader(getComments.username,
getComments.password, getComments.post_short_code, getComments.profile
)
}
@ApiBody({ type: AddStoryDataDto })
@ApiTags('Instagram')
@Post('add-story-mentions')
async addStoryMentions(@Body() addDto: AddStoryDataDto) {
return await this.instagramService.addStoryData(addDto)
}
}
......@@ -6,6 +6,7 @@ import { CommentSchema } from './models/comment.schema';
import { FollowerSchema } from './models/follower.schema';
import { LikeSchema } from './models/like.schema';
import { LottoryResultSchema } from './models/LottoryResult.schema';
import { StoryMentionSchema } from './models/storyMention.schema'
import { UserSchema } from './models/user.schema';
@Module({
......@@ -25,6 +26,9 @@ import { UserSchema } from './models/user.schema';
MongooseModule.forFeature([
{ name: 'LottryResult', schema: LottoryResultSchema },
]),
MongooseModule.forFeature([
{ name: 'StoryMention', schema: StoryMentionSchema },
]),
],
controllers: [InstagramController],
providers: [InstagramService]
......
......@@ -2,17 +2,19 @@ import {
HttpException,
Injectable,
OnApplicationBootstrap,
} from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model, Types } from 'mongoose';
import * as _ from 'lodash';
import { CommentDocument } from './models/comment.schema';
import { FollowerDocument } from './models/follower.schema';
import { LikeDocument } from './models/like.schema';
import { UserDocument } from './models/user.schema';
} from '@nestjs/common'
import { InjectModel } from '@nestjs/mongoose'
import { Model, Types } from 'mongoose'
import * as _ from 'lodash'
import { CommentDocument } from './models/comment.schema'
import { FollowerDocument } from './models/follower.schema'
import { LikeDocument } from './models/like.schema'
import { UserDocument } from './models/user.schema'
import FollowrData from './values/followers _data'
import { spawn } from 'child_process'
import * as path from "path"
import { StoryMentionDocument } from './models/storyMention.schema'
import { AddStoryDataDto } from './dto/add-story-data-dto'
@Injectable()
export class InstagramService implements OnApplicationBootstrap {
......@@ -25,6 +27,8 @@ export class InstagramService implements OnApplicationBootstrap {
private likeModel: Model<LikeDocument>,
@InjectModel('Comment')
private commentModel: Model<CommentDocument>,
@InjectModel('StoryMention')
private storyMentionModel: Model<StoryMentionDocument>,
) { }
......@@ -33,7 +37,7 @@ export class InstagramService implements OnApplicationBootstrap {
}
async getFollowersFromJsonData() {
console.log('start proccess...');
console.log('start proccess...')
let accountUsername = FollowrData.account_username
let account = await this.findOrCreateUser(accountUsername)
......@@ -50,64 +54,98 @@ export class InstagramService implements OnApplicationBootstrap {
}
}
console.log('end of proccess...')
return {message: "successfull"}
return { message: "successfull" }
}
async getLikesFromInstaLoader(username: string, password: string, post_short_code: string, profile: string) {
let paths = path.resolve("src","instagram","instaloader-service","getLikes.py")
const getLikesProccess = spawn('python3', [`${paths}`, `${username}`, `${password}`, `${post_short_code}`, `${profile}`,]);
let paths = path.resolve("src", "instagram", "instaloader-service", "getLikes.py")
const getLikesProccess = spawn('python3', [`${paths}`, `${username}`, `${password}`, `${post_short_code}`, `${profile}`,])
getLikesProccess.stdout.on('data', function (data) {
console.log('start collecting likes from python script ...');
console.log('start collecting likes from python script ...')
console.log(data.toString())
});
})
getLikesProccess.on('error', (err) => {
console.log(`child process has error ${err}`)
});
})
getLikesProccess.on('close', (code) => {
console.log(`child process close all stdio with code ${code}`);
});
console.log(`child process close all stdio with code ${code}`)
})
}
async getCommentsFromInstaLoader(username: string, password: string, post_short_code: string, profile: string) {
let paths = path.resolve("src","instagram","instaloader-service","getComments.py")
const getCommentsProccess = spawn('python3', [`'${paths}`, `${username}`, `${password}`, `${post_short_code}`, `${profile}`]);
let paths = path.resolve("src", "instagram", "instaloader-service", "getComments.py")
const getCommentsProccess = spawn('python3', [`'${paths}`, `${username}`, `${password}`, `${post_short_code}`, `${profile}`])
getCommentsProccess.stdout.on('data', function (data) {
console.log('start collecting comments from python script ...');
console.log('start collecting comments from python script ...')
console.log(data.toString())
});
})
getCommentsProccess.on('error', (err) => {
console.log(`child process has error ${err}`);
});
console.log(`child process has error ${err}`)
})
getCommentsProccess.on('close', (code) => {
console.log(`child process close all stdio with code ${code}`);
});
console.log(`child process close all stdio with code ${code}`)
})
}
async getFollowersFromInstaLoader(username: string, password: string, profile: string) {
let paths = path.resolve("src","instagram","instaloader-service","getFollowers.py")
const getFollowersProccess = spawn('python3', [`${paths}`, `${username}`, `${password}`, `${profile}`]);
let paths = path.resolve("src", "instagram", "instaloader-service", "getFollowers.py")
const getFollowersProccess = spawn('python3', [`${paths}`, `${username}`, `${password}`, `${profile}`])
getFollowersProccess.stdout.on('data', function (data) {
console.log('start collecting followers from python script ...');
console.log('start collecting followers from python script ...')
console.log(data.toString())
});
})
getFollowersProccess.on('error', (err) => {
console.log(`child process has error ${err}`);
});
console.log(`child process has error ${err}`)
})
getFollowersProccess.on('close', (code) => {
console.log(`child process close all stdio with code ${code}`);
});
console.log(`child process close all stdio with code ${code}`)
})
}
async addStoryData(addDto: AddStoryDataDto) {
for await (const userData of addDto.story_mentions) {
let foundUser = await this.userModel.findOne({ username: userData.username })
if (foundUser) {
let foundData = await this.storyMentionModel.findOne({
user_id: new Types.ObjectId(foundUser._id)
})
if (!foundData) {
await this.storyMentionModel.create({
_id: new Types.ObjectId(),
user_id: foundUser._id,
count: userData.count
})
}
else {
await this.storyMentionModel.findOneAndUpdate({
user_id: new Types.ObjectId(foundUser._id),
}, { count: userData.count })
}
}
else {
let newUser = await this.userModel.create({
_id: new Types.ObjectId()
})
await this.storyMentionModel.create({
_id: new Types.ObjectId(),
user_id: newUser._id,
count: userData.count
})
}
}
}
async findOrCreateUser(username: string) {
......
......@@ -2,12 +2,13 @@ import instaloader
import pymongo
import sys
username = "kakasrm"
password = "kaka1374"
username = str(sys.argv[1])
password = str(sys.argv[2])
mongo_connection_string = "mongodb://instagram:wcD3B5sGw0yQ@185.231.180.248:27017/instagram-lottry?authSource=admin&authMechanism=SCRAM-SHA-256"
database_name = "instagram-lottry"
post_short_code = "CShKEJijy4v"
PROFILE = "azadi.gold"
post_short_code = str(sys.argv[3])
PROFILE = str(sys.argv[4])
def __main__():
......
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document, Types } from 'mongoose';
export type StoryMentionDocument = StoryMention & Document;
@Schema({ timestamps: true })
export class StoryMention {
@Prop()
_id: Types.ObjectId
@Prop({ type: Types.ObjectId, ref: 'User' })
user_id: Types.ObjectId
@Prop()
count: number
}
export const StoryMentionSchema =
SchemaFactory.createForClass(StoryMention)
\ No newline at end of file
......@@ -18,7 +18,7 @@ export default {
},
{
username: "massi_a_6363 ",
username: "massi_a_6363",
count: 3
},
{
......
import { ApiProperty } from "@nestjs/swagger"
import { IsNotEmpty } from "class-validator"
export class CalculateScoreDto{
@ApiProperty({ example: "azadi.gold" })
@IsNotEmpty()
profile_username: string
@ApiProperty({ example: ['GKCUev0s5dJO','CSCUev0swJO','CSCUev0swJO'] })
@IsNotEmpty()
post_array: string[]
//add_to_story_data: Array<any>
}
\ No newline at end of file
import { ApiProperty } from "@nestjs/swagger"
import { IsMobilePhone, IsNotEmpty, IsString } from "class-validator"
export class ChangeStatusDto{
@ApiProperty({ example: '09186548065' })
@IsNotEmpty()
@IsMobilePhone('fa-IR')
mobile: string
@ApiProperty({ example: "azadi.gold" })
@IsNotEmpty()
@IsString()
username: string
}
\ No newline at end of file
import { ApiProperty } from "@nestjs/swagger"
import { IsNotEmpty } from "class-validator"
export class WeeklySearchDto {
@ApiProperty({ example: "kakasrm" })
@IsNotEmpty()
username: string
@ApiProperty({ example: "azadi.gold" })
@IsNotEmpty()
profile_username: string
@ApiProperty({ example: ['GKCUev0s5dJO','CSCUev0swJO','CSCUev0swJO'] })
@IsNotEmpty()
post_array: string[]
}
\ No newline at end of file
import { Body, Query, Controller, Get, Post } from '@nestjs/common';
import { ApiBody, ApiTags } from '@nestjs/swagger'
import { CalculateScoreDto } from './dto/calculate-score-dto'
import { ChangeStatusDto } from './dto/change-status-dto'
import { WeeklySearchDto } from './dto/weekly-search-dto'
......@@ -10,23 +11,30 @@ export class LotteryController {
constructor(private lotteryService: LotteryService) { }
//weekly lottery apies:
@ApiBody({ type: WeeklySearchDto })
@ApiTags('Lottery/weekly')
@Post('weekly/search')
async getUserResults(@Body() searchDto: WeeklySearchDto) {
return await this.lotteryService.getUserScore(searchDto.username,
searchDto.profile_username, searchDto.post_array)
}
@ApiBody({ type: CalculateScoreDto })
@ApiTags('Lottery/weekly')
@Post('weekly/calculate-score')
async addResultsToDb(@Body() calculateScoreDto: CalculateScoreDto) {
return await this.lotteryService.addResultsToDB(calculateScoreDto.profile_username,
calculateScoreDto.post_array)
}
@ApiTags('Lottery/weekly')
@Get('weekly/get-lottory-result')
async getResultDb() {
return await this.lotteryService.getResultDb()
}
@ApiBody({ type: ChangeStatusDto })
@ApiTags('Lottery/weekly')
@Post('weekly/change-status')
async changeStatus(@Body() changeStatusDto: ChangeStatusDto) {
console.log('here');
......
......@@ -5,6 +5,7 @@ import { FollowerSchema } from 'src/instagram/models/follower.schema';
import { LikeSchema } from 'src/instagram/models/like.schema';
import { LottoryResultSchema } from 'src/instagram/models/LottoryResult.schema';
import { PostSchema } from 'src/instagram/models/post.schema'
import { StoryMentionSchema } from 'src/instagram/models/storyMention.schema'
import { UserSchema } from 'src/instagram/models/user.schema';
import { LotteryController } from './lottery.controller';
import { LotteryService } from './lottery.service';
......@@ -30,6 +31,9 @@ import { ScoreService } from './score.service';
MongooseModule.forFeature([
{ name: 'LottryResult', schema: LottoryResultSchema },
]),
MongooseModule.forFeature([
{ name: 'StoryMention', schema: StoryMentionSchema },
]),
],
controllers: [LotteryController],
providers: [LotteryService, ScoreService]
......
import { HttpException, Injectable } from '@nestjs/common'
import { InjectModel } from '@nestjs/mongoose'
import { Model, Types } from 'mongoose'
import { Model, ObjectId, Types } from 'mongoose'
import { of } from 'rxjs'
import { CommentDocument } from 'src/instagram/models/comment.schema'
import { FollowerDocument } from 'src/instagram/models/follower.schema'
......@@ -11,6 +11,7 @@ import addToStoryData from '../instagram/values/add-to-story-data'
import { ChangeStatusDto } from './dto/change-status-dto'
import { ScoreService } from './score.service'
import * as _ from "lodash"
import { StoryMentionDocument } from 'src/instagram/models/storyMention.schema'
@Injectable()
......@@ -26,7 +27,9 @@ export class LotteryService {
@InjectModel('Comment')
private commentModel: Model<CommentDocument>,
@InjectModel('LottryResult')
private lotteryResultModel: Model<LottoryResultDocument>
private lotteryResultModel: Model<LottoryResultDocument>,
@InjectModel('StoryMention')
private storyMentionModel: Model<StoryMentionDocument>,
) { }
async getUserScore(username: string, profileUsername: string, postArray: string[]) {
......@@ -38,67 +41,32 @@ export class LotteryService {
return { likesScore, commentScore, addToStoryScore, totalScore: likesScore + commentScore + addToStoryScore }
}
async addResultsToDB(profileUsername: string, postArray: string[]) {
let foundUsernameInComment = await this.commentModel.distinct('user_id')
let foundUsernameInLike = await this.likeModel.distinct('user_id')
let foundUser_idsList = new Array<any>()
foundUsernameInComment.forEach((user_id) => {
if (!foundUser_idsList.includes(user_id)) {
foundUser_idsList.push(user_id)
}
})
foundUsernameInLike.forEach((user_id) => {
if (!foundUser_idsList.includes(user_id)) {
foundUser_idsList.push(user_id)
}
})
let foundUser_idsList = await this.getUserList()
let index = 0
for await (const user_id of foundUser_idsList) {
let userScore = await this.scoreService.calculateUserScore(user_id, profileUsername, postArray)
for (let u = 0; u < userScore; u++) {
console.log();
let foundIndex = await this.lotteryResultModel.findOne({
$and: [
{
user_id: new Types.ObjectId(user_id)
}, {
index: `${u}`,
}]
let userScore = await this.scoreService.calculateUserScore(user_id.toString(), profileUsername, postArray)
if(userScore>0){
console.log(userScore,user_id.toString());
}
let foundUserLastCount = await this.lotteryResultModel.countDocuments({
user_id: new Types.ObjectId(user_id)
})
let newChances = userScore - foundUserLastCount
for (let u = 0; u < newChances; u++) {
await this.lotteryResultModel.create({
_id: new Types.ObjectId(),
index: await this.codeGenerator(),
user_id: user_id,
status: 'valid',
})
if (!foundIndex) {
await this.lotteryResultModel.create({
_id: new Types.ObjectId(),
index: `${u}`,
user_id: user_id,
status: 'valid',
chance: await this.codeGenerator()
})
}
}
console.log(`${index}/${foundUser_idsList.length}`)
index++
}
console.log('end')
return 'successfull'
}
async codeGenerator() {
let lastIndex = await this.lotteryResultModel.find().sort({ createdAt: -1 })
if (lastIndex[0]) {
let lastChanceIndex = lastIndex[0].chance
console.log('last chance',lastChanceIndex);
let code =lastChanceIndex.split('LT_')[1]
console.log('code',code);
let res = `LT_${(Number(code)+1)}`
console.log('res',res);
return res
}
else {
return `LT_${1000}`
}
}
async getResultDb() {
return await this.lotteryResultModel
.find().populate("user_id", { "username": 1 }, "User").sort({ "status": 1 })
......@@ -119,4 +87,44 @@ export class LotteryService {
message: "status changed to online successfully"
}
}
async codeGenerator() {
let lastIndex = await this.lotteryResultModel.find().sort({ createdAt: -1 })
if (lastIndex[0]) {
let lastChanceIndex = lastIndex[0].index
let code = lastChanceIndex.split('LT_')[1]
let res = `LT_${(Number(code) + 1)}`
return res
}
else {
return `LT_${1000}`
}
}
async getUserList() {
let foundUsernameInComment = await this.commentModel.distinct('user_id')
let foundUsernameInLike = await this.likeModel.distinct('user_id')
let foundUsernamesInStoryData = new Array<any>()
for await (const iterator of addToStoryData.addToStoryData) {
let foundUser = await this.userModel.findOne({ username: iterator.username })
if (!foundUser) {
let createdUser = await this.userModel.create({
_id: new Types.ObjectId(),
username: iterator.username
})
foundUsernamesInStoryData.push(createdUser._id.toString())
}
else {
foundUsernamesInStoryData.push(foundUser._id.toString())
}
}
let userListTemp = foundUsernameInComment.concat(foundUsernameInLike)
let array = new Array<string>()
userListTemp.forEach(user => {
array.push(user.toString())
})
let userListTemp2 = array.concat(foundUsernamesInStoryData)
let userList = [...new Set(userListTemp2)]
return userList
}
}
......@@ -5,6 +5,7 @@ import { CommentDocument } from 'src/instagram/models/comment.schema'
import { FollowerDocument } from 'src/instagram/models/follower.schema'
import { LikeDocument } from 'src/instagram/models/like.schema'
import { PostDocument } from 'src/instagram/models/post.schema'
import { StoryMentionDocument } from 'src/instagram/models/storyMention.schema'
import { UserDocument } from 'src/instagram/models/user.schema'
import addToStoryData from '../instagram/values/add-to-story-data'
......@@ -24,18 +25,38 @@ export class ScoreService {
private lotteryResultModel: Model<CommentDocument>,
@InjectModel('Post')
private postModel: Model<PostDocument>,
@InjectModel('StoryMention')
private storyMentionModel: Model<StoryMentionDocument>,
) { }
async getUserLikesScore(user_id: string, profileUsername: string, postArray: string[]) {
let foundAccount = await this.userModel.findOne({ username: profileUsername })
let isfollowerValid = await this.followerModel.findOne({
$and: [{ user_id: new Types.ObjectId(user_id) }
, { account_id: foundAccount._id }]
$and: [
{ user_id: new Types.ObjectId(user_id) },
{ account_id: foundAccount._id }
]
})
if (isfollowerValid) {
let foundLikes = await this.likeModel.find({ user_id: new Types.ObjectId(user_id) })
return foundLikes.length
let score = 0
for await (const post of postArray) {
let foundPost = await this.postModel.findOne({ url: post })
let foundLike = await this.likeModel.findOne({
$and: [
{
user_id: new Types.ObjectId(user_id)
},
{
post_id: new Types.ObjectId(foundPost._id)
}
]
})
if (foundLike) {
score++
}
}
return score
}
else {
return 0
......@@ -77,13 +98,11 @@ export class ScoreService {
}
}
async getTagsScore(username: string) {
async getTagsScore(user_id: string) {
let addToStoryScore = 0
let foundUser = addToStoryData.addToStoryData.find((user) => {
return user.username === username
})
if (foundUser) {
addToStoryScore = foundUser.count
let foundUserInStory = await this.storyMentionModel.findOne({user_id: new Types.ObjectId(user_id)})
if (foundUserInStory) {
addToStoryScore = foundUserInStory.count
}
return addToStoryScore
}
......
Supports Markdown
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