|
20 | 20 |
|
21 | 21 | import ctypes |
22 | 22 | import json |
| 23 | +from dataclasses import dataclass |
23 | 24 | from datetime import datetime, date |
24 | 25 | from typing import List, Dict, Optional |
25 | 26 |
|
|
29 | 30 | from .enums import PluginType |
30 | 31 |
|
31 | 32 |
|
| 33 | +@dataclass(frozen=True) |
| 34 | +class ExtensionVersionPlatform: |
| 35 | + name: str |
| 36 | + download_url: str |
| 37 | + untracked_download_url: str |
| 38 | + |
| 39 | + |
| 40 | +@dataclass(frozen=True) |
| 41 | +class ExtensionVersion: |
| 42 | + id: str |
| 43 | + version: str |
| 44 | + long_description: str |
| 45 | + changelog: str |
| 46 | + minimum_client_version: int |
| 47 | + platforms: List[ExtensionVersionPlatform] |
| 48 | + created: str |
| 49 | + |
| 50 | + |
32 | 51 | class Extension: |
33 | 52 | """ |
34 | 53 | ``Extension`` is mostly read-only, however you can install/uninstall enable/disable plugins. Extensions are |
@@ -152,13 +171,23 @@ def minimum_version(self) -> int: |
152 | 171 | def minimum_version_info(self) -> 'binaryninja.CoreVersionInfo': |
153 | 172 | """Minimum version info the plugin was tested on""" |
154 | 173 | core_version_info = core.BNPluginGetMinimumVersionInfo(self.handle) |
155 | | - return binaryninja.CoreVersionInfo(core_version_info.major, core_version_info.minor, core_version_info.build) |
| 174 | + return binaryninja.CoreVersionInfo( |
| 175 | + core_version_info.major, |
| 176 | + core_version_info.minor, |
| 177 | + core_version_info.build, |
| 178 | + core_version_info.channel or "" |
| 179 | + ) |
156 | 180 |
|
157 | 181 | @property |
158 | 182 | def maximum_version_info(self) -> 'binaryninja.CoreVersionInfo': |
159 | 183 | """Maximum version info the plugin will support""" |
160 | 184 | core_version_info = core.BNPluginGetMaximumVersionInfo(self.handle) |
161 | | - return binaryninja.CoreVersionInfo(core_version_info.major, core_version_info.minor, core_version_info.build) |
| 185 | + return binaryninja.CoreVersionInfo( |
| 186 | + core_version_info.major, |
| 187 | + core_version_info.minor, |
| 188 | + core_version_info.build, |
| 189 | + core_version_info.channel or "" |
| 190 | + ) |
162 | 191 |
|
163 | 192 | @property |
164 | 193 | def name(self) -> str: |
@@ -206,14 +235,65 @@ def author(self) -> Optional[str]: |
206 | 235 | @deprecation.deprecated(deprecated_in="5.3", details='Use :py:attr:`current_version` in combination with :py:attr:`versions` instead.') |
207 | 236 | def version(self) -> Optional[str]: |
208 | 237 | """String version of the plugin""" |
| 238 | + return self.current_version.version |
| 239 | + |
| 240 | + @property |
| 241 | + def current_version(self) -> ExtensionVersion: |
| 242 | + """Current version metadata for the plugin""" |
209 | 243 | version: core.BNPluginVersion = core.BNPluginGetCurrentVersion(self.handle) |
210 | 244 | try: |
211 | | - version_string = version.versionString |
212 | | - except AttributeError: |
213 | | - version_string = "" |
| 245 | + platforms = [] |
| 246 | + for i in range(version.platformCount): |
| 247 | + platform = version.platforms[i] |
| 248 | + platforms.append(ExtensionVersionPlatform( |
| 249 | + name=platform.name or "", |
| 250 | + download_url=platform.downloadUrl or "", |
| 251 | + untracked_download_url=platform.untrackedDownloadUrl or "" |
| 252 | + )) |
| 253 | + return ExtensionVersion( |
| 254 | + id=version.id or "", |
| 255 | + version=version.versionString or "", |
| 256 | + long_description=version.longDescription or "", |
| 257 | + changelog=version.changelog or "", |
| 258 | + minimum_client_version=version.minimumClientVersion, |
| 259 | + platforms=platforms, |
| 260 | + created=version.created or "" |
| 261 | + ) |
214 | 262 | finally: |
215 | 263 | core.BNPluginFreeVersion(version) |
216 | | - return version_string |
| 264 | + |
| 265 | + @property |
| 266 | + def versions(self) -> List[ExtensionVersion]: |
| 267 | + """Version metadata for all available plugin versions""" |
| 268 | + result = [] |
| 269 | + count = ctypes.c_ulonglong(0) |
| 270 | + versions = core.BNPluginGetVersions(self.handle, count) |
| 271 | + try: |
| 272 | + if versions is None: |
| 273 | + return result |
| 274 | + for i in range(count.value): |
| 275 | + version = versions[i] |
| 276 | + platforms = [] |
| 277 | + for j in range(version.platformCount): |
| 278 | + platform = version.platforms[j] |
| 279 | + platforms.append(ExtensionVersionPlatform( |
| 280 | + name=platform.name or "", |
| 281 | + download_url=platform.downloadUrl or "", |
| 282 | + untracked_download_url=platform.untrackedDownloadUrl or "" |
| 283 | + )) |
| 284 | + result.append(ExtensionVersion( |
| 285 | + id=version.id or "", |
| 286 | + version=version.versionString or "", |
| 287 | + long_description=version.longDescription or "", |
| 288 | + changelog=version.changelog or "", |
| 289 | + minimum_client_version=version.minimumClientVersion, |
| 290 | + platforms=platforms, |
| 291 | + created=version.created or "" |
| 292 | + )) |
| 293 | + return result |
| 294 | + finally: |
| 295 | + if versions is not None: |
| 296 | + core.BNFreePluginVersions(versions, count.value) |
217 | 297 |
|
218 | 298 | @property |
219 | 299 | def install_platforms(self) -> List[str]: |
|
0 commit comments