|
import requests |
|
from requests.adapters import HTTPAdapter, Retry |
|
from datetime import datetime, timedelta |
|
|
|
from rich.table import Table |
|
from rich.console import Console |
|
|
|
console = Console() |
|
|
|
table = Table(title="VSCode Extensions") |
|
|
|
|
|
def get_vscode_extensions( |
|
id, |
|
max_page=10000, |
|
page_size=100, |
|
include_versions=True, |
|
include_files=True, |
|
include_category_and_tags=True, |
|
include_shared_accounts=True, |
|
include_version_properties=True, |
|
exclude_non_validated=False, |
|
include_installation_targets=True, |
|
include_asset_uri=True, |
|
include_statistics=True, |
|
include_latest_version_only=False, |
|
unpublished=False, |
|
include_name_conflict_info=True, |
|
api_version="7.2-preview.1", |
|
session=None, |
|
): |
|
if not session: |
|
session = requests.session() |
|
|
|
headers = {"Accept": f"application/json; charset=utf-8; api-version={api_version}"} |
|
|
|
flags = 0 |
|
if include_versions: |
|
flags |= 0x1 |
|
|
|
if include_files: |
|
flags |= 0x2 |
|
|
|
if include_category_and_tags: |
|
flags |= 0x4 |
|
|
|
if include_shared_accounts: |
|
flags |= 0x8 |
|
|
|
if include_shared_accounts: |
|
flags |= 0x8 |
|
|
|
if include_version_properties: |
|
flags |= 0x10 |
|
|
|
if exclude_non_validated: |
|
flags |= 0x20 |
|
|
|
if include_installation_targets: |
|
flags |= 0x40 |
|
|
|
if include_asset_uri: |
|
flags |= 0x80 |
|
|
|
if include_statistics: |
|
flags |= 0x100 |
|
|
|
if include_latest_version_only: |
|
flags |= 0x200 |
|
|
|
if unpublished: |
|
flags |= 0x1000 |
|
|
|
if include_name_conflict_info: |
|
flags |= 0x8000 |
|
|
|
for page in range(1, max_page + 1): |
|
body = { |
|
"filters": [ |
|
{ |
|
"criteria": [{"filterType": 7, "value": id}], |
|
"pageNumber": page, |
|
"pageSize": page_size, |
|
"sortBy": 0, |
|
"sortOrder": 0, |
|
} |
|
], |
|
"assetTypes": [], |
|
"flags": flags, |
|
} |
|
|
|
r = session.post( |
|
"https://marketplace.visualstudio.com/_apis/public/gallery/extensionquery", |
|
json=body, |
|
headers=headers, |
|
) |
|
r.raise_for_status() |
|
response = r.json() |
|
|
|
extensions = response["results"][0]["extensions"] |
|
for extension in extensions: |
|
yield extension |
|
|
|
if len(extensions) != page_size: |
|
break |
|
|
|
|
|
def main(): |
|
retry_strategy = Retry( |
|
total=3, |
|
backoff_factor=1, |
|
status_forcelist=[429, 500, 502, 503, 504], |
|
allowed_methods=["HEAD", "GET", "OPTIONS"], |
|
) |
|
adapter = HTTPAdapter(max_retries=retry_strategy) |
|
session = requests.Session() |
|
session.mount("https://", adapter) |
|
session.mount("http://", adapter) |
|
|
|
details = [] |
|
categories = {} |
|
used = set() |
|
|
|
table.add_column("Name", style="cyan", no_wrap=True) |
|
table.add_column("Version") |
|
table.add_column("Last Update") |
|
table.add_column("Install Count", justify="right") |
|
table.add_column("Description") |
|
|
|
for id in open("vscode-extensions.txt").readlines(): |
|
for extension in get_vscode_extensions(id.strip(), session=session): |
|
extension_name = extension["extensionName"] |
|
extension_description = extension.get("shortDescription", "") |
|
extensions_versions = extension["versions"] |
|
extension_last_update = extension["lastUpdated"] |
|
last_update_dt = datetime.strptime( |
|
extension_last_update, "%Y-%m-%dT%H:%M:%S.%fZ" |
|
) |
|
last_update = last_update_dt.strftime("%Y-%m-%d") |
|
extension_categories = extension["categories"] |
|
|
|
extensions_statistics = dict( |
|
{ |
|
(item["statisticName"], item["value"]) |
|
for item in extension["statistics"] |
|
} |
|
) |
|
extension_version_info = extensions_versions.pop(0) |
|
extension_version = extension_version_info["version"] |
|
|
|
table.add_row( |
|
extension_name, |
|
extension_version, |
|
last_update, |
|
str(round(extensions_statistics.get("install", 0))), |
|
extension_description, |
|
) |
|
info = f"{id.strip():50} {last_update:10} {str(round(extensions_statistics.get("install", 0))):>12} {extension_description}" |
|
|
|
for cat in extension_categories: |
|
if info in used: |
|
continue |
|
used.add(cat) |
|
categories.setdefault(cat, []).append(info) |
|
|
|
details.append(info) |
|
break |
|
|
|
console.print(table) |
|
|
|
with open("vscode-extensions-with-desc.txt", "w") as f: |
|
f.write("\n".join(details)) |
|
|
|
with open("vscode-extensions-categories.txt", "w") as f: |
|
for cat, extensions in sorted(categories.items()): |
|
f.write(f"{cat}\n") |
|
f.write("\n".join(extensions)) |
|
f.write("\n\n---\n\n") |
|
|
|
|
|
if __name__ == "__main__": |
|
main() |