Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add qbittorrent command, multiple sonarr/radarr instance support, single line commands #169

Open
wants to merge 28 commits into
base: master
Choose a base branch
from

Conversation

raaifr
Copy link

@raaifr raaifr commented Dec 16, 2024

Added some functions I found useful since I started using Addarr.

List of changes:

  • Refactored Conversation Handler Entry points and States and their flow

  • Added qBittorrent command to change speeds

  • Added single line command support. sending a command waiting for prompts to enter data felt tiring. See updated readme

  • Refactored tag creation. Default tags will also be created if they do not exist.

  • Multiple instances of Sonarr/Radarr can be added to config.yaml file as a list using labels as an identifier for each instance. Users will be prompted to choose which instance of sonarr/radarr they want to use when adding titles. See config_example.yaml

  • Refactored some variable/function names. Use of MovieSerie or SerieMovie is odd. Changed to Media. Would recommend use of "Media" to collectively refer to Series and Movies.

  • Added feature to create telegram notification profile in radarr/sonarr. Users will be notified on these events:

    • Media Downloaded
    • Media Removed
    • Media Upgraded to a better quality
  • Addressed minor consistency and labelling issues

  • Adapted all Series/Movies to support multiple instances

  • Bug Fixes associated with multi instance support in start, auth and delete commands

  • Registered bot commands programmatically. Available commands will be shown under Menu button in the bot conversation

Future Implementations

  • Suggest to add some admin functions like adding, removing users. There will be instances where giving out the bots password is not preferred.
  • Search using TMDB, IMDB id
  • A roadmap in the readme will be helpful for future developers

DEV NOTE

Rule of thumb I followed implementing returned states and their handlers is that the function will return state named after what that function is currently asking the user to do. And the state handler for that state will be named after the description of the next step that will be performed when that state is triggered.

For example: if the function asks for the title of a movie the function will return PROMPT_TITLE as the state and in the conversation handler the state handler for that state will be:

addMedia_handler = ConversationHandler(
        entry_points=[
            ...
        ],
        states={
            PROMPT_TITLE: [
                CallbackQueryHandler(storeTitle, pattern='...'),
            ],
            ...
        },
        fallbacks=[
            ...
        ],
    )

  def Start(update : Update, context: ContextTypes.DEFAULT_TYPE):
    .. some operations ..
    .. ask user to enter title
    return PROMPT_TITLE

  def storeTitle(update : Update, context: ContextTypes.DEFAULT_TYPE):
    .. store title here .. 

IMO this will help future developers following the flow easily.

  • With addition of qbittorrent command, #148 can be closed
  • With addition of single line comamnds, #122 can be closed
  • With addition of bot commands via post_init(), #171 can be closed

chatid.txt Outdated Show resolved Hide resolved
config_example.yaml Outdated Show resolved Hide resolved
config_example.yaml Outdated Show resolved Hide resolved
config_example.yaml Outdated Show resolved Hide resolved
config_example.yaml Outdated Show resolved Hide resolved
Copy link
Owner

@Waterboy1602 Waterboy1602 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are still a lot of bugs in this PR:

  • When you Addarr for the first time in a chat and send start you should get the following message: "You first need to authorize this chat. What is the password?". Now it doesn't respond to start. auth does get a respond of Addarr, but it's still not possible to authorize.

  • Some commands without / aren't working anymore. By example: Addarr should also respond to start instead of only to /start

  • Something wrong with the labels in config. If I use the default config labels, Addarr returns first a warning: WARNING - Radarr instance with label 'Movie' not found. and then an error: requests.exceptions.MissingSchema: Invalid URL 'None': No scheme supplied. Perhaps you meant https://None?. I assume you're wrongly saving/getting the label to set the instance.

  • Once you get the first series/movie it isn't possible to go to the next screen. Yes, add this, No, show me the next result and Execute a new search command don't work. Only stop gives a response.

  • /delete command goes to add

Waterboy1602

This comment was marked as duplicate.

Copy link
Owner

@Waterboy1602 Waterboy1602 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix the flake8 remarks

@Waterboy1602
Copy link
Owner

Thank you for the pull request! A lot of interesting new features and some code improvements are always welcome. Could you just look at my remarks?

@raaifr
Copy link
Author

raaifr commented Dec 27, 2024

My apologies for the code issues.

There are still a lot of bugs in this PR:

  • When you Addarr for the first time in a chat and send start you should get the following message: "You first need to authorize this chat. What is the password?". Now it doesn't respond to start. auth does get a respond of Addarr, but it's still not possible to authorize.

The start command is fixed now. I dont understand what authorize issue you are describing, but it will now respond to any of the following way of authorization:

  • auth password123
  • /auth password123

Could you describe your flow to arrive at this errors? I am unable to recreate these issues.

  • Something wrong with the labels in config. If I use the default config labels, Addarr returns first a warning: WARNING - Radarr instance with label 'Movie' not found. and then an error: requests.exceptions.MissingSchema: Invalid URL 'None': No scheme supplied. Perhaps you meant https://None?. I assume you're wrongly saving/getting the label to set the instance.
  • Once you get the first series/movie it isn't possible to go to the next screen. Yes, add this, No, show me the next result and Execute a new search command don't work. Only stop gives a response.

For both sonarr and radarr, all buttons are working for me as expected. am i missing something? can you retry with the latest changes please?

@raaifr raaifr marked this pull request as draft January 2, 2025 05:33
@raaifr raaifr marked this pull request as draft January 2, 2025 05:33
@Waterboy1602
Copy link
Owner

I can confirm that the authorization flow is now working as it's supposed to be and that Addarr responds to start.

  • About this issue:
  • Something wrong with the labels in config. If I use the default config labels, Addarr returns first a warning: WARNING - Radarr >instance with label 'Movie' not found. and then an error: requests.exceptions.MissingSchema: Invalid URL 'None': No scheme >supplied. Perhaps you meant https://None?. I assume you're wrongly saving/getting the label to set the instance.

When I use the config as in config_example.yaml and have the following labels configured:

#Sonarr Configuration
sonarr:
  - label: tv # label must be a unique value from other labels. use of name given in your sonarr instance will make it easy
    server:
[...]
#Radarr Configuration
radarr:
  - label: movies # label must be a unique value from other labels. use of name given in your radarr instance will make it easy
    server:

I get an error when I press Movie after the question "Is this a movie or a series?". So I start Addarr with start, I enter a movie title and then when I select Movie, this is the error it gives:

Error block

2025-01-04 14:21:10,205 - addarr - INFO - Storing godfather as title
2025-01-04 14:21:11,268 - addarr - INFO - choice: Movie
2025-01-04 14:21:11,270 - addarr - DEBUG - Only found 1 instance of radarr, so proceeding with that one...
2025-01-04 14:21:11,271 - addarr.radarr - ERROR - Radarr instance with label 'Movie' not found. Default instace will be used.
2025-01-04 14:21:11,274 - addarr.commons - WARNING - Radarr instance with label 'Movie' not found.
2025-01-04 14:21:11,275 - addarr.commons - WARNING - Generate of APIQUERY failed: unsupported operand type(s) for +: 'NoneType' and 'str'.
2025-01-04 14:21:11,277 - addarr.radarr - INFO - None
No error handlers are registered, logging exception.
Traceback (most recent call last):
  File "C:\Users\Wannes\Nextcloud\Development\Addarr\env\Lib\site-packages\telegram\ext\_application.py", line 1325, in process_update
    await coroutine
  File "C:\Users\Wannes\Nextcloud\Development\Addarr\env\Lib\site-packages\telegram\ext\_handlers\conversationhandler.py", line 844, in handle_update
    new_state: object = await handler.handle_update(
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Wannes\Nextcloud\Development\Addarr\env\Lib\site-packages\telegram\ext\_handlers\basehandler.py", line 158, in handle_update
    return await self.callback(update, context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Wannes\Nextcloud\Development\Addarr\src\addarr.py", line 384, in storeMediaType
    await promptInstanceSelection(update, context)
  File "C:\Users\Wannes\Nextcloud\Development\Addarr\src\addarr.py", line 466, in promptInstanceSelection
    return await storeInstance(update, context) # skip to next step
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Wannes\Nextcloud\Development\Addarr\src\addarr.py", line 513, in storeInstance
    searchResult = service.search(title)
                   ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Wannes\Nextcloud\Development\Addarr\src\radarr.py", line 41, in search
    req = requests.get(url)
          ^^^^^^^^^^^^^^^^^
  File "C:\Users\Wannes\Nextcloud\Development\Addarr\env\Lib\site-packages\requests\api.py", line 73, in get
    return request("get", url, params=params, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Wannes\Nextcloud\Development\Addarr\env\Lib\site-packages\requests\api.py", line 59, in request
    return session.request(method=method, url=url, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Wannes\Nextcloud\Development\Addarr\env\Lib\site-packages\requests\sessions.py", line 575, in request
    prep = self.prepare_request(req)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Wannes\Nextcloud\Development\Addarr\env\Lib\site-packages\requests\sessions.py", line 484, in prepare_request
    p.prepare(
  File "C:\Users\Wannes\Nextcloud\Development\Addarr\env\Lib\site-packages\requests\models.py", line 367, in prepare
    self.prepare_url(url, params)
  File "C:\Users\Wannes\Nextcloud\Development\Addarr\env\Lib\site-packages\requests\models.py", line 438, in prepare_url
    raise MissingSchema(
requests.exceptions.MissingSchema: Invalid URL 'None': No scheme supplied. Perhaps you meant https://None?

As I understand, it has something to do with non-existent labels, but I don't think this should cause an error since I only select one of the two options: Movie or Series.

When I change my config to the below, Addarr responds after I select Movie. So I guess something is wrongly coded that the labels should have the same name as the options it shows after "Is this a movie or a series?"

#Sonarr Configuration
sonarr:
  - label: Series # label must be a unique value from other labels. use of name given in your sonarr instance will make it easy
    server:
[...]
#Radarr Configuration
radarr:
  - label: Movie # label must be a unique value from other labels. use of name given in your radarr instance will make it easy
    server:
  • About this issue:
  • Once you get the first series/movie it isn't possible to go to the next screen. Yes, add this, No, show me the next result and Execute a new search command don't work. Only stop gives a response.

The flow I follow to get to this issue is like this: Start > Enter the title: > Friends > Is this a movie or a series? > Click Series > Is this the series you want to add? > Click No, show me the next result. After that I can see I pressed the button, but it doesn't responds anymore. Normally it should show another series to choose from to select. If I look in the logs, it also doesn't show any new logs after I get the first result.

Same happens when selecting Yes, add this or Execute a new search command. Only Stop gives me the message the command has ended.
It's also the same after entering a movie title and selecting Movies on the first option.

config_example.yaml Outdated Show resolved Hide resolved
config_example.yaml Outdated Show resolved Hide resolved
src/definitions.py Outdated Show resolved Hide resolved
@raaifr
Copy link
Author

raaifr commented Jan 18, 2025

This issue seems to have caused by incorrect parsing of the list. I was not able to replicate this error before because this only happens if there is a single radarr/sonarr instance provided in the config. I have since refactored how it fetches the instances.

Something wrong with the labels in config. If I use the default config labels, Addarr returns first a warning: WARNING - Radarr instance with label 'Movie' not found. and then an error: requests.exceptions.MissingSchema: Invalid URL 'None': No scheme supplied. Perhaps you meant https://None?. I assume you're wrongly saving/getting the label to set the instance.

Second issue is caused by the conversation handler confusing the state of the conversation when jumping from one function to another like if we have just one instance of sonarr it then it calls the function that shows the search results instead of asking the user to select an instance. In such cases I have found that returning the state that the next step needs after calling the next step function resolves this issue.

Once you get the first series/movie it isn't possible to go to the next screen. Yes, add this, No, show me the next result and Execute a new search command don't work. Only stop gives a response.

@raaifr raaifr marked this pull request as ready for review January 20, 2025 17:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants