diff --git a/.github/release-nest-v3 b/.github/release-nest-v3 index 56a6051..d8263ee 100644 --- a/.github/release-nest-v3 +++ b/.github/release-nest-v3 @@ -1 +1 @@ -1 \ No newline at end of file +2 \ No newline at end of file diff --git a/main.sh b/main.sh index 46c103b..1a42df4 100755 --- a/main.sh +++ b/main.sh @@ -6,7 +6,7 @@ set -e echo "$PIKA_BUILD_ARCH" > pika-build-arch -VERSION="0.3.0" +VERSION="0.4.0" cd ./pikafetch/ diff --git a/pikafetch/debian/changelog b/pikafetch/debian/changelog index 38b4ce9..18d879e 100644 --- a/pikafetch/debian/changelog +++ b/pikafetch/debian/changelog @@ -1,10 +1,15 @@ +pikafetch (0.4.0-101pika5) pika; urgency=medium + + * Smol birb + + -- ferreo Wed, 18 Jan 2023 21:48:14 +0000 + pikafetch (0.3.0-101pika5) pika; urgency=medium * Multiple disk support, add caching of GPU and packages info -- ferreo Wed, 18 Jan 2023 21:48:14 +0000 - pikafetch (0.2.0-101pika3) pika; urgency=medium * Move to zig nightly, remove all use of libc, switch to using arena allocator diff --git a/pikafetch/src/art/ascii_art.zig b/pikafetch/src/art/ascii_art.zig index 04d97d5..17f4d8d 100644 --- a/pikafetch/src/art/ascii_art.zig +++ b/pikafetch/src/art/ascii_art.zig @@ -2,23 +2,19 @@ const colors = @import("colors.zig"); pub fn getArt() []const []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, }; } diff --git a/pikafetch/src/display/layout.zig b/pikafetch/src/display/layout.zig index 0158547..9ef4c15 100644 --- a/pikafetch/src/display/layout.zig +++ b/pikafetch/src/display/layout.zig @@ -1,4 +1,4 @@ -pub const margin_width = 4; -pub const gap_width = 4; -pub const max_art_length = 46; +pub const margin_width = 2; +pub const gap_width = 2; +pub const max_art_length = 33; pub const color_seq_len = "\x1b[33m\x1b[1m".len; diff --git a/pikafetch/src/display/printer.zig b/pikafetch/src/display/printer.zig index 29bf928..83d2b9b 100644 --- a/pikafetch/src/display/printer.zig +++ b/pikafetch/src/display/printer.zig @@ -6,7 +6,7 @@ const terminal = @import("terminal.zig"); pub fn printDisplay(writer: anytype, info_lines: []const []const u8, term_size: terminal.TermSize) !void { const art_lines = ascii_art.getArt(); - var line_buf: [512]u8 = undefined; + var line_buf: [256]u8 = undefined; var i: usize = 0; 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; } } else { - @memset(line_buf[pos..][0..layout.max_art_length], ' '); - pos += layout.max_art_length; + const padding = layout.max_art_length - 2; + @memset(line_buf[pos..][0..padding], ' '); + pos += padding; } @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) { const info_line = info_lines[i]; + 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) + else + 0; - if (std.mem.startsWith(u8, info_line, "\x1b[") and std.mem.indexOf(u8, info_line, "███") != null) { + 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_info_len: usize = 0; + var visible_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)) - term_size.cols - (layout.margin_width + layout.max_art_length + layout.gap_width) - else - 0; while (j < info_line.len) : (j += 1) { if (info_line[j] == '\x1b') { in_escape = true; - last_color_seq_start = j; continue; } if (in_escape) { - if (info_line[j] == 'm') { - in_escape = false; - last_safe_pos = j + 1; - } + if (info_line[j] == 'm') in_escape = false; continue; } - visible_info_len += 1; - if (!in_escape) { - last_safe_pos = j + 1; - } - if (visible_info_len > available_width) break; + visible_len += 1; + if (visible_len > available_width) break; } if (j < info_line.len) { - @memcpy(line_buf[pos..][0..last_safe_pos], info_line[0..last_safe_pos]); - pos += last_safe_pos; - - 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"); - pos += 4; - } + @memcpy(line_buf[pos..][0..j], info_line[0..j]); + pos += j; + @memcpy(line_buf[pos..][0..4], "\x1b[0m"); + pos += 4; } else { @memcpy(line_buf[pos..][0..info_line.len], info_line); pos += info_line.len; diff --git a/pikafetch/src/system/hardware/motherboard.zig b/pikafetch/src/system/hardware/motherboard.zig index fa53d26..4b0f331 100644 --- a/pikafetch/src/system/hardware/motherboard.zig +++ b/pikafetch/src/system/hardware/motherboard.zig @@ -1,7 +1,6 @@ const std = @import("std"); 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", .{}); 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 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) { const product_name = try std.fs.openFileAbsolute("/sys/class/dmi/id/product_name", .{}); defer product_name.close(); diff --git a/pikafetch/src/system/info.zig b/pikafetch/src/system/info.zig index dc916c4..8970ba9 100644 --- a/pikafetch/src/system/info.zig +++ b/pikafetch/src/system/info.zig @@ -119,19 +119,19 @@ pub const SystemInfo = struct { 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}", .{ 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}Host:{s} {s}", .{ colors.Color.bold, 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}Packages:{s} {d} (native)", .{ colors.Color.bold, 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}WM:{s} {s}", .{ colors.Color.bold, 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}CPU:{s} {s}", .{ colors.Color.bold, colors.Color.reset, self.cpu_info }), + 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.yellow, colors.Color.reset, self.host }), + 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.yellow, colors.Color.reset, self.packages }), + 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.yellow, colors.Color.reset, self.wm }), + 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.yellow, colors.Color.reset, self.cpu_info }), }); for (self.gpus, 0..) |gpu_info, i| { - try info.append(try std.fmt.allocPrint(output_allocator, "{s}GPU{s}{s}: {s}", .{ - colors.Color.bold, + try info.append(try std.fmt.allocPrint(output_allocator, "{s} GPU{s}{s}: {s}", .{ + colors.Color.yellow, if (self.gpus.len > 1) try std.fmt.allocPrint(output_allocator, " {d}", .{i + 1}) else "", colors.Color.reset, gpu_info, @@ -139,18 +139,26 @@ pub const SystemInfo = struct { } try info.appendSlice(&[_][]const u8{ - try std.fmt.allocPrint(output_allocator, "{s}Memory:{s} {d:.2} {s} / {d:.2} {s} ({s}{d}%{s})", .{ - colors.Color.bold, colors.Color.reset, - calculations.mem_fmt.value, calculations.mem_fmt.unit, - calculations.mem_total_fmt.value, calculations.mem_total_fmt.unit, - calculations.usage_colors[0], calculations.mem_percentage, + try std.fmt.allocPrint(output_allocator, "{s}󰍛 Memory:{s} {d:.2} {s} / {d:.2} {s} ({s}{d}%{s})", .{ + colors.Color.yellow, + colors.Color.reset, + calculations.mem_fmt.value, + calculations.mem_fmt.unit, + calculations.mem_total_fmt.value, + calculations.mem_total_fmt.unit, + calculations.usage_colors[0], + calculations.mem_percentage, colors.Color.reset, }), - try std.fmt.allocPrint(output_allocator, "{s}Swap:{s} {d:.2} {s} / {d:.2} {s} ({s}{d}%{s})", .{ - colors.Color.bold, colors.Color.reset, - calculations.swap_fmt.value, calculations.swap_fmt.unit, - calculations.swap_total_fmt.value, calculations.swap_total_fmt.unit, - calculations.usage_colors[1], calculations.swap_percentage, + try std.fmt.allocPrint(output_allocator, "{s}󱥎 Swap:{s} {d:.2} {s} / {d:.2} {s} ({s}{d}%{s})", .{ + colors.Color.yellow, + colors.Color.reset, + calculations.swap_fmt.value, + calculations.swap_fmt.unit, + calculations.swap_total_fmt.value, + calculations.swap_total_fmt.unit, + calculations.usage_colors[1], + calculations.swap_percentage, colors.Color.reset, }), }); @@ -158,8 +166,8 @@ pub const SystemInfo = struct { for (self.disks, 0..) |disk_info, i| { const disk_fmt = format.formatSize(disk_info.used); 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}", .{ - colors.Color.bold, + try info.append(try std.fmt.allocPrint(output_allocator, "{s}󱥎 {s}:{s} {d:.2} {s} / {d:.2} {s} ({s}{d}%{s}) - {s}", .{ + colors.Color.yellow, disk_info.mount_point, colors.Color.reset, disk_fmt.value, @@ -174,13 +182,7 @@ pub const SystemInfo = struct { } try info.appendSlice(&[_][]const u8{ - try std.fmt.allocPrint(output_allocator, "", .{}), - 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, - }), + 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 }), }); return info.toOwnedSlice(); diff --git a/pikafetch/src/system/os/hostname.zig b/pikafetch/src/system/os/hostname.zig index 080a37e..5313542 100644 --- a/pikafetch/src/system/os/hostname.zig +++ b/pikafetch/src/system/os/hostname.zig @@ -12,15 +12,7 @@ pub fn getUsername(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) { - 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, - }; + const os_release = std.fs.openFileAbsolute("/etc/os-release", .{}) catch |err| return err; defer os_release.close(); 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'); - 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]); + return allocator.dupe(u8, "Unknown"); } diff --git a/pikafetch/src/system/os/packages.zig b/pikafetch/src/system/os/packages.zig index 212b13d..71944a8 100644 --- a/pikafetch/src/system/os/packages.zig +++ b/pikafetch/src/system/os/packages.zig @@ -6,7 +6,6 @@ const time = std.time; pub fn getDpkgCount() !u32 { const dpkg_path = "/var/lib/dpkg/status"; - // Get cache directory const allocator = std.heap.page_allocator; const home = try std.process.getEnvVarOwned(allocator, "HOME"); defer allocator.free(home); @@ -14,7 +13,6 @@ pub fn getDpkgCount() !u32 { const cache_dir = try fs.path.join(allocator, &.{ home, ".config", "pikafetch" }); defer allocator.free(cache_dir); - // Ensure cache directory exists, ignore if it already does fs.makeDirAbsolute(cache_dir) catch |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" }); defer allocator.free(cache_path); - // Check if cache exists and is valid if (try isCacheValid(dpkg_path, 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); try updateCache(cache_path, count); return count; } 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; defer dpkg_file.close(); const cache_file = fs.openFileAbsolute(cache_path, .{}) catch return false; defer cache_file.close(); - // Compare modification times const dpkg_stat = try dpkg_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; const bytes_read = try file.readAll(&buffer); - // Parse the cached count const content = buffer[0..bytes_read]; const count_str = std.mem.trim(u8, content, &std.ascii.whitespace); return try std.fmt.parseInt(u32, count_str, 10);