-
Notifications
You must be signed in to change notification settings - Fork 832
/
pip_manager.py
160 lines (128 loc) · 4.51 KB
/
pip_manager.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import sys
import pkg_resources
import importlib
from requests import Session
from bs4 import BeautifulSoup
from jadi import component
from aj.plugins.packages.api import PackageManager, Package
@component(PackageManager)
class PIPPackageManager(PackageManager):
"""
Manager to handle pip packages.
"""
id = 'pip'
name = 'PIP'
def __init__(self, context):
PackageManager.__init__(self, context)
def __make_package_pipdist(self, dist):
"""
Convert pip package object in package object.
:param apt_package: Pip package object from apt module
:type apt_package: Pip package object from apt module
:return: Package object
:rtype: Package object
"""
p = Package(self)
p.id = f'{dist.key}=={dist.version}'
p.name = dist.key
p.version = dist.version
p.description = None
p.is_installed = True
p.installed_version = dist.version
return p
def __make_package(self, dist):
"""
Convert pip package object in package object.
:param apt_package: Pip package object from apt module
:type apt_package: Pip package object from apt module
:return: Package object
:rtype: Package object
"""
p = Package(self)
p.id = f'{dist["name"]}=={dist["version"]}'
p.name = dist['name']
p.version = dist['version']
p.description = dist['summary']
p.created = dist['created']
importlib.reload(pkg_resources)
for d in pkg_resources.working_set:
if d.key == p.name:
p.is_installed = True
p.installed_version = d.version
p.is_upgradeable = p.installed_version != p.version
return p
def __requests_pypi_search(self, query):
"""
Launch a query on pypi search and filter the results with bs4.
Heavily inspired from https://github.com/victorgarric/pip_search/blob/master/pip_search/pip_search.py
:param query: string to search for
:type query: string
:return:
:rtype:
"""
api_url = 'https://pypi.org/search/'
session = Session()
packages = []
snippets = []
for page in range(1,3):
params = {'q': query, 'page': page}
result = session.get(api_url, params=params)
soup = BeautifulSoup(result.text, 'html.parser')
snippets += soup.select('a[class*="snippet"]')
for snippet in snippets:
package = {}
for value in ["name", "version", "created"]:
package[value] = snippet.select_one(f'span[class*="{value}"]').text.strip()
package['summary'] = snippet.select_one(f'p[class*="description"]').text.strip()
packages.append(package)
return packages
def list(self, query=None):
"""
Generator for all packages.
:param query: Search string
:type query: string
:return: Package object
:rtype:Package object
"""
for dist in self.__requests_pypi_search(query):
yield self.__make_package(dist)
def get_package(self, _id):
"""
Get package informations.
:param _id: Package name
:type _id: string
:return: Package object
:rtype: Package object
"""
for d in pkg_resources.working_set:
if d.key == _id.split('==')[0]:
return self.__make_package_pipdist(d)
def update_lists(self, progress_callback):
"""
Refresh list of packages.
:param progress_callback: Callback function to follow progress
:type progress_callback: function
"""
pass
def get_apply_cmd(self, selection):
"""
Prepare command to apply.
:param selection: Dict of packages an actions
:type selection: dict
:return: Command for terminal use
:rtype: string
"""
packages = []
cmd = ''
for sel in selection:
if sel['operation'] in ['install', 'upgrade']:
packages.append(sel['package']['id'])
if packages:
cmd = f'{sys.executable} -m pip install {" ".join(packages)} ;'
packages = []
for sel in selection:
if sel['operation'] in ['remove']:
packages.append(sel['package']['name'])
if packages:
cmd = f'{sys.executable} -m pip uninstall {" ".join(packages)}'
return cmd