Skip to content

Commit

Permalink
Merge pull request #18 from nianhua99/feat-add_share_usage
Browse files Browse the repository at this point in the history
Feat:add share usage
  • Loading branch information
nianhua99 authored Dec 26, 2023
2 parents 08ddff0 + 0bd9f38 commit 5b3393d
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 30 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.10-alpine
FROM python:3.9-slim-bookworm
WORKDIR /app
COPY . /app
ENV TZ Asia/Shanghai
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
~~GPT-4和Copilot帮助完成了本项目90%的代码~~
## 简单介绍
* **使用Web页面管理你PandoraNext的所有Token!**
* **你无需了解各种Token的含义和获取方式,Helper帮你处理了这一切!**
* 支持添加 `账号\密码` ,一键获取`Access Token``Session Token`
* 自动使用 `Session Token` 续期,节省Pandora额度!
* 管理账号下的所有`Share Token`。支持一键刷新所有`Share Token`、吊销指定`Share Token`
* 一键启动定时器,自动检测Token失效后刷新`Access Token``Share Token`
* 在以上操作完成后,会自动更新`config.json`文件,并调用`reload` Api,直接生效 !
* 本项目保持低侵入性,不参与管理PandoraNext程序。只是方便刷新、管理账号和各种Token。
![example.png](example.png)
![shareinfo.png](shareinfo.png)
## Docker部署
```shell
$ docker pull q11391/pandora-next-helper
Expand Down
2 changes: 1 addition & 1 deletion app.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,4 @@ def create_app():

if __name__ == '__main__':
app = create_app()
app.run(debug=False)
app.run(debug=True)
55 changes: 49 additions & 6 deletions main/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,41 @@ def delete_share(user_id, unique_name):
return redirect(url_for('main.manage_users'))


# 获取ShareToken用量信息
@main_bp.route('/share-info/<int:user_id>')
def share_info(user_id):
from app import query_db
user = query_db('select * from users where id = ?', one=True, args=(user_id,))
if user['access_token'] is None:
return jsonify({'code': 500, 'msg': '请先刷新'})
share_list = json.loads(user['share_list'])
dims = []
sources = []
for share in share_list:
info = share_tools.get_share_token_info(share['share_token'], user['access_token'])
if 'usage' in info:
if 'range' in info['usage']:
# 删除range键值对
del info['usage']['range']
temp = {'UniqueNames': share['unique_name']}
for k, v in info['usage'].items():
# 尝试转换为int
try:
v = int(v)
except:
pass
temp[k] = v
dims.append(k)
sources.append(temp)
dims = list(set(dims))
# 在dims的头部插入UniqueNames
dims.insert(0, 'UniqueNames')
return jsonify({
"dims": dims,
"source": sources
})


def refresh(user_id):
from app import query_db
user = query_db('select * from users where id = ?', one=True, args=(user_id,))
Expand Down Expand Up @@ -146,6 +181,7 @@ def refresh(user_id):

def refresh_all_user():
from app import scheduler, app
flag = False
with scheduler.app.app_context():
from app import query_db
users = query_db('select * from users')
Expand All @@ -160,10 +196,13 @@ def refresh_all_user():
exp_time = datetime.fromtimestamp(token_info['exp'])
if exp_time > datetime.now():
continue
flag = True
refresh(user['user_id'])
except Exception as e:
logger.error(e)
sync_pandora()
if flag:
sync_pandora()
logger.info('刷新成功')


@main_bp.route('/start_timer')
Expand Down Expand Up @@ -197,8 +236,11 @@ def refresh_route(user_id):

def make_json():
from app import query_db
from flask import current_app
import os
users = query_db("select * from users")
tokens = {}
with open(os.path.join(current_app.config['pandora_path'], 'tokens.json'), 'r') as f:
tokens = json.loads(f.read())
# 将share_list转换为json对象
for user in users:
# 当存在share_list时, 取所有share_token, 并写入tokens.json
Expand Down Expand Up @@ -227,11 +269,12 @@ def make_json():
tokens[user['email']]['shared'] = False
tokens[user['email']]['password'] = user['password']
# 检测当前是否存在tokens.json,如果有则备份,文件名为tokens.json + 当前时间
import os
if os.path.exists('tokens.json'):

if os.path.exists(os.path.join(current_app.config['pandora_path'], 'tokens.json')):
import time
os.rename('tokens.json', 'tokens.json.' + time.strftime("%Y%m%d%H%M%S", time.localtime()))
from flask import current_app
os.rename(os.path.join(current_app.config['pandora_path'], 'tokens.json'),
os.path.join(current_app.config['pandora_path'], 'tokens.json.' + time.strftime("%Y%m%d%H%M%S", time.localtime())))

# 将数据写入tokens.json
with open(os.path.join(current_app.config['pandora_path'], 'tokens.json'), 'w') as f:
# 美化json
Expand Down
Binary file added shareinfo.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 templates/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/echarts.min.js"></script>

{% block styles %}
<!-- Bootstrap CSS -->
{{ bootstrap.load_css() }}
Expand Down
111 changes: 89 additions & 22 deletions templates/manage_users.html
Original file line number Diff line number Diff line change
Expand Up @@ -108,24 +108,47 @@ <h5 class="modal-title" id="addShareModalLabel">添加新乘客</h5>
</div>
</div>

<!-- 图表模态框 -->
<div class="modal fade" id="chartModal" tabindex="-1" aria-labelledby="chartModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="chartModalLabel">用量信息</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- ECharts图表容器 -->
<div id="chartContainer" style="height: 400px;"></div>
<!-- Spinner -->
<div id="chartSpinner" class="text-center">
<div class="spinner-border" role="status">
<span class="visually-hidden">加载中...</span>
</div>
</div>
</div>
</div>
</div>
</div>

<table class="table table-hover text-center align-middle table-responsive">
<thead>
<tr>
<th scope="col">id</th>
<th scope="col">Email</th>
<th scope="col">Password</th>
<th scope="col">Session Token</th>
<th scope="col">Access Token</th>
<th scope="col">Shared</th>
<th scope="col">Update/Refresh Time</th>
<th scope="col" style="width: 200px">Operation</th>
</tr>
<tr>
<th scope="col">id</th>
<th scope="col">Email</th>
<th scope="col">Password</th>
<th scope="col">Session Token</th>
<th scope="col">Access Token</th>
<th scope="col">Shared</th>
<th scope="col">Update/Refresh Time</th>
<th scope="col">Share</th>
<th scope="col">Operation</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<th scope="row">
<button class="btn btn- btn-small" type="button" data-bs-toggle="collapse"
<button class="btn btn-small" type="button" data-bs-toggle="collapse"
data-bs-target="#collapseExample{{ user['id'] }}" aria-expanded="false"
aria-controls="collapseExample">
<i class="fa fa-angle-right"></i>
Expand All @@ -139,15 +162,20 @@ <h5 class="modal-title" id="addShareModalLabel">添加新乘客</h5>
<td>{{ '√' if user['shared'] == 1 else '×' }}</td>
<td>{{ user['update_time'] }}</td>
<td>
<button
type="button"
class="btn btn-outline-primary btn-sm"
data-bs-toggle="modal"
data-bs-target="#addShareModal"
data-bs-userid="{{ user['id'] }}"
>
新增
</button>
<div class="btn-group">
<button
type="button"
class="btn btn-outline-primary btn-sm"
data-bs-toggle="modal"
data-bs-target="#addShareModal"
data-bs-userid="{{ user['id'] }}"
>
新增
</button>
<button type="button" class="btn btn-outline-primary btn-sm" data-bs-toggle="modal" data-bs-target="#chartModal" data-userid="{{ user['id'] }}">用量</button>
</div>
</td>
<td>
<div class="btn-group" role="group" aria-label="Basic outlined example">
<button
type="button"
Expand All @@ -165,7 +193,7 @@ <h5 class="modal-title" id="addShareModalLabel">添加新乘客</h5>
</td>
</tr>
<tr>
<td colspan="8" class="collapse" id="collapseExample{{ user['id'] }}">
<td colspan="9" class="collapse" id="collapseExample{{ user['id'] }}">
<table class="table align-middle">
<tr>
<th>Unique Name</th>
Expand Down Expand Up @@ -201,6 +229,7 @@ <h5 class="modal-title" id="addShareModalLabel">添加新乘客</h5>
</div>
</div>
</div>

<footer class="footer mt-auto py-3">
<div class="container">
<div class="progress" role="progressbar" aria-label="Animated striped example" aria-valuenow="{{ balance['current'] }}"
Expand All @@ -216,6 +245,7 @@ <h5 class="modal-title" id="addShareModalLabel">添加新乘客</h5>
<span class="w-100 d-block py-3" style="color: var(--bs-secondary-color)" >Powered By PandoraNext Helper</span>
</div>
</footer>

<script>
const addShareModal = document.getElementById('addShareModal')
addShareModal.addEventListener('show.bs.modal', event => {
Expand All @@ -225,6 +255,44 @@ <h5 class="modal-title" id="addShareModalLabel">添加新乘客</h5>
const modalBodyInput = addShareModal.querySelector('.modal-body #user_id')
modalBodyInput.value = recipient
})
const chartModal = document.getElementById('chartModal')

chartModal.addEventListener('show.bs.modal', event => {
const button = event.relatedTarget
const recipient = button.getAttribute('data-userid')
console.log(recipient)
const chartContainer = chartModal.querySelector('#chartContainer')
const chartSpinner = chartModal.querySelector('#chartSpinner')
chartContainer.style.display = 'none'
chartSpinner.style.display = 'block'
fetch('/{{ api_prefix }}/share-info/' + recipient)
.then(response => response.json())
.then(responseData => {
var option = {
legend: {},
tooltip: {},
dataset: {
dimensions: responseData['dims'],
source: responseData['source']
},
xAxis: {type: 'category'},
yAxis: {},
series: []
}
for(var i = 1;i<responseData['dims'].length;i++){
option['series'].push({type: 'bar'})
}
console.log(option)
chartSpinner.style.display = 'none'
chartContainer.style.display = 'block'
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(chartContainer);
myChart.setOption(option);
})
.catch(error => {
console.error('Error:', error);
})
})
document.getElementById('addShareForm').addEventListener('submit', function (e) {
const submitButton = this.querySelector('button[type="submit"]');
const spinner = submitButton.querySelector('.spinner-border');
Expand All @@ -233,7 +301,6 @@ <h5 class="modal-title" id="addShareModalLabel">添加新乘客</h5>
spinner.style.display = 'inline-block';
buttonText.style.display = 'none';
});

document.getElementById('addUserForm').addEventListener('submit', function (event) {
// 阻止表单默认提交
event.preventDefault();
Expand Down

0 comments on commit 5b3393d

Please sign in to comment.