Заполнение mp3-тегов скриптом

Довелось скачать саундтрек к игре в виде кучи файлов без тегов вообще.

Захотелось на скорую руку заполнить хотя бы названия и номера треков (альбом/год/жанр — одинаковые для всех, с этим все сильно проще).

Для начала из имени каждого файла нужно вычленить название трека. Используем sed в однострочном цикле для разделения имени файла на три блока. Блоки в sed выделяются экранированными скобками: начало — \(, конец — \)

 
 
  1.                                                        вычленяем блок №2
  2.                                                         |             |
 
 
  1. for file in *.mp3; do name=$(sed "s/\(^.*_.\{1,3\}_\)\(.*\)\(\.mp3\)/\2/" <<< $file); echo $name ; done;
 
 
  1.                                           |                     |    
  2.            блок №1: начало строки, любые символы,          блок №3: .mp3
  3.                     подчеркивание, 1-3 любых символа,
  4.                     подчеркивание

Вывод:

 
 
  1. chat_thiscouldbeAWESOME
  2. lab sewers
  3. chat_downthe
  4. ...

(да, если вы решаете проблему с помощью регулярных выражений — у вас уже 2 проблемы, но в данном случае это отличное решение).

Убедившись что имена получаются корректные, меняем echo $name на редактор тегов mid3v2

 
 
  1. for file in *.mp3; do name=$(sed "s/\(^.*_.\{1,3\}_\)\(.*\)\(\.mp3\)/\2/" <<< $file); mid3v2 -t "$name" "$file" ; done;

Самое сложное сделано. Теперь номера треков (всего их 46, так что это число я подставляю вручную):

 
 
  1. i=1; for file in *.mp3; do mid3v2 -T  "${i}/46" "$file" ; ((i+=1)); done;

Все одинаковые для треков теги заполняются совсем просто, например год:

 
 
  1. for file in *.mp3; do mid3v2 -y 2010  "$file" ; done;

PS: утилита mid3v2 (рекомендуется как полностью поддерживающая v2/utf8-теги) входит в питоновский пакет mutagen и ставится примерно так (для debian/ubuntu)

 
 
  1. apt install python3-mutagen

или так (установка в пользовательский профиль из репозитория pypi)

 
 
  1. pip3 install --user mutagen

Debian 10 Buster + openbox (установка и настройка)

Уже давно сижу на облегченном дебиане, собранном с минимальной инсталляции. В процессе эксплуатации набралось шпаргалок по сборке системы моей мечты, которые записывались в файлик, а теперь перенесены в чуть более развернутом виде сюда на сайт.

Читать: Debian 10 Buster + openbox (установка и настройка)

25 центов на память о 2020

Невероятно долго ехала символичная монетка, которую выпустили в этом году, как ни странно, совсем по другому поводу. Хотя определенно это заговор рептилоидов =)

25 центов летучая мышь

Свежий чай — ха-ра-шо!

С этими эпидемиями из Китая хрен что доедет, а если доедет, то ехать будет просто вечность. Но доехало! В такой модной упаковке (штук на 9 плюх вообще-то)

Но плюхи только 3 — хватит на первое время =)

 

RussianFIO2AD — генератор учеток для Active Directory

По работе регулярно сталкиваюсь с присланными списками ФИО, которые нужно сконвертировать в учетки AD с шаблонными логинами и паролями. Для этих целей еще с год назад написал небольшую прожку, которую все это время тестировал, а сейчас немного допилил и могу поделиться.

Выглядит незамысловато

Вставляем из буфера список ФИО — поддерживается вставка из текстового файла или таблицы (с некоторыми оговорками, но как правило работает) — потом генерируем логины и пароли, проверяем чтобы в AD не было дублей и создаем учетки. Процесс коротенько можно увидеть на ютубе.

Скачать прожку можно на гитхабе: https://github.com/qiwichupa/RussianFIO2AD

Как всегда в таких случаях: нормальная работа не гарантируется, используйте на свой страх и риск, то, что у меня AD не сломалось — ничего не значит, может быть мне повезло)

fail2ban не добавляет правила nftables (Ubuntu 16), чиним!

Внезапно — в Ubuntu 16 корявый пакет fail2ban (10.2), которому не доложили конфигов! Поэтому ключевое:

 
 
  1. # идем куда нeдосыпали
  2. cd /etc/fail2ban/action.d/
  3. # бэкапим штатные (хоть и кривые) конфиги
  4. mv nftables-multiport.conf nftables-multiport.conf.bak
  5. mv nftables-allports.conf nftables-allports.conf.bak
  6. # качаем правильные конфиги
  7. wget https://raw.githubusercontent.com/fail2ban/fail2ban/master/config/action.d/nftables-allports.conf
  8. wget https://raw.githubusercontent.com/fail2ban/fail2ban/master/config/action.d/nftables-multiport.conf
  9. # вот этого вообще не было!:
  10. wget https://raw.githubusercontent.com/fail2ban/fail2ban/master/config/action.d/nftables.conf

 

Что я делал дальше:

  1. Убедился что у меня есть штатный конфиг «/etc/fail2ban/jail.conf», полученный копированием «jail.conf.dpkg-dist» с последующим вырезанием секции с тюрьмами (для них у меня «/jail.d/» есть и незачем их смешивать)
    /etc/fail2ban/jail.conf
     
    1. #
    2. # WARNING: heavily refactored in 0.9.0 release. Please review and
    3. # customize settings for your setup.
    4. #
    5. # Changes: in most of the cases you should not modify this
    6. # file, but provide customizations in jail.local file,
    7. # or separate .conf files under jail.d/ directory, e.g.:
    8. #
    9. # HOW TO ACTIVATE JAILS:
    10. #
    11. # YOU SHOULD NOT MODIFY THIS FILE.
    12. #
    13. # It will probably be overwritten or improved in a distribution update.
    14. #
    15. # Provide customizations in a jail.local file or a jail.d/customisation.local.
    16. # For example to change the default bantime for all jails and to enable the
    17. # ssh-iptables jail the following (uncommented) would appear in the .local file.
    18. # See man 5 jail.conf for details.
    19. #
    20. # [DEFAULT]
    21. # bantime = 1h
    22. #
    23. # [sshd]
    24. # enabled = true
    25. #
    26. # See jail.conf(5) man page for more information
    27. # Comments: use '#' for comment lines and ';' (following a space) for inline comments
    28. [INCLUDES]
    29. #before = paths-distro.conf
    30. before = paths-debian.conf
    31. # The DEFAULT allows a global definition of the options. They can be overridden
    32. # in each jail afterwards.
    33. [DEFAULT]
    34. #
    35. # MISCELLANEOUS OPTIONS
    36. #
    37. # "ignorself" specifies whether the local resp. own IP addresses should be ignored
    38. # (default is true). Fail2ban will not ban a host which matches such addresses.
    39. #ignorself = true
    40. # "ignoreip" can be a list of IP addresses, CIDR masks or DNS hosts. Fail2ban
    41. # will not ban a host which matches an address in this list. Several addresses
    42. # can be defined using space (and/or comma) separator.
    43. #ignoreip = 127.0.0.1/8 ::1
    44. # External command that will take an tagged arguments to ignore, e.g. <ip>,
    45. # and return true if the IP is to be ignored. False otherwise.
    46. #
    47. # ignorecommand = /path/to/command <ip>
    48. ignorecommand =
    49. # "bantime" is the number of seconds that a host is banned.
    50. bantime = 10m
    51. # A host is banned if it has generated "maxretry" during the last "findtime"
    52. # seconds.
    53. findtime = 10m
    54. # "maxretry" is the number of failures before a host get banned.
    55. maxretry = 5
    56. # "backend" specifies the backend used to get files modification.
    57. # Available options are "pyinotify", "gamin", "polling", "systemd" and "auto".
    58. # This option can be overridden in each jail as well.
    59. #
    60. # pyinotify: requires pyinotify (a file alteration monitor) to be installed.
    61. # If pyinotify is not installed, Fail2ban will use auto.
    62. # gamin: requires Gamin (a file alteration monitor) to be installed.
    63. # If Gamin is not installed, Fail2ban will use auto.
    64. # polling: uses a polling algorithm which does not require external libraries.
    65. # systemd: uses systemd python library to access the systemd journal.
    66. # Specifying "logpath" is not valid for this backend.
    67. # See "journalmatch" in the jails associated filter config
    68. # auto: will try to use the following backends, in order:
    69. # pyinotify, gamin, polling.
    70. #
    71. # Note: if systemd backend is chosen as the default but you enable a jail
    72. # for which logs are present only in its own log files, specify some other
    73. # backend for that jail (e.g. polling) and provide empty value for
    74. # journalmatch. See https://github.com/fail2ban/fail2ban/issues/959#issuecomment-74901200
    75. backend = auto
    76. # "usedns" specifies if jails should trust hostnames in logs,
    77. # warn when DNS lookups are performed, or ignore all hostnames in logs
    78. #
    79. # yes: if a hostname is encountered, a DNS lookup will be performed.
    80. # warn: if a hostname is encountered, a DNS lookup will be performed,
    81. # but it will be logged as a warning.
    82. # no: if a hostname is encountered, will not be used for banning,
    83. # but it will be logged as info.
    84. # raw: use raw value (no hostname), allow use it for no-host filters/actions (example user)
    85. usedns = warn
    86. # "logencoding" specifies the encoding of the log files handled by the jail
    87. # This is used to decode the lines from the log file.
    88. # Typical examples: "ascii", "utf-8"
    89. #
    90. # auto: will use the system locale setting
    91. logencoding = auto
    92. # "enabled" enables the jails.
    93. # By default all jails are disabled, and it should stay this way.
    94. # Enable only relevant to your setup jails in your .local or jail.d/*.conf
    95. #
    96. # true: jail will be enabled and log files will get monitored for changes
    97. # false: jail is not enabled
    98. enabled = false
    99. # "mode" defines the mode of the filter (see corresponding filter implementation for more info).
    100. mode = normal
    101. # "filter" defines the filter to use by the jail.
    102. # By default jails have names matching their filter name
    103. #
    104. filter = %(__name__)s[mode=%(mode)s]
    105. #
    106. # ACTIONS
    107. #
    108. # Some options used for actions
    109. # Destination email address used solely for the interpolations in
    110. # jail.{conf,local,d/*} configuration files.
    111. destemail = root@localhost
    112. # Sender email address used solely for some actions
    113. sender = root@<fq-hostname>
    114. # E-mail action. Since 0.8.1 Fail2Ban uses sendmail MTA for the
    115. # mailing. Change mta configuration parameter to mail if you want to
    116. # revert to conventional 'mail'.
    117. mta = sendmail
    118. # Default protocol
    119. protocol = tcp
    120. # Specify chain where jumps would need to be added in ban-actions expecting parameter chain
    121. chain = <known/chain>
    122. # Ports to be banned
    123. # Usually should be overridden in a particular jail
    124. port = 0:65535
    125. # Format of user-agent https://tools.ietf.org/html/rfc7231#section-5.5.3
    126. fail2ban_agent = Fail2Ban/%(fail2ban_version)s
    127. #
    128. # Action shortcuts. To be used to define action parameter
    129. # Default banning action (e.g. iptables, iptables-new,
    130. # iptables-multiport, shorewall, etc) It is used to define
    131. # action_* variables. Can be overridden globally or per
    132. # section within jail.local file
    133. banaction = nftables-multiport
    134. banaction_allports = nftables-allports
    135. # The simplest action to take: ban only
    136. action_ = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
    137. # ban & send an e-mail with whois report to the destemail.
    138. action_mw = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
    139. %(mta)s-whois[name=%(__name__)s, sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]
    140. # ban & send an e-mail with whois report and relevant log lines
    141. # to the destemail.
    142. action_mwl = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
    143. %(mta)s-whois-lines[name=%(__name__)s, sender="%(sender)s", dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s"]
    144. # See the IMPORTANT note in action.d/xarf-login-attack for when to use this action
    145. #
    146. # ban & send a xarf e-mail to abuse contact of IP address and include relevant log lines
    147. # to the destemail.
    148. action_xarf = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]
    149. xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath=%(logpath)s, port="%(port)s"]
    150. # ban IP on CloudFlare & send an e-mail with whois report and relevant log lines
    151. # to the destemail.
    152. action_cf_mwl = cloudflare[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"]
    153. %(mta)s-whois-lines[name=%(__name__)s, sender="%(sender)s", dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s"]
    154. # Report block via blocklist.de fail2ban reporting service API
    155. #
    156. # See the IMPORTANT note in action.d/blocklist_de.conf for when to use this action.
    157. # Specify expected parameters in file action.d/blocklist_de.local or if the interpolation
    158. # `action_blocklist_de` used for the action, set value of `blocklist_de_apikey`
    159. # in your `jail.local` globally (section [DEFAULT]) or per specific jail section (resp. in
    160. # corresponding jail.d/my-jail.local file).
    161. #
    162. action_blocklist_de = blocklist_de[email="%(sender)s", service=%(filter)s, apikey="%(blocklist_de_apikey)s", agent="%(fail2ban_agent)s"]
    163. # Report ban via badips.com, and use as blacklist
    164. #
    165. # See BadIPsAction docstring in config/action.d/badips.py for
    166. # documentation for this action.
    167. #
    168. # NOTE: This action relies on banaction being present on start and therefore
    169. # should be last action defined for a jail.
    170. #
    171. action_badips = badips.py[category="%(__name__)s", banaction="%(banaction)s", agent="%(fail2ban_agent)s"]
    172. #
    173. # Report ban via badips.com (uses action.d/badips.conf for reporting only)
    174. #
    175. action_badips_report = badips[category="%(__name__)s", agent="%(fail2ban_agent)s"]
    176. # Report ban via abuseipdb.com.
    177. #
    178. # See action.d/abuseipdb.conf for usage example and details.
    179. #
    180. action_abuseipdb = abuseipdb
    181. # Choose default action. To change, just override value of 'action' with the
    182. # interpolation to the chosen action shortcut (e.g. action_mw, action_mwl, etc) in jail.local
    183. # globally (section [DEFAULT]) or per specific section
    184. action = %(action_)s
  2. Создал файл «/etc/fail2ban/jail.local», который читается после «/etc/fail2ban/jail.conf» и служит для переопределения параметров
    /etc/fail2ban/jail.local
     
    1. [DEFAULT]
    2. banaction = nftables-multiport
    3. banaction_allports = nftables-allports

Все! В инете есть еще варианты назначить конкретную таблицу для правил f2b, но вот с такой конфигурацией он и сам прекрасно добавляет таблицу имени себя:

 
 
  1. table inet f2b-table {
  2.         set addr-set-sshd {
  3.                 type ipv4_addr
  4.                 elements = { 31.220.1.210, 37.49.226.161 }
  5.         }
  6.         set addr-set-wp-qiwichupa-net {
  7.                 type ipv4_addr
  8.                 elements = { 34.76.172.157, 34.82.91.206,
  9.                              35.183.87.236, 35.220.162.15 }
  10.         }
  11.         chain f2b-chain {
  12.                 type filter hook input priority -1; policy accept;
  13.                 tcp dport { ssh } ip saddr @addr-set-sshd reject
  14.                 tcp dport { http, https } ip saddr @addr-set-wp-qiwichupa-net reject
  15.         }
  16. }

Единственное что имеет смысл, создать файлик /etc/fail2ban/action.d/nftables-common.local:

 
 
  1. [Init]
  2. blocktype = drop

Он также будет читаться как конфиг nftables и заставит дропать, а не реджектить пакеты с заблокированных айпишников.

И на эту дичь было убито 4 часа -_-

Как заставить chrome/chromium использовать kde (qt) диалоги сохранения файла

Долгое время не мог найти решение, связанное с использованием chromium совместно с openbox. При таком раскладе браузер по дефолту использует гномовский диалог сохранения файлов, который лично мне неудобен.

Диалоги сохранения файла: GNOME/GTK  — слева, KDE/QT — справа.

Оказалось, проблема кроется в том, что chromium ориентируется на переменную окружения XDG_CURRENT_DESKTOP, которая описывает текущее окружение рабочего стола и которая не задается по дефолту, если использовать openbox.

Соответственно, решение сводится к установке пакета kdialog (если у вас дебиан и пакет еще не установлен), и прописыванию правильной переменной окружения. Последнее можно сделать двумя путями:

  1. добавить в файл  ~/.config/openbox/environment строку:
     
     
    1. XDG_CURRENT_DESKTOP=KDE

    в этом случае все приложения, запущенные в сеансе пользователя, будут уверены что работают в KDE. Однако, если изменения хочется применить только к хрому, есть второй вариант

  2. отредактировать ярлык браузера, изменив путь приложения на:
     
     
    1. env XDG_CURRENT_DESKTOP=KDE /usr/bin/chromium %U

    (для хромиума)

    при использовании lxpanel это можно сделать через его свойства, или же создав (изменив) файл:

    ~/.local/share/applications/chromium.desktop
     
    1. [Desktop Entry]
    2. Version=1.0
    3. Name=Chromium Web Browser
    4. Name[ast]=Restolador web Chromium
    5. Name[ca]=Navegador web Chromium
    6. Name[de]=Chromium-Webbrowser
    7. Name[es]=Navegador web Chromium
    8. Name[fr]=Navigateur Web Chromium
    9. Name[gl]=Navegador web Chromium
    10. Name[he]=דפדפן האינטרנט Chromium
    11. Name[hr]=Chromium web preglednik
    12. Name[hu]=Chromium webböngésző
    13. Name[id]=Peramban Web Chromium
    14. Name[it]=Browser web Chromium
    15. Name[ja]=Chromium ウェブ・ブラウザ
    16. Name[ko]=Chromium 웹 브라우저
    17. Name[pt_BR]=Chromium Navegador da Internet
    18. Name[ru]=Веб-браузер Chromium
    19. Name[sl]=Chromium spletni brskalnik
    20. Name[sv]=Webbläsaren Chromium
    21. Name[ug]=Chromium توركۆرگۈ
    22. Name[zh_CN]=Chromium 网页浏览器
    23. Name[zh_HK]=Chromium 網頁瀏覽器
    24. Name[zh_TW]=Chromium 網頁瀏覽器
    25. GenericName=Web Browser
    26. GenericName[ar]=متصفح الشبكة
    27. GenericName[ast]=Restolador web
    28. GenericName[bg]=Уеб браузър
    29. GenericName[bn]=ওয়েব ব্রাউজার
    30. GenericName[ca]=Navegador web
    31. GenericName[cs]=WWW prohlížeč
    32. GenericName[da]=Browser
    33. GenericName[de]=Webbrowser
    34. GenericName[el]=Περιηγητής ιστού
    35. GenericName[en_GB]=Web Browser
    36. GenericName[es]=Navegador web
    37. GenericName[et]=Veebibrauser
    38. GenericName[fi]=WWW-selain
    39. GenericName[fil]=Web Browser
    40. GenericName[fr]=Navigateur Web
    41. GenericName[gl]=Navegador web
    42. GenericName[gu]=વેબ બ્રાઉઝર
    43. GenericName[he]=דפדפן אינטרנט
    44. GenericName[hi]=वेब ब्राउज़र
    45. GenericName[hr]=Web preglednik
    46. GenericName[hu]=Webböngésző
    47. GenericName[id]=Peramban Web
    48. GenericName[it]=Browser web
    49. GenericName[ja]=ウェブ・ブラウザ
    50. GenericName[kn]=ಜಾಲ ವೀಕ್ಷಕ
    51. GenericName[ko]=웹 브라우저
    52. GenericName[lt]=Žiniatinklio naršyklė
    53. GenericName[lv]=Tīmekļa pārlūks
    54. GenericName[ml]=വെബ് ബ്രൌസര്
    55. GenericName[mr]=वेब ब्राऊजर
    56. GenericName[nb]=Nettleser
    57. GenericName[nl]=Webbrowser
    58. GenericName[or]=ଓ୍ବେବ ବ୍ରାଉଜର
    59. GenericName[pl]=Przeglądarka WWW
    60. GenericName[pt]=Navegador Web
    61. GenericName[pt_BR]=Navegador da Internet
    62. GenericName[ro]=Navigator de Internet
    63. GenericName[ru]=Веб-браузер
    64. GenericName[sk]=WWW prehliadač
    65. GenericName[sl]=Spletni brskalnik
    66. GenericName[sr]=Интернет прегледник
    67. GenericName[sv]=Webbläsare
    68. GenericName[ta]=இணைய உலாவி
    69. GenericName[te]=మహాతల అన్వేషి
    70. GenericName[th]=เว็บเบราว์เซอร์
    71. GenericName[tr]=Web Tarayıcı
    72. GenericName[ug]=توركۆرگۈ
    73. GenericName[uk]=Навігатор Тенет
    74. GenericName[vi]=Bộ duyệt Web
    75. GenericName[zh_CN]=网页浏览器
    76. GenericName[zh_HK]=網頁瀏覽器
    77. GenericName[zh_TW]=網頁瀏覽器
    78. Comment=Access the Internet
    79. Comment[ar]=الدخول إلى الإنترنت
    80. Comment[ast]=Accesu a Internet
    81. Comment[bg]=Достъп до интернет
    82. Comment[bn]=ইন্টারনেটটি অ্যাক্সেস করুন
    83. Comment[ca]=Accediu a Internet
    84. Comment[cs]=Přístup k internetu
    85. Comment[da]=Få adgang til internettet
    86. Comment[de]=Internetzugriff
    87. Comment[el]=Πρόσβαση στο Διαδίκτυο
    88. Comment[en_GB]=Access the Internet
    89. Comment[es]=Acceda a Internet
    90. Comment[et]=Pääs Internetti
    91. Comment[fi]=Käytä internetiä
    92. Comment[fil]=I-access ang Internet
    93. Comment[fr]=Explorer le Web
    94. Comment[gl]=Acceda a Internet
    95. Comment[gu]=ઇંટરનેટ ઍક્સેસ કરો
    96. Comment[he]=גישה לאינטרנט
    97. Comment[hi]=इंटरनेट तक पहुंच स्थापित करें
    98. Comment[hr]=Pristupite Internetu
    99. Comment[hu]=Az internet elérése
    100. Comment[id]=Akses Internet
    101. Comment[it]=Accesso a Internet
    102. Comment[ja]=インターネットにアクセス
    103. Comment[kn]=ಇಂಟರ್ನೆಟ್ ಅನ್ನು ಪ್ರವೇಶಿಸಿ
    104. Comment[ko]=인터넷에 연결합니다
    105. Comment[lt]=Interneto prieiga
    106. Comment[lv]=Piekļūt internetam
    107. Comment[ml]=ഇന്റര്നെറ്റ് ആക്സസ് ചെയ്യുക
    108. Comment[mr]=इंटरनेटमध्ये प्रवेश करा
    109. Comment[nb]=Gå til Internett
    110. Comment[nl]=Verbinding maken met internet
    111. Comment[or]=ଇଣ୍ଟର୍ନେଟ୍ ପ୍ରବେଶ କରନ୍ତୁ
    112. Comment[pl]=Skorzystaj z internetu
    113. Comment[pt]=Aceder à Internet
    114. Comment[pt_BR]=Acessar a internet
    115. Comment[ro]=Accesaţi Internetul
    116. Comment[ru]=Доступ в Интернет
    117. Comment[sk]=Prístup do siete Internet
    118. Comment[sl]=Dostop do interneta
    119. Comment[sr]=Приступите Интернету
    120. Comment[sv]=Surfa på Internet
    121. Comment[ta]=இணையத்தை அணுகுதல்
    122. Comment[te]=ఇంటర్నెట్ను ఆక్సెస్ చెయ్యండి
    123. Comment[th]=เข้าถึงอินเทอร์เน็ต
    124. Comment[tr]=İnternet'e erişin
    125. Comment[ug]=ئىنتېرنېتنى زىيارەت قىلىش
    126. Comment[uk]=Доступ до Інтернету
    127. Comment[vi]=Truy cập Internet
    128. Comment[zh_CN]=访问互联网
    129. Comment[zh_HK]=連線到網際網路
    130. Comment[zh_TW]=連線到網際網路
    131. Exec=env XDG_CURRENT_DESKTOP=KDE /usr/bin/chromium %U
    132. Terminal=false
    133. X-MultipleArgs=false
    134. Type=Application
    135. Icon=chromium
    136. Categories=Network;WebBrowser;
    137. MimeType=text/html;text/xml;application/xhtml_xml;application/x-mimearchive;x-scheme-handler/http;x-scheme-handler/https;
    138. StartupWMClass=chromium
    139. StartupNotify=true

py-subsrenamer: массовое переименование субтитров

Решил переписать на питоне башевый скрипт для переименования субтитров (согласно именам видеофайлов), чтобы можно было его использовать под виндой. Заодно оформил вариант с простеньким графическим интерфейсом (и немножко ознакомился с wxPython)

Скачать можно тут: https://github.com/qiwichupa/py-subsrenamer (экзешники смотреть тут)

Пример использования