Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- """
- NAME
- hb - Uploads data to a hastebin server
- SYNOPSYS
- hb [OPTION]... [FILE]...
- DESCRIPTION
- When invoked without any file name, hb will reads from standard
- input. If the caller supplies the file names, each of them will be
- uploaded separately. Upon completion, hb will print to the standard
- output the URL for each upload.
- -h, --help
- Displays help and exit
- CONFIGURATION
- By default, hb will upload to http://localhost:7777. If you
- want to upload to a different server, there are three ways to
- configure it.
- The first is to create a configuration file in the same directory
- of the script and name it `hb.json`. In a multiple-user
- environment, this configuration is meant to be global to all
- the users.
- The second is to create a per-user configuration file in
- `~/.hb.json`.
- Below is an example of such configuration file:
- {
- "HASTE_SERVER": "http://my-hastebin.com"
- }
- The third is to use an environment variable. Here is an example
- for the bash shell:
- export HASTE_SERVER=http://my-hastebin.com
- Below is the order of look-up to find the server, with the
- environment variable having the highest precedence:
- 1. The environment variable
- 2. The global configuration file
- 3. The per-user configuration file
- 4. If all failed, use http://localhost:7777
- LOG
- hb keeps a log of all the URLs in ~/.hb.log
- AUTHOR
- Written by Hai Vu (haivu2004 at gmail dot com)
- """
- import collections
- import json
- import logging
- import os
- import pathlib
- import sys
- import urllib.request
- logging.basicConfig(level=os.getenv('LOGLEVEL', 'WARN'))
- LOGGER = logging.getLogger(__name__)
- CONFIG = {
- 'HASTE_SERVER': 'http://localhost:7777'
- }
- def read_config_file(path):
- """
- Reads the user configuration from `path` and returns a dictionary.
- If the configuration file is not found, returns an empty
- dictionary.
- """
- try:
- with open(path, encoding='utf-8') as file_handle:
- config = json.load(file_handle)
- except FileNotFoundError:
- config = dict()
- return config
- def get_server_url():
- """
- Returns the server URL in the following search order. See the
- document above for search order.
- """
- user_config = read_config_file(pathlib.Path('~/.hb.json').expanduser())
- global_config_path = pathlib.Path(__file__).with_name('hb.json')
- global_config = read_config_file(global_config_path)
- all_configs = collections.ChainMap(
- os.environ,
- user_config,
- global_config,
- CONFIG)
- server_url = all_configs['HASTE_SERVER']
- if server_url.endswith('/'):
- server_url = server_url.rstrip('/')
- LOGGER.debug('Server URL: %s', server_url)
- return server_url
- def truncate(text):
- """
- given some text, truncate it to a certain size for display and
- replace all the new lines with spaces
- """
- return text[:40].replace('\n', ' ')
- def upload(url, data):
- """
- Upload the data to the hastebin server. The `url` parameter indicates the
- server's URL, e.g. 'https://hastebin.com'. The `data` parameter can either
- be a string, a bytes stream, or a file-like object serving raw bytes. Upon
- completion, the function returns a dictionary in which the key `key` will
- provide the token for locating the paste, e.g. `{"key": "xyz"}`. The caller
- can combine the server url with this key to create the full URL for
- accessing the paste, e.g. https://hastebin.com/xyz.
- """
- url = f'{url}/documents'
- if isinstance(data, str):
- data = data.encode('utf-8')
- request = urllib.request.Request(url, data)
- with urllib.request.urlopen(request) as response:
- output = json.load(response)
- return output
- def upload_wrapper(url, filename=None):
- """
- Uploads a file and perform other administrative tasks
- """
- if filename is None:
- data = sys.stdin.read()
- preview = truncate(data)
- else:
- data = open(filename, 'rb')
- preview = truncate(data.read(40).decode('utf-8'))
- data.seek(0)
- output = upload(url, data)
- output_url = f'{url}/{output["key"]}'
- log_file = pathlib.Path('~/.hb.log').expanduser()
- with open(log_file, 'a', encoding='utf-8') as file_handle:
- if filename is None:
- filename = 'stdin'
- output = f'{filename} - {output_url} - {preview}'
- print(output)
- file_handle.write(output)
- file_handle.write('\n')
- def show_usage():
- """
- Show the usage
- """
- print(__doc__)
- def main():
- """ Entry """
- server_url = get_server_url()
- if len(sys.argv) > 1:
- if sys.argv[1] in {'-h', '--help'}:
- show_usage()
- return
- for filename in sys.argv[1:]:
- upload_wrapper(server_url, filename)
- else:
- upload_wrapper(server_url)
- if __name__ == '__main__':
- main()
Add Comment
Please, Sign In to add comment