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

[wip] Ombi input plugin #2109

Closed
wants to merge 4 commits into from
Closed

[wip] Ombi input plugin #2109

wants to merge 4 commits into from

Conversation

bagobones
Copy link
Contributor

Motivation for changes:

Flexget lacks a UI for requesting content to download.

Ombi implements a great multi user request system.

As of Ombi v3 now has an API to make integration possible.

https://github.com/tidusjar/Ombi

Detailed changes:

  • basic ombi plugin that implements basic movie, shows, seasons, episodes input

Implemented feature requests:

  • Feathub #38. "This was my own request, found some time to work on it"

Config usage if relevant (new plugin or updated schema):

    schema = {
        'type': 'object',
        'properties': {
            'base_url': {'type': 'string'},
            'port': {'type': 'number', 'default': 3579},
            'api_key': {'type': 'string'},
            'username': {'type': 'string'},
            'password': {'type': 'string'},
            'type': {'type': 'string', 'enum': ['shows', 'seasons', 'episodes', 'movies']},
            'only_approved': {'type': 'boolean', 'default': True},
            'include_available': {'type': 'boolean', 'default': False},
            'include_year': {'type': 'boolean', 'default': False},
            'include_ep_title': {'type': 'boolean', 'default': False}
        },
        'oneOf': [
            {'required': ['username', 'password']},
            {'required': ['api_key']}
        ],
        'required': ['base_url', 'type'],
        'additionalProperties': False
    }

To Do:

  • May turn this into a full list plugin in the future once the Ombi API for adding TV requests improves.

@bagobones
Copy link
Contributor Author

Removed most elements of the list plugin, accept the mutable list. I have also reduced or removed most debug log messages and improve the exception handling.

@bagobones bagobones changed the title Ombi input plugin [add] Ombi input plugin Apr 6, 2018
@bagobones
Copy link
Contributor Author

Are the quality review checks on the mutable list 'add' and 'discard' methods correct? It seems to be overly picky as I see other pulls with that error. In my case they are not currently implemented but it seems to want something very specific.

@paranoidi
Copy link
Member

This looks pretty great! I'm not familiar with list plugin api to comment on add and discard method complaints.

url = '%s://%s:%s%s/api/v1/Token' % (parsedurl.scheme, parsedurl.netloc, self.config.get('port'), parsedurl.path)
data = {'username': self.config.get('username'),
'password': self.config.get('password')
}
Copy link
Member

Choose a reason for hiding this comment

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

Odd formatting

auth_header = self.ombi_auth()

parsedurl = urlparse(self.config.get('base_url'))
url=''
Copy link
Member

Choose a reason for hiding this comment

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

pep8

raise plugin.PluginError('Unable to connect to Ombi at %s. Error: %s' % (url, e))

def generate_movie_entry(self, parent_request):
entry = Entry()
Copy link
Member

Choose a reason for hiding this comment

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

Unused variable

return entry

def generate_tv_entry(self, parent_request, child_request=None, season=None, episode=None):
entry = Entry()
Copy link
Member

Choose a reason for hiding this comment

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

Unused variable, put return within blocks to avoid editor complaints for returning undefined variable

entry = Entry()
if self.config.get('type') == 'shows':
log.debug('Found: %s', parent_request.get('title'))
entry = Entry(title=self.generate_title(parent_request),
Copy link
Member

Choose a reason for hiding this comment

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

so here just "return Entry(...)"

else:
raise plugin.PluginError('Error: Unknown list type %s.' % (self.config.get('type')))

return entry
Copy link
Member

Choose a reason for hiding this comment

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

and then this becomes unnecessary, simpler overall

@property
def items(self):
if not self._items:

Copy link
Member

Choose a reason for hiding this comment

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

a bit odd empty lines here and there, not a big issue :)


self._items = []

for parent_request in json:
Copy link
Member

Choose a reason for hiding this comment

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

extracting these if blocks into own methods would be neater

ombi_status=parent_request.get('status'),
ombi_request_id=parent_request.get('id'))
elif self.config.get('type') == 'seasons':
log.debug('Found: %s S%s', parent_request.get('title'), season.get('seasonNumber'))
Copy link
Member

Choose a reason for hiding this comment

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

Kudos, almost everyone uses the python logger incorrectly with string formatting instead of doing it right with parameters 👍

Copy link
Member

@paranoidi paranoidi left a comment

Choose a reason for hiding this comment

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

Minor style issues, PEP8 mistakes need to be fixed

@bagobones
Copy link
Contributor Author

I am probably not able to come back to this for months.. Unless the existing code breaks in my own setup.. I just installed it as a user local plugin and have been using it with the main releases.

@cybervoid
Copy link

Hi @bagobones Is this plugin still working for you in flexget latest version?

@bagobones
Copy link
Contributor Author

@rafaelgil83

Flexget 2.17.14
Ombi dev branch 3.0.3993

I do not use all elements of the plugin so I don't guarantee anything. I also do not have ANY spare time for development on this (not my primary programming language and very much a fits my needs project)

I am using username and password auth in ombi, I am not sure if the API key auth still works. (username is the prefered method anyway due to better permission control).

All of the calls I use still appear to work despite both flexget and ombi being updated many times since I created the plugin.. As noted I use it with the normal flexget release but dump it in the user plugin folder.

Movie requests have been working very reliably to populate the movie list plugin in flexget.

  Ombi_Movies_List:
    priority: 40
    imdb_lookup: yes
    seen:
      local: yes
      fields: [ombi_request_id]
    ombi_list:
      base_url: '{? ombi.base_url ?}'
      port: 443
      username: '{? ombi.username ?}'
      password: '{? ombi.password ?}'
      type: movies
    accept_all: yes
    list_add:
      - movie_list: ombi_movies

Populating the series module from the TV requests is less reliable, I just try to match the series not episodes which means in my config I haven't been using or testing the "approved" state as in ombi that is a "per episode" API item.

I use this Template combined with the discover plugin and RSS feeds for TV.

  TV_Ombi:
    thetvdb_lookup: yes
    quality: "720p+"
    configure_series:
      settings:
        path: '/media/Video/TV/{{series_name}}/Season {{series_season}}/'
        season_packs: 2
        identified_by: ep
        begin: S01E01
      from:
        ombi_list:
          base_url: '{? ombi.base_url ?}'
          port: 443
          username: '{? ombi.username ?}'
          password: '{? ombi.password ?}'
          type: shows

@cybervoid
Copy link

Thank you!, I def will give it a try

@paranoidi
Copy link
Member

Tested to be functional, but the code is half-way. Some method calls which do not exists. Might take up and finish this as ombi seems pretty well suited for FlexGet.

@bagobones
Copy link
Contributor Author

It has been super useful for my personal use, that is for sure. Ombi makes a great front end for flexget.

I suppose that is part of the problem.. It works for me, so I haven't put more time into cleaning it up.

Probably a should be a function but wanted to commit this quick fix as it has caused me issues and was only in my local version.
@BHMath
Copy link

BHMath commented May 18, 2019

Wow i'd really like to use this pulgin all days. Are you still working on it ?
Can I help somehow ?

@bagobones
Copy link
Contributor Author

Wow i'd really like to use this pulgin all days. Are you still working on it ?
Can I help somehow ?

I generally don't have the time or the interest to keep working on this plugin as it already does what I need and i am not particularly good at coding in Python. I mostly just fix bugs I find that stop it from working in my config.

You can take the plugin as is and stick it ombi.py in a \plugins\ folder in your flexget directory to load it as a user plugin. That is what I do.. It works with the main flexget releases just fine.

The biggest things missing are the list functions that would allow flexget to edit ombi back.. You could do much more powerful things if it was a full list and not just an input.

@paranoidi paranoidi changed the title [add] Ombi input plugin [wip] Ombi input plugin May 20, 2019
@snickers2k
Copy link

snickers2k commented Aug 29, 2019

Might take up and finish this as ombi seems pretty well suited for FlexGet.

Can I help somehow ?

@BHMath or @paranoidi could you please enhance the plugin as managed_list plugin? i'm truly missing the option to tell ombi whats already in my flexget+trakt watchlist

@BHMath
Copy link

BHMath commented Sep 2, 2019

Unfortunately no I can't develop on the plugin and it actually suits me like this. But I can help on testing or else.

@snickers2k
Copy link

snickers2k commented Sep 3, 2019

yeah, my only problem is, that ombi does not know whats already in my flexget/trakt watchlist and people requesting these items again.

@ocervell
Copy link

ocervell commented Apr 7, 2021

@BHMath @paranoidi could we get this shipped please ? Last feature that's preventing me from switching to flexget ;) Thanks 👍

@bagobones
Copy link
Contributor Author

@BHMath @paranoidi could we get this shipped please ? Last feature that's preventing me from switching to flexget ;) Thanks 👍

You can still just grab my ombi.py and drop it into a plugins subfolder in your flexget main directory and it should still load with the latest releases.

I still have zero time to look into improving this.

@github-actions
Copy link

github-actions bot commented Sep 5, 2021

This PR is stale because it has been open 150 days with no activity. Remove stale label or comment or this will be closed in 60 days.

@github-actions github-actions bot added the Stale label Sep 5, 2021
@github-actions
Copy link

github-actions bot commented Nov 4, 2021

This PR has been stale for 60 days and is being closed. Apologies if this is still relevant, it can be hard to find the time to review and merge everything. Feel free to make sure it is up to date and open it again.

@github-actions github-actions bot closed this Nov 4, 2021
shadycuz added a commit to shadycuz/Flexget that referenced this pull request Jun 15, 2022
@shadycuz shadycuz mentioned this pull request Jun 15, 2022
21 tasks
@shadycuz
Copy link
Contributor

@bagobones @cybervoid @paranoidi @BHMath @snickers2k

I have converted this into a managed list plugin in #3481, if you could help with review/testing, that would be great 🚀

shadycuz added a commit to shadycuz/Flexget that referenced this pull request Jun 24, 2022
shadycuz added a commit to shadycuz/Flexget that referenced this pull request Oct 10, 2022
shadycuz added a commit to shadycuz/Flexget that referenced this pull request Oct 10, 2022
StefftheEmperor2 pushed a commit to StefftheEmperor2/Flexget that referenced this pull request Feb 7, 2023
StefftheEmperor2 pushed a commit to StefftheEmperor2/Flexget that referenced this pull request Feb 9, 2023
shadycuz added a commit to shadycuz/Flexget that referenced this pull request Nov 21, 2023
shadycuz added a commit to shadycuz/Flexget that referenced this pull request Nov 21, 2023
gazpachoking pushed a commit that referenced this pull request Dec 24, 2023
[add] ombi_list plugin

* Ombi input plugin

* Corrected the way the requests plugin was imported to use the flexget version for better error handling

* Removed unused json import

* Added error checking for missing IMDB ID when generating a URL.

Probably a should be a function but wanted to commit this quick fix as it has caused me issues and was only in my local version.

* move ombi input plugin to managed lists

* format and fix imports

* fix import deprication warning

* add the list interface to ombi

* implement suggestions from PR review #2109

* implement remaining list interfaces

* implement feedback from pr

* refactor movie/tv logic into parent class

* add doc string and better type hints for auth func

* black formatting updates

* Revert "refactor movie/tv logic into parent class"

This reverts commit 2e884d9.

* change static method to class method

* inverse the if statement

* use url instead of base_url and port

* some linting fixes

* revert movies back to using IMDB

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* refactor how HTTP requests and authentication is handled

Previous code was a bit scattered, with the authentication being methods
on the plugin and the requests being handled in the OmbiEntry class. I
have created a new class called OmbiRequest to handle both. I based this
design on TVDBRequest which seemed to be a decent implementation. The
only complaint I have is how much I have to pass around OmbiRequest, it
might be better to handle it as a module level variable, but I'm not
sure if that is appropriate.

* add error handling when making calls to the Ombi API

In most cases we will log an error message and return None, which
should allow the processing to continue.

* add custom exeception class for the Ombi API

Sometimes the Ombi API will return a 2xx status code but the response
still contains an error message. This custom exception class will
handle those cases.

* represent plugin configuration as a typed dict

* refactor how items are retried from ombi and how the cache works

* allowing the adding of items with a configurable status

This commit adds a number of new methods to the OmbiEntry class to mark
an entry as approved, available, requested, or denied. It also refactors
the add() method to support adding an entry with a status.

* fix the return value for already_requested when item not requested

* allow ombi_list to work with movies using imdb_id or tmdb_id

* add annotations backports to allow use of newer type hinting features

* add ability to specify how items are removed

This commit adds the on_remove config field to the ombi_list plugin.
This allows users to specify what happens to items when they are removed.
The default is to `delete` which clears the requested status from the
item in Ombi.

* use all the supported ids when searching the list for entrys

* change the API endpoint back to v1

* fix error checking with result is a list and not a dict

* add requestId propery to OmbiEntry class

If you use the /api/v1/Request/movie endpoint it will return all the
movies that have been requested. For some reason this endpoint does not
return the requestId. Then is needed to perform many other API actions,
like changing the status of the request to approved or denied.

I have added a property to the OmbiEntry for requestId. This property
will use the api/v2/Search endpoint which does return the requestId.

* fix issue with how Ombi items are filtered based on status

While testing I found out that an item in Ombi can be both approved and
denied at the same time. This meant I had to rework the filtering logic
to account for this.

I also found out that the /Search and /Request API's both return "items"
but the fields are different? For example when you perform a movie
search it will return a movie where the ID is the id for the movie and
the status is the status of the movie. But when you list all movie
requests you get a list of requests where the ID is the request ID and
the status is the status of the request. This seams obvious now but at
the time it wasn't because the structure of the JSON response for both
are nearly identical.

* make avaliable a seperate status than approved/denied

I also refactored movie filtering into its own function.

* handle url for episodes

* add ability to filter episodes by request status and availability

* add ability to request TV shows, seasons and episodes in Ombi

I'm still recovering from a cold so I don't have the energy to break
this up into multiple commits.  The main thing I did refactor how the
OmbiTv class works. It no longer accepts multiple Id's as I can only get
the tmdb_id to work with the Ombi APIs. I refactored how the
make_request method works. This way it was easy to implement it for both
OmbiMovie and OmbiTv. I also added a field called "ombi_title" so that
it prints the full title depending on if you have a show, season or
episode.

* refactor _find_entry to work with TV shows, seasons and episodes

This was needed to properly support list_match.

---------

Co-authored-by: bagobones <bagobones@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants