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.
- pkdevtools-0.13.20260406.332/PKDevTools/classes/GitHubCommitFetcher.py +347 -0
- pkdevtools-0.13.20260406.332/PKDevTools/classes/__init__.py +1 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKG-INFO +2 -2
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/pkdevtools.egg-info/PKG-INFO +2 -2
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/pkdevtools.egg-info/SOURCES.txt +1 -0
- pkdevtools-0.13.20260315.331/PKDevTools/classes/__init__.py +0 -1
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/LICENSE +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/LICENSE.txt +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/README.txt +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/__init__.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Archiver.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/ColorText.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Committer.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/CookieHelper.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/DBManager.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/DatabaseSyncChecker.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/DebugConfig.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Environment.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Fetcher.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Fileinfo.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/FunctionTimeouts.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/GitHubSecrets.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/GmailReader.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/MarketHours.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/MenuOptions.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/NSEMarketStatus.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/OutputControls.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKBackupRestore.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKDataProvider.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKDateUtilities.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKGitFolderDownloader.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKJoinableQueue.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKMultiProcessorClient.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKPickler.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKScalableDataFetcher.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKTimer.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Pikey.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/RepairDB.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Singleton.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/SuppressOutput.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/System.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Telegram.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/UserSubscriptions.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Utils.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/WorkflowManager.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/dictModel.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/githubutilities.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/log.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/multiprocessing_logging.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/pubsub/__init__.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/pubsub/events.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/pubsub/publisher.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/pubsub/subscriber.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/squash.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/test_PKDataProvider.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/test_PKScalableDataFetcher.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/turso.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/updater.py +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/release.md +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/requirements.txt +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/README.md +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/pkdevtools.egg-info/dependency_links.txt +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/pkdevtools.egg-info/entry_points.txt +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/pkdevtools.egg-info/not-zip-safe +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/pkdevtools.egg-info/requires.txt +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/pkdevtools.egg-info/top_level.txt +0 -0
- {pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/setup.cfg +0 -0
- {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.
|
|
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.
|
|
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.
|
|
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.
|
|
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)
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/pkdevtools.egg-info/SOURCES.txt
RENAMED
|
@@ -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'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Archiver.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/ColorText.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Committer.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/CookieHelper.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/DBManager.py
RENAMED
|
File without changes
|
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/DebugConfig.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Environment.py
RENAMED
|
File without changes
|
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Fileinfo.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/FunctionTimeouts.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/GitHubSecrets.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/GmailReader.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/MarketHours.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/MenuOptions.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/NSEMarketStatus.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/OutputControls.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKBackupRestore.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKDataProvider.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKDateUtilities.py
RENAMED
|
File without changes
|
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKJoinableQueue.py
RENAMED
|
File without changes
|
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/PKPickler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/RepairDB.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Singleton.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/SuppressOutput.py
RENAMED
|
File without changes
|
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/Telegram.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/WorkflowManager.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/dictModel.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/githubutilities.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/pubsub/__init__.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/pubsub/events.py
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/PKDevTools/classes/pubsub/publisher.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/pkdevtools.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/pkdevtools.egg-info/not-zip-safe
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/pkdevtools.egg-info/requires.txt
RENAMED
|
File without changes
|
{pkdevtools-0.13.20260315.331 → pkdevtools-0.13.20260406.332}/pkdevtools.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|