Skip to content

Commit

Permalink
add(*): first simple version.
Browse files Browse the repository at this point in the history
  • Loading branch information
nbsps committed Mar 25, 2022
1 parent 5bafcbd commit 3077d45
Show file tree
Hide file tree
Showing 1,109 changed files with 1,431,413 additions and 0 deletions.
53 changes: 53 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<div style="text-align: center" >
<img src="./front-end/recFront/public/silvensnrecsys.png" />
</div>

> Simple Recommender System
## What's Important

Maybe in several months, I'll come back to update the repository.(now: 📖🏃🏻‍♂️💖)

#### what you can do:

- [ ] rs models
- [ ] docker files
- [ ] other fns
- [ ] directly flink to redis (now it seems a trick) [import specific jar]

> **!!!** the system now is **really really really** rudimentary
## Functions

- similar movies
- movies (genres)
- recommend for specific user
- movies on hot (click shot)

## Envirenment

> `front`
>
> ~ recfront
>
> npm install
>
> npm run dev
>
> `back`
>
> ~ root
>
> make sure: zookeeper kafka(topic: rec3) redis
>
> python3 app.py
- pyspark
- pyfink
- kafka - redis
- node

## Architecture

<img src="./architecture/architecture.png" />

160 changes: 160 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import os
import random

from flask import Flask, render_template, jsonify, session
from flask import request

from rec.nearline.UserAction import UserAction
from rec.nearline.kafkaManager import kafkaInc
from rec.online.datastructer.DataManager import DataManager
from rec.utils.object2jsonable import object2jsonable
import rec.online.recFuncs.similarRec as similarRec
import rec.online.recFuncs.recForYou as recForYou
from rec.utils.redisManager import RedisManager

app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(24)

# @app.errorhandler(Exception)
# def global_exception_handler(e):
# return 'Error', 500


@app.before_request
def global_header_set():
if 'userId' not in session:
session['userId'] = 1


# @app.route('/')
# @app.route('/index.html')
# def index():
# return render_template('index.html')
#
#
# @app.route('/movie.html')
# def movie():
# args = request.args
# movieId = args['movieId']
# userId = session['userId']
# kafkaInc.send(UserAction(userId, movieId, "click").csvFormat())
# return render_template('movie.html')


@app.route('/movieclick')
def movieclick():
args = request.args
movieId = args['movieId']
userId = session['userId']
kafkaInc.send(UserAction(userId, movieId, "click").csvFormat())
return "ok", 200


# @app.route('/user.html')
# def user():
# return render_template('user.html')
#
#
# @app.route('/collection.html')
# def collection():
# return render_template('collection.html')


@app.route('/changeUid')
def changeUID():
session['userId'] = request.args['uid']
return "change success", 200, [('Content-Type', 'application/json; charset=utf-8')]


@app.route('/getAllUsers', methods=['GET'])
def getAllUsers():
users = random.sample(list(dataManager.userMap.values()), 30)
users = object2jsonable(users)
return jsonify(users), 200, [('Content-Type', 'application/json; charset=utf-8')]


@app.route('/getAllGenres', methods=['GET'])
def getAllGenres():
genres = random.sample([i[0] for i in sorted(dataManager.genreMoviesMap.items(), key=lambda g:len(g[1]), reverse=True)], 5)
genres = object2jsonable(genres)
return jsonify(genres), 200, [('Content-Type', 'application/json; charset=utf-8')]


@app.route('/getRecommendMovie', methods=['GET'])
def recommendM():
args = request.args
genre = args['genre']
size = args['size']
sortby = args['sortby']
movies = dataManager.getMoviesByGenre(genre, int(size), sortby)
movies = object2jsonable(movies)
return jsonify(movies), 200, [('Content-Type', 'application/json; charset=utf-8')]


@app.route('/getHotMovies', methods=['GET'])
def recHotM():
args = request.args
size = args['size']
# hot top 10
r = RedisManager()
k = r.keys("hot*")
movies = {i[3:]: r.get(i) for i in k}
movies = [dataManager.getMoviesById(int(m[0])) for m in sorted(movies.items(), key=lambda i: i[1], reverse=True)[:int(size)]]
movies = object2jsonable(movies)
return jsonify(movies), 200, [('Content-Type', 'application/json; charset=utf-8')]


@app.route('/getrecforyou', methods=['GET'])
def rec_for_you():
args = request.args
userId = args['id']
size = args['size']
model = args['model']
movies = recForYou.getRecList(int(userId), int(size), model)
movies = object2jsonable(movies)
return jsonify(movies), 200, [('Content-Type', 'application/json; charset=utf-8')]


@app.route('/getsimilarmovie', methods=['GET'])
def rec_by_similarM():
args = request.args
movieId = args['movieId']
size = args['size']
model = args['model']
movies = similarRec.getRecList(int(movieId), int(size), model)
print(movies)
movies = object2jsonable(movies)
return jsonify(movies), 200, [('Content-Type', 'application/json; charset=utf-8')]


@app.route('/getmovie', methods=['GET'])
def movie_info():
args = request.args
movieId = args['id']
movie = dataManager.getMoviesById(int(movieId))
movie = object2jsonable(movie)
return jsonify(movie), 200, [('Content-Type', 'application/json; charset=utf-8')]


@app.route('/getuser', methods=['GET'])
def user_info():
args = request.args
userId = args['id']
user = dataManager.getUserById(int(userId))
user = object2jsonable(user)
return jsonify(user), 200, [('Content-Type', 'application/json; charset=utf-8')]


@app.after_request
def global_header_set(response):
response.headers['Access-Control-Allow-Origin'] = '*'
return response


dataManager = DataManager()
dataManager.loadData('static/sampledata/movies.csv', 'static/sampledata/links.csv',
'static/sampledata/ratings.csv', 'static/modeldata/item2vecEmb.csv',
'static/modeldata/userEmb.csv', '', '')

if __name__ == '__main__':
app.run(debug=True)
Binary file added architecture/architecture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions front-end/recFront/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
VITE_API_DOMAIN=http://127.0.0.1:5000
VITE_STATIC_DOMAIN=http://127.0.0.1:5000/static/
2 changes: 2 additions & 0 deletions front-end/recFront/.env.production
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
VITE_API_DOMAIN=/
VITE_STATIC_DOMAIN=static/
24 changes: 24 additions & 0 deletions front-end/recFront/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
3 changes: 3 additions & 0 deletions front-end/recFront/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"recommendations": ["johnsoncodehk.volar"]
}
11 changes: 11 additions & 0 deletions front-end/recFront/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Vue 3 + Typescript + Vite

This template should help get you started developing with Vue 3 and Typescript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.

## Recommended IDE Setup

- [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar)

## Type Support For `.vue` Imports in TS

Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates. However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can enable Volar's `.vue` type support plugin by running `Volar: Switch TS Plugin on/off` from VSCode command palette.
13 changes: 13 additions & 0 deletions front-end/recFront/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>SilvensnRecSys</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
Loading

0 comments on commit 3077d45

Please sign in to comment.