poezio/src/common.py

199 lines
6.9 KiB
Python
Raw Normal View History

2011-09-06 00:45:53 +00:00
# Copyright 2010-2011 Florent Le Coz <louiz@louiz.org>
#
# This file is part of Poezio.
#
# Poezio is free software: you can redistribute it and/or modify
2011-09-11 15:10:05 +00:00
# it under the terms of the zlib license. See the COPYING file.
2010-02-13 15:18:39 +00:00
2010-05-18 13:29:02 +00:00
"""
various useful functions
"""
from datetime import datetime, timedelta
2010-02-13 15:18:39 +00:00
import base64
import os
import mimetypes
import hashlib
2010-02-14 03:51:03 +00:00
import subprocess
2010-03-18 19:43:44 +00:00
import curses
import time
import shlex
2010-03-18 19:43:44 +00:00
2011-07-03 00:06:40 +00:00
from config import config
ROOM_STATE_NONE = 11
ROOM_STATE_CURRENT = 10
ROOM_STATE_PRIVATE = 15
ROOM_STATE_MESSAGE = 12
ROOM_STATE_HL = 13
2010-02-13 15:18:39 +00:00
def get_base64_from_file(path):
2010-05-18 13:29:02 +00:00
"""
Convert the content of a file to base64
"""
2010-02-13 15:18:39 +00:00
if not os.path.isfile(path):
return (None, None, "File does not exist")
size = os.path.getsize(path)
if size > 16384:
return (None, None,"File is too big")
2010-05-18 13:29:02 +00:00
fdes = open(path, 'rb')
data = fdes.read()
2010-02-13 15:18:39 +00:00
encoded = base64.encodestring(data)
sha1 = hashlib.sha1(data).hexdigest()
mime_type = mimetypes.guess_type(path)[0]
return (encoded, mime_type, sha1)
2010-02-14 03:51:03 +00:00
def get_output_of_command(command):
2010-05-18 13:29:02 +00:00
"""
Runs a command and returns its output
"""
2010-02-14 03:51:03 +00:00
try:
2011-01-22 14:03:54 +00:00
return subprocess.check_output(command.split()).decode('utf-8').split('\n')
except subprocess.CalledProcessError:
2010-02-14 03:51:03 +00:00
return None
def is_in_path(command, return_abs_path=False):
"""
Return True if 'command' is found in one of the directories in the user's
path. If 'return_abs_path' is True, return the absolute path of the first
found command instead. Return False otherwise and on errors
"""
for directory in os.getenv('PATH').split(os.pathsep):
try:
if command in os.listdir(directory):
if return_abs_path:
return os.path.join(directory, command)
else:
return True
except OSError:
# If the user has non directories in his path
pass
return False
2010-05-18 13:29:02 +00:00
DISTRO_INFO = {
2010-02-14 03:51:03 +00:00
'Arch Linux': '/etc/arch-release',
'Aurox Linux': '/etc/aurox-release',
'Conectiva Linux': '/etc/conectiva-release',
'CRUX': '/usr/bin/crux',
'Debian GNU/Linux': '/etc/debian_version',
'Fedora Linux': '/etc/fedora-release',
'Gentoo Linux': '/etc/gentoo-release',
'Linux from Scratch': '/etc/lfs-release',
'Mandrake Linux': '/etc/mandrake-release',
'Slackware Linux': '/etc/slackware-version',
'Solaris/Sparc': '/etc/release',
'Source Mage': '/etc/sourcemage_version',
'SUSE Linux': '/etc/SuSE-release',
'Sun JDS': '/etc/sun-release',
'PLD Linux': '/etc/pld-release',
'Yellow Dog Linux': '/etc/yellowdog-release',
# many distros use the /etc/redhat-release for compatibility
# so Redhat is the last
'Redhat Linux': '/etc/redhat-release'
}
2010-05-18 13:29:02 +00:00
2010-02-14 03:51:03 +00:00
def get_os_info():
2010-05-18 13:29:02 +00:00
"""
Returns a detailed and well formated string containing
informations about the operating system
"""
if os.name == 'posix':
2010-02-14 03:51:03 +00:00
executable = 'lsb_release'
params = ' --description --codename --release --short'
full_path_to_executable = is_in_path(executable, return_abs_path = True)
if full_path_to_executable:
command = executable + params
2010-05-18 13:29:02 +00:00
process = subprocess.Popen([command], shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
close_fds=True)
process.wait()
output = process.stdout.readline().decode('utf-8').strip()
2010-02-14 03:51:03 +00:00
# some distros put n/a in places, so remove those
output = output.replace('n/a', '').replace('N/A', '')
return output
# lsb_release executable not available, so parse files
2010-05-18 13:29:02 +00:00
for distro_name in DISTRO_INFO:
path_to_file = DISTRO_INFO[distro_name]
2010-02-14 03:51:03 +00:00
if os.path.exists(path_to_file):
if os.access(path_to_file, os.X_OK):
# the file is executable (f.e. CRUX)
# yes, then run it and get the first line of output.
text = get_output_of_command(path_to_file)[0]
else:
2010-05-18 13:29:02 +00:00
fdes = open(path_to_file)
text = fdes.readline().strip() # get only first line
fdes.close()
2010-02-14 03:51:03 +00:00
if path_to_file.endswith('version'):
# sourcemage_version and slackware-version files
# have all the info we need (name and version of distro)
if not os.path.basename(path_to_file).startswith(
'sourcemage') or not\
os.path.basename(path_to_file).startswith('slackware'):
text = distro_name + ' ' + text
elif path_to_file.endswith('aurox-release') or \
path_to_file.endswith('arch-release'):
# file doesn't have version
text = distro_name
2010-05-18 13:29:02 +00:00
elif path_to_file.endswith('lfs-release'):
# file just has version
2010-02-14 03:51:03 +00:00
text = distro_name + ' ' + text
os_info = text.replace('\n', '')
return os_info
# our last chance, ask uname and strip it
uname_output = get_output_of_command('uname -sr')
if uname_output is not None:
os_info = uname_output[0] # only first line
return os_info
os_info = 'N/A'
return os_info
def datetime_tuple(timestamp):
"""
Convert timestamp using strptime and the format: %Y%m%dT%H:%M:%S
Because of various datetime formats are used the following exceptions
are handled:
- Optional milliseconds appened to the string are removed
- Optional Z (that means UTC) appened to the string are removed
- XEP-082 datetime strings have all '-' cahrs removed to meet
the above format.
"""
timestamp = timestamp.split('.')[0]
timestamp = timestamp.replace('-', '')
try:
ret = datetime.strptime(timestamp, '%Y%m%dT%H:%M:%SZ')
except ValueError: # Support the deprecated format, XEP 0091 :(
ret = datetime.strptime(timestamp, '%Y%m%dT%H:%M:%S')
# convert UTC to local time, with DST etc.
dst = timedelta(seconds=time.altzone)
ret -= dst
return ret
2011-05-19 18:38:12 +00:00
def shell_split(st):
sh = shlex.shlex(st, posix=True)
sh.whitespace_split = True
sh.quotes = '"'
ret = list()
try:
w = sh.get_token()
2011-05-19 18:38:12 +00:00
while w is not None:
ret.append(w)
w = sh.get_token()
return ret
except ValueError:
2011-05-19 18:38:12 +00:00
return st.split(" ")
def curses_color_pair(color):
if color < 0:
return curses.color_pair(-color) | curses.A_BOLD
return curses.color_pair(color)
2011-07-03 00:06:40 +00:00
def replace_key_with_bound(key):
if config.has_option('bindings', key):
return config.get(key, key, 'bindings')
else:
return key