This commit is contained in:
root 2024-04-08 21:59:15 +08:00
parent 959726a6a5
commit 83f1d53106
19 changed files with 329 additions and 24 deletions

1
MANIFEST.in Normal file
View File

@ -0,0 +1 @@
recursive-include pmpt/data *

View File

@ -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 .

View File

@ -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
View 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>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

View 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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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
View 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
View 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.

View 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 包变得更加便捷。
## 特性 ## 特性

View File

@ -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
View File

@ -0,0 +1,3 @@
black>=24.3.0
wheel
setuptools

View File

@ -0,0 +1,2 @@
flask>=3.0.2
flask_caching==2.1.0

View File

@ -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,
) )