From 3ec57454ed022b856ce37d7cb51127d6174bec18 Mon Sep 17 00:00:00 2001 From: vsedov Date: Sat, 9 Mar 2024 18:59:01 +0000 Subject: [PATCH] Feat: Auto readme update with recent stats --- .github/workflows/update.yml | 3 + README.md | 11 +++ db_checker.py | 165 +++++++++++++++++++++++++---------- test.py | 25 ++---- 4 files changed, 138 insertions(+), 66 deletions(-) diff --git a/.github/workflows/update.yml b/.github/workflows/update.yml index a3708786..40ec35d1 100644 --- a/.github/workflows/update.yml +++ b/.github/workflows/update.yml @@ -46,6 +46,7 @@ jobs: - name: Run pythonAuto run: | poetry run python generate_database.py + poetry run python db_checker.py - name: Commit database changes run: | @@ -54,6 +55,8 @@ jobs: if [[ ! -z $(git status -s) ]]; then git add database.json git commit -m "chore: update plugins database" + git add README.md + git commit -m "chore: update readme stats" git add dotfiles.json git commit -m "chore: update dotfiles database" fi diff --git a/README.md b/README.md index 425369d6..6d0f1759 100644 --- a/README.md +++ b/README.md @@ -30,3 +30,14 @@ poetry init -> poetry install -> poetry run python ... # Key Notes Remember, Robert's doing his best out here in the wilds of GitHub. Treat him well, and he'll treat you to the finest collection of Neovim treasures the internet has to offer. 🎩🔍 + + +# Database Information + +

Top 10 Plugins by Stars

PluginStars
telescope.nvim13298
lazy.nvim10586
nvim-lspconfig9167
packer.nvim7499
nvim-cmp6787
mason.nvim6422
nvim-tree.lua6290
neorg5473
harpoon5155
lualine.nvim5096

Top 10 Plugins by Issues

PluginIssues
telescope.nvim312
packer.nvim305
nvim-cmp223
lualine.nvim187
which-key.nvim183
neo-tree.nvim172
neorg153
mason.nvim137
trouble.nvim130
rust-tools.nvim121

Top 10 Plugins by Forks

PluginForks
nvim-lspconfig1978
null-ls.nvim802
telescope.nvim748
nvim-tree.lua589
lualine.nvim431
nvim-cmp339
tokyonight.nvim321
harpoon312
lspsaga.nvim273
ChatGPT.nvim264
+ +### Final Stats +- Total Plugins: 2425 +- Lua Plugins: 2425 +- Proportion of Lua Plugins (%): 100.00 +- Average Activity Score: 199.43 diff --git a/db_checker.py b/db_checker.py index 12fb51f6..06081f0d 100644 --- a/db_checker.py +++ b/db_checker.py @@ -5,6 +5,7 @@ from rich.console import Console from rich.table import Table + class DatabaseAnalyzer: def __init__(self, database_path='database.json', lengthA=10, lengthB=10): @@ -37,8 +38,8 @@ def simplify_language_distribution(self): # Use get to safely access the count for each language, defaulting to 0 if not found # This approach avoids KeyError for languages not present in language_counts self.plugins_df['simplified_language'] = self.plugins_df[ - 'language'].apply( - lambda x: x if language_counts.get(x, 0) > 1 else 'Other') + 'language'].apply(lambda x: x + if language_counts.get(x, 0) > 1 else 'Other') def calculate_statistics(self): stats_df = self.plugins_df[[ @@ -61,26 +62,27 @@ def get_topics_distribution(self): return topics_series.head(self.lengthB) # Only the top 5 topics def print_summary(self): - self.console.print( - f"Total plugins: {len(self.plugins_df)}", style="bold green") - - stats_df = self.calculate_statistics() - self.console.print("\nStatistical Summary:", style="bold underline") - self.print_table(stats_df, ['Metric', 'Mean', 'Standard Deviation']) - - lang_dist = self.get_language_distribution() - self.console.print("\nLanguage distribution:", style="bold underline") - self.print_table(lang_dist, ['Language', 'Count']) - - avg_activity_score_by_lang = self.get_average_activity_score_by_language( - ) - self.console.print( - "\nAverage Activity Score by Language:", style="bold underline") - self.print_table( - avg_activity_score_by_lang, ['Language', 'Average Activity Score']) + # self.console.print( + # f"Total plugins: {len(self.plugins_df)}", style="bold green") + # + # stats_df = self.calculate_statistics() + # self.console.print("\nStatistical Summary:", style="bold underline") + # self.print_table(stats_df, ['Metric', 'Mean', 'Standard Deviation']) + # + # lang_dist = self.get_language_distribution() + # self.console.print("\nLanguage distribution:", style="bold underline") + # self.print_table(lang_dist, ['Language', 'Count']) + + # avg_activity_score_by_lang = self.get_average_activity_score_by_language( + # ) + # self.console.print("\nAverage Activity Score by Language:", + # style="bold underline") + # self.print_table(avg_activity_score_by_lang, + # ['Language', 'Average Activity Score']) topics_distribution = self.get_topics_distribution() - self.console.print("\nTop Topics distribution:", style="bold underline") + self.console.print("\nTop Topics distribution:", + style="bold underline") self.print_table(topics_distribution, ['Topic', 'Count']) def print_table(self, data, columns): @@ -104,9 +106,8 @@ def print_top_plugins(self): } for category, column_name in categories.items(): - self.console.print( - f"\nTop {self.lengthA} Plugins by {category}:", - style="bold underline magenta") + self.console.print(f"\nTop {self.lengthA} Plugins by {category}:", + style="bold underline magenta") top_plugins = self.plugins_df.nlargest(self.lengthA, column_name)[[column_name]] @@ -120,40 +121,110 @@ def print_top_plugins(self): self.console.print(table) total_plugins = len(self.plugins_df) - lua_plugins = len(self.plugins_df[self.plugins_df['language'] == 'Lua']) - proportion_lua = (lua_plugins/total_plugins) * 100 + lua_plugins = len( + self.plugins_df[self.plugins_df['language'] == 'Lua']) + proportion_lua = (lua_plugins / total_plugins) * 100 average_activity_score = self.plugins_df['activity_score'].mean() table = Table(show_header=True, header_style="bold magenta") table.add_column("Total Plugins", style="dim", justify="right") table.add_column("Lua Plugins", style="dim", justify="right") - table.add_column( - "Proportion of Lua Plugins (%)", style="dim", justify="right") - table.add_column("Average Activity Score", style="dim", justify="right") + table.add_column("Proportion of Lua Plugins (%)", + style="dim", + justify="right") + table.add_column("Average Activity Score", + style="dim", + justify="right") - table.add_row( - str(total_plugins), str(lua_plugins), f"{proportion_lua:.2f}", - f"{average_activity_score:.2f}") + table.add_row(str(total_plugins), str(lua_plugins), + f"{proportion_lua:.2f}", f"{average_activity_score:.2f}") self.console.print(table) + def generate_markdown_table(self, data, columns): + markdown_table = "| " + " | ".join(columns) + " |\n" + markdown_table += "| " + " | ".join(['---'] * len(columns)) + " |\n" + if isinstance(data, pd.Series): + for index, value in data.items(): + markdown_table += "| " + " | ".join([str(index), + str(value)]) + " |\n" + else: + for index, row in data.iterrows(): + markdown_table += "| " + index + " | " + f"{row['mean']:.2f}" + " | " + f"{row['std']:.2f}" + " |\n" + return markdown_table + + def save_to_markdown(self): + new_content = "" + categories = { + "Stars": "stargazers_count", + "Issues": "open_issues_count", + "Forks": "forks_count" + } + + # Generate HTML for the top plugins in each category + plugins_html = self.generate_html_for_plugins(categories) + new_content += "
" + plugins_html + "
\n\n" + + # Final stats in Markdown + total_plugins = len(self.plugins_df) + lua_plugins = len( + self.plugins_df[self.plugins_df['language'] == 'Lua']) + proportion_lua = (lua_plugins / total_plugins) * 100 + average_activity_score = self.plugins_df['activity_score'].mean() + new_content += "### Final Stats\n" + new_content += f"- Total Plugins: {total_plugins}\n" + new_content += f"- Lua Plugins: {lua_plugins}\n" + new_content += f"- Proportion of Lua Plugins (%): {proportion_lua:.2f}\n" + new_content += f"- Average Activity Score: {average_activity_score:.2f}\n" + + # Read and split the existing README + try: + with open("README.md", "r+") as md_file: + content = md_file.read() + parts = content.split("# Database Information", 1) + updated_content = parts[ + 0] + "# Database Information\n\n" + new_content + md_file.seek(0) + md_file.write(updated_content) + md_file.truncate() + except FileNotFoundError: + with open("README.md", "w") as md_file: + md_file.write("# Database Information\n\n" + new_content) + + def generate_html_for_plugins(self, categories): + html_content = '' + for category, column_name in categories.items(): + top_plugins = self.plugins_df.nlargest(self.lengthA, + column_name)[[column_name]] + html_content += '' + html_content += '

Top 10 Plugins by ' + category + '

' + html_content += '' + for plugin_name, row in top_plugins.iterrows(): + html_content += '' + html_content += '
Plugin' + category + '
' + plugin_name + '' + str( + row[column_name]) + '
' + return html_content + + if __name__ == "__main__": parser = argparse.ArgumentParser(description='Check the database') - parser.add_argument( - '--db', - help='Path to the database file', - default='database.json', - type=str) - parser.add_argument( - "--lenA", help="Length of items you want to view", default=10, type=int) - parser.add_argument( - "--lenB", - help="Length of Topic Distribution you want to view", - default=15, - type=int) + parser.add_argument('--db', + help='Path to the database file', + default='database.json', + type=str) + parser.add_argument("--lenA", + help="Length of items you want to view", + default=10, + type=int) + parser.add_argument("--lenB", + help="Length of Topic Distribution you want to view", + default=10, + type=int) args = parser.parse_args() - analyzer = DatabaseAnalyzer( - database_path=args.db, lengthA=args.lenA, lengthB=args.lenB) - analyzer.print_summary() - analyzer.print_top_plugins() + analyzer = DatabaseAnalyzer(database_path=args.db, + lengthA=args.lenA, + lengthB=args.lenB) + # analyzer.print_summary() + # analyzer.print_top_plugins() + analyzer.save_to_markdown() diff --git a/test.py b/test.py index 298b6fe4..5ae91b32 100644 --- a/test.py +++ b/test.py @@ -527,12 +527,10 @@ def make_jobs(base) -> None: def name_function(x, y): return any(x.lower().startswith(ig.lower()) for ig in y) - - fixed_plugin_conds = [ - ] + fixed_plugin_conds = [] fixed_dotfile_conds = [ fullname_mapper( - lambda x, y: y.lower() in x.lower(),unwanted_config + lambda x, y: y.lower() in x.lower(), unwanted_config ), # checks if any of the unwanted config names are in d['full_name'] description_mapper( lambda x, @@ -541,30 +539,19 @@ def name_function(x, y): ), # check if any of the unwanted config names are in d['description'] ] both_conditions = [ - language_mapper( - lambda x, y: x.lower() == "lua", ["lua"] - ) + language_mapper(lambda x, y: x.lower() == "lua", ["lua"]) ] - optional_plugin_conds = [ - ends_nvim, - + optional_plugin_conds = [ends_nvim,] + optional_dotfile_conds = [begins_dot,] - ] - optional_dotfile_conds = [ - begins_dot, - ] - - conds = (fixed_plugin_conds,fixed_dotfile_conds) + conds = (fixed_plugin_conds, fixed_dotfile_conds) cases = { # mappings for conditions based on conditions (1, 0): "plugin_count", (0, 1): "dotfile_count", } - - - def make_jobtype(response): plugin_data = response # case = tuple(min(1, sum(cn(plugin_data) for cn in c)) for c in conds)