gemini publish
This commit is contained in:
parent
7322ad8d18
commit
8389289fac
30
Makefile
Normal file
30
Makefile
Normal file
|
@ -0,0 +1,30 @@
|
|||
# This makefile builds the website to be published.
|
||||
# For the HTTP/HTML portion, that's pushed to Github pages.
|
||||
# For the gemini portion, that's also pushed to my gemini server by this makefile.
|
||||
source_files := $(shell find content/*.md)
|
||||
target_files := $(patsubst content/%.md,gemini/%.gmi,$(source_files))
|
||||
|
||||
.PHONY: default
|
||||
default: publish build-html
|
||||
|
||||
gemini/%.gmi: content/%.md
|
||||
lowdown -tgemini $< > $@
|
||||
|
||||
.PHONY: build-gemini
|
||||
build-gemini: $(target_files)
|
||||
cp gemini/_index.gmi gemini/index.gmi
|
||||
for file in $(target_files) ; do \
|
||||
echo "=> $$file" | sed 's/gemini//' >> gemini/index.gmi ; \
|
||||
done
|
||||
|
||||
.PHONY: build-html
|
||||
build-html:
|
||||
boot publish
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
echo ${target_files}
|
||||
|
||||
.PHONY: publish
|
||||
publish: $(target_files)
|
||||
rsync -av content/img content/extra gemini/index.gmi $^ gemini.bgenc.net:/var/gemini/
|
|
@ -10,3 +10,6 @@ page](https://github.com/SeriousBug).
|
|||
|
||||
I published several papers and participated in academic reviews during graduate school, which you can find [links to here](/publications/).
|
||||
|
||||
This website is also available on the gemini protocol as [gemini.bgenc.net](gemini://gemini.bgenc.net).
|
||||
Please see the ["Clients" section on this page](https://gemini.circumlunar.space/software/)
|
||||
to find a client, then connect to `gemini.bgenc.net`.
|
||||
|
|
0
customizing-emacs.gmi
Normal file
0
customizing-emacs.gmi
Normal file
0
duplicity.gmi
Normal file
0
duplicity.gmi
Normal file
0
emacs-as-an-os.gmi
Normal file
0
emacs-as-an-os.gmi
Normal file
36
gemini/_index.gmi
Normal file
36
gemini/_index.gmi
Normal file
|
@ -0,0 +1,36 @@
|
|||
# Homepage of Kaan Barmore-Genç
|
||||
|
||||
Hey folks!
|
||||
|
||||
I'm a Software Engineer at Dendron, and a recent Master's graduate from the Ohio
|
||||
State University. I'm an avid Linux user, an enthusiast of many programming
|
||||
languages, a home cook, and an amateur gardener.
|
||||
|
||||
=> https://dendron.so Dendron
|
||||
=> https://bgenc.net/recipes/ My recipes
|
||||
|
||||
My interests include building web and mobile applications, both at the front and
|
||||
back end. Over the years I learned and used many programming languages and
|
||||
technologies, including JavaScript, TypeScript, React, React Native, Rust,
|
||||
Python, Java, C, C++, Clojure, and Haskell. Pretty much everthing I've worked on
|
||||
is open source and available on my Github page.
|
||||
|
||||
I published several papers and participated in academic reviews during graduate school. You can find them below.
|
||||
|
||||
=> /publications.gmi My publications
|
||||
|
||||
Here are some links if you need to reach me.
|
||||
|
||||
=> mailto:kaan@bgenc.net kaan@bgenc.net
|
||||
=> /extra/kaangenc.gpg GPG key
|
||||
=> https://github.com/SeriousBug Github
|
||||
=> https://www.linkedin.com/in/kaan-genc-8489b9205/ LinkedIn
|
||||
=> /extra/cv.pdf My CV
|
||||
=> https://mastodon.technology/@kaan My Mastodon
|
||||
|
||||
This page is also available on HTTP/HTML if you prefer that.
|
||||
|
||||
=> https://bgenc.net HTTP mirror
|
||||
|
||||
Finally, below is a list of all my blog posts. These are not sorted by date at the moment, but I'm working on fixing that soon.
|
||||
|
11
gemini/bash.gmi
Normal file
11
gemini/bash.gmi
Normal file
|
@ -0,0 +1,11 @@
|
|||
~~~~~~~~
|
||||
|
||||
title: Writing a Program in Bash
|
||||
|
||||
## date: 2015-04-12
|
||||
|
||||
I don’t really know why, but writing code in Bash makes me kinda anxious. It feels really old, outdated, and confusing. Why can’t a function return a string? And no classes, or even data types? After getting confused, usually, I just end up switching to Python. <!--more--> But this time, I decided to stick with Bash. And I am surprised. It is unbelievebly good. I must say, now I understand the Unix philosophy much better. Having small programs doing one thing very good allows you to combine the power of those programs in your scripts. You think your favourite programming language has a lot of libraries? Well, bash has access to more. The entire Unix ecosystem powers bash. Converting videos, taking screenshots, sending mails, downloading and processing pages; there are already command line tools for all of that, and you have great access to all of them.
|
||||
|
||||
The program I’ve started writing is called WoWutils[a]. And I’m still shocked at just how much functionality I have added with so little code. If you are considering writing a program in Bash too, just go through with it. It really is very powerful.
|
||||
|
||||
=> https://github.com/SeriousBug/WoWutils [a]
|
58
gemini/customizing-emacs.gmi
Normal file
58
gemini/customizing-emacs.gmi
Normal file
|
@ -0,0 +1,58 @@
|
|||
~~~~~~~~
|
||||
|
||||
title: Emacs and extensibility
|
||||
|
||||
## date: 2015-10-06
|
||||
|
||||
Update: I’ve put the small Emacs tools I have written to a gist[a].
|
||||
|
||||
=> https://gist.github.com/91c38ddde617b98ffbcb [a]
|
||||
|
||||
I have been using Emacs for some time, and I really love it. The amount of power it has, and the customizability is incredible. What other editor allow you to connect to a server over SSH and edit files, which is what I am doing to write this post. How many editors or IDE’s have support for so many languages?
|
||||
|
||||
```<!--more-->
|
||||
```
|
||||
|
||||
One thing I didn’t know in the past, however, is extensibility of Emacs. I mean, I do use a lot of packages, but I had never written Elisp and I didn’t know how hard or easy it would be. But after starting to learn Clojure a bit, and feeling more comfortable with lots of parenthesis, I decided to extend Emacs a bit to make it fit myself better.
|
||||
|
||||
The first thing I added is an “insert date” function. I use Emacs to take notes during lessons -using Org-mode- and I start every note with the date of the lesson. Sure, glancing at the date to the corner of my screen and writing it down takes just a few seconds, but why not write a command to do it for me? Here is what I came up with:
|
||||
|
||||
```(defun insert-current-date ()
|
||||
"Insert the current date in YYYY-MM-DD format."
|
||||
(interactive)
|
||||
(shell-command "date +'%Y-%m-%d'" t))
|
||||
```
|
||||
|
||||
Now that was easy and convenient. And being able to write my first piece of Elisp so easily was really fun, so I decided to tackle something bigger.
|
||||
|
||||
It is not rare that I need to compile and run a single C file. Nothing fancy, no libraries, no makefile, just a single C file to compile and run. I searched around the internet like “Emacs compile and run C”, but couldn’t find anything. I had been doing this by opening a shell in Emacs and compiling/running the program, but again, why not automate it?
|
||||
|
||||
The code that follows is not really good. “It works” is as good as it gets really, and actually considering that this is the first substantial Elisp I have written, that is pretty impressive -for the language and Emacs, which are both very helpful and powerful- I think.
|
||||
|
||||
```(require 's)
|
||||
(defun compile-run-buffer ()
|
||||
"Compile and run buffer."
|
||||
(interactive)
|
||||
(let* ((split-file-path (split-string buffer-file-name "/"))
|
||||
(file-name (car (last split-file-path)))
|
||||
(file-name-noext (car (split-string file-name "[.]")))
|
||||
(buffer-name (concat "compile-run: " file-name-noext))
|
||||
(buffer-name* (concat "*" buffer-name "*")))
|
||||
(make-comint buffer-name "gcc" nil "-Wall" "-Wextra" "-o" file-name-noext file-name)
|
||||
(switch-to-buffer-other-window buffer-name*)
|
||||
(set-process-sentinel (get-buffer-process (current-buffer))
|
||||
(apply-partially
|
||||
'(lambda (prog-name proc even)
|
||||
(if (s-suffix? "finished\n" even)
|
||||
(progn
|
||||
(insert "Compilation successful.\n\n")
|
||||
(comint-exec (current-buffer) prog-name (concat "./" prog-name) nil nil))
|
||||
(insert (concat "Compilation failed!\n" even))))
|
||||
file-name-noext))))
|
||||
```
|
||||
|
||||
Again, the code is not really good. I’m uploading it here right now because I’m actually very excited that I wrote this. Just now I can think of ways to improve this, for example moving the compiler and the flags to variables so that they can be customized. I could also improve the presentation, because strings printed by this function, comint and the running programs mixes up. I’ll update this blog post if I get to updating the code.
|
||||
|
||||
If this is your first time hearing about Emacs, this post may look very confusing. I don’t to Emacs any justice here, so do check it out somewhere like Emacs rocks[a]. On the other hand, if you have been looking a functionality like this, hope this helps. If you have any suggestions about the code, I’d love to hear them, you can find my email on the “about me” page. Anyway, have a good day!
|
||||
|
||||
=> http://emacsrocks.com/ [a]
|
64
gemini/duplicity.gmi
Normal file
64
gemini/duplicity.gmi
Normal file
|
@ -0,0 +1,64 @@
|
|||
~~~~~~~~
|
||||
|
||||
title: Taking Backups with Duplicity
|
||||
|
||||
## date: 2015-05-16
|
||||
|
||||
I wanted to start taking backups for some time, but I haven’t had the time to do any research and set everything up. After reading another horror story that was saved by backups[a], I decided to start taking some backups.
|
||||
|
||||
=> https://www.reddit.com/r/linuxmasterrace/comments/35ljcq/couple_of_days_ago_i_did_rm_rf_in_my_home/ [a]
|
||||
|
||||
```<!--more-->
|
||||
```
|
||||
|
||||
After doing some research on backup options, I decided on duplicity[a]. The backups are compressed, encrypted and incremental, both saving space and ensuring security. It supports both local and ssh files(as well as many other protocols), so it has everything I need.
|
||||
|
||||
=> http://duplicity.nongnu.org/ [a]
|
||||
|
||||
I first took a backup into my external hard drive, then VPS. The main problem I encountered was that duplicity uses paramiko[a] for ssh, but it wasn’t able to negotiate a key exchange algorithm with my VPS. Luckily, duplicity also supports pexpect[b], which uses OpenSSH. If you encounter the same problem, you just need to tell duplicity to use pexpect backend by prepending your url with pexpect+, like pexpect+ssh://example.com.
|
||||
|
||||
=> https://github.com/paramiko/paramiko [a]
|
||||
=> http://pexpect.sourceforge.net/pexpect.html [b]
|
||||
|
||||
Duplicity doesn’t seem to have any sort of configuration files of itself, so I ended up writing a small bash script to serve as a sort of configuration, and also keep me from running duplicity with wrong args. I kept forgetting to add an extra slash to file://, causing duplicity to backup my home directory into my home directory! :D
|
||||
|
||||
If anyone is interested, here’s the script:
|
||||
|
||||
```#!/bin/bash
|
||||
|
||||
if [[ $(id -u) != "0" ]]; then
|
||||
read -p "Backup should be run as root! Continue? [y/N]" yn
|
||||
case $yn in
|
||||
[Yy]*) break;;
|
||||
*) exit;;
|
||||
esac
|
||||
fi
|
||||
|
||||
|
||||
if [[ $1 = file://* ]]; then
|
||||
echo "Doing local backup."
|
||||
ARGS="--no-encryption"
|
||||
if [[ $1 = file:///* ]]; then
|
||||
URL=$1
|
||||
else
|
||||
echo "Use absolute paths for backup."
|
||||
exit 1
|
||||
fi
|
||||
elif [[ $1 = scp* ]]; then
|
||||
echo "Doing SSH backup."
|
||||
ARGS="--ssh-askpass"
|
||||
URL="pexpect+$1"
|
||||
else
|
||||
echo "Unknown URL, use scp:// or file://"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if [[ -n "$1" ]]; then
|
||||
duplicity $ARGS --exclude-filelist /home/kaan/.config/duplicity-files /home/kaan "$URL/backup"
|
||||
else
|
||||
echo "Please specify a location to backup into."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
```
|
176
gemini/emacs-as-an-os.gmi
Normal file
176
gemini/emacs-as-an-os.gmi
Normal file
|
@ -0,0 +1,176 @@
|
|||
~~~~~~~~
|
||||
|
||||
title: Emacs as an operating system date: 2016-04-14
|
||||
|
||||
## modified: 2016-05-29
|
||||
|
||||
Emacs is sometimes jokingly called a good operating system with a bad text editor. Over the last year, I found myself using more and more of Emacs, so I decided to try out how much of an operating system it is. Of course, operating system here is referring to the programs that the user interacts with, although I would love to try out some sort of Emacs-based kernel.
|
||||
|
||||
```<!--more-->
|
||||
```
|
||||
|
||||
# Emacs as a terminal emulator / multiplexer
|
||||
|
||||
Terminals are all about text, and Emacs is all about text as well. Not only that, but Emacs is also very good at running other processes and interacting with them. It is no surprise, I think, that Emacs works well as a terminal emulator.
|
||||
|
||||
Emacs comes out of the box with shell and term. Both of these commands run the shell of your choice, and give you a buffer to interact with it. Shell gives you a more emacs-y experience, while term overrides all default keymaps to give you a full terminal experience.
|
||||
|
||||
=> /img/emacs-terminal.png Emacs as a terminal emulator
|
||||
|
||||
To use emacs as a full terminal, you can bind these to a key in your window manager. I’m using i3, and my keybinding looks like this:
|
||||
|
||||
```bindsym $mod+Shift+Return exec --no-startup-id emacs --eval "(shell)"
|
||||
```
|
||||
|
||||
You can also create a desktop file to have a symbol to run this on a desktop environment. Try putting the following text in a file at ~/.local/share/applications/emacs-terminal.desktop:
|
||||
|
||||
```[Desktop Entry]
|
||||
Name=Emacs Terminal
|
||||
GenericName=Terminal Emulator
|
||||
Comment=Emacs as a terminal emulator.
|
||||
Exec=emacs --eval '(shell)'
|
||||
Icon=emacs
|
||||
Type=Application
|
||||
Terminal=false
|
||||
StartupWMClass=Emacs
|
||||
```
|
||||
|
||||
If you want to use term instead, replace (shell) above with (term "/usr/bin/bash").
|
||||
|
||||
A very useful feature of terminal multiplexers is the ability to leave the shell running, even after the terminal is closed, or the ssh connection has dropped if you are connection over that. Emacs can also achieve this with it’s server-client mode. To use that, start emacs with emacs --daemon, and then create a terminal by running emacsclient -c --eval '(shell)'. Even after you close emacsclient, since Emacs itself is still running, you can run the same command again to get back to your shell.
|
||||
|
||||
One caveat is that if there is a terminal/shell already running, Emacs will automatically open that whenever you try opening a new one. This can be a problem if you are using Emacs in server-client mode, or want to have multiple terminals in the same window. In that case, you can either do M-x rename-uniquely to change the name of the existing terminal, which will make Emacs create a new one next time, or you can add that to hook in your init.el to always have that behaviour:
|
||||
|
||||
```(add-hook 'shell-mode-hook 'rename-uniquely)
|
||||
(add-hook 'term-mode-hook 'rename-uniquely)
|
||||
```
|
||||
|
||||
# Emacs as a shell
|
||||
|
||||
Of course, it is not enough that Emacs works as a terminal emulator. Why not use Emacs as a shell directly, instead of bash/zsh? Emacs has you covered for that too. You can use eshell, which is a shell implementation, completely written in Emacs Lisp. All you need to do is press M-x eshell.
|
||||
|
||||
=> /img/eshell.png Eshell, Emacs shell
|
||||
|
||||
The upside is that eshell can evaluate and expand lisp expressions, as well as redirecting the output to Emacs buffers. The downside is however, eshell is not feature complete. It lacks some features such as input redirection, and the documentation notes that it is inefficient at piping output between programs.
|
||||
|
||||
If you want to use eshell instead of shell or term, you can replace shell in the examples of terminal emulator section with eshell.
|
||||
|
||||
# Emacs as a mail cilent
|
||||
|
||||
Zawinski’s Law[a]: Every program attempts to expand until it can read mail. Of course, it would be disappointing for Emacs to not handle mail as well.
|
||||
|
||||
=> http://www.catb.org/~esr/jargon/html/Z/Zawinskis-Law.html [a]
|
||||
|
||||
Emacs already ships with some mail capability. To get a full experience however, I’d recommend using mu4e[a] (mu for emacs). I have personally set up OfflineIMAP[b] to retrieve my emails, and mu4e gives me a nice interface on top of that.
|
||||
|
||||
=> http://www.djcbsoftware.nl/code/mu/mu4e.html [a]
|
||||
=> http://www.offlineimap.org/ [b]
|
||||
|
||||
=> /img/mu4e.png mu4e, mail client
|
||||
|
||||
I’m not going to talk about the configurations of these programs, I’d recommend checking out their documentations. Before ending this section, I also want to mention mu4e-alert[a] though.
|
||||
|
||||
=> https://github.com/iqbalansari/mu4e-alert [a]
|
||||
|
||||
# Emacs as a feed reader (RSS/Atom)
|
||||
|
||||
Emacs handles feeds very well too. The packages I’m using here are Elfeed[a] and Elfeed goodies[b]. Emacs can even show images in the feeds, so it covers everything I need from a feed reader.
|
||||
|
||||
=> https://github.com/skeeto/elfeed [a]
|
||||
=> https://github.com/algernon/elfeed-goodies [b]
|
||||
|
||||
=> /img/elfeed.png Elfeed, feed reader
|
||||
|
||||
# Emacs as a file manager
|
||||
|
||||
Why use a different program to manage your files when you can use Emacs? Emacs ships with dired, as well as image-dired. This gives you a file browser, with optional image thumbnail support.
|
||||
|
||||
# Emacs as a document viewer
|
||||
|
||||
Want to read a pdf? Need a program to do a presentation? Again, Emacs.
|
||||
|
||||
=> /img/docview.png Docview, document viewer
|
||||
|
||||
Emacs comes with DocView[a] which has support for PDF, OpenDocument and Microsoft Office files. It works surprisingly well.
|
||||
|
||||
=> https://www.gnu.org/software/emacs/manual/html_node/emacs/Document-View.html [a]
|
||||
|
||||
Also, PDF Tools[a] brings even more PDF viewing capabilities to Emacs, including annotations, text search and outline. After installing PDF Tools, Emacs has become my primary choice for reading PDF files.
|
||||
|
||||
=> https://github.com/politza/pdf-tools [a]
|
||||
|
||||
# Emacs as a browser
|
||||
|
||||
Emacs comes out of box with eww[a], a text-based web browser with support for images as well.
|
||||
|
||||
=> https://www.gnu.org/software/emacs/manual/html_node/eww/index.html#Top [a]
|
||||
|
||||
=> /img/eww.png eww, browser
|
||||
|
||||
Honestly, I don’t think I’ll be using Emacs to browse the web. But still, it is nice that the functionality is there.
|
||||
|
||||
# Emacs as a music player
|
||||
|
||||
Emacs can also act as a music player thanks to EMMS[a], Emacs MultiMedia System. If you are wondering, it doesn’t play the music by itself but instead uses other players like vlc or mpd.
|
||||
|
||||
=> https://www.gnu.org/software/emms/ [a]
|
||||
|
||||
It has support for playlists, and can show thumbnails as well. For the music types, it supports whatever the players it uses support, which means that you can basically use file type.
|
||||
|
||||
# Emacs as a IRC client
|
||||
|
||||
I don’t use IRC a lot, but Emacs comes out of the box with support for that as well thanks to ERC[a].
|
||||
|
||||
=> https://www.emacswiki.org/emacs?action=browse;oldid=EmacsIrcClient;id=ERC [a]
|
||||
|
||||
=> /img/erc.png erc, Emacs IRC client
|
||||
|
||||
# Emacs as a text editor
|
||||
|
||||
Finally, Emacs also can work well as a text editor.
|
||||
|
||||
Emacs is a pretty fine text editor out of the box, but I want to mention some packages here.
|
||||
|
||||
First, multiple cursors[a]. Multiple cursors mode allows you to edit text at multiple places at the same time.
|
||||
|
||||
=> https://github.com/magnars/multiple-cursors.el [a]
|
||||
|
||||
I also want to mention undo-tree[a]. It acts like a mini revision control system, allowing you to undo and redo without ever losing any text.
|
||||
|
||||
=> http://www.dr-qubit.org/emacs.php#undo-tree [a]
|
||||
|
||||
Another great mode is iy-go-to-char[a]. It allows you to quickly jump around by going to next/previous occurrances of a character. It is very useful when you are trying to move around a line.
|
||||
|
||||
=> https://github.com/doitian/iy-go-to-char [a]
|
||||
|
||||
Ace Jump Mode[a] allows you to jump around the visible buffers. It can jump around based on initial characters of words, or jump to specific lines. It can also jump from one buffer to another, which is very useful when you have several buffers open in your screen.
|
||||
|
||||
=> https://github.com/winterTTr/ace-jump-mode/ [a]
|
||||
|
||||
=> /img/ace-jump-mode.png Ace Jump Mode
|
||||
|
||||
Finally, I want to mention ag.el[a], which is an Emacs frontend for the silver searcher. If you don’t know about ag, it is a replacement for grep that recursively searches directories, and has some special handling for projects, and is very fast.
|
||||
|
||||
=> https://github.com/Wilfred/ag.el [a]
|
||||
|
||||
# Emacs as an IDE
|
||||
|
||||
People sometimes compare Emacs to IDE’s and complain that a text editor such as Emacs doesn’t have enough features. What they are forgetting, of course, is that Emacs is an operating system, and we can have an IDE in it as well.
|
||||
|
||||
There are different packages for every language, so I’ll be only speaking on language agnostic ones.
|
||||
|
||||
For interacting with git, magit[a] is a wonderful interface.
|
||||
|
||||
=> http://magit.vc/ [a]
|
||||
|
||||
=> /img/magit.png Magit, Git Porcelain
|
||||
|
||||
For auto-completion, Company mode[a] works wonders. I rely heavily on completion while writing code, and company mode has support for anything I tried writing.
|
||||
|
||||
=> https://company-mode.github.io/ [a]
|
||||
|
||||
If you like having your code checked as you type, flycheck[a] has you covered. It has support for many tools and languages.
|
||||
|
||||
=> https://www.flycheck.org/ [a]
|
||||
|
||||
=> /img/company-flycheck.png Company Mode and Flycheck
|
73
gemini/getting-deus-ex-running-on-linux.gmi
Normal file
73
gemini/getting-deus-ex-running-on-linux.gmi
Normal file
|
@ -0,0 +1,73 @@
|
|||
~~~~~~~~
|
||||
|
||||
title: Getting Deus Ex GOTY Edition running on Linux
|
||||
|
||||
## date: 2022-03-12
|
||||
|
||||
I’ve been struggling with this for a few hours, so I might as well document how I did it.
|
||||
|
||||
I have a particular setup, which ended up causing issues. Most important are that I’m using Sway, a tiling Wayland compositor, and a flatpak install of Steam.
|
||||
|
||||
## Mouse doesn’t move when the game is launched
|
||||
|
||||
It looks like there’s a problem with the game window grabbing the cursor on my setup, so moving the mouse doesn’t move the cursor in the game and if you move it too much to the side it takes you out of the game window.
|
||||
|
||||
The solution to this is using Gamescope, which is a nested Wayland compositor that makes the window inside it play nice with your actual compositor.
|
||||
|
||||
Because I’m using the flatpak install of Steam, I needed to install the flatpak version of gamescope[a]. One catch here is that for me, this wouldn’t work if I also had the flatpak MangoHud installed. The only solution I could come up with right now was to uninstall MangoHud.
|
||||
|
||||
=> https://github.com/flathub/com.valvesoftware.Steam.Utility.gamescope [a]
|
||||
|
||||
```flatpak remove org.freedesktop.Platform.VulkanLayer.MangoHud # if you have it installed
|
||||
flatpak install com.valvesoftware.Steam.Utility.gamescope
|
||||
```
|
||||
|
||||
Then, right click on the game and select properties, then in launch options type gamescope -f -- %command%. This will launch the game inside gamescope, and the cursor should move inside the game now.
|
||||
|
||||
## The game is too dark to see anything
|
||||
|
||||
It looks like the game relied on some old DirectX or OpenGL features or something, because once you do launch into the game, everything is extremely dark and hard to see. At first I was wondering how anyone could play the game like this, but it turns out that’s not how the game is supposed to look!
|
||||
|
||||
I finally managed to solve this by following the installer steps for the Deus Ex CD on Lutris[a]. Yeah, roundabout way to solve it, but it worked.
|
||||
|
||||
=> https://lutris.net/games/install/948/view [a]
|
||||
|
||||
First download the updated D3D9 and OpenGL renderers from the page, and extract them into the System folder inside the game.
|
||||
|
||||
```cd "$HOME/.var/app/com.valvesoftware.Steam/.steam/steam/steamapps/common/Deus Ex/System"
|
||||
wget https://lutris.net/files/games/deus-ex/dxd3d9r13.zip
|
||||
wget https://lutris.net/files/games/deus-ex/dxglr20.zip
|
||||
unzip dxd3d9r13.zip
|
||||
unzip dxglr20.zip
|
||||
```
|
||||
|
||||
Next, download and install the 1112fm patch.
|
||||
|
||||
```cd "$HOME/.var/app/com.valvesoftware.Steam/.steam/steam/steamapps/common/Deus Ex/System"
|
||||
wget https://lutris.net/files/games/deus-ex/DeusExMPPatch1112fm.exe
|
||||
env WINEPREFIX="$HOME/.var/app/com.valvesoftware.Steam/.steam/steam/steamapps/compatdata/6910/pfx/" wine DeusExMPPatch1112fm.exe
|
||||
```
|
||||
|
||||
Follow the steps of the installer. It should automatically find where the game is installed. Once the install is done, launch the game, then head into the settings and pick “Display Settings”, then “Rendering Device”. In the renderer selection window, pick “Show all devices”, and then select “Direct3D9 Support”.
|
||||
|
||||
=> /img/deus-ex-render-settings.png Launch back into the game, head into the display settings again, pick your resolution, and restart the game. Then head into the display settings yet again, this time change the color depth to 32 bit. Restart once more. Yes, you do have to do them separately or the game doesn’t save the color depth change for some reason. Finally, you can start playing!
|
||||
|
||||
=> /img/deus-ex-renderer-comparison.png ## Other small issues
|
||||
|
||||
Here are a few more issues you might hit during this whole process:
|
||||
|
||||
> My cursor moves too fast!
|
||||
|
||||
You need to turn down the cursor speed. My mouse has buttons to adjust the speed on the fly, so I use those to turn down the speed.
|
||||
|
||||
> After changing resolution, I can’t move my cursor!
|
||||
|
||||
Use the keyboard shortcuts (arrow keys and enter) to exit the game. It should work again when you restart.
|
||||
|
||||
> The cursor doesn’t move when I open the game, even with gamescope!
|
||||
|
||||
I’m not fully sure why or how this happens, but a few things I found useful:
|
||||
|
||||
* When the game is launching, and it’s showing the animation of the studio logo, don’t click! Press escape to bring up the menu instead.
|
||||
* Press escape to bring the menu up, then hit escape again to dismiss it. It sometimes starts working after that.
|
||||
* Use the keyboard to exit the game and restart. It always works the next time for me.
|
45
gemini/index.gmi
Normal file
45
gemini/index.gmi
Normal file
|
@ -0,0 +1,45 @@
|
|||
# Homepage of Kaan Barmore-Genç
|
||||
|
||||
Hey folks!
|
||||
|
||||
I'm a Software Engineer at Dendron, and a recent Master's graduate from the Ohio
|
||||
State University. I'm an avid Linux user, an enthusiast of many programming
|
||||
languages, a home cook, and an amateur gardener.
|
||||
|
||||
=> https://dendron.so Dendron
|
||||
=> https://bgenc.net/recipes/ My recipes
|
||||
|
||||
My interests include building web and mobile applications, both at the front and
|
||||
back end. Over the years I learned and used many programming languages and
|
||||
technologies, including JavaScript, TypeScript, React, React Native, Rust,
|
||||
Python, Java, C, C++, Clojure, and Haskell. Pretty much everthing I've worked on
|
||||
is open source and available on my Github page.
|
||||
|
||||
I published several papers and participated in academic reviews during graduate school. You can find them below.
|
||||
|
||||
=> /publications.gmi My publications
|
||||
|
||||
Here are some links if you need to reach me.
|
||||
|
||||
=> mailto:kaan@bgenc.net kaan@bgenc.net
|
||||
=> /extra/kaangenc.gpg GPG key
|
||||
=> https://github.com/SeriousBug Github
|
||||
=> https://www.linkedin.com/in/kaan-genc-8489b9205/ LinkedIn
|
||||
=> /extra/cv.pdf My CV
|
||||
=> https://mastodon.technology/@kaan My Mastodon
|
||||
|
||||
This page is also available on HTTP/HTML if you prefer that.
|
||||
|
||||
=> https://bgenc.net HTTP mirror
|
||||
|
||||
Finally, below is a list of all my blog posts. These are not sorted by date at the moment, but I'm working on fixing that soon.
|
||||
|
||||
=> /bash.gmi
|
||||
=> /customizing-emacs.gmi
|
||||
=> /duplicity.gmi
|
||||
=> /emacs-as-an-os.gmi
|
||||
=> /getting-deus-ex-running-on-linux.gmi
|
||||
=> /mpv.gmi
|
||||
=> /pass.gmi
|
||||
=> /publications.gmi
|
||||
=> /raid.gmi
|
66
gemini/mpv.gmi
Normal file
66
gemini/mpv.gmi
Normal file
|
@ -0,0 +1,66 @@
|
|||
~~~~~~~~
|
||||
|
||||
title: Motion Interpolation, 24 FPS to 60 FPS with mpv, VapourSynth and MVTools date: 2015-07-18
|
||||
|
||||
## modified: 2015-07-20
|
||||
|
||||
Watching videos at 60 FPS is great. It makes the video significantly smoother and much more enjoyable. Sadly, lots of movies and TV shows are still at 24 FPS. However, I recently discovered that it is actually possible to interpolate the extra frames by using motion interpolation, and convert a video from 24 FPS to 60 FPS in real time. While it is far from perfect, I think the visual artifacts are a reasonable tradeoff for high framerate.
|
||||
|
||||
```<!--more-->
|
||||
```
|
||||
|
||||
Firstly, what we need is mpv with VapourSynth enabled, and MVTools plugin for VapourSynth. VapourSynth must be enabled while compiling mpv. I adopted an AUR package mpv-vapoursynth[a] which you can use if you are on Arch. Otherwise, all you need to do is use --enable-vapoursynth flag when doing ./waf --configure. They explain the compilation on their repository[b], so look into there if you are compiling yourself.
|
||||
|
||||
=> https://aur4.archlinux.org/packages/mpv-vapoursynth/ [a]
|
||||
=> https://github.com/mpv-player/mpv [b]
|
||||
|
||||
After that, we need MVTools plugin for VapourSynth. This is available on Arch via vapoursynth-plugin-mvtools[a], otherwise you can find their repository here[b]. There is also a PPA for Ubuntu[c] where you can find vapoursynth-extra-plugins, but I haven’t used it myself so I can’t comment on it.
|
||||
|
||||
=> https://www.archlinux.org/packages/community/x86_64/vapoursynth-plugin-mvtools/ [a]
|
||||
=> https://github.com/dubhater/vapoursynth-mvtools [b]
|
||||
=> https://launchpad.net/~djcj/+archive/ubuntu/vapoursynth [c]
|
||||
|
||||
After both of these are enabled, we need a script to use MVTools from VapourSynth. There is one written by Niklas Haas, which you can find here as mvtools.vpy[a]. Personally, I tweaked the block sizes and precision to my liking, as well as removing the resolution limit he added. I’ll put the modified version here:
|
||||
|
||||
=> https://github.com/haasn/gentoo-conf/blob/master/home/nand/.mpv/filters/mvtools.vpy [a]
|
||||
|
||||
```# vim: set ft=python:
|
||||
|
||||
import vapoursynth as vs
|
||||
core = vs.get_core()
|
||||
clip = video_in
|
||||
|
||||
dst_fps = display_fps
|
||||
# Interpolating to fps higher than 60 is too CPU-expensive, smoothmotion can handle the rest.
|
||||
while (dst_fps > 60):
|
||||
dst_fps /= 2
|
||||
|
||||
# Skip interpolation for 60 Hz content
|
||||
if not (container_fps > 59):
|
||||
src_fps_num = int(container_fps * 1e8)
|
||||
src_fps_den = int(1e8)
|
||||
dst_fps_num = int(dst_fps * 1e4)
|
||||
dst_fps_den = int(1e4)
|
||||
# Needed because clip FPS is missing
|
||||
clip = core.std.AssumeFPS(clip, fpsnum = src_fps_num, fpsden = src_fps_den)
|
||||
print("Reflowing from ",src_fps_num/src_fps_den," fps to ",dst_fps_num/dst_fps_den," fps.")
|
||||
|
||||
sup = core.mv.Super(clip, pel=1, hpad=8, vpad=8)
|
||||
bvec = core.mv.Analyse(sup, blksize=8, isb=True , chroma=True, search=3, searchparam=1)
|
||||
fvec = core.mv.Analyse(sup, blksize=8, isb=False, chroma=True, search=3, searchparam=1)
|
||||
clip = core.mv.BlockFPS(clip, sup, bvec, fvec, num=dst_fps_num, den=dst_fps_den, mode=3, thscd2=12)
|
||||
|
||||
clip.set_output()
|
||||
```
|
||||
|
||||
At this point, you should be able to try this out as suggested in the script. To set this up more permanently, I’d suggest placing this script as ~/.config/mpv/mvtools.vpy, and also writing the following as ~/.config/mpv/mpv.conf:
|
||||
|
||||
```hwdec=no
|
||||
vf=vapoursynth=~/.config/mpv/mvtools.vpy
|
||||
```
|
||||
|
||||
Now, whenever you open mpv, it will always use motion interpolation.
|
||||
|
||||
The result is fairly good. I noticed some significant artifacts while watching anime, but it works well with movies. I’m guessing that it is harder to track the motion in animations since they are generally exaggerated.
|
||||
|
||||
One thing to keep in mind, however, is performance. With rel=2, viewing a 1080p video results in around 90% CPU usage across all cores and 1.6 GBs of ram on my Intel i7 4700MQ. With rel=1, CPU usage goes down to about 60% per core. This process is very heavy on the processor, and you may have trouble unless you have a fast CPU.
|
24
gemini/pass.gmi
Normal file
24
gemini/pass.gmi
Normal file
|
@ -0,0 +1,24 @@
|
|||
~~~~~~~~
|
||||
|
||||
title: Switching to pass
|
||||
|
||||
## date: 2015-03-30
|
||||
|
||||
For some time, I used LastPass to store my passwords. While LastPass works well, it doesn’t fit into the keyboard driven setup I have. I have been looking into alternatives for some time, I looked into KeePassX but just like LastPass, it doesn’t give me any ways to set up keyboard shortcuts. On the other hand, and I recently came across pass[a], and it provides everything I want.
|
||||
|
||||
=> http://www.passwordstore.org/ [a]
|
||||
|
||||
```<!--more-->
|
||||
```
|
||||
|
||||
Pass uses GPG keys to encrypt the passwords, and git to keep revisions and backups. It integrates well with the shell, and there is a dmenu script, a Firefox plugin and an Android app. All the passwords are just GPG enrypted files, stored in some folders anyway, so you don’t need anything special to work with them.
|
||||
|
||||
=> /img/passmenu.png passmenu, the dmenu pass script
|
||||
|
||||
So first, I needed to migrate my passwords from LastPass to pass. The website lists some scripts for migration, but sadly I missed that when I first looked at the page. So I decided to write a python script to handle the migration[a] myself. It inserts all passwords in domain/username format, and if there is any extra data written, it is added after the password as well. Secure notes are placed into their own folder, and any “Generated Password for …” entries are skipped. If you’re migrating from LastPass to pass, feel free to give it a try. If you are taking an export from their website however, do make sure that there is no whitespace before and after the csv.
|
||||
|
||||
=> https://gist.github.com/SeriousBug/e9f33873d10ad944cbe6 [a]
|
||||
|
||||
=> /img/password_store.png Password Store, the pass Android app
|
||||
|
||||
I certainly recommend trying out pass. It works very well, and it fits in with the unix philosophy.
|
76
gemini/publications.gmi
Normal file
76
gemini/publications.gmi
Normal file
|
@ -0,0 +1,76 @@
|
|||
~~~~~~~~
|
||||
|
||||
## no-ttr: true
|
||||
|
||||
```<div> <div class="publication">
|
||||
## Crafty: Efficient, HTM-Compatible Persistent Transactions
|
||||
<div class="authors">Kaan Genç, Michael D. Bond, and Guoqing Harry Xu</div>
|
||||
<div class="conf">ACM SIGPLAN Conference on Programming Language Design and Implementation <a href="https://pldi20.sigplan.org/home">(PLDI 2020)</a>, Online, June 2020</div>
|
||||
```
|
||||
|
||||
Crafty is a library for transactional storage, built for new non-volatile memory hardware. Taking advantage of hardware transactional capabilities of modern CPUs, it provides a low-overhead option that also eliminates the need for additional concurrency control.
|
||||
|
||||
Talk[a] Paper[b] Extended Paper[c] Implementation[d] Poster[e] </div>
|
||||
|
||||
=> https://www.youtube.com/watch?v=wdVLlQXV1to [a]
|
||||
=> https://dl.acm.org/doi/10.1145/3385412.3385991 [b]
|
||||
=> https://arxiv.org/pdf/2004.00262.pdf [c]
|
||||
=> https://github.com/PLaSSticity/Crafty [d]
|
||||
=> /extra/Crafty Poster.pdf [e]
|
||||
|
||||
```<div class="publication">
|
||||
## Dependence Aware, Unbounded Sound Predictive Race Detection
|
||||
<div class="authors">Kaan Genç, Jake Roemer, Yufan Xu, and Michael D. Bond</div>
|
||||
<div class="conf">ACM SIGPLAN International Conference on Object-Oriented Programming, Systems, Languages, and Applications <a href="https://2019.splashcon.org/track/splash-2019-oopsla">(OOPSLA 2019)</a>, Athens, Greece, October 2019</div>
|
||||
```
|
||||
|
||||
This paper presents 2 data race detection analyses which analyze a single run of a program to predict data races that can happen in other runs. These analyses take advantage of data and control flow dependence to accurately understand how the analyzed program works, expanding what races can be predicted.
|
||||
|
||||
Talk[a] Extended Paper (updated version)[b] Paper[c] Corrigendum to paper[d] Implementation[e] Poster[f] </div>
|
||||
|
||||
=> https://www.youtube.com/watch?v=YgZWnc31tVQ [a]
|
||||
=> https://arxiv.org/pdf/1904.13088.pdf [b]
|
||||
=> https://dl.acm.org/doi/10.1145/3360605 [c]
|
||||
=> https://dl.acm.org/action/downloadSupplement?doi=10.1145%2F3360605&file=3360605-corrigendum.pdf [d]
|
||||
=> https://github.com/PLaSSticity/SDP-WDP-implementation [e]
|
||||
=> /extra/DepAware Poster.pdf [f]
|
||||
|
||||
```<div class="publication">
|
||||
## SmartTrack: Efficient Predictive Race Detection
|
||||
<div class="authors">Jake Roemer, Kaan Genç, and Michael D. Bond</div>
|
||||
<div class="conf">ACM SIGPLAN Conference on Programming Language Design and Implementation <a href="https://pldi20.sigplan.org/home">(PLDI 2020)</a>, Online, June 2020 </div>
|
||||
```
|
||||
|
||||
Predictive data race detection methods greatly improve the number of data races found, but they typically significantly slow down programs compared to their non-predictive counterparts. SmartTrack, through improved analyses and clever algorithms, reduces their overhead to just around non-predictive analyses without impacting their performance.
|
||||
|
||||
Paper[a] Extended Paper[b] </div>
|
||||
|
||||
=> http://web.cse.ohio-state.edu/~mikebond/smarttrack-pldi-2020.pdf [a]
|
||||
=> https://arxiv.org/pdf/1905.00494.pdf [b]
|
||||
|
||||
```<div class="publication">
|
||||
## High-Coverage, Unbounded Sound Predictive Race Detection
|
||||
<div class="authors">Jake Roemer, Kaan Genç, and Michael D. Bond</div>
|
||||
<div class="conf">ACM SIGPLAN Conference on Programming Language Design and Implementation <a href="https://pldi18.sigplan.org/">(PLDI 2018)</a>, Philadelphia, PA, USA, June 2018</div>
|
||||
```
|
||||
|
||||
Predictive data race detection methods typically walk a tight line between predicting more races and avoiding false races. This paper presents a new analysis that can predict more races, and a method to efficiently eliminate false races.
|
||||
|
||||
Paper[a] Extended Paper[b] </div> </div>
|
||||
|
||||
=> http://web.cse.ohio-state.edu/~bond.213/vindicator-pldi-2018.pdf [a]
|
||||
=> http://web.cse.ohio-state.edu/~bond.213/vindicator-pldi-2018-xtr.pdf [b]
|
||||
|
||||
# Activities
|
||||
|
||||
PLDI 2021[a] Artifact Evaluation Committee member
|
||||
|
||||
=> https://pldi21.sigplan.org/track/pldi-2021-PLDI-Research-Artifacts [a]
|
||||
|
||||
ASPLOS 2021[a] Artifact Evaluation Committee member
|
||||
|
||||
=> https://asplos-conference.org/2021/ [a]
|
||||
|
||||
OOPSLA 2020[a] Artifact Evaluation Committee member
|
||||
|
||||
=> https://2020.splashcon.org/track/splash-2020-Artifacts [a]
|
94
gemini/raid.gmi
Normal file
94
gemini/raid.gmi
Normal file
|
@ -0,0 +1,94 @@
|
|||
~~~~~~~~
|
||||
|
||||
title: My local data storage setup
|
||||
|
||||
## date: 2022-03-10
|
||||
|
||||
Recently, I’ve needed a bit more storage. In the past I’ve relied on Google Drive, but if you need a lot of space Google Drive becomes prohibitively expensive. The largest option available, 2 TB, runs you $100 a year at the time of writing. While Google Drive comes with a lot of features, it also comes with a lot of privacy concerns, and I need more than 2 TB anyway. Another option would be Backblaze B2 or AWS S3, but the cost is even higher. Just to set a point of comparison, 16 TB of storage would cost $960 a year with B2 and a whopping $4000 a year with S3.
|
||||
|
||||
Luckily in reality, the cost of storage per GB has been coming down steadily. Large hard drives are cheap to come by, and while these drives are not incredibly fast, they are much faster than the speed of my internet connection. Hard drives it is then!
|
||||
|
||||
While I could get a very large hard drive, it’s generally a better idea to get multiple smaller hard drives. That’s because these drives often offer a better $/GB rate, but also because it allows us to mitigate the risk of data loss. So after a bit of search, I found these “Seagate Barracuda Compute 4TB” drives. You can find them on Amazon[a] or BestBuy[b].
|
||||
|
||||
=> https://www.amazon.com/gp/product/B07D9C7SQH/ [a]
|
||||
=> https://www.bestbuy.com/site/seagate-barracuda-4tb-internal-sata-hard-drive-for-desktops/6387158.p?skuId=6387158 [b]
|
||||
|
||||
These hard drives are available for $70 each at the time I’m writing this,and I bought 6 of them. This gets me to around $420, plus a bit more for SATA cables. Looking at Backblaze Hard Drive Stats[a], I think it’s fair to assume these drives will last at least 5 years. Dividing the cost by the expected lifetime, that gets me $84 per year, far below what the cloud storage costs! It’s of course not as reliable, and it requires maintenance on my end, but the difference in price is just too far to ignore.
|
||||
|
||||
=> https://www.backblaze.com/blog/backblaze-drive-stats-for-2021/ [a]
|
||||
|
||||
## Setup
|
||||
|
||||
I decided to set this all up inside my desktop computer. I have a large case so fitting all the hard drives in is not a big problem, and my motherboard does support 6 SATA drives (in addition to the NVMe that I’m booting off of). I also run Linux on my desktop computer, so I’ve got all the required software available.
|
||||
|
||||
For the software side of things, I decided to go with mdadm and ext4. There are also other options available like ZFS (not included in the linux kernel) or btrfs (raid-5 and raid-6 are known to be unreliable), but this was the setup I found the most comfortable and easy to understand for me. How it works is that mdadm combines the disks and presents it as a block device, then ext4 formats and uses the block device the same way you use it with any regular drive.
|
||||
|
||||
### Steps
|
||||
|
||||
I was originally planning to write the steps I followed here, but in truth I just followed whatever the ArchLinux wiki[a] told me. So I’ll just recommend you follow that as well.
|
||||
|
||||
=> https://wiki.archlinux.org/title/RAID#Installation [a]
|
||||
|
||||
The only thing I’ll warn you is that the wiki doesn’t clearly note just how long this process takes. It took almost a week for the array to build, and until the build is complete the array runs at a reduced performance. Be patient, and just give it some time to finish. As a reminder, you can always check the build status with cat /dev/mdstat.
|
||||
|
||||
## Preventative maintenance
|
||||
|
||||
Hard drives have a tendency to fail, and because RAID arrays are resilient, the failures can go unnoticed. You need to regularly check that the array is okay. Unfortunately, while there are quite a few resources online on how to set up RAID, very few of them actually talk about how to set up scrubs (full scans to look for errors) and error monitoring.
|
||||
|
||||
For my setup, I decided to set up systemd to check and report issues. For this, I first set up 2 timers: 1 that checks if there are any reported errors on the RAID array, and another that scrubs the RAID array. Systemd timers are 2 parts, a service file and a timer file, so here’s all the files.
|
||||
|
||||
* array-scrub.service ```toml [Unit] Description=Scrub the disk array After=multi-user.target OnFailure=[a]
|
||||
|
||||
=> report-failure-email@array-scrub.service [a]
|
||||
|
||||
[Service] Type=oneshot User=root ExecStart=bash -c ‘/usr/bin/echo check > /sys/block/md127/md/sync_action’
|
||||
|
||||
[Install] WantedBy=multi-user.target ```
|
||||
|
||||
* array-scrub.timer ```toml [Unit] Description=Periodically scrub the array.
|
||||
|
||||
[Timer] OnCalendar=Sat --* 05:00:00
|
||||
|
||||
[Install] WantedBy=timers.target ```
|
||||
|
||||
The timer above is the scrub operation, it tells RAID to scan the drives for errors. It actually takes up to a couple days in my experience for the scan to complete, so I run it once a week.
|
||||
|
||||
* array-report.service ```toml [Unit] Description=Check raid array errors that were found during a scrub or normal operation and report them. After=multi-user.target OnFailure=[a]
|
||||
|
||||
=> report-failure-email@array-report.service [a]
|
||||
|
||||
[Service] Type=oneshot ExecStart=/usr/bin/mdadm -D /dev/md127
|
||||
|
||||
[Install] WantedBy=multi-user.target ```
|
||||
|
||||
* array-report.timer ```toml [Unit] Description=Periodically report any issues in the array.
|
||||
|
||||
[Timer] OnCalendar=daily
|
||||
|
||||
[Install] WantedBy=timers.target ```
|
||||
|
||||
And this timer above checks the RAID array status to see if there were any errors found. This timer runs much more often (once a day), because it’s instant, and also because RAID can find errors during regular operation even when you are not actively running a scan.
|
||||
|
||||
### Error reporting
|
||||
|
||||
Another important thing here is this line in the service file: toml OnFailure=report-failure-email@array-report.service
|
||||
|
||||
The automated checks are of no use if I don’t know when something actually fails. Luckily, systemd can run a service when another service fails, so I’m using this to report failures to myself. Here’s what the service file looks like:
|
||||
|
||||
* report-failure-email@.service ```toml [Unit] Description=status email for %i to user
|
||||
|
||||
[Service] Type=oneshot ExecStart=/usr/local/bin/systemd-email address %i User=root ```
|
||||
|
||||
* /usr/local/bin/systemd-email ```sh #!/bin/sh
|
||||
|
||||
/usr/bin/sendmail -t <<ERRMAIL To: homelab@bgenc.net From: systemd <root@$HOSTNAME> Subject: Failure on $2 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8
|
||||
|
||||
$(systemctl status –lines 100 –no-pager “$2”) ERRMAIL ```
|
||||
|
||||
The service just runs this shell script, which is just a wrapper around sendmail. The %i in the service is the part after @ when you use the service, you can see that the OnFailure hook puts array-report after the @ which then gets passed to the email service, which then passes it on to the mail script.
|
||||
|
||||
To send emails, you also need to set up sendmail. I decided to install msmtp[a], and set it up to use my GMail account to send me an email.
|
||||
|
||||
=> https://wiki.archlinux.org/title/Msmtp [a]
|
||||
|
||||
To test if the error reporting works, edit the array-report.service and change the line ExecStart line to ExecStart=false. Then run the report service with systemd start array-report.service, you should now get an email letting you know that the array-report service failed, and attaches the last 100 lines of the service status to the email.
|
0
getting-deus-ex-running-on-linux.gmi
Normal file
0
getting-deus-ex-running-on-linux.gmi
Normal file
0
publications.gmi
Normal file
0
publications.gmi
Normal file
|
@ -21,7 +21,7 @@
|
|||
(when (not= slug "index") [:a.home {:href "/"} "Home"])
|
||||
[:img.picture {:alt "A photo of Kaan, after his OOPSLA 2019 talk." :src "/img/profile.jpg"}]
|
||||
[:div.name "Kaan Barmore-Genç"]
|
||||
[:div.title "M.S. Software Engineer"]
|
||||
[:div.title "M.S."]
|
||||
[:div.spacer]
|
||||
[:div.title "Software Engineer"]
|
||||
[:div.affiliation [:a {:href "http://dendron.so/"} "Dendron"]]
|
||||
|
|
Loading…
Reference in a new issue