github-growth-plotter 0.1.0__tar.gz → 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: github-growth-plotter
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: A tool to fetch GitHub stargazers and plot growth over time.
5
5
  Author: Open Source Maintainers
6
6
  Classifier: Programming Language :: Python :: 3
@@ -28,10 +28,12 @@ Dynamic: summary
28
28
 
29
29
  <div align="center">
30
30
 
31
+ <a href="https://github.com/ishandutta2007/Awesome-Awesome-Awesome"><img src="https://img.shields.io/badge/Awesome-%E2%9C%94-blueviolet?style=flat-square&logo=github" alt="Awesome"/></a><a href="https://discord.gg/jc4xtF58Ve"><img src="https://img.shields.io/badge/Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white" alt="Discord" /></a>
31
32
  [![Python](https://img.shields.io/badge/Python-3.x-blue?style=for-the-badge&logo=python&logoColor=white)](https://python.org)
32
33
  [![GitHub CLI](https://img.shields.io/badge/GitHub%20CLI-Required-black?style=for-the-badge&logo=github&logoColor=white)](https://cli.github.com/)
33
34
  [![Matplotlib](https://img.shields.io/badge/Matplotlib-Supported-orange?style=for-the-badge)](https://matplotlib.org/)
34
35
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg?style=for-the-badge)](https://opensource.org/licenses/MIT)
36
+ <a href="https://github.com/ishandutta2007"><img alt="GitHub followers" src="https://img.shields.io/github/followers/ishandutta2007?label=Follow" /></a>
35
37
 
36
38
  </div>
37
39
 
@@ -83,9 +85,15 @@ github-growth-plot --publish
83
85
  ```
84
86
  This automatically appends the following HTML snippet to the bottom of your `README.md`:
85
87
  ```html
86
- <p align="center">
87
- <img src="./assets/<username>_<reponame>_growth.svg" alt="<owner>/<repo>" width="100%" />
88
- </p>
88
+ ## Star History
89
+
90
+ <a href="https://star-history.com/#<username>/<reponame>&Timeline" align="center">
91
+ <picture>
92
+ <source media="(prefers-color-scheme: dark)" srcset="assets/<username>_<reponame>_growth.svg">
93
+ <img alt="Star History Chart" src="assets/<username>_<reponame>_growth.svg">
94
+ </picture>
95
+ </a>
96
+
89
97
  ```
90
98
 
91
99
  ## 📂 Generated Files
@@ -95,6 +103,16 @@ When executed, the script generates and manages the following files:
95
103
  - 📄 **`<username>_<reponame>_stargazers.csv`**: Raw historical star data (automatically ignored via `.gitignore`).
96
104
  - 🙈 **`.gitignore`**: Updated automatically to ignore the generated CSV file.
97
105
 
106
+ ## Star History
107
+
108
+ <a href="https://star-history.com/#ishandutta2007/add-github-growth-plot&Timeline" align="center">
109
+ <picture>
110
+ <source media="(prefers-color-scheme: dark)" srcset="assets/ishandutta2007_add-github-growth-plot_growth.svg">
111
+ <img alt="Star History Chart" src="assets/ishandutta2007_add-github-growth-plot_growth.svg">
112
+ </picture>
113
+ </a>
114
+
115
+
98
116
  ---
99
117
  *Made with ❤️ for Open Source Maintainers.*
100
118
 
@@ -6,10 +6,12 @@
6
6
 
7
7
  <div align="center">
8
8
 
9
+ <a href="https://github.com/ishandutta2007/Awesome-Awesome-Awesome"><img src="https://img.shields.io/badge/Awesome-%E2%9C%94-blueviolet?style=flat-square&logo=github" alt="Awesome"/></a><a href="https://discord.gg/jc4xtF58Ve"><img src="https://img.shields.io/badge/Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white" alt="Discord" /></a>
9
10
  [![Python](https://img.shields.io/badge/Python-3.x-blue?style=for-the-badge&logo=python&logoColor=white)](https://python.org)
10
11
  [![GitHub CLI](https://img.shields.io/badge/GitHub%20CLI-Required-black?style=for-the-badge&logo=github&logoColor=white)](https://cli.github.com/)
11
12
  [![Matplotlib](https://img.shields.io/badge/Matplotlib-Supported-orange?style=for-the-badge)](https://matplotlib.org/)
12
13
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg?style=for-the-badge)](https://opensource.org/licenses/MIT)
14
+ <a href="https://github.com/ishandutta2007"><img alt="GitHub followers" src="https://img.shields.io/github/followers/ishandutta2007?label=Follow" /></a>
13
15
 
14
16
  </div>
15
17
 
@@ -61,9 +63,15 @@ github-growth-plot --publish
61
63
  ```
62
64
  This automatically appends the following HTML snippet to the bottom of your `README.md`:
63
65
  ```html
64
- <p align="center">
65
- <img src="./assets/<username>_<reponame>_growth.svg" alt="<owner>/<repo>" width="100%" />
66
- </p>
66
+ ## Star History
67
+
68
+ <a href="https://star-history.com/#<username>/<reponame>&Timeline" align="center">
69
+ <picture>
70
+ <source media="(prefers-color-scheme: dark)" srcset="assets/<username>_<reponame>_growth.svg">
71
+ <img alt="Star History Chart" src="assets/<username>_<reponame>_growth.svg">
72
+ </picture>
73
+ </a>
74
+
67
75
  ```
68
76
 
69
77
  ## 📂 Generated Files
@@ -73,6 +81,16 @@ When executed, the script generates and manages the following files:
73
81
  - 📄 **`<username>_<reponame>_stargazers.csv`**: Raw historical star data (automatically ignored via `.gitignore`).
74
82
  - 🙈 **`.gitignore`**: Updated automatically to ignore the generated CSV file.
75
83
 
84
+ ## Star History
85
+
86
+ <a href="https://star-history.com/#ishandutta2007/add-github-growth-plot&Timeline" align="center">
87
+ <picture>
88
+ <source media="(prefers-color-scheme: dark)" srcset="assets/ishandutta2007_add-github-growth-plot_growth.svg">
89
+ <img alt="Star History Chart" src="assets/ishandutta2007_add-github-growth-plot_growth.svg">
90
+ </picture>
91
+ </a>
92
+
93
+
76
94
  ---
77
95
  *Made with ❤️ for Open Source Maintainers.*
78
96
 
@@ -1,2 +1,2 @@
1
1
  # GitHub Growth Plotter
2
- __version__ = "0.1.0"
2
+ __version__ = "0.1.1"
@@ -4,9 +4,10 @@ import requests
4
4
  import csv
5
5
  import os
6
6
  import sys
7
- from datetime import datetime
7
+ from datetime import datetime, timedelta
8
8
  import matplotlib.pyplot as plt
9
9
  import matplotlib.dates as mdates
10
+ from matplotlib.ticker import MaxNLocator
10
11
 
11
12
  def get_github_token():
12
13
  try:
@@ -74,9 +75,12 @@ def fetch_stargazers(repo, token):
74
75
  break
75
76
 
76
77
  for item in data:
78
+ user = item["user"]["login"]
79
+ starred_at = item["starred_at"]
80
+ print(f" ⭐ Found star: {user} at {starred_at}")
77
81
  stargazers.append({
78
- "user": item["user"]["login"],
79
- "starred_at": item["starred_at"]
82
+ "user": user,
83
+ "starred_at": starred_at
80
84
  })
81
85
 
82
86
  if "next" not in response.links:
@@ -93,24 +97,97 @@ def save_to_csv(stargazers, filename):
93
97
  writer.writerow(stargazer)
94
98
  print(f"Saved {len(stargazers)} stargazers to {filename}")
95
99
 
100
+ def parse_date(date_str):
101
+ try:
102
+ return datetime.strptime(date_str, "%Y-%m-%dT%H:%M:%SZ")
103
+ except ValueError:
104
+ try:
105
+ return datetime.fromisoformat(date_str.replace('Z', '+00:00'))
106
+ except Exception:
107
+ return datetime.strptime(date_str[:19], "%Y-%m-%dT%H:%M:%S")
108
+
96
109
  def plot_growth(stargazers, filename, repo):
97
- dates = [datetime.strptime(s["starred_at"], "%Y-%m-%dT%H:%M:%SZ") for s in stargazers]
98
- dates.sort()
99
-
110
+ parsed = []
111
+ print(f"\n--- Stargazer Dates (Total: {len(stargazers)}) ---")
112
+ for s in stargazers:
113
+ d = parse_date(s["starred_at"])
114
+ parsed.append((d, s["user"], s["starred_at"]))
115
+ print(f"User: {s['user']} | Starred At: {s['starred_at']} -> Parsed: {d.strftime('%Y-%m-%d %H:%M:%S UTC')}")
116
+ print("--------------------------------------------------\n")
117
+
118
+ parsed.sort(key=lambda x: x[0])
119
+ dates = [p[0] for p in parsed]
100
120
  counts = list(range(1, len(dates) + 1))
101
121
 
122
+ # Extend plot to today's date so the curve reflects current star count up to today
123
+ now = datetime.now()
124
+ if dates and now > dates[-1]:
125
+ dates.append(now)
126
+ counts.append(counts[-1])
127
+
102
128
  plt.figure(figsize=(10, 6))
103
129
  plt.plot(dates, counts, marker='', linestyle='-', color='b')
104
130
 
105
- plt.title(f"Stargazers Growth for {repo}")
106
- plt.xlabel("Date")
107
- plt.ylabel("Number of Stargazers")
131
+ vintage_fonts = 'Georgia'
132
+ cursive_fonts = 'Segoe Script'
133
+
134
+ plt.title("Star history", fontfamily=vintage_fonts, fontsize=16)
135
+
136
+ time_span = dates[-1] - dates[0] if len(dates) > 1 else timedelta(0)
137
+ span_days = time_span.days
138
+ total_seconds = time_span.total_seconds()
139
+
140
+ if span_days >= 730: # 2+ years
141
+ interval = max(1, int(span_days / 365 / 6))
142
+ locator = mdates.YearLocator(base=interval)
143
+ xlabel_text = "Years"
144
+ fmt = "%Y"
145
+ elif span_days >= 60: # 2+ months
146
+ interval = max(1, int(span_days / 30 / 6))
147
+ locator = mdates.MonthLocator(interval=interval)
148
+ xlabel_text = "Months"
149
+ fmt = "%b, %Y"
150
+ elif span_days >= 14: # 2+ weeks
151
+ interval = max(1, int(span_days / 7 / 6))
152
+ locator = mdates.WeekdayLocator(interval=interval)
153
+ xlabel_text = "Weeks"
154
+ fmt = "Week %W, %Y"
155
+ elif span_days >= 2: # 2+ days
156
+ interval = max(1, int(span_days / 6))
157
+ locator = mdates.DayLocator(interval=interval)
158
+ xlabel_text = "Day with month"
159
+ fmt = "%b %d"
160
+ elif total_seconds >= 3600: # Within 1-2 days, span across hours
161
+ interval = max(1, int(total_seconds / 3600 / 6))
162
+ locator = mdates.HourLocator(interval=interval)
163
+ xlabel_text = f"Time ({dates[0].strftime('%b %d, %Y')})" if dates[0].date() == dates[-1].date() else "Date & Time"
164
+ fmt = "%H:%M" if dates[0].date() == dates[-1].date() else "%b %d %H:%M"
165
+ else: # Very short time or same minute
166
+ locator = mdates.AutoDateLocator()
167
+ xlabel_text = f"Time ({dates[0].strftime('%b %d, %Y')})"
168
+ fmt = "%H:%M:%S"
169
+
170
+ plt.xlabel(xlabel_text, fontfamily=cursive_fonts, fontsize=12)
171
+ plt.ylabel("Github Stars", fontfamily=cursive_fonts, fontsize=12)
172
+
173
+ # Ensure Y-axis only uses integer counts
174
+ plt.gca().yaxis.set_major_locator(MaxNLocator(integer=True))
108
175
 
109
176
  # Format the x-axis to show dates nicely
110
- plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
111
- plt.gca().xaxis.set_major_locator(mdates.AutoDateLocator())
177
+ plt.gca().xaxis.set_major_formatter(mdates.DateFormatter(fmt))
178
+ plt.gca().xaxis.set_major_locator(locator)
112
179
  plt.gcf().autofmt_xdate()
113
180
 
181
+ # Set font for tick labels
182
+ for label in plt.gca().get_xticklabels() + plt.gca().get_yticklabels():
183
+ label.set_fontfamily(cursive_fonts)
184
+
185
+ # Add repo name to top left (which is usually empty in cumulative growth plots)
186
+ plt.text(0.05, 0.95, repo, transform=plt.gca().transAxes,
187
+ fontsize=14, fontfamily=cursive_fonts,
188
+ verticalalignment='top', horizontalalignment='left',
189
+ bbox=dict(facecolor='white', alpha=0.8, edgecolor='none'))
190
+
114
191
  plt.grid(True)
115
192
  plt.tight_layout()
116
193
  plt.savefig(filename)
@@ -134,9 +211,17 @@ def update_gitignore(filename):
134
211
  def publish_to_readme(plot_filename, repo):
135
212
  readme_path = "README.md"
136
213
  basename = os.path.basename(plot_filename)
137
- img_path = f"./assets/{basename}"
214
+ img_path = f"assets/{basename}"
138
215
 
139
- html_snippet = f'\n<p align="center">\n <img src="{img_path}" alt="{repo}" width="100%" />\n</p>\n'
216
+ html_snippet = (
217
+ f'\n## Star History\n\n'
218
+ f'<a href="https://star-history.com/#{repo}&Timeline" align="center">\n'
219
+ f' <picture>\n'
220
+ f' <source media="(prefers-color-scheme: dark)" srcset="{img_path}">\n'
221
+ f' <img alt="Star History Chart" src="{img_path}">\n'
222
+ f' </picture>\n'
223
+ f'</a>\n'
224
+ )
140
225
 
141
226
  if os.path.exists(readme_path):
142
227
  with open(readme_path, 'r', encoding='utf-8') as f:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: github-growth-plotter
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: A tool to fetch GitHub stargazers and plot growth over time.
5
5
  Author: Open Source Maintainers
6
6
  Classifier: Programming Language :: Python :: 3
@@ -28,10 +28,12 @@ Dynamic: summary
28
28
 
29
29
  <div align="center">
30
30
 
31
+ <a href="https://github.com/ishandutta2007/Awesome-Awesome-Awesome"><img src="https://img.shields.io/badge/Awesome-%E2%9C%94-blueviolet?style=flat-square&logo=github" alt="Awesome"/></a><a href="https://discord.gg/jc4xtF58Ve"><img src="https://img.shields.io/badge/Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white" alt="Discord" /></a>
31
32
  [![Python](https://img.shields.io/badge/Python-3.x-blue?style=for-the-badge&logo=python&logoColor=white)](https://python.org)
32
33
  [![GitHub CLI](https://img.shields.io/badge/GitHub%20CLI-Required-black?style=for-the-badge&logo=github&logoColor=white)](https://cli.github.com/)
33
34
  [![Matplotlib](https://img.shields.io/badge/Matplotlib-Supported-orange?style=for-the-badge)](https://matplotlib.org/)
34
35
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg?style=for-the-badge)](https://opensource.org/licenses/MIT)
36
+ <a href="https://github.com/ishandutta2007"><img alt="GitHub followers" src="https://img.shields.io/github/followers/ishandutta2007?label=Follow" /></a>
35
37
 
36
38
  </div>
37
39
 
@@ -83,9 +85,15 @@ github-growth-plot --publish
83
85
  ```
84
86
  This automatically appends the following HTML snippet to the bottom of your `README.md`:
85
87
  ```html
86
- <p align="center">
87
- <img src="./assets/<username>_<reponame>_growth.svg" alt="<owner>/<repo>" width="100%" />
88
- </p>
88
+ ## Star History
89
+
90
+ <a href="https://star-history.com/#<username>/<reponame>&Timeline" align="center">
91
+ <picture>
92
+ <source media="(prefers-color-scheme: dark)" srcset="assets/<username>_<reponame>_growth.svg">
93
+ <img alt="Star History Chart" src="assets/<username>_<reponame>_growth.svg">
94
+ </picture>
95
+ </a>
96
+
89
97
  ```
90
98
 
91
99
  ## 📂 Generated Files
@@ -95,6 +103,16 @@ When executed, the script generates and manages the following files:
95
103
  - 📄 **`<username>_<reponame>_stargazers.csv`**: Raw historical star data (automatically ignored via `.gitignore`).
96
104
  - 🙈 **`.gitignore`**: Updated automatically to ignore the generated CSV file.
97
105
 
106
+ ## Star History
107
+
108
+ <a href="https://star-history.com/#ishandutta2007/add-github-growth-plot&Timeline" align="center">
109
+ <picture>
110
+ <source media="(prefers-color-scheme: dark)" srcset="assets/ishandutta2007_add-github-growth-plot_growth.svg">
111
+ <img alt="Star History Chart" src="assets/ishandutta2007_add-github-growth-plot_growth.svg">
112
+ </picture>
113
+ </a>
114
+
115
+
98
116
  ---
99
117
  *Made with ❤️ for Open Source Maintainers.*
100
118
 
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
5
5
 
6
6
  setup(
7
7
  name="github-growth-plotter",
8
- version="0.1.0",
8
+ version="0.1.1",
9
9
  author="Open Source Maintainers",
10
10
  description="A tool to fetch GitHub stargazers and plot growth over time.",
11
11
  long_description=long_description,