pkdevtools 0.13.20260315.331__tar.gz → 0.13.20260406.332__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.
Files changed (68) hide show
  1. pkdevtools-0.13.20260406.332/PKDevTools/classes/GitHubCommitFetcher.py +347 -0
  2. pkdevtools-0.13.20260406.332/PKDevTools/classes/__init__.py +1 -0
  3. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKG-INFO +2 -2
  4. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/pkdevtools.egg-info/PKG-INFO +2 -2
  5. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/pkdevtools.egg-info/SOURCES.txt +1 -0
  6. pkdevtools-0.13.20260315.331/PKDevTools/classes/__init__.py +0 -1
  7. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/LICENSE +0 -0
  8. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/LICENSE.txt +0 -0
  9. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/README.txt +0 -0
  10. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/__init__.py +0 -0
  11. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Archiver.py +0 -0
  12. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/ColorText.py +0 -0
  13. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Committer.py +0 -0
  14. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/CookieHelper.py +0 -0
  15. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/DBManager.py +0 -0
  16. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/DatabaseSyncChecker.py +0 -0
  17. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/DebugConfig.py +0 -0
  18. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Environment.py +0 -0
  19. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Fetcher.py +0 -0
  20. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Fileinfo.py +0 -0
  21. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/FunctionTimeouts.py +0 -0
  22. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/GitHubSecrets.py +0 -0
  23. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/GmailReader.py +0 -0
  24. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/MarketHours.py +0 -0
  25. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/MenuOptions.py +0 -0
  26. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/NSEMarketStatus.py +0 -0
  27. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/OutputControls.py +0 -0
  28. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKBackupRestore.py +0 -0
  29. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKDataProvider.py +0 -0
  30. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKDateUtilities.py +0 -0
  31. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKGitFolderDownloader.py +0 -0
  32. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKJoinableQueue.py +0 -0
  33. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKMultiProcessorClient.py +0 -0
  34. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKPickler.py +0 -0
  35. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKScalableDataFetcher.py +0 -0
  36. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKTimer.py +0 -0
  37. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Pikey.py +0 -0
  38. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/RepairDB.py +0 -0
  39. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Singleton.py +0 -0
  40. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/SuppressOutput.py +0 -0
  41. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/System.py +0 -0
  42. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Telegram.py +0 -0
  43. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/UserSubscriptions.py +0 -0
  44. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Utils.py +0 -0
  45. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/WorkflowManager.py +0 -0
  46. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/dictModel.py +0 -0
  47. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/githubutilities.py +0 -0
  48. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/log.py +0 -0
  49. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/multiprocessing_logging.py +0 -0
  50. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/pubsub/__init__.py +0 -0
  51. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/pubsub/events.py +0 -0
  52. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/pubsub/publisher.py +0 -0
  53. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/pubsub/subscriber.py +0 -0
  54. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/squash.py +0 -0
  55. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/test_PKDataProvider.py +0 -0
  56. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/test_PKScalableDataFetcher.py +0 -0
  57. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/turso.py +0 -0
  58. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/updater.py +0 -0
  59. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/release.md +0 -0
  60. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/requirements.txt +0 -0
  61. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/README.md +0 -0
  62. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/pkdevtools.egg-info/dependency_links.txt +0 -0
  63. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/pkdevtools.egg-info/entry_points.txt +0 -0
  64. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/pkdevtools.egg-info/not-zip-safe +0 -0
  65. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/pkdevtools.egg-info/requires.txt +0 -0
  66. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/pkdevtools.egg-info/top_level.txt +0 -0
  67. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/setup.cfg +0 -0
  68. {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/setup.py +0 -0
@@ -0,0 +1,347 @@
1
+ import requests
2
+ from datetime import datetime, timezone, timedelta
3
+ from typing import Optional, List, Dict, Tuple
4
+ import os
5
+ from PKDevTools.classes.Environment import PKEnvironment
6
+ from PKDevTools.classes import Archiver
7
+
8
+
9
+ class GitHubCommitFetcher:
10
+ """
11
+ A class to fetch commits and files from GitHub repositories within a specified time window.
12
+
13
+ Usage:
14
+ fetcher = GitHubCommitFetcher()
15
+
16
+ # Get latest commit info
17
+ commit_info = fetcher.get_latest_commit_in_window(
18
+ file_path="pkbrokers/kite/examples/results/Data/ticks.json",
19
+ start_ist="09:40:00",
20
+ end_ist="09:50:00"
21
+ )
22
+
23
+ # Download the file
24
+ fetcher.download_file(commit_info["sha"], output_path="/path/to/save/ticks.json")
25
+
26
+ # Or do both at once
27
+ success, file_path = fetcher.fetch_latest_file_in_window(
28
+ file_path="pkbrokers/kite/examples/results/Data/ticks.json",
29
+ start_ist="09:40:00",
30
+ end_ist="09:50:00",
31
+ output_path="/path/to/save/ticks.json"
32
+ )
33
+ """
34
+
35
+ def __init__(self, owner: str = "pkjmesra", repo: str = "PKBrokers",
36
+ branch: str = "main", github_token: Optional[str] = None):
37
+ """
38
+ Initialize the GitHubCommitFetcher.
39
+
40
+ Args:
41
+ owner: GitHub repository owner
42
+ repo: Repository name
43
+ branch: Branch name (default: "main")
44
+ github_token: GitHub personal access token (optional but recommended)
45
+ """
46
+ self.owner = owner
47
+ self.repo = repo
48
+ self.branch = branch
49
+ self.github_token = github_token or PKEnvironment().GITHUB_TOKEN
50
+ self.ist_offset = timedelta(hours=5, minutes=30)
51
+
52
+ def _ist_to_utc(self, date_str: str, time_str: str) -> datetime:
53
+ """
54
+ Convert IST datetime string to UTC datetime object.
55
+
56
+ Args:
57
+ date_str: Date in YYYY-MM-DD format
58
+ time_str: Time in HH:MM:SS format (24-hour)
59
+
60
+ Returns:
61
+ UTC datetime object
62
+ """
63
+ dt_ist = datetime.strptime(f"{date_str} {time_str}", "%Y-%m-%d %H:%M:%S")
64
+ dt_utc = dt_ist - self.ist_offset
65
+ return dt_utc.replace(tzinfo=timezone.utc)
66
+
67
+ def _get_headers(self) -> Dict[str, str]:
68
+ """Get GitHub API headers with authentication if token is provided."""
69
+ headers = {}
70
+ if self.github_token:
71
+ headers["Authorization"] = f"token {self.github_token}"
72
+ return headers
73
+
74
+ def get_commits_in_window(
75
+ self,
76
+ file_path: str,
77
+ start_ist: str,
78
+ end_ist: str,
79
+ target_date: Optional[str] = None,
80
+ per_page: int = 100
81
+ ) -> List[Dict]:
82
+ """
83
+ Get all commits for a file within a specified IST time window.
84
+
85
+ Args:
86
+ file_path: Path to the file in the repository
87
+ start_ist: Start time in IST (HH:MM:SS format)
88
+ end_ist: End time in IST (HH:MM:SS format)
89
+ target_date: Date in YYYY-MM-DD format (defaults to today)
90
+ per_page: Number of commits per API page (max 100)
91
+
92
+ Returns:
93
+ List of commit dictionaries with keys: sha, date, message, author, url
94
+ """
95
+ if target_date is None:
96
+ target_date = datetime.now().strftime("%Y-%m-%d")
97
+
98
+ start_utc = self._ist_to_utc(target_date, start_ist)
99
+ end_utc = self._ist_to_utc(target_date, end_ist)
100
+
101
+ print(f"🔍 Looking for commits between IST {start_ist} - {end_ist} on {target_date}")
102
+ print(f" UTC window: {start_utc.isoformat()} to {end_utc.isoformat()}")
103
+
104
+ headers = self._get_headers()
105
+ url = f"https://api.github.com/repos/{self.owner}/{self.repo}/commits"
106
+ params = {
107
+ "path": file_path,
108
+ "sha": self.branch,
109
+ "per_page": per_page
110
+ }
111
+
112
+ all_commits = []
113
+ page = 1
114
+ window_commits = []
115
+
116
+ # Paginate through all commits
117
+ while True:
118
+ params["page"] = page
119
+ response = requests.get(url, headers=headers, params=params)
120
+
121
+ if response.status_code != 200:
122
+ print(f"❌ API error: {response.status_code}")
123
+ break
124
+
125
+ commits = response.json()
126
+ if not commits:
127
+ break
128
+
129
+ all_commits.extend(commits)
130
+ page += 1
131
+
132
+ # Stop if we've gone back far enough
133
+ oldest_date = datetime.fromisoformat(
134
+ commits[-1]["commit"]["committer"]["date"].replace('Z', '+00:00')
135
+ )
136
+ if oldest_date < start_utc:
137
+ break
138
+
139
+ print(f"📊 Fetched {len(all_commits)} total commits for {file_path}")
140
+
141
+ # Find commits within the time window
142
+ for commit in all_commits:
143
+ committer_date = datetime.fromisoformat(
144
+ commit["commit"]["committer"]["date"].replace('Z', '+00:00')
145
+ )
146
+
147
+ if start_utc <= committer_date <= end_utc:
148
+ window_commits.append({
149
+ "sha": commit["sha"],
150
+ "date": committer_date,
151
+ "message": commit["commit"]["message"].strip(),
152
+ "author": commit["commit"]["author"]["name"],
153
+ "url": commit["html_url"]
154
+ })
155
+
156
+ return window_commits
157
+
158
+ def get_latest_commit_in_window(
159
+ self,
160
+ file_path: str,
161
+ start_ist: str,
162
+ end_ist: str,
163
+ target_date: Optional[str] = None
164
+ ) -> Optional[Dict]:
165
+ """
166
+ Get the latest commit for a file within a specified IST time window.
167
+
168
+ Args:
169
+ file_path: Path to the file in the repository
170
+ start_ist: Start time in IST (HH:MM:SS format)
171
+ end_ist: End time in IST (HH:MM:SS format)
172
+ target_date: Date in YYYY-MM-DD format (defaults to today)
173
+
174
+ Returns:
175
+ Commit dictionary or None if no commit found
176
+ """
177
+ commits = self.get_commits_in_window(file_path, start_ist, end_ist, target_date)
178
+
179
+ if not commits:
180
+ print(f"❌ No commits found in the specified time window.")
181
+ return None
182
+
183
+ # Display all commits found
184
+ print(f"\n📋 Found {len(commits)} commit(s) in the time window:")
185
+ print("=" * 80)
186
+ for i, commit_info in enumerate(commits, 1):
187
+ ist_time = (commit_info["date"] + self.ist_offset).time()
188
+ print(f"{i}. Commit: {commit_info['sha'][:7]}")
189
+ print(f" Time (IST): {ist_time}")
190
+ print(f" Time (UTC): {commit_info['date']}")
191
+ print(f" Author: {commit_info['author']}")
192
+ print(f" Message: {commit_info['message']}")
193
+ print(f" URL: {commit_info['url']}")
194
+ print()
195
+
196
+ # Return the latest commit (first in the list)
197
+ latest = commits[0]
198
+ print("=" * 80)
199
+ print(f"✅ LATEST COMMIT IN WINDOW:")
200
+ print(f" SHA: {latest['sha'][:7]}")
201
+ print(f" Time (IST): {(latest['date'] + self.ist_offset).time()}")
202
+ print(f" Message: {latest['message']}")
203
+ print()
204
+
205
+ return latest
206
+
207
+ def download_file(
208
+ self,
209
+ commit_sha: str,
210
+ file_path: str,
211
+ output_path: Optional[str] = None
212
+ ) -> Tuple[bool, Optional[str]]:
213
+ """
214
+ Download a file from a specific commit.
215
+
216
+ Args:
217
+ commit_sha: Commit SHA hash
218
+ file_path: Path to the file in the repository
219
+ output_path: Path to save the file (defaults to user data dir with original filename)
220
+
221
+ Returns:
222
+ Tuple of (success, output_path)
223
+ """
224
+ raw_url = f"https://raw.githubusercontent.com/{self.owner}/{self.repo}/{commit_sha}/{file_path}"
225
+
226
+ if output_path is None:
227
+ filename = os.path.basename(file_path)
228
+ output_path = os.path.join(Archiver.get_user_data_dir(), filename)
229
+
230
+ # Ensure directory exists
231
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
232
+
233
+ print(f"📥 Downloading from {raw_url} ...")
234
+
235
+ try:
236
+ response = requests.get(raw_url, timeout=30)
237
+ if response.status_code == 200:
238
+ with open(output_path, "wb") as f:
239
+ f.write(response.content)
240
+ print(f"✅ Saved as {output_path}")
241
+ return True, output_path
242
+ else:
243
+ print(f"❌ Failed to download file: HTTP {response.status_code}")
244
+ return False, None
245
+ except Exception as e:
246
+ print(f"❌ Error downloading file: {e}")
247
+ return False, None
248
+
249
+ def fetch_latest_file_in_window(
250
+ self,
251
+ file_path: str,
252
+ start_ist: str,
253
+ end_ist: str,
254
+ target_date: Optional[str] = None,
255
+ output_path: Optional[str] = None
256
+ ) -> Tuple[bool, Optional[str], Optional[Dict]]:
257
+ """
258
+ Fetch the latest version of a file committed within the specified time window.
259
+
260
+ Args:
261
+ file_path: Path to the file in the repository
262
+ start_ist: Start time in IST (HH:MM:SS format)
263
+ end_ist: End time in IST (HH:MM:SS format)
264
+ target_date: Date in YYYY-MM-DD format (defaults to today)
265
+ output_path: Path to save the file (defaults to user data dir)
266
+
267
+ Returns:
268
+ Tuple of (success, output_path, commit_info)
269
+ """
270
+ # Get the latest commit in the window
271
+ commit_info = self.get_latest_commit_in_window(
272
+ file_path, start_ist, end_ist, target_date
273
+ )
274
+
275
+ if not commit_info:
276
+ return False, None, None
277
+
278
+ # Download the file
279
+ success, saved_path = self.download_file(
280
+ commit_info["sha"], file_path, output_path
281
+ )
282
+
283
+ return success, saved_path, commit_info
284
+
285
+
286
+ # Convenience function for backward compatibility
287
+ def fetch_ticks_json_in_window(
288
+ start_ist: str = "09:40:00",
289
+ end_ist: str = "09:50:00",
290
+ target_date: Optional[str] = None,
291
+ output_path: Optional[str] = None
292
+ ) -> Tuple[bool, Optional[str], Optional[Dict]]:
293
+ """
294
+ Convenience function to fetch ticks.json committed within a time window.
295
+
296
+ Args:
297
+ start_ist: Start time in IST (HH:MM:SS format)
298
+ end_ist: End time in IST (HH:MM:SS format)
299
+ target_date: Date in YYYY-MM-DD format (defaults to today)
300
+ output_path: Path to save the file (defaults to user data dir)
301
+
302
+ Returns:
303
+ Tuple of (success, output_path, commit_info)
304
+ """
305
+ fetcher = GitHubCommitFetcher()
306
+ return fetcher.fetch_latest_file_in_window(
307
+ file_path="pkbrokers/kite/examples/results/Data/ticks.json",
308
+ start_ist=start_ist,
309
+ end_ist=end_ist,
310
+ target_date=target_date,
311
+ output_path=output_path
312
+ )
313
+
314
+
315
+ # Example usage if run directly
316
+ # if __name__ == "__main__":
317
+ # # Example 1: Using the class directly
318
+ # fetcher = GitHubCommitFetcher()
319
+
320
+ # # Get commits for ticks.json between 9:40 AM and 9:50 AM IST today
321
+ # commits = fetcher.get_commits_in_window(
322
+ # file_path="pkbrokers/kite/examples/results/Data/ticks.json",
323
+ # start_ist="09:40:00",
324
+ # end_ist="09:50:00"
325
+ # )
326
+
327
+ # # Download the latest file
328
+ # if commits:
329
+ # success, path, commit = fetcher.fetch_latest_file_in_window(
330
+ # file_path="pkbrokers/kite/examples/results/Data/ticks.json",
331
+ # start_ist="09:40:00",
332
+ # end_ist="09:50:00"
333
+ # )
334
+
335
+ # Example 2: Using the convenience function
336
+ success, file_path, commit_info = fetch_ticks_json_in_window()
337
+
338
+ # Example 3: Custom parameters
339
+ # success, file_path, commit_info = fetcher.fetch_latest_file_in_window(
340
+ # file_path="custom/path/to/file.json",
341
+ # start_ist="10:00:00",
342
+ # end_ist="10:15:00",
343
+ # target_date="2026-04-05",
344
+ # output_path="/custom/output/path/file.json"
345
+ # )
346
+ # for commit in commit_info:
347
+ # print(f"SHA: {commit_info['sha'][:7]}, Time: {commit_info['date']}, Message: {commit_info['message']}")
@@ -0,0 +1 @@
1
+ VERSION='0.13.20260406.332'
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pkdevtools
3
- Version: 0.13.20260315.331
3
+ Version: 0.13.20260406.332
4
4
  Summary: A general day-to-day toolset for PKScreener repos
5
5
  Home-page: https://github.com/pkjmesra/PKDevTools
6
- Download-URL: https://github.com/pkjmesra/PKDevTools/archive/v0.13.20260315.331.zip
6
+ Download-URL: https://github.com/pkjmesra/PKDevTools/archive/v0.13.20260406.332.zip
7
7
  Author: pkjmesra
8
8
  Author-email: pkjmesra@gmail.com
9
9
  License: OSI Approved (MIT)
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pkdevtools
3
- Version: 0.13.20260315.331
3
+ Version: 0.13.20260406.332
4
4
  Summary: A general day-to-day toolset for PKScreener repos
5
5
  Home-page: https://github.com/pkjmesra/PKDevTools
6
- Download-URL: https://github.com/pkjmesra/PKDevTools/archive/v0.13.20260315.331.zip
6
+ Download-URL: https://github.com/pkjmesra/PKDevTools/archive/v0.13.20260406.332.zip
7
7
  Author: pkjmesra
8
8
  Author-email: pkjmesra@gmail.com
9
9
  License: OSI Approved (MIT)
@@ -18,6 +18,7 @@ PKDevTools/classes/Environment.py
18
18
  PKDevTools/classes/Fetcher.py
19
19
  PKDevTools/classes/Fileinfo.py
20
20
  PKDevTools/classes/FunctionTimeouts.py
21
+ PKDevTools/classes/GitHubCommitFetcher.py
21
22
  PKDevTools/classes/GitHubSecrets.py
22
23
  PKDevTools/classes/GmailReader.py
23
24
  PKDevTools/classes/MarketHours.py
@@ -1 +0,0 @@
1
- VERSION='0.13.20260315.331'