tag:acavalin.com,2005:/blog_feedACavalin - blog2024-03-13T15:32:38+01:00tag:acavalin.com,2005:Blog::Post/1462017-11-03T22:40:03+01:002024-03-13T15:32:38+01:00/p/fail2banSetup fail2ban to protect services2024-03-13T15:32:38ZTags: Debian, HowTo, Linux, RaspberryPi, SSH, Security<hr/><div class="md2html codehilite"><h3>Install <a href="http://www.fail2ban.org/">fail2ban</a>:</h3>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre>apt-get install fail2ban
</pre></td></tr></tbody></table>
</div>
<h3>Configure fail2ban:</h3>
<p>Put this file in in <code>/etc/fail2ban/jail.d/local.conf</code> (it is a modified copy of <code>jail.conf</code>):</p>
<div class="hll ini"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20</pre></td><td class="code"><pre><span class="nn">[DEFAULT]</span>
<span class="c"># space separeted list of IP addresses, CIDR masks, DNS hosts
</span><span class="py">ignoreip</span> <span class="p">=</span> <span class="s">127.0.0.1/8 192.168.1.1/24</span>
<span class="c"># number of seconds that a host is banned
</span><span class="py">bantime</span> <span class="p">=</span> <span class="s">3600</span>
<span class="c"># a host is banned if it has generated "maxretry" during the
# last "findtime" seconds
</span><span class="py">findtime</span> <span class="p">=</span> <span class="s">600</span>
<span class="py">maxretry</span> <span class="p">=</span> <span class="s">1</span>
<span class="nn">[sshd]</span>
<span class="py">enabled</span> <span class="p">=</span> <span class="s">true</span>
<span class="py">maxretry</span> <span class="p">=</span> <span class="s">1</span>
<span class="py">mode</span> <span class="p">=</span> <span class="s">extra</span>
<span class="nn">[sshd-ddos]</span>
<span class="py">enabled</span> <span class="p">=</span> <span class="s">true</span>
<span class="py">maxretry</span> <span class="p">=</span> <span class="s">1</span>
</pre></td></tr></tbody></table>
</div>
<h3>Starting, status, unblock IPs:</h3>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10</pre></td><td class="code"><pre><span class="c"># restart service after any config modification</span>
systemctl restart fail2ban
<span class="c"># show jailing info/counters</span>
fail2ban-client status
fail2ban-client status sshd
fail2ban-client status sshd-ddos
<span class="c"># look suspicious IPs in the logs</span>
journalctl -f -t sshd
</pre></td></tr></tbody></table>
</div>
<p>Ban management:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6</pre></td><td class="code"><pre><span class="c"># unlock blocked IPs</span>
fail2ban-client unban IP1 IP2 IP3 ...
fail2ban-client unban --all
<span class="c"># block an IP</span>
fail2ban-client -vvv <span class="nb">set </span>sshd banip x.x.x.x
</pre></td></tr></tbody></table>
</div>
<h3>SSH tips</h3>
<p>You can allow or deny access to specific users by editing <code>/etc/ssh/sshd_config</code>:</p>
<div class="hll conf"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5</pre></td><td class="code"><pre><span class="c"># allow ssh access only to users A and B and disallow all the others
</span><span class="n">AllowUsers</span> <span class="n">user_a</span> <span class="n">user_b</span>
<span class="c"># deny ssh access only to users A and B and allow all the others
</span><span class="n">DenyUsers</span> <span class="n">user_a</span> <span class="n">user_b</span>
</pre></td></tr></tbody></table>
</div>
<p>in this way the SSH demon triggers a faster failure+ban for the disallowed users.</p>
<hr>
<p>Source:
<a href="http://guide.debianizzati.org/index.php/Fail2ban">debianizzati</a>,
<a href="https://www.digitalocean.com/community/tutorials/how-to-protect-ssh-with-fail2ban-on-debian-7">digitalocean</a>,
<a href="https://stackoverflow.com/questions/29018312/howto-ban-ip-with-fail2ban-manually-by-command-line/32351941#32351941">stackoverflow</a></p>
</div>cloudtag:acavalin.com,2005:Blog::Post/1382017-11-03T20:52:39+01:002024-03-09T16:06:55+01:00/p/nut_upsSetup an UPS monitor2024-03-09T16:06:55ZTags: Debian, HowTo, Linux, RaspberryPi, UPS<hr/><div class="md2html codehilite"><div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre>apt-get install nut <span class="c"># install server</span>
</pre></td></tr></tbody></table>
</div>
<p>Set <code>MODE=standalone</code> in <code>/etc/nut/nut.conf</code>.</p>
<p>Append the user definition in <code>/etc/nut/upsd.users</code>:</p>
<div class="hll ini"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4</pre></td><td class="code"><pre><span class="nn">[monuser]</span>
<span class="py">password</span> <span class="p">=</span> <span class="s">ApAssWorD</span>
<span class="py">allowfrom</span> <span class="p">=</span> <span class="s">localhost</span>
<span class="err">upsmon</span> <span class="err">master</span>
</pre></td></tr></tbody></table>
</div>
<p>Optionally, set the daemon to listen only on IPv4 (defaults to both v4 and v6), append in <code>/etc/nut/upsd.conf</code>:</p>
<div class="hll conf"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre><span class="n">LISTEN</span> <span class="m">127</span>.<span class="m">0</span>.<span class="m">0</span>.<span class="m">1</span> <span class="m">3493</span>
</pre></td></tr></tbody></table>
</div>
<p>I had a <code>Powercom KIN-1200AP</code> connected via an USB to serial converter:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14</pre></td><td class="code"><pre><span class="c"># find the converter</span>
lsusb | grep Serial <span class="c"># Bus 001 Device 009: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port</span>
<span class="c"># create an udev rule to fix its device name,</span>
<span class="c"># append this in /etc/udev/rules.d/10-local.rules</span>
<span class="nv">ACTION</span><span class="o">==</span><span class="s2">"add"</span>, <span class="nv">KERNEL</span><span class="o">==</span><span class="s2">"ttyUSB[0-9]*"</span>, <span class="nv">SUBSYSTEMS</span><span class="o">==</span><span class="s2">"usb"</span>, ATTRS<span class="o">{</span>idVendor<span class="o">}==</span><span class="s2">"067b"</span>, ATTRS<span class="o">{</span>idProduct<span class="o">}==</span><span class="s2">"2303"</span>, SYMLINK+<span class="o">=</span><span class="s2">"ttyUSB_UPS"</span>
<span class="c"># append the UPS definition in /etc/nut/ups.conf</span>
<span class="o">[</span>myups]
driver <span class="o">=</span> powercom
port <span class="o">=</span> /dev/ttyUSB_UPS
desc <span class="o">=</span> <span class="s2">"Main supply"</span>
loadPercentage <span class="o">=</span> <span class="o">{</span>6.1343,-0.3808,1.075,0.1811<span class="o">}</span>
batteryPercentage <span class="o">=</span> <span class="o">{</span>5.0000,0.3268,-825.00,0.46511,0<span class="o">}</span>
</pre></td></tr></tbody></table>
</div>
<p>Now I have a <code>Line-Interactive Eaton 5E 850i</code> connected via USB:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5</pre></td><td class="code"><pre><span class="c"># append the UPS definition in /etc/nut/ups.conf</span>
<span class="o">[</span>myups]
driver <span class="o">=</span> usbhid-ups
port <span class="o">=</span> auto
desc <span class="o">=</span> <span class="s2">"Main supply"</span>
</pre></td></tr></tbody></table>
</div>
<p>If you encounter <a href="https://bugzilla.redhat.com/show_bug.cgi?id=1715504#c1">the error <code>usb_submit_urb(ctrl) failed: -1</code></a> when pluggin in the USB cable then append to your kernel boot params the NOGET quirk for this UPS (idVendor=0463, idProduct=ffff):</p>
<div class="hll plaintext"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre>usbhid.quirks=0x0463:0xffff:0x08
</pre></td></tr></tbody></table>
</div>
<p>Check the configured UPS status with the command <code>upsc myups</code>.</p>
<p>Configure the monitor in <code>/etc/nut/upsmon.conf</code>:</p>
<div class="hll conf"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19</pre></td><td class="code"><pre><span class="n">MONITOR</span> <span class="n">myups</span>@<span class="n">localhost</span> <span class="m">1</span> <span class="n">monuser</span> <span class="n">ApAssWorD</span> <span class="n">master</span>
<span class="c"># setup a custom script to notify you
</span><span class="n">NOTIFYCMD</span> /<span class="n">opt</span>/<span class="n">ups</span>/<span class="n">nut_notify_cmd</span>.<span class="n">sh</span>
<span class="c"># customize notification messages
</span><span class="n">NOTIFYMSG</span> <span class="n">ONLINE</span> <span class="s2">"UPS: Power restored - shutdown cancelled"</span>
<span class="n">NOTIFYMSG</span> <span class="n">ONBATT</span> <span class="s2">"UPS: Power failure - shutdown countdown started"</span>
<span class="n">NOTIFYMSG</span> <span class="n">REPLBATT</span> <span class="s2">"UPS: Battery exhausted, replacement needed"</span>
<span class="n">NOTIFYMSG</span> <span class="n">SHUTDOWN</span> <span class="s2">"UPS: Battery low - running immediate shutdown"</span>
<span class="c"># enable some logging
</span><span class="n">NOTIFYFLAG</span> <span class="n">ONLINE</span> <span class="n">SYSLOG</span>+<span class="n">EXEC</span>
<span class="n">NOTIFYFLAG</span> <span class="n">ONBATT</span> <span class="n">SYSLOG</span>+<span class="n">EXEC</span>
<span class="n">NOTIFYFLAG</span> <span class="n">LOWBATT</span> <span class="n">SYSLOG</span>+<span class="n">WALL</span>+<span class="n">EXEC</span>
<span class="n">NOTIFYFLAG</span> <span class="n">REPLBATT</span> <span class="n">SYSLOG</span>+<span class="n">WALL</span>+<span class="n">EXEC</span>
<span class="n">NOTIFYFLAG</span> <span class="n">SHUTDOWN</span> <span class="n">SYSLOG</span>+<span class="n">WALL</span>
<span class="n">NOTIFYFLAG</span> <span class="n">COMMOK</span> <span class="n">SYSLOG</span>
<span class="n">NOTIFYFLAG</span> <span class="n">COMMBAD</span> <span class="n">SYSLOG</span>
</pre></td></tr></tbody></table>
</div>
<p>Add the <code>nut</code> user to <code>dialout</code> group:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre>useradd -G dialout nut
</pre></td></tr></tbody></table>
</div>
<p>Restart the services and test the ups:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6</pre></td><td class="code"><pre>systemctl restart nut-driver
systemctl restart nut-server
systemctl restart nut-monitor
upsc -l <span class="c"># list all monitored UPSes</span>
upsc myups <span class="c"># show UPS details and status</span>
</pre></td></tr></tbody></table>
</div>
<p><mark>Note</mark>: Uninstall <code>xfce-powermanager</code> or you will get an USB communication error requiring a system reboot in order to clear it.</p>
<p><mark>Note</mark>: To cleanly unmount <a href="/p/veracrypt_volman">VeraCrypt volumes</a> you can use this <code>NOTIFYCMD</code> script:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13</pre></td><td class="code"><pre><span class="c">#!/bin/bash</span>
<span class="c"># /opt/ups/nut_notify_cmd.sh - nut NOTIFYCMD script</span>
<span class="c"># put in /etc/sudoers.d/local:</span>
<span class="c"># nut raoul = (root) NOPASSWD: /sbin/shutdown, /opt/systemd-units/vc-mounter.rb</span>
<span class="k">if</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$NOTIFYTYPE</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"ONBATT"</span> <span class="o">]</span>; <span class="k">then</span>
/opt/bin/shutdown -h 600 &
<span class="k">elif</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$NOTIFYTYPE</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"ONLINE"</span> <span class="o">]</span>; <span class="k">then
</span>sleep 3 <span class="c"># wait for first command to start</span>
/opt/bin/shutdown -c &
<span class="k">fi</span>
</pre></td></tr></tbody></table>
</div>
<p>that uses this useful shutdown script:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47</pre></td><td class="code"><pre><span class="c">#!/usr/bin/ruby</span>
<span class="nv">$VERBOSE</span> <span class="o">=</span> nil
<span class="c"># /opt/bin/shutdown - emulate shutdown command and unmount VeraCrypt volumes</span>
require <span class="s1">'optparse'</span>
require <span class="s1">'shellwords'</span>
opts <span class="o">=</span> <span class="o">{}</span>
OptionParser.new<span class="o">{</span>|o|
o.banner <span class="o">=</span> <span class="s2">"Usage: #{File.basename __FILE__} [options]"</span>
o.on<span class="o">(</span><span class="s1">'-r'</span>, <span class="s1">'--reboot [N]'</span>, Float, <span class="s1">'Reboot after N seconds (default=0)'</span><span class="o">)</span> <span class="k">do</span> |n|
opts.merge! action: :reboot, delay: n.to_f
end
o.on<span class="o">(</span><span class="s1">'-h'</span>, <span class="s1">'--poweroff [N]'</span>, Float, <span class="s1">'Poweroff after N seconds (default=0)'</span><span class="o">)</span> <span class="k">do</span> |n|
opts.merge! action: :shutdown, delay: n.to_f
end
o.on<span class="o">(</span><span class="s1">'-c'</span>, <span class="s1">'--cancel'</span>, <span class="s1">'Cancel a pending operation'</span><span class="o">)</span> <span class="k">do</span> |enabled|
opts.merge! action: :cancel
end
opts.merge! <span class="nb">help</span>: o.to_s
<span class="o">}</span>.parse!
<span class="k">case</span> opts[:action]
when :cancel
<span class="sb">`</span>pgrep -fl vc-mounter.rb<span class="sb">`</span>
<span class="k">if</span> <span class="nv">$?</span>.to_i <span class="o">==</span> 0
puts <span class="s1">'aborted'</span>
<span class="nb">exit
</span>end
<span class="c"># kill all but yourself</span>
pids <span class="o">=</span> <span class="sb">`</span>pgrep -f ruby.<span class="k">*</span>shutdown<span class="sb">`</span>.split<span class="o">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span>.map<span class="o">(</span>&:to_i<span class="o">)</span> - <span class="o">[</span>Process.pid]
pids.each<span class="o">{</span>|pid| system <span class="s2">"kill #{pid}"</span> <span class="o">}</span>
when :reboot, :shutdown
sleep opts[:delay]
<span class="sb">`</span>sudo swapon | grep <span class="s2">" file "</span> | cut -f 1 -d <span class="s2">" "</span><span class="sb">`</span>.strip.split<span class="o">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">)</span>.
each<span class="o">{</span>|f| system <span class="s2">"sudo swapoff #{f.shellescape}"</span> <span class="o">}</span>
system <span class="s1">'sudo /opt/systemd-units/vc-mounter.rb umount'</span>
system <span class="s2">"sudo /usr/sbin/shutdown -#{opts[:action] == :reboot ? :r : :h} 0 &"</span>
<span class="k">else
</span>puts opts[:help]
end
</pre></td></tr></tbody></table>
</div>
<hr>
<p>Source: <a href="https://srackham.wordpress.com/2013/02/27/configuring-nut-for-the-eaton-3s-ups-on-ubuntu-linux/">eaton ups setup</a></p>
</div>cloudtag:acavalin.com,2005:Blog::Post/3562021-12-17T14:19:36+01:002024-03-08T15:37:36+01:00/p/video_editing_softwareVideo editing software2024-03-08T15:37:36ZTags: Audio, Linux, Tools, Video<hr/><div class="md2html codehilite"><ol>
<li><strong><a href="https://www.shotcut.org/download/">shotcut</a></strong> <mark>appimage</mark></li>
<li><a href="https://kdenlive.org/en/download/">kdenlive</a> <mark>appimage</mark></li>
<li><a href="https://www.openshot.org/download/">openshot</a> <mark>appimage</mark></li>
<li><a href="https://jliljebl.github.io/flowblade/download.html">flowblade</a> <mark>deb</mark></li>
</ol>
<hr>
<p>Source: <a href="https://itsfoss.com/best-video-editing-software-linux/">itsfoss.com</a></p>
</div>cloudtag:acavalin.com,2005:Blog::Post/4502024-03-06T14:59:44+01:002024-03-06T14:59:44+01:00/p/gif_1st_frameextract first frame from animated GIF2024-03-06T14:59:44ZTags: HowTo, ImageMagick, Images, Terminal, Tools<hr/><div class="md2html codehilite"><div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5</pre></td><td class="code"><pre><span class="c"># from file</span>
convert image.gif[0] first_frame.gif
<span class="c"># from stdin</span>
cat image.gif | convert -<span class="s1">'[0]'</span> first_frame.gif
</pre></td></tr></tbody></table>
</div>
<hr>
<p>Source: <a href="https://stackoverflow.com/questions/21260529/how-can-i-extract-the-first-frame-of-an-animated-gif-using-imagemagicks-convert">stackoverflow</a></p>
</div>cloudtag:acavalin.com,2005:Blog::Post/4492024-03-04T11:12:58+01:002024-03-04T11:14:56+01:00/p/linux_datetimeLinux default date & time format2024-03-04T11:14:56ZTags: Configuration, HowTo, Linux<hr/><div class="md2html codehilite"><ol>
<li>find your current locale</li>
</ol>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre>locale | grep LC_TIME
<span class="c"># => LC_TIME="en_US.UTF-8"</span>
</pre></td></tr></tbody></table>
</div>
<ol>
<li><p>edit the corresponding file <code>/usr/share/i18n/locales/en_US</code></p></li>
<li><p>change values to your liking:</p></li>
</ol>
<div class="hll conf"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4</pre></td><td class="code"><pre><span class="n">d_t_fmt</span> <span class="s2">"%a %d %b %Y %T %Z"</span>
<span class="n">d_fmt</span> <span class="s2">"%Y//%m//%d"</span>
<span class="n">t_fmt</span> <span class="s2">"%T"</span>
<span class="n">date_fmt</span> <span class="s2">"%a %d %b %Y %T %Z"</span>
</pre></td></tr></tbody></table>
</div>
<ol>
<li>regenerate locales and <strong>re-login</strong></li>
</ol>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre>locale-gen
update-locale
</pre></td></tr></tbody></table>
</div>
<hr>
<p>Source: <a href="https://linuxopsys.com/topics/change-default-date-format-in-linux">linuxopsys</a></p>
</div>cloudtag:acavalin.com,2005:Blog::Post/4442024-02-22T14:27:21+01:002024-03-01T13:45:34+01:00/p/rails_bindev_via_gnu_screenRails bin/dev via GNU screen2024-03-01T13:45:34ZTags: Dev, Rails, Script, Terminal<hr/><div class="md2html codehilite"><p>Prepend to <code>bin/dev</code>:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8</pre></td><td class="code"><pre><span class="k">if </span><span class="nb">command</span> -v screen &> /dev/null; <span class="k">then
</span><span class="nv">rc_file</span><span class="o">=</span><span class="s2">"tmp/screenrc"</span>
grep -E -v <span class="s2">"^(screen|select|source) "</span> <span class="nv">$HOME</span>/.screenrc 2> /dev/null > <span class="nv">$rc_file</span>
nl bin/Procfile.dev | <span class="se">\</span>
sed -r <span class="s1">'s/^\s*([0-9]+)\s*([^:]+): (.+)/split\nfocus\nscreen -t \2 \1 \3/'</span> | <span class="se">\</span>
tail -n +3 >> <span class="nv">$rc_file</span>
<span class="nb">exec </span>screen -c <span class="nv">$rc_file</span>
<span class="k">fi</span>
</pre></td></tr></tbody></table>
</div>
<hr>
<p>Source: <a href="https://kyrylo.org/rails/overmind/2024/02/20/using-overmind-with-foreman-as-a-fallback-for-rails-7-1-apps.html">kyrylo.org</a> and <a href="https://github.com/DarthSim/overmind">overmind</a></p>
</div>cloudtag:acavalin.com,2005:Blog::Post/4412024-02-09T16:44:43+01:002024-03-01T12:02:29+01:00/p/micro_editor_settingsmicro editor settings2024-03-01T12:02:29ZTags: Editor, Reference, Terminal, Tools<hr/><div class="md2html codehilite"><h2>install fileamanger plugin</h2>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8</pre></td><td class="code"><pre><span class="c"># install official plugin (open in new split window via Tab key)</span>
micro -plugin install filemanager
<span class="c"># or install custom version (open in new tab via Enter key)</span>
mkdir -p ~/.config/micro/plug/filemanager/
<span class="nb">cd</span> ~/.config/micro/plug/filemanager/
wget https://github.com/acavalin/updated-plugins/raw/master/filemanager-plugin/filemanager.lua
wget https://github.com/acavalin/updated-plugins/raw/master/filemanager-plugin/syntax.yaml
</pre></td></tr></tbody></table>
</div>
<h2>~/.config/micro/settings.json</h2>
<div class="hll json"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11</pre></td><td class="code"><pre><span class="p">{</span><span class="w">
</span><span class="nt">"colorcolumn"</span><span class="p">:</span><span class="w"> </span><span class="mi">80</span><span class="p">,</span><span class="w">
</span><span class="nt">"colorscheme"</span><span class="p">:</span><span class="w"> </span><span class="s2">"railscast"</span><span class="p">,</span><span class="w">
</span><span class="nt">"filemanager.openontab"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nt">"filemanager.showdotfiles"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
</span><span class="nt">"filemanager.showignored"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
</span><span class="nt">"mouse"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w">
</span><span class="nt">"scrollbar"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nt">"tabsize"</span><span class="p">:</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w">
</span><span class="nt">"tabstospaces"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></pre></td></tr></tbody></table>
</div>
<p>NB: add <code>"clipboard": "internal"</code> when external is unavailable</p>
<h2>~/.config/micro/bindings.json</h2>
<div class="hll json"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10</pre></td><td class="code"><pre><span class="p">{</span><span class="w">
</span><span class="nt">"Alt-/"</span><span class="p">:</span><span class="w"> </span><span class="s2">"lua:comment.comment"</span><span class="p">,</span><span class="w">
</span><span class="nt">"Alt-h"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command:setlocal filetype shell"</span><span class="p">,</span><span class="w">
</span><span class="nt">"Ctrl-d"</span><span class="p">:</span><span class="w"> </span><span class="s2">"lua:comment.comment"</span><span class="p">,</span><span class="w">
</span><span class="nt">"Ctrl-o"</span><span class="p">:</span><span class="w"> </span><span class="s2">"lua:filemanager.toggle_tree"</span><span class="p">,</span><span class="w">
</span><span class="nt">"Ctrl-w"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Quit"</span><span class="p">,</span><span class="w">
</span><span class="nt">"Ctrl-q"</span><span class="p">:</span><span class="w"> </span><span class="s2">"QuitAll"</span><span class="p">,</span><span class="w">
</span><span class="nt">"Alt-Ctrl-f"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command-edit:replace s d"</span><span class="p">,</span><span class="w">
</span><span class="nt">"CtrlUnderscore"</span><span class="p">:</span><span class="w"> </span><span class="s2">"lua:comment.comment"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></pre></td></tr></tbody></table>
</div>
<h2>resizing window splits</h2>
<p>See <a href="https://github.com/zyedidia/micro/issues/1807#issuecomment-1907899274">this comment</a>,
<a href="https://github.com/itsoctotv/dotfiles/blob/main/micro/plug/resize/resize.lua">resize plugin</a>
and key bindings:</p>
<div class="hll json"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6</pre></td><td class="code"><pre><span class="p">{</span><span class="w">
</span><span class="nt">"Alt-A"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command:shrink_X"</span><span class="p">,</span><span class="w">
</span><span class="nt">"Alt-D"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command:grow_X"</span><span class="p">,</span><span class="w">
</span><span class="nt">"Alt-S"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command:grow_Y"</span><span class="p">,</span><span class="w">
</span><span class="nt">"Alt-W"</span><span class="p">:</span><span class="w"> </span><span class="s2">"command:shrink_Y"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></pre></td></tr></tbody></table>
</div>
<hr>
<p>See also:
<a href="https://github.com/zyedidia/micro">gh</a>,
<a href="https://discord.gg/nhWR6armnR">discord</a>,
keybindings <a href="https://github.com/zyedidia/micro/blob/master/runtime/help/keybindings.md">official</a> &
<a href="https://gist.github.com/rochacbruno/9e4f4c471e849276f11562272db446b0">gist</a></p>
</div>cloudtag:acavalin.com,2005:Blog::Post/4462024-02-29T14:55:16+01:002024-02-29T15:03:36+01:00/p/rails_memoryspeed_up_tipsRails memory/speed up tips2024-02-29T15:03:36ZTags: Rails, Reference, Ruby<hr/><div class="md2html codehilite"><ul>
<li><a href="https://www.speedshop.co/2015/07/22/secrets-to-speedy-ruby-apps-on-heroku.html">https://www.speedshop.co/2015/07/22/secrets-to-speedy-ruby-apps-on-heroku.html</a></li>
<li><a href="https://www.speedshop.co/2015/07/29/scaling-ruby-apps-to-1000-rpm.html">https://www.speedshop.co/2015/07/29/scaling-ruby-apps-to-1000-rpm.html</a></li>
<li><a href="https://www.sitepoint.com/ruby-uses-memory/">https://www.sitepoint.com/ruby-uses-memory/</a></li>
<li><a href="https://www.speedshop.co/2017/10/12/appserver.html">https://www.speedshop.co/2017/10/12/appserver.html</a></li>
<li><a href="https://www.speedshop.co/2018/03/28/nginx-unit-for-ruby.html">https://www.speedshop.co/2018/03/28/nginx-unit-for-ruby.html</a></li>
<li><a href="https://www.ombulabs.com/blog/rails/performance/notes-from-the-complete-guide-to-rails-performance-workshop.html">https://www.ombulabs.com/blog/rails/performance/notes-from-the-complete-guide-to-rails-performance-workshop.html</a> <mark>wrk test, law & formulas</mark></li>
<li><a href="https://jakeyesbeck.com/2019/06/18/ruby-processes-and-threads/">https://jakeyesbeck.com/2019/06/18/ruby-processes-and-threads/</a></li>
<li><a href="https://evilmartians.com/chronicles/big-on-heroku-scaling-fountain-without-losing-a-drop">https://evilmartians.com/chronicles/big-on-heroku-scaling-fountain-without-losing-a-drop</a></li>
<li><a href="https://medium.com/rubyinside/how-we-halved-our-memory-consumption-in-rails-with-jemalloc-86afa4e54aa3">https://medium.com/rubyinside/how-we-halved-our-memory-consumption-in-rails-with-jemalloc-86afa4e54aa3</a> </li>
<li><a href="https://justin.searls.co/posts/brand-new-rails-7-apps-exceed-heroku-s-memory-quotas/">https://justin.searls.co/posts/brand-new-rails-7-apps-exceed-heroku-s-memory-quotas/</a></li>
</ul>
<hr>
<p>source: <a href="https://www.reddit.com/r/rails/comments/1audueb/comment/krbams0/">reddit</a></p>
</div>cloudtag:acavalin.com,2005:Blog::Post/512016-09-23T14:36:14+02:002024-02-23T10:34:21+01:00/p/gnu_screenGNU Screen | terminal multiplexer2024-02-23T10:34:21ZTags: Linux, Terminal, Tools<hr/><div class="md2html codehilite"><style>div.md2html table tr { line-height: 0; }</style>
<h3>Screen commands shortcuts:</h3>
<table class="striped"><thead>
<tr>
<th>Shortcut</th>
<th>Descr</th>
</tr>
</thead><tbody>
<tr>
<td><code>^a c</code></td>
<td>create new terminal (use in new regions too)</td>
</tr>
<tr>
<td><code>^a #</code></td>
<td>switch to # terminal (0-9)</td>
</tr>
<tr>
<td><code>^a "</code></td>
<td>terminals list</td>
</tr>
<tr>
<td><code>^a A</code></td>
<td>set the current terminal name/title</td>
</tr>
<tr>
<td><code>^a d</code></td>
<td>detach session</td>
</tr>
<tr>
<td><code>^a S</code> or <code>^a |</code></td>
<td>split region horizontally or vertically</td>
</tr>
<tr>
<td><code>^a X</code></td>
<td>close current region</td>
</tr>
<tr>
<td><code>^a Q</code></td>
<td>close all regions but the current one</td>
</tr>
<tr>
<td><code>^a tab</code></td>
<td>switch inputo to next region</td>
</tr>
<tr>
<td><code>^a ^a</code></td>
<td>toggle between current and previous region</td>
</tr>
<tr>
<td><code>^a k</code></td>
<td>terminate the current window/tab</td>
</tr>
<tr>
<td><code>^a \</code></td>
<td>terminate entire session</td>
</tr>
<tr>
<td><code>^a :number x</code></td>
<td>changer current terminal number to <code>x</code></td>
</tr>
</tbody></table>
<h3>Scrolling + copy&paste:</h3>
<p>Press <code>^a esc</code> then use <code>PgUp/Dn</code> or <code>Up/Dn</code> arrows to scroll, when finished hit <code>return</code> two times.</p>
<p>If you move the cursor after hitting <code>return</code> once, you will be selecting text to copy, and hitting <code>return</code> the second time will copy it. Then you can paste it with <code>^a ]</code>.</p>
<h3>Command line how-to:</h3>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15</pre></td><td class="code"><pre>screen <span class="c"># start a new session (default screen is 0)</span>
screen -d -m <span class="c"># start a new detached session (useful in scrips)</span>
screen -r <span class="c"># reattach to a running session</span>
screen -d|-D <span class="o">[</span>pid.tty.host] <span class="c"># detaches the elsewhere running screen session</span>
<span class="c"># reattaching options (in case of a "stale attached state"):</span>
screen -d -r <span class="c"># reattach a session and if necessary detach it first</span>
screen -d -R <span class="c"># reattach a session and if necessary detach or create it</span>
screen -d -RR <span class="c"># reattach to the first session and if necessary detach or create it</span>
<span class="c"># or reattach trying even harder:</span>
screen -D -r <span class="c"># reattach a session, if necessary detach and logout remotely first</span>
screen -D -R <span class="c"># same as "-D -r" but also notify the user</span>
screen -D -RR <span class="c"># attach here and now. whatever that means, just do it</span>
</pre></td></tr></tbody></table>
</div>
<h3>Share a session with another user</h3>
<p><strong>Same account</strong></p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7</pre></td><td class="code"><pre><span class="c"># user1 starts the session then attach to it</span>
screen -d -m -S shared <span class="c"># start a new detached session called `shared`</span>
screen -x shared <span class="c"># attach in multi display mode</span>
<span class="c"># user2 only attach to it</span>
screen -ls <span class="c"># show current sessions</span>
screen -x shared <span class="c"># attach in multi display mode</span>
</pre></td></tr></tbody></table>
</div>
<p><strong>Different accounts</strong></p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8</pre></td><td class="code"><pre><span class="c"># user1 starts the session then attach to it</span>
screen -d -m -S shared <span class="c"># start a new detached session called `shared`</span>
screen -r shared <span class="c"># attach to the named session</span>
<span class="c"># press "Ctrl-a" and type ":multiuser on"</span>
<span class="c"># press "Ctrl-a" and type ":acladd user2"</span>
<span class="c"># user2 only attach to it</span>
screen -x user1/shared
</pre></td></tr></tbody></table>
</div>
<p><mark>Note</mark>: the multiuser mode needs screen as suid root but this is a security issue... if you want to enable it then type as root:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3</pre></td><td class="code"><pre>chmod u+s <span class="sb">`</span>which screen<span class="sb">`</span>
chmod 755 /var/run/screen
rm -fr /var/run/screen/<span class="k">*</span>
</pre></td></tr></tbody></table>
</div>
<p>but you really should make a third shared account which both users can log into.</p>
<h3>Customize session (see attachment):</h3>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75</pre></td><td class="code"><pre><span class="c"># ~/.screenrc - screen user config file</span>
<span class="c"># the following two lines give a two-line status, with the current window highlighted</span>
hardstatus alwayslastline <span class="s1">'%{= kG}@%{G}%H%? %1`%?%{g}|%= %{= kw}%-w%{+b yk} %n*%t%?(%u)%? %{-}%+w %=%{g}|%{y}%l%{g}|%{B}%Y-%m-%d %{W}%c%{g}'</span>
<span class="c"># huge scrollback buffer</span>
defscrollback 1000
<span class="c"># no welcome message</span>
startup_message off
<span class="c"># 256 colors</span>
term screen-256color
attrcolor b <span class="s2">".I"</span>
<span class="c">#termcapinfo xterm 'Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm'</span>
<span class="c">#termcapinfo xterm* ti@:te@</span>
<span class="c">#defbce on</span>
<span class="c"># mouse tracking allows to switch region focus by clicking</span>
mousetrack off
shelltitle --
<span class="c">#shell /usr/bin/fish</span>
<span class="c"># select window 1..10 with sequence "^a 1..0"</span>
<span class="nb">bind </span>c screen 1 <span class="c"># window numbering starts at 1 not 0</span>
<span class="nb">bind </span>0 <span class="k">select </span>10
<span class="c"># turn of flow control (^S-^Q / XON-XOFF characters)</span>
defflow off
<span class="c"># default windows</span>
screen 1 bash
screen 2 bash
<span class="k">select </span>1
<span class="c"># https://www.gnu.org/software/screen/manual/html_node/Key-Binding.html#Key-Binding</span>
maptimeout 1000
<span class="c"># NOTE: run `showkey -a` to see keycodes to use here</span>
<span class="c"># select window 11..20 with sequence "^A .N", where N=1..0</span>
<span class="nb">bind</span> . <span class="c"># unbind "^A ." (write termcap)</span>
bindkey <span class="s2">"^A.1"</span> <span class="k">select </span>11
bindkey <span class="s2">"^A.2"</span> <span class="k">select </span>12
bindkey <span class="s2">"^A.3"</span> <span class="k">select </span>13
bindkey <span class="s2">"^A.4"</span> <span class="k">select </span>14
bindkey <span class="s2">"^A.5"</span> <span class="k">select </span>15
bindkey <span class="s2">"^A.6"</span> <span class="k">select </span>16
bindkey <span class="s2">"^A.7"</span> <span class="k">select </span>17
bindkey <span class="s2">"^A.8"</span> <span class="k">select </span>18
bindkey <span class="s2">"^A.9"</span> <span class="k">select </span>19
bindkey <span class="s2">"^A.0"</span> <span class="k">select </span>20
<span class="c"># switch windows with F1 (prev) and F2 (next)</span>
<span class="c"># x11</span>
bindkey <span class="s2">"^[OP"</span> prev
bindkey <span class="s2">"^[OQ"</span> next
<span class="c"># old VT console</span>
bindkey <span class="s2">"^[[[A"</span> prev
bindkey <span class="s2">"^[[[B"</span> next
<span class="c">## get rid of silly xoff stuff</span>
<span class="c">#bind s split</span>
<span class="c">## Ctrl+F2 puts Screen into resize mode. Resize regions using hjkl keys.</span>
<span class="c">#bindkey "^[O1;5Q" eval "command -c rsz" # enter resize mode</span>
<span class="c">## use hjkl keys to resize regions</span>
<span class="c">#bind -c rsz h eval "resize -h -5" "command -c rsz"</span>
<span class="c">#bind -c rsz j eval "resize -h +5" "command -c rsz"</span>
<span class="c">#bind -c rsz k eval "resize -v -5" "command -c rsz"</span>
<span class="c">#bind -c rsz l eval "resize -v +5" "command -c rsz"</span>
<span class="c"># navigating regions with Ctrl-arrows</span>
<span class="c">#bindkey "^[[1;5D" focus left</span>
<span class="c">#bindkey "^[[1;5C" focus right</span>
<span class="c">#bindkey "^[[1;5A" focus up</span>
<span class="c">#bindkey "^[[1;5B" focus down</span>
</pre></td></tr></tbody></table>
</div>
<h3>Tips & tricks</h3>
<ul>
<li>Use this handy script to start your terminals the way you want:</li>
</ul>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8</pre></td><td class="code"><pre><span class="c">#!/bin/bash</span>
<span class="k">if</span> <span class="o">[</span> -z <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="o">]</span>; <span class="k">then
</span><span class="nb">echo</span> <span class="s2">"USAGE: bashto pwd [cmd arg1 arg2 ...]"</span>
<span class="nb">exit
</span><span class="k">fi
</span><span class="nb">cd</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="c"># go to the specified folder</span>
<span class="nb">shift</span>; <span class="o">[</span> -n <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&&</span> <span class="s2">"</span><span class="nv">$@</span><span class="s2">"</span> <span class="c"># execute an optional command</span>
<span class="nb">exec</span> /bin/bash <span class="c"># run shell</span>
</pre></td></tr></tbody></table>
</div>
<p><code>.screenrc</code> example: <code>screen -t www bashto /mnt/ramd elinks</code>.</p>
<ul>
<li>Keep <code>$DISPLAY</code> when using <a href="https://askubuntu.com/questions/9920/x11-forwarding-over-gnu-screen-is-it-possible/10042#10042">SSH with X11 forward</a>, put in <code>~/.bashrc</code>:</li>
</ul>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre><span class="o">[</span> -n <span class="s2">"</span><span class="nv">$DISPLAY</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&&</span> <span class="nb">echo</span> -n <span class="s2">"</span><span class="nv">$DISPLAY</span><span class="s2">"</span> > <span class="nv">$HOME</span>/.last_display
<span class="o">[</span> -z <span class="s2">"</span><span class="nv">$DISPLAY</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&&</span> <span class="nb">export </span><span class="nv">DISPLAY</span><span class="o">=</span><span class="k">$(</span>cat <span class="nv">$HOME</span>/.last_display<span class="k">)</span>
</pre></td></tr></tbody></table>
</div>
<p><mark>Alternatives:</mark></p>
<ul>
<li><a href="https://github.com/tmux/tmux/wiki">tmux</a></li>
<li><a href="https://gnometerminator.blogspot.it">GNU terminator</a> (graphical)</li>
</ul>
<hr>
<p>Source: <a href="https://www.gnu.org/software/screen/manual/html_node/Concept-Index.html#Concept-Index">GNU.org screen manual</a>, <a href="https://wiki.archlinux.org/index.php/GNU_Screen">ArchLinux tips</a>, <a href="https://gist.github.com/joaopizani/2718397">A killer GNU Screen Config gist</a>, <a href="https://forums.lime-technology.com/topic/11550-solved-how-to-enable-mc-mouse-support-while-using-screen/">MC mouse support</a>, <a href="https://dev.to/thiht/learn-to-use-screen-a-terminal-multiplexer-gl">Dev.to</a>, <a href="http://wiki.networksecuritytoolkit.org/index.php/HowTo_Share_A_Terminal_Session_Using_Screen">Shared session</a></p>
</div>cloudtag:acavalin.com,2005:Blog::Post/3452021-05-07T14:40:34+02:002024-02-23T09:39:32+01:00/p/chromium_personalizationsChromium personalizations2024-02-23T09:39:32ZTags: Browser, Chrome, Configuration, Tools<hr/><div class="md2html codehilite"><h2>Add-ons</h2>
<ul>
<li><a href="https://chrome.google.com/webstore/detail/dark-reader/eimadpbcbfnmbkopoojfekhnkhdbieeh">dark reader</a></li>
<li><a href="https://www.deepl.com/en/chrome-extension">DeepL Translate</a> -- <a href="https://chrome.google.com/webstore/detail/deepl-translate-reading-w/cofdbpoegempjloogbagkncekinflcnj">store</a></li>
<li><a href="https://chrome.google.com/webstore/detail/keepa-amazon-price-tracke/neebplgakaahbhdphmkckjjcegoiijjo">keepa amazon tracker</a></li>
<li><a href="https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo">tampermonkey</a></li>
<li><a href="https://chrome.google.com/webstore/detail/user-agent-switcher-and-m/bhchdcejhohfmigjafbampogmaanbfkg">user agent switcher</a></li>
<li><a href="https://chrome.google.com/webstore/detail/video-downloadhelper/lmjnegcaeklhafolokijcfjliaokphfk">video downloadhelper</a> -- <a href="https://www.downloadhelper.net">hp</a></li>
</ul>
<h2>developer mode</h2>
<p>Go to <a href="chrome://extensions/">chrome://extensions/</a> / <a href="vivaldi://extensions/">vivaldi://extensions/</a> and toggle <em>developer mode</em> switch.</p>
<h2>Vivaldi</h2>
<ul>
<li><a href="https://forum.vivaldi.net/category/112/vivaldi-browser-for-arm-raspberry-pi">Raspberry forum</a></li>
<li><a href="https://help.vivaldi.com/desktop/install-update/raspberry-pi/#drm-and-flash">Raspberry tips</a></li>
</ul>
<h3>Command line options</h3>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9</pre></td><td class="code"><pre><span class="c"># https://www.ghacks.net/2017/02/13/how-to-speed-up-the-vivaldi-web-browser/</span>
<span class="c"># optimized command for raspberry pi</span>
/usr/bin/vivaldi <span class="se">\</span>
--process-per-site <span class="se">\</span>
--enable-low-res-tiling <span class="se">\</span>
--enable-low-end-device-mode <span class="se">\</span>
--disk-cache-size<span class="o">=</span>104857600 <span class="se">\</span>
--disk-cache-dir<span class="o">=</span><span class="nv">$TMPD</span> <span class="se">\</span>
<span class="s2">"</span><span class="nv">$@</span><span class="s2">"</span>
</pre></td></tr></tbody></table>
</div>
<h3>Fix passwords <a href="https://forum.vivaldi.net/topic/43432/passwords-not-syncing-from-server/2">not syncing</a></h3>
<p>If you observe the following error in <a href="vivaldi://sync">vivaldi://sync</a></p>
<div class="hll plaintext"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre>Error: CleanupPasswordStore@components/password_manager/core/browser/sync/password_sync_bridge.cc:1067,
datatype error was encountered: Failed to get encryption key during database cleanup.
</pre></td></tr></tbody></table>
</div>
<ol>
<li>close Vivaldi</li>
<li><code>rm -f ~/.config/vivaldi/Default/Login\ Data*</code></li>
<li>launch Vivaldi and the sync error in <a href="vivaldi://sync">vivaldi://sync</a> should have vanished</li>
</ol>
<h3>Video DRM/Widevine on Vivaldi</h3>
<ul>
<li><a href="vivaldi://flags">vivaldi://flags</a> > Override software rendering list > Enable</li>
<li><a href="vivaldi://gpu">vivaldi://gpu</a></li>
<li><a href="vivaldi://components">vivaldi://components</a> > Widevine Content Decryption Module > check if it's loaded</li>
</ul>
<p>See:
<a href="https://gist.github.com/vyn20/7e1e1c313843d6a8180cfc1f47bee6aa">old script</a>,
<a href="https://forum.vivaldi.net/topic/53927/linux-arm-32-64-bit-os-with-drm-enable-gpu-hardware-accelerated-how-to">vivaldi forum</a>,
<a href="https://help.vivaldi.com/desktop/media/html5-proprietary-media-on-linux/">test video</a>,
<a href="https://bitmovin.com/demos/drm">another test page</a></p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre>apt install libwidevinecdm0
<span class="nb">echo</span> <span class="s1">'{"Path":"/opt/WidevineCdm"}'</span> > ~/.config/vivaldi/WidevineCdm/latest-component-updated-widevine-cdm
</pre></td></tr></tbody></table>
</div>
</div>cloudtag:acavalin.com,2005:Blog::Post/1762018-02-22T13:16:32+01:002024-02-09T16:54:14+01:00/p/nanorcnano editor settings2024-02-09T16:54:14ZTags: Editor, Reference, Terminal, Tools<hr/><div class="md2html codehilite"><div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19</pre></td><td class="code"><pre><span class="c"># /etc/nanorc or ~/.nanorc</span>
<span class="nb">set </span>tabsize 2
<span class="nb">set </span>tabstospaces
<span class="nb">set </span>smarthome
<span class="nb">set </span>regexp
<span class="nb">set </span>nonewlines
<span class="c">#set autoindent</span>
<span class="c">#set linenumbers</span>
<span class="nb">set </span>constantshow
<span class="c">#set mouse</span>
<span class="nb">set </span>nowrap
<span class="c"># use alt-</, or alt->/. to switch buffer</span>
<span class="c"># user ^R ^T to open a new file buffer with file manager</span>
<span class="nb">set </span>multibuffer
</pre></td></tr></tbody></table>
</div>
</div>cloudtag:acavalin.com,2005:Blog::Post/4402024-02-02T09:33:23+01:002024-02-02T09:33:23+01:00/p/remove_credit_card_data_from_githubremove credit card data from GitHub2024-02-02T09:33:23ZTags: GDPR, HowTo<hr/><div class="md2html codehilite"><ol>
<li>Open a new ticket to <a href="https://support.github.com/contact/account">GitHub</a></li>
<li>Category <code>Billing</code></li>
<li>Subject: <code>remove my credit card data</code></li>
<li>Body</li>
</ol>
<div class="hll plaintext"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7</pre></td><td class="code"><pre>Dear Customer Support, I live in Europe and as you are aware:
https://edpb.europa.eu/system/files/2021-05/recommendations022021_on_storage_of_credit_card_data_en_1.pdf
"According to the Article 7(3) GDPR, the data subject shall have the right to withdraw his or her consent for the storing of credit card data for the purposes of facilitating further purchases at any time. The withdrawal must be free, simple and as easy for the data subject, as it was to give consent. It must lead to the effective deletion by the controller of credit card data stored for the sole purpose of facilitating further transactions"
I withdraw my consent for you to store my information and I wish to remove and confirm by reply that you have deleted my credit card information from my account (your systems).
</pre></td></tr></tbody></table>
</div>
<hr>
<p>Source: gh discussion <a href="https://github.com/orgs/community/discussions/51727#discussioncomment-8343573">How do I remove a Payment method from github? #51727</a></p>
</div>cloudtag:acavalin.com,2005:Blog::Post/4302023-11-28T14:44:49+01:002024-01-31T12:47:53+01:00/p/home_network_designHome Network Design2024-01-31T12:47:53ZTags: Casa, Networking, Reference<hr/><div class="md2html codehilite"><p><strong>Disclaimer</strong>: I'm sure I have a few things wrong so my fellow Reddit friends will help me out here. The goal is to start a discussion on networks and how we may help those that need it. Unfortunately my time is limited today in how much I can write but I'll try to put down as much as I can to get the discussion going.</p>
<h1>I see a common complaint with many Google Stadia users:</h1>
<p>People complain about network performance issues, lag, and disconnects. But Motavar... I have a 1 gig connection and I can download software and stream Netflix without issue. Stadia's network sucks and the system is broken.</p>
<p>What Stadia does is expose poor networks, poor LAN/WAN setups, and wireless networks with poor design/interference. Maybe we can break this down a bit to see what is wrong with your network, some myths, and how we may solve them.</p>
<hr>
<h1>The amount of bandwidth you purchased doesn't always mean you have that bandwidth available to your target destination.</h1>
<p>So your ISP sold you a 1 gigabit connection. You spin up speedtest and test the closest ookla test point and sure enough you're around 900+ mbps to that location. Great you say.. but what you're missing is that some ISPs will give priority for the speedtest traffic over their network or setup a local ookla speedtest point on their network. Sure you may test well to that location or within your ISPs network but what about the rest of the Internet?</p>
<p>Your ISP unfortunately does not have unlimited bandwidth so the service is always oversubscribed. The amount of bandwidth will vary depending upon how loaded your local area is.</p>
<p>Your ISP has peering with other networks and backbones to reach the Internet. These same networks have limited bandwidth and cannot always give you, lets say, 1gbps to the target destination. The target destination may also have limited bandwidth and throttle the incoming requests. You will see this a lot when downloading a new game from an online store where everyone is trying to hit the location at once. The target destination unfortunately doesn't have unlimited bandwidth so your throughput will be lower. Not to mention the transit links you go through to reach that destination may be oversubscribed or have problems.</p>
<p>You can test with other online speed tests to find out what you're really getting but what's the point.. you're not going to convince another provider or backbone to increase their infrastructure just because you paid for 1gbps and they only have 500mbps. You need to get the <q>i have 1gbps internet everywhere</q> out of your head.</p>
<hr>
<h1>But I can stream Netflix and youtube without a problem.</h1>
<p>Sure, but that network stream can buffer to make up for times when the speed or latency is increased. There is some wiggle room but in the case of Stadia (or anything requiring near real time) you do not want buffering. So there is no wiggle room to make the connection appear to be smooth. You'll notice those times of reduced throughput or maybe route changes on the Internet cause additional latency.</p>
<p>Most networks or ISPs have multiple connections to backbones and unfortunately in the real world people run into telephone polls and fiber breaks, backhoes dig up lines, squirrels chew on your internet, hardware/optic failures happen, and well.. you're traffic ends up re-routing through another location which may cause latency to change all of a sudden. It might appear like google's servers are having issues when you're really noticing problems out in the physical world.</p>
<hr>
<h1>Lets Talk Wifi</h1>
<p>NOTE: You'll have to do additional research on your own since I cannot explain it all in this thread</p>
<p>So you picked up that fancy 5ghz dual band wireless router and stuck it in your house or apartment closest to your modem. You have like 8 antennas, maybe you spent like $150-300 for the thing so surely it's badass. It should cover the whole place and you're sitting on the other side of your house or apartment and speeds are low, latency sucks, so why is this?</p>
<p>You're most likely you're missing the whole part about wireless design and how RF works.</p>
<p>We'll get into wireless design further below but first lets talk about 2.4 and 5ghz.</p>
<h2>1. We'll start with 802.11 2.4ghz:</h2>
<p>The recommended channels for this setup would be 1, 6, or 11. To keep it clean you'll want to use these channels because of the following:</p>
<p>Channel 1 covers over way up to channel 3.</p>
<p>Channel 6 covers over channels 5 and 7</p>
<p>Channel 11 covers over 10 and 12</p>
<p>If you setup your home router with channel 1 and then channel 3 you'll end up causing your own interference for connected devices. I recommend you look at your router configuration and google 2.4ghz channels image and look at the pictures. You want to make sure your home network doesn't have anything that overlaps with each other. To keep it simple use the channels I listed above.</p>
<p>Unfortunately most people live in an area with neighbors and the 2.4ghz signal can travel pretty far. They usually see your traffic and choose a channel that doesn't match their neighbor. Unfortunately this usually overlaps with your channel and on top of that they turn up their wireless signal power thinking this will help drown you out. Unfortunately that doesn't help the situation and we'll get into that on wireless design below.</p>
<p>NOTE:</p>
<p>I could go further into 2.4ghz but honestly the only reason at this point to use 2.4ghz would be for legacy devices and if you live an area where you don't have a lot of people close by. If you didn't already know, the 2.4ghz range is also subject to interference from Bluetooth devices, microwaves, cordless phones, and other devices. So sticking with 2.4ghz you'll most likely run into problems so I recommend you move on from 2.4ghz.</p>
<h2>2. 5ghz Wifi</h2>
<p>This discussion we'll assume you're using 802.11AC 5ghz wifi since most people haven't moved into AX or beyond. This is what you want to be connected to, to avoid the problems listed above.</p>
<p>You'll want to use 5ghz since it has less interference from microwaves, cordless phones, Bluetooth, etc. Unfortunately it has less range so maybe we'll just jump into the wireless design to explain it further.</p>
<hr>
<h1>Wireless Design</h1>
<h2>Wireless is a physics problem.</h2>
<p>In 5ghz wifi the signal doesn't penetrate walls or structures like 2.4ghz does.</p>
<p>To begin this setup I recommend you download a wifi signal application onto your phone(analyzer). This will help you view the wireless signals around you and help you design your network. Any free wifi signal app on your phone should be okay.</p>
<h2>Channels</h2>
<p>There are 20mhz, 40mhz, 80mhz, and 160mhz wide channels. You can google 5ghz channels on google images or view this link for example:</p>
<p><a href="https://www.extremetech.com/wp-content/uploads/2014/06/graphic-80211-acChannels-all.png">https://www.extremetech.com/wp-content/uploads/2014/06/graphic-80211-acChannels-all.png</a></p>
<p>You have non-DFS and DFS channels. Think of the 5ghz wireless space like this.. you have wireless channels that are available for use all the time and channels that are borrowed from other areas like weather and aircraft radar.</p>
<p>The non-DFS channels are always available for us to use. They just work and we want to use these on our network.</p>
<p>The DFS channels are channels that we are borrowing from weather and aircraft radar. Under US law for example if you are using a DFS channel and an aircraft flies over your location your wireless device, by law, must shutdown that channel and wait (up to 20 mins) before trying to turn back on. Same goes with weather radar.. if you something scans your area those DFS channels will shutdown for a holdback time. Sucks, right?!</p>
<p><strong>So here are the channels we want to use for best performance:</strong></p>
<ul>
<li>36-48</li>
<li>149-165</li>
</ul>
<p>The DFS channels (which could be affected at any time) are:</p>
<ul>
<li>52-144</li>
</ul>
<p>...make a note of this as this will affect how we setup our network. BTW, if you haven't looked at an image of the 5ghz channels you really should, this will make a lot more sense!</p>
<p>These channels are broken up into groups.</p>
<p>You can run at:</p>
<ul>
<li>20mhz wide and get 36, 40, 44, 48</li>
<li>40mhz wide and get 36-40 , and 44-48</li>
<li>80mhz wide and get 36-48</li>
<li>160mhz - I wont go into this because it goes into the DFS range. I just don't want to go there.</li>
</ul>
<p>NOTE: The smaller the channels the more room for using non-DFS. But the smaller the channel the less throughput on SU-MIMO devices.</p>
<hr>
<p>So Motavar what is the point behind all these channels and 20mhz to 80mhz wide?</p>
<p>Well it all has to do with speed. Think of the channel like a hose connected to a faucet. The 20mhz is a small hose and a 80mhz is a big hose. The bigger the hose the more water it can hold. So the bigger the channel the more data you can squeeze in there. We can put down a lot of little hoses on the ground or put down bigger hoses but less of them.</p>
<p>Up until recently your wireless network card (or NIC as we'll call it) could only connect to one channel. This was called SU-MIMO. So if you connected a SU-MIMO NIC at 80mhz wide you're throughput would be 450mbps. But what if your NIC supported MU-MIMO like an iphone or galaxy s10.. MU-MIMO allows you to connect to lets say (2) channels (or 2 spatial streams). So you could get 450mbps x 2 or 867mpbs PHY.</p>
<p>What does this all mean? Break it down.</p>
<p>Well, if you have an older NIC that does SU-MIMO and your router is set for 80mhz wide channels your max throughput would be 450mbps. If you're running at 40mhz wide your throughput would be lower. If you had a newer device with MU-MIMO you could connect to lets say 2 80mhz wide streams for 867mpbs.</p>
<hr>
<p>Okay.. and..</p>
<p>Well with this info we are going to try and fix your wireless and solve this physics problem</p>
<p>We'll throw a few things out there (and correct me if I'm wrong):</p>
<ul>
<li>If you're trying to get 1gbps out of your wireless you're most likely not going to get it. Most modern devices would do MU-MIMO at 2x spatial streams. At 80mhz wide you're looking at 867mpbs PHY.</li>
<li>If you think this is going to be easy, it wont be.</li>
<li>If you think this is going to be cheap, it won't be.</li>
</ul>
<hr>
<p>So lets dig in!</p>
<p>You want to bring up your wireless analyzer app on your phone and walk around your house or apartment. The goal here is look at signal strength. For optimal performance you want to design your wireless network coverage for -68 or less (like -30). Wait, what.. yes, -68 or smaller. If you spot an area greater than -68 (like -70 to -90) then you'll want another AP (Access point) in this location.</p>
<p>Mental Note: You're wireless coverage should be -68 or less (-30).</p>
<p>With 5ghz you'll need to place wireless access points closer to your devices. For example in a 2600 square foot house I have (4) wireless access points (on the inside. 2 upstairs, 2 downstairs) and (2) wireless access points on the outside. (Wait, what, you're nuts!! yeah.. just work with me on this)</p>
<blockquote>
<p>But Motavar we'll just turn the power up on the router!</p>
</blockquote>
<p>WRONG… DON'T DO IT</p>
<p>Turning up the power on a wireless router (increasing signal output) is not the correct way to resolve wireless issues. Here is an example of what happens. If you turn the power up on your router, yes, it can talk further, but unfortunately your smaller devices like cameras, mobile phones, etc do not have the power to communicate back. Lets think of it this way:</p>
<p>Motavar is on one side of your house with a megaphone and is screaming at you “Hey it's me!”! He's yelling at the top of his lungs and with a megaphone you can hear him loud and clear! But you, reddit user, you don't have a megaphone so you say “here I am” but Motavar cannot hear you. ☹</p>
<p>^This is what happens when you turn up wireless power.</p>
<p>Your mobile device can hear the wireless signal but due to antenna design and low power it just can't reach the router. Or it may reach, very weak, so the throughput is lower. Mobile devices are design to conserve power so output is usually lower. Same with something like a chromecast.</p>
<p>But maybe your mobile device works sort of okay. Increased power causes another issue. Roaming</p>
<p>“Roaming between wireless access points is a function of the client and NOT the wireless access point”. Each manufacturer of wireless devices at what threshold a device will “roam”. On windows devices for example you get setup aggressive roaming which tells it to roam to another AP when the signal is just a little bit better. But on a mobile device you cannot tweak this (that I know of). So if you turned the power up on a wireless access point, the inbound signal looks strong but it cannot talk back. But since the signal is strong it won't roam to a closer AP. So your performance sucks as you move around. If all of your Aps are at high power you're less likely to roam to the better access point. Turning down your wireless power will allow your mobile devices to roam better.</p>
<p>MENTAL NOTE: <strong>YOU WANT TO TURN YOUR POWER DOWN OR ACCESS POINTS</strong></p>
<p>This gives your mobile device a chance to roam to the nearest AP which it can actually talk to!</p>
<hr>
<p>Okay but looking at your wifi app analyzer you have low signal strength (greater than -68). Now what?</p>
<p>Well here is the hard part. You need to add more Access Points for additional coverage. But what.. I didn't have to do that with 2.4ghz. Well 2.4ghz goes through walls easier, 5ghz doesn't. So more access points is what you need.</p>
<p><strong>And this friends is why 5ghz = $</strong></p>
<hr>
<h1>So lets get into Channels and MU-MIMO</h1>
<p>You now realized that you need more access points</p>
<p>What channel should you setup?</p>
<p>80MHZ vs 40MHZ</p>
<h2><strong>80mhz</strong>...</h2>
<p>If want the best throughput you would go for 80mhz wide.</p>
<p>The only reason to go this route would be if you had modern NICs or devices that could do MU-MIMO.</p>
<p>If you have MU-MIMO devices you want to divide your network into two main areas:</p>
<p>You want your primary area to be channel 36-48 – 80mhz wide. So your MU-MIMO device will do 867mbps You want your second most important area to be 149-165 – 80mhz wide. So your other MU-MIMO devices can do 867mbps there.</p>
<p>The rest of your wifi network that isn't that important (basement, kitchen, bathroom) can use the DFS channels which would die at any point (remember that weather radar and aircraft bullshit.. yeah.. it's a real thing). So you have to think of these areas as changing channels or dying at any point.</p>
<h2>40mhz...</h2>
<p>Unfortunately not all devices talk 80mhz wide on MU-MIMO</p>
<p>So lets say you hook up an Amazon Alexa device to your new fancy 80mhz wide network. It only talks 40mhz. So now it takes up airtime on your 80mhz wide channels and ends up slowing down the whole 80mhz wide channel. What do you do?</p>
<p><strong>This is why most people would want to setup a 40mhz wide channel design for their home.</strong></p>
<p>It gives you more channels to work with that are outside of the DFS range. You don't have to worry about channels shutting down for 20 minutes when aircraft is detected. This would be the best setup for most people.</p>
<p>But Motavar, you told me that 40mhz was slower. Unfortunately it is but if you want stability this is what you most likely have to do. But What if I really wanted to have 80mhz MU-MIMO 867mbps speeds for when I work from home and yet I wanted 40mhz for my IOT devices?</p>
<p>Well that is where we get into making multiple wireless networks. Lets do it!</p>
<hr>
<h1>Breaking down your home Wifi into multiple wireless networks:</h1>
<p>I recommend the following:</p>
<ul>
<li>Put your 2.4ghz onto one wireless network name (call it Legacy or whatever.. FBI VAN1)</li>
<li>Put your 5ghz 40mhz wide onto one wireless network name (IOT_Crap)</li>
<li>Put your 5ghz 80mhz wide onto one wireless network name (Fast_Stuff)</li>
</ul>
<p>We breakdown wireless networks into different performance groups. We do this for a few reasons.</p>
<ol>
<li>If your 2.4ghz wireless name and your 5ghz wireless network have the same names you'll run into roaming issues, performance issues, etc. You have no control over where the wireless endpoint is going or connecting to. iPhones and other devices have an issue switching between 2.4/5 with the same SSID. Be smart, take control of your wifi, and put legacy stuff on 2.4ghz. Put the new stuff on 5ghz. We do this by creating new network names or SSIDs.<br>
Note: The switching between 2.4ghz and 5ghz using the same ssid (network name) is called bandwidth steering. Unfortunately the technology is known to have issues with different wireless network devices and mobile devices. Save yourself the frustration and create a different network for your 2.4ghz devices.</li>
<li>Put your chromecasts, alexas, and IOT devices onto a 5ghz 40mhz wide network. This is done to control broadcast traffic and bandwidth usage. Most of these devices do not support 80mhz wide. So instead of slowing down our 80mhz wide network we'll put them into their own little world.</li>
<li>Put your most critical high bandwidth devices like work from home laptops and modern phones onto your wireless 80mhz wide network for the most bandwidth. Just make sure they support MU-MIMO or 2x spatial streams for 867mbps. If they cannot do 867mpbs+ then stick them on the 40mhz wide wifi network.</li>
<li>And while we're at it...<br>
Make a guest network for your kids and kids friends. Keep them off your production network. I can't tell you how many times my daughters friends drove up and sat outside our house using wifi. You don't want them on your production network poking around. If your home router supports a guest network then do this. You'll thank me later.<br>
Example: You're daughter breaks up with her Boyfriend and now you change the wifi password. If they are not on a guest network that means you're running around to X amount of devices changing the wifi. I have 40+ devices in my home.. changing the password is not an easy thing. Stick the kids and friends on guest and save yourself the headache.</li>
</ol>
<hr>
<p>Okay so now you realized that you need to have multiple wireless networks. Now what!?!</p>
<ul>
<li>Bust out the phone with the signal analyzer, walk around, and start looking where you need additional access points. You want -68 (or better) in all areas where devices will sit. Put your phone in the spot where the device will be. If the signal is greater than 68 (like -70 or -90) its time for a closer AP.</li>
<li>Put in additional access points.</li>
<li>Create your different wifi networks. Create your 2.4ghz legacy network, Setup your guest network and setup your 40mhz wide network.</li>
<li>Make sure each Access Point has its own non-DFS channel assigned to it that doesn't overlap with the access point near it.</li>
<li>Once again, look at those images on google and look at what channels do not overlap. Just say no to overlapping channels!</li>
</ul>
<hr>
<p>What about Mesh networks?</p>
<p>Disclaimer: I'm not familiar with the mesh networks and what channels they use for communications. Its very well possible that they use non DFS channels to build their connection but I don't know if that is 40 or 80 wide. My take on this would be to use non-DFS for the mesh. If it uses 40mhz wide that would still leave you non-DFS channels for use with clients. My only advise is to try and avoid DFS channels in your network layout.</p>
<p>Some reddit people will have to comment on Mesh networks and what they use for channel width.</p>
<p>Note: I spent the time running cables through my home to attach APs and avoid using mesh networks. This is because I was going for 80mhz throughout for optimal performance. While mesh works I personally did not want to go down that road.</p>
<hr>
<h1>Take Aways (thoughts)</h1>
<ul>
<li>Look at your wireless network and confirm you have no overlap</li>
<li>Turn down your wireless power and add additional access points</li>
<li>Design your network around -68 and better to all devices in your house</li>
<li>Design around 40mhz wide and only design for 80mhz wide for newer devices which require higher throughput</li>
<li>Only design for 80mhz wide if you have newer devices that support MU-MIMO 2x spatial streams. Only put newer MU-MIMO devices on your 80mhz wide wireless network. Only create 80mhz if you really really need 867mpbs.</li>
<li>Don't call your 2.4ghz wireless network the same name as your 5ghz wireless network. Create different wireless networks. It's okay, just don't exceed 4 networks (SSIDs)</li>
<li>Create a guest network for kids and friends. Never give them access to your production network.</li>
<li>Use your phone app/wireless signal analyzer to find weak spots in your wireless coverage</li>
<li>Try to avoid 2.4ghz whenever possible.</li>
</ul>
<hr>
<p>AND FINALLY</p>
<ol>
<li>IF IT DOESN'T MOVE IT GETS A PATCH CORD.<br>
If you have a device that is there all the time, and if possible, run an ethernet cable to it. Wireless is a shared medium meaning the bandwidth is shared and limited. It has to wait for people to stop talking before others can talk. Don't fill up your wireless network with devices that never move around. Spend the time and run an ethernet cable to it. The less devices on your wireless network the better performance you will have.</li>
<li>INVEST IN YOUR HOME NETWORK<br>
I know networking equipment isn't cheap but you really need to start thinking about what you're doing with your home network. Maybe you work from home, or watch movies, provide access for your kids to do research or school work, manage your home IOT devices/cameras/security systems. Start investing into your network since the amount of devices being added will only grow.</li>
</ol>
<p><u>And this is why Google Stadia recommends plugging the Chromecast into your ethernet connection.</u></p>
<p>They know most of you have a single router sitting in a closet somewhere and the signal strength is low. Most likely you have like 30 devices on a single access point so the airtime is limited for communications. You're probably too cheap to upgrade your 2.4ghz linksys router to something new. It's nothing personal but they know you most likely didn't invest in your home network, so recommending you plug-in your chromecast is an easy fix.</p>
<p>There are many factors that go into network performance and unfortunately many of these are outside the control of Google. Before you bash the service and get pissed off that Stadia sucks you really need to understand whats going on in your network and your Internet connection. Google Stadia is amazing and what it really showed us is that many networks have problems.</p>
<hr>
<p>So just because you have super fast Internet at home doesn't really mean you have a great network for Stadia.</p>
<p>-Motavar</p>
<p>PS:</p>
<blockquote>
<p>This post was to start a discussion on home networks in general.</p>
<p>I agree that bandwidth doesn't equal performance.</p>
<p>It probably would have be better for me to state that you cannot just throw a wifi router in your house and claim to have 1gbps internet so your performance is good. When your chromecast is connected at 2.4ghz on channel 3, you live in an apartment with 6 other neighbors using 2.4, and your chromecast is about 60 feet away from the router. The latency and interference would probably suck.</p>
<p>I think the goal here is to show that having a great internet connection is not always that easy. Setting up a home wireless network isn't always plug and play as it sounds.</p>
<p>There is work that goes into setting up your network (or wifi network) and a lot of people cannot just turn around and blindly blame Google because Stadia lags.</p>
<p>I'm hoping the community will chime in and offer advice for everyone that has network issues. There are more factors that we haven't touched on like other people on your network sucking up bandwidth, trying to prioritize network traffic, solar flares (hahah), I mean the list can go on and on and on.</p>
</blockquote>
<p>But maybe we can help everyone out and share setups that work. Go over products that seem to work for people. Point out things that cause issues on their networks. Maybe show how to trouble-shoot issues using traceroute or how to use a wifi analyzer on your phone. I'm not sure how far we want to go to help people but it's an attempt.</p>
<blockquote>
<p>But why go through all this effort?</p>
</blockquote>
<p>My personal goal is to promote Stadia because what I think what Google did here is amazing. It opens a whole new world of large scale gaming, gaming in any location that has a great Internet connection, opens up gaming on devices that do not have 3d hardware. Will it replace PCs and consoles.. nah.. but I see it opening more options for us as gamers. I think its cool that I can pick up a controller and play a game, then move to another room in the house without having to move a console. I think it's cool that I can travel and play a game on my work laptop or phone without any drama. I have nothing invested in google (and honestly my wife who works for Microsoft hates me when I talk about this) but I think this is something that we should promote. Lets help each other out. I mean really.. no one likes shitty Internet at their friends house. :)</p>
<p>PPS:</p>
<p><strong>Special Note on -68 signal strength</strong>:</p>
<p>When you see me talk about -68 OR LESS in signal strength I'm really talking about -0 to -68. For all my math friends out there technically this would be greater than -68 which would result in a smaller number like -30. But for this post I would request that you ignore the - part and think of signal strength as the smaller the number you see the better the signal is. We can get go down the rabbit hole of greater vs less than.. and that is what I expect from reddit but maybe we can save it for another day? :)</p>
<hr>
<p>Source: <a href="https://www.reddit.com/r/Stadia/comments/e7jrmf/your_network_design_and_google_stadia_we_need_to/">r/Stadia network design by u/Motovar</a>, <a href="https://www.reddit.com/r/Stadia/comments/kihb4b/how_to_properly_optimize_for_stadia/">r/Stadia optimize</a></p>
</div>cloudtag:acavalin.com,2005:Blog::Post/4342023-12-06T11:15:37+01:002024-01-31T12:47:08+01:00/p/web_chat_imChat from web with unknown contact2024-01-31T12:47:08ZTags: Browser, Messaging, Tools<hr/><div class="md2html codehilite"><p>Open chat from web to phone number without storing contact in address book:</p>
<table class="striped"><thead>
<tr>
<th>Service</th>
<th>Url</th>
</tr>
</thead><tbody>
<tr>
<td>WhatsApp</td>
<td><a href="https://wa.me/+39xxxxxxxxxx">https://wa.me/+39xxxxxxxxxx</a></td>
</tr>
<tr>
<td>Telegram</td>
<td><a href="https://t.me/+39xxxxxxxxxx">https://t.me/+39xxxxxxxxxx</a></td>
</tr>
</tbody></table>
</div>cloudtag:acavalin.com,2005:Blog::Post/4382024-01-26T17:37:57+01:002024-01-26T17:40:39+01:00/p/ventoy_win_vhdBoot Windows from VHD via Ventoy2024-01-26T17:40:39ZTags: Tools, Virtualization, Windows<hr/><div class="md2html codehilite"><p>In my experience, Windows updates are no issue. I've received them so far without any problems.</p>
<p>Here's what I did.</p>
<p><strong>Prerequisite</strong></p>
<ul>
<li> USB3 storage device with enough space for a Windows 10 install. I have a Samsung T5 that uses USB 3.1 Gen 2 speeds, but I'm 99% sure any USB3 device will be fine, especially if you got a decent amount of RAM so that Windows doesn't need to hit the paging file much.<br>
However, event this is not a hard requirement <a href="https://www.ventoy.net/en/doc_browser.html">because Ventoy can run off the internal hard drive</a>. I've just never bothered with that as all my internal disks are LUKS encrypted, so I'll consider it outside the scope of this write-up.</li>
</ul>
<p><strong>Setting up Ventoy</strong></p>
<ol>
<li><p><a href="https://www.ventoy.net/en/download.html">Download Ventoy</a> and run it.</p></li>
<li><p>Insert your target USB device. It should pop up in Ventoy interface.</p></li>
<li><p>Install Ventoy on it (<strong>THIS WILL DELETE ALL THE EXISTING DATA ON THE USB</strong>). The GUI is pretty easy. You can choose between UEFI and MBR (MBR should support both UEFI and Legacy BIOS), and between <a href="https://www.ventoy.net/en/doc_secure.html">Secure Boot on</a> and off. It's all supported. Just select whatever scheme your computer is using.</p></li>
<li><p>Create <code>/ventoy</code> folder in the root of the drive, and put into it <code>ventoy_vhdboot.img</code> downloaded from <a href="https://github.com/ventoy/vhdiso/releases">https://github.com/ventoy/vhdiso/releases</a>. It's in the .zip.</p></li>
</ol>
<p><strong>Setting up Windows</strong></p>
<ol>
<li><p>Download your virtualisation software of choice. I used <a href="https://www.virtualbox.org/">VirtualBox</a>, but any software that can read VHD files and run Windows should work.</p></li>
<li><p>Create a new VM, and within it, create a VHD virtual disk file. I suggest using dynamic disk size (so that the disk grows with your Windows install size) but fixed works too.</p></li>
<li><p>Boot Windows ISO and install Windows. Windows 7, 8, 10, and 11 all work. I used 10. Install it into the VM like normal. Allow Windows to use whole virtual disk.</p></li>
<li><p>Once you're happy with Windows in the VM shut it down, and boot it in VM again. Verify that the Windows is booting correctly in VM.</p></li>
</ol>
<p><strong>Putting it all together</strong></p>
<ol>
<li><p>With the Windows cleanly shutdown in the VM, and the VM off, copy the VHD file from wherever VM software put it to the root of the Ventoy partition (not in the <code>/ventoy</code> folder, and not in the tiny ventoyefi parition).<br>
Optionally, use checksum to confirm that the copying was clean and did not get corrupted.</p></li>
<li><p>With the Ventoy USB still plugged in, reboot your main PC, and enter into the boot menu. The Ventoy device should be visible, just like any Linux live USB would be. Select it.</p></li>
<li><p>A new menu pops up, showing your Windows VHD file. Select it.</p></li>
<li><p>That's it. Windows will boot on bare metal, off the USB device, and it will boot the contents of the VHD file.</p></li>
<li><p>Once you're done gaming, shut down Windows. If you unplug the USB, there will be no trace left of Windows on your PC as it is all contained within the VHD on the USB.</p></li>
</ol>
<p><strong>Thing to keep in mind</strong></p>
<ul>
<li><p>Once you boot into Windows on bare metal, you will need to install graphics drivers, launchers, Steam, like normal. There's no difference, it'll behave like a normal Windows install. You can accept Window updates.<br>
If you're really nervous about Windows updates, you could check the file into a local git repo, and if updates destroy your install, you can roll it back with git. However, I have never had any issues.</p></li>
<li><p>If you are gonna use Windows 10, use an ISO that's newer than Windows 10 v1809 as earlier versions require Ventoy to be using NTFS partition, which will be annoying. You can grab the latest ISO from Microsoft <a href="https://www.microsoft.com/en-us/software-download/windows10ISO">here</a>.</p></li>
<li><p>You'll probably want to store your actual game files on another disk. You can mount your computer's internal disks in Windows like normal as long as Windows can read it. I would suggest creating a btrfs partition and putting your Steam libary and game data there. Windows cannot read btrfs by default, but if you install <a href="https://github.com/maharmstone/btrfs">winbtrfs</a>, it can.<br>
Don't use NTFS, it won't work with Proton/Wine. Don't use exFAT, it does not support symlinks.</p></li>
</ul>
<p><strong>Bonus</strong></p>
<p>Now that you have Ventoy working, you can <a href="https://www.ventoy.net/en/plugin_vtoyboot.html">easily try Linux ISOs on bare metal without trashing your existing Linux install</a>. It's basically a distrohopping superpower.</p>
<p>To boot the Live ISO of a Linux distro, just drag it into Ventoy drive and boot it the same way as Windows.</p>
<p>To try it with persistence (<strong>much</strong> better), install the Linux ISO via VM (like you did with Windows) and then copy the VHD file to Ventoy drive and boot it on bare metal.<br>
Not all Linux distros are supported, but <strong>MANY</strong> are. It's basically the same as the above described process with Windows, with few differences:</p>
<ul>
<li><p>Linux distros don't work with dynamic VHDs. You have to use a fixed size one.</p></li>
<li><p>Once you boot the Linux install in the VM first time, you gotta install <code>vtoyboot.sh</code> found here: <a href="https://github.com/ventoy/vtoyboot/releases">https://github.com/ventoy/vtoyboot/releases</a>. Without it the Linux distro will not be bootable in Ventoy.<br>
You also need to re-run <code>vtoyboot.sh</code> if your distro receives kernel or bootloader updates.</p></li>
<li><p>Once you copy the .vhd file, you need to rename it with a file extension .vtoy; otherwise it won't boot. I usually just add it, so if my file is originally <code>linux.vhd</code>, I rename it to <code>linux.vhd.vtoy</code></p></li>
</ul>
<hr>
<p>Source: <a href="https://www.reddit.com/r/linux_gaming/comments/wxed28/comment/ilupj7z/?utm_source=share&utm_medium=web2x&context=3">reddit</a>, <a href="https://www.ventoy.net/en/plugin_vhdboot.html">ventoy docs</a></p>
</div>cloudtag:acavalin.com,2005:Blog::Post/1072017-07-25T15:05:24+02:002024-01-26T11:05:12+01:00/p/tasse_cc_cdTasse su conto corrente e deposito2024-01-26T11:05:12ZTags: Banca, Info<hr/><div class="md2html codehilite"><ol>
<li>In ambo i rapporti si paga il <code>26%</code> sugli interessi maturati.</li>
<li>Importo del bollo statale:
<ul>
<li><strong>Conto corrente:</strong> <code>34.20€</code> se saldo medio <code>>= 5000€</code> altrimenti <code>0€</code></li>
<li><strong>Conto deposito:</strong> <code>0.2%</code> del saldo se giacenza media <code>>= 5000€</code> altrimenti <code>1€</code><br>
NB: con un tasso lordo di <u>0.28%</u> si va a patta: <code>0.0028 * 0.74 - 0.002 =~ 0</code><br>
NB: conviene spostarli sul CC se: capitale > 34.2/(tasso * 0.74 - 0.002)</li>
</ul></li>
</ol>
<p><mark><a href="https://forum.finanzaonline.com/threads/conti-deposito-foglio-excel-calcolo-interessi-e-rendimenti-confronto-e-strategie-cap-xx-info-post-1-e-2.2048428/#post-59833795">XLS confronto tassi/condizioni conti deposito</a></mark></p>
<hr>
<p>Fonte: <a href="http://finanza.ilportafoglio.info/2014/12/tasse-conto-deposito-imposta-di-bollo-tassazione-interessi.html">ilportafoglio</a>, <a href="http://www.confrontaconti.it/guide-e-strumenti/domande-frequenti/quali-tasse-si-pagano-su-un-conto-corrente.aspx">confrontaconti</a></p>
</div>cloudtag:acavalin.com,2005:Blog::Post/3912023-01-20T18:43:08+01:002024-01-17T22:43:07+01:00/p/stadia_bluetooth_controllerStadia bluetooth controller2024-01-17T22:43:07ZTags: Games, Tools<hr/><div class="md2html codehilite"><h2><a href="https://stadia.google.com/controller/">bluetooth update</a></h2>
<p>The first time you turn on the controller, it should enter pairing mode — the status light should flash orange. To enter pairing mode manually, hold the “Y + Stadia” buttons for 2 seconds. Once paired, the controller auto-connects to the last paired device when turned on.</p>
<p>What the status lights mean:</p>
<ul>
<li>Flashing orange / Pairing mode, visible to other devices</li>
<li>Flashing white / Connecting to last paired device</li>
<li>Solid white / Connected to a device</li>
</ul>
<h2><a href="https://support.google.com/stadia/answer/13067284?visit_id=638098328106149906-3136869802&p=controllerconnect&rd=1#linuxrule&zippy=,im-on-a-linux-based-computer-and-cant-update-my-stadia-controller-help">flashing</a></h2>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16</pre></td><td class="code"><pre>sudo bash
<span class="o">{</span> cat <span class="sh"><<EOF
# SDP protocol
KERNEL=="hidraw*", ATTRS{idVendor}=="1fc9", MODE="0666"
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="1fc9", MODE="0666"
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="0d28", MODE="0666"
# Flashloader
KERNEL=="hidraw*", ATTRS{idVendor}=="15a2", MODE="0666"
# Controller
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="18d1", MODE="0666"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="18d1", ATTRS{idProduct}=="9400", MODE="0660", TAG+="uaccess"
EOF
</span><span class="o">}</span> | sudo tee /etc/udev/rules.d/70-stadiacontroller-flash.rules
udevadm control --reload-rules <span class="o">&&</span> udevadm trigger
</pre></td></tr></tbody></table>
</div>
<h2>references</h2>
<ul>
<li><a href="https://www.reddit.com/r/Stadia/comments/10ej13s/stadia_controller_how_to_enable_bluetooth/">official reddit post</a> and <a href="https://www.reddit.com/r/Stadia/comments/10ej13s/comment/j4rsvp5/">firmware bkup</a>, <a href="https://github.com/merlinschumacher/Stadia-Controller-Bluetooth-Firmware-Bin">on github</a></li>
<li><a href="https://www.reddit.com/r/Stadia/comments/189m06p/anyone_working_on_a_way_to_unlock_controller/">another reddit post</a> and <a href="https://github.com/Scyne/stadiaRawBtFw">firmware dump</a></li>
</ul>
</div>cloudtag:acavalin.com,2005:Blog::Post/1852018-04-20T18:14:08+02:002024-01-14T23:51:41+01:00/p/android_appsUseful Android apps2024-01-14T23:51:41ZTags: Android, Audio, Games, Images, Networking, Security, Tools, Video<hr/><div class="md2html codehilite"><p>Stores: <a href="https://play.google.com">Google Play</a>, <mark><a href="https://f-droid.org/packages/com.machiav3lli.fdroid/">NeoStore</a></mark>, <a href="https://f-droid.org">F-Droid</a>, <a href="https://f-droid.org/packages/com.looker.droidify/">Droid-ify</a>, <a href="https://auroraoss.com">Aurora</a> (<a href="https://gitlab.com/AuroraOSS/AuroraStore">src</a>)</p>
<h3>To check</h3>
<ul>
<li><a href="https://forum.fairphone.com/t/fp4-which-camera-app/81750/25">FP4 alt. camera</a>
<ul>
<li><mark><a href="https://play.google.com/store/apps/details?id=app.grapheneos.camera.play">Secure Camera</a></mark></li>
<li><a href="https://play.google.com/store/apps/details?id=net.sourceforge.opencamera">Open Camera</a></li>
<li>GCam: <a href="https://www.celsoazevedo.com/files/android/google-camera/dev-wichaya/">wichaya</a>, <a href="https://www.celsoazevedo.com/files/android/google-camera/dev-Nikita/">nikita</a></li>
</ul></li>
<li>Games:
<ul>
<li><a href="https://f-droid.org/en/packages/com.swordfish.lemuroid/">lemuroid</a> -- libretro emulator</li>
<li><a href="https://www.golfgl.de/lightblocks/">lightblocks</a> -- tetris clone for any device</li>
</ul></li>
<li><a href="https://f-droid.org/packages/com.foobnix.pro.pdf.reader/">Librera Reader</a> -- eBook and PDF reader</li>
<li><a href="https://github.com/zhanghai/materialfiles">MaterialFiles</a> -- file manager</li>
<li>Multi profiles:
<ul>
<li><a href="https://f-droid.org/packages/net.typeblog.shelter/">Shelter</a> -- Isolate and run multiple instances of apps using Work Profiles</li>
<li><a href="https://github.com/WaxMoon/MultiApp">MultiApp</a> -- virtual Android container</li>
</ul></li>
<li><a href="https://github.com/kabouzeid/Phonograph">Phonograph</a> -- material music player</li>
<li>Image gallery:
<ul>
<li><a href="https://f-droid.org/packages/deckers.thibault.aves.libre/">deckerst/Aves</a> / <a href="https://github.com/deckerst/aves">gh</a></li>
<li><a href="https://f-droid.org/packages/com.dot.gallery/">IacobIonut01/Gallery</a> / <a href="https://github.com/IacobIonut01/Gallery">gh</a></li>
</ul></li>
<li><a href="https://play.google.com/store/apps/dev?id=8268163890866913014&hl=en_US">Goodwy apps</a> / <a href="https://github.com/Goodwy">gh</a></li>
<li><a href="https://f-droid.org/en/packages/com.github.axet.audiorecorder/">Audio Recorder</a></li>
<li><a href="https://github.com/FossifyOrg">FossifyOrg</a> -- a <a href="https://github.com/SimpleMobileTools">SimpleMobileTools fork</a> before <a href="https://www.reddit.com/r/fossdroid/comments/1893j2p/simple_mobile_tools_is_about_to_be_acquired/">acquisition</a></li>
<li><a href="https://play.google.com/store/apps/details?id=app.alextran.immich">Immich</a> / <a href="https://immich.app/">hp</a> / <a href="https://github.com/immich-app/immich">gh</a> -- Self-hosted backup solution for photos and videos</li>
<li><a href="https://play.google.com/store/apps/details?id=com.folderv.file">FV File Manager</a> + <a href="https://shizuku.rikka.app/guide/setup/">Shizuku</a> bridge -- workaround <a href="https://www.reddit.com/r/Android/comments/j3zgmm/managing_files_in_the_androiddata_folder_on/">android 13 locking /Android/data</a></li>
</ul>
<h3>General</h3>
<ul>
<li><a href="https://play.google.com/store/apps/details?id=com.Astalavist4.prependcountrycodefree">Add Country Code</a> -- fix contacts</li>
<li><a href="https://play.google.com/store/apps/details?id=com.aftership.AfterShip">AfterShip</a> -- post tracking</li>
<li><a href="https://play.google.com/store/apps/details?id=com.andropenoffice">AndrOpen Office</a> -- libre office port</li>
<li><a href="https://play.google.com/store/apps/details?id=skezza.main">BigSMS</a></li>
<li><a href="https://play.google.com/store/apps/details?id=de.sfr.calctape">CalcTape</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.geonaute.geonaute">Decathlon Coach</a> -- <a href="https://www.decathloncoach.com/it/home/advices/advice/mon-defi-gym-routine-great-pilates-domyos211">home</a>, esercizi da 10/15'/gg</li>
<li><a href="https://play.google.com/store/apps/details?id=com.deepl.mobiletranslator">DeepL Translate</a></li>
<li><a href="https://f-droid.org/packages/ws.xsoh.etar/">Etar</a> -- OpenSource Calendar</li>
<li><a href="https://play.google.com/store/apps/details?id=com.syncedsynapse.eventflowwidget">Event Flow Widget</a></li>
<li><a href="https://play.google.com/store/apps/details?id=org.mozilla.focus">Firefox focus</a></li>
<li><a href="https://github.com/helloworld1/FreeOTPPlus">Free-OTP+</a> / <a href="https://github.com/freeotp/freeotp-android">Free-OTP</a> -- free TOTP autenticator</li>
<li><a href="https://play.google.com/store/apps/details?id=com.google.android.apps.docs">Google Drive</a> -- copy to clipboard share option</li>
<li><a href="https://play.google.com/store/apps/details?id=com.android.keepass">KeePassDroid</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.flufflydelusions.app.enotesclassiclite">Classic notes lite</a> -- notepad on steroids</li>
<li><a href="https://play.google.com/store/apps/details?id=com.teslacoilsw.launcher.prime">Nova Launcher</a> + <a href="https://play.google.com/store/apps/details?id=com.teslacoilsw.notifier">TeslaUnread</a> -- unread badges</li>
<li><a href="https://play.google.com/store/apps/details?id=acr.browser.lightning">Lightning browser</a></li>
<li><a href="https://play.google.com/store/apps/details?id=org.stanwu.smartscreenlockpro">Off+</a> -- turn off screen hack</li>
<li><a href="https://play.google.com/store/apps/details?id=com.opera.mini.native">OperaMini</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.ciaostudio.pixeliconpack">Pixeful icon pack</a> -- inexpensive icon pack (usable with Nova launcher)</li>
<li><a href="https://play.google.com/store/apps/details?id=org.plantnet">Pl@ntNet</a> -- plant recognition</li>
<li><a href="https://github.com/sunnygoyal/PowerToggles">Power Toggles</a></li>
<li><a href="https://play.google.com/store/apps/details?id=la.droid.qr">QR Droid</a> -- bar/qrcode scanner</li>
<li><a href="https://play.google.com/store/apps/details?id=com.katecca.screenofflock">Screen Off</a> -- lock display widget</li>
<li><a href="https://play.google.com/store/apps/details?id=org.mistergroup.muzutozvednout">Should I Answer?</a> -- call spam blocker</li>
<li><a href="https://play.google.com/store/apps/details?id=com.riteshsahu.SMSBackupRestore">SMS Backup & Restore</a></li>
<li><a href="https://play.google.com/store/apps/details?id=Orion.Soft">Sound Profile</a> -- rich sound profile manager</li>
<li><a href="https://play.google.com/store/apps/details?id=com.sygic.aura">Sygic</a> -- car navigator</li>
<li><a href="https://play.google.com/store/apps/details?id=com.sygiclabs.voice">Telegram</a> -- IM</li>
<li><a href="https://play.google.com/store/apps/details?id=com.textra">Textra</a> -- customizable SMS app</li>
<li><a href="https://play.google.com/store/apps/details?id=com.cootek.smartinputv5">TouchPal</a> -- very customizable multi-mode keyboard</li>
<li><a href="https://play.google.com/store/apps/details?id=com.vuze.torrent.downloader">Vuze</a> -- torrent downloader</li>
<li><a href="https://play.google.com/store/apps/details?id=fr.gaulupeau.apps.InThePoche">Wallabag</a> -- save articles to read later</li>
<li><del><a href="https://play.google.com/store/apps/details?id=cn.wps.moffice_eng">WPS Office</a> -- MSOffice compatible</del> <em>use AndrOpen Office</em></li>
</ul>
<h3>Media</h3>
<ul>
<li><a href="https://play.google.com/store/apps/details?id=com.boldbeast.recorder">Boldbeast Recorder</a> / <a href="https://www.boldbeast.com/android/call_recorder.html">hp</a> -- audio & call recorder</li>
<li><a href="https://f-droid.org/en/packages/com.github.axet.bookreader/">BookReader</a> -- ebook reader (epub, ecc)</li>
<li><a href="https://play.google.com/store/apps/details?id=com.flavionet.android.camera.pro">Camera FV-5</a></li>
<li><a href="https://play.google.com/store/apps/details?id=net.fred.feedex">Flym feed reader</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.bianor.amspersonal">iMediaShare</a> -- media caster</li>
<li><a href="https://github.com/YTVanced/VancedManager">YouTube Vanced</a> -- YT ad free + background play</li>
<li><a href="https://play.google.com/store/apps/details?id=com.rookiestudio.perfectviewer">Perfect Viewer</a> -- image viewer</li>
<li><a href="https://play.google.com/store/apps/details?id=com.diune.pictures">Piktures</a> -- simple & powerful gallery</li>
<li><a href="https://play.google.com/store/apps/details?id=com.rhmsoft.pulsar.pro">Pulsar</a> -- music player</li>
<li><a href="https://play.google.com/store/apps/details?id=de.program_co.benclockradioplusplus">Radio alarm clock++</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.radiosonline.radiofmitalia">Radio FM Italia</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.adam.aslfms">Simple Last.fm Scrobbler</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.andrwq.recorder">Smart Recorder</a> -- audio recorder</li>
<li><a href="https://play.google.com/store/apps/details?id=com.niksoftware.snapseed">Snapseed</a> -- rich image editor</li>
<li><a href="https://play.google.com/store/apps/details?id=com.melodis.midomiMusicIdentifier.freemium">Sound Hound</a> -- song search by your own whistles and voice!</li>
<li><a href="https://play.google.com/store/apps/details?id=org.videolan.vlc">VLC</a> -- rich video player + DLNA renderer</li>
</ul>
<h3>Games</h3>
<ul>
<li><a href="https://play.google.com/store/apps/details?id=com.squareenixmontreal.avssi">Alien Vs Space invaders</a></li>
<li><a href="https://play.google.com/store/apps/details?id=jp.co.ponos.yasumimasu">Day Off</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.linegames.dcglobal">Destiny Child</a> -- <a href="/p/destiny_child_game_resources">dedicated post</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.squareenixmontreal.deusexgo">Deus Ex Go</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.The717pixels.DungeonCards">Dungeon cards</a></li>
<li><a href="https://play.google.com/store/apps/details?id=ru.elron.gamepadtester">GamePad Tester</a> -- test controller</li>
<li><a href="https://play.google.com/store/apps/details?id=com.devolver.grispaid">GRIS</a></li>
<li><a href="https://play.google.com/store/apps/details?id=uk.co.aifactory.heartsfree">Hearts Free</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.wooga.jelly_splash">Jelly Splash</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.squareenixmontreal.lcgo">Lara Croft Go</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.pavostudio.live2dviewerex">Live2DViewerEX</a> -- <a href="https://store.steampowered.com/app/616720/Live2DViewerEX/">steam license</a></li>
<li><a href="https://play.google.com/store/apps/details?id=air.com.coworkdream.PicrossLUNA">Picross Luna I</a> & <a href="https://play.google.com/store/apps/details?id=air.com.coworkdream.PicrossLUNA2">Picross Luna II</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.fortafygames.pigeonpop">Pigeon Pop</a>, <a href="https://pigeon-pop.it.uptodown.com/android">alt</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.spookyhousestudios.progressbar95">Progressbar95</a></li>
<li><del><a href="https://play.google.com/store/apps/details?id=jp.co.capcom.smash.retail">Puzzle Fighter</a></del></li>
<li><a href="https://play.google.com/store/apps/details?id=com.shatteredpixel.shatteredpixeldungeon">Shattered Pixel Dungeon</a> <strong>foss</strong> -- <a href="https://github.com/00-Evan/shattered-pixel-dungeon">github</a>, <a href="https://f-droid.org/en/packages/com.shatteredpixel.shatteredpixeldungeon/">f-droid</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.explusalpha.Snes9xPlus">Snes9x EX+</a></li>
<li>--- to see ---</li>
<li><a href="https://play.google.com/store/apps/details?id=com.sega.HokutoRevive.en">Fist of the north star</a> (Hokuto no Ken)</li>
<li><a href="https://play.google.com/store/apps/details?id=com.miHoYo.bh3global">Honkai Impact 3rd</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.netmarble.kofg">The King of Fighters ALLSTAR</a></li>
</ul>
<h3>System</h3>
<ul>
<li><a href="https://play.google.com/store/apps/details?id=com.digibites.accubattery">AccuBattery</a> -- alert when reaching xx% charge level</li>
<li><a href="https://play.google.com/store/apps/details?id=com.cpuid.cpu_z">CPUz</a> | <a href="https://play.google.com/store/apps/details?id=ru.andr7e.deviceinfohw">Device Info HW</a></li>
<li><a href="https://f-droid.org/packages/at.bitfire.davdroid/">DavX5</a> -- CalDAV, CardDav sync</li>
<li><a href="https://play.google.com/store/apps/details?id=com.google.android.diskusage">DiskUsage</a> -- xdiskusage port</li>
<li><a href="https://play.google.com/store/apps/details?id=com.ghostsq.commander">Ghost Commander</a> -- TotalC./MC/NC <strong>foss</strong> clone</li>
<li><a href="https://play.google.com/store/apps/details?id=org.pocketworkstation.pckeyboard">Hacker's Keyboard</a> -- full PC keyboard</li>
<li><a href="https://play.google.com/store/apps/details?id=com.sonelli.juicessh">JuiceSSH</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.blackspruce.lpd">Let's Print Droid</a> -- CUPS client</li>
<li><a href="https://play.google.com/store/apps/details?id=com.blackspruce.mupdf">Let's Print PDF</a></li>
<li><a href="https://play.google.com/store/apps/details?id=ru.gelin.android.browser.open">Open in browser</a></li>
<li><a href="https://play.google.com/store/apps/details?id=de.blinkt.openvpn">OpenVPN</a></li>
<li><a href="https://play.google.com/store/apps/details?id=net.mx17.overridedns">Override DNS</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.rhmsoft.edit.pro">QuickEdit Pro</a> -- fast text editor</li>
<li><a href="https://play.google.com/store/apps/details?id=at.android.autosync">Quick Sync</a> widget -- sync Google account</li>
<li><a href="https://play.google.com/store/apps/details?id=com.glavsoft.rrviewerpro">Remote Ripple</a> -- vnc viewer</li>
<li><a href="https://play.google.com/store/apps/details?id=com.sane.droid">SANEDroid</a> -- SANE client</li>
<li><a href="https://play.google.com/store/apps/dev?id=9070296388022589266">Simple Mobile Tools</a> -- replacements for all fundamental apps</li>
<li><a href="https://play.google.com/store/apps/details?id=net.dinglisch.android.taskerm">Tasker</a> -- <a href="https://tasker.joaoapps.com/">homepage</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.termux">Termux</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.keramidas.TitaniumBackup">Titanium backup</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.ghisler.android.TotalCommander">Total commander</a> -- rich file manager <a href="http://midnight-commander.org/">MC style</a></li>
<li><a href="https://play.google.com/store/apps/details?id=free.vpn.unblock.proxy.turbovpn">Turbo VPN</a> -- AD supported free VPN</li>
<li><a href="https://play.google.com/store/apps/details?id=com.malerbati.wifionoff">Wi-Fi on/off</a> widget</li>
<li><a href="https://play.google.com/store/apps/details?id=ru.zdevs.zarchiver">ZArchiver</a> -- supports many archive types (7zip) </li>
</ul>
<h3>Home automation</h3>
<ul>
<li>~<del><a href="https://play.google.com/store/apps/details?id=com.dlink.mydlinkmyhome">mydlink Home</a></del>~ -- socket <a href="https://www.amazon.it/dp/B00OK34DBK">D-Link DSP-W215</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.tuya.smartlife">SmartLife</a> -- rbg lamp <a href="https://www.amazon.it/dp/B07MV3MRR9">LOFTer 10W</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.tplink.iot">TP-Link Tapo</a> -- socket <a href="https://www.amazon.it/dp/B07Z5JD3T4">Tapo P100</a></li>
</ul>
<h3>Svago</h3>
<ul>
<li><a href="https://play.google.com/store/apps/details?id=it.kindjackal.lcga">Lucca Comics</a></li>
</ul>
<hr>
<p>Other lists:
<a href="https://forum.xda-developers.com/t/android-ultimate-collection-guides.4513231/">Retrial</a>,
<a href="https://github.com/Finalboss77/Best-foss-apps-for-privacy-security-android">Finalboss77</a></p>
</div>cloudtag:acavalin.com,2005:Blog::Post/2902020-03-04T17:31:13+01:002024-01-14T14:11:08+01:00/p/multimedia_scripts_for_windowsMultimedia scripts for windows2024-01-14T14:11:08ZTags: Cygwin, Images, Terminal, Tools, Video, Windows<hr/><div class="md2html codehilite"><h3>external tools</h3>
<ul>
<li><a href="https://www.ffmpeg.org/download.html">ffmpeg for windows</a></li>
<li><a href="https://www.sentex.ca/%7Emwandel/jhead/">jhead</a></li>
<li><a href="https://visipics.info">VisiPics</a> photo duplicate finder</li>
<li><a href="https://windirstat.net">WinDirStat</a> folder tree size</li>
</ul>
<h3><code>comprimi_media</code></h3>
<div class="hll ruby"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11</pre></td><td class="code"><pre><span class="c1">#!/bin/env ruby</span>
<span class="n">dirs</span> <span class="o">=</span> <span class="sx">%x[ find -mindepth 1 -maxdepth 1 -type d ]</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">).</span><span class="nf">sort</span>
<span class="n">dirs</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">d</span><span class="o">|</span>
<span class="nb">puts</span> <span class="s2">"===== CARTELLA [ </span><span class="si">#{</span><span class="n">d</span><span class="si">}</span><span class="s2"> ] ====="</span>
<span class="nb">print</span> <span class="s1">'foto : '</span><span class="p">;</span> <span class="nb">system</span> <span class="s1">'ls|egrep -i "(jpe*g|png|heic)$"|wc -l'</span><span class="p">,</span> <span class="ss">chdir: </span><span class="n">d</span>
<span class="nb">print</span> <span class="s1">'video: '</span><span class="p">;</span> <span class="nb">system</span> <span class="s1">'ls|egrep -i "(mp4|mov|avi|mpeg|hevc)$"|wc -l'</span><span class="p">,</span> <span class="ss">chdir: </span><span class="n">d</span>
<span class="nb">system</span> <span class="s1">'comprimi_media.single'</span><span class="p">,</span> <span class="ss">chdir: </span><span class="n">d</span>
<span class="k">end</span>
<span class="nb">puts</span> <span class="s2">"</span><span class="se">\n\n</span><span class="s2">FINE"</span>
</pre></td></tr></tbody></table>
</div>
<h3><code>comprimi_media.single</code></h3>
<div class="hll ruby"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62</pre></td><td class="code"><pre><span class="c1">#!/bin/env ruby</span>
<span class="sx">%w{ shellwords FileUtils progressbar }</span><span class="p">.</span><span class="nf">each</span><span class="p">{</span><span class="o">|</span><span class="n">l</span><span class="o">|</span> <span class="nb">require</span> <span class="n">l</span> <span class="p">}</span>
<span class="n">pb_opts</span> <span class="o">=</span> <span class="p">{</span> <span class="ss">progress_mark: </span><span class="s1">'#'</span><span class="p">,</span> <span class="ss">remainder_mark: </span><span class="s1">'_'</span><span class="p">,</span> <span class="ss">length: </span><span class="mi">79</span><span class="p">,</span>
<span class="ss">starting_at: </span><span class="mi">0</span><span class="p">,</span> <span class="ss">format: </span><span class="s1">'%t: %J<br> [%B] %e'</span><span class="p">}</span>
<span class="n">all_files</span> <span class="o">=</span> <span class="no">Dir</span><span class="p">[</span><span class="s1">'*'</span><span class="p">].</span><span class="nf">sort</span>
<span class="n">all_files</span><span class="p">.</span><span class="nf">grep</span><span class="p">(</span><span class="sr">/\.(aae)$/i</span><span class="p">).</span><span class="nf">each</span><span class="p">{</span><span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="no">FileUtils</span><span class="p">.</span><span class="nf">rm_f</span> <span class="n">f</span> <span class="p">}</span>
<span class="n">re_images</span> <span class="o">=</span> <span class="sr">/\.(jpe*g|png|heic)$/i</span>
<span class="n">files</span> <span class="o">=</span> <span class="n">all_files</span><span class="p">.</span><span class="nf">grep</span><span class="p">(</span><span class="n">re_images</span><span class="p">)</span>
<span class="k">if</span> <span class="n">files</span><span class="p">.</span><span class="nf">size</span> <span class="o">></span> <span class="mi">0</span>
<span class="nb">puts</span> <span class="s1">''</span>
<span class="no">FileUtils</span><span class="p">.</span><span class="nf">mkdir_p</span> <span class="s1">'_fatti'</span>
<span class="no">FileUtils</span><span class="p">.</span><span class="nf">mkdir_p</span> <span class="s1">'foto'</span>
<span class="n">pb</span> <span class="o">=</span> <span class="no">ProgressBar</span><span class="p">.</span><span class="nf">create</span> <span class="n">pb_opts</span><span class="p">.</span><span class="nf">merge</span><span class="p">(</span><span class="ss">title: </span><span class="s2">"</span><span class="si">#{</span><span class="n">files</span><span class="p">.</span><span class="nf">size</span><span class="si">}</span><span class="s2"> immagini"</span><span class="p">,</span> <span class="ss">total: </span><span class="n">files</span><span class="p">.</span><span class="nf">size</span><span class="p">)</span>
<span class="n">files</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span>
<span class="n">pb</span><span class="p">.</span><span class="nf">log</span> <span class="s2">" => </span><span class="si">#{</span><span class="n">f</span><span class="si">}</span><span class="s2">"</span>
<span class="n">fout</span> <span class="o">=</span> <span class="n">f</span><span class="p">.</span><span class="nf">sub</span><span class="p">(</span><span class="n">re_images</span><span class="p">,</span> <span class="s1">'.jpg'</span><span class="p">)</span>
<span class="nb">system</span> <span class="sx">%Q| convert -quality 80 </span><span class="si">#{</span><span class="n">f</span><span class="p">.</span><span class="nf">shellescape</span><span class="si">}</span><span class="sx"> foto/</span><span class="si">#{</span><span class="n">fout</span><span class="p">.</span><span class="nf">shellescape</span><span class="si">}</span><span class="sx"> |</span>
<span class="no">FileUtils</span><span class="p">.</span><span class="nf">mv</span> <span class="n">f</span><span class="p">,</span> <span class="s2">"_fatti/</span><span class="si">#{</span><span class="n">f</span><span class="si">}</span><span class="s2">"</span> <span class="k">if</span> <span class="vg">$?</span><span class="p">.</span><span class="nf">to_i</span> <span class="o">==</span> <span class="mi">0</span>
<span class="n">pb</span><span class="p">.</span><span class="nf">increment</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">re_videos</span> <span class="o">=</span> <span class="sr">/\.(mp4|mov|avi|mpeg|hevc)$/i</span>
<span class="n">files</span> <span class="o">=</span> <span class="n">all_files</span><span class="p">.</span><span class="nf">grep</span><span class="p">(</span><span class="n">re_videos</span><span class="p">)</span>
<span class="k">if</span> <span class="n">files</span><span class="p">.</span><span class="nf">size</span> <span class="o">></span> <span class="mi">0</span>
<span class="nb">puts</span> <span class="s1">''</span>
<span class="no">FileUtils</span><span class="p">.</span><span class="nf">mkdir_p</span> <span class="s1">'_fatti'</span>
<span class="no">FileUtils</span><span class="p">.</span><span class="nf">mkdir_p</span> <span class="s1">'video'</span>
<span class="n">pb</span> <span class="o">=</span> <span class="no">ProgressBar</span><span class="p">.</span><span class="nf">create</span> <span class="n">pb_opts</span><span class="p">.</span><span class="nf">merge</span><span class="p">(</span><span class="ss">title: </span><span class="s2">"</span><span class="si">#{</span><span class="n">files</span><span class="p">.</span><span class="nf">size</span><span class="si">}</span><span class="s2"> video"</span><span class="p">,</span> <span class="ss">total: </span><span class="n">files</span><span class="p">.</span><span class="nf">size</span><span class="p">)</span>
<span class="n">files</span><span class="p">.</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span>
<span class="n">pb</span><span class="p">.</span><span class="nf">log</span> <span class="s2">" => </span><span class="si">#{</span><span class="n">f</span><span class="si">}</span><span class="s2">"</span>
<span class="n">fout</span> <span class="o">=</span> <span class="n">f</span><span class="p">.</span><span class="nf">sub</span><span class="p">(</span><span class="n">re_videos</span><span class="p">,</span> <span class="s1">'.mp4'</span><span class="p">)</span>
<span class="c1"># https://superuser.com/questions/326629/how-can-i-make-ffmpeg-be-quieter-less-verbose</span>
<span class="nb">system</span> <span class="sx">%Q| ffmpeg -hide_banner -loglevel error -stats -i </span><span class="si">#{</span><span class="n">f</span><span class="p">.</span><span class="nf">shellescape</span><span class="si">}</span><span class="sx"> -c:v libx264 -c:a libmp3lame -b:a 128k video/</span><span class="si">#{</span><span class="n">fout</span><span class="p">.</span><span class="nf">shellescape</span><span class="si">}</span><span class="sx"> |</span>
<span class="no">FileUtils</span><span class="p">.</span><span class="nf">mv</span> <span class="n">f</span><span class="p">,</span> <span class="s2">"_fatti/</span><span class="si">#{</span><span class="n">f</span><span class="si">}</span><span class="s2">"</span> <span class="k">if</span> <span class="vg">$?</span><span class="p">.</span><span class="nf">to_i</span> <span class="o">==</span> <span class="mi">0</span>
<span class="n">pb</span><span class="p">.</span><span class="nf">increment</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">if</span> <span class="no">Dir</span><span class="p">[</span><span class="s1">'*'</span><span class="p">].</span><span class="nf">reject</span><span class="p">{</span><span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="no">File</span><span class="p">.</span><span class="nf">directory?</span> <span class="n">f</span> <span class="p">}.</span><span class="nf">size</span> <span class="o">==</span> <span class="mi">0</span>
<span class="c1"># elinmina fatti se tutto e' andato a buon fine</span>
<span class="no">FileUtils</span><span class="p">.</span><span class="nf">rm_rf</span> <span class="s1">'_fatti'</span>
<span class="c1"># elimina l'unica cartella presente dopo averne spostato i files nel parent</span>
<span class="k">if</span> <span class="no">Dir</span><span class="p">[</span><span class="s1">'*'</span><span class="p">].</span><span class="nf">size</span> <span class="o">==</span> <span class="mi">1</span>
<span class="n">dir</span> <span class="o">=</span> <span class="no">Dir</span><span class="p">[</span><span class="s1">'*'</span><span class="p">].</span><span class="nf">first</span>
<span class="nb">system</span> <span class="s2">"mv -i * .."</span><span class="p">,</span> <span class="ss">chdir: </span><span class="n">dir</span>
<span class="no">FileUtils</span><span class="p">.</span><span class="nf">rm_rf</span> <span class="n">dir</span> <span class="k">if</span> <span class="vg">$?</span><span class="p">.</span><span class="nf">to_i</span> <span class="o">==</span> <span class="mi">0</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="c1"># mostra evntuali cartelle _fatti ancora presenti</span>
<span class="n">dirs</span> <span class="o">=</span> <span class="sx">%x[ find -mindepth 1 -type d -name _fatti ]</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">).</span><span class="nf">sort</span><span class="p">.</span><span class="nf">map</span><span class="p">{</span><span class="o">|</span><span class="n">d</span><span class="o">|</span> <span class="no">File</span><span class="p">.</span><span class="nf">dirname</span> <span class="n">d</span><span class="p">[</span><span class="mi">2</span><span class="p">,</span><span class="mi">300</span><span class="p">]</span> <span class="p">}</span>
<span class="k">if</span> <span class="n">dirs</span><span class="p">.</span><span class="nf">size</span> <span class="o">></span> <span class="mi">0</span>
<span class="nb">puts</span> <span class="s2">"Cartelle da controllare:"</span>
<span class="nb">puts</span> <span class="n">dirs</span>
<span class="k">end</span>
</pre></td></tr></tbody></table>
</div>
<h3>misc ruby</h3>
<div class="hll ruby"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5</pre></td><td class="code"><pre><span class="c1"># rename_foto_by_ts</span>
<span class="n">ruby</span> <span class="o">-</span><span class="n">e</span> <span class="s1">'Dir["**/*"].grep(/\.jpg/i).sort.each{|f| system %Q[jhead -n"%Y-%m-%d_%H-%M-%S" "#{f}"] }'</span>
<span class="c1"># enumerate files</span>
<span class="no">Dir</span><span class="p">[</span><span class="s1">'*'</span><span class="p">].</span><span class="nf">sort</span><span class="p">.</span><span class="nf">each_with_index</span><span class="p">{</span><span class="o">|</span><span class="n">f</span><span class="p">,</span> <span class="n">i</span><span class="o">|</span> <span class="no">File</span><span class="p">.</span><span class="nf">rename</span> <span class="n">f</span><span class="p">,</span> <span class="s2">"</span><span class="si">#{</span><span class="s1">'%04d'</span> <span class="o">%</span> <span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="si">}</span><span class="s2">.mp4"</span><span class="p">};</span> <span class="kp">nil</span>
</pre></td></tr></tbody></table>
</div>
<h3>misc shell</h3>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5</pre></td><td class="code"><pre><span class="c"># PDF to JPG</span>
ls <span class="k">*</span>.pdf | sed -r <span class="s1">'s/(.+).pdf/pdftoppm -jpeg \0 \L\1.jpg/'</span> | sh
<span class="c"># lossless rotate JPG</span>
jpegtran -rotate 90 <span class="k">in</span>.jpg > out.jpg
</pre></td></tr></tbody></table>
</div>
</div>cloudtag:acavalin.com,2005:Blog::Post/4192023-09-29T11:14:26+02:002023-12-26T17:21:49+01:00/p/rvm_install_ruby_with_jemalloc_yjitRVM install Ruby with jemalloc and YJIT2023-12-26T17:21:49ZTags: HowTo, Ruby<hr/><div class="md2html codehilite"><p><strong>Note:</strong> YJIT is only available on arm64 and aarch64.</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19</pre></td><td class="code"><pre>apt install rustc <span class="c"># needed by YJIT</span>
apt install libjemalloc-dev <span class="c"># needed by jemalloc</span>
<span class="c"># install</span>
rvm install ruby-3.3.0 -C --with-jemalloc --enable-yjit
<span class="c"># jemalloc test 1</span>
<span class="nv">MALLOC_CONF</span><span class="o">=</span>stats_print:true rvm 3.3.0 <span class="k">do </span>ruby -e <span class="s2">"exit"</span>
<span class="c"># jemalloc test 2</span>
ldd <span class="sb">`</span>which ruby<span class="sb">`</span> | grep jemalloc
<span class="c"># => libjemalloc.so.2 => /lib/aarch64-linux-gnu/libjemalloc.so.2</span>
<span class="c"># YJIT test</span>
ruby --yjit -v
<span class="c"># => ruby 3.3.0 (2023-12-25 revision 5124f9ac75) +YJIT [aarch64-linux]</span>
<span class="c"># YJIT lazy loading:</span>
ruby --yjit --yjit-disable -e <span class="s2">"... ; RubyVM::YJIT.enable ; ..."</span>
</pre></td></tr></tbody></table>
</div>
<hr>
<p>Source:
<a href="https://stackoverflow.com/questions/43908844/error-on-installing-ruby-with-jemalloc/55075298#55075298">jemalloc @ stackoverflow.com</a>,
YJIT <a href="https://docs.ruby-lang.org/en/master/yjit/yjit_md.html">docs</a> and <a href="https://github.com/rvm/rvm/issues/5138">RVM howto</a></p>
</div>cloudtag:acavalin.com,2005:Blog::Post/3992023-05-26T16:23:28+02:002023-12-19T18:08:20+01:00/p/kobo_toolsKobo tools2023-12-19T18:08:20ZTags: HowTo, Kobo, Tools, eReader<hr/><div class="md2html codehilite"><h1>Resolutions</h1>
<ul>
<li>Sage: 1440x1920</li>
<li>Glo: 758x1024</li>
</ul>
<h1>Developer mode / hidden settings</h1>
<ol>
<li>Type <code>devmodeon</code> in the searchbar, search and return to home screen</li>
<li>New menu entry apperars: Settings > Device Information > Developer options</li>
<li>Optional: type <code>devmodeoff</code> to disable it</li>
</ol>
<h1>NickelMenu / quick launcher</h1>
<ol>
<li>Download latest <code>KoboRoot.tgz</code> from <a href="https://pgaskin.net/NickelMenu/">home page</a>/<a href="https://github.com/pgaskin/NickelMenu">github</a></li>
<li>Connect Kobo to your PC</li>
<li>Put KoboRoot.tgz into <code>KOBOeReader/.kobo</code></li>
<li>Eject your eReader and wait for it to <u>reboot</u></li>
<li>Ensure there is a new menu item in the bottom-right
main menu entitled <u>NickelMenu</u></li>
<li>Connect Kobo to your PC again and create a file
named <code>KOBOeReader/.adds/nm/config</code>, and follow
the instructions in <code>KOBOeReader/.adds/nm/doc</code>
to configure NickelMenu</li>
</ol>
<p>Example:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42</pre></td><td class="code"><pre>menu_item :main :Browser <span class="o">(</span>fullscreen<span class="o">)</span> :nickel_browser :
menu_item :main :Browser <span class="o">(</span>modal<span class="o">)</span> :nickel_browser :modal
<span class="c"># KOreader: prevent Kobo from scanning hidden folders on 4.17+</span>
<span class="c"># https://github.com/koreader/koreader/wiki/Installation-on-Kobo-devices#important-notes</span>
<span class="c"># ==> append in ".kobo/Kobo/Kobo eReader.conf":</span>
<span class="c"># [FeatureSettings]</span>
<span class="c"># ExcludeSyncFolders=(\\.(?!kobo|adobe).+|([^.][^/]*/)+\\..+)</span>
menu_item :main :KOReader :cmd_spawn :quiet :exec /mnt/onboard/.adds/koreader/koreader.sh
menu_item :main :Plato :cmd_spawn :quiet :/mnt/onboard/.adds/plato/plato.sh
menu_item :main :Invert Screen :nickel_orientation :invert
menu_item :main :Sudoku :nickel_extras :sudoku
<span class="c">#menu_item :main :Solitaire :nickel_extras :solitaire</span>
<span class="c">#menu_item :main :WordScramble :nickel_extras :word_scramble</span>
<span class="c">#menu_item :main :Dump Syslog :cmd_spawn :logread > /mnt/onboard/.adds/syslog.log</span>
menu_item :main :USB connect :nickel_misc :force_usb_connection
menu_item :main :IP Address :cmd_output :500:/sbin/ifconfig | /usr/bin/awk <span class="s1">'/inet addr/{print substr($2,6)}'</span>
menu_item :main :Telnet :cmd_output :500:quiet :/usr/bin/pkill -f <span class="s2">"^/usr/bin/tcpsvd -E 0.0.0.0 2023"</span>
chain_success:skip:5
chain_failure :cmd_spawn :quiet :/bin/mount -t devpts | /bin/grep -q /dev/pts <span class="o">||</span> <span class="o">{</span> /bin/mkdir -p /dev/pts <span class="o">&&</span> /bin/mount -t devpts devpts /dev/pts; <span class="o">}</span>
chain_success :cmd_spawn :quiet :exec /usr/bin/tcpsvd -E 0.0.0.0 2023 /usr/sbin/telnetd -i -l /bin/login
chain_success :dbg_toast :Started Telnet server on port 2023
chain_failure :dbg_toast :Error starting Telnet server on port 2023
chain_always:skip:-1
chain_success :dbg_toast :Stopped Telnet server on port 2023
menu_item :main :FTP :cmd_spawn :quiet:/usr/bin/pkill -f <span class="s2">"^/usr/bin/tcpsvd -E 0.0.0.0 1021"</span> <span class="o">||</span> <span class="nb">true</span> <span class="o">&&</span> <span class="nb">exec</span> /usr/bin/tcpsvd -E 0.0.0.0 1021 /usr/sbin/ftpd -w -t 30 /mnt/onboard
chain_success :dbg_toast :Started FTP server on port 1021.
menu_item :main :Sleep :power :sleep
<span class="c">#menu_item :main :Reboot :power :reboot</span>
menu_item :main :Power Off :power :shutdown
menu_item :library :Import books :nickel_misc :rescan_books_full
menu_item :browser :Quit :nickel_misc :home
menu_item :browser :Open modal :nickel_browser :modal
menu_item :browser :Invert Screen :nickel_orientation :invert
menu_item :selection_search :WebSearch :nickel_browser :modal:https://duckduckgo.com/?q<span class="o">={</span>1|S|%<span class="o">}</span>
</pre></td></tr></tbody></table>
</div>
<p>Notes:
- FTP: user = <code>root</code>, pass = <em>empty</em>
- Telnet: pass = <em>none</em></p>
<h1>KOReader / alternative reader, swiss knife</h1>
<p>See the
<a href="http://koreader.rocks/koreader-user-guide.pdf">user guide</a> and
<a href="https://github.com/koreader/koreader/wiki">wiki</a>, then follow
<a href="https://github.com/koreader/koreader/wiki/Installation-on-Kobo-devices#alternative-manual-installation-method-based-on-nickelmenu">install instructions</a>:</p>
<ol>
<li>Download the latest release from <a href="https://github.com/koreader/koreader">github</a></li>
<li>Connect Kobo to your PC</li>
<li>unzip -d /path/to/KOBOeReader/.adds/ koreader-kobo-v2023.04.zip</li>
<li><p>prevent Kobo from scanning hidden folders on 4.17+, append in <code>.kobo/Kobo/Kobo eReader.conf</code>:</p>
<div class="hll ini"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre><span class="nn">[FeatureSettings]</span>
<span class="py">ExcludeSyncFolders</span><span class="p">=</span><span class="s">(</span><span class="se">\\</span><span class="s">.(?!kobo|adobe).+|([^.][^/]*/)+</span><span class="se">\\</span><span class="s">..+)</span>
</pre></td></tr></tbody></table>
</div></li>
<li><p>add entry in NickelMenu, put in <code>.adds/nm/config</code>:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre>menu_item :main :KOReader :cmd_spawn :quiet :exec /mnt/onboard/.adds/koreader/koreader.sh
</pre></td></tr></tbody></table>
</div></li>
<li><p>Eject your eReader and enjoy</p></li>
</ol>
<p>From the user guide a command to <strong>optimize images</strong> for the ereader with ImageMagick:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6</pre></td><td class="code"><pre>convert input-image.ext <span class="se">\</span>
-colorspace Lab -filter LanczosSharp -distort Resize 1404x1872 <span class="se">\</span>
-colorspace sRGB -background white -gravity center -extent 1404x1872! <span class="se">\</span>
-grayscale Rec709Luminance -colorspace sRGB <span class="se">\</span>
-dither FloydSteinberg -remap _eink_cmap.gif <span class="se">\</span>
-quality 75 output-image.ext
</pre></td></tr></tbody></table>
</div>
<p><code>_eink_cmap.gif</code> is also attached to this post.</p>
<h1>Plato / alternative reader</h1>
<p>See the
<a href="https://www.mobileread.com/forums/showthread.php?t=292914">forum thread</a>
and <a href="https://www.mobileread.com/forums/showpost.php?p=4189882&postcount=818">NickelMenu entry</a>:</p>
<ol>
<li>Download the latest release from <a href="https://github.com/baskerville/plato">github</a></li>
<li>Connect Kobo to your PC</li>
<li>mkdir /path/to/KOBOeReader/.add/plato</li>
<li>unzip -d /path/to/KOBOeReader/.adds/plato/ plato-0.9.36.7z</li>
<li>prevent Kobo from scanning hidden folders on 4.17+, see KOReader instruction above</li>
<li><p>add entry in NickelMenu, put in <code>.adds/nm/config</code>:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre>menu_item :main :Plato :cmd_spawn :quiet :/mnt/onboard/.adds/plato/plato.sh
</pre></td></tr></tbody></table>
</div></li>
<li><p>Eject your eReader and enjoy</p></li>
</ol>
<h1>Misc tools</h1>
<ul>
<li><a href="https://pgaskin.net/kepubify/">kepubify</a> -- EPUB to KEPUB converter written in Go (standalone executable)</li>
</ul>
<h1>QOL settings</h1>
<ul>
<li><p><a href="https://wiki.mobileread.com/wiki/Kobo_Configuration_Options">full reference</a></p></li>
<li><p><a href="https://ebooks.stackexchange.com/questions/7162/is-it-possible-to-take-a-screenshot-from-a-kobo-ereader-device#7166">enable screenshots</a> by pressing power button (saves a PNG in kobo root dir), append in <code>.kobo/Kobo/Kobo eReader.conf</code>:</p>
<div class="hll ini"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre><span class="nn">[FeatureSettings]</span>
<span class="py">Screenshots</span><span class="p">=</span><span class="s">true</span>
</pre></td></tr></tbody></table>
</div></li>
<li><p>auto accept the <q>Computer detected</q> popup when plugged into a computer and enable <q>devmodeon</q>:</p>
<div class="hll ini"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3</pre></td><td class="code"><pre><span class="nn">[DeveloperSettings]</span>
<span class="py">AutoUsbGadget</span><span class="p">=</span><span class="s">true</span>
<span class="py">EnableDebugServices</span><span class="p">=</span><span class="s">true</span>
</pre></td></tr></tbody></table>
</div></li>
<li><p><a href="https://www.mobileread.com/forums/showthread.php?p=3868795">random screensaver</a> (sleep/poweroff):</p>
<ol>
<li>put images in <code>.kobo/screensaver</code></li>
<li>Settings > Energy saving and privacy > check <q>Show current read</q> and <q>Show book covers full screen</q></li>
</ol></li>
<li><p>manual reset procedure: <a href="https://help.kobo.com/hc/en-us/articles/360017765853-Manual-reset-your-Kobo-Sage-Kobo-Libra-2-Kobo-Forma-or-Kobo-Libra-H2O">Sage</a>, <a href="https://help.kobo.com/hc/en-us/articles/360017605274-Manual-reset-your-Kobo-Glo">Glo</a></p></li>
</ul>
</div>cloudtag:acavalin.com,2005:Blog::Post/1162017-08-16T14:53:28+02:002023-12-15T12:49:48+01:00/p/raspberrypi_serverRaspberryPi server2023-12-15T12:49:48ZTags: DLNA, Firewall, HowTo, Linux, Monitoring, Multimedia, RaspberryPi, Tools<hr/><div class="md2html codehilite"><h3>Table of contents:</h3>
<ol>
<li><a href="#sys_update">Update raspbian linux to latest version</a></li>
<li><a href="#pi_pass">Change password, hostname, full xdm greeter</a></li>
<li><a href="#static_ip">Configure a static IP address</a></li>
<li><a href="#bootparams">Tune kernel settings</a></li>
<li><a href="#videosett">Tune video settings</a></li>
<li><a href="#audiosett">Tune audio settings</a></li>
<li><a href="#wifi">Tune wifi settings</a></li>
<li><a href="#eth">Tune eth settings</a></li>
<li><a href="#overscan">Remove tv black borders</a></li>
<li><a href="#slow_mouse">Fix slow usb mouse</a></li>
<li><a href="#low_power">Reduce power consumption</a></li>
<li><a href="#oclock">Overclock</a></li>
<li><a href="#life_hdd">Extend lifespan of mechanical HDD</a></li>
<li><a href="#life_sd">Extend lifespan of sdcard</a></li>
<li><a href="#zram">Extend your RAM by enabling ZRAM</a></li>
<li><a href="#nfs">Setup a NAS (via NFS)</a></li>
<li><a href="#vnc">Setup a remote desktop (via VNC)</a></li>
<li><a href="#printer">Setup a shared printer</a></li>
<li><a href="#firewall">Setup the firewall</a></li>
<li><a href="#ssh_tunnels">SSH access and tunnels</a></li>
<li><a href="#syslog">Save external syslog</a></li>
<li><a href="#bluetooth">Enable bluetooth without WiFi</a></li>
<li><a href="#ext_posts">Dedicated posts:</a>
<ul>
<li><a href="/p/shared_bashrc">Source a common <code>bashrc</code> for your users</a></li>
<li><a href="/p/veracrypt_volman">Setup VeraCrypt volume manager</a></li>
<li><a href="/p/deluged">Setup Deluge torrent manager</a></li>
<li><a href="/p/dlnad">Setup a DLNA media server</a></li>
<li><a href="/p/kodi_setup">Setup Kodi media center</a></li>
<li><a href="/p/saned">Setup a shared scanner</a></li>
<li><a href="/p/nut_ups">Setup an UPS monitor</a></li>
<li><a href="/p/dnsmasqd">Setup dnsmasq DNS server</a></li>
<li><a href="/p/freedns">Setup a freeDNS account</a></li>
<li><a href="/p/webdavd">Setup a WebDav fileserver</a></li>
<li><a href="/p/fail2ban">Setup fail2ban to protect services</a></li>
<li><a href="/p/vpn_setup">Setup a VPN to protect your privacy</a></li>
<li><a href="/p/munind">Setup monitoring with Munin</a></li>
<li><a href="/p/gnu_screen">Setup a good Screen config</a></li>
<li><a href="/p/retropie_setup">Setup RetroPie</a></li>
</ul></li>
<li><a href="#tools">Tools</a></li>
<li><a href="#backup">Backup</a></li>
<li><a href="#misc">Miscellanea</a></li>
</ol>
<hr>
<p><a name="sys_update"></a></p>
<h3>Update raspbian linux to latest version:</h3>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14</pre></td><td class="code"><pre>apt-get update
apt-get upgrade
apt-get dist-upgrade
apt-get clean
apt-get autoremove
rpi-update <span class="c"># update firmware & kernel</span>
apt-get purge bash-completion <span class="c"># speed up shell TAB-auto completion</span>
<span class="c"># --- os version update, eg: from jessie (deb8) to stretch (deb9)</span>
sed -i <span class="s1">'s/jessie/stretch/g'</span> /etc/apt/sources.list
sed -i <span class="s1">'s/jessie/stretch/g'</span> /etc/apt/sources.list.d/raspi.list
<span class="c"># repeat the commands above, then check the current version:</span>
cat /etc/os-release
</pre></td></tr></tbody></table>
</div>
<p><mark>Debian 10 upgrade</mark>: see <a href="https://www.raspberrypi.org/blog/buster-the-new-version-of-raspbian/?fbclid=IwAR2WnQOS87ULViDUJdhbjfriVHW_BMkE4Cm_C3wk3OaBs_AoCiwb82f3GP0">rpi blog post</a> notes and comments.</p>
<p><br><hr><br></p>
<p><a name="pi_pass"></a></p>
<h3>Change password, hostname, full xdm greeter:</h3>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4</pre></td><td class="code"><pre>sudo raspi-config <span class="c"># Change User Password; Hostname</span>
<span class="c"># choose lightdm-gtk-greeter</span>
sudo update-alternatives --config lightdm-greeter
</pre></td></tr></tbody></table>
</div>
<p><br><hr><br></p>
<p><a name="static_ip"></a></p>
<h3>Configure a <a href="http://sizious.com/2015/08/28/setting-a-static-ip-on-raspberry-pi-on-raspbian-20150505/">static IP address</a> (see also <a href="https://raspberrypi.stackexchange.com/questions/37920/how-do-i-set-up-networking-wifi-static-ip-address">this</a> and <a href="https://www.raspberrypi.org/forums/viewtopic.php?t=140252">fallback method</a>):</h3>
<p>append the desired following blocks to <code>/etc/dhcpcd.conf</code>:</p>
<div class="hll conf"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13</pre></td><td class="code"><pre><span class="n">interface</span> <span class="n">eth0</span>
<span class="n">fallback</span> <span class="n">mylan</span>
<span class="n">SSID</span> <span class="n">my_wifi_ssid</span>
<span class="n">fallback</span> <span class="n">mylan</span>
<span class="n">interface</span> <span class="n">wlan0</span>
<span class="n">fallback</span> <span class="n">mylan</span>
<span class="n">profile</span> <span class="n">mylan</span>
<span class="n">static</span> <span class="n">ip_address</span>=<span class="m">192</span>.<span class="m">168</span>.<span class="m">1</span>.<span class="m">110</span>/<span class="m">24</span>
<span class="n">static</span> <span class="n">routers</span>=<span class="m">192</span>.<span class="m">168</span>.<span class="m">1</span>.<span class="m">1</span>
<span class="n">static</span> <span class="n">domain_name_servers</span>=<span class="m">84</span>.<span class="m">200</span>.<span class="m">69</span>.<span class="m">80</span> <span class="m">37</span>.<span class="m">235</span>.<span class="m">1</span>.<span class="m">174</span> <span class="m">84</span>.<span class="m">200</span>.<span class="m">70</span>.<span class="m">40</span> <span class="m">37</span>.<span class="m">235</span>.<span class="m">1</span>.<span class="m">177</span>
</pre></td></tr></tbody></table>
</div>
<p><mark>Note</mark>: Do <em>not</em> use the directive <code>inform 192.168.1.110</code> because it <a href="https://www.raspberrypi.org/forums/viewtopic.php?p=866076#p866076">breaks the UPS monitor</a>.</p>
<p><mark>Optional</mark> do not wait for network at boot: run <code>raspi-config</code> and select <em>Boot</em> > <em>Wait for Network at Boot</em> > <em>No</em>.</p>
<p><br><hr><br></p>
<p><a name="bootparams"></a></p>
<h3>Tune kernel settings</h3>
<ul>
<li><a href="https://github.com/raspberrypi/firmware/issues/1795">disable 64 bit kernel image</a>, put in <code>/boot/config.txt</code>:</li>
</ul>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre><span class="nv">arm_64bit</span><span class="o">=</span>0
</pre></td></tr></tbody></table>
</div>
<ul>
<li>Disable IPv6: append <code>ipv6.disable=1</code> to kernel parameters in <code>/boot/cmdline.txt</code> or:</li>
</ul>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4</pre></td><td class="code"><pre><span class="c"># via sysctl:</span>
<span class="nb">echo</span> <span class="s2">"net.ipv6.conf.all.disable_ipv6 = 1"</span> >> /etc/sysctl.d/local.conf
<span class="c"># via modprobe:</span>
<span class="nb">echo</span> <span class="s2">"blacklist ipv6"</span> >> /etc/modprobe.d/local.conf
</pre></td></tr></tbody></table>
</div>
<ul>
<li>Set autoreboot on kernel panic: append <code>panic=5</code> to kernel parameters in <code>/boot/cmdline.txt</code> or via <code>sysctl</code>:</li>
</ul>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre><span class="nb">echo</span> <span class="s2">"kernel.panic = 5"</span> >> /etc/sysctl.d/local.conf
</pre></td></tr></tbody></table>
</div>
<ul>
<li><p>use <code>eth0</code> as first ethernet device name (<a href="https://wiki.debian.org/NetworkInterfaceNames#CUSTOM_SCHEMES_USING_.LINK_FILES">wiki</a>)</p>
<ul>
<li>raspi-config > Advanced Options > Network Interface Names > disable predictable network i/f names</li>
<li>append <code>net.ifnames=0</code> to <code>/boot/cmdline.txt</code></li>
</ul></li>
<li><p>better/visible boot messages: append <code>consoleblank=0 plymouth.enable=0</code> to kernel parameters in <code>/boot/cmdline.txt</code></p></li>
<li><p>Remove tv black borders: set <code>disable_overscan=1</code> in the <code>/boot/config.txt</code>.</p></li>
<li><p>Fix slow usb mouse: append <code>usbhid.mousepoll=0</code> to kernel parameters in <code>/boot/cmdline.txt</code>.</p></li>
</ul>
<p><br><hr><br></p>
<p><a name="videosett"></a></p>
<h3>Tune video settings</h3>
<p>Run <code>raspi-config</code> and in the <code>Advanced Options</code> section, if using a raspberry
pi 4 then enable both the <em>GL driver</em> and the <em>Compositor</em> otherwise turn them off.</p>
<ul>
<li><p><mark>Note:</mark> to ensure the loading of Pi4's VC4/GL driver make sure to uninstall Xorg frame buffer drivers:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre>apt install xserver-xorg-video-vesa
apt purge xserver-xorg-video-fbdev xserver-xorg-video-fbturbo
</pre></td></tr></tbody></table>
</div></li>
<li><p>Fix <a href="https://www.raspberrypi.org/forums/viewtopic.php?p=328079&sid=150eb9bd0d87fcb5c3287d063b8b3a4d#p328079">HDMI no signal</a></p></li>
</ul>
<div class="hll plaintext"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3</pre></td><td class="code"><pre># /boot/config.txt
hdmi_force_hotplug=1
config_hdmi_boost=6
</pre></td></tr></tbody></table>
</div>
<ul>
<li><p>Fix Pi4's <a href="https://retropie.org.uk/forum/topic/24436/drm_ioctl_mode_create_dumb-failed-cannot-allocate-memory/8">DRM mem error</a>:<a name="pi4drm-err"></a></p>
<div class="hll plaintext"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre>DRM_IOCTL_MODE_CREATE_DUMB failed: Cannot allocate memory
</pre></td></tr></tbody></table>
</div>
<p>If you see the above error then use these <code>/boot/config.txt</code> settings:</p>
<div class="hll ini"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15</pre></td><td class="code"><pre><span class="c"># force HD, and prevent 4K memory drain (optional)
</span><span class="py">hdmi_group</span><span class="p">=</span><span class="s">1</span>
<span class="py">hdmi_mode</span><span class="p">=</span><span class="s">16</span>
<span class="nn">[hdmi:0]</span>
<span class="py">hdmi_max_pixel_freq</span><span class="p">=</span><span class="s">200000000</span>
<span class="nn">[hdmi:1]</span>
<span class="py">hdmi_max_pixel_freq</span><span class="p">=</span><span class="s">200000000</span>
<span class="nn">[pi4]</span>
<span class="c"># Enable DRM VC4 V3D driver on top of the dispmanx display stack (default driver)
</span><span class="py">dtoverlay</span><span class="p">=</span><span class="s">vc4-fkms-v3d</span>
<span class="c"># number of active displays 1-2
</span><span class="py">max_framebuffers</span><span class="p">=</span><span class="s">1</span>
<span class="c"># disable any memory split
#gpu_mem=256
</span></pre></td></tr></tbody></table>
</div>
<p>and append <code>cma=384M</code> to <code>/boot/cmdline.txt</code>.</p></li>
</ul>
<p><br><hr><br></p>
<p><a name="audiosett"></a></p>
<h3>Tune audio settings</h3>
<ul>
<li>fix <a href="https://www.raspberrypi.org/forums/viewtopic.php?f=131&t=269833&start=50#p1660207">robotic/metallic audio</a></li>
</ul>
<div class="hll conf"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre><span class="c"># add tsched=0 in /etc/pulse/default.pa on this line:
</span><span class="n">load</span>-<span class="n">module</span> <span class="n">module</span>-<span class="n">udev</span>-<span class="n">detect</span> <span class="n">tsched</span>=<span class="m">0</span>
</pre></td></tr></tbody></table>
</div>
<ul>
<li>disable microphone auto adjust (<a href="https://nzeid.net/pulseaudio-disable-auto-volume">src1</a>, <a href="https://askubuntu.com/questions/279407/how-to-disable-microphone-from-auto-adjusting-its-input-volume/736655#736655">src2</a>, <a href="https://askubuntu.com/questions/689209/how-to-disable-microphone-volume-auto-adjustment-in-cisco-webex/761103#761103">src3</a>):</li>
</ul>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4</pre></td><td class="code"><pre><span class="nb">cd</span> /usr/share/pulseaudio/alsa-mixer/paths
tar -czvf ../paths.tgz . <span class="c"># backup</span>
perl -pi -0 -e <span class="s1">'s/(\[[A-Za-z ]*(Mic Boost|Capture)\][A-Za-z._=\s-]+volume *= *)merge/\1zero/g;'</span> <span class="k">*</span>mic<span class="k">*</span>.conf
shutdown -r 0
</pre></td></tr></tbody></table>
</div>
<ul>
<li>to have a much better audio quality you can buy an usb soundcard (eg. <a href="https://www.amazon.it/gp/product/B0819R4NXH">PCM2704 DAC</a>)</li>
</ul>
<div class="hll conf"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6</pre></td><td class="code"><pre><span class="c"># /etc/modprobe.d/local-audio.conf
</span>
<span class="c"># https://alsa.opensrc.org/MultipleCards#Reordering_the_driver_for_a_particular_card
</span><span class="n">options</span> <span class="n">snd_bcm2835</span> <span class="n">index</span>=<span class="m">0</span>
<span class="c"># get vendor and product IDs via "lsusb" (my PCM2704 has 08bb:27c4)
</span><span class="n">options</span> <span class="n">snd</span>-<span class="n">usb</span>-<span class="n">audio</span> <span class="n">index</span>=<span class="m">2</span>,<span class="m">3</span>,<span class="m">4</span> <span class="n">vid</span>=<span class="m">0</span><span class="n">x08bb</span>,<span class="m">0</span><span class="n">x1395</span>,<span class="m">0</span><span class="n">x046d</span> <span class="n">pid</span>=<span class="m">0</span><span class="n">x27c4</span>,<span class="m">0</span><span class="n">x0025</span>,<span class="m">0</span><span class="n">x0836</span>
</pre></td></tr></tbody></table>
</div>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5</pre></td><td class="code"><pre><span class="c"># set default card in pulseaudio (taken from raspi-config script)</span>
pulseaudio --check <span class="o">||</span> pulseaudio -D
<span class="nb">export </span><span class="nv">XDG_RUNTIME_DIR</span><span class="o">=</span>/run/user/<span class="sb">`</span>id -g<span class="sb">`</span>
pacmd list-sinks | grep -e index -e alsa.name <span class="c"># identify your card number</span>
pactl <span class="nb">set</span>-default-sink 3
</pre></td></tr></tbody></table>
</div>
<p><br><hr><br></p>
<p><a name="wifi"></a></p>
<h3>Tune wifi settings</h3>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14</pre></td><td class="code"><pre><span class="c"># disable roaming</span>
<span class="nb">echo</span> <span class="s2">"options brcmfmac roamoff=1"</span> >> /etc/modprobe.d/local.conf
<span class="c"># set correct regional domain</span>
sed -i <span class="s1">'s/REGDOMAIN=.*/REGDOMAIN=IT/'</span> /etc/default/crda
<span class="c"># auto turn off power management</span>
<span class="nb">cd</span> /etc/network/if-up.d/
<span class="nb">echo</span> -e <span class="s1">'#!/bin/bash\n/sbin/iw dev wlan0 set power_save off'</span> > <span class="nb">local</span>-wlan
chmod 755 <span class="nb">local</span>-wlan
<span class="c"># find an optimal MTU size via:</span>
<span class="c"># ping -c 2 -M do -s 1600 www.google.com</span>
<span class="c"># then save it with:</span>
<span class="nb">echo</span> <span class="s2">"/sbin/ip link set dev wlan0 mtu 1400"</span> >> <span class="nb">local</span>-wlan
</pre></td></tr></tbody></table>
</div>
<p>Turn off bluetooth if unused, see <a href="#low_power">this section</a>.</p>
<p><br><hr><br></p>
<p><a name="eth"></a></p>
<h3>Tune eth settings</h3>
<ul>
<li><p><a href="https://github.com/raspberrypi/Raspberry-Pi-OS-64bit/issues/178#issuecomment-1386871175">Disable eee</a>
<q>Energy Efficient Ethernet</q> support</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre><span class="nb">echo</span> <span class="s2">"dtparam=eee=off"</span> >> /boot/config.txt
</pre></td></tr></tbody></table>
</div></li>
<li><p><a href="https://raspberrypi.stackexchange.com/questions/116677/force-wired-ethernet-speed-to-100-full/140550#140550">Force eth0 speed</a>
to 100Mbs full duplex:</p></li>
</ul>
<ol>
<li><p>create a <q>device tree file</q> <code>cm4-disable-gigabit-ethernet.dts</code>:</p>
<div class="hll plaintext"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12</pre></td><td class="code"><pre> /dts-v1/;
/plugin/;
/ {
/* Change the phy max-speed to 100 Mbps */
fragment@0 {
target = <&phy1>;
__overlay__ {
max-speed = <100>;
};
};
};
</pre></td></tr></tbody></table>
</div></li>
<li><p>compile and install:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre> sudo dtc -@ -Hepapr -I dts -O dtb -o /boot/overlays/cm4-disable-gigabit-ethernet.dtbo cm4-disable-gigabit-ethernet.dts
<span class="nb">echo</span> <span class="s2">"dtoverlay=cm4-disable-gigabit-ethernet"</span> >> /boot/config.txt
</pre></td></tr></tbody></table>
</div></li>
</ol>
<p><br><hr><br></p>
<p><a name="low_power"></a></p>
<h3>Reduce <a href="https://www.jeffgeerling.com/blogs/jeff-geerling/raspberry-pi-zero-conserve-energy">power consumption</a>:</h3>
<p>turn off leds (<a href="https://raspberrypi.stackexchange.com/questions/112134/raspberry-pi-4-turn-red-led-off-via-software/112136#112136">RPIex</a>, <a href="https://forums.raspberrypi.com/viewtopic.php?p=1725261&sid=d9e96aff2dbbbad00b57812b443e6446#p1725261">forum</a>, <a href="https://lindevs.com/turn-off-built-in-leds-on-raspberry-pi">lindevs</a>) by putting in <code>/boot/config.txt</code> under the <code>[pi4]</code> tag:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12</pre></td><td class="code"><pre><span class="o">[</span>pi4]
<span class="c"># Disable the PWR LED</span>
<span class="nv">dtparam</span><span class="o">=</span><span class="nv">pwr_led_trigger</span><span class="o">=</span>default-on
<span class="nv">dtparam</span><span class="o">=</span><span class="nv">pwr_led_activelow</span><span class="o">=</span>off
<span class="c"># Disable the Activity LED</span>
<span class="nv">dtparam</span><span class="o">=</span><span class="nv">act_led_trigger</span><span class="o">=</span>none
<span class="nv">dtparam</span><span class="o">=</span><span class="nv">act_led_activelow</span><span class="o">=</span>off
<span class="c"># Disable ethernet port LEDs (0=ACT, 1=LNK)</span>
<span class="nv">dtparam</span><span class="o">=</span><span class="nv">eth_led0</span><span class="o">=</span>4
<span class="nv">dtparam</span><span class="o">=</span><span class="nv">eth_led1</span><span class="o">=</span>4
</pre></td></tr></tbody></table>
</div>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre><span class="c"># disable HDMI output (and set boot to console via raspi-config)</span>
/usr/bin/tvservice -o <span class="c"># -p to re-enable</span>
</pre></td></tr></tbody></table>
</div>
<p>set boot to console and reduce memory split:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre>raspi-config <span class="c"># Boot Options > Desktop / CLI > Console</span>
raspi-config <span class="c"># Advanced Options > Memory Split > 16</span>
</pre></td></tr></tbody></table>
</div>
<p>turn off unsued wlan/bluetooth (see <code>/boot/overlays/README</code>), put in <code>/boot/config.txt</code>:</p>
<div class="hll plaintext"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre>dtoverlay=disable-wifi
dtoverlay=disable-bt
</pre></td></tr></tbody></table>
</div>
<p>and turn off the bluetooth services:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre>systemctl disable hciuart
systemctl disable bluetooth
</pre></td></tr></tbody></table>
</div>
<p><br><hr><br></p>
<p><a name="oclock"></a></p>
<h3><a href="https://retropie.org.uk/forum/topic/27430/howto-optimized-boot-config-txt">Overclock</a> RPI4:</h3>
<p>Add these lines in <code>/boot/config.txt</code>:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4</pre></td><td class="code"><pre><span class="nv">arm_freq</span><span class="o">=</span>2048
<span class="nv">v3d_freq</span><span class="o">=</span>750
<span class="nv">over_voltage</span><span class="o">=</span>6
<span class="nv">hdmi_enable_4kp60</span><span class="o">=</span>1
</pre></td></tr></tbody></table>
</div>
<p>optionally set <code>performance</code> cpu governor:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre><span class="c"># /etc/rc.local</span>
<span class="nb">echo </span>performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
</pre></td></tr></tbody></table>
</div>
<p><br><hr><br></p>
<p><a name="life_hdd"></a></p>
<h3><a href="https://www.htpcguides.com/spin-down-and-manage-hard-drive-power-on-raspberry-pi/">Extend lifespan</a> of mechanical HDD:</h3>
<p>put in <code>/etc/hdparm.conf</code>:</p>
<div class="hll conf"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7</pre></td><td class="code"><pre>/<span class="n">dev</span>/<span class="n">sda</span> {
<span class="n">write_cache</span> = <span class="n">on</span>
<span class="c"># -B -- disable Advanced Power Management
</span> <span class="n">apm</span> = <span class="m">254</span>
<span class="c"># -S -- 1h timeout
</span> <span class="n">spindown_time</span> = <span class="m">242</span>
}
</pre></td></tr></tbody></table>
</div>
<p><br><hr><br></p>
<p><a name="life_sd"></a></p>
<h3>Extend lifespan of sdcard:</h3>
<p>install my <a href="https://github.com/acavalin/systemd-units">tmpfs-folders script</a> and add a custom periodic cleaning of <code>/var/log</code> files in root <code>crontab</code>:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre><span class="c"># m h dom mon dow command</span>
0 0 <span class="k">*</span> <span class="k">*</span> 3 /opt/systemd-units/clear_var_log.sh > /dev/null 2> /dev/null
</pre></td></tr></tbody></table>
</div>
<p><br><hr><br></p>
<p><a name="zram"></a></p>
<h3>Extend your RAM by enabling <a href="https://www.kernel.org/doc/Documentation/blockdev/zram.txt">ZRAM</a> (compressed RAM):</h3>
<p>put in <code>/etc/rc.local</code>:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10</pre></td><td class="code"><pre><span class="k">if </span>modprobe zram <span class="nv">num_devices</span><span class="o">=</span>1 ; <span class="k">then
</span><span class="nb">echo </span>lz4 > /sys/block/zram0/comp_algorithm
<span class="nb">echo </span>384M > /sys/block/zram0/mem_limit
<span class="nb">echo </span>768M > /sys/block/zram0/disksize
mkswap /dev/zram0
swapon -p 10 /dev/zram0
sysctl vm.swappiness<span class="o">=</span>90
<span class="k">fi</span>
</pre></td></tr></tbody></table>
</div>
<p>and optionally disable <code>dphys-swapfile</code> swapfile service:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre>systemctl disable dphys-swapfile
</pre></td></tr></tbody></table>
</div>
<p><br><hr><br></p>
<p><a name="nfs"></a></p>
<h3>Setup a NAS (via NFS):</h3>
<p>Server side commands:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9</pre></td><td class="code"><pre>apt-get install nfs-kernel-server
systemctl <span class="nb">enable </span>rpcbind <span class="c"># it's disabled by default...</span>
systemctl restart nfs-kernel-server
<span class="c"># add a share to /etc/exports</span>
<span class="nb">echo</span> <span class="s2">"/path 192.168.1.0/24(rw,sync,no_subtree_check,all_squash,anonuid=1001,anongid=1001)"</span> >> /etc/exports
exportfs -ra <span class="c"># reload server</span>
</pre></td></tr></tbody></table>
</div>
<p>and append these lines to <code>/ect/rc.local</code>:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3</pre></td><td class="code"><pre><span class="c"># fix: nfs server doesn't start without rpcbind</span>
systemctl start rpcbind
systemctl restart nfs-kernel-server
</pre></td></tr></tbody></table>
</div>
<p>Client side commands:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre><span class="nb">echo</span> <span class="s2">"192.168.1.110:/path /mnt/path nfs defaults,user,exec 0 0"</span> >> /etc/fstab
mount /mnt/path
</pre></td></tr></tbody></table>
</div>
<p><br><hr><br></p>
<p><a name="vnc"></a></p>
<h3>Setup a remote desktop (via VNC):</h3>
<p>You have three options:</p>
<ol>
<li>Install the modern TigerVNC server, see the <a href="/p/vnc_remote">dedicated post</a></li>
<li>Use the lightdm TigerVNC service by enabling it in <code>/etc/lightdm/lightdm.conf</code></li>
<li><p>Install the old TightVNC:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5</pre></td><td class="code"><pre>apt-get install tightvncserver
<span class="c"># set a password and run a LQ server on display 1:</span>
vncpasswd
vncserver -geometry 1024x768 -depth 8 :1
vncviewer server_ip:1 <span class="c"># connect from another host</span>
</pre></td></tr></tbody></table>
</div></li>
</ol>
<p><br><hr><br></p>
<p><a name="printer"></a></p>
<h3>Setup a <a href="https://wiki.debian.org/SystemPrinting">shared printer</a>:</h3>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7</pre></td><td class="code"><pre>apt-get install cups
apt-get install hplip <span class="c"># HP printers drivers</span>
hp-setup -i <span class="c"># install printer + dl drivers</span>
elinks http://localhost:631
<span class="c"># Administration > Printers > Add printer</span>
<span class="c"># Server settings > Share printers connected to this system</span>
</pre></td></tr></tbody></table>
</div>
<p>then turn the printer off and on again.</p>
<p>On Android you can install these apps: <a href="https://play.google.com/store/apps/details?id=com.blackspruce.lpd&hl=it">Let's print Droid</a>, and <a href="https://play.google.com/store/apps/details?id=com.blackspruce.mupdf&hl=it">Let's Print PDF</a>.</p>
<p><br><hr><br></p>
<p><a name="firewall"></a></p>
<h3>Setup the <a href="/p/ufw_firewall_setup">firewall</a>:</h3>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18</pre></td><td class="code"><pre>apt-get install ufw
ufw reset <span class="c"># reset to defaults</span>
ufw default deny incoming
ufw default allow outgoing
ufw allow from 192.168.1.0/24 <span class="c"># your intranet</span>
ufw allow from x.x.x.x <span class="c"># a trusted IP</span>
ufw limit 22/tcp <span class="c"># max 6 new connections every 30 seconds</span>
ufw limit 2200:2230/udp <span class="c"># mosh port range</span>
ufw allow 1810:1820/tcp <span class="c"># bittorent - data</span>
ufw allow 1810:1820/udp
ufw allow 6881:6891/tcp <span class="c"># bittorent - tracker</span>
ufw allow 6881:6891/udp
ufw allow 6771/udp <span class="c"># bittorent - local peer discovery</span>
ufw <span class="nb">enable</span>
</pre></td></tr></tbody></table>
</div>
<p><br><hr><br></p>
<p><a name="ssh_tunnels"></a></p>
<h3>SSH access and tunnels:</h3>
<p>Here is an example for creating some simple forward tunnels while connecting to a remote server:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7</pre></td><td class="code"><pre><span class="c"># deluge thin client & web ui, vnc, nginx</span>
ssh <span class="se">\</span>
-L 58846:localhost:58846 <span class="se">\</span>
-L 8112:localhost:8112 <span class="se">\</span>
-L 5901:localhost:5901 <span class="se">\</span>
-L 1234:localhost:1234 <span class="se">\</span>
user@server_addr
</pre></td></tr></tbody></table>
</div>
<p>There are some great SSH clients as <a href="http://www.putty.org/">PuTTY</a> for windows/linux and <a href="https://juicessh.com/">juiceSSH</a> on Android.</p>
<p>Use <a href="https://mosh.org"><code>mosh</code></a> (<a href="http://sonelli.freshdesk.com/support/solutions/articles/173671-how-can-i-change-the-mosh-port-number-">even with juiceSSH!</a>) to reliably connect from <em>unstable or high latency</em> networks:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre>apt-get install mosh <span class="c"># run this both on client and server</span>
mosh -p 2200:2230 user@server_addr <span class="c"># connect to opened UDP ports on server</span>
</pre></td></tr></tbody></table>
</div>
<p>Read the <a href="/p/ssh_tunnels">dedicated post</a> for an advanced tunnel usage.</p>
<p>Read the <a href="/p/ssh_socks5_proxy">dedicated post</a> to setup a SOCKS proxy with SSH.</p>
<p><mark>Note:</mark> if sshd is slow to start at boot (<code>systemd-analyze blame</code>) then install <code>haveged</code> to have <a href="https://bbs.archlinux.org/viewtopic.php?pid=1816853#p1816853">more entropy</a>. Also apply <a href="https://github.com/MichaIng/DietPi/issues/4710#issuecomment-914167649">this patch</a> if it's killed by systemd on debian bullseye:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4</pre></td><td class="code"><pre>mkdir -p /etc/systemd/system/haveged.service.d
<span class="nb">echo</span> -e <span class="s1">'[Service]\nSystemCallFilter=uname'</span> > /etc/systemd/system/haveged.service.d/dietpi.conf
systemctl daemon-reload
systemctl restart haveged
</pre></td></tr></tbody></table>
</div>
<p><br><hr><br></p>
<p><a name="syslog"></a></p>
<h3>Save <a href="https://pimylifeup.com/raspberry-pi-syslog-server/">external syslog</a> via rsyslog:</h3>
<ul>
<li>enable tcp/udp ports, uncomment these lines in <code>/etc/rsyslog.conf</code></li>
</ul>
<div class="hll conf"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5</pre></td><td class="code"><pre><span class="n">module</span>(<span class="n">load</span>=<span class="s2">"imudp"</span>)
<span class="n">input</span>(<span class="n">type</span>=<span class="s2">"imudp"</span> <span class="n">port</span>=<span class="s2">"514"</span>)
<span class="n">module</span>(<span class="n">load</span>=<span class="s2">"imtcp"</span>)
<span class="n">input</span>(<span class="n">type</span>=<span class="s2">"imtcp"</span> <span class="n">port</span>=<span class="s2">"514"</span>)
</pre></td></tr></tbody></table>
</div>
<ul>
<li>filter and save remote logs by IP, create <code>/etc/rsyslog.d/router.conf</code></li>
</ul>
<div class="hll conf"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4</pre></td><td class="code"><pre>$<span class="n">template</span> <span class="n">routerlog</span>, <span class="s2">"/var/log/router.log"</span>
<span class="n">if</span> $<span class="n">fromhost</span>-<span class="n">ip</span> <span class="n">startswith</span> <span class="s2">"192.168.1.1"</span> <span class="n">then</span> -?<span class="n">routerlog</span>
& <span class="n">stop</span>
</pre></td></tr></tbody></table>
</div>
<ul>
<li>restart service</li>
</ul>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre>systemctl restart rsyslog
</pre></td></tr></tbody></table>
</div>
<ul>
<li>configure the device (eg. a router) to use your raspi IP as the remote syslog server</li>
</ul>
<p><br><hr><br></p>
<p><a name="bluetooth"></a></p>
<h3>Enable bluetooth without WiFi</h3>
<ul>
<li>disable WiFi by blacklisting its modules, add in <code>/etc/modprobe.d/local-wifi.conf</code>:</li>
</ul>
<div class="hll conf"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre><span class="n">blacklist</span> <span class="n">brcmfmac</span>
<span class="n">blacklist</span> <span class="n">brcmutil</span>
</pre></td></tr></tbody></table>
</div>
<ul>
<li>set <code>enable_uart=1</code> in <code>/boot/config.txt</code></li>
<li><a href="https://forums.raspberrypi.com/viewtopic.php?p=1835878#p1835878">ensure</a> <code>/boot/cmdline.txt</code> contains this text in this <strong>exact</strong> order:</li>
</ul>
<div class="hll plaintext"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre>console=serial0,115200 console=tty1
</pre></td></tr></tbody></table>
</div>
<ul>
<li>enable services:</li>
</ul>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre>systemctl <span class="nb">enable </span>hciuart
systemctl <span class="nb">enable </span>bluetooth
</pre></td></tr></tbody></table>
</div>
<p><br><hr><br></p>
<p><a name="ext_posts"></a></p>
<h3>Dedicated posts:</h3>
<ul>
<li><a href="/p/shared_bashrc">Source a common <code>bashrc</code> for your users</a></li>
<li><a href="/p/veracrypt_volman">Setup VeraCrypt volume manager</a></li>
<li><a href="/p/deluged">Setup Deluge torrent manager</a></li>
<li><a href="/p/dlnad">Setup a DLNA media server</a></li>
<li><a href="/p/kodi_setup">Setup Kodi media center</a></li>
<li><a href="/p/saned">Setup a shared scanner</a></li>
<li><a href="/p/nut_ups">Setup an UPS monitor</a></li>
<li><a href="/p/dnsmasqd">Setup dnsmasq DNS server</a></li>
<li><a href="/p/freedns">Setup a freeDNS account</a></li>
<li><a href="/p/webdavd">Setup a WebDav fileserver</a></li>
<li><a href="/p/fail2ban">Setup fail2ban to protect services</a></li>
<li><a href="/p/vpn_setup">Setup a VPN to protect your privacy</a></li>
<li><a href="/p/munind">Setup monitoring with Munin</a></li>
<li><a href="/p/gnu_screen">Setup a good Screen config</a></li>
<li><a href="/p/retropie_setup">Setup RetroPie</a></li>
</ul>
<p><br><hr><br></p>
<p><a name="tools"></a></p>
<h3>Tools:</h3>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3</pre></td><td class="code"><pre>apt-get install rpi-chromium-mods <span class="c"># video acceleration on google chrome</span>
apt-get install remmina <span class="c"># very handy VNC/SSH GUI</span>
apt-get install omxplayer <span class="c"># accelerated cli media player</span>
</pre></td></tr></tbody></table>
</div>
<ul>
<li><p>Fast/light web browsers:</p>
<ul>
<li><a href="https://www.raspberrypi.org/forums/viewtopic.php?t=40860">kweb</a> - raspberry pi's custom webkit build with omxplayer support</li>
<li><a href="https://vivaldi.com/download/">vivaldi</a> - opera like browser</li>
<li>midori</li>
</ul></li>
<li><p>OMXplayer <a href="https://www.raspberrypi.org/forums/viewtopic.php?t=53494">GUIs</a>:</p>
<ul>
<li><a href="https://github.com/vladcc/gomx">gomx</a> -- light Python+Tk via <a href="https://github.com/willprice/python-omxplayer-wrapper">python-omxplayer-wrapper</a></li>
</ul>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5</pre></td><td class="code"><pre>sudo apt install libdbus-1-dev libglib2.0-dev
pip install omxplayer-wrapper
wget -O ~/bin/gomx https://github.com/vladcc/gomx/raw/master/gomx/gomx.py
chmod 755 ~/bin/gomx
sed -i <span class="s1">'s/^PL_WIN_PAD = .*/PL_WIN_PAD = 0/'</span> ~/bin/gomx <span class="c"># adjust padding</span>
</pre></td></tr></tbody></table>
</div>
<ul>
<li><a href="https://github.com/KenT2/tboplayer">tboplayer</a> -- via <a href="https://github.com/jbaiter/pyomxplayer">pyomxplayer</a> + <a href="https://github.com/rg3/youtube-dl/">youtube-dl</a> + <a href="http://lyrics.wikia.com">lyrics</a></li>
</ul></li>
<li><p><a href="https://github.com/nucular/raspi-keygen">raspi-keygen</a> -- <a href="https://www.reddit.com/r/raspberry_pi/comments/5x7xbo/patch_for_mpeg2_vc1_license/">Patch for MPEG-2, VC-1 license</a> (untested, use it at your own risk)</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre><span class="nb">cd</span> /boot <span class="o">&&</span> cp start.elf start.elf_backup <span class="o">&&</span> <span class="se">\</span>
perl -pne <span class="s1">'s/\x47\xE9362H\x3C\x18/\x47\xE9362H\x3C\x1F/g'</span> < start.elf_backup > start.elf
</pre></td></tr></tbody></table>
</div></li>
<li><p><a href="https://mkvtoolnix.download/downloads.html#raspbian">latest mkvtoolnix</a> for raspbian</p></li>
</ul>
<p><br><hr><br></p>
<p><a name="backup"></a></p>
<h3>Backup:</h3>
<p>You can do a <a href="/p/bkup_restore_disks">full/raw</a> sdcard backup, a <a href="/p/linux_live_backup">live/tar</a> one, or an <a href="https://github.com/acavalin/ribs">incremental</a> one.</p>
<p>As an alternative to <code>7za</code> you can use <code>xz</code> just like the <code>gz</code> command (or use the <code>-J</code> option of <code>tar</code>).</p>
<h4>Incremental backup commands</h4>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35</pre></td><td class="code"><pre><span class="c"># --- backup ----------------------------------------</span>
<span class="nb">cd</span> /tmp <span class="o">&&</span> mkdir -p p1 p2
sudo mount -o ro /dev/sdc1 p1
sudo mount -o ro /dev/sdc2 p2
<span class="nb">cd </span>bkup-folder
sudo sfdisk -d /dev/sdc > ptable
mkdir -p p1 p2
sudo ribs -b --no-p p1 /tmp/p1
sudo ribs -b p2 /tmp/p2
sudo umount /tmp/p?
<span class="c"># --- restore ---------------------------------------</span>
<span class="nb">cd </span>bkup-folder
<span class="nb">cd</span> /tmp <span class="o">&&</span> mkdir -p p1 p2
sfdisk /dev/sdc < ptable
mkfs.vfat /dev/sdc1
mkfs.ext4 /dev/sdc2
sudo mount /dev/sdc1 p1
sudo mount /dev/sdc2 p2
sudo ribs -r p1 /tmp/p1
sudo ribs -r p2 /tmp/p2
cat ptable | grep label-id <span class="c"># view old partition ID</span>
<span class="c"># change to the new partition ID</span>
sfdisk -d /dev/sdc | grep label-id
<span class="c"># update PARTUUID in p1/cmdline.txt </span>
<span class="c"># update PARTUUID in p2/etc/fstab</span>
sudo umount /tmp/p?
</pre></td></tr></tbody></table>
</div>
<p><br><hr><br></p>
<p><a name="misc"></a></p>
<h3>Miscellanea:</h3>
<ul>
<li><p>turn TV/monitor on/off</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3</pre></td><td class="code"><pre>cec-ctl -d/dev/cec0 --playback -S <span class="c"># initialize</span>
cec-ctl -d/dev/cec0 --to 0 --standby <span class="c"># turn OFF</span>
cec-ctl -d/dev/cec0 --to 0 --image-view-on <span class="c"># turn ON</span>
</pre></td></tr></tbody></table>
</div></li>
<li><p>Fix <a href="https://kodi.wiki/view/Raspberry_Pi_FAQ#TV_is_not_detected_unless_powered_on_first">TV/monitor not detected unless powered on first</a>:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre>sudo tvservice -d /boot/edid.dat
</pre></td></tr></tbody></table>
</div>
<div class="hll conf"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3</pre></td><td class="code"><pre><span class="c"># /boot/config.txt
</span><span class="n">hdmi_edid_file</span>=<span class="m">1</span>
<span class="n">hdmi_force_hotplug</span>=<span class="m">1</span>
</pre></td></tr></tbody></table>
</div></li>
<li><p>Test if we are on a raspberry (<a href="https://raspberrypi.stackexchange.com/questions/5100/detect-that-a-python-program-is-running-on-the-pi">/sys</a>, <a href="https://www.raspberrypi.org/forums/viewtopic.php?f=32&t=54413">/proc/cpuinfo</a>):</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre>cat /sys/firmware/devicetree/base/model <span class="c"># Raspberry Pi 3 Model B Rev 1.2</span>
grep Hardware /proc/cpuinfo <span class="c"># Hardware : BCM2708</span>
</pre></td></tr></tbody></table>
</div></li>
<li><p>To save space on new installs of <em>ruby gems</em>, put in <code>~/.gemrc</code>:</p>
<div class="hll plaintext"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre>install: --no-rdoc --no-ri --no-document
update: --no-rdoc --no-ri --no-document
</pre></td></tr></tbody></table>
</div>
<p>and to install a gem in the user <code>$HOME</code> use this command:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4</pre></td><td class="code"><pre>gem install --user-install bundler
<span class="c"># remember to update your PATH adding this line to ~/.bashrc</span>
<span class="nb">export </span><span class="nv">PATH</span><span class="o">=</span><span class="nv">$HOME</span>/.gem/ruby/2.1.0/bin:<span class="nv">$PATH</span>
</pre></td></tr></tbody></table>
</div></li>
<li><p>If you have a logitech wireless keyboard (eg: K400+) then you can use <a href="https://github.com/pwr/Solaar">solaar</a> to query and configure it:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6</pre></td><td class="code"><pre>git clone https://github.com/pwr/Solaar.git
<span class="nb">cd </span>Solaar/bin
solaar show all
solaar show 1 | grep Battery
solaar config 1 fn-swap off <span class="c"># toggle function keys</span>
</pre></td></tr></tbody></table>
</div></li>
<li><p>If you have a keyboard without the <code>F#</code> keys (like the <a href="https://kano.me/">kano keybord</a>) you can emulate them with <code>xdotool</code> and then run it via <code>xbindkeys</code>:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4</pre></td><td class="code"><pre>sudo apt-get install xdotool xbindkeys xbindkeys-config
xdotool key ctrl+alt+F1 <span class="c"># emulate these key press</span>
xbindkeys-config <span class="c"># create and save your bindings</span>
xbindkeys <span class="c"># run daemon</span>
</pre></td></tr></tbody></table>
</div>
<p>or you can use <code>xmodmap</code> to remap existing keys:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3</pre></td><td class="code"><pre>xmodmap -pke | tee ~/.Xmodmap > ~/.Xmodmap-orig
nano ~/.Xmodmap <span class="c"># edit keys</span>
xmodmap ~/.Xmodmap <span class="c"># load changes (run this on X startup)</span>
</pre></td></tr></tbody></table>
</div>
<p>see <code>Xorg keyboard</code> references on the bottom.</p></li>
<li><p><a href="https://www.raspberrypi-spy.co.uk/2014/05/how-to-autostart-apps-in-rasbian-lxde-desktop/">Autostart programs when loggin in LXDE</a>: put your commands prefixed by <code>@</code> in <code>~/.config/lxsession/LXDE-pi/autostart</code></p></li>
<li><p>Change video mode/resolution without rebooting -- see <a href="https://www.raspberrypi.org/forums/viewtopic.php?t=162837">rpi forum post</a></p></li>
</ul>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15</pre></td><td class="code"><pre><span class="c"># query available video modes</span>
tvservice -m CEA
<span class="c">#Group CEA has 16 modes:</span>
<span class="c"># mode 4: 1280x720 @ 60Hz 16:9, clock:74MHz progressive </span>
<span class="c"># mode 19: 1280x720 @ 50Hz 16:9, clock:74MHz progressive </span>
<span class="c"># (prefer) mode 16: 1920x1080 @ 60Hz 16:9, clock:148MHz progressive </span>
<span class="c"># set custom video mode</span>
tvservice -e <span class="s2">"CEA 4 HDMI"</span>
<span class="c">#fbset -depth 8 ; fbset -depth 16</span>
fbset -g 1280 720 1280 720 16
xrefresh
<span class="c"># set default video mode</span>
tvservice -p
</pre></td></tr></tbody></table>
</div>
<ul>
<li><p>Android/LineageOS: <a href="https://konstakang.com/devices/rpi3/">images</a> by <a href="https://twitter.com/konstatuomio">Konsta</a>, <a href="https://www.raspberrypi.org/forums/viewtopic.php?t=247482">forum</a></p></li>
<li><p><a href="https://zoom.us">Zoom</a>: <a href="https://devforum.zoom.us/t/have-you-considered-building-zoom-for-the-raspberry-pi-4-linux-system/14257/13">arm port request</a>, <a href="https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=254367">forum</a></p></li>
<li><p><code>qpdfview</code> a PDF viewer <a href="https://www.raspberrypi.com/news/raspbian-update-june-2018/">better than <code>xpdf</code></a> (modern GUI, fast render, page preload and cache)</p></li>
</ul>
<p><br><br></p>
<hr>
<p>Notes:</p>
<ul>
<li>Raspberry Pi 3 <a href="https://www.reddit.com/r/raspberry_pi/comments/4b2enb/psa_raspberry_pi_3_provides_12a_usb_current_by/">provides 1.2A USB</a> current by <a href="https://www.raspberrypi.org/help/faqs/#powerReqs"><em>default</em></a> (no need to set <code>max_usb_current=1</code> in <code>/boot/config.txt</code>). Of course a 2.5A PSU is mandatory.</li>
</ul>
<p>Tips:</p>
<ul>
<li><a href="https://www.raspberrypi.org/products/sense-hat/">SenseHAT</a>: <a href="https://www.raspberrypi.org/blog/sense-hat-projects/">blog post</a></li>
<li><a href="https://github.com/Hemisphere-Project/HPlayer/blob/master/README.md">hplayer</a> (mplayer)</li>
<li><a href="https://github.com/libfuse/sshfs/blob/master/README.rst">SSHfs</a></li>
<li>read-only sdcard: <a href="https://learn.adafruit.com/read-only-raspberry-pi/">adafruits post</a> from <a href="https://www.raspberrypi.org/blog/adafruits-read-only/">raspi post</a></li>
</ul>
<p>Sources:</p>
<ul>
<li>power consumption: <a href="https://www.pidramble.com/wiki/benchmarks/power-consumption">pidramble</a>, <a href="http://www.jeffgeerling.com/blogs/jeff-geerling/raspberry-pi-zero-conserve-energy">jeffgeerling</a></li>
<li>ZRAM: <a href="https://www.kernel.org/doc/Documentation/blockdev/zram.txt">kernel</a>, <a href="https://gist.github.com/sultanqasim/79799883c6b81c710e36a38008dfa374">raspberry pi 3 gist</a>, <a href="http://with-raspberrypi.blogspot.it/2014/04/how-to-use-zram.html">with-raspberrypi blog</a>, <a href="https://stoned.io/linux/Using-ZRAM-Compressed-RAM-Block-Device-On-Debian-Jessie-On-Old-Hardware/">stoned.io</a></li>
<li>NFS server in Raspbian: <a href="https://www.raspberrypi.org/forums/viewtopic.php?t=191451">can't connect</a></li>
<li>Reduce SDcard wearing: <a href="https://raspberrypi.stackexchange.com/questions/62533/how-can-i-reduce-the-writing-to-log-files/62536#62536">stackexchange post</a> e <a href="http://www.tremende.com/ramlog/#install_2">ramlog pkg</a></li>
<li>Xorg keyboard: <a href="http://wiki.linuxquestions.org/wiki/List_of_keysyms">keysym list</a>, xmodmap tutorials by <a href="http://xahlee.info/linux/linux_xmodmap_tutorial.html">xahlee</a> and <a href="https://wiki.archlinux.org/index.php/Xmodmap">archlinux wiki</a></li>
<li><a href="http://baddotrobot.com/blog/2017/10/26/upgrade-raspian-jessie-to-stretch/">upgrade raspbian8 to 9</a></li>
<li><a href="https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=138312&sid=6a3bda5ae0445765be8c8db13c68d422&start=50#p1094659">Fix wifi poor performance</a> + <a href="https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=44044&start=425#p919682">turn power management off</a> + <a href="http://projectable.me/optimize-my-pi-wi-fi/">optimize</a></li>
</ul>
</div>cloudtag:acavalin.com,2005:Blog::Post/932017-04-07T15:54:39+02:002023-12-11T17:37:43+01:00/p/concatenate_video_filesConcatenate video files2023-12-11T17:37:43ZTags: HowTo, Tools, Video<hr/><div class="md2html codehilite"><p>Use either of these commands to concatenate video files with the same codec and dimensions:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5</pre></td><td class="code"><pre><span class="c"># mencoder</span>
mencoder -oac copy -ovc copy -idx -o out.avi <span class="k">in*</span>.avi
<span class="c"># ffmpeg</span>
ls <span class="k">in*</span>.avi | sed <span class="s1">'s/.*/file \0/'</span> | ffmpeg -f concat -c copy -i - out.avi
</pre></td></tr></tbody></table>
</div>
<p>Check video resolutions:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6</pre></td><td class="code"><pre><span class="k">for </span>i <span class="k">in</span> <span class="k">*</span>.mp4; <span class="k">do
</span><span class="nb">echo</span> -en <span class="s2">"</span><span class="nv">$i</span><span class="se">\t</span><span class="s2">"</span>
ffprobe -v error -select_streams v:0 <span class="se">\</span>
-show_entries <span class="nv">stream</span><span class="o">=</span>width,height <span class="se">\</span>
-of <span class="nv">csv</span><span class="o">=</span><span class="nv">s</span><span class="o">=</span>x:p<span class="o">=</span>0 <span class="s2">"</span><span class="nv">$i</span><span class="s2">"</span>
<span class="k">done</span>
</pre></td></tr></tbody></table>
</div>
<p>To concatenate video files with different codecs and/or dimensions you have to reencode all files choosing common codecs/dimensions:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre>mencoder -oac mp3lame -ovc x264 -idx -vf <span class="nv">expand</span><span class="o">=</span>640:640 -o out.avi <span class="k">in*</span>.avi
</pre></td></tr></tbody></table>
</div>
<hr>
<p>Source: <a href="https://trac.ffmpeg.org/wiki/Concatenate">FFmpeg</a> / <a href="https://stackoverflow.com/questions/7333232/how-to-concatenate-two-mp4-files-using-ffmpeg/11175851#11175851">ffmpeg@stackoverflow</a>, <a href="https://www.mplayerhq.hu/DOCS/HTML/en/index.html">Mencoder</a></p>
</div>cloudtag:acavalin.com,2005:Blog::Post/3382021-03-21T22:29:07+01:002023-12-01T12:12:32+01:00/p/linux_radioListen to radio FM/DAB with RTL2832U2023-12-01T12:12:32ZTags: Audio, Linux, Multimedia, Terminal, Tools<hr/><div class="md2html codehilite"><div class="hll conf"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre><span class="c"># /etc/udev/rules.d/10-local_rtl-sdr.rules
</span><span class="n">SUBSYSTEM</span>==<span class="s2">"usb"</span>, <span class="n">ATTRS</span>{<span class="n">idVendor</span>}==<span class="s2">"0ccd"</span>, <span class="n">ATTRS</span>{<span class="n">idProduct</span>}==<span class="s2">"00d3"</span>, <span class="n">GROUP</span>=<span class="s2">"audio"</span>, <span class="n">MODE</span>=<span class="s2">"0666"</span>, <span class="n">SYMLINK</span>+=<span class="s2">"rtl-sdr"</span>
</pre></td></tr></tbody></table>
</div>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre><span class="c"># reload udev and plug the usb RTL2832U stick</span>
udevadm control --reload-rules <span class="o">&&</span> udevadm trigger
</pre></td></tr></tbody></table>
</div>
<h2>FM</h2>
<p>Using <a href="cubicsdr">cubicsdr FM app</a> (GUI):</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre>apt install cubicsdr
CubicSDR
</pre></td></tr></tbody></table>
</div>
<p>Using <code>rtl-sdr</code>:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4</pre></td><td class="code"><pre>apt install rtl-sdr
<span class="c"># play a FM radio station at freq. 107300000Hz with 6x sampling</span>
rtl_fm -f 107.30e6 -M wbfm -s 200000 -r 48000 - | aplay -r 48000 -f S16_LE
</pre></td></tr></tbody></table>
</div>
<h2>DAB</h2>
<p>Using <a href="https://www.welle.io">welle.io</a>:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3</pre></td><td class="code"><pre>apt install welle.io
welle-io <span class="c"># GUI</span>
welle-cli -c 7D -p R101
</pre></td></tr></tbody></table>
</div>
<p>Using <a href="https://github.com/Opendigitalradio/dablin">dablin</a> + <a href="https://github.com/Opendigitalradio/dabtools">dabtools</a>/<a href="https://github.com/JvanKatwijk/eti-stuff">eti-cmdline</a>:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10</pre></td><td class="code"><pre><span class="c"># compile dabtools</span>
git clone https://github.com/Opendigitalradio/dabtools.git <span class="o">&&</span> <span class="nb">cd </span>dabtools
mkdir -p mybuild <span class="o">&&</span> cmake -DCMAKE_BUILD_TYPE<span class="o">=</span>Release -S . -B mybuild
cmake --build mybuild
find -type f -executable mybuild
mv mybuild/src/dab2eti mybuild/src/eti2mpa ~/bin/
<span class="c"># dablin</span>
apt-get install dablin
dablin -D dab2eti -d ~/bin/dab2eti -c 12C -l R101
</pre></td></tr></tbody></table>
</div>
<p>Using <a href="https://github.com/JvanKatwijk/terminal-DAB-xxx">terminal-DAB-xxx</a>:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17</pre></td><td class="code"><pre>apt-get install <span class="se">\</span>
git cmake build-essential g++ pkg-config libsndfile1-dev libfftw3-dev portaudio19-dev zlib1g-dev libusb-1.0-0-dev libsamplerate0-dev ncurses-base <span class="se">\</span>
libfaad-dev librtlsdr-dev
git clone https://github.com/JvanKatwijk/terminal-DAB-xxx.git
<span class="nb">cd </span>terminal-DAB-xxx
mkdir build <span class="o">&&</span> <span class="nb">cd </span>build
cmake .. -DRTLSDR<span class="o">=</span>ON -DFAAD<span class="o">=</span>ON -DPICTURES<span class="o">=</span>OFF
make
mv terminal-DAB-rtlsdr t-dab <span class="o">&&</span> strip t-dab
<span class="c"># http://www.air-radio.it/T_DAB.html</span>
<span class="c"># 12A EuroDAB http://www.litaliaindigitale.it/radio-dab/mux-eurodab-italia</span>
<span class="c"># 12C DAB Italia https://www.dab.it</span>
<span class="c"># 12D DAB+ RAI http://www.rai.it/dl/DigitalRadio/dab_raiway.html</span>
./t-dab -Q -C 12C -S R101 <span class="c"># play service "R101" on channel "12C" with autogain</span>
</pre></td></tr></tbody></table>
</div>
<hr>
<p>See also:
<a href="https://wiki.opendigitalradio.org/DAB_reception">opendigitalradio.org</a>,
<a href="https://github.com/JvanKatwijk/qt-dab">Qt-DAB app</a></p>
</div>cloudtag:acavalin.com,2005:Blog::Post/1492017-11-09T13:25:26+01:002023-11-30T13:23:25+01:00/p/retropie_setupSetup RetroPie gaming station2023-11-30T13:23:25ZTags: Debian, Games, HowTo, Linux, RaspberryPi<hr/><div class="md2html codehilite"><p><center>
<
<a href="https://github.com/RetroPie">repos</a> |
<a href="https://github.com/RetroPie/RetroPie-Setup#general-usage">installer</a> |
<a href="https://retropie.org.uk/docs/">docs</a> |
<a href="https://retropie.org.uk/forum/">forum</a>
>
</center></p>
<h3>Setting up RetroPie</h3>
<ul>
<li>Check your locale settings with the <code>locale</code> command:</li>
</ul>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16</pre></td><td class="code"><pre><span class="gp">pi$ </span>locale | sort
<span class="nv">LANG</span><span class="o">=</span>en_GB.UTF-8
<span class="nv">LANGUAGE</span><span class="o">=</span>
<span class="nv">LC_ADDRESS</span><span class="o">=</span><span class="s2">"en_GB.UTF-8"</span>
<span class="nv">LC_ALL</span><span class="o">=</span>
<span class="nv">LC_COLLATE</span><span class="o">=</span><span class="s2">"en_GB.UTF-8"</span>
<span class="nv">LC_CTYPE</span><span class="o">=</span><span class="s2">"en_GB.UTF-8"</span>
<span class="nv">LC_IDENTIFICATION</span><span class="o">=</span><span class="s2">"en_GB.UTF-8"</span>
<span class="nv">LC_MEASUREMENT</span><span class="o">=</span><span class="s2">"en_GB.UTF-8"</span>
<span class="nv">LC_MESSAGES</span><span class="o">=</span><span class="s2">"en_GB.UTF-8"</span>
<span class="nv">LC_MONETARY</span><span class="o">=</span><span class="s2">"en_GB.UTF-8"</span>
<span class="nv">LC_NAME</span><span class="o">=</span><span class="s2">"en_GB.UTF-8"</span>
<span class="nv">LC_NUMERIC</span><span class="o">=</span><span class="s2">"en_GB.UTF-8"</span>
<span class="nv">LC_PAPER</span><span class="o">=</span><span class="s2">"en_GB.UTF-8"</span>
<span class="nv">LC_TELEPHONE</span><span class="o">=</span><span class="s2">"en_GB.UTF-8"</span>
<span class="nv">LC_TIME</span><span class="o">=</span><span class="s2">"en_GB.UTF-8"</span>
</pre></td></tr></tbody></table>
</div>
<p>and <a href="https://www.raspberrypi.org/forums/viewtopic.php?f=50&t=11870">set missing values</a> in <code>/etc/environment</code>:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre><span class="nv">LANGUAGE</span><span class="o">=</span><span class="s2">"en_GB:en"</span>
<span class="nv">LC_ALL</span><span class="o">=</span><span class="s2">"en_GB.UTF-8"</span>
</pre></td></tr></tbody></table>
</div>
<ul>
<li>Login as <code>pi</code>, clone the setup script and run it:</li>
</ul>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3</pre></td><td class="code"><pre>git clone --depth<span class="o">=</span>1 https://github.com/RetroPie/RetroPie-Setup.git ~/RetroPie-Setup
<span class="nb">cd</span> ~/RetroPie-Setup
sudo ./retropie_setup.sh
</pre></td></tr></tbody></table>
</div>
<p>do a <em>Basic Install</em> and <strong>disable the splashscreen</strong> in <em>Configuration</em> to avoid a suddend switch to VT1 after the graphical login (see reddit <a href="https://www.reddit.com/r/raspberry_pi/comments/6e5q0z/retropie_booting_to_terminal/">Q</a>/<a href="https://www.reddit.com/r/raspberry_pi/comments/6dyn8f/why_does_my_raspberry_pi_keep_going_to_the/">A</a> and <a href="https://github.com/RetroPie/RetroPie-Setup/wiki/FAQ#how-do-i-boot-to-the-desktop-or-kodi">retropie faq</a>).</p>
<ul>
<li><p>Disable screenblanker by appending <code>consoleblank=0</code> to kernel parameters in /boot/cmdline.txt.</p></li>
<li><p>Set memory split for the video card to at least 128MB via <code>raspi-config</code>.</p></li>
<li><p>Create a shortcut to <a href="http://www.aoakley.com/articles/2016-12-29-raspberry-pi-retropie-pixel-desktop.php">launch EmulationStation from the Pixel</a> desktop (or use the <code>alacarte</code> menu editor):</p></li>
</ul>
<div class="hll ini"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9</pre></td><td class="code"><pre><span class="c"># ~/.local/share/applications/retropie.desktop
</span><span class="nn">[Desktop Entry]</span>
<span class="py">Type</span><span class="p">=</span><span class="s">Application</span>
<span class="py">Name</span><span class="p">=</span><span class="s">RetroPie</span>
<span class="py">Comment</span><span class="p">=</span><span class="s">Retro video game emulators</span>
<span class="py">Exec</span><span class="p">=</span><span class="s">/home/pi/bin/start-retropie</span>
<span class="py">Icon</span><span class="p">=</span><span class="s">/path/to/retropie.png</span>
<span class="py">Terminal</span><span class="p">=</span><span class="s">false</span>
<span class="py">Categories</span><span class="p">=</span><span class="s">Application;Game;</span>
</pre></td></tr></tbody></table>
</div>
<p>create the <code>/home/pi/bin/start-retropie</code>:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8</pre></td><td class="code"><pre><span class="c">#!/bin/sh</span>
<span class="c"># release the video card and switch to the 1st foreground virtual terminal</span>
sudo /path/to/ttyecho -n /dev/tty1 <span class="se">\</span>
<span class="s2">"sudo systemctl stop lightdm ; "</span> <span class="se">\</span>
<span class="s2">"sleep 1 ; "</span> <span class="se">\</span>
<span class="s2">"chvt 1 ; "</span> <span class="se">\</span>
<span class="s2">"emulationstation --debug > /run/shm/ra.log 2>&1 ; "</span> <span class="se">\</span>
<span class="s2">"sudo systemctl start lightdm"</span>
</pre></td></tr></tbody></table>
</div>
<p>then compile and install the <a href="https://gist.github.com/FUT/5812683"><code>ttyecho</code> program</a> (see attachment).</p>
<p><mark>Note</mark>: Make sure you have enabled console autologin on VT1 via <code>raspi-config</code>.</p>
<ul>
<li><p>Optionally you can configure <code>runcommand</code> to <a href="https://github.com/retropie/retropie-setup/wiki/runcommand">show a game splashscreen</a> by enabling <em>Launch Menu Art</em> in its configuration, and even set a system default image by installing the experimental package <code>launchingimages</code>.</p></li>
<li><p>Show scanlines:</p>
<ul>
<li>Configuration <code>></code> Retroarch <code>></code> Enable shaders and overlays</li>
<li>Configuration <code>></code> Configedit <code>></code> Configure basic libretro emulator options <code>></code> Configure default options for all libretro emulators <code>></code> Video shader enable and Video shader file <code>></code> crt-pi.glslp</li>
</ul></li>
<li><p>When configuring controller <em>you can skip buttons you don't have</em> by simply <strong>long press</strong> a button.</p></li>
<li><p>Setup <a href="https://elinux.org/RPiconfig#Video_mode_options">video mode</a>:</p></li>
</ul>
<p>Set your tv/monitor format by setting <code>sdtv_mode=2</code> (PAL) in <code>/boot/config.txt</code>.</p>
<p>Set the low resolution VGA mode <code>CEA-1</code> by putting in <code>/opt/retropie/configs/all/videomodes.cfg</code>:</p>
<div class="hll ini"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29</pre></td><td class="code"><pre><span class="py">mame4all</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="py">mupen64plus</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="py">pifba</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-beetle-</span><span class="py">ngp</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-beetle-pce-</span><span class="py">fast</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-beetle-</span><span class="py">supergrafx</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-</span><span class="py">caprice32</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-</span><span class="py">fbalpha</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-</span><span class="py">fceumm</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-</span><span class="py">fuse</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-</span><span class="py">gambatte</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-genesis-plus-</span><span class="py">gx</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-</span><span class="py">gpsp</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-</span><span class="py">handy</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-</span><span class="py">mame2000</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-</span><span class="py">mame2003</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-</span><span class="py">mgba</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-</span><span class="py">mupen64plus</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-</span><span class="py">nestopia</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-pcsx-</span><span class="py">rearmed</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-</span><span class="py">picodrive</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-</span><span class="py">prosystem</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-</span><span class="py">quicknes</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-</span><span class="py">snes9x2002</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-</span><span class="py">snes9x2005</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-</span><span class="py">snes9x2010</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-</span><span class="py">stella</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-vba-</span><span class="py">next</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
<span class="err">lr-</span><span class="py">vecx</span> <span class="p">=</span> <span class="s">"CEA-1"</span>
</pre></td></tr></tbody></table>
</div>
<p>in this manner your TV will do the upscaling work and the emulators will run faster.</p>
<h3>Upgrading RetroPie version</h3>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3</pre></td><td class="code"><pre><span class="nb">cd</span> ~/RetroPie-Setup
git pull
sudo ./retropie_setup.sh <span class="c"># and choose "Update" from the menu</span>
</pre></td></tr></tbody></table>
</div>
<p><mark>Note</mark>: When the upgrade is finished make sure the <code>splashscreen</code> is <strong>disabled</strong>.</p>
<h3>Scraping game images</h3>
<ul>
<li>Install <a href="https://github.com/retropie/retropie-setup/wiki/scraper#lars-muldjords-skyscraper"><code>Skyscraper</code></a> in the experimental packages</li>
<li>Customize game aliases in <code>~/.skyscraper/aliasMap.csv</code></li>
<li><a href="https://github.com/muldjord/skyscraper#custom-data-import">Import your custom JPG/PNG images</a> by placing them in <code>~/.skyscraper/import/<covers|screenshots|wheels></code> with the same name as your roms</li>
</ul>
<h3>PlayStation tips (<code>lr-pcsx-rearmed</code>)</h3>
<ul>
<li>Use this script to <a href="https://pandorawiki.org/Creating_images_of_PSX_games_using_Linux">rip your own</a> original PSX cd-rom discs:</li>
</ul>
<div class="hll ruby"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24</pre></td><td class="code"><pre><span class="c1">#!/usr/bin/env ruby</span>
<span class="nb">require</span> <span class="s1">'shellwords'</span>
<span class="n">dev</span> <span class="o">=</span> <span class="s1">'/dev/dvd'</span>
<span class="n">title</span> <span class="o">=</span> <span class="no">ARGV</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="nf">strip</span>
<span class="n">vol</span> <span class="o">=</span> <span class="sb">`volname </span><span class="si">#{</span><span class="n">dev</span><span class="si">}</span><span class="sb">`</span><span class="p">.</span><span class="nf">strip</span>
<span class="n">vol</span> <span class="o">=</span> <span class="s1">'NO-LABEL'</span> <span class="k">if</span> <span class="n">vol</span><span class="p">.</span><span class="nf">size</span> <span class="o">==</span> <span class="mi">0</span>
<span class="nb">puts</span> <span class="s2">"</span><span class="si">#{</span><span class="n">vol</span><span class="si">}</span><span class="s2"> - </span><span class="si">#{</span><span class="n">title</span><span class="si">}</span><span class="se">\n\n</span><span class="s2">"</span>
<span class="nb">system</span> <span class="s2">"cdrdao read-cd --read-raw --read-subchan rw_raw --datafile </span><span class="si">#{</span><span class="n">title</span><span class="p">.</span><span class="nf">shellescape</span><span class="si">}</span><span class="s2">.bin --device </span><span class="si">#{</span><span class="n">dev</span><span class="si">}</span><span class="s2"> --driver generic-mmc-raw </span><span class="si">#{</span><span class="n">title</span><span class="p">.</span><span class="nf">shellescape</span><span class="si">}</span><span class="s2">.toc"</span> <span class="c1"># 2>&1 | tee #{title.shellescape}.log</span>
<span class="nb">system</span> <span class="s2">"eject </span><span class="si">#{</span><span class="n">dev</span><span class="si">}</span><span class="s2">"</span> <span class="k">if</span> <span class="vg">$?</span><span class="p">.</span><span class="nf">to_i</span> <span class="o">==</span> <span class="mi">0</span>
<span class="c1"># add comment</span>
<span class="n">lines</span> <span class="o">=</span> <span class="no">File</span><span class="p">.</span><span class="nf">read</span><span class="p">(</span><span class="s2">"</span><span class="si">#{</span><span class="n">title</span><span class="si">}</span><span class="s2">.toc"</span><span class="p">).</span><span class="nf">split</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span>
<span class="n">lines</span><span class="p">.</span><span class="nf">insert</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="s2">"// </span><span class="si">#{</span><span class="n">vol</span><span class="si">}</span><span class="s2"> - </span><span class="si">#{</span><span class="n">title</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
<span class="no">File</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="s2">"</span><span class="si">#{</span><span class="n">title</span><span class="si">}</span><span class="s2">.toc"</span><span class="p">,</span><span class="s1">'w'</span><span class="p">){</span><span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="n">f</span><span class="p">.</span><span class="nf">puts</span> <span class="n">lines</span> <span class="p">}</span>
<span class="c1"># update m3u</span>
<span class="k">if</span> <span class="n">title</span> <span class="o">=~</span> <span class="sr">/^(.+) \(CD(.)\)$/</span>
<span class="no">File</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="s2">"</span><span class="si">#{</span><span class="vg">$1</span><span class="si">}</span><span class="s2">.m3u"</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">){</span><span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="n">f</span><span class="p">.</span><span class="nf">puts</span> <span class="s2">"</span><span class="si">#{</span><span class="n">title</span><span class="si">}</span><span class="s2">.toc"</span><span class="p">}</span>
<span class="k">end</span>
<span class="c1">#toc2cue $vol.toc $vol.cue # optional</span>
</pre></td></tr></tbody></table>
</div>
<p>if using a different program that creates multiple <code>bin</code> files then you can merge them via <a href="https://github.com/putnam/binmerge"><code>binmerge</code></a></p>
<ul>
<li><p>File <a href="https://docs.libretro.com/library/pcsx_rearmed/#extensions">extensions</a>: <code>bin</code>/<code>img</code> + <code>toc</code>/<code>cue</code> + <code>sbi</code> (image, descr, subchannel)</p></li>
<li><p>Multidisc <a href="https://docs.libretro.com/library/pcsx_rearmed/#playing-pal-copy-protected-games">howto</a>:</p></li>
</ul>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8
9
10</pre></td><td class="code"><pre><span class="c"># files in Retropie/roms/psx folder:</span>
.multidisc/Title <span class="o">(</span>CD1<span class="o">)</span>.bin
.multidisc/Title <span class="o">(</span>CD1<span class="o">)</span>.toc
.multidisc/Title <span class="o">(</span>CD2<span class="o">)</span>.bin
.multidisc/Title <span class="o">(</span>CD2<span class="o">)</span>.toc
Title.m3u
<span class="c"># Title.m3u file contents:</span>
.multidisc/Title <span class="o">(</span>CD1<span class="o">)</span>.toc
.multidisc/Title <span class="o">(</span>CD2<span class="o">)</span>.toc
</pre></td></tr></tbody></table>
</div>
<ul>
<li>Datasets, subchannels, CUE sheets: <a href="http://redump.org/downloads/">redump.org</a>, <a href="http://www.emuparadise.org/PSX/cues%20and%20sbis.zip">emuparadise.org</a></li>
</ul>
<h3>Setup an arcade controller via <a href="https://retropie.org.uk/docs/Universal-Controller-Calibration-&-Mapping-Using-xboxdrv/">xboxdrv</a></h3>
<p>Install <code>xboxdrv</code> from <code>retropie_setup.sh</code>, customize and run the command without <code>--silent --daemon --detach</code> options and test the new virtual controller with <code>jstest /dev/input/js0</code>, then put it in <code>/etc/rc.local</code>:</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6</pre></td><td class="code"><pre>/opt/retropie/supplementary/xboxdrv/bin/xboxdrv <span class="se">\</span>
--detach-kernel-driver <span class="se">\</span>
--silent --daemon --detach --pid-file /run/xboxdrv.pid <span class="se">\</span>
--device-by-id 045e:028e --type xbox360 <span class="se">\</span>
--trigger-as-button --dpad-only <span class="se">\</span>
--device-name <span class="s2">"DragonSlay Arcade DGSAK17"</span>
</pre></td></tr></tbody></table>
</div>
<p>and create a new <a href="https://github.com/xboxdrv/xboxdrv/issues/42#issuecomment-44109839">dbus rule</a> in <code>/etc/dbus-1/system.d/org.seul.Xboxdrv.conf</code>:</p>
<div class="hll xml"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7</pre></td><td class="code"><pre><span class="cp"><!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"></span>
<span class="nt"><busconfig></span>
<span class="nt"><policy</span> <span class="na">context=</span><span class="s">"default"</span><span class="nt">></span>
<span class="nt"><allow</span> <span class="na">own=</span><span class="s">"org.seul.Xboxdrv"</span><span class="nt">/></span>
<span class="nt"></policy></span>
<span class="nt"></busconfig></span>
</pre></td></tr></tbody></table>
</div>
<p>See also:</p>
<ul>
<li><a href="https://github.com/RetroPie/RetroPie-Setup/wiki/Xbox-360-Controller">https://github.com/RetroPie/RetroPie-Setup/wiki/Xbox-360-Controller</a></li>
<li><a href="https://github.com/RetroPie/RetroPie-Setup/wiki/Universal-Controller-Calibration-&-Mapping-Using-xboxdrv">https://github.com/RetroPie/RetroPie-Setup/wiki/Universal-Controller-Calibration-&-Mapping-Using-xboxdrv</a></li>
</ul>
<h3>Raspberry Pi4 tips</h3>
<ul>
<li><a href="https://retropie.org.uk/forum/topic/24436/drm_ioctl_mode_create_dumb-failed-cannot-allocate-memory/8">suggested video settings</a> on <em><a href="/p/raspberrypi_server#pi4drm-err">DRM mem error fix</a></em> paragraph</li>
<li><a href="https://retropie.org.uk/forum/topic/27430/howto-optimized-boot-config-txt">overclock & video settings</a> </li>
<li><a href="https://retropie.org.uk/forum/topic/27429/howto-emulator-performance-tweaks-for-psp-and-n64-and-quality-for-psx">psp & n64</a></li>
<li><a href="https://retropie.org.uk/forum/topic/27431/howto-major-performance-boost-on-retroarch-based-emulators">tune retroarch based emulators</a></li>
<li><a href="https://retropie.org.uk/forum/topic/27428/howto-change-output-resolution-to-720p-on-libretro-retroarch-emulators">libretro 720p resolution</a></li>
</ul>
<hr>
<p>Source:
<a href="https://retropie.org.uk/">RetroPie HP</a>,
<a href="http://www.wired.co.uk/article/retro-arcade-machine-raspberry-pi">wired</a>,
<a href="http://www.aoakley.com/articles/2016-12-29-raspberry-pi-retropie-pixel-desktop.php">Pixel & RetroPie</a>,
<a href="https://retropie.org.uk/forum/favicon.ico">RP icon</a>,
<a href="https://gist.github.com/FUT/5812683">TTYecho</a>, <a href="https://www.linuxquestions.org/questions/linux-software-2/is-there-a-way-to-switch-to-a-tty-with-a-command-135429/#post2477651">change linux vt/tty</a></p>
<p>Retropie docs:
<a href="https://github.com/RetroPie/RetroPie-Setup/wiki">Wiki</a>,
<a href="https://github.com/RetroPie/RetroPie-Setup/wiki/Manual-Installation">Manual install</a>,
<a href="https://github.com/RetroPie/RetroPie-Setup/wiki/RetroArch-Configuration#hotkeys">RA hotkeys</a>,
<a href="https://github.com/RetroPie/RetroPie-Setup/wiki/Controller-Configuration">Controller setup</a>,
<a href="https://github.com/retropie/retropie-setup/wiki/Supported-Systems">Supported systems</a>,
<a href="https://github.com/RetroPie/RetroPie-Setup/wiki/Arcade">Arcade HP</a> &
<a href="http://mameworld.info">MAME info</a></p>
<p>PlayStation 1: convert ISO to PBP format on <a href="https://gbatemp.net/threads/guide-to-converting-ps1-games-for-psp.206195/">windows</a> and <a href="http://linuxevia.blogspot.it/2012/06/popstation-su-ubuntu-i-giochi-psx-sulla.html">linux</a> -- see <a href="https://www.liranuna.com/misc-projects/gtk-popstation/">gtk-popstation</a> and <a href="https://www.linux-apps.com/p/1127474/">psx2psp/popstation</a> by <a href="https://git.opendesktop.org/Ivanvega">Ivan Vega</a></p>
<p>MAME resources: <a href="http://www.progettosnaps.net/snapshots/">Snapshots</a>, <a href="http://www.progettosnaps.net/dats/">DAT/XML files</a>, <a href="http://www.progettosnaps.net/catver/">game lists</a> by genre, <a href="https://www.raspberrypi.org/forums/viewtopic.php?f=78&t=70957">ES gamelist.xml script</a></p>
<p>Game systems DAT/XML files: <a href="http://hyperlist.hyperspin-fe.com/index.php">HyperList</a></p>
<hr>
<h2>TODO/WIP:</h2>
<ul>
<li><a href="https://retropie.org.uk/docs/Netplay/">NetPlay docs</a></li>
<li><a href="https://www.google.it/search?q=retroarch+netplay+implementations+differ&oq=retroarch+netplay+implementations+differ">retroarch netplay implementations differ</a></li>
</ul>
</div>cloudtag:acavalin.com,2005:Blog::Post/4322023-11-29T16:06:33+01:002023-11-29T16:06:38+01:00/p/cmake_howtoHow do I build a CMake project2023-11-29T16:06:38ZTags: Dev, HowTo, Linux<hr/><div class="md2html codehilite"><div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5</pre></td><td class="code"><pre>md -p mybuild <span class="o">&&</span> cmake -DCMAKE_BUILD_TYPE<span class="o">=</span>Release -S . -B mybuild
cmake --build mybuild
find -type f -executable mybuild
</pre></td></tr></tbody></table>
</div>
<hr>
<p>Source: <a href="https://stackoverflow.com/questions/67425557/how-do-i-build-a-cmake-project">stackoverflow</a></p>
</div>cloudtag:acavalin.com,2005:Blog::Post/4312023-11-29T15:03:59+01:002023-11-29T15:08:48+01:00/p/linux_run_asLinux Run Command As Another User2023-11-29T15:08:48ZTags: HowTo, Linux, Terminal<hr/><div class="md2html codehilite"><h1>runuser</h1>
<p>Only <code>root</code> can use it, no password asked, less overhead than others.</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5</pre></td><td class="code"><pre>runuser -u username -- <span class="nb">command </span>args
<span class="c"># -l = login shell, -P = allocate a pty</span>
runuser -l userNameHere -c <span class="s1">'command args'</span>
runuser -P -l userNameHere -c <span class="s1">'/user/bin/bash -ilc "command args"'</span>
</pre></td></tr></tbody></table>
</div>
<p>Note: You can also use <code>#!/usr/bin/env -S bash -il</code> shebang in a <code>command</code> script to get the real final user environment.</p>
<h1>sudo</h1>
<p>Asks user password.</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3</pre></td><td class="code"><pre><span class="c"># -i = login shell, -u = username</span>
sudo -iu username <span class="c"># open default shell for `username`</span>
sudo -iu username <span class="nb">command </span>args
</pre></td></tr></tbody></table>
</div>
<h1>su</h1>
<p>Asks target password.</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3</pre></td><td class="code"><pre><span class="c"># - or --login = login shell</span>
su - <span class="c"># open root shell</span>
su - username -c <span class="s2">"command args"</span>
</pre></td></tr></tbody></table>
</div>
<hr>
<p>Source: <a href="https://www.cyberciti.biz/open-source/command-line-hacks/linux-run-command-as-different-user/">nixCraft</a></p>
</div>cloudtag:acavalin.com,2005:Blog::Post/4232023-10-20T12:03:38+02:002023-11-24T12:22:20+01:00/p/email_validation_in_railsemail validation in rails2023-11-24T12:22:20ZTags: Dev, Email, HowTo, Rails<hr/><div class="md2html codehilite"><div class="hll ruby"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4</pre></td><td class="code"><pre><span class="n">validates</span> <span class="ss">:email</span><span class="p">,</span>
<span class="ss">presence: </span><span class="kp">true</span><span class="p">,</span>
<span class="ss">uniqueness: </span><span class="p">{</span> <span class="ss">case_sensitive: </span><span class="kp">false</span> <span class="p">},</span>
<span class="ss">format: </span><span class="p">{</span> <span class="ss">with: </span><span class="no">URI</span><span class="o">::</span><span class="no">MailTo</span><span class="o">::</span><span class="no">EMAIL_REGEXP</span> <span class="p">}</span>
</pre></td></tr></tbody></table>
</div>
<p>Simply use <code>/\A.+@.+\..+\z/i</code> and put and end to the overkill.</p>
<hr>
<p>Source: <a href="https://github.com/mikker/passwordless">passwordless gem</a>, <a href="https://guides.rubyonrails.org/active_record_validations.html#custom-validators">railsguides</a>, <a href="https://davidcel.is/articles/stop-validating-email-addresses-with-regex/">Stop Validating Email Addresses with Regex</a></p>
</div>cloudtag:acavalin.com,2005:Blog::Post/3612022-02-21T17:31:18+01:002023-11-22T17:27:07+01:00/p/github_rubygems_registryuse github rubygems registry2023-11-22T17:27:07ZTags: Dev, Gems, Git, HowTo, Ruby<hr/><div class="md2html codehilite"><h1><a href="https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-rubygems-registry">Working with the RubyGems registry</a></h1>
<ul>
<li><p>generate a <a href="https://github.com/settings/tokens">personal access token</a> and grant it repo permissions (replace <code>MY_GITHUB_TOKEN</code> with its content)</p></li>
<li><p><code>cat ~/.gem/credentials</code></p>
<div class="hll yaml"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre><span class="nn">---</span>
<span class="s">:github</span><span class="pi">:</span> <span class="s">Bearer MY_GITHUB_TOKEN</span>
</pre></td></tr></tbody></table>
</div></li>
<li><p><code>cat .bundle/config</code></p>
<p>Note: replace any <code>-</code> with <code>___</code>.</p>
<div class="hll yaml"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2</pre></td><td class="code"><pre><span class="nn">---</span>
<span class="s">BUNDLE_HTTPS://RUBYGEMS__PKG__GITHUB__COM/ACAVALIN/</span><span class="pi">:</span> <span class="s2">"</span><span class="s">acavalin:MY_GITHUB_TOKEN"</span>
</pre></td></tr></tbody></table>
</div></li>
<li><p><code>cat .gemrc</code></p>
<div class="hll yaml"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1
2
3
4
5
6
7
8</pre></td><td class="code"><pre><span class="s">gem</span><span class="pi">:</span> <span class="s">--no-document</span>
<span class="s">backtrace</span><span class="pi">:</span> <span class="s">false</span>
<span class="s">bulk_threshold</span><span class="pi">:</span> <span class="s">1000</span>
<span class="s">sources</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">https://rubygems.org/</span>
<span class="pi">-</span> <span class="s">https://acavalin:MY_GITHUB_TOKEN@rubygems.pkg.github.com/acavalin/</span>
<span class="s">update_sources</span><span class="pi">:</span> <span class="s">true</span>
<span class="s">verbose</span><span class="pi">:</span> <span class="s">true</span>
</pre></td></tr></tbody></table>
</div></li>
<li><p>build the gem, examples:</p>
<ul>
<li><code>gem build name.gemspec</code></li>
<li><code>rake --tasks ; rake build</code></li>
</ul></li>
<li><p>push gem to registry</p>
<div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre>gem push --key github --host https://rubygems.pkg.github.com/acavalin name-0.0.1.gem
</pre></td></tr></tbody></table>
</div></li>
<li><p>use gem in project</p>
<ul>
<li>Gemfile: <code>gem "name "0.0.1", source: "https://rubygems.pkg.github.com/acavalin"</code></li>
<li>cmdline: <code>gem install --clear-sources --source https://acavalin:MY_GITHUB_TOKEN@rubygems.pkg.github.com/acavalin deluge-rpc</code></li>
</ul></li>
</ul>
</div>cloudtag:acavalin.com,2005:Blog::Post/4292023-11-21T13:49:39+01:002023-11-21T13:50:11+01:00/p/bind_mountsLinux show bind mounts2023-11-21T13:50:11ZTags: HowTo, Linux, Terminal<hr/><div class="md2html codehilite"><div class="hll shell"><table style="border-spacing: 0"><tbody><tr><td class="gutter gl" style="text-align: right"><pre class="lineno">1</pre></td><td class="code"><pre>findmnt | fgrep <span class="se">\\</span><span class="o">[</span>
</pre></td></tr></tbody></table>
</div>
<hr>
<p>Source: stackexchange <a href="https://unix.stackexchange.com/questions/18048/list-only-bind-mounts/290441#290441">1</a>
and <a href="https://unix.stackexchange.com/questions/18048/list-only-bind-mounts#18067">2</a></p>
</div>cloud