Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
MisakaFxxk authored Mar 7, 2023
1 parent aa6109d commit bbaccaa
Show file tree
Hide file tree
Showing 3 changed files with 271 additions and 0 deletions.
74 changes: 74 additions & 0 deletions Infuse/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Infuse扫库优化模块

### 一、原理实现

Infuse扫库时只需要接收固定的json数据,所以我们可以将这些数据保存到数据库内,如果有扫库请求,通过URL内的一些参数定位json,返回即可。

Nginx劫持Infuse扫库请求到本地搭建的扫库服务上,首先判断此条json数据库内是否存在,若存在则直接返回,若不存在则通过GET向Emby请求获取,先向Infuse客户端返回json,再保存到数据库内,以供下次直接使用。

### 二、环境配置

Nginx反向代理本地Emby服务端,Python3&Pip3。

```
安装Python第三方包:
pip3 install flask
pip3 install requests
pip3 install pymysql
pip3 install DBUtils==1.2
```

### 三、Nginx配置

打开Nginx反向代理配置文件,在location / 下面的大括号****添加:

I know, I know,这个实现方法相当蠢。如果有高人还望不吝赐教,但目前它至少能跑,反正代码和我有一个能跑就行。

```
if ($http_user_agent ~* "Infuse") {
set $check yes;
}
if ( $request_uri ~* /Users/(.*)/Items\?ExcludeLocationTypes=Virtual )
{
set $check2 "${check}yes";
}
if ( $request_uri ~* Episode )
{
set $check3 "${check2}yes";
}
if ( $request_uri ~* Movie )
{
set $check3 "${check2}yes";
}
set $check4 yes;
if ( $request_uri ~* StartIndex=0 )
{
set $check4 no;
}
set $check3 "${check3}${check4}";
if ($check3 = "yesyesyesyes")
{
proxy_pass http://127.0.0.1:60000;
}
```

### 三、数据库配置

在Emby本机上安装Mysql 8.0数据库。

首先创建一个名为`infuse`的数据库,然后创建一个名为`metadata`的表,表内结构如下,也可直接使用文件夹内的metadata.sql来导入表结构。

![image-20230307091348630](C:\Users\ChengYifei\AppData\Roaming\Typora\typora-user-images\image-20230307091348630.png)

### 四、Python配置

`infuse.py`下载到本地并打开,修改第11行的Emby地址为未经过Nginx反向代理的Emby地址,修改14行开始的数据库配置内的user和password。

### 五、启动优化模块

```
screen -S infuse
python3 infuse.py
或后台运行:
nohup python3 infuse.py > infuse.log 2>&1 &
```
165 changes: 165 additions & 0 deletions Infuse/infuse.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import flask,requests,json,pymysql
from flask import request
from DBUtils.PooledDB import PooledDB
from pymysql.converters import escape_string

api = flask.Flask(__name__)
localhost = 'http://127.0.0.1:8096' #本地Emby地址,未经过Nginx的Emby访问链接,最后不加/

#连接数据库
DB_CONFIG={
"host":"127.0.0.1",
"port":3306,
"user":"",
"password":"",
"db":"infuse",
"charset":"utf8"
}

#创建Mysql线程池
class MysqlTools(object):
def __init__(self):
self.pool=PooledDB(
creator=pymysql,
maxconnections=10, #连接池允许的最大连接数
mincached=1,
maxcached=5,
maxshared=3,
blocking=True,
maxusage=None,
setsession=[],
ping=0,
host=DB_CONFIG["host"],
port=DB_CONFIG["port"],
user=DB_CONFIG["user"],
password=DB_CONFIG["password"],
database=DB_CONFIG["db"],
charset=DB_CONFIG["charset"]
)

def open(self):
conn=self.pool.connection()
cursor=conn.cursor(cursor=pymysql.cursors.DictCursor)
return conn,cursor

def close(self,conn,cursor):
cursor.close()
conn.close()

def get_list(self, sql, args=None):
try:
conn,cursor=self.open()
cursor.execute(sql, args)
result = cursor.fetchall()
self.close(conn,cursor)
return result
except:
return False

# 查询单条记录
def get_one(self, sql, args=None):
try:
conn, cursor = self.open()
cursor.execute(sql, args)
result = cursor.fetchone()
self.close(conn, cursor)
return result
except:
return False

# 执行单条sql
def execute_one(self, sql, args=None):
try:
conn, cursor = self.open()
cursor.execute(sql, args)
conn.commit()
self.close(conn, cursor)
return True
except Exception as e:
print(e)

# 添加数据返回insertID
def create(self, sql, args=None):
try:
conn, cursor = self.open()
cursor.execute(sql, args)
conn.commit()
insert_id = cursor.lastrowid
self.close(conn, cursor)
return insert_id
except:
self.close(conn, cursor)
return False

def close(self,conn,cursor):
try:

cursor.close()
conn.close()
except:
raise Exception("关闭数据库失败")


@api.route('/Users/<user_id>/Items', methods=["GET", "POST"])
def update(user_id):
my_mysql=MysqlTools()
#参数获取
ParentId = request.args.get("ParentId")
StartIndex = request.args.get("StartIndex")
Limit = request.args.get("Limit")
IncludeItemTypes = request.args.get("IncludeItemTypes")
UserAgent = request.user_agent
XEmbyAuthorization = request.headers.get('X-Emby-Authorization')

#判断是否为新数据
exist = 0
try:
sql = "select count(*) from metadata where ParentId = {ParentId} and StartIndex = {StartIndex} and IncludeItemTypes = '{IncludeItemTypes}'".format(ParentId=ParentId,StartIndex=StartIndex,IncludeItemTypes=IncludeItemTypes)
result = my_mysql.get_one(sql)
except Exception as e:
print(e,"flag1")
else:
exist = result["count(*)"]
if(exist == 0):
#新数据请求
print("未命中,写入数据库")
headers = {
'Connection': 'keep-alive',
'Accept-Language': 'zh-CN',
'Accept-Encoding': 'gzip, deflate',
'User-Agent': str(UserAgent),
'Accept': 'application/json',
'X-Emby-Authorization': str(XEmbyAuthorization)
}
url = localhost + '/Users/{user_id}/Items?ExcludeLocationTypes=Virtual&Fields=DateCreated,Etag,Genres,MediaSources,Overview,ParentId,Path,People,ProviderIds,SortName,CommunityRating,OfficialRating,PremiereDate&ParentId={ParentId}&StartIndex={StartIndex}&Limit={Limit}&IncludeItemTypes={IncludeItemTypes}&Recursive=true'.format(user_id=user_id,ParentId=ParentId,StartIndex=StartIndex,Limit=Limit,IncludeItemTypes=IncludeItemTypes)
response = requests.get(url,headers=headers)
resjson = response.json()

try:
#向Infuse客户端返回
return resjson,200,{"Content-Type":"application/json; charset=utf-8","Access-Control-Allow-Headers": "Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, Content-Type, Date, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-MediaBrowser-Token, X-Emby-Token, X-Emby-Client, X-Emby-Client-Version, X-Emby-Device-Id, X-Emby-Device-Name, X-Emby-Authorization","Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS","Access-Control-Allow-Origin": "*"}
finally:
#向数据库追加新数据
data = json.dumps(resjson,ensure_ascii=False)
try:
sql = "insert into metadata (ParentId,StartIndex,IncludeItemTypes,data) values ({ParentId},{StartIndex},'{IncludeItemTypes}','{data}')".format(ParentId=ParentId,StartIndex=StartIndex,IncludeItemTypes=IncludeItemTypes,data=escape_string(data))
result = my_mysql.create(sql)
except Exception as e:
print(e,"flag2")
else:
#数据库中已存在
print("命中")
try:
sql = "select data from metadata where ParentId = {ParentId} and StartIndex = {StartIndex} and IncludeItemTypes = '{IncludeItemTypes}'".format(ParentId=ParentId,StartIndex=StartIndex,IncludeItemTypes=IncludeItemTypes)
result = my_mysql.get_one(sql)
except Exception as e:
print(e,"flag3")
else:
data = result["data"]
resjson = json.loads(data)
#向Infuse客户端返回
return resjson,200,{"Content-Type":"application/json; charset=utf-8","Access-Control-Allow-Headers": "Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, Content-Type, Date, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-MediaBrowser-Token, X-Emby-Token, X-Emby-Client, X-Emby-Client-Version, X-Emby-Device-Id, X-Emby-Device-Name, X-Emby-Authorization","Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS","Access-Control-Allow-Origin": "*"}


if __name__ == '__main__':
api.run(port=60000,debug=True,host='0.0.0.0',threaded=True)
32 changes: 32 additions & 0 deletions Infuse/metadata.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
Navicat Premium Data Transfer
Source Server : 公益服2Infuse数据库
Source Server Type : MySQL
Source Server Version : 80024 (8.0.24)
Source Host : 172.96.161.64:3306
Source Schema : infuse
Target Server Type : MySQL
Target Server Version : 80024 (8.0.24)
File Encoding : 65001
Date: 06/03/2023 15:44:29
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for metadata
-- ----------------------------
DROP TABLE IF EXISTS `metadata`;
CREATE TABLE `metadata` (
`ParentId` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`StartIndex` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`IncludeItemTypes` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`limit` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`data` longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;

SET FOREIGN_KEY_CHECKS = 1;

0 comments on commit bbaccaa

Please sign in to comment.