first commit

This commit is contained in:
Alnus Tmp 2021-12-19 18:15:08 -05:00
commit 8b02d3c4f1
9 changed files with 511 additions and 0 deletions

218
.gitignore vendored Normal file
View File

@ -0,0 +1,218 @@
# ---> Python
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
*.bk
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# ---> Emacs
# -*- mode: gitignore; -*-
*~
\#*\#
/.emacs.desktop
/.emacs.desktop.lock
*.elc
auto-save-list
tramp
.\#*
# Org-mode
.org-id-locations
*_archive
# flymake-mode
*_flymake.*
# eshell files
/eshell/history
/eshell/lastdir
# elpa packages
/elpa/
# reftex files
*.rel
# AUCTeX auto folder
/auto/
# cask packages
.cask/
dist/
# Flycheck
flycheck_*.el
# server auth directory
/server/
# projectiles files
.projectile
# directory configuration
.dir-locals.el
# network security
/network-security.data
# ---> Vim
# Swap
[._]*.s[a-v][a-z]
!*.svg # comment out if you don't need vector files
[._]*.sw[a-p]
[._]s[a-rt-v][a-z]
[._]ss[a-gi-z]
[._]sw[a-p]
# Session
Session.vim
Sessionx.vim
# Temporary
.netrwhist
*~
# Auto-generated tag files
tags
# Persistent undo
[._]*.un~
# ---> VirtualEnv
# Virtualenv
# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
.Python
[Bb]in
[Ii]nclude
[Ll]ib
[Ll]ib64
[Ll]ocal
[Ss]cripts
pyvenv.cfg
.venv
pip-selfcheck.json

14
COPYRIGHT Normal file
View File

@ -0,0 +1,14 @@
Copyright (C) 2021 Alnus Tmp <alnus@disroot.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

0
HISTORY.rst Normal file
View File

32
LICENSE Normal file
View File

@ -0,0 +1,32 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Multi migrate git to Gitea
Copyright (C) 2019 Jovany Leandro G.C
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

0
README.md Normal file
View File

0
README.rst Normal file
View File

0
__init__.py Normal file
View File

203
migrate_to_gitea.py Normal file
View File

@ -0,0 +1,203 @@
import requests
import json
import click
__provider_git = {
'bitbucket' : {
'host' : 'https://api.bitbucket.org',
'page_url' : '%s/2.0/repositories/%s?pagelen=100&fields=next,values.slug,values.links',
'next_page_url' : None,
'repo_name' : 'slug',
'repo_url' : None,},
'github' : {
'host' : 'https://api.github.com',
'page_url' : '%s/orgs/%s/repos?&per_page=100&page=1',
'next_page_url' : '%s/orgs/%s/repos?&per_page=100&page=%s',
'repo_name' : 'name',
'repo_url' : 'clone_url',},
'github_user' : {
'host' : 'https://api.github.com',
'page_url' : '%s/users/%s/repos?&per_page=100&page=1',
'next_page_url' : '%s/users/%s/repos?&per_page=100&page=%s',
'repo_name' : 'name',
'repo_url' : 'clone_url',},
'gitlab' : {
'host' : 'https://gitlab.com/api/v4/groups/',
'page_url' : '%s/%s/projects?per_page=100&page=1',
'next_page_url' : '%s/%s/projects?per_page=100&page=%s',
'repo_name' : 'name',
'repo_url' : 'web_url', },
}
@click.group()
def cli():
pass
def listRepos(provider_git, team_org, verbose = False):
count = 1
host = __provider_git[provider_git]['host']
repo_name = __provider_git[provider_git]['repo_name']
page_url = __provider_git[provider_git]['page_url'] % (host, team_org)
response = requests.get(page_url)
page_json = response.json()
repos = {}
print(page_url)
if provider_git == 'bitbucket':
while page_url is not None:
response = requests.get(page_url)
page_json = response.json()
# Parse repositories from the JSON
if "error" not in page_json:
for repo in page_json['values']:
if verbose:
print(repo[repo_name])
repos[repo[repo_name]] = repo['links']['clone'][0]['href']
page_url = page_json.get('next', None)
else:
page_url = None
else:
while len(page_json) >= count:
for repo in page_json:
if isinstance(repo, dict):
if verbose:
print(repo[repo_name])
repo_url = repo[__provider_git[provider_git]['repo_url']]
repos[repo[repo_name]] = repo_url
count += 1
next_page_url = __provider_git[provider_git]['next_page_url'] % (host, team_org, count)
response = requests.get(next_page_url)
page_json = response.json()
return repos
class Gitea():
def listORGS(host, headers = None):
ORGS_URI = "/orgs"
ENDPOINT_ORGS = "%s%s" % (host, ORGS_URI)
try:
r = requests.get(url=url, headers=headers)
if r.status_code != 200:
return r.content
else:
return "Done: %s" % (r.content)
except Not_Connect:
print("Fail")
def listRepo(host, team, headers, verbose = False):
next_page_url = '%s/orgs/%s/repos?page=1&limit=50' % (host, team)
response = requests.get(next_page_url, headers = headers)
page_json = response.json()
count = 1
repos = {}
while len(page_json) >= count:
for repo in page_json:
if isinstance(repo, dict):
if verbose:
print(repo['name'])
repos[repo['name']] = repo['clone_url']
count += 1
next_page_url = '%s/orgs/%s/repos?limit=50&page=%s' % (host, team, count)
response = requests.get(next_page_url, headers = headers)
page_json = response.json()
return repos
def foundBranch(url, branch, headers = None, repo = None):
url_branch = "%s/%s/branches/%s" % (url, repo, branch)
try:
r = requests.get(url=url_branch, headers=headers)
if r.status_code == 200:
return repo
except Not_Connect:
print("Fail")
def createMirror(team, clone_addr, repo_name, uid, private, url, headers = None):
migrate_data = {}
migrate_data["mirror"] = True
migrate_data["UID"] = uid
migrate_data["repo_name"] = repo_name
migrate_data["clone_addr"] = clone_addr
migrate_data["private"] = private
migrate_data["repo_owner"] = team
try:
r = requests.post(url=url, data=json.dumps(migrate_data), headers=headers)
if r.status_code != 200 or r.status_code != 201:
return "Non-OK Response: %s" % (r.content)
else:
return "Done: %s" % (r.status_code)
except Not_Connect:
print("Fail")
@click.command()
@click.option('--provider_git',
type=click.Choice([*__provider_git],
case_sensitive=False),
required=True)
@click.option('--team_org', required=True)
@click.option('--verbose', default=False)
def list_repo(provider_git, team_org, verbose):
listRepos(provider_git, team_org, verbose)
@click.command()
@click.option('--domain', required=True)
@click.option('--team_org', required=True)
@click.option('--access_token', default=None)
def list_repo_token(domain, team_org, access_token):
HOST = "https://%s/api/v1" % (domain)
HEADERS = { "accept": "application/json", "content-type": "application/json" }
HEADERS["Authorization"] = "token %s" % (access_token)
Gitea.listRepo(host = HOST, team = team_org, headers = HEADERS)
@click.command()
@click.option('--domain', required=True)
@click.option('--provider_git',
type=click.Choice([*__provider_git],
case_sensitive=False),
required=True)
@click.option('--team_org_source', required=True)
@click.option('--team_org_dest', required=True)
@click.option('--access_token', default=None)
@click.option('--private', default=True)
@click.option('--verbose', default=False)
def mirror_repo(domain, provider_git, team_org_source,
team_org_dest, access_token, private, verbose):
repos = listRepos(provider_git, team_org_source, verbose)
HOST = "https://%s/api/v1" % (domain)
MIGRATE_URI = "/repos/migrate"
ENDPOINT_MIGRATE = "%s%s" % (HOST, MIGRATE_URI)
HEADERS = { "accept": "application/json", "content-type": "application/json" }
HEADERS["Authorization"] = "token %s" % (access_token)
count = 0
for repo in repos:
count += 1
print(Gitea.createMirror(team_org_dest, repos[repo],
repo, 1, private, ENDPOINT_MIGRATE, headers = HEADERS))
@click.command()
@click.option('--domain', required=True)
@click.option('--team_org', required=True)
@click.option('--access_token', default=None)
@click.option('--private', default=True)
@click.option('--branch', required=True)
def get_branch_repo_gitea(domain, team_org, access_token,
private, branch):
HOST = "https://%s/api/v1" % (domain)
BRANCH_URI = "/repos/%s" % (team_org)
ENDPOINT_BRANCH = "%s%s" % (HOST, BRANCH_URI)
HEADERS = { "accept": "application/json", "content-type": "application/json" }
HEADERS["Authorization"] = "token %s" % (access_token)
repos = Gitea.listRepo(HOST, team_org, HEADERS)
for repo in repos:
if Gitea.foundBranch(ENDPOINT_BRANCH, branch, HEADERS, repo):
print(repo)
cli.add_command(list_repo)
cli.add_command(list_repo_token)
cli.add_command(mirror_repo)
cli.add_command(get_branch_repo_gitea)
if __name__ == '__main__':
cli()

44
setup.py Normal file
View File

@ -0,0 +1,44 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from setuptools import setup, find_packages
with open('README.md') as readme_file:
readme = readme_file.read()
with open('HISTORY.rst') as history_file:
history = history_file.read()
requirements = ['Click==8.0.3',
'requests==2.26.0']
setup(
author="Alnus Tmp",
author_email='alnus@disroot.org',
classifiers=[
'Development Status :: 2 - Pre-Alpha',
'Intended Audience :: Developers',
'License :: OSI Approved :: GNU General Public License v3 (GPLv3)',
'Natural Language :: English',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
],
description="Multi migrate git hosted to Gitea",
py_modules=['migrate_to_gitea'],
entry_points={
'console_scripts': [
'migrate_to_gitea=migrate_to_gitea:cli',
],
},
install_requires=requirements,
license="GNU General Public License v3",
long_description=readme + '\n\n' + history,
long_description_content_type='text/x-rst',
keywords='migrate, gitea',
name='multimigrate_to_gitea',
url='https://github.com/bit4bit/facho',
version='0.1.0'
)