添加UI
This commit is contained in:
parent
959726a6a5
commit
83f1d53106
1
MANIFEST.in
Normal file
1
MANIFEST.in
Normal file
|
@ -0,0 +1 @@
|
||||||
|
recursive-include pmpt/data *
|
13
Makefile
13
Makefile
|
@ -14,12 +14,14 @@ BUILD_DIR := build
|
||||||
ALL: help
|
ALL: help
|
||||||
help:
|
help:
|
||||||
@echo "Available targets:"
|
@echo "Available targets:"
|
||||||
@echo " install Install dependencies"
|
@echo " build Build Package"
|
||||||
@echo " test Run tests"
|
@echo " init Initialization"
|
||||||
@echo " clean Clean up"
|
@echo " clean Clean up"
|
||||||
|
@echo " cleanall Clear All"
|
||||||
|
@echo " venv Create a virtual environment"
|
||||||
|
|
||||||
build:
|
build: pre
|
||||||
$(PYTHON) setup.py bdist_wheel -d $(DIST_DIR) sdist -d $(DIST_DIR)
|
$(PYTHON) setup.py bdist_wheel -d $(DIST_DIR) sdist -d $(DIST_DIR) bdist_egg -d $(DIST_DIR)
|
||||||
|
|
||||||
init: venv
|
init: venv
|
||||||
@for file in requirements/*.txt; do \
|
@for file in requirements/*.txt; do \
|
||||||
|
@ -45,3 +47,6 @@ commit:
|
||||||
git add .; \
|
git add .; \
|
||||||
git commit -m "$(msg)"; \
|
git commit -m "$(msg)"; \
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
pre: init
|
||||||
|
$(PYTHON) -m black .
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
# pylint:disable=W0611
|
# pylint:disable=W0611
|
||||||
|
import datetime
|
||||||
|
import webbrowser
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
import click
|
import click
|
||||||
from . import update as updates
|
|
||||||
from . import util
|
|
||||||
from moyanlib import jsons
|
from moyanlib import jsons
|
||||||
from rich.table import Table
|
from rich.table import Table
|
||||||
|
from . import update as updates
|
||||||
|
from . import util
|
||||||
from . import source as sou
|
from . import source as sou
|
||||||
from . import environment as environ
|
from . import environment as environ
|
||||||
from . import install as installs
|
from . import install as installs
|
||||||
from . import search as searchs
|
from . import search as searchs
|
||||||
import datetime
|
from . import web as webs
|
||||||
import webbrowser
|
|
||||||
import time
|
|
||||||
|
|
||||||
|
|
||||||
@click.group()
|
@click.group()
|
||||||
|
@ -123,5 +126,10 @@ def version():
|
||||||
environ.main()
|
environ.main()
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command()
|
||||||
|
def web():
|
||||||
|
webs.run()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
cli()
|
cli()
|
||||||
|
|
147
pmpt/data/index.html
Normal file
147
pmpt/data/index.html
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>PMPT WebUI</title>
|
||||||
|
<!-- Bootstrap CSS -->
|
||||||
|
<link href="statics/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="statics/css/bootstrap-icons.min.css">
|
||||||
|
<style>
|
||||||
|
.trs>* {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.memu>.left {
|
||||||
|
margin-right: 1.75%;
|
||||||
|
float: left;
|
||||||
|
|
||||||
|
}
|
||||||
|
.memu>.left {
|
||||||
|
margin-right: 1.75%;
|
||||||
|
float: left;
|
||||||
|
|
||||||
|
}
|
||||||
|
.memu>.right {
|
||||||
|
margin-right: 1.75%;
|
||||||
|
float: right;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="memu">
|
||||||
|
<button id="add-row-btn" class="btn btn-primary btn-sm left">Add</button>
|
||||||
|
<button id="add-row-btn" class="btn btn-primary btn-sm left">Search</button>
|
||||||
|
<button class="btn btn-outline-primary btn-sm right"><i class="bi bi-gear"></i></button>
|
||||||
|
<button class="btn btn-outline-primary btn-sm right"><i class="bi bi-arrow-counterclockwise"></i></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr class="trd">
|
||||||
|
<th scope="col">Package Name</th>
|
||||||
|
<th scope="col">Version</th>
|
||||||
|
<th scope="col">Options</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="table-body">
|
||||||
|
|
||||||
|
<!-- Table rows will be dynamically added here -->
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div align="center" id="loading">
|
||||||
|
<img src="statics/img/loading.svg" width="10%">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal fade" id="alert" tabindex="-1" aria-labelledby="alertTitle" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h1 class="modal-title fs-5" id="alertTitle">Modal title</h1>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body" id="alertBody">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" id="alertOK">OK</button>
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" aria-label="Close" onclick="javascript:">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Bootstrap JS and jQuery -->
|
||||||
|
<script src="statics/js/jquery-3.7.1.min.js"></script>
|
||||||
|
<script src="statics/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var alertCallback = 10;
|
||||||
|
|
||||||
|
function alert(title, body, callback) {
|
||||||
|
|
||||||
|
alertCallback = callback
|
||||||
|
$("#alertTitle").html(title)
|
||||||
|
$("#alertBody").html(body)
|
||||||
|
$("#alertOK").attr("onclick", "javasrcipt:" + callback)
|
||||||
|
$("#alert").modal("show")
|
||||||
|
|
||||||
|
}
|
||||||
|
// Function to add a new row to the table
|
||||||
|
function addRow(name, ver) {
|
||||||
|
var newRowHtml = `
|
||||||
|
<tr pn=${name} >
|
||||||
|
<td><a href="/package/${name}">${name}</a></td>
|
||||||
|
<td>${ver}</td>
|
||||||
|
<td class="row">
|
||||||
|
<button onclick="javascript:packageDel(this)" href="#" class="btn btn-link col">Delete</button>
|
||||||
|
<button onclick="javascript:packageDel(this)" href="#" class="btn btn-link col">Update</button>
|
||||||
|
<button onclick="javascript:packageDel(this)" href="#" class="btn btn-link col">More</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Append the new row to the table body
|
||||||
|
$("#table-body").append(newRowHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
function delpack(namd) {
|
||||||
|
$.ajax({
|
||||||
|
url: "/api/remove"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function packageDel(element) {
|
||||||
|
var parentRow = element.parentNode.parentNode;
|
||||||
|
|
||||||
|
// Get the value of the 'pn' attribute of the parent row
|
||||||
|
var packageName = parentRow.getAttribute('pn');
|
||||||
|
alert("Delete Package", "Are you sure you want to delete?", "delpack('" + packageName + "')")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add event listener for the "Add Row" button
|
||||||
|
$(document).ready(function() {
|
||||||
|
$.ajax({
|
||||||
|
url: "http://127.0.0.1:14536/api/list",
|
||||||
|
type: "GET",
|
||||||
|
dataType: "JSON",
|
||||||
|
success: function(res) {
|
||||||
|
$.each(res, function(index, items) {
|
||||||
|
addRow(items.name, items.ver);
|
||||||
|
});
|
||||||
|
$("#loading").remove()
|
||||||
|
},
|
||||||
|
error: function(xhr) {
|
||||||
|
alert("Error","Unable to connect to backend","retryGetList()")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
5
pmpt/data/statics/css/bootstrap-icons.min.css
vendored
Normal file
5
pmpt/data/statics/css/bootstrap-icons.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
5
pmpt/data/statics/css/bootstrap.min.css
vendored
Normal file
5
pmpt/data/statics/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
pmpt/data/statics/fonts/bootstrap-icons.woff2
Normal file
BIN
pmpt/data/statics/fonts/bootstrap-icons.woff2
Normal file
Binary file not shown.
9
pmpt/data/statics/img/loading.svg
Normal file
9
pmpt/data/statics/img/loading.svg
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="5%" height="5%" viewBox="0 0 40 40" enable-background="new 0 0 40 40" xml:space="preserve">
|
||||||
|
<path opacity="0.2" fill="#0D6EFD" d="M20.201,5.169c-8.254,0-14.946,6.692-14.946,14.946c0,8.255,6.692,14.946,14.946,14.946
|
||||||
|
s14.946-6.691,14.946-14.946C35.146,11.861,28.455,5.169,20.201,5.169z M20.201,31.749c-6.425,0-11.634-5.208-11.634-11.634
|
||||||
|
c0-6.425,5.209-11.634,11.634-11.634c6.425,0,11.633,5.209,11.633,11.634C31.834,26.541,26.626,31.749,20.201,31.749z"></path>
|
||||||
|
<path fill="#0D6EFD" d="M26.013,10.047l1.654-2.866c-2.198-1.272-4.743-2.012-7.466-2.012h0v3.312h0
|
||||||
|
C22.32,8.481,24.301,9.057,26.013,10.047z" transform="rotate(42.1171 20 20)">
|
||||||
|
<animateTransform attributeType="xml" attributeName="transform" type="rotate" from="0 20 20" to="360 20 20" dur="0.5s" repeatCount="indefinite"></animateTransform>
|
||||||
|
</path>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 939 B |
6
pmpt/data/statics/js/bootstrap.bundle.min.js
vendored
Normal file
6
pmpt/data/statics/js/bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
pmpt/data/statics/js/jquery-3.7.1.min.js
vendored
Normal file
2
pmpt/data/statics/js/jquery-3.7.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -58,7 +58,7 @@ def init():
|
||||||
open(os.path.join(dirs.user_config_dir, "Source.json"), "w").write("[]")
|
open(os.path.join(dirs.user_config_dir, "Source.json"), "w").write("[]")
|
||||||
from . import source
|
from . import source
|
||||||
|
|
||||||
source.add()
|
source.add("https://pypi.org/simple", 1)
|
||||||
|
|
||||||
if not os.path.exists(os.path.join(dirs.user_config_dir, "api.url")):
|
if not os.path.exists(os.path.join(dirs.user_config_dir, "api.url")):
|
||||||
open(os.path.join(dirs.user_config_dir, "api.url"), "w").write(
|
open(os.path.join(dirs.user_config_dir, "api.url"), "w").write(
|
||||||
|
|
51
pmpt/web.py
Normal file
51
pmpt/web.py
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
from flask import Flask, render_template, jsonify, redirect
|
||||||
|
from . import util
|
||||||
|
import os
|
||||||
|
from flask_caching import Cache
|
||||||
|
|
||||||
|
current_dir = os.path.dirname(__file__)
|
||||||
|
|
||||||
|
app = Flask(
|
||||||
|
__file__,
|
||||||
|
template_folder=os.path.join(current_dir, "data"),
|
||||||
|
static_folder=os.path.join(current_dir, "data", "statics"),
|
||||||
|
)
|
||||||
|
|
||||||
|
config = { # some Flask specific configs
|
||||||
|
"CACHE_TYPE": "FileSystemCache", # Flask-Caching related configs
|
||||||
|
"CACHE_DEFAULT_TIMEOUT": 600,
|
||||||
|
"CACHE_DIR": util.dirs.user_cache_dir,
|
||||||
|
}
|
||||||
|
app.config.from_mapping(config)
|
||||||
|
cache = Cache(app)
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
app.run(port=14536)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/")
|
||||||
|
@cache.cached(timeout=36000)
|
||||||
|
def index():
|
||||||
|
return render_template("index.html")
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/package/<name>")
|
||||||
|
def package(name):
|
||||||
|
return redirect("https://pypi.org/project/" + name)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/api/list")
|
||||||
|
@cache.cached(timeout=600)
|
||||||
|
def api_list():
|
||||||
|
listv = util.runpip("freeze", out=False)
|
||||||
|
outlist = []
|
||||||
|
for line in iter(listv.stdout.readline, b""):
|
||||||
|
|
||||||
|
line = line.decode("utf-8").strip() # 将字节转换为字符串并去除换行符
|
||||||
|
if "==" not in line or line[0] == "#":
|
||||||
|
continue
|
||||||
|
lineList = line.split("==")
|
||||||
|
lineDict = {"name": lineList[0], "ver": lineList[1]}
|
||||||
|
outlist.append(lineDict)
|
||||||
|
return jsonify(outlist)
|
67
readme.en.md
Normal file
67
readme.en.md
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
# PMPT (Python Package Advanced Manager)
|
||||||
|
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
|
||||||
|
PMPT is an advanced tool for managing Python packages, designed to simplify the process of installation, updating, and uninstallation of packages. It provides a simple and user-friendly command-line interface, making Python package management more convenient.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Local Index**: PMPT uses a local index to speed up package querying and installation, improving management efficiency.
|
||||||
|
|
||||||
|
- **Sleek Interface**: PMPT offers an intuitive and sleek command-line interface, allowing users to easily perform package management operations.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
You can install PMPT using the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install pmpt
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Installing Packages
|
||||||
|
|
||||||
|
Install Python packages using PMPT:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pmpt install <package_name>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Updating Index
|
||||||
|
|
||||||
|
Update the local index:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pmpt update
|
||||||
|
```
|
||||||
|
|
||||||
|
### Removing Packages
|
||||||
|
|
||||||
|
Uninstall a specified Python package from the system:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pmpt remove <package_name>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Listing Installed Packages
|
||||||
|
|
||||||
|
List all Python packages currently installed on the system:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pmpt list
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adding a Source
|
||||||
|
|
||||||
|
Add a download source:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pmpt source add <url>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contribution
|
||||||
|
|
||||||
|
Contributions are welcome! If you find a bug or have any suggestions for improvement, please submit an issue or directly propose a pull request.
|
||||||
|
|
||||||
|
## Copyright and License
|
||||||
|
|
||||||
|
PMPT follows the MIT License. For details, please refer to the [LICENSE](LICENSE) file.
|
|
@ -1,5 +1,5 @@
|
||||||
# PMPT (Python Package Advanced Manager)
|
# PMPT (Python Package Advanced Manager)
|
||||||
|
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
|
||||||
PMPT 是一个用于管理 Python 包的高级工具,旨在简化包的安装、更新和卸载过程。它提供了一套简单易用的命令行界面,使得管理 Python 包变得更加便捷。
|
PMPT 是一个用于管理 Python 包的高级工具,旨在简化包的安装、更新和卸载过程。它提供了一套简单易用的命令行界面,使得管理 Python 包变得更加便捷。
|
||||||
|
|
||||||
## 特性
|
## 特性
|
||||||
|
|
|
@ -1,18 +1,11 @@
|
||||||
certifi==2024.2.2
|
|
||||||
charset-normalizer==3.3.2
|
|
||||||
click==8.1.7
|
click==8.1.7
|
||||||
dill==0.3.8
|
dill==0.3.8
|
||||||
idna==3.6
|
|
||||||
loguru==0.7.2
|
loguru==0.7.2
|
||||||
markdown-it-py==3.0.0
|
moyanlib>=1.5.1712028240
|
||||||
mdurl==0.1.2
|
|
||||||
moyanlib==1.5.1712028240
|
|
||||||
platformdirs==4.2.0
|
platformdirs==4.2.0
|
||||||
psutil==5.9.8
|
psutil==5.9.8
|
||||||
pyasn1==0.6.0
|
requests>=2.31.0
|
||||||
Pygments==2.17.2
|
|
||||||
requests==2.31.0
|
|
||||||
rich==13.7.1
|
rich==13.7.1
|
||||||
rsa==4.9
|
|
||||||
tqdm==4.66.2
|
tqdm==4.66.2
|
||||||
urllib3==2.2.1
|
zstandard==0.22.0
|
||||||
|
tinydb==4.8.0
|
3
requirements/dev.txt
Normal file
3
requirements/dev.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
black>=24.3.0
|
||||||
|
wheel
|
||||||
|
setuptools
|
|
@ -0,0 +1,2 @@
|
||||||
|
flask>=3.0.2
|
||||||
|
flask_caching==2.1.0
|
3
setup.py
3
setup.py
|
@ -4,7 +4,7 @@ from pmpt import util
|
||||||
setup(
|
setup(
|
||||||
name="pmpt", # 包的名称
|
name="pmpt", # 包的名称
|
||||||
version=util.__version__, # 版本号
|
version=util.__version__, # 版本号
|
||||||
packages=find_packages(), # 包含的包
|
packages=find_packages(exclude=["tests", "tests.*"]), # 包含的包
|
||||||
author="MoYan", # 作者
|
author="MoYan", # 作者
|
||||||
author_email="moyan@moyanjdc.top", # 作者邮箱
|
author_email="moyan@moyanjdc.top", # 作者邮箱
|
||||||
description="A Python Package Advanced Manager", # 包的简要描述
|
description="A Python Package Advanced Manager", # 包的简要描述
|
||||||
|
@ -27,4 +27,5 @@ setup(
|
||||||
extras_require={
|
extras_require={
|
||||||
"web": open("requirements/web.txt").read().split("\n"),
|
"web": open("requirements/web.txt").read().split("\n"),
|
||||||
},
|
},
|
||||||
|
include_package_data=True,
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user