#!/usr/bin/env python3
# ------------------------------------------------------------------------------
# shorten-url.py
# ==============
#
# Scope Native
# Copyright (C) 2024 by RaySoft, Zurich, Switzerland
# License GNU General Public License (GPL) 2.0
# https://www.gnu.org/licenses/gpl2.txt
#
# ------------------------------------------------------------------------------
BITLY_QUERY_URL = 'https://bit.ly/'
BITLY_POST_URL = 'https://api-ssl.bitly.com/v4/shorten'
BITLY_API_KEY = '******************************'
# ------------------------------------------------------------------------------
PROGRAM_NAME = 'shorten-url'
PROGRAM_VERSION = '0.3'
# ------------------------------------------------------------------------------
from argparse import ArgumentParser, FileType
from itertools import chain
from json import loads
from re import compile
from sys import exit, stderr
import urllib.error
from urllib.parse import quote_plus
from urllib.request import urlopen
# ------------------------------------------------------------------------------
def main():
parser = ArgumentParser(
description=f'Shorten URLs with Bitly URL shortener ({BITLY_QUERY_URL})',
prog=PROGRAM_NAME,
)
parser.add_argument(
'-V', '--version', action='version',
version=f'%(prog)s {PROGRAM_VERSION}',
)
parser.add_argument(
'-n', '--nobr', action='store_true',
help='print the output without a line break',
)
group1 = parser.add_mutually_exclusive_group(required=True)
group1.add_argument(
'-u', '--url', metavar='URL', action='append', nargs='+',
help='Read URL(s) from command line',
)
group1.add_argument(
'-f', '--file', metavar='FILE', action='append', nargs='+',
type=FileType(mode='r', encoding='UTF-8'),
help='Read URL(s) from a file(s). Use a dash (-) to read from stdin',
)
args = parser.parse_args()
urls = []
if args.url and len(args.url) > 0:
urls = list(chain.from_iterable(args.url))
elif args.file and len(args.file) > 0:
files = list(chain.from_iterable(args.file))
for file in files:
for line in file.readlines():
urls.append(line.strip())
url_regex = compile(
r'^https?://'
r'(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+'
r'(?:[a-z]{2,6}\.?|[a-z0-9-]{2,}\.?)'
r'(?::\d+)?'
r'(?:/?|[/?]\S+)$'
)
headers = {
'Authorization': f'Bearer {BITLY_API_KEY}',
'Content-Type': 'application/json',
}
for url in urls:
url.lower()
if not url_regex.match(url):
print(f'{PROGRAM_NAME}: error', file=stderr)
return 1
req = urllib.request.Request(
BITLY_POST_URL, data=f'{{ "long_url": "{url}" }}'.encode(),
headers=headers,
)
with urlopen(req) as response:
obj = response.read().decode('utf-8')
end = '\n'
if args.nobr:
end = ''
print(loads(obj)['link'], end=end)
return 0
# ------------------------------------------------------------------------------
if __name__ == '__main__':
return_value = main()
exit(return_value)
~/dev/shorten-url --url='https://www.rpl.ch' --url='https://www.raysoft.ch'
~/dev/shorten-url --file=- <<<'https://www.raysoft.ch'
echo 'https://www.raysoft.ch' | ~/dev/shorten-url --file=-
~/dev/shorten-url --file="${HOME}/tmp/urls-1.txt" --file="${HOME}/tmp/urls-2.txt"
cat "${HOME}/tmp/urls-1.txt" "${HOME}/tmp/urls-2.txt" | ~/dev/shorten-url --file=-