From 9bbdb79b60527831e8f76569dc8dd24574906235 Mon Sep 17 00:00:00 2001 From: Spiros Georgaras Date: Fri, 22 Apr 2022 10:24:33 +0300 Subject: [PATCH] - Version 0.8.9.17 (0.9-beta13) - adding titles log - changing versioning --- Changelog | 8 ++ README.html | 51 ++++++++++- README.md | 48 ++++++++++ build.html | 17 +++- build.md | 14 ++- devel/build_install_pyradio | 82 ++++++++++------- devel/build_install_pyradio.bat | 6 +- devel/pre-commit | 9 +- pyradio.1 | 66 +++++++++++++- pyradio/__init__.py | 8 +- pyradio/common.py | 16 ++++ pyradio/config.py | 151 +++++++++++++++++++++++++++---- pyradio/config_window.py | 6 ++ pyradio/install.py | 126 ++++++++++++++++++-------- pyradio/log.py | 43 ++++++++- pyradio/main.py | 91 ++++++------------- pyradio/player.py | 12 ++- pyradio/radio.py | 82 +++++++++++++---- pyradio/simple_curses_widgets.py | 21 ++++- pyradio/win.py | 48 ++++++++++ pyradio_rb.1 | 5 +- radio-browser.html | 5 +- radio-browser.md | 2 + setup.py | 2 - windows-mplayer.html | 3 +- windows-mpv.html | 3 +- windows.html | 21 ++++- windows.md | 27 +++++- 28 files changed, 764 insertions(+), 209 deletions(-) diff --git a/Changelog b/Changelog index d9e0ffd4..1cb5391a 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,11 @@ +2022-04-29 s-n-g + * version 0.8.9.17 (0.9-beta13) + * adding Title's Log + * changing versioning + * fixing user isntallation in build_install_pyradio + * fixing python2 main.py crash (#153) + * updating docs + 2022-03-15 s-n-g * version 0.8.9.15 (0.9-beta12) * fixing "0" and "$" insertion on RadioBrowser search window diff --git a/README.html b/README.html index 9c37ec05..8af34c88 100644 --- a/README.html +++ b/README.html @@ -24,7 +24,7 @@ TD {text-align: left; vertical-align: top; padding: 5px 10px;border: 1px solid SaddleBrown;} pre { background-color: rgba(245, 245, 245, 1); color: #474747; padding: 1.5em; border: 1px solid #C7C7C7; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; overflow: auto; box-shadow: 5px 5px 15px #C7C7C7;} .task-list {list-style-type: none; padding: 0; margin: 0 0 0 1em ;} - img{display: block; margin-left: auto; margin-right: auto; max-width: 600px; width: 100%; background:transparent; padding:3px; border:1px solid #999999; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; box-shadow:5px 5px 15px #888888;} + img{display: block; margin-left: auto; margin-right: auto; max-width: 750; width: 100%; background:transparent; padding:3px; border:1px solid #999999; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; box-shadow:5px 5px 15px #888888;} a{ color: SaddleBrown;} a:visited{color: SaddleBrown;} @@ -39,6 +39,7 @@

PyRadio

Command line internet radio player.

Ben Dowling - https://github.com/coderholic

Pyradio +

Table of Contents Top

  • Mouse support
  • +
  • Titles logging +
  • Online radio directory services
  • Session Locking
  • Pyradio reduced to the “Limited display” +

    Note: These two modes do not work on Windows, either 7 or 10. The “Console”window will shrink as desired, but will not always notify PyRadio about it, so results will vary.

    Config file Top

    PyRadio upon its execution tries to read its configuration file (i.e. ~/.config/pyradio/config). If this file is not found, it will be created. If an error occurs while parsing it, an error message will be displayed and PyRadio will terminate.

    @@ -924,6 +938,7 @@

    CJK characters support

    The Line editor supports the insertion of CJK Unified Ideographs, as described on CJK Unified Ideographs (Unicode block) also known as URO, abbreviation of Unified Repertoire and Ordering. These characters, although encoded as a single code-point (character), actually take up a 2-character space, when rendered on the terminal.

    A depiction of the editor’s behavior can be seen at this image:

    CJK Characters on Pyradio +

    Moving stations around Top

    Rearranging the order of the stations in the playlist is another feature PyRadio offers.

    All you have to do is specify the source station (the station to be moved) and the position it will be moved to (target).

    @@ -1021,6 +1036,7 @@

    Using the command line

    Using the Configuration Window

    When the user uses the configuration window (shown in the following image), he is presented with an interface which will permit him to select the player to use with PyRadio and edit its extra parameters.

    PyRadio Player Selectio Window +

    Each of the supported players can have up to 11 sets of extra parameters (the first one is the default).

    The user can add (“a”) a new parameter, edit (“e”) an existing set and delete (“x” or “DEL”) one.

    Changing parameters set

    @@ -1071,6 +1087,7 @@

    Displaying Station Info PyRadio Station Info Window +

    If these two names are not identical, the user can press “r” to rename the station in the playlist using the “Reported Name”. This way an unknown station (when only the URL is known) can be correctly identified (after being inserted in a playlist with a dummy station name).

    Copying and pasting - Registers Top

    PyRadio takes the concept of registers from vim, and adapts their function to its own needs. So this is how it all works.

    @@ -1131,6 +1148,10 @@

    Mouse support All one has to do is enable mouse support in the “Config Window” (mouse support is disabled by default) and restart PyRadio for the change to take effect.

    Then, the mouse can be used as follows:

    ++++ @@ -1160,6 +1181,34 @@

    Mouse support

    Action
    +

    Titles logging Top

    +

    Version 0.8.9.17 adds to PyRadio the ability to log the titles displayed at the bottom of its window, in a log file, for refference.

    +

    The logger, which works independantly from the “degub” function, is actually a Rotating File Handler, configured to write up to 5 files of around 50KB each (parameters maxBytes=50000 and backupCount=5).

    +

    The way this works, according to the documenataion, is that one “can use the maxBytes and backupCount values to allow the file to rollover at a predetermined size. When the size is about to be exceeded, the file is closed and a new file is silently opened for output. Rollover occurs whenever the current log file is nearly maxBytes in length… When backupCount is non-zero, the system will save old log files by appending the extensions ‘.1’, ‘.2’ etc., to the filename. For example, with a backupCount of 5 and a base file name of app.log, you would get app.log, app.log.1, app.log.2, up to app.log.5. The file being written to is always app.log. When this file is filled, it is closed and renamed to app.log.1, and if files app.log.1, app.log.2, etc. exist, then they are renamed to app.log.2, app.log.3 etc. respectively.

    +

    The function can be enabled:

    +
      +
    1. using the -lt (--log-titles) command line parameter, or
    2. +
    3. by pressing “W” while in the Main, the Playlist or the Register mode.
    4. +
    +

    The titles are written in a file called pyradio-titles.log which is saved at PyRadio configuration directory.

    +

    Log file sample:

    +
    Apr 18 (Mon) 13:12 | >>> Station: Lounge (Illinois Street Lounge - SomaFM)
    +Apr 18 (Mon) 13:12 |     Jack Costanzo - La Cumparsa, Harlem Nocturne
    +Apr 18 (Mon) 13:14 |     Don Baker Trio - Third Man Theme
    +Apr 18 (Mon) 13:16 |     Gillian Hills - Un Petit Baiser
    +

    Tagging a title

    +

    An extra functionality is made possible because of “titles’s logging”: tagging a title (something like liking a song).

    +

    The idea is that the user plays a station and hears a song he likes and want to look it up later. With this functionality, he can tag the song (make a note in the log file), so he can refer to it at a later time.

    +

    To tag a title, one has to press the “w” key.

    +

    Then, if titles’s logging is already enabled, the log file will have an entry similar to the one shown below:

    +
    Apr 18 (Mon) 13:39 |     Tom Russell - Bus Station
    +Apr 18 (Mon) 13:40 |     Tom Russell - Bus Station (LIKED)
    +

    If title’s logging is not enabled, it will be turned on, the song will be tagged and logging will be turned off again:

    +
    Apr 18 (Mon) 15:38 | === Logging started
    +Apr 18 (Mon) 15:38 | >>> Station: Folk (Folk Forward - SomaFM)
    +Apr 18 (Mon) 15:38 |     Lord Huron - Lullaby
    +Apr 18 (Mon) 15:38 |     Lord Huron - Lullaby (LIKED)
    +Apr 18 (Mon) 15:38 | === Logging stopped

    Online radio directory services Top

    PyRadio supports the following Online radio directory services:

      diff --git a/README.md b/README.md index 3c8b86a4..159d28cc 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ Ben Dowling - [https://github.com/coderholic](https://github.com/coderholic) ![Pyradio](https://members.hellug.gr/sng/pyradio/pyradio.png) + ## Table of Contents @@ -47,6 +48,8 @@ Ben Dowling - [https://github.com/coderholic](https://github.com/coderholic) * [PyRadio Themes](#pyradio-themes) * [Using transparency](#using-transparency) * [Mouse support](#mouse-support) +* [Titles logging](#titles-logging) + * [Tagging a title](#tagging-a-title) * [Online radio directory services](#online-radio-directory-services) * [Session Locking](#session-locking) * [Session unlocking](#session-unlocking) @@ -744,6 +747,51 @@ Then, the mouse can be used as follows: | **Wheel** | Scroll up / down | | **Shift-Wheel** | Adjust volume
      (does not work with all terminals) | +## Titles logging + +Version **0.8.9.17** adds to **PyRadio** the ability to log the titles displayed at the bottom of its window, in a log file, for refference. + +The logger, which works independantly from the "*degub*" function, is actually a [Rotating File Handler](https://docs.python.org/3/library/logging.handlers.html#logging.handlers.RotatingFileHandler), configured to write up to 5 files of around 50KB each (parameters **maxBytes=50000** and **backupCount=5**). + +The way this works, according to the documenataion, is that one "can use the **maxBytes** and **backupCount** values to allow the file to rollover at a predetermined size. When the size is about to be exceeded, the file is closed and a new file is silently opened for output. Rollover occurs whenever the current log file is nearly **maxBytes** in length… When **backupCount** is non-zero, the system will save old log files by appending the extensions ‘.1’, ‘.2’ etc., to the filename. For example, with a backupCount of 5 and a base file name of **app.log**, you would get *app.log*, *app.log.1*, *app.log.2*, up to *app.log.5*. The file being written to is always **app.log**. When this file is filled, it is closed and renamed to *app.log.1*, and if files *app.log.1*, *app.log.2*, etc. exist, then they are renamed to *app.log.2*, *app.log.3* etc. respectively. + +The function can be enabled: + +1. using the `-lt` (`--log-titles`) command line parameter, or +2. by pressing "**W**" while in the **Main**, the **Playlist** or the **Register** mode. + +The titles are written in a file called `pyradio-titles.log` which is saved at **PyRadio** configuration directory. + +Log file sample: + +``` +Apr 18 (Mon) 13:12 | >>> Station: Lounge (Illinois Street Lounge - SomaFM) +Apr 18 (Mon) 13:12 | Jack Costanzo - La Cumparsa, Harlem Nocturne +Apr 18 (Mon) 13:14 | Don Baker Trio - Third Man Theme +Apr 18 (Mon) 13:16 | Gillian Hills - Un Petit Baiser +``` + +### Tagging a title + +An extra functionality is made possible because of "*titles's logging*": tagging a title (something like liking a song). + +The idea is that the user plays a station and hears a song he likes and want to look it up later. With this functionality, he can tag the song (make a note in the log file), so he can refer to it at a later time. + +To tag a title, one has to press the "**w**" key. + +Then, if titles's logging is already enabled, the log file will have an entry similar to the one shown below: + + Apr 18 (Mon) 13:39 | Tom Russell - Bus Station + Apr 18 (Mon) 13:40 | Tom Russell - Bus Station (LIKED) + +If title's logging is not enabled, it will be turned on, the song will be tagged and logging will be turned off again: + + Apr 18 (Mon) 15:38 | === Logging started + Apr 18 (Mon) 15:38 | >>> Station: Folk (Folk Forward - SomaFM) + Apr 18 (Mon) 15:38 | Lord Huron - Lullaby + Apr 18 (Mon) 15:38 | Lord Huron - Lullaby (LIKED) + Apr 18 (Mon) 15:38 | === Logging stopped + ## Online radio directory services **PyRadio** supports the following *Online radio directory services*: diff --git a/build.html b/build.html index cd05beb9..41e46204 100644 --- a/build.html +++ b/build.html @@ -24,7 +24,7 @@ TD {text-align: left; vertical-align: top; padding: 5px 10px;border: 1px solid SaddleBrown;} pre { background-color: rgba(245, 245, 245, 1); color: #474747; padding: 1.5em; border: 1px solid #C7C7C7; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; overflow: auto; box-shadow: 5px 5px 15px #C7C7C7;} .task-list {list-style-type: none; padding: 0; margin: 0 0 0 1em ;} - img{display: block; margin-left: auto; margin-right: auto; max-width: 600px; width: 100%; background:transparent; padding:3px; border:1px solid #999999; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; box-shadow:5px 5px 15px #888888;} + img{display: block; margin-left: auto; margin-right: auto; max-width: 750; width: 100%; background:transparent; padding:3px; border:1px solid #999999; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; box-shadow:5px 5px 15px #888888;} a{ color: SaddleBrown;} a:visited{color: SaddleBrown;} @@ -50,12 +50,14 @@

      Table of Contents <
    • Linux
    • macOS
    • Windows
    -
  • Performing the installation * Note for macOS users +
  • Performing the installation
  • @@ -80,6 +82,7 @@

    Linux

    Use your distribution method to install

    1. python-wheel
    2. +
    3. python-setuptools
    4. python-requests
    5. python-dnspython
    6. python-psutil
    7. @@ -94,9 +97,15 @@

      Notice for Python 2 users

      curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py
       sudo python[2] get-pip.py

      When you are done, proceed to “Performing the installation”.

      +

      Rasberry Pi installation

      +

      If installing on a Rasberry Pi, there are a couple of things you should be aware of:

      +
        +
      1. The default player will be MPlayer
      2. +
      3. If you still want to use MPV, please make sure you increase the Connection timeout value to at least 20 (sometimes even 30 for some machines). Even then, your machine may eventually crash, if it’s on the lower end of things and PyRadio is left running for hours.
      4. +

      macOS

      First thing you do is install python dependencies (assuming python 3 is installed):

      -
      pip3 install --upgrade wheel requests dnspython psutil
      +
      python3 -m pip install --upgrade wheel setuptools requests dnspython psutil

      Everything else you need to install and run pyradio is available on Homebrew. If you haven’t already downloaded its client, go ahead and do it.

      Open a terminal and type:

      /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
      @@ -133,7 +142,7 @@

      Performing the installation Note for macOS users

      +

      Note for macOS users

      This release of PyRadio has been tested on Catalina and Big Sur.

      On Catalina the executable has been placed on a location which is not directly accessible (not in the PATH). PyRadio will try to link it to your bin folder (creating ~/bin/pyradio), and PyRadio will be ready yo be executed, provided that this folder is in your PATH and that Homebrew default installation folders have been used during the installation of Python 3.

      In case a different Homebrew location has been used (or a different package manager, for this matter), you can just point the installation to the correct path, using the following command (post installation):

      diff --git a/build.md b/build.md index c383f012..9cebeba0 100644 --- a/build.md +++ b/build.md @@ -12,10 +12,11 @@ Ben Dowling - [https://github.com/coderholic](https://github.com/coderholic) * [Preparing for the installation](#preparing-for-the-installation) * [Linux](#linux) * [Notice for Python 2 users](#notice-for-python-2-users) + * [Rasberry Pi installation](#rasberry-pi-installation) * [macOS](#macos) * [Windows](#windows) * [Performing the installation](#performing-the-installation) - * [Note for macOS users](#note-for-macos-users) + * [Note for macOS users](#note-for-macos-users) * [Updating a pre 0.8.9 installation](#updating-a-pre-0.8.9-installation) @@ -51,6 +52,7 @@ Before installing **PyRadio** you have to prepare your system, so that you end u Use your distribution method to install 1. *python-wheel* +1. *python-setuptools* 2. *python-requests* 3. *python-dnspython* 4. *python-psutil* @@ -72,12 +74,18 @@ If your distro does not provide it (some do not anymore), use the following comm When you are done, proceed to "[Performing the installation](#performing-the-installation)". +#### Rasberry Pi installation + +If installing on a Rasberry Pi, there are a couple of things you should be aware of: + +1. The default player will be **MPlayer** +3. If you still want to use **MPV**, please make sure you increase the *Connection timeout* value to at least 20 (sometimes even 30 for some machines). Even then, your machine may eventually crash, if it's on the lower end of things and **PyRadio** is left running for hours. ### macOS First thing you do is install python dependencies (assuming python 3 is installed): - pip3 install --upgrade wheel requests dnspython psutil + python3 -m pip install --upgrade wheel setuptools requests dnspython psutil Everything else you need to install and run **pyradio** is available on [Homebrew](https://github.com/Homebrew/homebrew). If you haven't already downloaded its client, go ahead and do it. @@ -149,7 +157,7 @@ If for some reason you want a **python 2** installation, execute: python2 install.py -#### Note for macOS users +### Note for macOS users This release of **PyRadio** has been tested on **Catalina** and **Big Sur**. diff --git a/devel/build_install_pyradio b/devel/build_install_pyradio index 2582aa30..f707cc20 100755 --- a/devel/build_install_pyradio +++ b/devel/build_install_pyradio @@ -54,13 +54,37 @@ done < /tmp/pyradio-delete.$$ rm -f /tmp/pyradio-uninstall.$$ /tmp/pyradio-delete.$$ 2>/dev/null } +function remove_pip_sudo_install(){ + sudo python -m pip uninstall -y pyradio 2>/dev/null 1>&2 + sudo python2 -m pip uninstall -y pyradio 2>/dev/null 1>&2 + sudo python3 -m pip uninstall -y pyradio 2>/dev/null 1>&2 +} -function remove_pip_install(){ +function uninstall(){ + echo 'Uninstalling PyRadio' + echo -n ' ** Removing python files ... ' python -m pip uninstall -y pyradio 2>/dev/null 1>&2 python2 -m pip uninstall -y pyradio 2>/dev/null 1>&2 + python3 -m pip uninstall -y pyradio 2>/dev/null 1>&2 + echo 'done' + echo -n ' ** Removing help files ... ' + if [ -d ~/.local/share/doc/pyradio ];then + rm -rf ~/.local/share/doc/pyradio 2>/dev/null + else + rm -rf ~/.local/local/share/doc/pyradio 2>/dev/null + fi + rm -f ~/.local/share/man/man1/pyradio*gz 2>/dev/null + echo 'done' + if [ $(uname -s) = "Darwin" ] || [ $(uname -s) = "darwin" ];then + # delete link on mac + echo -n ' ** Removing link to executable ... ' + [ -h ~/bin/pyradio ] && rm ~/bin/pyradio 2>/dev/null + echo 'done' + fi + echo "PyRadio successfully uninstalled" } -function uninstall(){ +function uninstall_sudo(){ local user [ -z "$1" ] && { user=$(which pyradio 2>/dev/null) || { @@ -68,7 +92,6 @@ function uninstall(){ exit } } - # keep this sudo as to not break lines sudo echo 'Uninstalling PyRadio' echo -n ' ** Removing executable ... ' sudo rm -f `which pyradio 2>/dev/null` 2>/dev/null @@ -77,21 +100,14 @@ function uninstall(){ else sudo rm -rf /usr/local/share/doc/pyradio 2>/dev/null fi - if [ -d ~/.local/share/doc/pyradio ];then - rm -rf ~/.local/share/doc/pyradio 2>/dev/null - else - rm -rf ~/.local/local/share/doc/pyradio 2>/dev/null - fi echo done echo -n ' ** Removing help files ... ' sudo rm -f /usr/share/man/man1/pyradio.1.gz 2>/dev/null || sudo rm -f /usr/local/share/man/man1/pyradio.1.gz 2>/dev/null sudo rm -f /usr/share/man/man1/pyradio_rb.1.gz 2>/dev/null || sudo rm -f /usr/local/share/man/man1/pyradio_rb.1.gz 2>/dev/null - rm -f ~/.local/share/man/man1/pyradio.1.gz 2>/dev/null - rm -f ~/.local/share/man/man1/pyradio_rb.1.gz 2>/dev/null echo done #set -x remove_paths - remove_pip_install + remove_pip_sudo_install if [ $(uname -s) = "Darwin" ] || [ $(uname -s) = "darwin" ];then # delete link on mac [ -h ~/bin/pyradio ] && rm ~/bin/pyradio 2>/dev/null @@ -99,15 +115,6 @@ function uninstall(){ echo "PyRadio successfully uninstalled" } -function create_bdist(){ - rm -rf build pyradio.egg-info dist debian 2>/dev/null - python3 setup.py bdist || { - echo "Error creating bdist" - exit 1 - } - -} - function get_cur_version(){ cur_version=$(grep 'version_info = ' pyradio/__init__.py | sed 's/version_info = (//;s/, /./g;s/)//') cur_state=$(grep 'app_state = ' pyradio/__init__.py | sed "s/app_state = //;s/'//g") @@ -118,8 +125,18 @@ function get_cur_version(){ function do_dev(){ if [ -z "${NO_DEV}" ] then - cp pyradio/config.py pyradio/config.py.dev - sed -i "s/git_description = ''/git_description = '$DEVEL'/" pyradio/config.py + [ -z "$DEVEL" ] && { + rm pyradio/config.pydev 2>/dev/null + return + } + sed -idev "s/git_description = ''/git_description = '$DEVEL'/" pyradio/config.py + fi +} + +function do_undev(){ + if [ -e pyradio/config.pydev ] + then + mv pyradio/config.pydev pyradio/config.py fi } @@ -130,7 +147,7 @@ function do_exit(){ [ "$REMOVE_DIR" = "$HOME/tmp-pyradio" ] || \ [ "$REMOVE_DIR" = "/tmp/pyradio" ] || \ [ "$REMOVE_DIR" = "/tmp/tmp-pyradio" ];then - sudo rm -fr "$REMOVE_DIR" + rm -fr "$REMOVE_DIR" fi fi } @@ -337,13 +354,14 @@ do done set -- "${POSITIONAL[@]}" # restore positional parameters -if [ -z "$NO_DEV" ] -then - cd pyradio - DEVEL=$(python -c 'from install import get_devel_version; print(get_devel_version())') - echo "Devel version: $DEVEL" - cd .. -fi +# if [ -z "$NO_DEV" ] +# then +# cd pyradio +# DEVEL=$(python -c 'from install import get_github_long_description_for_script; get_github_long_description_for_script()') +# # DEVEL=$(python -c 'from install import get_devel_version; print(get_devel_version())') +# echo "Devel version: $DEVEL" +# cd .. +# fi if [ $(uname -s) = "Darwin" ] || [ $(uname -s) = "darwin" ];then @@ -401,9 +419,11 @@ else python"${TO_PYTHON}" -m pip install . fi +do_undev + if [ $? -eq 0 ] then - [ -z "${NO_DEV}" ] && mv pyradio/config.py.dev pyradio/config.py + [ -z "${NO_DEV}" ] && [ -e pyradio/config.py.dev ] && mv pyradio/config.py.dev pyradio/config.py gzip -k pyradio.1 gzip -k pyradio_rb.1 mkdir -p ~/.local/share/man/man1 2>/dev/null diff --git a/devel/build_install_pyradio.bat b/devel/build_install_pyradio.bat index 811e9d41..5757411b 100644 --- a/devel/build_install_pyradio.bat +++ b/devel/build_install_pyradio.bat @@ -49,12 +49,14 @@ FOR /f "delims=" %%i IN ('ECHO %DESKTOP%') DO SET DESKTOP=%%i SET ALL=0 IF "%1"=="-u" GOTO uninstall IF "%1"=="-R" GOTO uninstall +REM Do not run uninstall while installing IF "%1"=="-U" ( SET ALL=1 - GOTO uninstall + REM GOTO uninstall ) IF "%1"=="" GOTO noparam -SET "PROGRAM=python%arg1%" +IF "%arg1%" == "2" SET "PROGRAM=python%arg1%" +IF "%arg1%" == "3" SET "PROGRAM=python%arg1%" :noparam CLS diff --git a/devel/pre-commit b/devel/pre-commit index e82f3a8b..b8abae3a 100755 --- a/devel/pre-commit +++ b/devel/pre-commit @@ -52,7 +52,7 @@ do echo '% PyRadio RadioBrowser Implementation' > tmp.md fi cat ${afile} >> tmp.md - pandoc -s -t html tmp.md -o ${out} || { + pandoc --wrap=none -s -t html tmp.md -o ${out} || { echo "Error: pandoc not found" rm tmp.md exit 1 @@ -83,7 +83,7 @@ do TD {text-align: left; vertical-align: top; padding: 5px 10px;border: 1px solid SaddleBrown;} \ pre { background-color: rgba(245, 245, 245, 1); color: #474747; padding: 1.5em; border: 1px solid #C7C7C7; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; overflow: auto; box-shadow: 5px 5px 15px #C7C7C7;} \ .task-list {list-style-type: none; padding: 0; margin: 0 0 0 1em ;} \ - img{display: block; margin-left: auto; margin-right: auto; max-width: 600px; width: 100%; background:transparent; padding:3px; border:1px solid #999999; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; box-shadow:5px 5px 15px #888888;} \ + img{display: block; margin-left: auto; margin-right: auto; max-width: 750; width: 100%; background:transparent; padding:3px; border:1px solid #999999; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; box-shadow:5px 5px 15px #888888;} \ ' ${out} sed -i -e 's///g' \ -e 's{{{g' \ @@ -117,7 +117,10 @@ do -e 's|<.strong><.sup>W<.strong>|^W|' \ "$out" fi - + #sed -i "/^alt=/d" ${out} + # sed -i '/
      /d' ${out} + sed -i 's/\.md/.html/' ${out} diff --git a/pyradio.1 b/pyradio.1 index 25bfaa7e..27c3050d 100644 --- a/pyradio.1 +++ b/pyradio.1 @@ -1,7 +1,7 @@ .\" Copyright (C) 2011 Ben Dowling .\" This manual is freely distributable under the terms of the GPL. .\" -.TH pyradio 1 "March 2022" PyRadio +.TH pyradio 1 "April 2022" PyRadio .SH Name .PP @@ -849,6 +849,70 @@ Adjust volume (does not work with all terminals) .RE +.SH Titles logging + +Version \fB0.8.9.17\fR adds to \fBpyradio\fR the ability to log the titles displayed at the bottom of its window, in a log file, for refference. + +The logger, which works independantly from the "\fIdegub\fR" function, is actually a \fIRotating File Handler\fR (\fIhttps://docs.python.org/3/library/logging.handlers.html#logging.handlers.RotatingFileHandler\fR), configured to write up to 5 files of around 50KB each (parameters \fBmaxBytes=50000\fR and \fBbackupCount=5\fR). + +The way this works, according to the documenataion, is that one "can use the \fBmaxBytes\fR and \fBbackupCount\fR values to allow the file to rollover at a predetermined size. When the size is about to be exceeded, the file is closed and a new file is silently opened for output. Rollover occurs whenever the current log file is nearly \fBmaxBytes\fR in length… When \fBbackupCount\fR is non-zero, the system will save old log files by appending the extensions ‘.1’, ‘.2’ etc., to the filename. For example, with a backupCount of 5 and a base file name of \fBapp.log\fR, you would get \fIapp.log\fR, \fIapp.log.1\fR, \fIapp.log.2\fR, up to \fIapp.log.5\fR. The file being written to is always \fBapp.log\fR. When this file is filled, it is closed and renamed to \fIapp.log.1\fR, and if files \fIapp.log.1\fR, \fIapp.log.2\fR, etc. exist, then they are renamed to \fIapp.log.2\fR, \fIapp.log.3\fR etc. respectively. + +The function can be enabled: + +.RS 5 +.IP 1. 3 +using the \fI-lt\fR (\fI--log-titles\fR) command line parameter, or + +.IP 2. 3 +by pressing "\fBW\fR" while in the \fBMain\fR, the \fBPlaylist\fR or the \fBRegister\fR mode. + +.RE + +The titles are written in a file called \fIpyradio-titles.log\fR which is saved at \fBpyradio\fR configuration directory. + +Log file sample: + +.RS 5 +\fIApr 18 (Mon) 13:12 | >>> Station: Lounge (Illinois Street Lounge - SomaFM) +.br +Apr 18 (Mon) 13:12 | Jack Costanzo - La Cumparsa, Harlem Nocturne +.br +Apr 18 (Mon) 13:14 | Don Baker Trio - Third Man Theme +.br +Apr 18 (Mon) 13:16 | Gillian Hills - Un Petit Baiser +\fR +.RE + +\fBTagging a title\fR + +An extra functionality is made possible because of "\fItitles's logging\fR": tagging a title (something like liking a song). + +The idea is that the user plays a station and hears a song he likes and want to look it up later. With this functionality, he can tag the song (make a note in the log file), so he can refer to it at a later time. + +To tag a title, one has to press the "\fBw\fR" key. + +Then, if titles's logging is already enabled, the log file will have an entry similar to the one shown below: + +.RS 5 +\fIApr 18 (Mon) 13:39 | Tom Russell - Bus Station +.br +Apr 18 (Mon) 13:40 | Tom Russell - Bus Station (LIKED)\fR +.RE + +If title's logging is not enabled, it will be turned on, the song will be tagged and logging will be turned off again: + +.RS 5 +\fIApr 18 (Mon) 15:38 | === Logging started +.br +Apr 18 (Mon) 15:38 | >>> Station: Folk (Folk Forward - SomaFM) +.br +Apr 18 (Mon) 15:38 | Lord Huron - Lullaby +.br +Apr 18 (Mon) 15:38 | Lord Huron - Lullaby (LIKED) +.br +Apr 18 (Mon) 15:38 | === Logging stopped\fR +.RE + .SH Online Radio Directory Services \fBPyRadio\fR supports the following \fIOnline Radio Directory services\fR: diff --git a/pyradio/__init__.py b/pyradio/__init__.py index 718b3c16..94ceb3d1 100644 --- a/pyradio/__init__.py +++ b/pyradio/__init__.py @@ -1,12 +1,6 @@ " pyradio -- Console radio player. " -version_info = (0, 8, 9, 16) - -# Application state: -# New stable version: '' -# Beta version: 'betax', x=1,2,3... -# RC version: 'RCx', x=1,23... -app_state = '' +version_info = (0, 8, 9, 17) # Set it to True if new stations have been # added to the package's stations.csv diff --git a/pyradio/common.py b/pyradio/common.py index 7f2e80aa..ad2d61f4 100644 --- a/pyradio/common.py +++ b/pyradio/common.py @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- +import io +from os.path import exists """ Theming constants """ def FOREGROUND(): return 0 @@ -44,3 +46,17 @@ def erase_curses_win(self, Y, X, beginY, beginX, char=' ', color=5): empty_win.erase() empty_win.refresh() +def is_rasberrypi(): + ''' Try to detest rasberry pi ''' + try: + with io.open('/sys/firmware/devicetree/base/model', 'r') as m: + if 'raspberry pi' in m.read().lower(): + return True + except Exception: + pass + return False + + # if exists('/usr/bin/raspi-config'): + # return True + # return False + diff --git a/pyradio/config.py b/pyradio/config.py index 7fc41c80..f0952924 100644 --- a/pyradio/config.py +++ b/pyradio/config.py @@ -12,10 +12,11 @@ from shutil import copyfile, move import threading from copy import deepcopy -from pyradio import version, app_state, stations_updated +from pyradio import version, stations_updated from .browser import PyRadioStationsBrowser, probeBrowsers from .install import get_github_long_description +from .common import is_rasberrypi HAS_REQUESTS = True try: import requests @@ -1085,6 +1086,14 @@ class PyRadioConfig(PyRadioStations): theme_has_error = False theme_not_supported_notification_shown = False + log_titles = False + log_degub = False + + ''' Titles logging ''' + _current_log_title = _current_log_station = '' + _old_log_title = _old_log_station = '' + _last_liked_title = '' + ''' True if lock file exists ''' locked = False @@ -1182,6 +1191,8 @@ def __init__(self): self.config_file = path.join(self.stations_dir, 'config') self.force_to_remove_lock_file = False + self.titles_log = PyRadioLog(self) + #self.titles_log = PyRadioLog(self.stations_dir) @property def open_last_playlist(self): @@ -1433,16 +1444,17 @@ def get_pyradio_version(self): The version to use when checking for updates ''' ret = None - if app_state: - self.info = " PyRadio {0}-{1} ".format(version, app_state) - else: - self.info = " PyRadio {0} ".format(version) - ''' git_description can be set at build time - if so, revision will be shown along with the version - ''' - # if revision is not 0 - git_description = 'PyRadio 0.8.9.14' - if git_description: + self.info = " PyRadio {0} ".format(version) + ''' git_description can be set at build time + if so, revision will be shown along with the version + ''' + # if revision is not 0 + git_description = '' + if git_description: + git_info = git_description.split('-') + if logger.isEnabledFor(logging.DEBUG): + logger.debug('versrion = {0} - git_info = {1}'.format(version, git_info)) + if git_info[0] == version: if git_description.endswith('-git') or \ git_description.endswith('-sng') or \ git_description.endswith('-dev'): @@ -1452,17 +1464,18 @@ def get_pyradio_version(self): self.info = ' ' + git_description ret = self.info + " (development version)" else: - git_info = git_description.split('-') try: - if git_info[1] != '0': - if 'beta' in git_info[1] or 'rc' in git_info[1].lower(): - self.info = " PyRadio {1}-{1}".format(git_info[0], git_info[1]) - ret = "RyRadio built from git: https://github.com/coderholic/pyradio/commit/{0} (rev. {1})".format(git_info[-1], git_info[2]) - else: - self.info = " PyRadio {0}-r{1} ".format(version, git_info[1]) - ret = "RyRadio built from git: https://github.com/coderholic/pyradio/commit/{0} (rev. {1})".format(git_info[-1], git_info[1]) + if git_info[1] == '0': + self.info = " PyRadio {}".format(git_info[0]) + ret = 'PyRadio built from git master branch' + else: + self.info = " PyRadio {0}-r{1}".format(git_info[0], git_info[1]) + ret = "RyRadio built from git: https://github.com/coderholic/pyradio/commit/{0} (rev. {1})".format(git_info[-1], git_info[1]) except: pass + else: + self.info = " PyRadio {}".format(version) + ret = '' self.current_pyradio_version = self.info.replace(' PyRadio ', '').replace(' ', '') # if self._distro != 'None': # self.info += '({})'.format(self._distro) @@ -1586,7 +1599,20 @@ def _check_config_file(self, usr): ''' Copy package config into user dir ''' if not path.exists(user_config_file): - copyfile(package_config_file, user_config_file) + if is_rasberrypi(): + self._convert_config_for_rasberrypi(package_config_file, user_config_file) + else: + copyfile(package_config_file, user_config_file) + + def _convert_config_for_rasberrypi(self, package_config_file, user_config_file): + lines = [] + with open(package_config_file, 'r') as f: + lines = [line.strip() for line in f] + for i in range(len(lines)): + if lines[i].startswith('player'): + lines[i] = 'player = mplayer,vlc,mpv' + with open(user_config_file, 'w') as f: + f.write('\n'.join(lines) + '\n') def read_config(self): lines = [] @@ -2042,6 +2068,9 @@ def read_playlist_file( is_last_playlist=is_last_playlist, is_register=is_register) + def can_like_a_station(self): + return True if self._current_log_title != self._last_liked_title else False + class PyRadioPlaylistStack(object): @@ -2295,3 +2324,85 @@ def replace(self, a_search_path, new_item): self._p[i] = list(new_item[:]) ret += 1 return ret + + +class PyRadioLog(object): + + PATTERN = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' + PATTERN_TITLE = '%(asctime)s | %(message)s' + + log_titles = log_debug = False + + titles_handler = debug_handler = None + + def __init__(self, pyradio_config): + self._cnf = pyradio_config + self._stations_dir = pyradio_config.stations_dir + + def configure_logger(self, debug=None, titles=None): + logger = logging.getLogger('pyradio') + logger.setLevel(logging.DEBUG) + if debug or titles: + if debug and not self.log_debug: + # Handler + self.debug_handler = logging.FileHandler(path.join(path.expanduser('~'), 'pyradio.log')) + self.debug_handler.setLevel(logging.DEBUG) + + # create formatter + formatter = logging.Formatter(self.PATTERN) + + # add formatter to ch + self.debug_handler.setFormatter(formatter) + + # add ch to logger + #l = logging.getLogger() + logger.addHandler(self.debug_handler) + + # inform config + self.log_degub = True + + if titles and not self.log_titles: + self.titles_handler = logging.handlers.RotatingFileHandler( + path.join( + self._stations_dir, + 'pyradio-titles.log'), + maxBytes=50000, + backupCount=5) + self.titles_handler.setFormatter(logging.Formatter( + fmt=self.PATTERN_TITLE, + datefmt='%b %d (%a) %H:%M') + ) + self.titles_handler.setLevel(logging.CRITICAL) + #l = logging.getLogger() + logger.addHandler(self.titles_handler) + self.log_titles = True + logger.critical('=== Logging started') + + if (not titles) and self.log_titles: + if self.titles_handler: + logger.critical('=== Logging stopped') + logger.removeHandler(self.titles_handler) + self.log_titles = False + self.titles_handler = None + + logging.raiseExceptions = False + logging.lastResort = None + + def tag_title(self, the_log): + ''' tags a title + + Returns: + 0: All ok + 1: Error + 2: Already tagged + ''' + if self._cnf.can_like_a_station(): + if logger.isEnabledFor(logging.CRITICAL): + try: + the_log._write_title_to_log() + except: + return 1 + return 0 + return 2 + + diff --git a/pyradio/config_window.py b/pyradio/config_window.py index 8a17526b..c1c27fdd 100644 --- a/pyradio/config_window.py +++ b/pyradio/config_window.py @@ -196,8 +196,11 @@ def _print_title(self): self._old_theme == self._saved_config_options['theme'][1] and \ self._old_use_transparency == self._saved_config_options['use_transparency'][1] and not self._cnf.params_changed: dirty_title = '─ ' + self._cnf.dirty_config = False else: dirty_title = ' *' + logger.error('>>> setting dirty title') + self._cnf.dirty_config = True X = int((self.maxX - len(self._title) - 1) / 2) try: self._win.addstr(0, X, dirty_title, curses.color_pair(3)) @@ -215,6 +218,7 @@ def _print_title(self): pass def refresh_selection(self): + logger.error('start of refresh_selection, dirty config = {}'.format(self._cnf.dirty_config)) self._print_title() if not self.too_small: for i, it in enumerate(list(self._config_options.values())): @@ -240,6 +244,7 @@ def refresh_selection(self): else: if it[1] != '-': self._win.addstr('{}'.format(it[1][:self._second_column - len(it[0]) - 6]), hcol) + logger.error('end of refresh_selection, dirty config = {}'.format(self._cnf.dirty_config)) self._win.refresh() def _get_col_line(self, ind): @@ -438,6 +443,7 @@ def keypress(self, char): self._win.nodelay(False) if char == -1: ''' ESCAPE ''' + logger.error('dirty config is {}, and ESC pressed'.format(self._cnf.dirty_config)) #self._config_options['theme'][1] = self._old_theme self._saved_config_options['theme'][1] = self._old_theme self._cnf.opts['theme'][1] = self._old_theme diff --git a/pyradio/install.py b/pyradio/install.py index 7ad953a1..a2ac4faa 100644 --- a/pyradio/install.py +++ b/pyradio/install.py @@ -35,6 +35,11 @@ # import logging # logger = logging.getLogger(__name__) +''' This is PyRadio version this + install.py was released for +''' +PyRadioInstallPyReleaseVersion = '0.8.9.16' + def print_pyradio_on(): print(''' _____ _____ _ _ @@ -167,8 +172,16 @@ def version_string_to_list(this_version): # logger.error('DE a_n_l = "{}"'.format(a_n_l)) return a_n_l +def get_github_long_description_for_script(): + ret = get_github_long_description() + if ret[1]: + print(ret[1]) + else: + print('') + def get_github_long_description( only_tag_name=False, + devel=False, use_sng_repo=False, sng_branch=False, do_not_exit=False @@ -269,14 +282,25 @@ def get_github_long_description( # print('\n\n' + tag_name) # print(tag_hash) + # print(str(use_sng_repo)) + # revision=15 # print(revision) if revision > 0: - this_version = tag_name + '-r' + str(revision) + '-' + returns[0][0]['sha'][:7] + if devel: + ''' coderholic devel branch + currently it does not exist + ''' + this_version = tag_name + '-r' + str(revision) + '-' + returns[0][0]['sha'][:8] + '-dev' + else: + ''' coderholic master branch ''' + this_version = tag_name + '-' + str(revision) + '-' + returns[0][0]['sha'][:8] if use_sng_repo: - this_version += '-sng' - if not sng_branch: - this_version += '-dev' + ''' sng repo ''' + this_version = tag_name + '-r' + str(revision) + '-' + returns[0][0]['sha'][:8] + '-sng' + if not sng_branch: + ''' sng devel branch ''' + this_version += '-dev' else: this_version = None @@ -310,19 +334,20 @@ def get_devel_version(): def windows_put_devel_version(): ''' not used ''' - long_descr = get_devel_version() - from shutil import copyfile - cur_dir = os.getcwd() - copyfile(os.path.join(cur_dir, 'config.py'), os.path.join(cur_dir, 'config.py.dev')) - try: - with open(os.path.join(cur_dir, 'config.py'), 'r') as con: - lines = con.read() - lines = lines.replace("git_description = ''", "git_description = '" + long_descr + "'") - with open(os.path.join(cur_dir, 'config.py'), 'w') as con: - con.write(lines) - except: - print('Error: Cannot change downloaded files...\n Please close all running programs and try again.') - sys.exit(1) + long_descr = get_github_long_description()[1] + if long_descr: + from shutil import copyfile + cur_dir = os.getcwd() + copyfile(os.path.join(cur_dir, 'config.py'), os.path.join(cur_dir, 'config.py.dev')) + try: + with open(os.path.join(cur_dir, 'config.py'), 'r') as con: + lines = con.read() + lines = lines.replace("git_description = ''", "git_description = '" + long_descr + "'") + with open(os.path.join(cur_dir, 'config.py'), 'w') as con: + con.write(lines) + except: + print('Error: Cannot change downloaded files...\n Please close all running programs and try again.') + sys.exit(1) def WindowExists(title): ''' fixing #146 ''' @@ -578,7 +603,8 @@ def update_or_uninstall_on_windows(self, mode='update', from_pyradio=False, firs b.write('cd "' + os.path.join(self._dir, self.ZIP_DIR[self._package]) + '"\n') b.write('IF EXIST C:\\Users\\Spiros\\pyradio (\n') - b.write('COPY C:\\Users\\Spiros\\pyradio\\pyradio\\*.py pyradio\n') + b.write('COPY C:\\Users\\Spiros\\pyradio\\pyradio\\install.py pyradio\n') + # b.write('COPY C:\\Users\\Spiros\\pyradio\\pyradio\\*.py pyradio\n') b.write('COPY C:\\Users\\Spiros\\pyradio\\devel\\*.bat devel\n') b.write(')\n') @@ -602,7 +628,8 @@ def update_or_uninstall_on_windows(self, mode='update', from_pyradio=False, firs b.write('cd "' + os.path.join(self._dir, self.ZIP_DIR[self._package]) + '"\n') b.write('IF EXIST C:\\Users\\Spiros\\pyradio (\n') - b.write('COPY C:\\Users\\Spiros\\pyradio\\pyradio\\*.py pyradio\n') + b.write('COPY C:\\Users\\Spiros\\pyradio\\pyradio\\install.py pyradio\n') + # b.write('COPY C:\\Users\\Spiros\\pyradio\\pyradio\\*.py pyradio\n') b.write('COPY C:\\Users\\Spiros\\pyradio\\devel\\*.bat devel\n') b.write(')\n') @@ -631,8 +658,12 @@ def open_windows_dir(self): os.startfile(self._dir) def _no_download_method(self): - print('Error: PyRadio has no way to download files...') - print(' Please either install python\'s "requests" module and try again.\n') + if platform.system().lower().startswith('darwin'): + subprocess.call('python3 -m pip install requests', shell=True) + print('\n\nPyradio has installed the minimum necessary modules for its execution\nPlease execute the same command again...') + else: + print('Error: PyRadio has no way to download files...') + print(' Please install python\'s "requests" module and try again.\n') sys.exit(1) def _do_it(self, mode='update'): @@ -640,7 +671,7 @@ def _do_it(self, mode='update'): self._no_download_method() ''' Am I root ?''' - self._prompt_sudo() + #self._prompt_sudo() '''' get tmp dir ''' if os.path.isdir('/tmp'): @@ -676,10 +707,10 @@ def _do_it(self, mode='update'): ''' install pyradio ''' if self.user: param += ' --user' - ret = subprocess.call('sudo devel/build_install_pyradio -no-dev -x ' + self._python_exec.python + ' ' + param, shell=True) + ret = subprocess.call('devel/build_install_pyradio -no-dev -x ' + self._python_exec.python + ' ' + param, shell=True) else: ''' uninstall pyradio ''' - ret = subprocess.call('sudo devel/build_install_pyradio -no-dev -x ' + self._python_exec.python + ' -R' + param, shell=True) + ret = subprocess.call('devel/build_install_pyradio -no-dev -x ' + self._python_exec.python + ' -R' + param, shell=True) if ret > 0: ret = False else: @@ -734,14 +765,20 @@ def _download_pyradio(self): ''' from shutil import copyfile cur_dir = os.getcwd() - print('\n\n{}\n\n'.format(os.path.join(self._dir, self.ZIP_DIR[self._package]))) - print(cur_dir) - copyfile('/home/spiros/projects/my-gits/pyradio/pyradio/install.py', + copyfile('/Users/max/pyradio/pyradio/install.py', os.path.join(cur_dir, 'install.py')) - copyfile('/home/spiros/projects/my-gits/pyradio/devel/build_install_pyradio', \ - os.path.join(os.path.join(self._dir, self.ZIP_DIR[self._package], - 'devel', 'build_install_pyradio')) - ) + #copyfile('/Users/max/pyradio/devel/build_install_pyradio', \ + # os.path.join(os.path.join(self._dir, self.ZIP_DIR[self._package], + # 'devel', 'build_install_pyradio')) + #) + #print('\n\n{}\n\n'.format(os.path.join(self._dir, self.ZIP_DIR[self._package]))) + #print(cur_dir) + #copyfile('/home/spiros/projects/my-gits/pyradio/pyradio/install.py', + # os.path.join(cur_dir, 'install.py')) + #copyfile('/home/spiros/projects/my-gits/pyradio/devel/build_install_pyradio', \ + # os.path.join(os.path.join(self._dir, self.ZIP_DIR[self._package], + # 'devel', 'build_install_pyradio')) + #) # copyfile('/home/spiros/projects/my-gits/pyradio/pyradio/config.py', # os.path.join(self._dir, self.ZIP_DIR[self._package], 'pyradio', 'config.py')) ''' @@ -897,7 +934,7 @@ def _do_it(self, mode='update'): #exe = find_pyradio_win_exe() #print(exe) #sys.exit() - # l=get_github_long_description(use_sng_repo=True) + # l=get_github_long_description() # print(l) # print(get_devel_version()) # sys.exit() @@ -947,6 +984,14 @@ def _do_it(self, mode='update'): sys.stdout.flush() if platform.system().lower().startswith('darwin'): + ''' get python version ''' + if sys.version_info < (3, 0): + print('Error: Python 2 is not supported any more!') + print(' Please install Python 3 and execute the command:') + print('\n python3 install.py') + print('\n to install PyRadio.\n\n') + sys.exit(1) + if args.brew != "False": if args.brew is None: param = ' --fix-mac-path' @@ -994,18 +1039,20 @@ def _do_it(self, mode='update'): args.force = True package = 1 VERSION, github_long_description = get_github_long_description(use_sng_repo=True, sng_branch=True) - if not github_long_description: - github_long_description = 'PyRadio' - github_long_description = github_long_description.replace('-', '-r', 1) + # if not github_long_description: + # github_long_description = 'PyRadio' + # if github_long_description: + # github_long_description = github_long_description.replace('-', '-r', 1) # github_long_description += '-sng' elif args.sng_devel: '''' sng devel ''' args.force = True package = 2 VERSION, github_long_description = get_github_long_description(use_sng_repo=True) - if not github_long_description: - github_long_description = 'PyRadio' - github_long_description = github_long_description.replace('-', '-r', 1) + # if not github_long_description: + # github_long_description = 'PyRadio' + # id github_long_description: + # github_long_description = github_long_description.replace('-', '-r', 1) # github_long_description += '-sng-dev' elif args.devel: ''' official devel ''' @@ -1022,6 +1069,9 @@ def _do_it(self, mode='update'): else: VERSION = get_github_tag() + if VERSION is None: + VERSION = PyRadioInstallPyReleaseVersion + if args.uninstall: if platform.system().lower().startswith('win'): ''' ok, create BAT file on Windows''' diff --git a/pyradio/log.py b/pyradio/log.py index cc21ce07..6df163ca 100644 --- a/pyradio/log.py +++ b/pyradio/log.py @@ -27,7 +27,9 @@ class Log(object): _show_status_updates = False - def __init__(self): + + def __init__(self, config): + self._cnf = config self.width = None def setScreen(self, cursesScreen): @@ -111,6 +113,7 @@ def write(self, ''' update main message ''' if self.msg: self.cursesScreen.erase() + d_msg = '' try: d_msg = self.msg.strip()[0: self.width].replace('\r', '').replace('\n', '') self.cursesScreen.addstr(0, 1, d_msg) @@ -122,6 +125,7 @@ def write(self, pass # if logger.isEnabledFor(logging.ERROR): # logger.error('Error updating the Status Bar') + self._write_title_to_log(d_msg) if self._show_status_updates: if logger.isEnabledFor(logging.DEBUG): try: @@ -212,3 +216,40 @@ def write(self, def readline(self): pass + + def _write_title_to_log(self, msg=None, force=False): + if msg is None: + d_msg = None + else: + d_msg = msg.replace('[Muted] ', '') + if d_msg is None and self._cnf._current_log_title: + try: + logger.critical(self._cnf._current_log_title.replace('Title: ', ' ') + ' (LIKED)') + self._cnf._last_liked_title = self._cnf._current_log_title + except: + logger.critical('Error writing LIKED title...') + elif d_msg.startswith('Title: '): + if logger.isEnabledFor(logging.CRITICAL): + if force or not d_msg in self._cnf._old_log_title: + try: + logger.critical(d_msg.replace('Title: ', ' ')) + except: + logger.critical('Error writing title...') + self._cnf._old_log_title = d_msg + self._cnf._current_log_title = d_msg + elif d_msg.startswith('Playing: '): + if logger.isEnabledFor(logging.CRITICAL): + if force or not d_msg in self._cnf._old_log_station: + try: + logger.critical(d_msg.replace('Playing: ', '>>> Station: ')) + except: + logger.critical('Error writing station name...') + self._cnf._old_log_station = d_msg + self._cnf._current_log_station = d_msg + + def write_start_log_station_and_title(self): + if self._cnf._current_log_station: + self._write_title_to_log(self._cnf._current_log_station, force=True) + if self._cnf._current_log_title: + self._write_title_to_log(self._cnf._current_log_title, force=True) + diff --git a/pyradio/main.py b/pyradio/main.py index fc053a2b..2330ab9f 100644 --- a/pyradio/main.py +++ b/pyradio/main.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- import sys import curses -import logging +import logging, logging.handlers from argparse import ArgumentParser, SUPPRESS as SUPPRESS from os import path, getenv, environ from sys import platform, version_info @@ -13,6 +13,7 @@ from .install import PyRadioUpdate, PyRadioUpdateOnWindows, is_pyradio_user_installed, version_string_to_list, get_github_tag PATTERN = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' +PATTERN_TITLE = '%(asctime)s | %(message)s' PY3 = sys.version[0] == '3' @@ -34,22 +35,19 @@ def pyradio_config_file(): except: pass -def __configureLogger(): - logger = logging.getLogger('pyradio') - logger.setLevel(logging.DEBUG) +def __configureLogger(pyradio_config, debug=None, titles=None): + if debug or titles: - # Handler - fh = logging.FileHandler(path.join(path.expanduser('~'), 'pyradio.log')) - fh.setLevel(logging.DEBUG) - - # create formatter - formatter = logging.Formatter(PATTERN) - - # add formatter to ch - fh.setFormatter(formatter) + if debug and not pyradio_config.log_degub: + if platform.startswith('win'): + print('Debug mode activated\n printing messages to file: "{}\pyradio.log"'.format(getenv('USERPROFILE'))) + else: + print('Debug mode activated; printing messages to file: "~/pyradio.log"') - # add ch to logger - logger.addHandler(fh) + pyradio_config.titles_log.configure_logger( + debug=debug, + titles=titles + ) def shell(): version_too_old = False @@ -104,6 +102,8 @@ def shell(): help='Uninstall PyRadio.') parser.add_argument('--unlock', action='store_true', help="Remove sessions' lock file.") + parser.add_argument('-lt', '--log-titles', action='store_true', + help='Log titles to file.') parser.add_argument('-d', '--debug', action='store_true', help='Start pyradio in debug mode.') parser.add_argument('-V', '--version', action='store_true', @@ -359,12 +359,13 @@ def shell(): print(format_string.format(str(num+1), a_station[0], a_station[1], encoding)) sys.exit() - if args.debug: - __configureLogger() - if platform.startswith('win'): - print('Debug mode activated\n printing messages to file: "{}\pyradio.log"'.format(getenv('USERPROFILE'))) - else: - print('Debug mode activated; printing messages to file: "~/pyradio.log"') + #pyradio_config.log.configure_logger(titles=True) + if args.debug or args.log_titles: + __configureLogger(debug=args.debug, + titles=args.log_titles, + pyradio_config=pyradio_config + ) + logging.raiseExceptions = False else: ''' Refer to https://docs.python.org/3.7/howto/logging.html section "What happens if no configuration is provided" @@ -444,34 +445,17 @@ def shell(): ''' curses is off ''' if pyradio.setup_return_status: if pyradio_config.WIN_UNINSTALL and platform.startswith('win'): - from msvcrt import getwch - from os import sep - import subprocess - the_path = __file__.split(sep) - the_file = sep.join(the_path[:-1]) + sep + 'install.py' - print('\nTo complete the process you will have to execute a batch file.') - print('Windows Explorer will open the location of the batch file to run.') - print('') - print('Please double click') - print('') - print(' uninstall.bat') - print('') - print('to remove PyRadio from your system.') - print('') - print('After you are done, you can delete the folder it resides in.') - print('\nPress any key to continue...', end='', flush=True) - getwch() - #print('\nPress any key to exit...', end='', flush=True) - #getwch() - subprocess.call('python ' + the_file + ' -R', - stdout=subprocess.DEVNULL, - stderr=subprocess.DEVNULL) + # doing it this way so that pyton2 does not break (#153) + from .win import win_press_any_key_to_unintall + win_press_any_key_to_unintall() sys.exit() if pyradio_config.WIN_PRINT_PATHS and platform.startswith('win'): ''' print exe path ''' + # doing it this way so that pyton2 does not break (#153) + from .win import win_print_exe_paths print('') - print_exe_paths() + win_print_exe_paths() if pyradio_config.WIN_MANAGE_PLAYERS and platform.startswith('win'): ''' manage players''' @@ -577,24 +561,5 @@ def get_format_string(stations): header_format_string = '{0:' + str(len0+num+2) + '.' + str(len0+num+2) + 's} | {1:' + str(len1) + '.' + str(len1) + 's} | {2}' return header_format_string, format_string -def print_exe_paths(): - ''' Windows only - ''' - from .install import fix_pyradio_win_exe - exe = fix_pyradio_win_exe() - if exe[0] and exe[1]: - print('PyRadio EXE files:') - print(' System:\n {}'.format(exe[0])) - print(' User:\n {}'.format(exe[1])) - else: - print('PyRadio EXE file:') - if exe[0]: - print(' {}'.format(exe[0])) - else: - print(' {}'.format(exe[1])) - print('\nPress any key to exit...', end='', flush=True) - from msvcrt import getwch - getwch() - if __name__ == '__main__': shell() diff --git a/pyradio/player.py b/pyradio/player.py index a17b2223..21ad45df 100644 --- a/pyradio/player.py +++ b/pyradio/player.py @@ -1135,6 +1135,7 @@ def _get_mpv_metadata(self, *args): except: self.oldUserInput['Title'] = 'Title: ' + title.decode('utf-8', 'replace') string_to_show = self.title_prefix + self.oldUserInput['Title'] + #logger.critical(string_to_show) if stop(): return False self.outputStream.write(msg=string_to_show, counter='') @@ -1434,10 +1435,16 @@ def close(self): self._stop_delay_thread() if self.process is not None: self._kill_process_tree(self.process.pid) - self.process.wait() - self.process = None + try: + self.process.wait() + except: + pass + finally: + self.process = None try: self.update_thread.join() + except: + pass finally: self.update_thread = None @@ -1560,6 +1567,7 @@ class MpvPlayer(Player): if WIN: PLAYER_CMD = find_mpv_on_windows() NEW_PROFILE_STRING = 'volume=50\n\n' + if pywhich(PLAYER_CMD): executable_found = True else: diff --git a/pyradio/radio.py b/pyradio/radio.py index 62ceab3d..da359322 100644 --- a/pyradio/radio.py +++ b/pyradio/radio.py @@ -528,7 +528,7 @@ def setup(self, stdscr): if logger.isEnabledFor(logging.INFO) and rev: logger.info(rev) - self.log = Log() + self.log = Log(self._cnf) ''' For the time being, supported players are mpv, mplayer and vlc. ''' try: self.player = player.probePlayer( @@ -2071,7 +2071,10 @@ def _show_main_help_page_4(self, from_keyboard=False): reset_metrics=False) def _show_main_help_page_5(self, from_keyboard=False): - txt = '''!Windows Only + txt = '''!Titles Logger + W |Toggle Logger on/off + w |Tag a station as liked + !Windows Only F7 |Delete old installation files. F8 |Players management. F9 |Show |EXE| location. @@ -4339,7 +4342,7 @@ def _paste(self, playlist=''): playlist ) if ret == 0: - self._show_statiosn_pasted() + self._show_station_pasted() else: self._show_paste_failed() else: @@ -4811,9 +4814,52 @@ def keypress(self, char): self._i_am_resizing = False return + if char in (ord('w'), ) and self.ws.operation_mode in ( + self.ws.NORMAL_MODE, + self.ws.PLAYLIST_MODE + ): + if self.player.isPlaying(): + if self._cnf.can_like_a_station(): + toggled = False + if self._cnf.titles_log.titles_handler is None: + self.toggle_titles_logging() + self.log.write_start_log_station_and_title() + toggled = True + ret = self._cnf.titles_log.tag_title(self.log) + if toggled: + self.toggle_titles_logging() + else: + ret = 2 + + if ret == 0: + self._show_delayed_notification('___Title tagged as liked___') + elif ret == 1: + self._show_delayed_notification('___Error liking Title___', delay=1.2) + else: + self._show_delayed_notification('___Title already tagged as liked___') + else: + self._show_delayed_notification('___Error: Player not in playback___', delay=1.2) + return + + elif char in (ord('W'), ) and self.ws.operation_mode in ( + self.ws.NORMAL_MODE, + self.ws.PLAYLIST_MODE + ): + self.toggle_titles_logging() + self.log.write_start_log_station_and_title() + if self._cnf.titles_log.titles_handler: + self._show_delayed_notification('___Titles Log Enabled___') + else: + self._show_delayed_notification('___Titles Log Disabled___') + return # if self._limited_width_mode: # return + ''' if small exit ''' + if self._limited_height_mode or self._limited_width_mode: + self._handle_limited_height_keys(char) + return + if self.ws.operation_mode == self.ws.WIN_UNINSTALL_MODE: self.ws.close_window() if char in (ord('y'), ): @@ -4843,10 +4889,6 @@ def keypress(self, char): win_del_old_inst() return - if self._limited_height_mode or self._limited_width_mode: - self._handle_limited_height_keys(char) - return - if self.ws.operation_mode in ( self.ws.DEPENDENCY_ERROR, self.ws.NO_PLAYER_ERROR_MODE, @@ -5838,7 +5880,7 @@ def keypress(self, char): ) self.refreshBody() if ret == 0: - self._show_statiosn_pasted() + self._show_station_pasted() else: self._show_paste_failed() self.refreshBody() @@ -7050,17 +7092,20 @@ def _exit_browser_config(self): self._browser_config_win = None self.refreshBody() - def _show_statiosn_pasted(self): - self._show_notification_with_delay( - txt='___Station pasted!!!___', - mode_to_set=self.ws.operation_mode, - callback_function=self.refreshBody) + def _show_delayed_notification(self, txt, delay=.75): + if not (self._limited_height_mode or self._limited_width_mode): + self._show_notification_with_delay( + txt, + delay=delay, + mode_to_set=self.ws.operation_mode, + callback_function=self.refreshBody + ) + + def _show_station_pasted(self): + self._show_delayed_notification('___Station pasted!!!___') def _show_nothing_to_paste(self): - self._show_notification_with_delay( - txt='___Nothing to paste!!!___', - mode_to_set=self.ws.operation_mode, - callback_function=self.refreshBody) + self._show_delayed_notification('___Nothing to paste!!!___') def _show_paste_failed(self): self._show_notification_with_delay( @@ -7673,6 +7718,9 @@ def set_param_set_by_id(self, a_param_id=0): logger.debug('Activating parameter No {0} for player "{1}"'.format(a_param_id, self._cnf.PLAYER_NAME)) return True + def toggle_titles_logging(self): + self._cnf.titles_log.configure_logger(titles=not self._cnf.titles_log.log_titles) + ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Windows only section ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' diff --git a/pyradio/simple_curses_widgets.py b/pyradio/simple_curses_widgets.py index 7206d2a3..1877b11e 100644 --- a/pyradio/simple_curses_widgets.py +++ b/pyradio/simple_curses_widgets.py @@ -1173,7 +1173,7 @@ def __init__(self, @property def height(self): - '''Returns the widget's Y position ''' + '''Returns the widget's height ''' return self._maxY @height.setter @@ -1182,7 +1182,7 @@ def height(self, value): @property def width(self): - '''Returns the widget's X position ''' + '''Returns the widget's width ''' return self._maxX @width.setter @@ -1207,10 +1207,20 @@ def X(self): def X(self, value): self._X = val + @property + def parent(self): + '''Returns the widget's window ''' + return self._parent + + @parent.setter + def parent(self, value): + if self._showed: + self.show(parent=value) + @property def window(self): - '''Returns if the widget is enabled''' - return self._enabled + '''Returns the widget's window ''' + return self._win @window.setter def window(self, value): @@ -1249,7 +1259,8 @@ def set_items(self, items=None): def show(self, parent=None): if parent: - self._win = parent + self._parent = parent + self._win = None for i, n in enumerate(self.items): if self._align == self.LEFT: disp_item = ' ' * self._margin + n.ljust(self._item_width) + ' ' * self._margin diff --git a/pyradio/win.py b/pyradio/win.py index 7a358470..20553503 100644 --- a/pyradio/win.py +++ b/pyradio/win.py @@ -7,6 +7,9 @@ import site from shutil import rmtree from msvcrt import getwch +from msvcrt import getwch +from os import sep +import subprocess HAVE_PYUNPACK = True @@ -21,6 +24,51 @@ except ImportError: from player import find_mpv_on_windows, find_mplayer_on_windows, find_vlc_on_windows +def win_press_any_key_to_unintall(): + the_path = __file__.split(sep) + the_file = sep.join(the_path[:-1]) + sep + 'install.py' + print('\nTo complete the process you will have to execute a batch file.') + print('Windows Explorer will open the location of the batch file to run.') + print('') + print('Please double click') + print('') + print(' uninstall.bat') + print('') + print('to remove PyRadio from your system.') + print('') + print('After you are done, you can delete the folder it resides in.') + from .win import press_any_key_to_continue + print('\nPress any key to exit...', end='', flush=True) + getwch() + #print('\nPress any key to exit...', end='', flush=True) + #getwch() + subprocess.call('python ' + the_file + ' -R', + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL) + +def win_print_exe_paths(): + from .install import fix_pyradio_win_exe + exe = fix_pyradio_win_exe() + if exe[0] and exe[1]: + print('PyRadio EXE files:') + print(' System:\n {}'.format(exe[0])) + print(' User:\n {}'.format(exe[1])) + else: + print('PyRadio EXE file:') + if exe[0]: + print(' {}'.format(exe[0])) + else: + print(' {}'.format(exe[1])) + # doing it this way so that pyton2 does not break (#153) + from .win import press_any_key_to_continue + print('\nPress any key to exit...', end='', flush=True) + getwch() + +def press_any_key_to_continue(): + print('\nPress any key to exit...', end='', flush=True) + from msvcrt import getwch + getwch() + def install_module(a_module, do_not_exit=False, print_msg=True): if print_msg: print('Installing module: ' + a_module) diff --git a/pyradio_rb.1 b/pyradio_rb.1 index 68bd234c..adc24223 100644 --- a/pyradio_rb.1 +++ b/pyradio_rb.1 @@ -1,7 +1,7 @@ .\" Copyright (C) 2011 Ben Dowling .\" This manual is freely distributable under the terms of the GPL. .\" -.TH pyradio_rb 1 "March 2022" pyradio +.TH pyradio_rb 1 "April 2022" pyradio .SH Name .PP @@ -209,6 +209,9 @@ In case the server returns no results, the window will automatically reopen so t .PP Navigation between the various fields is done using the "\fBTab\fR" (and "\fBShift-Tab\fR") key, the arrows and vim keys ("\fBj\fR", "\fBk\fR", "\fBh\fR" and "\fBl\fR"), provided that any given key is not already used by one of the on window "widgets". +Toggling the state of check boxes is done by pressing \fISPACE\fR. The \fBDisplay by\fR and \fBSearch for\fR check boxes are mutually exclusive (enabling one disables the other). Each of them will give access to more fields when enabled. + + To perform a search (server query) one would just press \fIEnter\fR on the "\fBOK\fR" button, or "\fIs\fR" on any widget other than a \fBLine editor\fR. This window performs two functions: diff --git a/radio-browser.html b/radio-browser.html index 45f80401..a211d6fb 100644 --- a/radio-browser.html +++ b/radio-browser.html @@ -24,7 +24,7 @@ TD {text-align: left; vertical-align: top; padding: 5px 10px;border: 1px solid SaddleBrown;} pre { background-color: rgba(245, 245, 245, 1); color: #474747; padding: 1.5em; border: 1px solid #C7C7C7; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; overflow: auto; box-shadow: 5px 5px 15px #C7C7C7;} .task-list {list-style-type: none; padding: 0; margin: 0 0 0 1em ;} - img{display: block; margin-left: auto; margin-right: auto; max-width: 600px; width: 100%; background:transparent; padding:3px; border:1px solid #999999; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; box-shadow:5px 5px 15px #888888;} + img{display: block; margin-left: auto; margin-right: auto; max-width: 750; width: 100%; background:transparent; padding:3px; border:1px solid #999999; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; box-shadow:5px 5px 15px #888888;} a{ color: SaddleBrown;} a:visited{color: SaddleBrown;} @@ -68,6 +68,7 @@

      Table of Contents <

      Opening RadioBrowser Top

      To open RadioBrowser one would just press “O” at the program’s main window. Since at this point this is the only service supported, the service will be activated.

      Pyradio’s RadioBrowser interface +

      Upon activation, the default query will be preformed and (if successful) its results will be presented to the user. If unsuccessful, a relevant message will be displayed and the program will return to the local playlist that was previously opened.

      By default, PyRadio will load the first 100 most voted stations on RadioBrowser.

      Closing RadioBrowser Top

      @@ -197,8 +198,10 @@

      Search Window The “Search window” opens when “s” is pressed and loads the “search term” that was used to fetch the stations currently presented in the “RadioBrowser window”. If this is the first time this window is opened within this session, the search term that’s loaded is the “default search term”.

      Note: In case the server returns no results, the window will automatically reopen so that you can redefine the “search term”.

      Navigation between the various fields is done using the “Tab” (and “Shift-Tab”) key, the arrows and vim keys (“j”, “k”, “h” and “l”), provided that any given key is not already used by one of the on window “widgets”.

      +

      Toggling the state of check boxes is done by pressing SPACE. The “Display by” and “Search for” check boxes are mutually exclusive (enabling one disables the other). Each of them will give access to more fields when enabled.

      To perform a search (server query) one would just press Enter on the “OK” button, or “s” on any widget other than a Line editor.

      RadioBrowser Search Window +

      This window performs two functions:

      1. composes a search term to be forwarded to the search function and
      2. diff --git a/radio-browser.md b/radio-browser.md index b4fae3cc..b4bb9fab 100644 --- a/radio-browser.md +++ b/radio-browser.md @@ -181,6 +181,8 @@ The "**Search window**" opens when "**s**" is pressed and loads the "**search te Navigation between the various fields is done using the "**Tab**" (and "**Shift-Tab**") key, the arrows and **vim keys** ("**j**", "**k**", "**h**" and "**l**"), provided that any given key is not already used by one of the on window "widgets". +Toggling the state of check boxes is done by pressing **SPACE**. The "*Display by*" and "*Search for*" check boxes are mutually exclusive (enabling one disables the other). Each of them will give access to more fields when enabled. + To perform a search (server query) one would just press **Enter** on the "**OK**" button, or "**s**" on any widget other than a *Line editor*. ![RadioBrowser Search Window](https://members.hellug.gr/sng/pyradio/radio-browser-search-window.png) diff --git a/setup.py b/setup.py index 26601398..18b39b07 100644 --- a/setup.py +++ b/setup.py @@ -18,13 +18,11 @@ def read(filename): if version_info < (2, 7): install_requires.append('argparse') - meta = dict( name=__project__, version=version, license=__license__, description=read('DESCRIPTION').rstrip(), - long_description=read('README.md'), platforms=('Any'), author='Ben Dowling', author_email='ben.m.dowling@gmail.com', diff --git a/windows-mplayer.html b/windows-mplayer.html index ba15632c..ab011c92 100644 --- a/windows-mplayer.html +++ b/windows-mplayer.html @@ -24,7 +24,7 @@ TD {text-align: left; vertical-align: top; padding: 5px 10px;border: 1px solid SaddleBrown;} pre { background-color: rgba(245, 245, 245, 1); color: #474747; padding: 1.5em; border: 1px solid #C7C7C7; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; overflow: auto; box-shadow: 5px 5px 15px #C7C7C7;} .task-list {list-style-type: none; padding: 0; margin: 0 0 0 1em ;} - img{display: block; margin-left: auto; margin-right: auto; max-width: 600px; width: 100%; background:transparent; padding:3px; border:1px solid #999999; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; box-shadow:5px 5px 15px #888888;} + img{display: block; margin-left: auto; margin-right: auto; max-width: 750; width: 100%; background:transparent; padding:3px; border:1px solid #999999; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; box-shadow:5px 5px 15px #888888;} a{ color: SaddleBrown;} a:visited{color: SaddleBrown;} @@ -61,5 +61,6 @@

        MPlayer installation Navigating to %APPDATA% + diff --git a/windows-mpv.html b/windows-mpv.html index 7908c440..0f88463f 100644 --- a/windows-mpv.html +++ b/windows-mpv.html @@ -24,7 +24,7 @@ TD {text-align: left; vertical-align: top; padding: 5px 10px;border: 1px solid SaddleBrown;} pre { background-color: rgba(245, 245, 245, 1); color: #474747; padding: 1.5em; border: 1px solid #C7C7C7; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; overflow: auto; box-shadow: 5px 5px 15px #C7C7C7;} .task-list {list-style-type: none; padding: 0; margin: 0 0 0 1em ;} - img{display: block; margin-left: auto; margin-right: auto; max-width: 600px; width: 100%; background:transparent; padding:3px; border:1px solid #999999; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; box-shadow:5px 5px 15px #888888;} + img{display: block; margin-left: auto; margin-right: auto; max-width: 750; width: 100%; background:transparent; padding:3px; border:1px solid #999999; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; box-shadow:5px 5px 15px #888888;} a{ color: SaddleBrown;} a:visited{color: SaddleBrown;} @@ -60,5 +60,6 @@

        MPV installation In order to do that, open an Explorer File Manager window, and enter “%APPDATA%” at its location field and press ENTER.

        If you are unsure on how to do that, please refer to the following image (you can ENTER %APPDATA% or any other Windows System Variable this way).

        Navigating to %APPDATA% + diff --git a/windows.html b/windows.html index b6819dec..e6987bab 100644 --- a/windows.html +++ b/windows.html @@ -24,7 +24,7 @@ TD {text-align: left; vertical-align: top; padding: 5px 10px;border: 1px solid SaddleBrown;} pre { background-color: rgba(245, 245, 245, 1); color: #474747; padding: 1.5em; border: 1px solid #C7C7C7; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; overflow: auto; box-shadow: 5px 5px 15px #C7C7C7;} .task-list {list-style-type: none; padding: 0; margin: 0 0 0 1em ;} - img{display: block; margin-left: auto; margin-right: auto; max-width: 600px; width: 100%; background:transparent; padding:3px; border:1px solid #999999; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; box-shadow:5px 5px 15px #888888;} + img{display: block; margin-left: auto; margin-right: auto; max-width: 750; width: 100%; background:transparent; padding:3px; border:1px solid #999999; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; box-shadow:5px 5px 15px #888888;} a{ color: SaddleBrown;} a:visited{color: SaddleBrown;} @@ -50,6 +50,7 @@

        Table of Contents <
      3. Installing Python
      4. Verifying the installation
      5. +
      6. 7zip installation
      7. Player installation
      8. @@ -90,6 +92,7 @@

        Installation The installation consists of three steps:

        1. Python installation
        2. +
        3. 7Zip installation
        4. Player installation
        5. PyRadio installation
        @@ -100,6 +103,7 @@

        Installing Python

        Here’s how you do that: the page contains some folders named pyXY (XY is the python version the folder corresponds to). Make a note of the largest XY number; this is the latest Python version supported, and this is the one you should download. At the time of writing this, version 3.9 was the latest supported one (folder py39), even though Python 3.10 had already been released.

        When the download is done, run its setup and select “Custom Installation” so that you can “Add Python to environment variables”. You can refer to the following image to see the relevant setting.

        Python Installation +

        Verifying the installation

        Either if you have just installed Python or you already have it installed, you need to verify that its executable is in the PATH (i.e. Python can be executed from a console by typing”python”).

        So, go ahead and open a console (the command is cmd) and type python.

        @@ -109,7 +113,10 @@

        Verifying the installation

        >>>

        If the command could not be found, you have to run the installation again, select “Modify” and set the “Add Python to environment variables” option. You can refer to the following image to see the relevant setting.

        Python Installation Modification +

        Note: If you don’t have the setup file of the original Python installation, you will have to download it from Python’s Windows Downloads. In case you want to upgrade to the latest version, you must uninstall the one currently installed, beforehand.

        +

        7zip installation Top

        +

        Go to 7zip web site and download and install the latest release that’s compatible with your Windows installation. Unless you are still on a 32-bit Windows 7 environment, you just go grub the first link provided.

        Player installation Top

        As already stated MPV will be automatically installed on a fresh installation.

        If the user decides to install a different player, he should have the following in mind:

        @@ -144,7 +151,9 @@

        Player installation MPV or MPlayer installation

        -

        PyRadio provides a helper function to install, update and uninstall MPV and MPlayer. To enable this function, just execute PyRadio and press “F8”. Then PyRadio will terminate and you will be presented with a screen similar to the following one:

        +

        PyRadio provides a helper function to install, update and uninstall MPV and MPlayer.

        +

        This function will be part of the installation procedure, when PyRadio detects that this is a fresh installation.

        +

        After you have installed or updated PyRadio, you cas still enable this function, by executing PyRadio and pressing “F8”. Then PyRadio will terminate and you will be presented with a screen similar to the following one:

        Reading config...
         Reading playlist...
         
        @@ -193,6 +202,7 @@ 

        Fresh python installation?

        Final steps

        If the installation is successful, you will get something similar to the following image:

        Installation image +

        PyRadio has been installed preforming a “user installation”, which means that the program is available to your current user only.

        Furthermore, if the WARNING shown in the previous image has been shown to you, the executable of the program is not in your PATH (you cannot just open a console and type “pyradio” to execute it; you have to use the Icon/Shortcut created on your Desktop to do that).

        Now, you can just call it a day; you can run PyRadio from its Desktop Shortcut.

        @@ -202,6 +212,7 @@

        Final steps

        Getting the path to pyradio.exe

        In case one has not added the “Scripts” path to the PATH variable, but has to have the path to the executable of the program (in order to execute it from a console, for example), one can just execute PyRadio and press “F9”. Then the following info will be displayed:

        Pressing F9 +

        After PyRadio terminates, the following will be displayed:

        Reading config...
         Reading playlist...
        @@ -216,6 +227,12 @@ 

        Getting the path to pyradio.exe

        In this example, both a “System” and a “User” path to PyRadio executable is displayed.

        This would be the case after installing a version newer than 0.8.9.14 while a version older than 0.8.9.14 is already installed.

        If this is your case, please follow the instructions found in “Removing an old-style installation”.

        +

        Using the Titles Logging feature

        +

        If you want to use the Titles Logging feature, and your Country/Region is anything different than English, chances are you will have to correctly set your locale for non-unicode applications, which is something you should be doing regardless. Otherwise, the titles’ log file may contain unreadable characters.

        +

        If you want to go on and set your locale for non-unicode applications, just refer to the following image.

        +INTL.CPL + +

        The instructions work for Windows 7 up to 11.

        Cleaning up

        After the installation is completed, there will be some files left on your system, which you may want to remove. These are:

          diff --git a/windows.md b/windows.md index 3e957ee2..f534fdd0 100644 --- a/windows.md +++ b/windows.md @@ -14,6 +14,7 @@ Ben Dowling - [https://github.com/coderholic](https://github.com/coderholic) * [Python installation](#python-installation) * [Installing Python](#installing-python) * [Verifying the installation](#verifying-the-installation) + * [7zip installation](#7zip-installation) * [Player installation](#player-installation) * [MPV or MPlayer installation](#mpv-or-mplayer-installation) * [VLC installation](#vlc-installation) @@ -21,6 +22,7 @@ Ben Dowling - [https://github.com/coderholic](https://github.com/coderholic) * [Fresh python installation?](#fresh-python-installation?) * [Final steps](#final-steps) * [Getting the path to pyradio.exe](#getting-the-path-to-pyradio.exe) + * [Using the Titles Logging feature](#using-the-titles-logging-feature) * [Cleaning up](#cleaning-up) * [Updating PyRadio](#updating-pyradio) * [Updating a pre 0.8.9 installation](#updating-a-pre-0.8.9-installation) @@ -63,8 +65,9 @@ Having said that, let us proceed with the installation. The installation consists of three steps: 1. **Python** installation -2. **Player** installation -3. **PyRadio** installation +2. **7Zip** installation +3. **Player** installation +4. **PyRadio** installation ### Python installation @@ -100,6 +103,10 @@ If the command could not be found, you have to run the installation again, selec **Note:** If you don't have the setup file of the original **Python** installation, you will have to **download** it from [Python's Windows Downloads](https://www.python.org/downloads/windows/). In case you want to upgrade to the latest version, you **must uninstall** the one currently installed, beforehand. +### 7zip installation + +Go to [7zip web site](https://www.7-zip.org/) and download and install the latest release that's compatible with your Windows installation. Unless you are still on a 32-bit Windows 7 environment, you just go grub the first link provided. + ### Player installation As already stated [MPV](https://mpv.io) will be automatically installed on a fresh installation. @@ -114,7 +121,11 @@ If the user decides to install a different player, he should have the following #### MPV or MPlayer installation -**PyRadio** provides a helper function to install, update and uninstall [MPV](https://mpv.io) and [MPlayer](http://www.mplayerhq.hu/design7/news.html). To enable this function, just execute **PyRadio** and press "**F8**". Then **PyRadio** will terminate and you will be presented with a screen similar to the following one: +**PyRadio** provides a helper function to install, update and uninstall [MPV](https://mpv.io) and [MPlayer](http://www.mplayerhq.hu/design7/news.html). + +This function will be part of the installation procedure, when **PyRadio** detects that this is a fresh installation. + +After you have installed or updated **PyRadio**, you cas still enable this function, by executing **PyRadio** and pressing "**F8**". Then **PyRadio** will terminate and you will be presented with a screen similar to the following one: ``` Reading config... @@ -232,6 +243,16 @@ This would be the case after installing a version newer than **0.8.9.14** while If this is your case, please follow the instructions found in "[Removing an old-style installation](#removing-an-old-style-installation)". +#### Using the Titles Logging feature + +If you want to use the [Titles Logging](README.md#titles-logging) feature, and your Country/Region is anything different than **English**, chances are you will have to correctly set your locale for non-unicode applications, which is something you should be doing regardless. Otherwise, the titles' log file may contain unreadable characters. + +If you want to go on and set your locale for non-unicode applications, just refer to the following image. + +![INTL.CPL](https://members.hellug.gr/sng/pyradio/intl.jpg) + +The instructions work for Windows 7 up to 11. + #### Cleaning up After the installation is completed, there will be some files left on your system, which you may want to remove. These are: