Python:
from json import dumps
from os import makedirs
from ssl import create_default_context
from requests import Session
from requests.adapters import HTTPAdapter
from ssl import Purpose
from urllib3.poolmanager import PoolManager
class CustomHttpAdapter(HTTPAdapter):
def __init__(self, ssl_context=None, **kwargs):
self.ssl_context = ssl_context
super().__init__(**kwargs)
def init_poolmanager(self, connections, maxsize, block=False):
self.poolmanager = PoolManager(
num_pools=connections, maxsize=maxsize,
block=block, ssl_context=self.ssl_context
)
class JiraConnect:
def __init__(self, token: str, domain: str, path: str = '/rest/api/2') -> None:
self.url = f'https://{domain}{path}'
self.jsession = self._get_legacy_session()
self.jsession.headers.update({
'Content-Type': 'application/json; charset=utf-8',
'Authorization' : 'Bearer ' + token
})
self.spath = f'JIRA_{domain}'
self.exclude_ext = (
# '.png', '.jpg', '.jpeg', '.mov', '.mp4', '.gif'
)
makedirs(self.spath, exist_ok=True)
def _get_legacy_session(self) -> Session:
ctx = create_default_context(Purpose.SERVER_AUTH)
ctx.options |= 0x4 # OP_LEGACY_SERVER_CONNECT
session = Session()
session.mount('https://', CustomHttpAdapter(ctx))
return session
def _save_data(self, file_name: str, content: dict) -> None:
with open(f'./{self.spath}/{file_name}.json', 'a') as saver:
saver.write(dumps(
content, indent=4, sort_keys=True, default=str
))
def dump(self) -> str:
done = 0
params = {
'jql': 'order by created DESC',
'startAt': 0,
'fields': ['attachment', 'project', 'comment', 'description']
}
while True:
answer = self.jsession.get(f'{self.url}/search', params=params).json()
for issue in answer['issues']:
iid = issue.get('id', '0')
desc = issue['fields']['description'] or ''
attachments = issue['fields']['attachment']
project = issue['fields']['project']
comments = issue['fields']['comment']['comments']
name = project['name']
path = f"./{self.spath}/{name}/{iid}"
makedirs(path, exist_ok=True)
with open(path+'/issue.txt', 'a') as saver:
saver.write(desc+'\n\nComments:\n')
for comment in comments:
author = comment.get('author', {}).get('displayName', 'Nobody')
body = comment.get('body', '')
date = comment.get('created', '0000-00-00 00:00:00')
saver.write(f'[{date}] ({author}) -> {body}\n{"*"*15}\n')
for attachment in attachments:
name = attachment.get('filename', '').lower()
url = attachment.get('content', '')
size = attachment.get('size', '')
if name.split('.')[-1] in self.exclude_ext:
continue
self.get_attachment(url, f'{path}/{size}_{name}')
done += 1
print(f'Dumped: {done}', end='\r')
params['startAt'] += answer['maxResults']
def get_attachment(self, url: str, save_path: str) -> None:
file_content = self.jsession.get(url).content
with open(save_path, 'wb') as file:
file.write(file_content)
if __name__ == '__main__':
jira = JiraConnect(
'token',
'jira.evilsite.com'
)
jira.dump()