Extract GitHub repository information
(self, text: str)
| 258 | return None |
| 259 | |
| 260 | def _extract_github_info(self, text: str) -> Optional[Dict]: |
| 261 | """Extract GitHub repository information""" |
| 262 | try: |
| 263 | # Match GitHub URLs |
| 264 | github_pattern = r'github\.com/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_.-]+)' |
| 265 | match = re.search(github_pattern, text, re.IGNORECASE) |
| 266 | |
| 267 | if match: |
| 268 | owner = match.group(1) |
| 269 | repo = match.group(2) |
| 270 | # Remove any trailing punctuation or special chars |
| 271 | repo = re.sub(r'[^a-zA-Z0-9_.-].*$', '', repo) |
| 272 | |
| 273 | url = f"{self.github_api_base}/repos/{owner}/{repo}" |
| 274 | headers = { |
| 275 | 'Accept': 'application/vnd.github.v3+json', |
| 276 | 'User-Agent': 'OneCite/1.0' |
| 277 | } |
| 278 | |
| 279 | response = requests.get(url, headers=headers, timeout=10) |
| 280 | |
| 281 | if response.status_code == 200: |
| 282 | data = response.json() |
| 283 | |
| 284 | version = None |
| 285 | try: |
| 286 | tags_url = f"{self.github_api_base}/repos/{owner}/{repo}/tags" |
| 287 | tags_response = requests.get(tags_url, headers=headers, timeout=5) |
| 288 | if tags_response.status_code == 200: |
| 289 | tags = tags_response.json() |
| 290 | if tags and len(tags) > 0: |
| 291 | version = tags[0].get('name', '').lstrip('v') |
| 292 | except Exception: |
| 293 | pass |
| 294 | |
| 295 | return { |
| 296 | 'source': 'github', |
| 297 | 'type': 'software', |
| 298 | 'is_software': True, |
| 299 | 'repo': f"{owner}/{repo}", |
| 300 | 'title': data.get('name', repo), |
| 301 | 'description': data.get('description', ''), |
| 302 | 'authors': [data.get('owner', {}).get('login', owner)], |
| 303 | 'year': data.get('created_at', '')[:4] if data.get('created_at') else None, |
| 304 | 'url': data.get('html_url', ''), |
| 305 | 'version': version, |
| 306 | 'publisher': 'GitHub', |
| 307 | 'language': data.get('language', ''), |
| 308 | 'stars': data.get('stargazers_count', 0) |
| 309 | } |
| 310 | |
| 311 | except Exception as e: |
| 312 | self.logger.warning(f"Failed to extract GitHub info: {str(e)}") |
| 313 | |
| 314 | return None |
| 315 | |
| 316 | def _extract_zenodo_info(self, text: str) -> Optional[Dict]: |
| 317 | """Extract Zenodo/Figshare dataset information""" |