Make brid smaller, add icons, make colours nicer + small opti
All checks were successful
PikaOS Package Build & Release (amd64-v3) / build (push) Successful in 51s

This commit is contained in:
ferreo 2024-12-04 21:28:57 +00:00
parent a281ba0bd0
commit 912e6c7189
10 changed files with 75 additions and 123 deletions

View File

@ -1 +1 @@
1 2

View File

@ -6,7 +6,7 @@ set -e
echo "$PIKA_BUILD_ARCH" > pika-build-arch echo "$PIKA_BUILD_ARCH" > pika-build-arch
VERSION="0.3.0" VERSION="0.4.0"
cd ./pikafetch/ cd ./pikafetch/

View File

@ -1,10 +1,15 @@
pikafetch (0.4.0-101pika5) pika; urgency=medium
* Smol birb
-- ferreo <harderthanfire@gmail.com> Wed, 18 Jan 2023 21:48:14 +0000
pikafetch (0.3.0-101pika5) pika; urgency=medium pikafetch (0.3.0-101pika5) pika; urgency=medium
* Multiple disk support, add caching of GPU and packages info * Multiple disk support, add caching of GPU and packages info
-- ferreo <harderthanfire@gmail.com> Wed, 18 Jan 2023 21:48:14 +0000 -- ferreo <harderthanfire@gmail.com> Wed, 18 Jan 2023 21:48:14 +0000
pikafetch (0.2.0-101pika3) pika; urgency=medium pikafetch (0.2.0-101pika3) pika; urgency=medium
* Move to zig nightly, remove all use of libc, switch to using arena allocator * Move to zig nightly, remove all use of libc, switch to using arena allocator

View File

@ -3,22 +3,18 @@ const colors = @import("colors.zig");
pub fn getArt() []const []const u8 { pub fn getArt() []const []const u8 {
return &[_][]const u8{ return &[_][]const u8{
colors.Color.yellow ++ colors.Color.bold ++ " - " ++ colors.Color.reset, colors.Color.yellow ++ colors.Color.bold ++ " - " ++ colors.Color.reset,
colors.Color.yellow ++ colors.Color.bold ++ " ---------------- " ++ colors.Color.reset, colors.Color.yellow ++ colors.Color.bold ++ " ------------ " ++ colors.Color.reset,
colors.Color.yellow ++ colors.Color.bold ++ " ------------------ " ++ colors.Color.reset, colors.Color.yellow ++ colors.Color.bold ++ " -------------" ++ colors.Color.reset,
colors.Color.yellow ++ colors.Color.bold ++ " -------------------" ++ colors.Color.reset, colors.Color.yellow ++ colors.Color.bold ++ "-- -----=*-=--#####" ++ colors.Color.reset,
colors.Color.yellow ++ colors.Color.bold ++ "-- -----------=*-=----#####" ++ colors.Color.reset, colors.Color.yellow ++ colors.Color.bold ++ "----------------------###-=####" ++ colors.Color.reset,
colors.Color.yellow ++ colors.Color.bold ++ "-----------------------------####--=######" ++ colors.Color.reset, colors.Color.yellow ++ colors.Color.bold ++ "-----------------------+---+#" ++ colors.Color.reset,
colors.Color.yellow ++ colors.Color.bold ++ "------------------------------++---+####" ++ colors.Color.reset, colors.Color.yellow ++ colors.Color.bold ++ "=========----------=+=-----" ++ colors.Color.reset,
colors.Color.yellow ++ colors.Color.bold ++ "=============----------------=+=-----" ++ colors.Color.reset, colors.Color.yellow ++ colors.Color.bold ++ "==========-------####+-----" ++ colors.Color.reset,
colors.Color.yellow ++ colors.Color.bold ++ "=================-----------####+----" ++ colors.Color.reset, colors.Color.yellow ++ colors.Color.bold ++ "===========------*###=---" ++ colors.Color.reset,
colors.Color.yellow ++ colors.Color.bold ++ "==================----------*###=----" ++ colors.Color.reset, colors.Color.yellow ++ colors.Color.bold ++ "============------------" ++ colors.Color.reset,
colors.Color.yellow ++ colors.Color.bold ++ "===================-----------------" ++ colors.Color.reset, colors.Color.yellow ++ colors.Color.bold ++ " ===========----------" ++ colors.Color.reset,
colors.Color.yellow ++ colors.Color.bold ++ " ==================-----------------" ++ colors.Color.reset, colors.Color.yellow ++ colors.Color.bold ++ " =========-----::::" ++ colors.Color.reset,
colors.Color.yellow ++ colors.Color.bold ++ " =================----------------" ++ colors.Color.reset, colors.Color.yellow ++ colors.Color.bold ++ " =====--::::::::" ++ colors.Color.reset,
colors.Color.yellow ++ colors.Color.bold ++ " ===============------------::::" ++ colors.Color.reset, colors.Color.yellow ++ colors.Color.bold ++ " .::::::::." ++ colors.Color.reset,
colors.Color.yellow ++ colors.Color.bold ++ " ============-:::::::::::::::" ++ colors.Color.reset,
colors.Color.yellow ++ colors.Color.bold ++ " =======--:::::::::::::::" ++ colors.Color.reset,
colors.Color.yellow ++ colors.Color.bold ++ " .::::::::::::::::. " ++ colors.Color.reset,
colors.Color.yellow ++ colors.Color.bold ++ " ::::::: " ++ colors.Color.reset,
}; };
} }

View File

@ -1,4 +1,4 @@
pub const margin_width = 4; pub const margin_width = 2;
pub const gap_width = 4; pub const gap_width = 2;
pub const max_art_length = 46; pub const max_art_length = 33;
pub const color_seq_len = "\x1b[33m\x1b[1m".len; pub const color_seq_len = "\x1b[33m\x1b[1m".len;

View File

@ -6,7 +6,7 @@ const terminal = @import("terminal.zig");
pub fn printDisplay(writer: anytype, info_lines: []const []const u8, term_size: terminal.TermSize) !void { pub fn printDisplay(writer: anytype, info_lines: []const []const u8, term_size: terminal.TermSize) !void {
const art_lines = ascii_art.getArt(); const art_lines = ascii_art.getArt();
var line_buf: [512]u8 = undefined; var line_buf: [256]u8 = undefined;
var i: usize = 0; var i: usize = 0;
while (i < @max(art_lines.len, info_lines.len)) : (i += 1) { while (i < @max(art_lines.len, info_lines.len)) : (i += 1) {
@ -31,8 +31,9 @@ pub fn printDisplay(writer: anytype, info_lines: []const []const u8, term_size:
pos += padding; pos += padding;
} }
} else { } else {
@memset(line_buf[pos..][0..layout.max_art_length], ' '); const padding = layout.max_art_length - 2;
pos += layout.max_art_length; @memset(line_buf[pos..][0..padding], ' ');
pos += padding;
} }
@memset(line_buf[pos..][0..layout.gap_width], ' '); @memset(line_buf[pos..][0..layout.gap_width], ' ');
@ -40,57 +41,37 @@ pub fn printDisplay(writer: anytype, info_lines: []const []const u8, term_size:
if (i < info_lines.len) { if (i < info_lines.len) {
const info_line = info_lines[i]; const info_line = info_lines[i];
if (std.mem.startsWith(u8, info_line, "\x1b[") and std.mem.indexOf(u8, info_line, "███") != null) {
@memcpy(line_buf[pos..][0..info_line.len], info_line);
pos += info_line.len;
} else {
var visible_info_len: usize = 0;
var j: usize = 0;
var last_color_seq_start: ?usize = null;
var in_escape = false;
var last_safe_pos: usize = 0;
const available_width = if (term_size.cols > (layout.margin_width + layout.max_art_length + layout.gap_width)) const available_width = if (term_size.cols > (layout.margin_width + layout.max_art_length + layout.gap_width))
term_size.cols - (layout.margin_width + layout.max_art_length + layout.gap_width) term_size.cols - (layout.margin_width + layout.max_art_length + layout.gap_width)
else else
0; 0;
if (std.mem.indexOf(u8, info_line, "") != null) {
@memcpy(line_buf[pos..][0..info_line.len], info_line);
pos += info_line.len;
} else {
var visible_len: usize = 0;
var j: usize = 0;
var in_escape = false;
while (j < info_line.len) : (j += 1) { while (j < info_line.len) : (j += 1) {
if (info_line[j] == '\x1b') { if (info_line[j] == '\x1b') {
in_escape = true; in_escape = true;
last_color_seq_start = j;
continue; continue;
} }
if (in_escape) { if (in_escape) {
if (info_line[j] == 'm') { if (info_line[j] == 'm') in_escape = false;
in_escape = false;
last_safe_pos = j + 1;
}
continue; continue;
} }
visible_info_len += 1; visible_len += 1;
if (!in_escape) { if (visible_len > available_width) break;
last_safe_pos = j + 1;
}
if (visible_info_len > available_width) break;
} }
if (j < info_line.len) { if (j < info_line.len) {
@memcpy(line_buf[pos..][0..last_safe_pos], info_line[0..last_safe_pos]); @memcpy(line_buf[pos..][0..j], info_line[0..j]);
pos += last_safe_pos; pos += j;
var needs_reset = false;
var k: usize = 0;
while (k < last_safe_pos) : (k += 1) {
if (info_line[k] == '\x1b') {
needs_reset = true;
}
}
if (needs_reset) {
@memcpy(line_buf[pos..][0..4], "\x1b[0m"); @memcpy(line_buf[pos..][0..4], "\x1b[0m");
pos += 4; pos += 4;
}
} else { } else {
@memcpy(line_buf[pos..][0..info_line.len], info_line); @memcpy(line_buf[pos..][0..info_line.len], info_line);
pos += info_line.len; pos += info_line.len;

View File

@ -1,7 +1,6 @@
const std = @import("std"); const std = @import("std");
pub fn getMotherboard(allocator: std.mem.Allocator) ![]const u8 { pub fn getMotherboard(allocator: std.mem.Allocator) ![]const u8 {
// Try board_name first as it's usually more reliable
const board_name = try std.fs.openFileAbsolute("/sys/class/dmi/id/board_name", .{}); const board_name = try std.fs.openFileAbsolute("/sys/class/dmi/id/board_name", .{});
defer board_name.close(); defer board_name.close();
@ -9,7 +8,6 @@ pub fn getMotherboard(allocator: std.mem.Allocator) ![]const u8 {
const size = try board_name.readAll(&buffer); const size = try board_name.readAll(&buffer);
const name = std.mem.trim(u8, buffer[0..size], "\n\r "); const name = std.mem.trim(u8, buffer[0..size], "\n\r ");
// If board_name is empty or generic, try product_name as fallback
if (name.len == 0) { if (name.len == 0) {
const product_name = try std.fs.openFileAbsolute("/sys/class/dmi/id/product_name", .{}); const product_name = try std.fs.openFileAbsolute("/sys/class/dmi/id/product_name", .{});
defer product_name.close(); defer product_name.close();

View File

@ -119,19 +119,19 @@ pub const SystemInfo = struct {
try info.appendSlice(&[_][]const u8{ try info.appendSlice(&[_][]const u8{
try std.fmt.allocPrint(output_allocator, "{s}{s}@{s}{s}", .{ colors.Color.yellow, self.username, self.hostname, colors.Color.reset }), try std.fmt.allocPrint(output_allocator, "{s}{s}@{s}{s}", .{ colors.Color.yellow, self.username, self.hostname, colors.Color.reset }),
try std.fmt.allocPrint(output_allocator, "{s}------------{s}", .{ colors.Color.yellow, colors.Color.reset }), try std.fmt.allocPrint(output_allocator, "{s}------------{s}", .{ colors.Color.yellow, colors.Color.reset }),
try std.fmt.allocPrint(output_allocator, "{s}OS:{s} {s}", .{ colors.Color.bold, colors.Color.reset, self.os_name }), try std.fmt.allocPrint(output_allocator, "{s}󰨇 OS:{s} {s}", .{ colors.Color.yellow, colors.Color.reset, self.os_name }),
try std.fmt.allocPrint(output_allocator, "{s}Host:{s} {s}", .{ colors.Color.bold, colors.Color.reset, self.host }), try std.fmt.allocPrint(output_allocator, "{s}󰌢 Host:{s} {s}", .{ colors.Color.yellow, colors.Color.reset, self.host }),
try std.fmt.allocPrint(output_allocator, "{s}Kernel:{s} {s}", .{ colors.Color.bold, colors.Color.reset, self.kernel }), try std.fmt.allocPrint(output_allocator, "{s}Kernel:{s} {s}", .{ colors.Color.yellow, colors.Color.reset, self.kernel }),
try std.fmt.allocPrint(output_allocator, "{s}Packages:{s} {d} (native)", .{ colors.Color.bold, colors.Color.reset, self.packages }), try std.fmt.allocPrint(output_allocator, "{s}󰏗 Packages:{s} {d} (native)", .{ colors.Color.yellow, colors.Color.reset, self.packages }),
try std.fmt.allocPrint(output_allocator, "{s}Shell:{s} {s}", .{ colors.Color.bold, colors.Color.reset, self.shell_name }), try std.fmt.allocPrint(output_allocator, "{s}Shell:{s} {s}", .{ colors.Color.yellow, colors.Color.reset, self.shell_name }),
try std.fmt.allocPrint(output_allocator, "{s}WM:{s} {s}", .{ colors.Color.bold, colors.Color.reset, self.wm }), try std.fmt.allocPrint(output_allocator, "{s}󱂬 WM:{s} {s}", .{ colors.Color.yellow, colors.Color.reset, self.wm }),
try std.fmt.allocPrint(output_allocator, "{s}Terminal:{s} {s}", .{ colors.Color.bold, colors.Color.reset, self.terminal }), try std.fmt.allocPrint(output_allocator, "{s}Terminal:{s} {s}", .{ colors.Color.yellow, colors.Color.reset, self.terminal }),
try std.fmt.allocPrint(output_allocator, "{s}CPU:{s} {s}", .{ colors.Color.bold, colors.Color.reset, self.cpu_info }), try std.fmt.allocPrint(output_allocator, "{s}CPU:{s} {s}", .{ colors.Color.yellow, colors.Color.reset, self.cpu_info }),
}); });
for (self.gpus, 0..) |gpu_info, i| { for (self.gpus, 0..) |gpu_info, i| {
try info.append(try std.fmt.allocPrint(output_allocator, "{s}GPU{s}{s}: {s}", .{ try info.append(try std.fmt.allocPrint(output_allocator, "{s}GPU{s}{s}: {s}", .{
colors.Color.bold, colors.Color.yellow,
if (self.gpus.len > 1) try std.fmt.allocPrint(output_allocator, " {d}", .{i + 1}) else "", if (self.gpus.len > 1) try std.fmt.allocPrint(output_allocator, " {d}", .{i + 1}) else "",
colors.Color.reset, colors.Color.reset,
gpu_info, gpu_info,
@ -139,18 +139,26 @@ pub const SystemInfo = struct {
} }
try info.appendSlice(&[_][]const u8{ try info.appendSlice(&[_][]const u8{
try std.fmt.allocPrint(output_allocator, "{s}Memory:{s} {d:.2} {s} / {d:.2} {s} ({s}{d}%{s})", .{ try std.fmt.allocPrint(output_allocator, "{s}󰍛 Memory:{s} {d:.2} {s} / {d:.2} {s} ({s}{d}%{s})", .{
colors.Color.bold, colors.Color.reset, colors.Color.yellow,
calculations.mem_fmt.value, calculations.mem_fmt.unit, colors.Color.reset,
calculations.mem_total_fmt.value, calculations.mem_total_fmt.unit, calculations.mem_fmt.value,
calculations.usage_colors[0], calculations.mem_percentage, calculations.mem_fmt.unit,
calculations.mem_total_fmt.value,
calculations.mem_total_fmt.unit,
calculations.usage_colors[0],
calculations.mem_percentage,
colors.Color.reset, colors.Color.reset,
}), }),
try std.fmt.allocPrint(output_allocator, "{s}Swap:{s} {d:.2} {s} / {d:.2} {s} ({s}{d}%{s})", .{ try std.fmt.allocPrint(output_allocator, "{s}󱥎 Swap:{s} {d:.2} {s} / {d:.2} {s} ({s}{d}%{s})", .{
colors.Color.bold, colors.Color.reset, colors.Color.yellow,
calculations.swap_fmt.value, calculations.swap_fmt.unit, colors.Color.reset,
calculations.swap_total_fmt.value, calculations.swap_total_fmt.unit, calculations.swap_fmt.value,
calculations.usage_colors[1], calculations.swap_percentage, calculations.swap_fmt.unit,
calculations.swap_total_fmt.value,
calculations.swap_total_fmt.unit,
calculations.usage_colors[1],
calculations.swap_percentage,
colors.Color.reset, colors.Color.reset,
}), }),
}); });
@ -158,8 +166,8 @@ pub const SystemInfo = struct {
for (self.disks, 0..) |disk_info, i| { for (self.disks, 0..) |disk_info, i| {
const disk_fmt = format.formatSize(disk_info.used); const disk_fmt = format.formatSize(disk_info.used);
const disk_total_fmt = format.formatSize(disk_info.total); const disk_total_fmt = format.formatSize(disk_info.total);
try info.append(try std.fmt.allocPrint(output_allocator, "{s}{s}:{s} {d:.2} {s} / {d:.2} {s} ({s}{d}%{s}) - {s}", .{ try info.append(try std.fmt.allocPrint(output_allocator, "{s}󱥎 {s}:{s} {d:.2} {s} / {d:.2} {s} ({s}{d}%{s}) - {s}", .{
colors.Color.bold, colors.Color.yellow,
disk_info.mount_point, disk_info.mount_point,
colors.Color.reset, colors.Color.reset,
disk_fmt.value, disk_fmt.value,
@ -174,13 +182,7 @@ pub const SystemInfo = struct {
} }
try info.appendSlice(&[_][]const u8{ try info.appendSlice(&[_][]const u8{
try std.fmt.allocPrint(output_allocator, "", .{}), try std.fmt.allocPrint(output_allocator, "{s} Colors:{s} \x1b[37m● \x1b[31m● \x1b[32m● \x1b[33m● \x1b[34m● \x1b[35m● \x1b[36m● \x1b[37m● {s}", .{ colors.Color.yellow, colors.Color.reset, colors.Color.reset }),
try std.fmt.allocPrint(output_allocator, "\x1b[30m███\x1b[31m███\x1b[32m███\x1b[33m███\x1b[34m███\x1b[35m███\x1b[36m███\x1b[37m███{s}", .{
colors.Color.reset,
}),
try std.fmt.allocPrint(output_allocator, "\x1b[90m███\x1b[91m███\x1b[92m███\x1b[93m███\x1b[94m███\x1b[95m███\x1b[96m███\x1b[97m███{s}", .{
colors.Color.reset,
}),
}); });
return info.toOwnedSlice(); return info.toOwnedSlice();

View File

@ -12,15 +12,7 @@ pub fn getUsername(allocator: std.mem.Allocator) ![]const u8 {
} }
pub fn getOSName(allocator: std.mem.Allocator) ![]const u8 { pub fn getOSName(allocator: std.mem.Allocator) ![]const u8 {
const os_release = std.fs.openFileAbsolute("/etc/os-release", .{}) catch |err| switch (err) { const os_release = std.fs.openFileAbsolute("/etc/os-release", .{}) catch |err| return err;
error.FileNotFound => {
var uts: std.os.linux.utsname = undefined;
_ = std.os.linux.uname(&uts);
const len = std.mem.indexOfScalar(u8, &uts.sysname, 0) orelse uts.sysname.len;
return allocator.dupe(u8, uts.sysname[0..len]);
},
else => return err,
};
defer os_release.close(); defer os_release.close();
var buffer: [4096]u8 = undefined; var buffer: [4096]u8 = undefined;
@ -39,20 +31,5 @@ pub fn getOSName(allocator: std.mem.Allocator) ![]const u8 {
} }
} }
lines = std.mem.splitScalar(u8, content, '\n'); return allocator.dupe(u8, "Unknown");
while (lines.next()) |line| {
if (std.mem.startsWith(u8, line, "NAME=")) {
const value = line["NAME=".len..];
const clean_value = if (value.len >= 2 and value[0] == '"' and value[value.len - 1] == '"')
value[1 .. value.len - 1]
else
value;
return allocator.dupe(u8, clean_value);
}
}
var uts: std.os.linux.utsname = undefined;
_ = std.os.linux.uname(&uts);
const len = std.mem.indexOfScalar(u8, &uts.sysname, 0) orelse uts.sysname.len;
return allocator.dupe(u8, uts.sysname[0..len]);
} }

View File

@ -6,7 +6,6 @@ const time = std.time;
pub fn getDpkgCount() !u32 { pub fn getDpkgCount() !u32 {
const dpkg_path = "/var/lib/dpkg/status"; const dpkg_path = "/var/lib/dpkg/status";
// Get cache directory
const allocator = std.heap.page_allocator; const allocator = std.heap.page_allocator;
const home = try std.process.getEnvVarOwned(allocator, "HOME"); const home = try std.process.getEnvVarOwned(allocator, "HOME");
defer allocator.free(home); defer allocator.free(home);
@ -14,7 +13,6 @@ pub fn getDpkgCount() !u32 {
const cache_dir = try fs.path.join(allocator, &.{ home, ".config", "pikafetch" }); const cache_dir = try fs.path.join(allocator, &.{ home, ".config", "pikafetch" });
defer allocator.free(cache_dir); defer allocator.free(cache_dir);
// Ensure cache directory exists, ignore if it already does
fs.makeDirAbsolute(cache_dir) catch |err| { fs.makeDirAbsolute(cache_dir) catch |err| {
if (err != error.PathAlreadyExists) return err; if (err != error.PathAlreadyExists) return err;
}; };
@ -22,26 +20,22 @@ pub fn getDpkgCount() !u32 {
const cache_path = try fs.path.join(allocator, &.{ cache_dir, "dpkg_cache" }); const cache_path = try fs.path.join(allocator, &.{ cache_dir, "dpkg_cache" });
defer allocator.free(cache_path); defer allocator.free(cache_path);
// Check if cache exists and is valid
if (try isCacheValid(dpkg_path, cache_path)) { if (try isCacheValid(dpkg_path, cache_path)) {
return try readFromCache(cache_path); return try readFromCache(cache_path);
} }
// If cache is invalid or doesn't exist, count packages and update cache
const count = try countPackages(dpkg_path); const count = try countPackages(dpkg_path);
try updateCache(cache_path, count); try updateCache(cache_path, count);
return count; return count;
} }
fn isCacheValid(dpkg_path: []const u8, cache_path: []const u8) !bool { fn isCacheValid(dpkg_path: []const u8, cache_path: []const u8) !bool {
// Check if both files exist
const dpkg_file = fs.openFileAbsolute(dpkg_path, .{}) catch return false; const dpkg_file = fs.openFileAbsolute(dpkg_path, .{}) catch return false;
defer dpkg_file.close(); defer dpkg_file.close();
const cache_file = fs.openFileAbsolute(cache_path, .{}) catch return false; const cache_file = fs.openFileAbsolute(cache_path, .{}) catch return false;
defer cache_file.close(); defer cache_file.close();
// Compare modification times
const dpkg_stat = try dpkg_file.stat(); const dpkg_stat = try dpkg_file.stat();
const cache_stat = try cache_file.stat(); const cache_stat = try cache_file.stat();
@ -55,7 +49,6 @@ fn readFromCache(cache_path: []const u8) !u32 {
var buffer: [128]u8 = undefined; var buffer: [128]u8 = undefined;
const bytes_read = try file.readAll(&buffer); const bytes_read = try file.readAll(&buffer);
// Parse the cached count
const content = buffer[0..bytes_read]; const content = buffer[0..bytes_read];
const count_str = std.mem.trim(u8, content, &std.ascii.whitespace); const count_str = std.mem.trim(u8, content, &std.ascii.whitespace);
return try std.fmt.parseInt(u32, count_str, 10); return try std.fmt.parseInt(u32, count_str, 10);