Skip to content

Commit def30cf

Browse files
committed
add creating the badge link from the weekly workflow
1 parent 19dfd30 commit def30cf

File tree

4 files changed

+92
-10
lines changed

4 files changed

+92
-10
lines changed

.github/workflows/weekly-badge-and-stats-update.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ jobs:
2525
pip install -r requirements.txt
2626
2727
- name: Update badges
28-
run: python manager.py members update_badges
28+
env:
29+
BITLY_TOKEN: ${{ secrets.BITLY_TOKEN }}
30+
run: |
31+
python manager.py members update_badges
32+
python manager.py members update_badge_list
2933
3034
- name: Update stats
3135
run: python manager.py members update_github

ecosystem/cli/members.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,49 @@ def update_badges(self):
9494
) as outfile:
9595
json.dump(data, outfile, indent=4)
9696
self.logger.info("Badge for %s has been updated.", project.name)
97+
project.update_badge()
98+
self.dao.update(project.name_id, badge=project.badge)
99+
100+
def update_badge_list(self):
101+
"""Updates badge list in qisk.it/ecosystem-badges."""
102+
start_tag = "<!-- start:table-badge -->"
103+
end_tag = "<!-- end:table-badge -->"
104+
105+
projects = []
106+
for project in self.dao.get_all():
107+
if project.badge is None:
108+
continue
109+
projects.append((project.name, project.badge, project.badge_md))
110+
111+
projects.sort(key=lambda x: x[0].casefold())
112+
113+
lines = [
114+
"",
115+
"<table>",
116+
'<tr><th width="10%">Member</th><th width="60%">Badge</th><th>MD Code</th></tr>',
117+
]
118+
for name, badge, badge_md in projects:
119+
lines.append(
120+
"<tr>"
121+
f"<td>{name}</td>"
122+
f'<td><img src="{badge}" /></td>'
123+
f'<td><pre class="notranslate"><code>{badge_md}</code> &nbsp; </pre></td>'
124+
"</tr>"
125+
)
126+
lines.append("</table>\n")
127+
readme_md = os.path.join(self.current_dir, "badges", "README.md")
128+
129+
with open(readme_md, "r") as readme_file:
130+
content = readme_file.read()
131+
132+
to_replace = content[
133+
content.find(start_tag) + len(start_tag) : content.rfind(end_tag)
134+
]
135+
136+
new_content = content.replace(to_replace, "\n".join(lines))
137+
138+
with open(readme_md, "w") as outfile:
139+
outfile.write(new_content)
97140

98141
def update_github(self):
99142
"""Updates GitHub data."""

ecosystem/member.py

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from .serializable import JsonSerializable, parse_datetime
88
from .github import GitHubData
99
from .pypi import PyPIData
10-
from .request import URL
10+
from .request import URL, request_json
1111

1212

1313
class Member(JsonSerializable): # pylint: disable=too-many-instance-attributes
@@ -32,6 +32,7 @@ def __init__( # pylint: disable=too-many-arguments, too-many-locals
3232
documentation: URL | None = None,
3333
packages: list[URL] | None = None,
3434
uuid: str | None = None,
35+
badge: str | None = None,
3536
github: GitHubData | None = None,
3637
pypi: dict[str, PyPIData] | None = None,
3738
julia: JuliaData | None = None,
@@ -56,6 +57,7 @@ def __init__( # pylint: disable=too-many-arguments, too-many-locals
5657
self.github = github
5758
self.pypi = pypi
5859
self.julia = julia
60+
self.badge = badge
5961

6062
self.__dict__.setdefault("created_at", parse_datetime("now"))
6163
self.__dict__.setdefault("updated_at", parse_datetime("now"))
@@ -100,7 +102,6 @@ def to_dict(self) -> dict:
100102
base_dict = super().to_dict()
101103
if "ibm_maintained" in base_dict and base_dict["ibm_maintained"] is False:
102104
del base_dict["ibm_maintained"]
103-
base_dict["badge"] = self.badge
104105
return base_dict
105106

106107
def __eq__(self, other: "Member"):
@@ -127,12 +128,12 @@ def name_id(self):
127128
return repo_dir.lower().replace(".", "_")
128129

129130
@property
130-
def badge(self):
131+
def badge_md(self):
131132
"""Markdown with the badge for README"""
132133
return (
133-
"[![Qiskit Ecosystem](https://img.shields.io/endpoint?"
134-
"style=flat&url=https%3A%2F%2Fqiskit.github.io%2Fecosystem%"
135-
f"2Fb%2F{self.short_uuid})](https://qisk.it/e)"
134+
f"[![Qiskit Ecosystem]({self.badge})](https://qisk.it/e)"
135+
if self.badge
136+
else None
136137
)
137138

138139
def update_github(self):
@@ -142,6 +143,24 @@ def update_github(self):
142143
self.github.update_json()
143144
self.github.update_owner_repo()
144145

146+
def _create_qisk_dot_it_link_for_badge(self):
147+
data = {
148+
"long_url": "https://img.shields.io/endpoint?style=flat&url="
149+
f"https://qiskit.github.io/ecosystem/b/{self.short_uuid}",
150+
"domain": "qisk.it",
151+
"keyword": f"e-{self.short_uuid}",
152+
"group_guid": "Bj9rgMHKfxH",
153+
"title": f'Qiskit ecosystem "{self.name}" badge',
154+
"tags": ["qiskit ecosystem badge", "permanent _do NOT remove_"],
155+
}
156+
response = request_json("https://api-ssl.bitly.com/v4/bitlinks", post=data)
157+
return response["link"]
158+
159+
def update_badge(self):
160+
"""If not there yet, creates a new Bitly link for the badge"""
161+
if self.badge is None:
162+
self.badge = self._create_qisk_dot_it_link_for_badge()
163+
145164
def update_pypi(self):
146165
"""
147166
Updates all the PyPI information in the project.

ecosystem/request.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,16 @@
2020

2121

2222
def request_json(
23-
url: str, headers: dict[str, str] = None, parser=None, content_handler=None
23+
url: str,
24+
headers: dict[str, str] = None,
25+
post=None,
26+
parser=None,
27+
content_handler=None,
2428
):
25-
"""Requests the JSON in <url> with <headers>"""
29+
"""Requests the JSON in <url> with <headers>
30+
31+
if post is set with a dictionary, then that dict is sent as POST's JSON
32+
"""
2633
if parser is None:
2734
parser = json.loads
2835
url = URL(url)
@@ -41,7 +48,16 @@ def request_json(
4148
headers["Authorization"] = "token " + token
4249
headers["User-Agent"] = "github.com/Qiskit/ecosystem/"
4350

44-
response = requests.get(str(url), headers=headers, timeout=240)
51+
if url.hostname.endswith("bitly.com"):
52+
token = os.getenv("BITLY_TOKEN")
53+
if token:
54+
headers["Authorization"] = "Bearer " + token
55+
56+
if post is None:
57+
response = requests.get(str(url), headers=headers, timeout=240)
58+
else:
59+
response = requests.post(str(url), headers=headers, timeout=240, json=post)
60+
4561
if not response.ok:
4662
raise EcosystemError(
4763
f"Bad response {str(url)}: {response.reason} ({response.status_code})"

0 commit comments

Comments
 (0)