<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title>Duje Mihanović's Site</title><id>http://dujemihanovic.xyz/</id><updated>2025-06-11T17:23:47Z</updated><link href="http://dujemihanovic.xyz/"/><link rel="self" href="http://dujemihanovic.xyz/index.xml"/><author><name>Duje Mihanović</name><email>duje@dujemihanovic.xyz</email><uri>http://dujemihanovic.xyz/</uri></author><generator uri="https://gohugo.io/">Hugo</generator><entry><id>http://dujemihanovic.xyz/posts/fixing-acer/</id><link rel="alternate" href="http://dujemihanovic.xyz/posts/fixing-acer/"/><title>Fixing a trash-picked Acer Aspire E1-731</title><updated>2025-06-11T17:23:47Z</updated><published>2025-06-11T17:14:45Z</published><content type="html">&lt;p&gt;Recently I found an Acer E1-731 on a random junk pile. At a first glance it
seemed relatively modern &lt;em&gt;(which I concluded from the presence of USB 3.0)&lt;/em&gt;, but
also heavily water damaged. While most would conclude that it cannot be saved at
that point, I decided to take it with me anyway to see if there&amp;rsquo;s anything worth
salvaging and try to repair the laptop itself.&lt;/p&gt;
&lt;h2 id="first-impressions"&gt;First impressions&lt;/h2&gt;
&lt;p&gt;The first thing I did upon taking the laptop was to remove the main battery, as
any current would massively speed up corrosion of the board. Once the laptop was
at my workstation, I took off the bottom cover and found that what had been
exposed of the motherboard was unsurprisingly rather dirty, but there was no
corrosion to be found.&lt;/p&gt;
&lt;p&gt;&lt;img src="./dirty.jpg" alt="An example of the dirt on the board"&gt;&lt;/p&gt;
&lt;p&gt;With the back cover gone I was able to remove the 4GB DDR3 SODIMM, 500GB WD
Blue hard drive and an Atheros WiFi card, which were then dried and the SODIMM
and WiFi further cleaned up with IPA and again dried. With these aside, I
continued disassembling the laptop to dry everything as quickly as possible and
also to remove the RTC battery &lt;em&gt;(for the same reason as the main battery)&lt;/em&gt;. Not
coincidentally, there were a few small corroded areas around the RTC battery
socket, but besides that the board was in pretty good shape.&lt;/p&gt;
&lt;p&gt;With all of the parts dried and therefore safe from any further corrosion, I
decided to test the salvaged RAM and HDD. Both ended up working and the HDD is
also perfectly healthy &lt;em&gt;(judging by the reallocated sector count, which is 0)&lt;/em&gt;,
which alone made picking up this laptop worthwhile. The main objective however
was to repair the laptop itself, so then I proceeded to have a look at the
motherboard itself.&lt;/p&gt;
&lt;h2 id="diagnosing-the-board"&gt;Diagnosing the board&lt;/h2&gt;
&lt;p&gt;After having made sure that the board was dry and clean of corrosion, I detached
the DC in jack and power button from the bottom case and hooked them up to the
motherboard to give it a test boot. However, it gave no signs of life: no LED
lit up at all and pressing the power button also did nothing.&lt;/p&gt;
&lt;p&gt;My first action was to measure the voltage at the power button header and I
found that it was abnormally low &lt;em&gt;(~300-400mV for a signal meant to be 3.3V)&lt;/em&gt;.
After some more probing around I found out that the main rail was also gone,
which I traced down to the DC in circuit. To be more specific, it seemed that
something was wrong with the DC in MOSFET as its drain was at the expected ~20V,
but the source at just ~900mV.&lt;/p&gt;
&lt;p&gt;At this point, I needed schematics and a boardview, as the board itself is
devoid of any component markings with the exception of screw holes and
connectors. Fortunately, they were rather easy to find &lt;em&gt;(&amp;ldquo;VA70/VG70 rev 2.1
schematic boardview&amp;rdquo;)&lt;/em&gt; and so I proceeded to ask and search around to see what
could be going wrong. I first checked the downstream VRMs for any shorts or
overloads which were said to potentially cause this, but I found nothing. Next,
I went through the charge controller circuit as suggested by a certain forum
post, but also found nothing wrong there.&lt;/p&gt;
&lt;p&gt;Eventually, I had a look at the 2nd DC in MOSFET &lt;em&gt;(&lt;code&gt;Q8802&lt;/code&gt;)&lt;/em&gt;, right between the
1st one &lt;em&gt;(&lt;code&gt;Q8800&lt;/code&gt;)&lt;/em&gt; and a battery charging MOSFET. I have found that the
R&lt;sub&gt;DS(off)&lt;/sub&gt; of this MOSFET was just about ~500Ω, which I suspected to be
extremely low considering a enhancement-mode MOSFET is not meant to conduct at
all while off. I desoldered this MOSFET and when powering the board again, there
was ~20V on both the drain and source of the 1st DC in MOSFET.&lt;/p&gt;
&lt;p&gt;&lt;img src="./dcin.png" alt="DC in circuit as seen on the boardview"&gt;&lt;/p&gt;
&lt;p&gt;From that &lt;strong&gt;and the apparent fact that nothing was wrong downstream&lt;/strong&gt;, I
concluded that the 2nd DC in MOSFET was faulty and needed a replacement.&lt;/p&gt;
&lt;h2 id="sourcing-a-replacement-mosfet"&gt;Sourcing a replacement MOSFET&lt;/h2&gt;
&lt;p&gt;I decided to buy the replacements from AliExpress as usual. There is, of course,
a risk of getting fakes, but in this case the MOSFETs I bought are genuine.
Specifically, the MOSFET in question is an &lt;code&gt;IRFHS8342&lt;/code&gt;, and I bought the
replacements &lt;a href="https://www.aliexpress.com/item/1005006286498650.html"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="replacing-the-mosfet"&gt;Replacing the MOSFET&lt;/h2&gt;
&lt;p&gt;After the MOSFETs arrived, I soldered one onto the board. The specific procedure
I used was to tin the pads with my iron in advance and apply flux liberally
before applying hot air.&lt;/p&gt;
&lt;p&gt;When I plugged in the board &lt;em&gt;(after letting it cool down, of course)&lt;/em&gt;, it would
click at a regular interval and otherwise show no signs of life. This was still
progress, so while remaining cautiously optimistic I made a few more
measurements around the board. The main rail voltage had now gone up to
oscillating at around 4V, which could suggest that there&amp;rsquo;s a VRM being
overloaded, but just like the previous time I found no shorts anywhere.&lt;/p&gt;
&lt;p&gt;While desoldering the dead MOSFET, I had accidentally knocked two capacitors
between it and the other MOSFET &lt;em&gt;(&lt;code&gt;C8802&lt;/code&gt; and &lt;code&gt;C8803&lt;/code&gt;)&lt;/em&gt; off the board. Just to
rule out these two causing issues, I went ahead with soldering these two back
on. &lt;code&gt;C8802&lt;/code&gt; was soldered on easily, but on the other hand I dropped and lost
&lt;code&gt;C8803&lt;/code&gt; while trying to solder it back on. Nevertheless, with &lt;code&gt;C8802&lt;/code&gt; again
present the board finally powered up!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;For reference, here&amp;rsquo;s these 2 capacitors in the schematic:&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="./dcin2.png" alt="DC in circuit as seen on schematic"&gt;&lt;/p&gt;
&lt;p&gt;With the board finally showing signs of life, the only thing remaining to do was
to check whether it outputs an image. I initially tried HDMI, but there was no
output at all. On the other hand, with the internal display connected it POSTed
straight away. From here it was simply a matter of installing a new RTC battery
and reassembling the laptop.&lt;/p&gt;
&lt;h2 id="final-words"&gt;Final words&lt;/h2&gt;
&lt;p&gt;The laptop now runs well, but not without flaws. The water had sadly not been
kind to the display and as a result the light guide is visibly distorted, which
doesn&amp;rsquo;t really have an impact on usage but isn&amp;rsquo;t nice to see either.&lt;/p&gt;
&lt;p&gt;The main battery was found to be dangerously discharged &lt;em&gt;(~1.4V per cell)&lt;/em&gt;,
however the BMS successfully revived it and reports a full charge capacity of
~30Wh with a design capacity of 48.4Wh, leading to a wear level of around 39%. A
battery calibration together with time will reveal whether this figure is true,
but I am nevertheless exceedingly happy to have a working battery.&lt;/p&gt;
&lt;p&gt;Finally, I believe that the clicking thing serves to confirm the importance of
&lt;strong&gt;replacing dead filter capacitors&lt;/strong&gt;. Even if the board booted without &lt;code&gt;C8802&lt;/code&gt;,
it&amp;rsquo;s not impossible that there would have been stability issues later on. I have
since found &lt;code&gt;C8803&lt;/code&gt; again, however I will probably not disassemble the whole
laptop again just to solder it back on. If I do end up tearing it down again for
another reason or the laptop shows any instability, I will take the time to
solder it back on.&lt;/p&gt;</content><summary type="html">&lt;p&gt;Recently I found an Acer E1-731 on a random junk pile. At a first glance it
seemed relatively modern &lt;em&gt;(which I concluded from the presence of USB 3.0)&lt;/em&gt;, but
also heavily water damaged. While most would conclude that it cannot be saved at
that point, I decided to take it with me anyway to see if there&amp;rsquo;s anything worth
salvaging and try to repair the laptop itself.&lt;/p&gt;
&lt;h2 id="first-impressions"&gt;First impressions&lt;/h2&gt;
&lt;p&gt;The first thing I did upon taking the laptop was to remove the main battery, as
any current would massively speed up corrosion of the board. Once the laptop was
at my workstation, I took off the bottom cover and found that what had been
exposed of the motherboard was unsurprisingly rather dirty, but there was no
corrosion to be found.&lt;/p&gt;</summary></entry><entry><id>http://dujemihanovic.xyz/posts/caddy-git-http/</id><link rel="alternate" href="http://dujemihanovic.xyz/posts/caddy-git-http/"/><title>Configuring Git over HTTP(S) with Caddy</title><updated>2025-05-17T17:16:22Z</updated><published>2025-05-17T16:04:13Z</published><content type="html">&lt;p&gt;Since I switched to Caddy from Nginx, the only thing that worked on Nginx but I
just couldn&amp;rsquo;t get working on Caddy was cloning Git repositories over HTTP.&lt;/p&gt;
&lt;p&gt;I had initially tried sort of backporting the Nginx configuration, which didn&amp;rsquo;t
work. After some time I ran into &lt;a href="https://www.jamesatkins.com/posts/git-over-http-with-caddy/"&gt;James Atkins'
post&lt;/a&gt; in which he
detailed how he tackled this issue. Again, this didn&amp;rsquo;t work for me &lt;em&gt;(possibly
because I use GitWeb rather than cgit)&lt;/em&gt;, so I ended up just configuring a Git
daemon as a workaround until I eventually figure it out.&lt;/p&gt;
&lt;p&gt;That has finally happened, so here I&amp;rsquo;ll share my working configuration and try
to explain it.&lt;/p&gt;
&lt;h2 id="the-configuration"&gt;The configuration&lt;/h2&gt;
&lt;p&gt;First, let&amp;rsquo;s see the configuration itself:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;@git_cgi path_regexp &amp;#34;^.*/(HEAD|info/refs|objects/info/[^/]+|git-upload-pack|git-receive-pack)$&amp;#34;
@git_static path_regexp &amp;#34;^.*/objects/([0-9a-f]{2}/[0-9a-f]{38}|pack/pack-[0-9a-f]{40}\.(pack|idx))$&amp;#34;
@push-info query service=git-receive-pack
@push path_regexp &amp;#34;^.*/git-receive-pack$&amp;#34;
root / /usr/share/gitweb
try_files {uri} gitweb.cgi
handle @git_cgi {
reverse_proxy unix//run/fcgiwrap.socket {
transport fastcgi {
env SCRIPT_FILENAME /usr/lib/git-core/git-http-backend
env GIT_PROJECT_ROOT /var/lib/git
env REQUEST_METHOD {method}
env QUERY_STRING {query}
env PATH_INFO {path}
}
}
}
handle @git_static {
file_server {
root /var/lib/git
}
}
basicauth @push bcrypt restricted {
}
basicauth @push-info bcrypt restricted {
}
reverse_proxy unix//run/fcgiwrap.socket {
transport fastcgi {
env GITWEB_CONFIG /etc/gitweb.conf
split .cgi
}
}
handle /static/* {
file_server {
root /usr/share/gitweb
}
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="explanation"&gt;Explanation&lt;/h2&gt;
&lt;h3 id="matchers"&gt;Matchers&lt;/h3&gt;
&lt;p&gt;The first two matchers &lt;em&gt;(&lt;code&gt;@git_{cgi,static}&lt;/code&gt;)&lt;/em&gt; are for repository data, of which
the first matcher is handled by &lt;code&gt;git-http-backend&lt;/code&gt; while the other is just plain
old files which are served by Caddy for performance reasons.&lt;/p&gt;
&lt;p&gt;The other two are for pushing over HTTP, which will be covered later.&lt;/p&gt;
&lt;h3 id="root-and-try_files"&gt;&lt;code&gt;root&lt;/code&gt; and &lt;code&gt;try_files&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;My &lt;code&gt;root&lt;/code&gt; directive may seem unusual at first since it matches &lt;code&gt;/&lt;/code&gt; instead of
&lt;code&gt;*&lt;/code&gt;, however this was necessary because otherwise all requests, including the
ones covered by the &lt;code&gt;@git_*&lt;/code&gt; matchers ended up being handled by GitWeb with
predictable results.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;try_files&lt;/code&gt; directive simply uses the GitWeb CGI script as the index
document.&lt;/p&gt;
&lt;h3 id="reverse_proxy"&gt;&lt;code&gt;reverse_proxy&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The &amp;ldquo;root&amp;rdquo; &lt;code&gt;reverse_proxy&lt;/code&gt; is almost not worth explaining; it simply makes Caddy
run GitWeb through FastCGI.&lt;/p&gt;
&lt;h3 id="the-various-handles"&gt;The various &lt;code&gt;handle&lt;/code&gt;s&lt;/h3&gt;
&lt;p&gt;This is the interesting part.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;/static/*&lt;/code&gt; handle takes care of GitWeb&amp;rsquo;s static files, which include a
JavaScript file, a stylesheet and some (fav)icons.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;@git_cgi&lt;/code&gt; handle is probably the most important one and the next
troublemaker after &lt;code&gt;root&lt;/code&gt;: after resolving &lt;code&gt;root&lt;/code&gt; any &lt;code&gt;git clone&lt;/code&gt; would result
in a HTTP 500 &lt;em&gt;(actually, not cloning, but &lt;code&gt;curl&lt;/code&gt;ing &lt;code&gt;&amp;lt;repo&amp;gt;/info/refs&lt;/code&gt;)&lt;/em&gt;. The
gist of it is that &lt;code&gt;git-http-backend&lt;/code&gt; relies on a number of environment values
which do not seem to be filled in by Caddy, so it had to be done manually &lt;em&gt;(for
some reason, apparently only I seem to have to do this)&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Figuring out what had to be added was puzzling, as FastCGI did not seem to have
been logging in either the journal or somewhere in &lt;code&gt;/var/log&lt;/code&gt;, so I ended up
manually running &lt;code&gt;git-http-backend&lt;/code&gt; with the aforementioned environment
variables and that way I could know why the backend was failing. From there it
was just a matter of adding the required environment variables to make the
backend happy.&lt;/p&gt;
&lt;p&gt;Particularly worth elaborating are &lt;code&gt;{path}&lt;/code&gt; and &lt;code&gt;{query}&lt;/code&gt;. &lt;code&gt;git clone&lt;/code&gt; will
issue a GET request on &lt;code&gt;/&amp;lt;repo&amp;gt;.git/info/refs?service=git-upload-pack&lt;/code&gt;, and the
backend does not like having the service query in its &lt;code&gt;PATH_INFO&lt;/code&gt;, which would
happen if &lt;code&gt;{uri}&lt;/code&gt; was used instead. The query is still needed for detecting v2
protocol support, so it is passed to the backend separately in &lt;code&gt;QUERY_STRING&lt;/code&gt;.
&lt;code&gt;git-http-backend(1)&lt;/code&gt; has more information on all of this.&lt;/p&gt;
&lt;p&gt;Besides that, I also had to juggle around with permissions on the Git root,
first to make the backend work at all and then to make pushing work; I
eventually settled on &lt;code&gt;git:www-data&lt;/code&gt;, &lt;code&gt;775&lt;/code&gt; &lt;em&gt;(on directories)&lt;/em&gt; and &lt;code&gt;sudo -u www-data git config --global safe.directory '*'&lt;/code&gt; &lt;em&gt;(user names might differ
between distros, mine is Debian 12)&lt;/em&gt;.&lt;/p&gt;
&lt;h3 id="basicauth"&gt;&lt;code&gt;basicauth&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;They add a layer of authentication on authenticated pushes. As
&lt;code&gt;git-http-backend(1)&lt;/code&gt; suggests, I have added authentication to both ref
advertisement and the call to &lt;code&gt;git-receive-pack&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you don&amp;rsquo;t need/want/whatever HTTP pushing, you could drop these directives
and the two push matchers. I&amp;rsquo;d also recommend dropping &lt;code&gt;|git-receive-pack&lt;/code&gt; from
the &lt;code&gt;@git_cgi&lt;/code&gt; regexp to make sure it may not be called.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: the directive is &lt;code&gt;basic_auth&lt;/code&gt; on newer Caddy versions (2.6.2 is currently
packaged in Debian 12). Keep this in mind if Caddy errors out here for you.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="final-words"&gt;Final words&lt;/h2&gt;
&lt;p&gt;While this configuration works fine, I suspect it may be optimized &lt;em&gt;(read:
shortened)&lt;/em&gt; further. In particular, I suspect the push matchers and their
respective &lt;code&gt;basicauth&lt;/code&gt; directives could be squashed together, but I can&amp;rsquo;t really
think of a way to do that &lt;em&gt;(or any other potential optimization)&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;If you have any ideas on this or questions in general, feel free to use the
reply button below or &lt;a href="http://dujemihanovic.xyz/contact"&gt;contact&lt;/a&gt; me via another medium.&lt;/p&gt;</content><summary type="html">&lt;p&gt;Since I switched to Caddy from Nginx, the only thing that worked on Nginx but I
just couldn&amp;rsquo;t get working on Caddy was cloning Git repositories over HTTP.&lt;/p&gt;
&lt;p&gt;I had initially tried sort of backporting the Nginx configuration, which didn&amp;rsquo;t
work. After some time I ran into &lt;a href="https://www.jamesatkins.com/posts/git-over-http-with-caddy/"&gt;James Atkins'
post&lt;/a&gt; in which he
detailed how he tackled this issue. Again, this didn&amp;rsquo;t work for me &lt;em&gt;(possibly
because I use GitWeb rather than cgit)&lt;/em&gt;, so I ended up just configuring a Git
daemon as a workaround until I eventually figure it out.&lt;/p&gt;</summary></entry><entry><id>http://dujemihanovic.xyz/posts/fixing-mouse/</id><link rel="alternate" href="http://dujemihanovic.xyz/posts/fixing-mouse/"/><title>Fixing the scroll wheel on a SteelSeries Rival 310</title><updated>2024-09-14T19:47:16Z</updated><published>2024-09-14T16:00:03Z</published><content type="html">&lt;p&gt;If you&amp;rsquo;ve been using a computer mouse for a while, you might get an issue where
the scroll wheel moves randomly, jumps around while scrolling or at times
doesn&amp;rsquo;t respond at all. My mouse also developed this issue recently, but luckily
it&amp;rsquo;s very easy to fix. The only thing that happens is various gunk builds up on
the wheel sensor and this causes misreadings, so obviously cleaning up that gunk
makes the wheel work like new again. Here I&amp;rsquo;ll show how I did that on my mouse,
but the general idea applies to any mouse.&lt;/p&gt;
&lt;h2 id="what-you-need"&gt;What you need&lt;/h2&gt;
&lt;p&gt;No matter what, you&amp;rsquo;ll need the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A mouse&lt;/li&gt;
&lt;li&gt;Corresponding screwdriver(s) - &lt;em&gt;In 99% (if not 100%) of cases a Phillips #1 will
be enough&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Some way to remove the gunk: toothbrush and/or blowing&lt;/li&gt;
&lt;li&gt;A working brain cell&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If the screws are hidden under the mouse feet &lt;em&gt;(like in my case)&lt;/em&gt;, you might
also want to have a hairdryer or hot air station together with a sharp object to
remove the feet without damaging them. To do this, heat up the feet &lt;em&gt;(on low
heat, obviously; I used 100C as that&amp;rsquo;s the least my hot air station can do)&lt;/em&gt;
until you can no longer touch them, then pry them away with the sharp object. I
don&amp;rsquo;t think I did the best job at this, but I was able to reapply them
acceptably well after the repair.&lt;/p&gt;
&lt;h2 id="fixing-the-mouse"&gt;Fixing the mouse&lt;/h2&gt;
&lt;p&gt;First, for reference, I&amp;rsquo;ll throw in a picture of the mouse:&lt;/p&gt;
&lt;p&gt;&lt;img src="./mouse.jpg" alt="The mouse"&gt;&lt;/p&gt;
&lt;p&gt;After removing the feet, the screws become visible:&lt;/p&gt;
&lt;p&gt;&lt;img src="./mousebtm.jpg" alt="Bottom of the mouse"&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Here you can see why I said I didn&amp;rsquo;t do the best job of removing the feet: some
glue remains on the mouse. I&amp;rsquo;m quite sure that after a perfect removal it would
all be on the feet and this would allow them to be reapplied perfectly, but as I
said I was able to do so well enough IMO.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;After unscrewing the 4 screws revealed under the feet, the bottom and top halves
of the mouse come apart easily. From there I was able to take a look at the
scroll wheel assembly, and there sure was something to see:&lt;/p&gt;
&lt;p&gt;&lt;img src="./wheel2.jpg" alt="Scroll wheel"&gt;
&lt;img src="./wheel.jpg" alt="Scroll wheel, again"&gt;&lt;/p&gt;
&lt;p&gt;To get to the scroll wheel in this case, I had to unscrew that &lt;code&gt;LED BOARD&lt;/code&gt;, take
it out of the wheel &lt;em&gt;(which took a few seconds)&lt;/em&gt; and then unscrew the entire
mainboard from the chassis. Once that is done, I attacked both the wheel and the
sensor with a toothbrush and blown air and then gave the rest of the mouse a
much needed clean while at it. This picture of the area under the board gives a
good idea of how dirty the mouse was:&lt;/p&gt;
&lt;p&gt;&lt;img src="./btm.jpg" alt="Dirt"&gt;&lt;/p&gt;
&lt;p&gt;Once I cleaned that up somewhat, putting the 2 boards and then 2 halves of the
chassis back in place was pretty easy. To test the mouse, I screwed in 2 of the
chassis screws diagonally, plugged the mouse into my PC and hoped everything
would work, which it did. After the other 2 screws came reapplying the feet;
because I had not removed them perfectly, they didn&amp;rsquo;t seem to pop back in well.
I worked around this by pressing them against with the chassis with the sharp
object, and as I have already said this gave an acceptable result.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;With that, the mouse was back in full order. One issue I didn&amp;rsquo;t fix yet is the
side panels ungluing after a liquid accident long ago, but I doubt that&amp;rsquo;s worth
describing.&lt;/p&gt;
&lt;p&gt;I hope that in the future I will be able to write about repairs of more complex
devices.&lt;/p&gt;</content><summary type="html">&lt;p&gt;If you&amp;rsquo;ve been using a computer mouse for a while, you might get an issue where
the scroll wheel moves randomly, jumps around while scrolling or at times
doesn&amp;rsquo;t respond at all. My mouse also developed this issue recently, but luckily
it&amp;rsquo;s very easy to fix. The only thing that happens is various gunk builds up on
the wheel sensor and this causes misreadings, so obviously cleaning up that gunk
makes the wheel work like new again. Here I&amp;rsquo;ll show how I did that on my mouse,
but the general idea applies to any mouse.&lt;/p&gt;</summary></entry><entry><id>http://dujemihanovic.xyz/posts/going-offline/</id><link rel="alternate" href="http://dujemihanovic.xyz/posts/going-offline/"/><title>Going offline</title><updated>2024-08-27T13:41:18Z</updated><published>2024-08-27T00:46:42Z</published><content type="html">&lt;p&gt;&lt;a href="http://dujemihanovic.xyz"&gt;dujemihanovic.xyz&lt;/a&gt; will be going offline today,
August 27th, 2024, sometime around noon or afternoon according to UTC and will
remain offline for a bit more than a week.&lt;/p&gt;
&lt;p&gt;An explanation will be posted after the site goes back online.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update&lt;/em&gt;: The shutdown has been called off.&lt;/p&gt;</content><summary type="html">&lt;p&gt;&lt;a href="http://dujemihanovic.xyz"&gt;dujemihanovic.xyz&lt;/a&gt; will be going offline today,
August 27th, 2024, sometime around noon or afternoon according to UTC and will
remain offline for a bit more than a week.&lt;/p&gt;
&lt;p&gt;An explanation will be posted after the site goes back online.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Update&lt;/em&gt;: The shutdown has been called off.&lt;/p&gt;</summary></entry><entry><id>http://dujemihanovic.xyz/posts/skeleton-theme/</id><link rel="alternate" href="http://dujemihanovic.xyz/posts/skeleton-theme/"/><title>Now Available: Skeleton Theme</title><updated>2024-08-25T12:30:02Z</updated><published>2024-08-24T17:15:08Z</published><content type="html">&lt;p&gt;The barebones theme used by my website has been split up into its own
repository. If you&amp;rsquo;re interested, check it out
&lt;a href="https://git.dujemihanovic.xyz/?p=hugo-skeleton.git;a=summary"&gt;here&lt;/a&gt; and an
example commit to actually use it
&lt;a href="https://git.dujemihanovic.xyz/?p=dujemihanovic.xyz.git;a=commit;h=9f594273c05fcb73d06ff92607a8bddb5d0173fb"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Note that I haven&amp;rsquo;t thoroughly split them up quite yet. This means there may be
remaining mentions of my name in the theme. I expect to correct that sometime.&lt;/p&gt;</content><summary type="html">&lt;p&gt;The barebones theme used by my website has been split up into its own
repository. If you&amp;rsquo;re interested, check it out
&lt;a href="https://git.dujemihanovic.xyz/?p=hugo-skeleton.git;a=summary"&gt;here&lt;/a&gt; and an
example commit to actually use it
&lt;a href="https://git.dujemihanovic.xyz/?p=dujemihanovic.xyz.git;a=commit;h=9f594273c05fcb73d06ff92607a8bddb5d0173fb"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Note that I haven&amp;rsquo;t thoroughly split them up quite yet. This means there may be
remaining mentions of my name in the theme. I expect to correct that sometime.&lt;/p&gt;</summary></entry><entry><id>http://dujemihanovic.xyz/posts/freshrss/</id><link rel="alternate" href="http://dujemihanovic.xyz/posts/freshrss/"/><title>Software Review: FreshRSS</title><updated>2024-08-21T12:27:03Z</updated><published>2024-06-08T12:14:37Z</published><content type="html">&lt;p&gt;Most RSS users start off with desktop readers such as Newsboat or Akregator in
order to keep things simple. However, due to certain drawbacks of this approach
&lt;em&gt;(which I will talk about below)&lt;/em&gt; I have looked for an aggregator I can install
on my VPS and use as such. After a bit of research, I have decided to go with
&lt;a href="https://freshrss.org/"&gt;FreshRSS&lt;/a&gt; and here I&amp;rsquo;ll explain why I decided to ditch
Akregator in the first place and why I chose FreshRSS.&lt;/p&gt;
&lt;h2 id="what-even-is-rss"&gt;What even is RSS?&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;If you&amp;rsquo;re already initiated on this subject, feel free to skip to the next
section.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;A practically universal use case for the Internet is reading various blogs and
news. However, as your number of followed blog and news sites builds up, going
through all of them looking for new content becomes a serious chore. To make
things worse, many (generally news) sites are becoming increasingly bloated.
&lt;em&gt;(Not just technologically, but also with garbage content!)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;RSS solves these issues beautifully. The idea is that each site has an XML
document (called an &lt;strong&gt;RSS feed&lt;/strong&gt;, or &lt;strong&gt;feed&lt;/strong&gt; for short) which contains a list
of the N latest posts on that website. You can add an arbitrary number of these
feeds into your reader and it will automatically sync these at a specified
interval, optionally notifying you of new content. This removes the chore of
having to go through your followed sites manually, but it also works around the
technological bloat issue as the feeds can only contain plain text or &lt;em&gt;(more
common and still reasonable)&lt;/em&gt; plain HTML. Finally, low-quality content can be
much more easily ignored or straight up filtered from your reader.&lt;/p&gt;
&lt;p&gt;Unfortunately, RSS has declined since its golden age in the 2000&amp;rsquo;s with &lt;a href="https://support.mozilla.org/en-US/kb/feed-reader-replacements-firefox"&gt;Firefox
dropping its own
reader&lt;/a&gt;
and many people forgetting about RSS, however it persists on many sites (even
big ones) and other readers continue to be actively developed.&lt;/p&gt;
&lt;h2 id="whats-the-problem-with-traditional-readers"&gt;What&amp;rsquo;s the problem with traditional readers?&lt;/h2&gt;
&lt;p&gt;If you consume your feeds on multiple devices &lt;em&gt;(as most people, me included,
probably do)&lt;/em&gt; with a traditional reader, your feeds and other info on them (such
as read and important markers) will not sync. Besides that, you might lose
articles on high-volume feeds if you do not open your feed reader for a while
(which might be just a few days) and the feed has a sufficiently low N.&lt;/p&gt;
&lt;p&gt;The solution to these problems is to run your aggregator on a server. There
exist public ones, but a far better solution would be to host your own. This is
where FreshRSS comes in.&lt;/p&gt;
&lt;h2 id="how-to-install-it"&gt;How to install it?&lt;/h2&gt;
&lt;p&gt;If you have Docker Compose, put something like this into a &lt;code&gt;docker-compose.yml&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;version&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;3.8&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;volumes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;data&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;extensions&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;services&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;freshrss&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;image&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;freshrss/freshrss:latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;container_name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;freshrss&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;hostname&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;freshrss&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;restart&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;unless-stopped&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;ports&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e6db74"&gt;&amp;#34;8181:80&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;logging&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;options&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;max-size&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;10m&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;volumes&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;data:/var/www/FreshRSS/data&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#ae81ff"&gt;extensions:/var/www/FreshRSS/extensions&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;environment&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;TZ&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Europe/Zagreb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;CRON_MIN&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;3,33&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, configure your web server to point a subdomain or path to the respective
port. Open the subdomain or path in your browser, do the initial setup and
you&amp;rsquo;re done. Add a few categories and feeds, then go through the settings and
configure everything to your wishes.&lt;/p&gt;
&lt;p&gt;Since FreshRSS is a PWA, you may &amp;ldquo;install&amp;rdquo; it using a Chromium-based browser
&lt;em&gt;(which I do on Android)&lt;/em&gt; or through the &lt;strong&gt;Web Apps&lt;/strong&gt; program on a Linux Mint
system.&lt;/p&gt;
&lt;h2 id="how-does-it-feel-to-use-should-i-use-it"&gt;How does it feel to use? Should I use it?&lt;/h2&gt;
&lt;p&gt;There&amp;rsquo;s not that much to say. Adding feeds is as simple as on a traditional
reader, all my feeds and starred articles sync between devices &lt;em&gt;(strictly
speaking, they do not, but are fetched from the server)&lt;/em&gt; and it overall behaves
pretty much just like Akregator did excluding the issues.&lt;/p&gt;
&lt;p&gt;If you only read feeds on one device and don&amp;rsquo;t care about losing articles from
big news sites here and there, you should probably stick with a traditional
reader as that is obviously less complicated, probably a bit more secure, allows
offline reading and so on. However, if your RSS experience is affected by one of
the aforementioned issues, I can highly recommend FreshRSS as it&amp;rsquo;s relatively
simple to set up and does not otherwise try to be radically different just for
the sake of it.&lt;/p&gt;</content><summary type="html">&lt;p&gt;Most RSS users start off with desktop readers such as Newsboat or Akregator in
order to keep things simple. However, due to certain drawbacks of this approach
&lt;em&gt;(which I will talk about below)&lt;/em&gt; I have looked for an aggregator I can install
on my VPS and use as such. After a bit of research, I have decided to go with
&lt;a href="https://freshrss.org/"&gt;FreshRSS&lt;/a&gt; and here I&amp;rsquo;ll explain why I decided to ditch
Akregator in the first place and why I chose FreshRSS.&lt;/p&gt;</summary></entry><entry><id>http://dujemihanovic.xyz/posts/matrix-delegation/</id><link rel="alternate" href="http://dujemihanovic.xyz/posts/matrix-delegation/"/><title>Matrix delegation and how it may bite you</title><updated>2024-08-21T12:27:03Z</updated><published>2024-01-14T11:19:48Z</published><content type="html">&lt;p&gt;For those who don&amp;rsquo;t know, delegation in Matrix is used in server-to-server
communication to figure out which server serves a given domain. As an example,
if my own Matrix homeserver was running on &lt;code&gt;matrix.dujemihanovic.xyz&lt;/code&gt; instead of
&lt;code&gt;dujemihanovic.xyz&lt;/code&gt;, I could delegate the latter to the former to save anyone
wanting to contact me from having to type out the &lt;code&gt;matrix.&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Besides domain name, delegation can also be used to specify which port to use
for server-to-server communication. The default is &lt;code&gt;8448&lt;/code&gt;, and if it&amp;rsquo;s blocked
you can use delegation to use &lt;code&gt;443&lt;/code&gt; for server-to-server as client-to-server
does by default. However, if you can, &lt;strong&gt;I&amp;rsquo;d strongly suggest using &lt;code&gt;8448&lt;/code&gt;!&lt;/strong&gt; I had
been delegating S2S to &lt;code&gt;443&lt;/code&gt; almost the whole time I have had this server for no
reason and it seems that this caused an extremely weird issue with a certain
room:&lt;/p&gt;
&lt;h2 id="what-happened"&gt;What happened?&lt;/h2&gt;
&lt;p&gt;Message fetching kept breaking &lt;strong&gt;constantly&lt;/strong&gt;. What I mean by that is that when
I joined the room everything would work fine the first few messages, but at some
point I would start getting notifications without any new message being present
in that room. I have noticed that logging out and back in would get the missing
messages in my client, but then the forementioned cycle would repeat again no
matter how many times I logged out and back in &lt;em&gt;(this also happened on other
clients besides Element desktop)&lt;/em&gt;. To confirm my homeserver was the issue, I
joined the room with my old matrix.org account and sure enough that worked just
fine.&lt;/p&gt;
&lt;p&gt;I tried the usual things such as restarting Dendrite and the whole VPS, but to
no avail. I was pretty insistent that the issue was not with my homeserver but
the main server hosting the room &lt;em&gt;(which, unsurprisingly, turned out to be
false)&lt;/em&gt; and so I gave up on that. The eyeopening moment was me reading the
&lt;a href="https://gitlab.com/famedly/conduit/-/blob/next/DEPLOY.md"&gt;conduit
documentation&lt;/a&gt; &lt;em&gt;(I had
considered migrating to it)&lt;/em&gt;, specifically this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If Conduit runs behind Cloudflare reverse proxy, which doesn&amp;rsquo;t support port
8448 on free plans,&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This implies that routing server-to-server traffic to &lt;code&gt;443&lt;/code&gt; should only be done
if it&amp;rsquo;s &lt;strong&gt;absolutely impossible&lt;/strong&gt; to use &lt;code&gt;8448&lt;/code&gt; for this, and the &lt;a href="https://matrix-org.github.io/synapse/latest/delegate.html#when-do-i-need-delegation"&gt;Synapse
documentation&lt;/a&gt;
said something similar:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;However&lt;/strong&gt;, if your homeserver&amp;rsquo;s APIs aren&amp;rsquo;t accessible on port 8448 and on
the domain server_name points to, you will need to let other servers know how
to find it using delegation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="fixing-the-issue"&gt;Fixing the issue&lt;/h2&gt;
&lt;p&gt;Encouraged by this, I fixed up my server:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;allow port &lt;code&gt;8448&lt;/code&gt; in &lt;code&gt;ufw&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;add something like this to &lt;code&gt;Caddyfile&lt;/code&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;dujemihanovic.xyz:8448 {
reverse_proxy /_matrix/* localhost:8008
}
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;change &lt;code&gt;/.well-known/matrix/server&lt;/code&gt; to point to &lt;code&gt;dujemihanovic.xyz:8448&lt;/code&gt; &lt;em&gt;(in
theory, I could have gotten rid of that &lt;code&gt;return&lt;/code&gt; directive altogether as
&lt;code&gt;8448&lt;/code&gt; is default anyway, but I still chose to specify it just to be safe)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;reload &lt;code&gt;caddy&lt;/code&gt; and restart &lt;code&gt;dendrite&lt;/code&gt; &lt;em&gt;(the latter is, again, just to be
safe)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once all this was done, the room finally started acting normally.&lt;/p&gt;
&lt;h2 id="small-sidenote"&gt;Small sidenote&lt;/h2&gt;
&lt;p&gt;I must note that delegating federation to &lt;code&gt;443&lt;/code&gt; &lt;strong&gt;should not cause breakage like
this&lt;/strong&gt;. Despite this, it still did so in my case and for that reason I wrote
about it anyway. It&amp;rsquo;s very unlikely that you will be affected by this issue, but
I still believe it should be pointed out in the event that it does.&lt;/p&gt;</content><summary type="html">&lt;p&gt;For those who don&amp;rsquo;t know, delegation in Matrix is used in server-to-server
communication to figure out which server serves a given domain. As an example,
if my own Matrix homeserver was running on &lt;code&gt;matrix.dujemihanovic.xyz&lt;/code&gt; instead of
&lt;code&gt;dujemihanovic.xyz&lt;/code&gt;, I could delegate the latter to the former to save anyone
wanting to contact me from having to type out the &lt;code&gt;matrix.&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Besides domain name, delegation can also be used to specify which port to use
for server-to-server communication. The default is &lt;code&gt;8448&lt;/code&gt;, and if it&amp;rsquo;s blocked
you can use delegation to use &lt;code&gt;443&lt;/code&gt; for server-to-server as client-to-server
does by default. However, if you can, &lt;strong&gt;I&amp;rsquo;d strongly suggest using &lt;code&gt;8448&lt;/code&gt;!&lt;/strong&gt; I had
been delegating S2S to &lt;code&gt;443&lt;/code&gt; almost the whole time I have had this server for no
reason and it seems that this caused an extremely weird issue with a certain
room:&lt;/p&gt;</summary></entry><entry><id>http://dujemihanovic.xyz/posts/projects/</id><link rel="alternate" href="http://dujemihanovic.xyz/posts/projects/"/><title>My projects are now listed on the website</title><updated>2024-08-21T12:27:03Z</updated><published>2023-09-16T13:15:59Z</published><content type="html">&lt;p&gt;I have created a &lt;a href="http://dujemihanovic.xyz/projects"&gt;new section&lt;/a&gt; of the site dedicated to my projects.
Currently the section numbers one whole project, that being &lt;a href="http://dujemihanovic.xyz/projects/pxa1908"&gt;my effort to get
Marvell PXA1908 booting mainline Linux&lt;/a&gt;. Check it out, &lt;a href="http://dujemihanovic.xyz/contact"&gt;let me
know&lt;/a&gt; if you have any suggestions for the new page and, if you can,
contribute to the effort!&lt;/p&gt;</content><summary type="html">&lt;p&gt;I have created a &lt;a href="http://dujemihanovic.xyz/projects"&gt;new section&lt;/a&gt; of the site dedicated to my projects.
Currently the section numbers one whole project, that being &lt;a href="http://dujemihanovic.xyz/projects/pxa1908"&gt;my effort to get
Marvell PXA1908 booting mainline Linux&lt;/a&gt;. Check it out, &lt;a href="http://dujemihanovic.xyz/contact"&gt;let me
know&lt;/a&gt; if you have any suggestions for the new page and, if you can,
contribute to the effort!&lt;/p&gt;</summary></entry><entry><id>http://dujemihanovic.xyz/posts/rss-updates/</id><link rel="alternate" href="http://dujemihanovic.xyz/posts/rss-updates/"/><title>RSS updates</title><updated>2024-08-21T12:27:03Z</updated><published>2023-08-30T18:55:52Z</published><content type="html">&lt;p&gt;I have made some small, but important changes to the way the RSS feed of the site
is generated.&lt;/p&gt;
&lt;p&gt;The biggest change is the relocation of the feed from
&lt;a href="http://dujemihanovic.xyz/posts/index.xml"&gt;dujemihanovic.xyz/posts/index.xml&lt;/a&gt; to
&lt;a href="http://dujemihanovic.xyz/index.xml"&gt;dujemihanovic.xyz/index.xml&lt;/a&gt;. To make sure subscribers &lt;em&gt;(assuming
any exist)&lt;/em&gt; don&amp;rsquo;t get cut off by this change, I have set up a 301 redirect from
the old location to the new one and I &lt;strong&gt;don&amp;rsquo;t plan&lt;/strong&gt; to remove this redirect,
although it probably won&amp;rsquo;t hurt to change the feed URL anyway &lt;em&gt;(Akregator and
Newsboat, the readers I tested, don&amp;rsquo;t seem to care much about the 301 and keep
using the old URL).&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I have also done some small cleanup of the code, the commit range in the
&lt;a href="http://git.dujemihanovic.xyz/?p=dujemihanovic.xyz.git;a=shortlog"&gt;repository&lt;/a&gt;
is &lt;code&gt;5a43568..47271c2&lt;/code&gt; for those interested. I have also looked into adding an
Atom feed at some point.&lt;/p&gt;</content><summary type="html">&lt;p&gt;I have made some small, but important changes to the way the RSS feed of the site
is generated.&lt;/p&gt;
&lt;p&gt;The biggest change is the relocation of the feed from
&lt;a href="http://dujemihanovic.xyz/posts/index.xml"&gt;dujemihanovic.xyz/posts/index.xml&lt;/a&gt; to
&lt;a href="http://dujemihanovic.xyz/index.xml"&gt;dujemihanovic.xyz/index.xml&lt;/a&gt;. To make sure subscribers &lt;em&gt;(assuming
any exist)&lt;/em&gt; don&amp;rsquo;t get cut off by this change, I have set up a 301 redirect from
the old location to the new one and I &lt;strong&gt;don&amp;rsquo;t plan&lt;/strong&gt; to remove this redirect,
although it probably won&amp;rsquo;t hurt to change the feed URL anyway &lt;em&gt;(Akregator and
Newsboat, the readers I tested, don&amp;rsquo;t seem to care much about the 301 and keep
using the old URL).&lt;/em&gt;&lt;/p&gt;</summary></entry><entry><id>http://dujemihanovic.xyz/posts/updating-dendrite/</id><link rel="alternate" href="http://dujemihanovic.xyz/posts/updating-dendrite/"/><title>Updating/installing Dendrite</title><updated>2024-08-21T12:27:03Z</updated><published>2023-08-24T16:41:53Z</published><content type="html">&lt;p&gt;I decided to share the method I just devised for updating (and perhaps
installing) Dendrite on my VPS.&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;/h2&gt;
&lt;p&gt;I discovered that yesterday (as of writing), Dendrite was updated to
&lt;a href="https://github.com/matrix-org/dendrite/releases/tag/v0.13.2"&gt;0.13.2&lt;/a&gt;, and I was
running 0.13.1. Because old thing bad and new thing good, I decided to update
right away!&lt;/p&gt;
&lt;p&gt;The method I tried using for this was essentially the same as I used for the
initial install:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Stop dendrite service&lt;/li&gt;
&lt;li&gt;Download new tarball&lt;/li&gt;
&lt;li&gt;Unpack new tarball into existing dendrite directory&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;go build -o ./bin ./cmd/...&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is where the issues start: it errored out on some nats something and I
assumed it just didn&amp;rsquo;t like being unpacked into an existing dendrite directory,
so I made a new one. It failed again and then I read the actual error that
occurred, and as it turned out the version of Go packaged in Debian is too old
to compile the nats thing. Isn&amp;rsquo;t that a classic?&lt;/p&gt;
&lt;p&gt;I looked around to see if maybe Go has its own Debian repository, but I was out
of luck. It seemed that the 2 options were either install Go from source or just
stick with Dendrite 0.13.1, but in the end I decided on a 3rd solution:&lt;/p&gt;
&lt;h2 id="compiling-it-locally"&gt;Compiling it locally&lt;/h2&gt;
&lt;p&gt;My personal machine runs Artix, so there should be no problem with outdated Go
(or anything really) whatsoever. I figured that I could compile Dendrite on my
personal machine and then &lt;code&gt;rsync&lt;/code&gt; the binaries onto my VPS, just like I did with
my Piped-Material frontend. Here are the steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Clone &lt;a href="https://github.com/matrix-org/dendrite"&gt;Dendrite git repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Checkout &lt;code&gt;v0.13.2&lt;/code&gt; &lt;em&gt;(replace with latest version)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;go build -o ./bin ./cmd/...&lt;/code&gt; and wait for it to compile&lt;/li&gt;
&lt;li&gt;On VPS, move &lt;code&gt;/opt/dendrite&lt;/code&gt; to &lt;code&gt;/opt/dendrite-old&lt;/code&gt; and create new
&lt;code&gt;/opt/dendrite&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;(optional)&lt;/em&gt; Strip the binaries so they take up less space: &lt;code&gt;strip --strip-unneeded bin/*&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rsync&lt;/code&gt; the &lt;code&gt;bin&lt;/code&gt; directory: &lt;code&gt;rsync -aAXvhzP bin root@vps:/opt/dendrite/&lt;/code&gt;&lt;br&gt;
&lt;em&gt;Most likely all these options aren&amp;rsquo;t needed, it is what I use for VPS
backups so I decided to not touch it just to be safe.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Back on the VPS, copy over &lt;code&gt;matrix_key.pem&lt;/code&gt;, &lt;code&gt;media_store&lt;/code&gt;, &lt;em&gt;(if it exists)&lt;/em&gt;
&lt;code&gt;searchindex&lt;/code&gt; and &lt;code&gt;dendrite.yaml&lt;/code&gt; from &lt;code&gt;dendrite-old&lt;/code&gt; into &lt;code&gt;dendrite&lt;/code&gt;.&lt;br&gt;
I have noticed that Dendrite also creates a &lt;code&gt;jetstream&lt;/code&gt; directory, I&amp;rsquo;m not
sure what it is for but my homeserver seems to work fine without copying it
over.&lt;/li&gt;
&lt;li&gt;Update configuration file. To do this, I went back to the Git repository on
my local machine and ran &lt;code&gt;git log -p dendrite-sample.yaml&lt;/code&gt;. This time the
only change was that MSC2946 (Space Summaries) was de-MSCified, so I removed
that from the config file.&lt;/li&gt;
&lt;li&gt;Make sure the user and group &lt;code&gt;dendrite&lt;/code&gt; own every file in &lt;code&gt;/opt/dendrite&lt;/code&gt;.
Run: &lt;code&gt;chown -R dendrite:dendrite /opt/dendrite&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;After doing this, I started Dendrite again using &lt;code&gt;systemctl&lt;/code&gt; and to my surprise
the homeserver was up and running first try. I also took this time to enable
server-side search and DNS caching, which is something I overlooked during the
initial setup of my homeserver. I have also verified that space previews still
work despite MSC2946 being removed from the configuration file.&lt;/p&gt;
&lt;p&gt;This way I was also able to save a bit of disk space, which is important since
space is often rather limited on VPSes.&lt;/p&gt;</content><summary type="html">&lt;p&gt;I decided to share the method I just devised for updating (and perhaps
installing) Dendrite on my VPS.&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;/h2&gt;
&lt;p&gt;I discovered that yesterday (as of writing), Dendrite was updated to
&lt;a href="https://github.com/matrix-org/dendrite/releases/tag/v0.13.2"&gt;0.13.2&lt;/a&gt;, and I was
running 0.13.1. Because old thing bad and new thing good, I decided to update
right away!&lt;/p&gt;
&lt;p&gt;The method I tried using for this was essentially the same as I used for the
initial install:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Stop dendrite service&lt;/li&gt;
&lt;li&gt;Download new tarball&lt;/li&gt;
&lt;li&gt;Unpack new tarball into existing dendrite directory&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;go build -o ./bin ./cmd/...&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is where the issues start: it errored out on some nats something and I
assumed it just didn&amp;rsquo;t like being unpacked into an existing dendrite directory,
so I made a new one. It failed again and then I read the actual error that
occurred, and as it turned out the version of Go packaged in Debian is too old
to compile the nats thing. Isn&amp;rsquo;t that a classic?&lt;/p&gt;</summary></entry><entry><id>http://dujemihanovic.xyz/posts/dropping-gitea/</id><link rel="alternate" href="http://dujemihanovic.xyz/posts/dropping-gitea/"/><title>Dropping Gitea</title><updated>2024-08-21T12:27:03Z</updated><published>2023-08-18T22:44:54Z</published><content type="html">&lt;p&gt;I have decided to drop Gitea as it&amp;rsquo;s only really useful when you have multiple
people collaborating on a project and is just bloatware otherwise. To
demonstrate, here&amp;rsquo;s how much bandwidth it takes to load in the old Gitea site&amp;rsquo;s
main page:&lt;/p&gt;
&lt;p&gt;&lt;img src="./gitea.jpg" alt="Gitea"&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how much it takes up with the amazing &lt;code&gt;gitweb&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="./gitweb.jpg" alt="gitweb"&gt;&lt;/p&gt;
&lt;p&gt;If you do the math, you will find that the new &lt;code&gt;gitweb&lt;/code&gt; site is roughly 22.18
times smaller than the Gitea site! This will certainly help with browsing on
older computers and weaker internet connections.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(Also notice that &lt;code&gt;gitweb&lt;/code&gt; does not make that pesky 3rd-party request!)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I also expect to move some of my previous projects from Git{Hub,Lab} here
relatively soon.&lt;/p&gt;
&lt;h2 id="what-about-the-old-site"&gt;What about the old site?&lt;/h2&gt;
&lt;p&gt;I will keep it as an option in case I by some miracle end up creating a project
with lots of outside contribution as that&amp;rsquo;s when it would become truly useful.
Until then, I always accept patches sent with the venerable
&lt;a href="https://git-send-email.io"&gt;git send-email&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If the new site breaks down in any way, please &lt;a href="http://dujemihanovic.xyz/contact/"&gt;let me know&lt;/a&gt;.&lt;/p&gt;</content><summary type="html">&lt;p&gt;I have decided to drop Gitea as it&amp;rsquo;s only really useful when you have multiple
people collaborating on a project and is just bloatware otherwise. To
demonstrate, here&amp;rsquo;s how much bandwidth it takes to load in the old Gitea site&amp;rsquo;s
main page:&lt;/p&gt;
&lt;p&gt;&lt;img src="./gitea.jpg" alt="Gitea"&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how much it takes up with the amazing &lt;code&gt;gitweb&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="./gitweb.jpg" alt="gitweb"&gt;&lt;/p&gt;
&lt;p&gt;If you do the math, you will find that the new &lt;code&gt;gitweb&lt;/code&gt; site is roughly 22.18
times smaller than the Gitea site! This will certainly help with browsing on
older computers and weaker internet connections.&lt;/p&gt;</summary></entry><entry><id>http://dujemihanovic.xyz/posts/windows-backup/</id><link rel="alternate" href="http://dujemihanovic.xyz/posts/windows-backup/"/><title>Windows Backup fails with 0x81000037? Check your filesystem</title><updated>2024-08-21T12:27:03Z</updated><published>2023-08-17T17:58:49Z</published><content type="html">&lt;h2 id="the-problem"&gt;The Problem&lt;/h2&gt;
&lt;p&gt;Yesterday, in preparation for a &amp;ldquo;downgrade&amp;rdquo; to Windows 10 from 11, I was trying
to make a backup of my Windows files &lt;em&gt;(using the Windows 7 Backup and Restore
control panel)&lt;/em&gt;. Not long after it actually started copying the files, it spat
out this error:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Windows Backup failed while trying to read from the shadow copy on one of the volumes being backed up. Please check in the event logs for any relevant errors.&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The error code listed was &lt;code&gt;0x81000037&lt;/code&gt;, and the first thing I did out of
instinct was look this code up. The &lt;a href="https://support.microsoft.com/en-us/topic/windows-backup-or-restore-errors-0x80070001-0x81000037-or-0x80070003-e63576a2-22c9-8e90-bdde-e51a9e8e1893"&gt;official Microsoft support
topic&lt;/a&gt;
stated that this error is caused if a reparse point &lt;em&gt;(Windows slang for
symlink)&lt;/em&gt; points to a FAT volume or is located on a volume containing compressed
files. The listed workaround for this error is to delete the offending reparse
point, and to locate it the topic suggests using the command &lt;code&gt;dir /al /s&lt;/code&gt;, which
is roughly equivalent to &lt;code&gt;find -type l&lt;/code&gt; in Unix-like systems.&lt;/p&gt;
&lt;p&gt;The first roadblock occurred when I found out that there is no offending reparse
point which could cause this error, so I consulted &lt;code&gt;eventvwr&lt;/code&gt; and found out that
Windows Backup leaves some logs at &lt;code&gt;%WINDIR%\Logs\WindowsBackup&lt;/code&gt;. It seemed to
me that there are certain cache files that caused it to fail, so I deleted them
and tried again. The backup again failed and I tried doing this a few more
times, but as nothing helped I eventually gave up.&lt;/p&gt;
&lt;h2 id="the-solution"&gt;The Solution&lt;/h2&gt;
&lt;p&gt;Having been unable to fix Windows&amp;rsquo; backup utility, I decided to just copy the
files to the backup drive and copy them over back after the &amp;ldquo;downgrade&amp;rdquo;. This is
when the actual solution to my problem becomes visible: Windows Explorer
errored, I forgot the exact message by now but it went something like &lt;em&gt;&amp;ldquo;The file
XYZ is not available at the location&amp;rdquo;&lt;/em&gt; or something, searching for the exact
message is as pointless as always.&lt;/p&gt;
&lt;p&gt;This usually indicates filesystem errors, so I ran &lt;code&gt;chkdsk C:&lt;/code&gt; and,
unsurprisingly, it found errors on the filesystem. Besides others, it mentions
the files XYZ that couldn&amp;rsquo;t be copied to the backup drive. I ran &lt;code&gt;chkdsk /scan C:&lt;/code&gt;, rebooted through the filesystem error notification that popped up right
after &lt;em&gt;(&lt;code&gt;chkdsk /f C:&lt;/code&gt; and reboot will work as well)&lt;/em&gt; and let it fix the errors.
Once it rebooted, the backup completed without errors. After installing Windows
10, restoring the backup was a breeze &lt;em&gt;(I only had AppData to back up,
everything else was already on other drives)&lt;/em&gt; and so I was quickly up and
running, then amazed by how fast and snappy Windows 10 is compared to its
&amp;ldquo;successor&amp;rdquo;, but that&amp;rsquo;s worthy of a separate post.&lt;/p&gt;
&lt;p&gt;(I don&amp;rsquo;t expect to get around to writing such post anytime soon though.)&lt;/p&gt;
&lt;h2 id="heading"&gt;&lt;em&gt;&amp;ldquo;Why are you writing about this?&amp;rdquo;&lt;/em&gt;&lt;/h2&gt;
&lt;p&gt;As you may know, Microsoft stuff is notorious for being not very well documented
and it&amp;rsquo;s entirely possible &lt;em&gt;(even if very unlikely)&lt;/em&gt; that someone else encounters
the same issue I have and is left helpless thanks to Windows&amp;rsquo; lack of a
&lt;strong&gt;proper, easy-to-use, centralized and well-written technical documentation
system&lt;/strong&gt; &lt;em&gt;(think of &lt;code&gt;man&lt;/code&gt;&amp;rsquo;s sections 4, 5, 7 and 8 for an idea of what I mean)&lt;/em&gt;,
not to mention countless YouTubers that parrot the same solutions as mentioned
on the web many times before. I hope that this article will be useful to the one
or so person with the same issue that may stumble upon it.&lt;/p&gt;
&lt;p&gt;TLDR: Nobody seems to have mentioned this before &lt;em&gt;(please correct me if I&amp;rsquo;m
wrong)&lt;/em&gt;, so might as well help the potential other person stuck in the same boat
as me.&lt;/p&gt;</content><summary type="html">&lt;h2 id="the-problem"&gt;The Problem&lt;/h2&gt;
&lt;p&gt;Yesterday, in preparation for a &amp;ldquo;downgrade&amp;rdquo; to Windows 10 from 11, I was trying
to make a backup of my Windows files &lt;em&gt;(using the Windows 7 Backup and Restore
control panel)&lt;/em&gt;. Not long after it actually started copying the files, it spat
out this error:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Windows Backup failed while trying to read from the shadow copy on one of the volumes being backed up. Please check in the event logs for any relevant errors.&lt;/code&gt;&lt;/p&gt;</summary></entry><entry><id>http://dujemihanovic.xyz/posts/site-is-now-on-gitea/</id><link rel="alternate" href="http://dujemihanovic.xyz/posts/site-is-now-on-gitea/"/><title>Site is now on Gitea</title><updated>2024-08-21T12:27:03Z</updated><published>2023-08-06T19:27:40Z</published><content type="html">&lt;p&gt;Even though the site is still nothing special,
I have published its source code on
&lt;a href="http://git.dujemihanovic.xyz/"&gt;my new gitweb instance&lt;/a&gt;. To save you a click
or two, the repository itself can be found
&lt;a href="http://git.dujemihanovic.xyz/?p=dujemihanovic.xyz.git;a=summary"&gt;here&lt;/a&gt;.
If you have any suggestions as to how to improve the site, feel free to
&lt;a href="http://dujemihanovic.xyz/contact/"&gt;contact me&lt;/a&gt;. If you are willing to directly contribute, I also accept
patches sent with &lt;code&gt;git send-email&lt;/code&gt;, a great tutorial on how to use it can be
found &lt;a href="https://git-send-email.io"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For convenience and to emphasize this, I have also added a &amp;ldquo;This site is free
software&amp;rdquo; link to the footer, right under the RSS button.&lt;/p&gt;
&lt;h2 id="edits"&gt;Edits&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;2023-08-19: Change links to point to gitweb instance&lt;/li&gt;
&lt;/ul&gt;</content><summary type="html">&lt;p&gt;Even though the site is still nothing special,
I have published its source code on
&lt;a href="http://git.dujemihanovic.xyz/"&gt;my new gitweb instance&lt;/a&gt;. To save you a click
or two, the repository itself can be found
&lt;a href="http://git.dujemihanovic.xyz/?p=dujemihanovic.xyz.git;a=summary"&gt;here&lt;/a&gt;.
If you have any suggestions as to how to improve the site, feel free to
&lt;a href="http://dujemihanovic.xyz/contact/"&gt;contact me&lt;/a&gt;. If you are willing to directly contribute, I also accept
patches sent with &lt;code&gt;git send-email&lt;/code&gt;, a great tutorial on how to use it can be
found &lt;a href="https://git-send-email.io"&gt;here&lt;/a&gt;.&lt;/p&gt;</summary></entry><entry><id>http://dujemihanovic.xyz/posts/first-post/</id><link rel="alternate" href="http://dujemihanovic.xyz/posts/first-post/"/><title>First Post</title><updated>2024-08-21T12:27:03Z</updated><published>2023-08-05T21:21:40Z</published><content type="html">&lt;p&gt;This is the first post on my new blog. I don&amp;rsquo;t expect to write much at all, but
if I do it will most likely be about my experiences with Linux on smartphones
and perhaps reviews/recommendations of products I come across.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m still experimenting with Hugo, so don&amp;rsquo;t be surprised if the site layout
changes dramatically in a short period of time. I put the source code for this
site under a (as of writing, local) Git repository which I do intend to make
public if and when the blog becomes something relatively serious.&lt;/p&gt;
&lt;p&gt;EDIT: The source code is now public: &lt;a href="http://dujemihanovic.xyz/posts/site-is-now-on-gitea/"&gt;Site is now on
Gitea&lt;/a&gt;&lt;/p&gt;</content><summary type="html">&lt;p&gt;This is the first post on my new blog. I don&amp;rsquo;t expect to write much at all, but
if I do it will most likely be about my experiences with Linux on smartphones
and perhaps reviews/recommendations of products I come across.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m still experimenting with Hugo, so don&amp;rsquo;t be surprised if the site layout
changes dramatically in a short period of time. I put the source code for this
site under a (as of writing, local) Git repository which I do intend to make
public if and when the blog becomes something relatively serious.&lt;/p&gt;</summary></entry></feed>