Browse Source

Add Repo subclass GiteaRepo. Always collect and use the instance_url for cross-api compatibility.

master
poikilos 3 years ago
parent
commit
ed9806b2b0
  1. 144
      utilities/enissue.py

144
utilities/enissue.py

@ -7,6 +7,15 @@ License: See license file at https://github.com/poikilos/EnlivenMinetest
This script caches issues (To This script caches issues (To
~/.cache/enissue/poikilos/EnlivenMinetest/issues ~/.cache/enissue/poikilos/EnlivenMinetest/issues
by default). by default).
Options:")
--cache-base <dir> Set the directory for cached files.
--verbose Enable verbose mode.
--debug Enable verbose mode (same as --debug).
--copy-meta-to <dbname> --db-type <db-type) --db-user <user> --db-password <password>
Write database entries for the issue, timeline events, and reactions
to each timeline event (overwrite ANY existing data if same id!).
Only "PostgresQL" is implemented for db-type.
''' '''
from __future__ import print_function from __future__ import print_function
import sys import sys
@ -166,27 +175,29 @@ def usage():
print("") print("")
print("") print("")
print("") print("")
print("Options:") print(__doc__)
print("--cache-base <dir> Set the directory for cached files.")
print("--verbose Enable verbose mode.")
print("--debug Enable verbose mode (same as --debug).")
class Repo: class Repo:
profile = None profile = None
os_user = None
if platform.system() == "Windows": if platform.system() == "Windows":
profile = os.environ['USERPROFILE'] profile = os.environ['USERPROFILE']
os_user = os.environ.get('USERNAME')
else: else:
profile = os.environ['HOME'] profile = os.environ['HOME']
os_user = os.environ.get('USER')
def __init__( def __init__(
self, self,
remote_user="poikilos", remote_user="poikilos",
repo_name="EnlivenMinetest", repo_name="EnlivenMinetest",
repository_id="80873867", repository_id="80873867",
api_repo_url_fmt = "https://api.github.com/repos/{ru}/{rn}", instance_url="https://api.github.com",
api_issue_url_fmt = "{api_url}/issues/{issue_no}", api_repo_url_fmt="{instance_url}/repos/{ru}/{rn}",
search_issues_url_fmt = "https://api.github.com/search/issues?q=repo%3A{ru}/{rn}+", api_issue_url_fmt="{instance_url}/repos/{ru}/{rn}/issues/{issue_no}",
search_issues_url_fmt="{instance_url}/search/issues?q=repo%3A{ru}/{rn}+",
search_results_key="items", search_results_key="items",
page_size=30, page_size=30,
c_issues_name_fmt="issues_page={p}{q}.json", c_issues_name_fmt="issues_page={p}{q}.json",
@ -194,7 +205,7 @@ class Repo:
default_query={'state':'open'}, default_query={'state':'open'},
hide_events=['renamed', 'assigned'], hide_events=['renamed', 'assigned'],
caches_path=None, caches_path=None,
api_comments_url_fmt="{repo_url}/issues/comments", api_comments_url_fmt="{instance_url}/repos/{ru}/{rn}/issues/comments",
): ):
''' '''
Keyword arguments: Keyword arguments:
@ -234,6 +245,7 @@ class Repo:
"~/.cache/enissue/poikilos/EnlivenMinetest/issues". To set "~/.cache/enissue/poikilos/EnlivenMinetest/issues". To set
it later, use the setCachesPath method. it later, use the setCachesPath method.
''' '''
self.instance_url = instance_url
self.rateLimitFmt = ("You may be able to view the issues" self.rateLimitFmt = ("You may be able to view the issues"
" at the html_url, and a login may be" " at the html_url, and a login may be"
" required. The URL \"{}\" is not" " required. The URL \"{}\" is not"
@ -253,17 +265,21 @@ class Repo:
self.api_repo_url_fmt = api_repo_url_fmt self.api_repo_url_fmt = api_repo_url_fmt
self.api_issue_url_fmt = api_issue_url_fmt self.api_issue_url_fmt = api_issue_url_fmt
self.repo_url = self.api_repo_url_fmt.format( self.repo_url = self.api_repo_url_fmt.format(
instance_url=instance_url,
ru=remote_user, ru=remote_user,
rn=repo_name, rn=repo_name,
) )
self.search_issues_url = search_issues_url_fmt.format( self.search_issues_url = search_issues_url_fmt.format(
instance_url=instance_url,
ru=remote_user, ru=remote_user,
rn=repo_name, rn=repo_name,
) )
self.api_comments_url_fmt = api_comments_url_fmt self.api_comments_url_fmt = api_comments_url_fmt
self.comments_url = api_comments_url_fmt.format( self.comments_url = api_comments_url_fmt.format(
repo_url=self.repo_url, instance_url=instance_url,
ru=remote_user,
rn=repo_name,
) )
self.issues_url = self.repo_url + "/issues" self.issues_url = self.repo_url + "/issues"
@ -401,7 +417,9 @@ class Repo:
make_list = True make_list = True
# Change query_s to the issue url (formerly issue_url): # Change query_s to the issue url (formerly issue_url):
query_s = self.api_issue_url_fmt.format( query_s = self.api_issue_url_fmt.format(
api_url=self.repo_url, instance_url=self.instance_url,
ru=self.remote_user,
rn=self.repo_name,
issue_no=issue_no, issue_no=issue_no,
) )
else: else:
@ -1021,6 +1039,62 @@ class Repo:
return {'issue':matching_issue, 'count':match_count} return {'issue':matching_issue, 'count':match_count}
class GiteaRepo(Repo):
def __init__(
self,
repo_url,
# instance_url="https://api.github.com",
# repository_id="80873867",
# api_repo_url_fmt="{instance_url}/repos/{ru}/{rn}",
# api_issue_url_fmt="{instance_url}/repos/{ru}/{rn}/issues/{issue_no}",
# search_issues_url_fmt="{instance_url}/search/issues?q=repo%3A{ru}/{rn}+",
# search_results_key="items",
page_size=30,
# c_issues_name_fmt="issues_page={p}{q}.json",
# c_issue_name_fmt="{issue_no}.json",
default_query={'state':'open'},
hide_events=['renamed', 'assigned'],
caches_path=None,
# api_comments_url_fmt="{instance_url}/repos/{ru}/{rn}/issues/comments",
):
if repo_url.endswith(".git"):
repo_url = repo_url[:-4]
urlParts = repo_url.split("/")
remote_user = urlParts[-2]
repo_name = urlParts[-1]
debug("* constructing GiteaRepo")
debug(" * detected remote_user \"{}\" in url"
"".format(remote_user))
debug(" * detected repo_name \"{}\" in url"
"".format(repo_name))
instance_url = "/".join(urlParts[:-2])
debug(" * detected Gitea url " + instance_url)
# NOTE: self.instance_url is set by super __init__ below.
base_query_fmt = "?q=repo%3A{ru}/{rn}+"
search_issues_url_fmt = \
"{instance_url}/api/v1/repos/issues/search"+base_query_fmt
Repo.__init__(
self,
remote_user=remote_user,
repo_name=repo_name,
repository_id=None,
instance_url=instance_url,
api_repo_url_fmt="{instance_url}/api/v1/repos/{ru}/{rn}",
api_issue_url_fmt="{instance_url}/api/v1/repos/{ru}/{rn}/issues/{issue_no}",
search_issues_url_fmt=search_issues_url_fmt,
search_results_key="items", # TODO: Change for Gitea ??
page_size=page_size, # TODO: Change for Gitea ??
default_query=default_query, # TODO: Change for Gitea ??
hide_events=hide_events,
caches_path=caches_path,
api_comments_url_fmt="{instance_url}/api/v1/repos/{ru}/{rn}/issues/comments",
)
# API documentation:
# https://docs.gitea.io/en-us/api-usage/ says:
# > API Reference guide is auto-generated by swagger and available on: https://gitea.your.host/api/swagger or on [gitea demo instance](https://try.gitea.io/api/swagger)
# > The OpenAPI document is at: https://gitea.your.host/swagger.v1.json
def main(): def main():
global verbose global verbose
mode = None mode = None
@ -1032,6 +1106,10 @@ def main():
search_terms = [] search_terms = []
SEARCH_COMMANDS = ['find', 'AND'] SEARCH_COMMANDS = ['find', 'AND']
caches_path = None caches_path = None
logic = {}
save_key = None
collect_logic = ['--copy-meta-to', '--db-type', '--db-user',
'--db-password', '--cache-base']
for i in range(1, len(sys.argv)): for i in range(1, len(sys.argv)):
arg = sys.argv[i] arg = sys.argv[i]
isValue = False isValue = False
@ -1081,9 +1159,8 @@ def main():
elif arg == "--help": elif arg == "--help":
usage() usage()
exit(0) exit(0)
elif arg == "--cache-base": elif arg in collect_logic:
pass save_key = arg.strip("-")
# options['caches_path'] = None
elif arg.startswith("--"): elif arg.startswith("--"):
usage() usage()
error("Error: The argument \"{}\" is not valid" error("Error: The argument \"{}\" is not valid"
@ -1092,8 +1169,6 @@ def main():
elif prev_arg in SEARCH_COMMANDS: elif prev_arg in SEARCH_COMMANDS:
search_terms.append(arg) search_terms.append(arg)
isValue = True isValue = True
elif prev_arg == "--cache-base":
caches_path = arg
elif arg == "find": elif arg == "find":
# print("* adding criteria: {}".format(arg)) # print("* adding criteria: {}".format(arg))
mode = "list" mode = "list"
@ -1111,6 +1186,9 @@ def main():
+ modes['find']['examples'][andI]) + modes['find']['examples'][andI])
exit(1) exit(1)
mode = "list" mode = "list"
elif save_key is not None:
logic[save_key] = arg
save_key = None
elif arg != "page": elif arg != "page":
mode = "list" mode = "list"
match_all_labels.append(arg) match_all_labels.append(arg)
@ -1124,8 +1202,12 @@ def main():
mode = "list" mode = "list"
if issue_no is not None: if issue_no is not None:
mode = "issue" mode = "issue"
if save_key is not None:
raise ValueError("--{} requires a space then a value."
"".format(save_key))
caches_path = logic.get('cache-base')
valid_modes = ["issue"] valid_modes = ["issue"]
print("command metadata: {}".format(logic))
for k, v in modes.items(): for k, v in modes.items():
valid_modes.append(k) valid_modes.append(k)
@ -1172,6 +1254,36 @@ def main():
results, msg = repo.load_issues(options, issue_no=issue_no, results, msg = repo.load_issues(options, issue_no=issue_no,
search_terms=search_terms) search_terms=search_terms)
debug("* done load_issues for single issue") debug("* done load_issues for single issue")
dstRepoUrl = logic.get('copy-meta-to')
if dstRepoUrl is not None:
if mode != "issue":
raise ValueError("Only rewriting one Gitea issue at a time"
" is implemented. Specify a number.")
db_type = logic.get('db-type')
if db_type is None:
db_type = "PostgresQL"
error("WARNING: No db-type was specified, so db-type was"
" set to the default: {}".format(db_type))
db_u = logic.get("db-user")
if db_u is None:
db_u = Repo.os_user
error("WARNING: No db-type was specified, so db-user was"
" set to the default: {}".format(db_u))
pass
db_p = logic.get('db-password')
is_deleted = False
if msg is not None:
if "deleted" in msg:
is_deleted = True
if db_p is None:
error("WARNING: No db-password was specified, so the db"
" operation will be attempted without it."
" Success will depend on your database type and"
" settings.")
dstRepo = GiteaRepo(dstRepoUrl)
# print("* rewriting Gitea issue {}...".format(issue_no))
sys.exit(0) # Change based on return of the method.
if msg is not None: if msg is not None:
error(msg) error(msg)
if "deleted" in msg: if "deleted" in msg:

Loading…
Cancel
Save