当前位置 : 主页 > 编程语言 > 其它开发 >

我最高产的EasyPyPI又双叒叕更新了!v1.4.0发布

来源:互联网 收集:自由互联 发布时间:2022-07-17
我愿称之为Python最方便的装库方式!颠覆你对PyPI的认知!! 更新内容 新增了初始化参数,该参数为“--init” 调试参数改为“--debug” 新增了“以管理员身份安装”功能,专治权限不足
我愿称之为Python最方便的装库方式! 颠覆你对PyPI的认知!! 更新内容
  • 新增了初始化参数,该参数为“--init”
  • 调试参数改为“--debug”
  • 新增了“以管理员身份安装”功能,专治权限不足
  • 新增了“根据Python源码安装依赖”功能,我愿称之为最方便的安装方式!
  • 移除了但没有完全移除彩蛋,从根本做起
重磅功能:根据Python源码安装依赖

这应该是史上最简单的装库方式,你只需要选中那个程序的Python源码,然后EasyPyPI会自动识别程序会导入的所有库,然后只需要选择你没有安装的那几个即可。

请注意:该功能刚开发好,BUG可能会很多。

代码
import os
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.filedialog as filebox
import webbrowser
from threading import Thread
import sys

sdo=False
sdi=False


if len(sys.argv)>=1 and '--debug' in sys.argv:
    sdi=True

def showDebug(show_info=False):
    global sdo,sdo_btn,sdi,egg_count
    if show_info:
        if sdi:
            sdi=False
            sdi_btn['text']='显示调试信息'
        else:
            sdi=True
            sdi_btn['text']='隐藏调试信息'
    else:
        if sdo:
            win.geometry('300x390')
            sdo_btn['text']='显示调试选项  v'
            egg_count=0
            sdo=False
        else:
            win.geometry('300x505')
            sdo_btn['text']='隐藏调试选项  ^'
            sdo=True

def dprint(msg):
    global sdi
    if sdi:
        print(msg)

def init():
    global py_path,pip_path,python_path
    try:
        if '--init' in sys.argv:#如果用户要求重新配置
            i=abc#以前这部分关于判断文件是否存在的写法令我震惊,我决定通过制造异常来直接触发except,将错就错(划去
        dprint('正在读取配置信息')
        py_path_f=open("./py_path.cfg",'r',encoding='utf-8')
        py_path=py_path_f.read()
        dprint('根据配置信息,您的Python位于:'+py_path)
        py_path_f.close()
        pip_path=py_path+"/scripts/pip.exe"
        python_path=py_path+"/python.exe"
        dprint('读取完成')
        if py_path=='使用环境变量':
            dprint('使用环境变量')
            pip_path='pip'
            python_path='python'
    except Exception as e:
        dprint('读取设置失败:'+str(e))
        win=tk.Tk()
        win.withdraw()
        py_path=filebox.askdirectory(title='请选择Python安装路径')
        py_path_f=open("./py_path.cfg",'w',encoding='utf-8')
        py_path_f.write(py_path)
        py_path_f.close()
        pip_path=py_path+"/scripts/pip.exe"

def locate_pip(name=''):
    os.system("where pip")
    os.system("where pip3")
    print('==================================================')

def install(name):
    os.system(pip_path+" install "+name+' -i https://pypi.douban.com/simple')
    print('==================================================')

def uninstall(name):
    if name=='pip':
        print('请勿卸载pip!否则通常情况下,您将无法装回!')
    else:
        os.system(pip_path+" uninstall "+name)
    print('==================================================')

def upgrade(name=''):
    os.system(python_path+" -m pip install --upgrade pip -i https://pypi.douban.com/simple")
    print('==================================================')

def list_pkg(name=''):
    os.system(pip_path+" list")
    print('==================================================')

def about(name=''):
    os.system(pip_path+" --version")
    print('==================================================')
    
def start(func,p=''):
    #print(func)
    dprint('将向函数传入此类型的参数:'+str(type(p)))
    dprint('将向函数传入参数:'+str(p))
    #t=Thread(target=func,args=p)
    t=Thread(target=lambda:func(p))
    t.start()

def view(url):
    webwin=tk.Tk()
    webwin.title('网页查看器')
    frame=WebView2(webwin,1200,680)
    frame.load_url(url)
    frame.pack(fill=tk.BOTH,expand=True)
    ttk.Button(webwin,text='在浏览器打开',command=lambda:webbrowser.open(url)).pack(fill=tk.X,side=tk.BOTTOM)
    webwin.mainloop()

def inst_from_lst(lst):
    for i in lst:
        print('正在安装:'+str(i))
        install(str(i))

def start_inst_from_lst(lst,sel,window):#一个杂到无法注释的函数,用于获取选中的库然后开始安装
    selm=[]
    for i in list(sel):
        selm.append(lst[int(i)])
    dprint('即将安装您选中的库:'+str(selm))
    start(inst_from_lst,selm)
    window.destroy()

def inst_from_py(name=''):
    fpath=filebox.askopenfilename(title='请选择Python源码文件',filetypes=[('Python源码文件','.py')])
    f=open(fpath,'r',encoding='utf-8')
    cont=f.read()
    f.close()
    print('正在分析文件...')
    modules=[]#空列表,用于存储要安装的依赖名称(每一项的类型为字符串)
    i=0#记录行数
    for line in cont.split('\n'):#遍历所有代码
        i+=1
        #判断是不是一行导入库的代码,后面的大段条件是为了排除变量(或函数)名含“import”,就例如这段代码,“line.split('#')[0]”的意思是忽略注释满足(或不满足)条件
        if 'import' in line.split('#')[0] and ('=' not in line.split('#')[0]) and ('if' not in line.split('#')[0]) and ('while' not in line.split('#')[0]) and ('print' not in line.split('#')[0]) and ('(' not in line.split('#')[0]):
            thismodule=line
            if 'from' in line:#“from ... import ...”比较特殊,因为它把库名分开了
                thismodule=line.split(' ')[line.split(' ').index('from')+1]#获取“from”后面那个词
            elif 'as' in line:#“import ... as ...”也很特殊,因为里面不仅包含库名,还包含一个别名...
                thismodule=line.split(' ')[line.split(' ').index('import')+1]#同理,获取“import”后面那个词
            else:
                thismodule=thismodule.replace(' ','').replace('import','').replace('as','').replace('from','')#一般情况下,可以直接剔除除了库名以外的所有信息
            thismodule=thismodule.split('.')[0]#如果代码只调用了里面的某一部分,则获取最顶层的名称
            dprint('检测到于第 '+str(i)+' 行导入的库:'+thismodule)
            modules.append(thismodule)#存储依赖名称
            #但愿这个if语句里面没问题
    #去重(副作用:重排)
    modules=list(set(modules))
    #完成
    print('分析完成!请继续操作...')
    print('==================================================')
    #多选窗口这块我直接照搬了WordLST
    dwin=tk.Toplevel()
    dwin.title('选择欲安装的依赖 - EasyPyPI')
    dwin.transient(win)
    tk.Label(dwin,text='请选择欲安装的依赖,然后点击“开始安装”',anchor='w').pack(fill=tk.X,padx=20)
    tk.Label(dwin,text='默认不会以管理员身份安装,若个别库安装时提示权限不足,请单独安装',anchor='w',fg='#707070').pack(fill=tk.X,padx=20)
    tk.Label(dwin,text='可能会识别到并显示自带的库,此BUG已知且暂不打算修复,请谅解',anchor='w',fg='#707070').pack(fill=tk.X,padx=20)
    dlst=tk.Listbox(dwin,width=20,bd=0,highlightthickness=0,activestyle='none',selectmode='multiple',height=20)
    dlst.pack(fill=tk.BOTH,padx=20,pady=15)
    ttk.Button(dwin,text='开始安装',command=lambda:start_inst_from_lst(modules,dlst.curselection(),dwin)).pack(fill=tk.X,expand=True)
    for i in modules:
        dlst.insert(tk.END,i)

dprint('您传入了参数:'+str(sys.argv))

init()

dprint('执行:     '+pip_path+' install '+'(库名)'+' -i https://pypi.douban.com/simple')
dprint('==================================================')

try:
    from tkwebview2.tkwebview2 import WebView2
except ModuleNotFoundError:
    print('将为您安装必须的库:')
    install('tkwebview2')
    print('==================================================')

win=tk.Tk()
win.title('Easy PyPI')
win.geometry('300x390')
win.resizable(0,0)
win.update()


name_enter=ttk.Entry(win)
name_enter.pack(fill=tk.X)

#功能区
ttk.Button(win,text='安装',command=lambda:start(install,name_enter.get())).pack(fill=tk.X)
ttk.Button(win,text='以管理员身份安装',command=lambda:start(install,name_enter.get()+' --user')).pack(fill=tk.X)
ttk.Button(win,text='卸载',command=lambda:start(uninstall,name_enter.get())).pack(fill=tk.X)
ttk.Button(win,text='根据Python源码安装依赖',command=inst_from_py).pack(fill=tk.X)
ttk.Button(win,text='关于此库',command=lambda:view("https://pypi.org/project/"+name_enter.get()+"/")).pack(fill=tk.X)
ttk.Button(win,text='列出所有已经安装的库',command=lambda:start(list_pkg)).pack(fill=tk.X)
ttk.Button(win,text='更新PIP',command=lambda:start(upgrade)).pack(fill=tk.X)
ttk.Button(win,text='关于PIP',command=lambda:start(about)).pack(fill=tk.X)
ttk.Button(win,text='查看环境变量中有关PIP路径的配置',command=lambda:start(locate_pip)).pack(fill=tk.X)
sdo_btn=ttk.Button(win,text='显示调试选项  v',command=showDebug)
sdo_btn.pack(fill=tk.X)

#介绍区被删去,因为它被CHM所替代

tk.Button(win,text='2022 By 人工智障',bg='lightgrey',bd=0,command=lambda:view("http://rgzz.great-site.net/?i=1")).pack(fill=tk.X)
tk.Button(win,text='问题反馈',bg='lightgrey',bd=0,command=lambda:view("https://support.qq.com/products/384388?")).pack(fill=tk.X)
tk.Button(win,text='帮助(更新不及时)',bg='lightgrey',bd=0,command=lambda:view("http://rgzz.great-site.net/soft/ezpip/WebHelp/")).pack(fill=tk.X)
tk.Button(win,text='开源许可证',bg='lightgrey',bd=0,command=lambda:view("https://www.mozilla.org/en-US/MPL/1.1/")).pack(fill=tk.X)


#调试选项
ttk.Button(win,text='显示输入的内容',command=lambda:print(name_enter.get()+'\n'+'==================================================')).pack(fill=tk.X)
ttk.Button(win,text='使用内建网页查看器打开输入的网址',command=lambda:view(name_enter.get())).pack(fill=tk.X)

sdi_btn=ttk.Button(win,text='显示调试信息',command=lambda:showDebug(show_info=True))
sdi_btn.pack(fill=tk.X)

egg_btn=ttk.Button(win,text='要相信彩蛋会永远陪着你,好吗?:)',state='disabled')
egg_btn.pack(fill=tk.X)


win.mainloop()
上一篇:Spring知识点详解
下一篇:没有了
网友评论