-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updates thanks to focus on project and a projects funding links (#20)
- Loading branch information
Showing
3 changed files
with
90 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,12 @@ | ||
{ | ||
"amoffat": "http://formconstantdance.org/donate", | ||
"brosner": "https://earn.com/brosner/", | ||
"django": "https://www.djangoproject.com/fundraising/", | ||
"freakboy3742": "https://pybee.org/contributing/membership/", | ||
"jezdez": "https://www.paypal.me/jezdez", | ||
"kennethreitz": "https://paypal.me/kennethreitz42", | ||
"lamby": "https://www.paypal.me/lambyuk", | ||
"nedbatchelder": "https://www.paypal.me/nedbat", | ||
"phildini": "https://patreon.com/phildini", | ||
"singingwolfboy": "https://earn.com/singingwolfboy/", | ||
"untitaker": "https://www.paypal.me/untitaker" | ||
"coverage": { | ||
"url": "https://www.paypal.me/nedbat", | ||
"authors": ["Ned Batchelder"] | ||
}, | ||
"django": {"url": "https://www.djangoproject.com/fundraising/"}, | ||
"virtualenv": {"url": "https://www.paypal.me/untitaker"}, | ||
"thanks": { | ||
"url": "https://patreon.com/phildini", | ||
"authors": ["Philip James", "Tom Marks"] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,82 +1,97 @@ | ||
# -*- coding: utf-8 -*- | ||
|
||
from collections import namedtuple | ||
from humanfriendly.tables import format_pretty_table | ||
import json | ||
import os | ||
try: | ||
import pip._internal as pip | ||
except ImportError: | ||
import pip | ||
import requirements | ||
import requests | ||
from termcolor import colored, cprint | ||
try: | ||
import xmlrpclib | ||
except ImportError: | ||
import xmlrpc.client as xmlrpclib | ||
|
||
|
||
json_file = ("{}/thanks.json".format(os.path.dirname(os.path.realpath(__file__)))) | ||
client = xmlrpclib.ServerProxy('https://pypi.python.org/pypi') | ||
JSON_FILE = ("{}/thanks.json".format(os.path.dirname(os.path.realpath(__file__)))) | ||
|
||
ProjectData = namedtuple('ProjectData', ['name', 'funding_link', 'authors']) | ||
|
||
|
||
class Thanks(): | ||
def __init__(self, debug=False): | ||
self.debug = debug | ||
self.data = {} | ||
with open(json_file, 'r') as j: | ||
print('Loading data about {}'.format(colored('contributors...', 'cyan'))) | ||
self.data = json.load(j) | ||
self.data = self.load_local_project_data() | ||
self.give_thanks_to = {} | ||
self.local_installs = {} | ||
for package in pip.get_installed_distributions(): | ||
self.local_installs[package.key] = package | ||
|
||
def find_package_roles(self, requirements_file): | ||
with open(requirements_file, 'r') as reqs: | ||
print('Scanning your {} file...'.format(colored('requirements', 'red'))) | ||
for req in requirements.parse(reqs): | ||
self.update_give_thanks(req.name) | ||
if req.name in self.local_installs: | ||
for package in self.local_installs[req.name].requires(): | ||
self.update_give_thanks(package.key) | ||
if self.give_thanks_to: | ||
cprint( | ||
'You depend on {} who would {}'.format( | ||
colored('{} authors'.format(len(self.give_thanks_to)), 'cyan'), | ||
colored('enjoy donations!', 'green'), | ||
), attrs=['bold']) | ||
table_data = [] | ||
for contributor in self.give_thanks_to: | ||
table_data.append( | ||
[ | ||
colored(contributor, 'cyan'), | ||
colored(self.give_thanks_to[contributor]['url'], 'green'), | ||
colored(", ".join(set(self.give_thanks_to[contributor]['packages'])), 'red'), | ||
] | ||
) | ||
print(format_pretty_table( | ||
data=table_data, | ||
column_names=['Author', 'Where to thank', 'Packages'], | ||
horizontal_bar=' ', | ||
vertical_bar=' ', | ||
)) | ||
def load_local_project_data(self): | ||
print('Loading data about {}'.format(colored('contributors...', 'cyan'))) | ||
with open(JSON_FILE, 'r') as fh: | ||
data = json.load(fh) | ||
for project_name in data.keys(): | ||
authors = ', '.join(data[project_name].get('authors', [])) | ||
data[project_name]['authors'] = authors | ||
return data | ||
|
||
def find_project_details(self, requirements_list): | ||
print('Scanning your {} file...'.format(colored('requirements', 'red'))) | ||
reqs = [ | ||
next(requirements.parse(r)) | ||
for r in requirements_list | ||
] | ||
for req in reqs: | ||
self.update_give_thanks(req.name) | ||
self._display_thanks() | ||
|
||
def _display_thanks(self): | ||
if self.give_thanks_to: | ||
cprint( | ||
'You depend on {} who would {}'.format( | ||
colored('{} authors'.format(len(self.give_thanks_to)), 'cyan'), | ||
colored('enjoy donations!', 'green'), | ||
), attrs=['bold']) | ||
colorized_data = [ | ||
ProjectData( | ||
name=colored(pd.name, 'cyan'), | ||
funding_link=colored(pd.funding_link, 'green'), | ||
authors=colored(pd.authors, 'yellow'), | ||
) | ||
for pd in self.give_thanks_to.values() | ||
] | ||
|
||
print(format_pretty_table( | ||
data=colorized_data, | ||
column_names=['Project', 'Where to thank', 'Authors'], | ||
horizontal_bar=' ', | ||
vertical_bar=' ', | ||
)) | ||
|
||
def get_local_data(self, project_name): | ||
if project_name in self.data: | ||
data = ProjectData( | ||
name=project_name, | ||
funding_link=self.data[project_name]['url'], | ||
authors=self.data[project_name]['authors'] | ||
) | ||
else: | ||
data = None | ||
return data | ||
|
||
def get_remote_data(self, project_name): | ||
url_format = 'https://pypi.org/pypi/{}/json'.format | ||
try: | ||
resp = requests.get(url_format(project_name)) | ||
project_data = resp.json() | ||
data = ProjectData( | ||
name=project_name, | ||
funding_link=project_data['info'].get('funding_url', ''), | ||
authors=project_data['info'].get('author', '') | ||
) | ||
except requests.exceptions.ConnectionError: | ||
data = None | ||
except json.decoder.JSONDecodeError: | ||
data = None | ||
return data | ||
|
||
def update_give_thanks(self, package_name): | ||
if self.debug: | ||
print('Checking ', package_name) | ||
try: | ||
roles = client.package_roles(package_name) | ||
role_names = set(role[1] for role in roles) | ||
if self.debug: | ||
print('Checking role names: ', role_names) | ||
for name in role_names: | ||
if name in self.give_thanks_to: | ||
self.give_thanks_to[name]['packages'].append(package_name) | ||
else: | ||
if name in self.data: | ||
self.give_thanks_to[name] = { | ||
'url': self.data[name], | ||
'packages': [package_name], | ||
} | ||
except TypeError: | ||
pass | ||
package_data = self.get_local_data(package_name) or self.get_remote_data(package_name) | ||
if package_data: | ||
self.give_thanks_to[package_name] = package_data |