port playvid to zig

finally done with that one...
This commit is contained in:
LordMZTE 2024-03-16 19:04:56 +01:00
parent dbac90ea87
commit 5e091df878
Signed by: LordMZTE
GPG Key ID: B64802DC33A64FF6
5 changed files with 108 additions and 40 deletions

View File

@ -1,39 +0,0 @@
#!/usr/bin/env -S ros -Q --
#|-*- mode:lisp -*-|#
#|
exec ros -Q -- $0 "$@"
|#
(progn ;;init forms
(ros:ensure-asdf)
#+quicklisp(ql:quickload '(uiop) :silent t))
(defpackage :playvid
(:use :cl))
(in-package :playvid)
(defun main (&rest argv)
(let* ((vidfile (or (uiop:parse-native-namestring (car argv))
(let ((dir (uiop:directory-files ".")))
(nth (random (length dir) (make-random-state t)) dir))))
(basename (pathname-name vidfile)))
(format t "playing video: ~a~%" basename)
(uiop:run-program (list "mpv" (uiop:native-namestring vidfile))
:input :interactive
:error-output :interactive
:output :interactive
:ignore-error-status t)
(let ((confirm (uiop:run-program (list
"rofi"
"-dmenu"
"-theme"
(format nil "~a/.local/share/rofi/applets/confirm.rasi"
(user-homedir-pathname))
"-mesg"
(format nil "delete `~a`?" basename))
:input (lambda (s) (format s "No~CYes" #\newline))
:ignore-error-status t
:output :string)))
(when (string-equal (format nil "Yes~C" #\newline) confirm)
(format t "deleting file `~a`~%" basename)
(delete-file vidfile)))))

3
scripts/playvid/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
zig-cache/
zig-out/
flake.lock

24
scripts/playvid/build.zig Normal file
View File

@ -0,0 +1,24 @@
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "playvid",
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
b.installArtifact(exe);
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}

View File

@ -0,0 +1,80 @@
const std = @import("std");
pub fn main() !u8 {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const alloc = gpa.allocator();
var file_buf: [std.os.PATH_MAX]u8 = undefined;
const file = try findVideoFile(alloc, &file_buf);
try std.io.getStdOut().writer().print("playing: `{s}`\n", .{file});
var child = std.process.Child.init(&.{ "mpv", file }, alloc);
const term = try child.spawnAndWait();
if (!std.meta.eql(term, .{ .Exited = 0 })) return 1;
if (try promtForDeletion(file)) {
try std.io.getStdOut().writer().print("deleting: `{s}`\n", .{file});
try std.fs.cwd().deleteFile(file);
}
return 0;
}
fn findVideoFile(alloc: std.mem.Allocator, out_buf: []u8) ![]const u8 {
var basedir: []const u8 = ".";
if (std.os.argv.len >= 2) {
const arg = std.mem.span(std.os.argv[1]);
if ((try std.fs.cwd().statFile(arg)).kind == .directory) {
basedir = arg;
} else {
if (arg.len > out_buf.len) return error.OutOfMemory;
@memcpy(out_buf[0..arg.len], arg);
return out_buf[0..arg.len];
}
}
var fname_arena = std.heap.ArenaAllocator.init(alloc);
defer fname_arena.deinit();
var cwd_iter = try std.fs.cwd().openDir(basedir, .{ .iterate = true });
defer cwd_iter.close();
var iter = cwd_iter.iterate();
var files = std.ArrayList([]const u8).init(alloc);
defer files.deinit();
while (try iter.next()) |entry| {
switch (entry.kind) {
.file => {
try files.append(try fname_arena.allocator().dupe(u8, entry.name));
},
else => {},
}
}
if (files.items.len == 0) return error.DirectoryEmpty;
const idx = std.crypto.random.uintLessThan(usize, files.items.len);
if (files.items[idx].len > out_buf.len) return error.OutOfMemory;
@memcpy(out_buf[0..files.items[idx].len], files.items[idx]);
return out_buf[0..files.items[idx].len];
}
fn promtForDeletion(file: []const u8) !bool {
try std.io.getStdOut().writer().print("delete file `{s}`? [Y/N] ", .{file});
const old_termios = try std.os.tcgetattr(std.os.STDIN_FILENO);
var new_termios = old_termios;
new_termios.lflag.ICANON = false; // No line buffering
try std.os.tcsetattr(std.os.STDIN_FILENO, .NOW, new_termios);
defer std.os.tcsetattr(std.os.STDIN_FILENO, .NOW, old_termios) catch {};
const answer = try std.io.getStdIn().reader().readByte();
const ret = switch (answer) {
'y', 'Y' => true,
else => false,
};
try std.io.getStdOut().writeAll("\n");
return ret;
}

View File

@ -24,6 +24,7 @@
(install-zig "scripts/mzteriver")
(install-zig "scripts/openbrowser")
(install-zig "scripts/playtwitch")
(install-zig "scripts/playvid")
(install-zig "scripts/prompt")
(install-zig "scripts/randomwallpaper")
(install-zig "scripts/vinput")
@ -31,5 +32,4 @@
(install-zig "scripts/wlbg")
(install-roswell "scripts/launchmenu.ros")
(install-roswell "scripts/playvid.ros")
null)