From 01ced0b7ce47d279789efb2dc70d1cd009ac56ad Mon Sep 17 00:00:00 2001
From: davidovski <david@davidovski.xyz>
Date: Sat, 9 Oct 2021 22:20:41 +0100
Subject: initial commit

---
 scripts/.scripts/vfetch | 288 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 288 insertions(+)
 create mode 100755 scripts/.scripts/vfetch

(limited to 'scripts/.scripts/vfetch')

diff --git a/scripts/.scripts/vfetch b/scripts/.scripts/vfetch
new file mode 100755
index 0000000..e0018e3
--- /dev/null
+++ b/scripts/.scripts/vfetch
@@ -0,0 +1,288 @@
+#!/usr/bin/env python3
+
+from xdg.BaseDirectory import xdg_config_home
+from enum import Enum
+import subprocess
+import platform
+import distro
+import json
+import re
+import os
+import wmctrl
+
+colors = [
+    # Regular colors.
+    "\u001b[30m",
+    "\u001b[31m",
+    "\u001b[32m",
+    "\u001b[33m",
+    "\u001b[34m",
+    "\u001b[35m",
+    "\u001b[36m",
+    "\u001b[37m",
+
+    # Bright colors.
+    "\u001b[30;1m",
+    "\u001b[31;1m",
+    "\u001b[32;1m",
+    "\u001b[33;1m",
+    "\u001b[34;1m",
+    "\u001b[35;1m",
+    "\u001b[36;1m",
+    "\u001b[37;1m",
+
+    # Reset.
+    "\u001b[0m"
+]
+
+decorations = [
+    "\u001b[1m", # Bold.
+    "\u001b[4m", # Underline.
+    "\u001b[7m"  # Reversed.
+]
+
+# Creates a copy of the specified string with color and decorations added.
+def colored(string, colorIndex, decorationIndices=[]):
+    newString = colors[colorIndex]
+    for decorationIndex in decorationIndices:
+        newString += decorations[decorationIndex]
+    newString += string + colors[len(colors)-1]
+    return newString
+
+# Enum for the different data types.
+class Type(str, Enum):
+    os = 'os'
+    kernel = 'kernel'
+    wm = 'wm'
+    packages = 'packages'
+    uptime = 'uptime'
+
+# Enum for the different align modes.
+class AlignMode(str, Enum):
+    spaces = 'spaces'
+    center = 'center'
+
+# Loads the settings from the configuration file.
+# First checks for a configuration file in ~/.config/vfetch/vfetch.conf,
+# else it defaults to the configuration file in the same folder as the script.
+def loadSettings():
+    try:
+        file = open(xdg_config_home + '/vfetch/vfetch.conf', 'r')
+    except FileNotFoundError:
+        file = open(os.path.dirname(os.path.realpath(__file__)) + '/vfetch.conf', 'r')
+    content = file.read()
+    settings = json.loads(content)
+    file.close()
+    return settings
+
+# Prints string without ending with a new line.
+def printn(string):
+    print(string, end="")
+
+# Prints string at a specified position.
+def printAt(string, *position):
+    if len(position) == 1:
+        x = position[0][0]
+        y = position[0][1]
+    else:
+        x = position[0]
+        y = position[1]
+    printn("\x1b7\x1b[%d;%df%s\x1b8" % (y+1, x+1, string))
+
+# Prints the data lines.
+def printLines(lines, colorIndex, offsetX, offsetY, alignMode, alignSpace):
+    longestName = 0
+    dataPosition = 0
+
+    if alignMode is AlignMode.spaces:
+        for line in lines:
+            position = len(line[0]) + alignSpace
+            if position > dataPosition:
+                dataPosition = position
+    else:
+        # Finds the length of the longest name.
+        longestName = len(max(lines, key = lambda data: len(data[0]))[0])
+
+    y = 0
+    x = offsetX
+    # Prints the lines and formats them accordingly.
+    for line in lines:
+        if alignMode is AlignMode.spaces:
+            printAt(line[1], x + dataPosition, y+offsetY)
+        elif alignMode is AlignMode.center:
+            line[0] = ' ' * (longestName - len(line[0])) + line[0]
+
+        printAt(colored(line[0], colorIndex, [0]), x, y+offsetY)
+        if alignMode is AlignMode.center:
+            printAt(' ~ ' + line[1], x+len(line[0]), y+offsetY)
+        y += 1
+
+# Sets the cursor position.
+def setCursorPosition(*position, newLine=False):
+    if len(position) == 1:
+        x = position[0][0]
+        y = position[0][1]
+    else:
+        x = position[0]
+        y = position[1]
+    string = '\033[%d;%dH' % (y, x)
+    if newLine:
+        print(string)
+    else:
+        printn(string)
+
+# Runs the specified terminal command.
+def termRun(command, arguments):
+    output = subprocess.run([command, arguments], text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    return output.stdout
+
+# Prints ascii image.
+def printAscii(position, asciiImage):
+    setCursorPosition(position)
+    lines = asciiImage.split('\n')
+    for line in lines:
+        print(line)
+
+# Gets the operating system.
+def getOS(architecture=False, removeLinux=False):
+    os = distro.linux_distribution()[0]
+    if removeLinux:
+        os = re.sub('linux', '', os, flags=re.IGNORECASE)
+    os = os.rstrip()
+    if architecture:
+        os += ' ' + platform.machine()
+    return os
+
+# Gets the kernel.
+def getKernel(fullName=True):
+    kernel = platform.release()
+    if not fullName:
+        kernel = kernel.split('-')[0]
+    return kernel
+
+# Gets the window manager.
+def getWM():
+    try:
+        return wmctrl.os.environ.get('DESKTOP_SESSION')
+    except:
+        pass
+    try:
+        return wmctrl.os.environ.get('XDG_SESSION_DESKTOP')
+    except:
+        return None
+
+# Gets the number of packages.
+def getPackages(displayPackageManager=False):
+    try:
+        packages = termRun('pacman', '-Qq')
+        string = str(len(packages.split('\n')))
+        if displayPackageManager:
+            string += ' (pacman)'
+        return string
+    except:
+        return None
+
+# Gets the machine uptime.
+def getUptime():
+    with open('/proc/uptime', 'r') as f:
+        uptime_seconds = float(f.readline().split()[0])
+        hours = uptime_seconds / 3600
+        minutes = (hours - int(hours)) * 60
+        hours = int(hours)
+        minutes = int(minutes)
+        string = ''
+        if hours != 0:
+            string += str(hours) + 'h '
+        if minutes != 0 or hours == 0:
+            string += str(minutes) + 'm'
+    return string
+
+# Gets the data for the specified data type.
+def getData(type, settings):
+    data = {
+        Type.os: getOS(settings['displayArchitecture'], settings['removeLinux']),
+        Type.kernel: getKernel(settings['kernelFullName']),
+        Type.wm: getWM(),
+        Type.packages: getPackages(settings['displayPackageManager']),
+        Type.uptime: getUptime()
+    }.get(type, None)
+
+    if data is None:
+        return None
+
+    name = {
+        Type.os: [ 'OS', '' ],
+        Type.kernel: [ 'Kernel', '' ],
+        Type.wm: [ 'WM', '缾' ],
+        Type.packages: [ 'Packages', '' ],
+        Type.uptime: [ 'Uptime', '' ]
+    }.get(type, None)[int(settings['iconMode'])]
+
+    if settings['lowercase']:
+        name = name.lower()
+        data = data.lower()
+
+    return [name, data]
+
+# Gets the size of the specified ascii image.
+def asciiSize(asciiImage):
+    x = 0
+    split = asciiImage.split('\n')
+    for line in split:
+        if len(line) > x:
+            x = len(line)
+    return [x, len(split)]
+
+# Trims the specified ascii image of empty lines and trailing whitespaces.
+def trimAscii(asciiImage):
+    lines = asciiImage.split('\n')
+    string = ''
+    for line in lines:
+        trimmedString = line.rstrip()
+        if len(trimmedString) != 0:
+            string += trimmedString + '\n'
+    string = string[:-1] # Removes last newline.
+    return string
+
+# Loads the ascii image at the specified path.
+def loadAsciiImage(path):
+    file = open(path, 'r')
+    asciiImage = trimAscii(file.read())
+    file.close()
+    return asciiImage
+
+settings = loadSettings()
+
+displayAscii = settings['displayAscii']
+offset = settings['offset']
+
+# Loads the data lines. If the data is invalid (None) it does not get added.
+lines = []
+for dataType in settings['data']:
+    data = getData(dataType, settings)
+    if data is not None:
+        lines.append(data)
+
+# Loads the ascii image if the option is set for it.
+if displayAscii:
+    asciiImage = loadAsciiImage(settings['asciiImage'])
+    size = asciiSize(asciiImage)
+    offset[0] += size[0]
+    finalPosition = [0, size[1]]
+else:
+    finalPosition = [0, len(lines)+offset[1]]
+
+# Makes the prompt after the script finishes have a blank line before it.
+finalPosition[1] += 1
+
+os.system('clear')
+
+if displayAscii:
+    printAscii([0,0], asciiImage)
+
+alignMode = AlignMode(settings['alignMode'])
+
+printLines(lines, settings['colorIndex'], offset[0], offset[1], alignMode, settings['alignSpace'])
+
+# Sets the final cursor position for the prompt to end up at.
+setCursorPosition(finalPosition, newLine=True)
-- 
cgit v1.2.1