#!/usr/bin/python import sys import getopt import subprocess import pathlib import time import os import requests import uuid import urllib.parse import json import pyperclip from config import SCREENSHOT_CONFIG from pychee import pychee def usage(path): print('A tiny wrapper around maim to take screenshots and save or upload them (+ copy link in clipboard).\n') print('The default behaviour is : nothing.') print('Usage:') print('\t' + sys.argv[0] + ' [--upload] [--save] [--path=]') print('\t' + sys.argv[0] + ' --help') print('\nOptions:') print('\t-h --help \tShow this screen.') print('\t-u --upload \tUpload to server and copy link to clipboard.') print('\t\t\tOnly Lychee Laravel server is supported for now.') print('\t-s --save\tSave locally.') print('\t-p --path\tPath where to save locally [default: ' + path +'].') def read_args(argv): path = SCREENSHOT_CONFIG['default_path'] try: opts, _ = getopt.getopt(argv, "husp:", ["help", "upload", "save", "path="]) except getopt.GetoptError: usage(path) upload = False save = False for opt, _ in opts: if opt in ('-h', '--help'): usage(path) elif opt in ('-u', '--upload'): upload = True elif opt in ('-s', '--save'): save = True elif opt in ('-p', '--path'): path = opt # Expand path if there is a ~ inside path = os.path.expanduser(path) return (upload, save, path) def screenshot(img_format): output = '/tmp/screenshot' proc = subprocess.run(['maim', '-sl', '--color=0.6,0.4,0.2,0.2', '-f', img_format, '-u', '-m', '9', '-b', '5', output], check=True) with open(output, 'rb') as f: return f.read() def save_img(path, img, img_format): # Create directory if needed pathlib.Path(path).mkdir(parents=True, exist_ok=True) # Get date formatted with second granularity date = time.strftime("%Y-%m-%d_%H-%M-%S") # Write image to appropriate file. # We get binary from maim, so open in binary mode filepath = os.path.join(path, date + '.' + img_format) with open(filepath, 'wb') as f: f.write(img) return filepath def login(): client = pychee.LycheeClient(SCREENSHOT_CONFIG['base_url']) client.login(SCREENSHOT_CONFIG['user'], SCREENSHOT_CONFIG['password']) return client def get_album_id(client, name): albums = client.get_albums() for album in albums['albums']: if album['title'] == name: return album['id'] raise RuntimeError("No album " + name + " found!") def upload_image(client, album_id, binary_img, img_format): return client.add_photo(binary_img, str(uuid.uuid4()) + '.' + img_format, album_id) def get_image_direct_link(client, image_id): return SCREENSHOT_CONFIG['base_url'] + '/' + client.get_photo(image_id)['url'] def main(argv): upload, save, path = read_args(argv) # If we upload the file, set format to jpg, even if we save the screenshot after img_format = SCREENSHOT_CONFIG['upload_format'] if upload else SCREENSHOT_CONFIG['save_format'] if upload or save: try: img = screenshot(img_format) if save: final_path = save_img(path, img, img_format) pyperclip.copy(final_path) subprocess.run(['notify-send', '-u', 'low', '-i', 'Info', '-a', 'Screenchost', 'Screenshot taken', 'Path copied to clipboard!']) if upload: s = login() album_id = get_album_id(s, SCREENSHOT_CONFIG['album_name']) image_id = upload_image(s, album_id, img, img_format) image_link = get_image_direct_link(s, image_id) pyperclip.copy(image_link) subprocess.run(['notify-send', '-u', 'low', '-i', 'Info', '-a', 'Screenchost', 'Screenshot uploaded', 'Link copied to clipboard!']) except subprocess.CalledProcessError as e: print("Screenshot taking has failed {0}".format(e)) if __name__ == "__main__": main(sys.argv[1:])