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

update calculate result proccess from scratch

parent 857df234
This diff is collapsed.
......@@ -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