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

Creating plugins with inheritance #167

Open
imDMG opened this issue Apr 8, 2021 · 2 comments
Open

Creating plugins with inheritance #167

imDMG opened this issue Apr 8, 2021 · 2 comments

Comments

@imDMG
Copy link

imDMG commented Apr 8, 2021

I was thinking a lot, how about base class for plugins?

[spoiler] Something like this...
class BaseEngine(ABC):
  version: float
  authors: str

  """
  `url`, `name`, `supported_categories` should be static variables of the
  engine_name class, otherwise qbt won't install the plugin.

  `url`: The URL of the search engine.
  `name`: The name of the search engine, spaces and special characters are
          allowed here.
  `supported_categories`: What categories are supported by the search engine
                          and their corresponding id, possible categories are
                          ('all', 'movies', 'tv', 'music', 'games', 'anime',
                          'software', 'pictures', 'books').
  """
  name: str
  url: str
  supported_categories: dict = {'all': None}

  @property
  @abstractmethod
  def version(self) -> float: ...

  @property
  @abstractmethod
  def authors(self) -> str: ...

  @property
  @abstractmethod
  def name(self) -> str: ...

  @property
  @abstractmethod
  def url(self) -> str: ...

  @abstractmethod
  def search(self, what: str, cat: str):
      """
      Here you can do what you want to get the result from the search engine
      website.
      Everytime you parse a result line, store it in a dictionary and call
      the prettyPrint(your_dict) function.

      `what`: String with the search tokens, already escaped (e.g.
              "Ubuntu+Linux")
      `cat`: The name of a search category in ('all', 'movies', 'tv',
             'music', 'games', 'anime', 'software', 'pictures', 'books')
      """

  def download_torrent(self, info: str):
      """
      Providing this function is optional.
      It can however be interesting to provide your own torrent download
      implementation in case the search engine in question does not allow
      traditional downloads (for example, cookie-based download).
      """
      print(download_file(info))

It will help (i think) beginners to understand which attribute/method is required to implement.
Also, qbt developers will be able to manipulate some basic logic or engine behavior.

@imDMG
Copy link
Author

imDMG commented Apr 10, 2021

Plus two supporting methods to this class (these allways used):

[spoiler] Code
    def pretty_printer(self, engine_url: str, name: str, link: str, size: str,
                       seeds: str, leech: str, desc_link: str = None):
        size = str(self.any_size_to_bytes(size))
        text = "|".join([link, name.replace("|", " "), size, seeds, leech,
                         engine_url] + [desc_link] if desc_link else [])

        # fd 1 is stdout
        with open(1, 'w', encoding='utf-8', closefd=False) as utf8stdout:
            print(text, file=utf8stdout)

    @staticmethod
    def any_size_to_bytes(size_string: str):
        """
        Convert a string like '1 KB' to '1024' (bytes)
        Possible formats: 2.6Gb, 3,2 M, 5211564
        """
        # separate integer from unit
        size_string = size_string.strip()
        if not size_string[0].isdigit():
            return -1
        try:
            # get first literal
            unit = ''.join(filter(str.isalpha, size_string))[0]
        except IndexError:
            return int(size_string)
        size = size_string[:size_string.index(unit)].strip().replace(',', '.')

        # convert
        units_dict = {'T': 40, 'G': 30, 'M': 20, 'K': 10}
        return int(float(size) * 2 ** units_dict.get(unit.upper(), 0))

@ngosang
Copy link
Member

ngosang commented May 16, 2021

I agree with this change but I think it will be difficult to implement for the following reasons:

I'm not very active in this project but I'm open to review and accept PR as long as they are backwards compatible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants