diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -68,6 +68,7 @@ lister.gitlab=swh.lister.gitlab:register lister.gnu=swh.lister.gnu:register lister.golang=swh.lister.golang:register + lister.hackage=swh.lister.hackage:register lister.launchpad=swh.lister.launchpad:register lister.npm=swh.lister.npm:register lister.opam=swh.lister.opam:register diff --git a/swh/lister/hackage/__init__.py b/swh/lister/hackage/__init__.py new file mode 100644 --- /dev/null +++ b/swh/lister/hackage/__init__.py @@ -0,0 +1,99 @@ +# Copyright (C) 2022 The Software Heritage developers +# See the AUTHORS file at the top-level directory of this distribution +# License: GNU General Public License version 3, or any later version +# See top-level LICENSE file for more information + + +""" +Hackage lister +============== + +The Hackage lister list origins from `hackage.haskell.org`_, the `Haskell`_ Package +Repository. + +The registry provide an `http api`_ from where the lister retrieve package names +and build origins urls. + +As of August 2022 `hackage.haskell.org`_ list 15536 package names. + +Origins retrieving strategy +--------------------------- + +To get a list of all package names we make a POST call to +`https://hackage.haskell.org/packages/search` endpoint with some params given as +json data. + +Default params:: + + { + "page": 0, + "sortColumn": "default", + "sortDirection": "ascending", + "searchQuery": "(deprecated:any)", + } + +The page size is 50. The lister will make has much http api call has needed to get +all results. + +Page listing +------------ + +The result is paginated, each page is 50 records long. + +Entry data set example:: + + { + "description": "3D model parsers", + "downloads": 6, + "lastUpload": "2014-11-08T03:55:23.879047Z", + "maintainers": [{"display": "capsjac", "uri": "/user/capsjac"}], + "name": {"display": "3dmodels", "uri": "/package/3dmodels"}, + "tags": [ + {"display": "graphics", "uri": "/packages/tag/graphics"}, + {"display": "lgpl", "uri": "/packages/tag/lgpl"}, + {"display": "library", "uri": "/packages/tag/library"}, + ], + "votes": 1.5, + } + +Origins from page +----------------- + +The lister yields 50 origins url per page. +Each ListedOrigin has a `last_update` date set. + +Running tests +------------- + +Activate the virtualenv and run from within swh-lister directory:: + + pytest -s -vv --log-cli-level=DEBUG swh/lister/hackage/tests + +Testing with Docker +------------------- + +Change directory to swh/docker then launch the docker environment:: + + docker-compose up -d + +Then connect to the lister:: + + docker exec -it docker_swh-lister_1 bash + +And run the lister (The output of this listing results in “oneshot” tasks in the scheduler):: + + swh lister run -l hackage + +.. _hackage.haskell.org: https://hackage.haskell.org/ +.. _Haskell: https://haskell.org/ +.. _http api: https://hackage.haskell.org/api +""" + + +def register(): + from .lister import HackageLister + + return { + "lister": HackageLister, + "task_modules": ["%s.tasks" % __name__], + } diff --git a/swh/lister/hackage/lister.py b/swh/lister/hackage/lister.py new file mode 100644 --- /dev/null +++ b/swh/lister/hackage/lister.py @@ -0,0 +1,125 @@ +# Copyright (C) 2022 The Software Heritage developers +# See the AUTHORS file at the top-level directory of this distribution +# License: GNU General Public License version 3, or any later version +# See top-level LICENSE file for more information + +import logging +from typing import Any, Dict, Iterator, List, Optional + +import iso8601 +import requests +from tenacity.before_sleep import before_sleep_log + +from swh.lister.utils import throttling_retry +from swh.scheduler.interface import SchedulerInterface +from swh.scheduler.model import ListedOrigin + +from .. import USER_AGENT +from ..pattern import CredentialsType, StatelessLister + +logger = logging.getLogger(__name__) + +# Aliasing the page results returned by `get_pages` method from the lister. +HackageListerPage = List[Dict[str, Any]] + + +class HackageLister(StatelessLister[HackageListerPage]): + """List Hackage (The Haskell Package Repository) origins.""" + + LISTER_NAME = "hackage" + VISIT_TYPE = "hackage" + INSTANCE = "hackage" + + BASE_URL = "https://hackage.haskell.org/" + PACKAGE_NAMES_URL_PATTERN = "{base_url}packages/search" + PACKAGE_INFO_URL_PATTERN = "{base_url}package/{pkgname}" + + def __init__( + self, + scheduler: SchedulerInterface, + credentials: Optional[CredentialsType] = None, + url: Optional[str] = None, + ): + super().__init__( + scheduler=scheduler, + credentials=credentials, + instance=self.INSTANCE, + url=url if url else self.BASE_URL, + ) + self.session = requests.Session() + self.session.headers.update( + { + "Accept": "application/json", + "User-Agent": USER_AGENT, + } + ) + # Ensure to set this with same value as the http api search endpoint use + # (50 as of august 2022) + self.page_size: int = 50 + + @throttling_retry(before_sleep=before_sleep_log(logger, logging.WARNING)) + def page_request(self, url: str, params: Dict[str, Any]) -> requests.Response: + + logger.info("Fetching URL %s with params %s", url, params) + # We need to use POST for the search api + response = self.session.post(url, json=params) + if response.status_code != 200: + logger.warning( + "Unexpected HTTP status code %s on %s: %s", + response.status_code, + response.url, + response.content, + ) + response.raise_for_status() + + return response + + def get_pages(self) -> Iterator[HackageListerPage]: + """Yield an iterator which returns 'page' + + It uses the http api endpoint `https://hackage.haskell.org/packages/search` + to get a list of package names from which we build an origin url. + + Results are paginated. + """ + params = { + "page": 0, + "sortColumn": "default", + "sortDirection": "ascending", + "searchQuery": "(deprecated:any)", + } + + data = self.page_request( + url=self.PACKAGE_NAMES_URL_PATTERN.format(base_url=self.url), params=params + ).json() + + nb_entries: int = data["numberOfResults"] + (nb_pages, remainder) = divmod(nb_entries, self.page_size) + if remainder: + nb_pages += 1 + yield data["pageContents"] + + for page in range(1, nb_pages): + params["page"] = page + data = self.page_request( + url=self.PACKAGE_NAMES_URL_PATTERN.format(base_url=self.url), + params=params, + ).json() + yield data["pageContents"] + + def get_origins_from_page(self, page: HackageListerPage) -> Iterator[ListedOrigin]: + """Iterate on all pages and yield ListedOrigin instances.""" + assert self.lister_obj.id is not None + + for entry in page: + pkgname = entry["name"]["display"] + last_update = iso8601.parse_date(entry["lastUpload"]) + url = self.PACKAGE_INFO_URL_PATTERN.format( + base_url=self.url, pkgname=pkgname + ) + yield ListedOrigin( + lister_id=self.lister_obj.id, + visit_type=self.VISIT_TYPE, + url=url, + last_update=last_update, + ) diff --git a/swh/lister/hackage/tasks.py b/swh/lister/hackage/tasks.py new file mode 100644 --- /dev/null +++ b/swh/lister/hackage/tasks.py @@ -0,0 +1,19 @@ +# Copyright (C) 2022 The Software Heritage developers +# See the AUTHORS file at the top-level directory of this distribution +# License: GNU General Public License version 3, or any later version +# See top-level LICENSE file for more information + +from celery import shared_task + +from swh.lister.hackage.lister import HackageLister + + +@shared_task(name=__name__ + ".HackageListerTask") +def list_hackage(**lister_args): + """Lister task for Hackage, the Haskell Package Repository""" + return HackageLister.from_configfile(**lister_args).run().dict() + + +@shared_task(name=__name__ + ".ping") +def _ping(): + return "OK" diff --git a/swh/lister/hackage/tests/__init__.py b/swh/lister/hackage/tests/__init__.py new file mode 100644 diff --git a/swh/lister/hackage/tests/data/https_fake49.haskell.org/packages_search_0 b/swh/lister/hackage/tests/data/https_fake49.haskell.org/packages_search_0 new file mode 100644 --- /dev/null +++ b/swh/lister/hackage/tests/data/https_fake49.haskell.org/packages_search_0 @@ -0,0 +1 @@ +{"numberOfResults":49,"pageContents":[{"description":"Haskell package for easy integration with the 2captcha API.","downloads":1,"lastUpload":"2021-09-09T05:13:30.343509948Z","maintainers":[{"display":"qwbarch","uri":"/user/qwbarch"}],"name":{"display":"2captcha","uri":"/package/2captcha"},"tags":[{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"mit","uri":"/packages/tag/mit"},{"display":"network","uri":"/packages/tag/network"}],"votes":1.5},{"description":"Examples of 3D graphics programming with OpenGL","downloads":8,"lastUpload":"2016-07-22T14:26:23.038905Z","maintainers":[{"display":"WolfgangJeltsch","uri":"/user/WolfgangJeltsch"}],"name":{"display":"3d-graphics-examples","uri":"/package/3d-graphics-examples"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"fractals","uri":"/packages/tag/fractals"},{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"program","uri":"/packages/tag/program"}],"votes":1.75},{"description":"3D model parsers","downloads":6,"lastUpload":"2014-11-08T03:55:23.879047Z","maintainers":[{"display":"capsjac","uri":"/user/capsjac"}],"name":{"display":"3dmodels","uri":"/package/3dmodels"},"tags":[{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"lgpl","uri":"/packages/tag/lgpl"},{"display":"library","uri":"/packages/tag/library"}],"votes":1.5},{"description":"A tetris-like game (works with GHC 6.8.3 and Gtk2hs 0.9.13)","downloads":8,"lastUpload":"2010-05-07T18:55:25Z","maintainers":[{"display":"AndrewCalleja","uri":"/user/AndrewCalleja"}],"name":{"display":"4Blocks","uri":"/package/4Blocks"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"game","uri":"/packages/tag/game"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Abstract Application Interface.","downloads":8,"lastUpload":"2015-08-03T23:13:02.007983Z","maintainers":[{"display":"bash0r","uri":"/user/bash0r"}],"name":{"display":"AAI","uri":"/package/AAI"},"tags":[{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"},{"display":"mit","uri":"/packages/tag/mit"}],"votes":0},{"description":"An alternating list of two types","downloads":7,"lastUpload":"2014-06-23T21:53:36.114282Z","maintainers":[{"display":"DylanJust","uri":"/user/DylanJust"}],"name":{"display":"ABList","uri":"/package/ABList"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Angles in degrees and radians.","downloads":10,"lastUpload":"2010-07-23T14:10:27Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Angle","uri":"/package/AC-Angle"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"numerical","uri":"/packages/tag/numerical"}],"votes":0},{"description":"Handle Boolean values generatically.","downloads":4,"lastUpload":"2010-11-09T11:39:08Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Boolean","uri":"/package/AC-Boolean"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"},{"display":"logic","uri":"/packages/tag/logic"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"Detect which OS you're running on.","downloads":5,"lastUpload":"2011-06-08T10:12:03Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-BuildPlatform","uri":"/package/AC-BuildPlatform"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"system","uri":"/packages/tag/system"}],"votes":0},{"description":"Efficient RGB colour types.","downloads":12,"lastUpload":"2014-01-12T16:33:02.796921Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Colour","uri":"/package/AC-Colour"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"numerical","uri":"/packages/tag/numerical"}],"votes":0},{"description":"GTK+ pixel plotting.","downloads":5,"lastUpload":"2010-10-28T10:24:31Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-EasyRaster-GTK","uri":"/package/AC-EasyRaster-GTK"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Efficient half-integer type.","downloads":6,"lastUpload":"2009-08-12T19:15:37Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-HalfInteger","uri":"/package/AC-HalfInteger"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"numerical","uri":"/packages/tag/numerical"}],"votes":0},{"description":"A simple test framework.","downloads":7,"lastUpload":"2012-02-24T13:54:02Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-MiniTest","uri":"/package/AC-MiniTest"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"testing","uri":"/packages/tag/testing"}],"votes":0},{"description":"Trivial package for writing PPM images.","downloads":3,"lastUpload":"2010-01-18T22:26:54Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-PPM","uri":"/package/AC-PPM"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"codec","uri":"/packages/tag/codec"},{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"A pure Haskell PRNG.","downloads":1,"lastUpload":"2011-08-25T09:34:35Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Random","uri":"/package/AC-Random"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"random","uri":"/packages/tag/random"}],"votes":0},{"description":"Trivial wrapper over ansi-terminal.","downloads":2,"lastUpload":"2010-10-28T12:38:15Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Terminal","uri":"/package/AC-Terminal"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"numerical","uri":"/packages/tag/numerical"}],"votes":0},{"description":"Immutable arrays with plain integer indicies.","downloads":5,"lastUpload":"2010-01-17T13:34:07Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-VanillaArray","uri":"/package/AC-VanillaArray"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Efficient geometric vectors and transformations.","downloads":25,"lastUpload":"2011-08-12T12:33:08Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Vector","uri":"/package/AC-Vector"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"numerical","uri":"/packages/tag/numerical"}],"votes":0},{"description":"Fancy type-system stuff for AC-Vector","downloads":13,"lastUpload":"2010-08-15T15:34:26Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Vector-Fancy","uri":"/package/AC-Vector-Fancy"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"numerical","uri":"/packages/tag/numerical"}],"votes":0},{"description":"Essential features","downloads":4,"lastUpload":"2015-01-02T21:48:24.005724Z","maintainers":[{"display":"JamesCandy","uri":"/user/JamesCandy"}],"name":{"display":"ACME","uri":"/package/ACME"},"tags":[{"display":"acme","uri":"/packages/tag/acme"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"}],"votes":2.25},{"description":"Efficient, high-level dynamic programming.","downloads":41,"lastUpload":"2019-10-01T18:22:22.276688014Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"ADPfusion","uri":"/package/ADPfusion"},"tags":[{"display":"algorithms","uri":"/packages/tag/algorithms"},{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data-structures","uri":"/packages/tag/data-structures"},{"display":"formal-languages","uri":"/packages/tag/formal-languages"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Dynamic programming on tree and forest structures","downloads":2,"lastUpload":"2017-11-23T22:15:26.956207149Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"ADPfusionForest","uri":"/package/ADPfusionForest"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"formal-languages","uri":"/packages/tag/formal-languages"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Dynamic programming for Set data structures.","downloads":8,"lastUpload":"2017-10-19T14:36:27.804439921Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"ADPfusionSet","uri":"/package/ADPfusionSet"},"tags":[{"display":"algorithms","uri":"/packages/tag/algorithms"},{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data-structures","uri":"/packages/tag/data-structures"},{"display":"formal-languages","uri":"/packages/tag/formal-languages"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"foundational type classes for approximating exact real numbers","downloads":8,"lastUpload":"2011-05-11T11:25:48Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-Basics","uri":"/package/AERN-Basics"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Compositional lazy dataflow networks for exact real number computation","downloads":11,"lastUpload":"2009-07-29T10:06:08Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-Net","uri":"/package/AERN-Net"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"distributed-computing","uri":"/packages/tag/distributed-computing"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"arbitrary precision real interval arithmetic","downloads":39,"lastUpload":"2011-05-11T11:31:11Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-Real","uri":"/package/AERN-Real"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"arbitrary precision real interval arithmetic","downloads":10,"lastUpload":"2011-05-11T13:37:45Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-Real-Double","uri":"/package/AERN-Real-Double"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"arbitrary precision real interval arithmetic","downloads":11,"lastUpload":"2011-05-11T11:31:35Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-Real-Interval","uri":"/package/AERN-Real-Interval"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"polynomial function enclosures (PFEs) approximating exact real functions","downloads":26,"lastUpload":"2009-07-29T10:05:31Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-RnToRm","uri":"/package/AERN-RnToRm"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"GL plotting of polynomial function enclosures (PFEs)","downloads":15,"lastUpload":"2009-08-01T16:05:31Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-RnToRm-Plot","uri":"/package/AERN-RnToRm-Plot"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"Fast AES encryption/decryption for bytestrings","downloads":40,"lastUpload":"2014-05-07T21:04:03.888615Z","maintainers":[{"display":"SveinOveAas","uri":"/user/SveinOveAas"}],"name":{"display":"AES","uri":"/package/AES"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"cryptography","uri":"/packages/tag/cryptography"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Arrowized functional state machines","downloads":21,"lastUpload":"2016-04-21T22:13:19.148646Z","maintainers":[{"display":"hanzhxu","uri":"/user/hanzhxu"}],"name":{"display":"AFSM","uri":"/package/AFSM"},"tags":[{"display":"frp","uri":"/packages/tag/frp"},{"display":"library","uri":"/packages/tag/library"},{"display":"mit","uri":"/packages/tag/mit"}],"votes":2},{"description":"A library for writing AGI scripts for Asterisk","downloads":14,"lastUpload":"2009-12-07T20:12:57Z","maintainers":[{"display":"JeremyShaw","uri":"/user/JeremyShaw"}],"name":{"display":"AGI","uri":"/package/AGI"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"network","uri":"/packages/tag/network"}],"votes":0},{"description":"A binding for the OpenAL Utility Toolkit","downloads":38,"lastUpload":"2019-06-10T16:09:36.285351988Z","maintainers":[{"display":"StephenBlackheath","uri":"/user/StephenBlackheath"},{"display":"SvenPanne","uri":"/user/SvenPanne"}],"name":{"display":"ALUT","uri":"/package/ALUT"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"sound","uri":"/packages/tag/sound"}],"votes":0},{"description":"Low-level bindings for Asterisk Manager Interface (AMI).","downloads":2,"lastUpload":"2012-01-16T06:02:43Z","maintainers":[{"display":"IlyaPortnov","uri":"/user/IlyaPortnov"}],"name":{"display":"AMI","uri":"/package/AMI"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"network","uri":"/packages/tag/network"}],"votes":0},{"description":"Num instance for Applicatives provided via the ANum newtype","downloads":14,"lastUpload":"2018-02-13T00:06:58.303270679Z","maintainers":[{"display":"DanBurton","uri":"/user/DanBurton"}],"name":{"display":"ANum","uri":"/package/ANum"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"ASN.1 support for Haskell","downloads":4,"lastUpload":"2008-06-22T10:41:52Z","maintainers":[{"display":"HerbertValerioRiedel","uri":"/user/HerbertValerioRiedel"}],"name":{"display":"ASN1","uri":"/package/ASN1"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"language","uri":"/packages/tag/language"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Mutable variables with Exception handling and concurrency support.","downloads":11,"lastUpload":"2009-12-08T15:41:14Z","maintainers":[{"display":"AlexMason","uri":"/user/AlexMason"}],"name":{"display":"AVar","uri":"/package/AVar"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"concurrency","uri":"/packages/tag/concurrency"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"A binding to a part of the ANSI escape code for the console","downloads":2,"lastUpload":"2010-01-24T23:44:07Z","maintainers":[{"display":"HaraldWolfsgruber","uri":"/user/HaraldWolfsgruber"}],"name":{"display":"AWin32Console","uri":"/package/AWin32Console"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"system","uri":"/packages/tag/system"}],"votes":0},{"description":"Monads-tf instances for the AbortT monad transformer.","downloads":2,"lastUpload":"2012-12-07T13:58:51Z","maintainers":[{"display":"GregoryCrosswhite","uri":"/user/GregoryCrosswhite"}],"name":{"display":"AbortT-monadstf","uri":"/package/AbortT-monadstf"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"mtl instances for the AbortT monad transformer","downloads":8,"lastUpload":"2016-02-06T22:37:44.304337Z","maintainers":[{"display":"GregoryCrosswhite","uri":"/user/GregoryCrosswhite"}],"name":{"display":"AbortT-mtl","uri":"/package/AbortT-mtl"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"A monad and monadic transformer providing \"abort\" functionality","downloads":16,"lastUpload":"2019-07-19T14:08:41.889681784Z","maintainers":[{"display":"GregoryCrosswhite","uri":"/user/GregoryCrosswhite"}],"name":{"display":"AbortT-transformers","uri":"/package/AbortT-transformers"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"An easy-to-use video game framework for Haskell.","downloads":5,"lastUpload":"2014-11-11T00:20:57.714901Z","maintainers":[{"display":"AdityaBhargava","uri":"/user/AdityaBhargava"}],"name":{"display":"ActionKid","uri":"/package/ActionKid"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"game-engine","uri":"/packages/tag/game-engine"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Library for incremental computing.","downloads":11,"lastUpload":"2013-01-28T21:50:50Z","maintainers":[{"display":"DustinDeWeese","uri":"/user/DustinDeWeese"},{"display":"MagnusCarlsson","uri":"/user/MagnusCarlsson"},{"display":"PeterJonsson","uri":"/user/PeterJonsson"}],"name":{"display":"Adaptive","uri":"/package/Adaptive"},"tags":[{"display":"algorithms","uri":"/packages/tag/algorithms"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Library for incremental computing.","downloads":8,"lastUpload":"2013-01-26T09:17:43Z","maintainers":[{"display":"PaoloGiarrusso","uri":"/user/PaoloGiarrusso"}],"name":{"display":"Adaptive-Blaisorblade","uri":"/package/Adaptive-Blaisorblade"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Lisperati's adventure game in Lisp translated to Haskell","downloads":8,"lastUpload":"2010-06-11T00:01:05Z","maintainers":[{"display":"TimWawrzynczak","uri":"/user/TimWawrzynczak"}],"name":{"display":"Advgame","uri":"/package/Advgame"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"game","uri":"/packages/tag/game"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Assessment services for the Advise-Me project","downloads":7,"lastUpload":"2019-10-30T07:45:20.345073378Z","maintainers":[{"display":"BastiaanHeeren","uri":"/user/BastiaanHeeren"}],"name":{"display":"Advise-me","uri":"/package/Advise-me"},"tags":[{"display":"apache","uri":"/packages/tag/apache"},{"display":"education","uri":"/packages/tag/education"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Mapping between Aeson's JSON and Bson objects.","downloads":24,"lastUpload":"2022-05-06T10:41:14.015254306Z","maintainers":[{"display":"AndrasSlemmer","uri":"/user/AndrasSlemmer"},{"display":"NiklasHambuechen","uri":"/user/NiklasHambuechen"}],"name":{"display":"AesonBson","uri":"/package/AesonBson"},"tags":[{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Generator-generator for QuickCheck","downloads":10,"lastUpload":"2012-08-01T11:36:04Z","maintainers":[{"display":"JonasDuregard","uri":"/user/JonasDuregard"}],"name":{"display":"Agata","uri":"/package/Agata"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"deprecated","uri":"/packages/tag/deprecated"}],"votes":2.75}]} diff --git a/swh/lister/hackage/tests/data/https_fake51.haskell.org/packages_search_0 b/swh/lister/hackage/tests/data/https_fake51.haskell.org/packages_search_0 new file mode 100644 --- /dev/null +++ b/swh/lister/hackage/tests/data/https_fake51.haskell.org/packages_search_0 @@ -0,0 +1 @@ +{"numberOfResults":51,"pageContents":[{"description":"Haskell package for easy integration with the 2captcha API.","downloads":1,"lastUpload":"2021-09-09T05:13:30.343509948Z","maintainers":[{"display":"qwbarch","uri":"/user/qwbarch"}],"name":{"display":"2captcha","uri":"/package/2captcha"},"tags":[{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"mit","uri":"/packages/tag/mit"},{"display":"network","uri":"/packages/tag/network"}],"votes":1.5},{"description":"Examples of 3D graphics programming with OpenGL","downloads":8,"lastUpload":"2016-07-22T14:26:23.038905Z","maintainers":[{"display":"WolfgangJeltsch","uri":"/user/WolfgangJeltsch"}],"name":{"display":"3d-graphics-examples","uri":"/package/3d-graphics-examples"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"fractals","uri":"/packages/tag/fractals"},{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"program","uri":"/packages/tag/program"}],"votes":1.75},{"description":"3D model parsers","downloads":6,"lastUpload":"2014-11-08T03:55:23.879047Z","maintainers":[{"display":"capsjac","uri":"/user/capsjac"}],"name":{"display":"3dmodels","uri":"/package/3dmodels"},"tags":[{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"lgpl","uri":"/packages/tag/lgpl"},{"display":"library","uri":"/packages/tag/library"}],"votes":1.5},{"description":"A tetris-like game (works with GHC 6.8.3 and Gtk2hs 0.9.13)","downloads":8,"lastUpload":"2010-05-07T18:55:25Z","maintainers":[{"display":"AndrewCalleja","uri":"/user/AndrewCalleja"}],"name":{"display":"4Blocks","uri":"/package/4Blocks"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"game","uri":"/packages/tag/game"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Abstract Application Interface.","downloads":8,"lastUpload":"2015-08-03T23:13:02.007983Z","maintainers":[{"display":"bash0r","uri":"/user/bash0r"}],"name":{"display":"AAI","uri":"/package/AAI"},"tags":[{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"},{"display":"mit","uri":"/packages/tag/mit"}],"votes":0},{"description":"An alternating list of two types","downloads":7,"lastUpload":"2014-06-23T21:53:36.114282Z","maintainers":[{"display":"DylanJust","uri":"/user/DylanJust"}],"name":{"display":"ABList","uri":"/package/ABList"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Angles in degrees and radians.","downloads":10,"lastUpload":"2010-07-23T14:10:27Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Angle","uri":"/package/AC-Angle"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"numerical","uri":"/packages/tag/numerical"}],"votes":0},{"description":"Handle Boolean values generatically.","downloads":4,"lastUpload":"2010-11-09T11:39:08Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Boolean","uri":"/package/AC-Boolean"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"},{"display":"logic","uri":"/packages/tag/logic"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"Detect which OS you're running on.","downloads":5,"lastUpload":"2011-06-08T10:12:03Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-BuildPlatform","uri":"/package/AC-BuildPlatform"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"system","uri":"/packages/tag/system"}],"votes":0},{"description":"Efficient RGB colour types.","downloads":12,"lastUpload":"2014-01-12T16:33:02.796921Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Colour","uri":"/package/AC-Colour"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"numerical","uri":"/packages/tag/numerical"}],"votes":0},{"description":"GTK+ pixel plotting.","downloads":5,"lastUpload":"2010-10-28T10:24:31Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-EasyRaster-GTK","uri":"/package/AC-EasyRaster-GTK"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Efficient half-integer type.","downloads":6,"lastUpload":"2009-08-12T19:15:37Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-HalfInteger","uri":"/package/AC-HalfInteger"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"numerical","uri":"/packages/tag/numerical"}],"votes":0},{"description":"A simple test framework.","downloads":7,"lastUpload":"2012-02-24T13:54:02Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-MiniTest","uri":"/package/AC-MiniTest"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"testing","uri":"/packages/tag/testing"}],"votes":0},{"description":"Trivial package for writing PPM images.","downloads":3,"lastUpload":"2010-01-18T22:26:54Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-PPM","uri":"/package/AC-PPM"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"codec","uri":"/packages/tag/codec"},{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"A pure Haskell PRNG.","downloads":1,"lastUpload":"2011-08-25T09:34:35Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Random","uri":"/package/AC-Random"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"random","uri":"/packages/tag/random"}],"votes":0},{"description":"Trivial wrapper over ansi-terminal.","downloads":2,"lastUpload":"2010-10-28T12:38:15Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Terminal","uri":"/package/AC-Terminal"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"numerical","uri":"/packages/tag/numerical"}],"votes":0},{"description":"Immutable arrays with plain integer indicies.","downloads":5,"lastUpload":"2010-01-17T13:34:07Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-VanillaArray","uri":"/package/AC-VanillaArray"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Efficient geometric vectors and transformations.","downloads":25,"lastUpload":"2011-08-12T12:33:08Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Vector","uri":"/package/AC-Vector"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"numerical","uri":"/packages/tag/numerical"}],"votes":0},{"description":"Fancy type-system stuff for AC-Vector","downloads":13,"lastUpload":"2010-08-15T15:34:26Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Vector-Fancy","uri":"/package/AC-Vector-Fancy"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"numerical","uri":"/packages/tag/numerical"}],"votes":0},{"description":"Essential features","downloads":4,"lastUpload":"2015-01-02T21:48:24.005724Z","maintainers":[{"display":"JamesCandy","uri":"/user/JamesCandy"}],"name":{"display":"ACME","uri":"/package/ACME"},"tags":[{"display":"acme","uri":"/packages/tag/acme"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"}],"votes":2.25},{"description":"Efficient, high-level dynamic programming.","downloads":41,"lastUpload":"2019-10-01T18:22:22.276688014Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"ADPfusion","uri":"/package/ADPfusion"},"tags":[{"display":"algorithms","uri":"/packages/tag/algorithms"},{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data-structures","uri":"/packages/tag/data-structures"},{"display":"formal-languages","uri":"/packages/tag/formal-languages"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Dynamic programming on tree and forest structures","downloads":2,"lastUpload":"2017-11-23T22:15:26.956207149Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"ADPfusionForest","uri":"/package/ADPfusionForest"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"formal-languages","uri":"/packages/tag/formal-languages"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Dynamic programming for Set data structures.","downloads":8,"lastUpload":"2017-10-19T14:36:27.804439921Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"ADPfusionSet","uri":"/package/ADPfusionSet"},"tags":[{"display":"algorithms","uri":"/packages/tag/algorithms"},{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data-structures","uri":"/packages/tag/data-structures"},{"display":"formal-languages","uri":"/packages/tag/formal-languages"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"foundational type classes for approximating exact real numbers","downloads":8,"lastUpload":"2011-05-11T11:25:48Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-Basics","uri":"/package/AERN-Basics"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Compositional lazy dataflow networks for exact real number computation","downloads":11,"lastUpload":"2009-07-29T10:06:08Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-Net","uri":"/package/AERN-Net"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"distributed-computing","uri":"/packages/tag/distributed-computing"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"arbitrary precision real interval arithmetic","downloads":39,"lastUpload":"2011-05-11T11:31:11Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-Real","uri":"/package/AERN-Real"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"arbitrary precision real interval arithmetic","downloads":10,"lastUpload":"2011-05-11T13:37:45Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-Real-Double","uri":"/package/AERN-Real-Double"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"arbitrary precision real interval arithmetic","downloads":11,"lastUpload":"2011-05-11T11:31:35Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-Real-Interval","uri":"/package/AERN-Real-Interval"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"polynomial function enclosures (PFEs) approximating exact real functions","downloads":26,"lastUpload":"2009-07-29T10:05:31Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-RnToRm","uri":"/package/AERN-RnToRm"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"GL plotting of polynomial function enclosures (PFEs)","downloads":15,"lastUpload":"2009-08-01T16:05:31Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-RnToRm-Plot","uri":"/package/AERN-RnToRm-Plot"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"Fast AES encryption/decryption for bytestrings","downloads":40,"lastUpload":"2014-05-07T21:04:03.888615Z","maintainers":[{"display":"SveinOveAas","uri":"/user/SveinOveAas"}],"name":{"display":"AES","uri":"/package/AES"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"cryptography","uri":"/packages/tag/cryptography"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Arrowized functional state machines","downloads":21,"lastUpload":"2016-04-21T22:13:19.148646Z","maintainers":[{"display":"hanzhxu","uri":"/user/hanzhxu"}],"name":{"display":"AFSM","uri":"/package/AFSM"},"tags":[{"display":"frp","uri":"/packages/tag/frp"},{"display":"library","uri":"/packages/tag/library"},{"display":"mit","uri":"/packages/tag/mit"}],"votes":2},{"description":"A library for writing AGI scripts for Asterisk","downloads":14,"lastUpload":"2009-12-07T20:12:57Z","maintainers":[{"display":"JeremyShaw","uri":"/user/JeremyShaw"}],"name":{"display":"AGI","uri":"/package/AGI"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"network","uri":"/packages/tag/network"}],"votes":0},{"description":"A binding for the OpenAL Utility Toolkit","downloads":38,"lastUpload":"2019-06-10T16:09:36.285351988Z","maintainers":[{"display":"StephenBlackheath","uri":"/user/StephenBlackheath"},{"display":"SvenPanne","uri":"/user/SvenPanne"}],"name":{"display":"ALUT","uri":"/package/ALUT"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"sound","uri":"/packages/tag/sound"}],"votes":0},{"description":"Low-level bindings for Asterisk Manager Interface (AMI).","downloads":2,"lastUpload":"2012-01-16T06:02:43Z","maintainers":[{"display":"IlyaPortnov","uri":"/user/IlyaPortnov"}],"name":{"display":"AMI","uri":"/package/AMI"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"network","uri":"/packages/tag/network"}],"votes":0},{"description":"Num instance for Applicatives provided via the ANum newtype","downloads":14,"lastUpload":"2018-02-13T00:06:58.303270679Z","maintainers":[{"display":"DanBurton","uri":"/user/DanBurton"}],"name":{"display":"ANum","uri":"/package/ANum"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"ASN.1 support for Haskell","downloads":4,"lastUpload":"2008-06-22T10:41:52Z","maintainers":[{"display":"HerbertValerioRiedel","uri":"/user/HerbertValerioRiedel"}],"name":{"display":"ASN1","uri":"/package/ASN1"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"language","uri":"/packages/tag/language"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Mutable variables with Exception handling and concurrency support.","downloads":11,"lastUpload":"2009-12-08T15:41:14Z","maintainers":[{"display":"AlexMason","uri":"/user/AlexMason"}],"name":{"display":"AVar","uri":"/package/AVar"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"concurrency","uri":"/packages/tag/concurrency"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"A binding to a part of the ANSI escape code for the console","downloads":2,"lastUpload":"2010-01-24T23:44:07Z","maintainers":[{"display":"HaraldWolfsgruber","uri":"/user/HaraldWolfsgruber"}],"name":{"display":"AWin32Console","uri":"/package/AWin32Console"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"system","uri":"/packages/tag/system"}],"votes":0},{"description":"Monads-tf instances for the AbortT monad transformer.","downloads":2,"lastUpload":"2012-12-07T13:58:51Z","maintainers":[{"display":"GregoryCrosswhite","uri":"/user/GregoryCrosswhite"}],"name":{"display":"AbortT-monadstf","uri":"/package/AbortT-monadstf"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"mtl instances for the AbortT monad transformer","downloads":8,"lastUpload":"2016-02-06T22:37:44.304337Z","maintainers":[{"display":"GregoryCrosswhite","uri":"/user/GregoryCrosswhite"}],"name":{"display":"AbortT-mtl","uri":"/package/AbortT-mtl"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"A monad and monadic transformer providing \"abort\" functionality","downloads":16,"lastUpload":"2019-07-19T14:08:41.889681784Z","maintainers":[{"display":"GregoryCrosswhite","uri":"/user/GregoryCrosswhite"}],"name":{"display":"AbortT-transformers","uri":"/package/AbortT-transformers"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"An easy-to-use video game framework for Haskell.","downloads":5,"lastUpload":"2014-11-11T00:20:57.714901Z","maintainers":[{"display":"AdityaBhargava","uri":"/user/AdityaBhargava"}],"name":{"display":"ActionKid","uri":"/package/ActionKid"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"game-engine","uri":"/packages/tag/game-engine"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Library for incremental computing.","downloads":11,"lastUpload":"2013-01-28T21:50:50Z","maintainers":[{"display":"DustinDeWeese","uri":"/user/DustinDeWeese"},{"display":"MagnusCarlsson","uri":"/user/MagnusCarlsson"},{"display":"PeterJonsson","uri":"/user/PeterJonsson"}],"name":{"display":"Adaptive","uri":"/package/Adaptive"},"tags":[{"display":"algorithms","uri":"/packages/tag/algorithms"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Library for incremental computing.","downloads":8,"lastUpload":"2013-01-26T09:17:43Z","maintainers":[{"display":"PaoloGiarrusso","uri":"/user/PaoloGiarrusso"}],"name":{"display":"Adaptive-Blaisorblade","uri":"/package/Adaptive-Blaisorblade"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Lisperati's adventure game in Lisp translated to Haskell","downloads":8,"lastUpload":"2010-06-11T00:01:05Z","maintainers":[{"display":"TimWawrzynczak","uri":"/user/TimWawrzynczak"}],"name":{"display":"Advgame","uri":"/package/Advgame"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"game","uri":"/packages/tag/game"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Assessment services for the Advise-Me project","downloads":7,"lastUpload":"2019-10-30T07:45:20.345073378Z","maintainers":[{"display":"BastiaanHeeren","uri":"/user/BastiaanHeeren"}],"name":{"display":"Advise-me","uri":"/package/Advise-me"},"tags":[{"display":"apache","uri":"/packages/tag/apache"},{"display":"education","uri":"/packages/tag/education"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Mapping between Aeson's JSON and Bson objects.","downloads":24,"lastUpload":"2022-05-06T10:41:14.015254306Z","maintainers":[{"display":"AndrasSlemmer","uri":"/user/AndrasSlemmer"},{"display":"NiklasHambuechen","uri":"/user/NiklasHambuechen"}],"name":{"display":"AesonBson","uri":"/package/AesonBson"},"tags":[{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Generator-generator for QuickCheck","downloads":10,"lastUpload":"2012-08-01T11:36:04Z","maintainers":[{"display":"JonasDuregard","uri":"/user/JonasDuregard"}],"name":{"display":"Agata","uri":"/package/Agata"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"testing","uri":"/packages/tag/testing"}],"votes":0},{"description":"A dependently typed functional programming language and proof assistant","downloads":306,"lastUpload":"2022-04-02T18:00:16.805589944Z","maintainers":[{"display":"AndreasAbel","uri":"/user/AndreasAbel"},{"display":"AndresSicardRamirez","uri":"/user/AndresSicardRamirez"},{"display":"NilsAndersDanielsson","uri":"/user/NilsAndersDanielsson"},{"display":"UlfNorell","uri":"/user/UlfNorell"}],"name":{"display":"Agda","uri":"/package/Agda"},"tags":[{"display":"dependent-types","uri":"/packages/tag/dependent-types"},{"display":"program","uri":"/packages/tag/program"}],"votes":2.75}]} diff --git a/swh/lister/hackage/tests/data/https_fake51.haskell.org/packages_search_1 b/swh/lister/hackage/tests/data/https_fake51.haskell.org/packages_search_1 new file mode 100644 --- /dev/null +++ b/swh/lister/hackage/tests/data/https_fake51.haskell.org/packages_search_1 @@ -0,0 +1 @@ +{"numberOfResults":51,"pageContents":[{"description":"Command-line program for type-checking and compiling Agda programs","downloads":20,"lastUpload":"2012-03-12T11:01:45Z","maintainers":[{"display":"NilsAndersDanielsson","uri":"/user/NilsAndersDanielsson"},{"display":"UlfNorell","uri":"/user/UlfNorell"}],"name":{"display":"Agda-executable","uri":"/package/Agda-executable"},"tags":[{"display":"dependent-types","uri":"/packages/tag/dependent-types"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"program","uri":"/packages/tag/program"}],"votes":0}]} diff --git a/swh/lister/hackage/tests/data/https_hackage.haskell.org/packages_search_0 b/swh/lister/hackage/tests/data/https_hackage.haskell.org/packages_search_0 new file mode 100644 --- /dev/null +++ b/swh/lister/hackage/tests/data/https_hackage.haskell.org/packages_search_0 @@ -0,0 +1 @@ +{"numberOfResults":150,"pageContents":[{"description":"Haskell package for easy integration with the 2captcha API.","downloads":1,"lastUpload":"2021-09-09T05:13:30.343509948Z","maintainers":[{"display":"qwbarch","uri":"/user/qwbarch"}],"name":{"display":"2captcha","uri":"/package/2captcha"},"tags":[{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"mit","uri":"/packages/tag/mit"},{"display":"network","uri":"/packages/tag/network"}],"votes":1.5},{"description":"Examples of 3D graphics programming with OpenGL","downloads":8,"lastUpload":"2016-07-22T14:26:23.038905Z","maintainers":[{"display":"WolfgangJeltsch","uri":"/user/WolfgangJeltsch"}],"name":{"display":"3d-graphics-examples","uri":"/package/3d-graphics-examples"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"fractals","uri":"/packages/tag/fractals"},{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"program","uri":"/packages/tag/program"}],"votes":1.75},{"description":"3D model parsers","downloads":6,"lastUpload":"2014-11-08T03:55:23.879047Z","maintainers":[{"display":"capsjac","uri":"/user/capsjac"}],"name":{"display":"3dmodels","uri":"/package/3dmodels"},"tags":[{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"lgpl","uri":"/packages/tag/lgpl"},{"display":"library","uri":"/packages/tag/library"}],"votes":1.5},{"description":"A tetris-like game (works with GHC 6.8.3 and Gtk2hs 0.9.13)","downloads":8,"lastUpload":"2010-05-07T18:55:25Z","maintainers":[{"display":"AndrewCalleja","uri":"/user/AndrewCalleja"}],"name":{"display":"4Blocks","uri":"/package/4Blocks"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"game","uri":"/packages/tag/game"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Abstract Application Interface.","downloads":8,"lastUpload":"2015-08-03T23:13:02.007983Z","maintainers":[{"display":"bash0r","uri":"/user/bash0r"}],"name":{"display":"AAI","uri":"/package/AAI"},"tags":[{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"},{"display":"mit","uri":"/packages/tag/mit"}],"votes":0},{"description":"An alternating list of two types","downloads":7,"lastUpload":"2014-06-23T21:53:36.114282Z","maintainers":[{"display":"DylanJust","uri":"/user/DylanJust"}],"name":{"display":"ABList","uri":"/package/ABList"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Angles in degrees and radians.","downloads":10,"lastUpload":"2010-07-23T14:10:27Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Angle","uri":"/package/AC-Angle"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"numerical","uri":"/packages/tag/numerical"}],"votes":0},{"description":"Handle Boolean values generatically.","downloads":4,"lastUpload":"2010-11-09T11:39:08Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Boolean","uri":"/package/AC-Boolean"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"},{"display":"logic","uri":"/packages/tag/logic"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"Detect which OS you're running on.","downloads":5,"lastUpload":"2011-06-08T10:12:03Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-BuildPlatform","uri":"/package/AC-BuildPlatform"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"system","uri":"/packages/tag/system"}],"votes":0},{"description":"Efficient RGB colour types.","downloads":12,"lastUpload":"2014-01-12T16:33:02.796921Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Colour","uri":"/package/AC-Colour"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"numerical","uri":"/packages/tag/numerical"}],"votes":0},{"description":"GTK+ pixel plotting.","downloads":5,"lastUpload":"2010-10-28T10:24:31Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-EasyRaster-GTK","uri":"/package/AC-EasyRaster-GTK"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Efficient half-integer type.","downloads":6,"lastUpload":"2009-08-12T19:15:37Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-HalfInteger","uri":"/package/AC-HalfInteger"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"numerical","uri":"/packages/tag/numerical"}],"votes":0},{"description":"A simple test framework.","downloads":7,"lastUpload":"2012-02-24T13:54:02Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-MiniTest","uri":"/package/AC-MiniTest"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"testing","uri":"/packages/tag/testing"}],"votes":0},{"description":"Trivial package for writing PPM images.","downloads":3,"lastUpload":"2010-01-18T22:26:54Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-PPM","uri":"/package/AC-PPM"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"codec","uri":"/packages/tag/codec"},{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"A pure Haskell PRNG.","downloads":1,"lastUpload":"2011-08-25T09:34:35Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Random","uri":"/package/AC-Random"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"random","uri":"/packages/tag/random"}],"votes":0},{"description":"Trivial wrapper over ansi-terminal.","downloads":2,"lastUpload":"2010-10-28T12:38:15Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Terminal","uri":"/package/AC-Terminal"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"numerical","uri":"/packages/tag/numerical"}],"votes":0},{"description":"Immutable arrays with plain integer indicies.","downloads":5,"lastUpload":"2010-01-17T13:34:07Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-VanillaArray","uri":"/package/AC-VanillaArray"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Efficient geometric vectors and transformations.","downloads":25,"lastUpload":"2011-08-12T12:33:08Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Vector","uri":"/package/AC-Vector"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"numerical","uri":"/packages/tag/numerical"}],"votes":0},{"description":"Fancy type-system stuff for AC-Vector","downloads":13,"lastUpload":"2010-08-15T15:34:26Z","maintainers":[{"display":"AndrewCoppin","uri":"/user/AndrewCoppin"}],"name":{"display":"AC-Vector-Fancy","uri":"/package/AC-Vector-Fancy"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"numerical","uri":"/packages/tag/numerical"}],"votes":0},{"description":"Essential features","downloads":4,"lastUpload":"2015-01-02T21:48:24.005724Z","maintainers":[{"display":"JamesCandy","uri":"/user/JamesCandy"}],"name":{"display":"ACME","uri":"/package/ACME"},"tags":[{"display":"acme","uri":"/packages/tag/acme"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"}],"votes":2.25},{"description":"Efficient, high-level dynamic programming.","downloads":41,"lastUpload":"2019-10-01T18:22:22.276688014Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"ADPfusion","uri":"/package/ADPfusion"},"tags":[{"display":"algorithms","uri":"/packages/tag/algorithms"},{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data-structures","uri":"/packages/tag/data-structures"},{"display":"formal-languages","uri":"/packages/tag/formal-languages"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Dynamic programming on tree and forest structures","downloads":2,"lastUpload":"2017-11-23T22:15:26.956207149Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"ADPfusionForest","uri":"/package/ADPfusionForest"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"formal-languages","uri":"/packages/tag/formal-languages"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Dynamic programming for Set data structures.","downloads":8,"lastUpload":"2017-10-19T14:36:27.804439921Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"ADPfusionSet","uri":"/package/ADPfusionSet"},"tags":[{"display":"algorithms","uri":"/packages/tag/algorithms"},{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data-structures","uri":"/packages/tag/data-structures"},{"display":"formal-languages","uri":"/packages/tag/formal-languages"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"foundational type classes for approximating exact real numbers","downloads":8,"lastUpload":"2011-05-11T11:25:48Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-Basics","uri":"/package/AERN-Basics"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Compositional lazy dataflow networks for exact real number computation","downloads":11,"lastUpload":"2009-07-29T10:06:08Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-Net","uri":"/package/AERN-Net"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"distributed-computing","uri":"/packages/tag/distributed-computing"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"arbitrary precision real interval arithmetic","downloads":39,"lastUpload":"2011-05-11T11:31:11Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-Real","uri":"/package/AERN-Real"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"arbitrary precision real interval arithmetic","downloads":10,"lastUpload":"2011-05-11T13:37:45Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-Real-Double","uri":"/package/AERN-Real-Double"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"arbitrary precision real interval arithmetic","downloads":11,"lastUpload":"2011-05-11T11:31:35Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-Real-Interval","uri":"/package/AERN-Real-Interval"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"polynomial function enclosures (PFEs) approximating exact real functions","downloads":26,"lastUpload":"2009-07-29T10:05:31Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-RnToRm","uri":"/package/AERN-RnToRm"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"GL plotting of polynomial function enclosures (PFEs)","downloads":15,"lastUpload":"2009-08-01T16:05:31Z","maintainers":[{"display":"MichalKonecny","uri":"/user/MichalKonecny"}],"name":{"display":"AERN-RnToRm-Plot","uri":"/package/AERN-RnToRm-Plot"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"Fast AES encryption/decryption for bytestrings","downloads":40,"lastUpload":"2014-05-07T21:04:03.888615Z","maintainers":[{"display":"SveinOveAas","uri":"/user/SveinOveAas"}],"name":{"display":"AES","uri":"/package/AES"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"cryptography","uri":"/packages/tag/cryptography"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Arrowized functional state machines","downloads":21,"lastUpload":"2016-04-21T22:13:19.148646Z","maintainers":[{"display":"hanzhxu","uri":"/user/hanzhxu"}],"name":{"display":"AFSM","uri":"/package/AFSM"},"tags":[{"display":"frp","uri":"/packages/tag/frp"},{"display":"library","uri":"/packages/tag/library"},{"display":"mit","uri":"/packages/tag/mit"}],"votes":2},{"description":"A library for writing AGI scripts for Asterisk","downloads":14,"lastUpload":"2009-12-07T20:12:57Z","maintainers":[{"display":"JeremyShaw","uri":"/user/JeremyShaw"}],"name":{"display":"AGI","uri":"/package/AGI"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"network","uri":"/packages/tag/network"}],"votes":0},{"description":"A binding for the OpenAL Utility Toolkit","downloads":38,"lastUpload":"2019-06-10T16:09:36.285351988Z","maintainers":[{"display":"StephenBlackheath","uri":"/user/StephenBlackheath"},{"display":"SvenPanne","uri":"/user/SvenPanne"}],"name":{"display":"ALUT","uri":"/package/ALUT"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"sound","uri":"/packages/tag/sound"}],"votes":0},{"description":"Low-level bindings for Asterisk Manager Interface (AMI).","downloads":2,"lastUpload":"2012-01-16T06:02:43Z","maintainers":[{"display":"IlyaPortnov","uri":"/user/IlyaPortnov"}],"name":{"display":"AMI","uri":"/package/AMI"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"network","uri":"/packages/tag/network"}],"votes":0},{"description":"Num instance for Applicatives provided via the ANum newtype","downloads":14,"lastUpload":"2018-02-13T00:06:58.303270679Z","maintainers":[{"display":"DanBurton","uri":"/user/DanBurton"}],"name":{"display":"ANum","uri":"/package/ANum"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"ASN.1 support for Haskell","downloads":4,"lastUpload":"2008-06-22T10:41:52Z","maintainers":[{"display":"HerbertValerioRiedel","uri":"/user/HerbertValerioRiedel"}],"name":{"display":"ASN1","uri":"/package/ASN1"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"language","uri":"/packages/tag/language"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Mutable variables with Exception handling and concurrency support.","downloads":11,"lastUpload":"2009-12-08T15:41:14Z","maintainers":[{"display":"AlexMason","uri":"/user/AlexMason"}],"name":{"display":"AVar","uri":"/package/AVar"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"concurrency","uri":"/packages/tag/concurrency"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"A binding to a part of the ANSI escape code for the console","downloads":2,"lastUpload":"2010-01-24T23:44:07Z","maintainers":[{"display":"HaraldWolfsgruber","uri":"/user/HaraldWolfsgruber"}],"name":{"display":"AWin32Console","uri":"/package/AWin32Console"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"system","uri":"/packages/tag/system"}],"votes":0},{"description":"Monads-tf instances for the AbortT monad transformer.","downloads":2,"lastUpload":"2012-12-07T13:58:51Z","maintainers":[{"display":"GregoryCrosswhite","uri":"/user/GregoryCrosswhite"}],"name":{"display":"AbortT-monadstf","uri":"/package/AbortT-monadstf"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"mtl instances for the AbortT monad transformer","downloads":8,"lastUpload":"2016-02-06T22:37:44.304337Z","maintainers":[{"display":"GregoryCrosswhite","uri":"/user/GregoryCrosswhite"}],"name":{"display":"AbortT-mtl","uri":"/package/AbortT-mtl"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"A monad and monadic transformer providing \"abort\" functionality","downloads":16,"lastUpload":"2019-07-19T14:08:41.889681784Z","maintainers":[{"display":"GregoryCrosswhite","uri":"/user/GregoryCrosswhite"}],"name":{"display":"AbortT-transformers","uri":"/package/AbortT-transformers"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"An easy-to-use video game framework for Haskell.","downloads":5,"lastUpload":"2014-11-11T00:20:57.714901Z","maintainers":[{"display":"AdityaBhargava","uri":"/user/AdityaBhargava"}],"name":{"display":"ActionKid","uri":"/package/ActionKid"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"game-engine","uri":"/packages/tag/game-engine"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Library for incremental computing.","downloads":11,"lastUpload":"2013-01-28T21:50:50Z","maintainers":[{"display":"DustinDeWeese","uri":"/user/DustinDeWeese"},{"display":"MagnusCarlsson","uri":"/user/MagnusCarlsson"},{"display":"PeterJonsson","uri":"/user/PeterJonsson"}],"name":{"display":"Adaptive","uri":"/package/Adaptive"},"tags":[{"display":"algorithms","uri":"/packages/tag/algorithms"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Library for incremental computing.","downloads":8,"lastUpload":"2013-01-26T09:17:43Z","maintainers":[{"display":"PaoloGiarrusso","uri":"/user/PaoloGiarrusso"}],"name":{"display":"Adaptive-Blaisorblade","uri":"/package/Adaptive-Blaisorblade"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Lisperati's adventure game in Lisp translated to Haskell","downloads":8,"lastUpload":"2010-06-11T00:01:05Z","maintainers":[{"display":"TimWawrzynczak","uri":"/user/TimWawrzynczak"}],"name":{"display":"Advgame","uri":"/package/Advgame"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"game","uri":"/packages/tag/game"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Assessment services for the Advise-Me project","downloads":7,"lastUpload":"2019-10-30T07:45:20.345073378Z","maintainers":[{"display":"BastiaanHeeren","uri":"/user/BastiaanHeeren"}],"name":{"display":"Advise-me","uri":"/package/Advise-me"},"tags":[{"display":"apache","uri":"/packages/tag/apache"},{"display":"education","uri":"/packages/tag/education"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Mapping between Aeson's JSON and Bson objects.","downloads":24,"lastUpload":"2022-05-06T10:41:14.015254306Z","maintainers":[{"display":"AndrasSlemmer","uri":"/user/AndrasSlemmer"},{"display":"NiklasHambuechen","uri":"/user/NiklasHambuechen"}],"name":{"display":"AesonBson","uri":"/package/AesonBson"},"tags":[{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Generator-generator for QuickCheck","downloads":10,"lastUpload":"2012-08-01T11:36:04Z","maintainers":[{"display":"JonasDuregard","uri":"/user/JonasDuregard"}],"name":{"display":"Agata","uri":"/package/Agata"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"testing","uri":"/packages/tag/testing"}],"votes":0},{"description":"A dependently typed functional programming language and proof assistant","downloads":306,"lastUpload":"2022-04-02T18:00:16.805589944Z","maintainers":[{"display":"AndreasAbel","uri":"/user/AndreasAbel"},{"display":"AndresSicardRamirez","uri":"/user/AndresSicardRamirez"},{"display":"NilsAndersDanielsson","uri":"/user/NilsAndersDanielsson"},{"display":"UlfNorell","uri":"/user/UlfNorell"}],"name":{"display":"Agda","uri":"/package/Agda"},"tags":[{"display":"dependent-types","uri":"/packages/tag/dependent-types"},{"display":"program","uri":"/packages/tag/program"}],"votes":2.75}]} diff --git a/swh/lister/hackage/tests/data/https_hackage.haskell.org/packages_search_1 b/swh/lister/hackage/tests/data/https_hackage.haskell.org/packages_search_1 new file mode 100644 --- /dev/null +++ b/swh/lister/hackage/tests/data/https_hackage.haskell.org/packages_search_1 @@ -0,0 +1 @@ +{"numberOfResults":150,"pageContents":[{"description":"Command-line program for type-checking and compiling Agda programs","downloads":20,"lastUpload":"2012-03-12T11:01:45Z","maintainers":[{"display":"NilsAndersDanielsson","uri":"/user/NilsAndersDanielsson"},{"display":"UlfNorell","uri":"/user/UlfNorell"}],"name":{"display":"Agda-executable","uri":"/package/Agda-executable"},"tags":[{"display":"dependent-types","uri":"/packages/tag/dependent-types"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Aho-Corasick string matching algorithm","downloads":7,"lastUpload":"2012-11-09T05:36:49Z","maintainers":[{"display":"SergeyLymar","uri":"/user/SergeyLymar"}],"name":{"display":"AhoCorasick","uri":"/package/AhoCorasick"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"text","uri":"/packages/tag/text"}],"votes":0},{"description":"Find the minimal subset/submap satisfying some property.","downloads":7,"lastUpload":"2016-08-24T06:15:53.900038Z","maintainers":[{"display":"EchoNolan","uri":"/user/EchoNolan"}],"name":{"display":"AlanDeniseEricLauren","uri":"/package/AlanDeniseEricLauren"},"tags":[{"display":"algorithms","uri":"/packages/tag/algorithms"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Algorithmic music composition","downloads":6,"lastUpload":"2018-04-06T11:21:37Z","maintainers":[{"display":"omelkonian","uri":"/user/omelkonian"}],"name":{"display":"AlgoRhythm","uri":"/package/AlgoRhythm"},"tags":[{"display":"algorithmic-music-composition","uri":"/packages/tag/algorithmic-music-composition"},{"display":"automatic-music-generation","uri":"/packages/tag/automatic-music-generation"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"chaos-music","uri":"/packages/tag/chaos-music"},{"display":"generative-music-grammars","uri":"/packages/tag/generative-music-grammars"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Example implementation of Algorithm W for Hindley-Milner\ntype inference.","downloads":10,"lastUpload":"2015-05-27T07:33:48.676828Z","maintainers":[{"display":"MartinGrabmueller","uri":"/user/MartinGrabmueller"}],"name":{"display":"AlgorithmW","uri":"/package/AlgorithmW"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"development","uri":"/packages/tag/development"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Collection of alignment algorithms","downloads":11,"lastUpload":"2017-03-14T14:41:48.734043445Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"AlignmentAlgorithms","uri":"/package/AlignmentAlgorithms"},"tags":[{"display":"algorithms","uri":"/packages/tag/algorithms"},{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"data-structures","uri":"/packages/tag/data-structures"},{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"library","uri":"/packages/tag/library"},{"display":"linguistics","uri":"/packages/tag/linguistics"}],"votes":0},{"description":"Near-future Sci-Fi roguelike and tactical squad combat game","downloads":105,"lastUpload":"2021-12-17T17:46:58.38087348Z","maintainers":[{"display":"MikolajKonarski","uri":"/user/MikolajKonarski"}],"name":{"display":"Allure","uri":"/package/Allure"},"tags":[{"display":"agpl","uri":"/packages/tag/agpl"},{"display":"game","uri":"/packages/tag/game"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"},{"display":"roguelike","uri":"/packages/tag/roguelike"}],"votes":2},{"description":"Android view hierarchy importer","downloads":4,"lastUpload":"2012-12-19T12:15:44Z","maintainers":[{"display":"alpheccar","uri":"/user/alpheccar"}],"name":{"display":"AndroidViewHierarchyImporter","uri":"/package/AndroidViewHierarchyImporter"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"development","uri":"/packages/tag/development"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Updated version of Yampa: a library for programming hybrid systems.","downloads":4,"lastUpload":"2011-03-27T02:54:06Z","maintainers":[{"display":"EdwardAmsden","uri":"/user/EdwardAmsden"}],"name":{"display":"Animas","uri":"/package/Animas"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"frp","uri":"/packages/tag/frp"},{"display":"library","uri":"/packages/tag/library"},{"display":"reactivity","uri":"/packages/tag/reactivity"}],"votes":0},{"description":"Constructing, analyzing and destructing annotated trees","downloads":18,"lastUpload":"2016-12-05T10:03:17.260388Z","maintainers":[{"display":"MartijnVanSteenbergen","uri":"/user/MartijnVanSteenbergen"}],"name":{"display":"Annotations","uri":"/package/Annotations"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"generics","uri":"/packages/tag/generics"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Convert ANSI Terminal Sequences to nice HTML markup","downloads":5,"lastUpload":"2011-09-10T19:20:01Z","maintainers":[{"display":"JensStimpfle","uri":"/user/JensStimpfle"}],"name":{"display":"Ansi2Html","uri":"/package/Ansi2Html"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"program","uri":"/packages/tag/program"},{"display":"web","uri":"/packages/tag/web"}],"votes":0},{"description":"A simple music library with the capability of generating .ly and .mid files.","downloads":10,"lastUpload":"2020-07-07T13:19:57.888821262Z","maintainers":[{"display":"Liisi_Kerik","uri":"/user/Liisi_Kerik"}],"name":{"display":"Aoide","uri":"/package/Aoide"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"composition","uri":"/packages/tag/composition"},{"display":"library","uri":"/packages/tag/library"},{"display":"music","uri":"/packages/tag/music"}],"votes":0},{"description":"Library for Apple Push Notification Service","downloads":6,"lastUpload":"2009-07-13T19:38:44Z","maintainers":[{"display":"ChrisMoos","uri":"/user/ChrisMoos"}],"name":{"display":"ApplePush","uri":"/package/ApplePush"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"network","uri":"/packages/tag/network"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Call AppleScript from Haskell, and then call back into Haskell.","downloads":20,"lastUpload":"2012-02-15T11:12:39Z","maintainers":[{"display":"ReinerPope","uri":"/user/ReinerPope"},{"display":"WouterSwierstra","uri":"/user/WouterSwierstra"}],"name":{"display":"AppleScript","uri":"/package/AppleScript"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"foreign","uri":"/packages/tag/foreign"}],"votes":0},{"description":"Function approximation","downloads":2,"lastUpload":"2015-04-26T10:09:29.167094Z","maintainers":[{"display":"DominicSteinitz","uri":"/user/DominicSteinitz"}],"name":{"display":"ApproxFun-hs","uri":"/package/ApproxFun-hs"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"Unboxed references, dynamic arrays and more","downloads":22,"lastUpload":"2009-06-26T19:04:43Z","maintainers":[{"display":"GwernBranwen","uri":"/user/GwernBranwen"}],"name":{"display":"ArrayRef","uri":"/package/ArrayRef"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"A library to generate Netlist code from Arrow descriptions.","downloads":3,"lastUpload":"2015-02-21T13:23:05.402924Z","maintainers":[{"display":"frosch03","uri":"/user/frosch03"},{"display":"brettschneider","uri":"/user/brettschneider"}],"name":{"display":"ArrowVHDL","uri":"/package/ArrowVHDL"},"tags":[{"display":"library","uri":"/packages/tag/library"},{"display":"public-domain","uri":"/packages/tag/public-domain"},{"display":"testing","uri":"/packages/tag/testing"}],"votes":0},{"description":"Strongly typed Attribute Grammars implemented using type-level programming.","downloads":52,"lastUpload":"2022-05-26T18:50:24.876992743Z","maintainers":[{"display":"MarcosViera","uri":"/user/MarcosViera"},{"display":"jpgarcia","uri":"/user/jpgarcia"}],"name":{"display":"AspectAG","uri":"/package/AspectAG"},"tags":[{"display":"aspect-oriented-programming","uri":"/packages/tag/aspect-oriented-programming"},{"display":"development-","uri":"/packages/tag/development-"},{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"language","uri":"/packages/tag/language"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Fast Bencode encoding and parsing library","downloads":14,"lastUpload":"2014-06-24T23:33:17.506075Z","maintainers":[{"display":"FlorianHartwig","uri":"/user/FlorianHartwig"}],"name":{"display":"AttoBencode","uri":"/package/AttoBencode"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Simple lightweight JSON parser, generator & manipulator based on ByteString","downloads":22,"lastUpload":"2011-02-03T05:13:20Z","maintainers":[{"display":"HiromiIshii","uri":"/user/HiromiIshii"}],"name":{"display":"AttoJson","uri":"/package/AttoJson"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"text","uri":"/packages/tag/text"}],"votes":0},{"description":"Visualisation of Strange Attractors in 3-Dimensions","downloads":11,"lastUpload":"2010-03-15T10:01:26Z","maintainers":[{"display":"RubenZilibowitz","uri":"/user/RubenZilibowitz"}],"name":{"display":"Attrac","uri":"/package/Attrac"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Yet another parser generator for C/C++","downloads":2,"lastUpload":"2011-11-08T06:36:20Z","maintainers":[{"display":"XinyuJiang","uri":"/user/XinyuJiang"}],"name":{"display":"Aurochs","uri":"/package/Aurochs"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"development","uri":"/packages/tag/development"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"GUI library based upon generic programming (SYB3)","downloads":9,"lastUpload":"2008-09-17T10:58:40Z","maintainers":[{"display":"MadsLindstroem","uri":"/user/MadsLindstroem"}],"name":{"display":"AutoForms","uri":"/package/AutoForms"},"tags":[{"display":"gui","uri":"/packages/tag/gui"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Balanced binary trees using the AVL algorithm.","downloads":18,"lastUpload":"2008-08-29T05:59:00Z","maintainers":[{"display":"AdrianHey","uri":"/user/AdrianHey"}],"name":{"display":"AvlTree","uri":"/package/AvlTree"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data-structures","uri":"/packages/tag/data-structures"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Embedded BASIC","downloads":23,"lastUpload":"2009-02-09T09:36:35Z","maintainers":[{"display":"LennartAugustsson","uri":"/user/LennartAugustsson"}],"name":{"display":"BASIC","uri":"/package/BASIC"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"language","uri":"/packages/tag/language"},{"display":"library","uri":"/packages/tag/library"}],"votes":2},{"description":"Big Contact Map Tools","downloads":7,"lastUpload":"2015-05-05T17:37:55.917192Z","maintainers":[{"display":"kaizhang","uri":"/user/kaizhang"}],"name":{"display":"BCMtools","uri":"/package/BCMtools"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"library","uri":"/packages/tag/library"},{"display":"mit","uri":"/packages/tag/mit"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"A compiler front-end generator.","downloads":93,"lastUpload":"2022-02-17T17:38:38.309476485Z","maintainers":[{"display":"AndreasAbel","uri":"/user/AndreasAbel"},{"display":"GregoireDetrez","uri":"/user/GregoireDetrez"},{"display":"MarkusForsberg","uri":"/user/MarkusForsberg"},{"display":"ThomasHallgren","uri":"/user/ThomasHallgren"}],"name":{"display":"BNFC","uri":"/package/BNFC"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"parsing","uri":"/packages/tag/parsing"},{"display":"program","uri":"/packages/tag/program"}],"votes":2.25},{"description":"Deriving Parsers and Quasi-Quoters from BNF Grammars","downloads":51,"lastUpload":"2020-02-09T23:44:05.066878431Z","maintainers":[{"display":"JeanPhilippeBernardy","uri":"/user/JeanPhilippeBernardy"},{"display":"JonasDuregard","uri":"/user/JonasDuregard"},{"display":"ArtemPelenitsyn","uri":"/user/ArtemPelenitsyn"}],"name":{"display":"BNFC-meta","uri":"/package/BNFC-meta"},"tags":[{"display":"development","uri":"/packages/tag/development"},{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"language","uri":"/packages/tag/language"},{"display":"library","uri":"/packages/tag/library"},{"display":"parsing","uri":"/packages/tag/parsing"},{"display":"text","uri":"/packages/tag/text"}],"votes":0},{"description":"Translations of classic Truth Maintenance Systems","downloads":3,"lastUpload":"2022-04-22T00:24:50.851029935Z","maintainers":[{"display":"jpmrst","uri":"/user/jpmrst"}],"name":{"display":"BPS","uri":"/package/BPS"},"tags":[{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"},{"display":"truth-maintenance","uri":"/packages/tag/truth-maintenance"}],"votes":0},{"description":"Tools for self-assembly","downloads":2,"lastUpload":"2014-06-12T19:26:55.982603Z","maintainers":[{"display":"pmeunier","uri":"/user/pmeunier"}],"name":{"display":"Baggins","uri":"/package/Baggins"},"tags":[{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"A Drum Machine DSL for Haskell","downloads":17,"lastUpload":"2015-10-26T16:12:59.52351Z","maintainers":[{"display":"5outh","uri":"/user/5outh"}],"name":{"display":"Bang","uri":"/package/Bang"},"tags":[{"display":"library","uri":"/packages/tag/library"},{"display":"mit","uri":"/packages/tag/mit"},{"display":"sound","uri":"/packages/tag/sound"}],"votes":0},{"description":"An ad-hoc P2P chat program","downloads":8,"lastUpload":"2008-04-05T02:14:35Z","maintainers":[{"display":"GwernBranwen","uri":"/user/GwernBranwen"}],"name":{"display":"Barracuda","uri":"/package/Barracuda"},"tags":[{"display":"library","uri":"/packages/tag/library"},{"display":"network","uri":"/packages/tag/network"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"An interpreter for the Befunge-93 Programming Language","downloads":3,"lastUpload":"2010-05-20T18:25:24Z","maintainers":[{"display":"BrandonSimmons","uri":"/user/BrandonSimmons"}],"name":{"display":"Befunge93","uri":"/package/Befunge93"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"compilers-interpreters","uri":"/packages/tag/compilers-interpreters"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Benchmark functions with history","downloads":5,"lastUpload":"2015-11-19T14:22:31.9303Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"BenchmarkHistory","uri":"/package/BenchmarkHistory"},"tags":[{"display":"benchmarking","uri":"/packages/tag/benchmarking"},{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Berkeley DB binding","downloads":30,"lastUpload":"2013-03-13T19:54:56Z","maintainers":[{"display":"JohnMcCall","uri":"/user/JohnMcCall"},{"display":"StephenBlackheath","uri":"/user/StephenBlackheath"}],"name":{"display":"BerkeleyDB","uri":"/package/BerkeleyDB"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"database","uri":"/packages/tag/database"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Berkeley DB XML binding","downloads":25,"lastUpload":"2011-09-06T20:51:27Z","maintainers":[{"display":"StephenBlackheath","uri":"/user/StephenBlackheath"}],"name":{"display":"BerkeleyDBXML","uri":"/package/BerkeleyDBXML"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"database","uri":"/packages/tag/database"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Factorization of polynomials over finite field","downloads":2,"lastUpload":"2013-06-10T11:40:22Z","maintainers":[{"display":"AbdelwahebMiled","uri":"/user/AbdelwahebMiled"}],"name":{"display":"BerlekampAlgorithm","uri":"/package/BerlekampAlgorithm"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"math","uri":"/packages/tag/math"}],"votes":0},{"description":"The Bidirectional Generic Update Language","downloads":11,"lastUpload":"2016-08-30T09:49:01.746971Z","maintainers":[{"display":"joshko","uri":"/user/joshko"},{"display":"Zirun","uri":"/user/Zirun"}],"name":{"display":"BiGUL","uri":"/package/BiGUL"},"tags":[{"display":"generics","uri":"/packages/tag/generics"},{"display":"language","uri":"/packages/tag/language"},{"display":"lenses","uri":"/packages/tag/lenses"},{"display":"library","uri":"/packages/tag/library"},{"display":"public-domain","uri":"/packages/tag/public-domain"}],"votes":2.25},{"description":"Image editor for pixel art","downloads":10,"lastUpload":"2014-01-24T03:18:08.778401Z","maintainers":[{"display":"ManuelChakravarty","uri":"/user/ManuelChakravarty"}],"name":{"display":"BigPixel","uri":"/package/BigPixel"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"development","uri":"/packages/tag/development"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Source-to-source plugin for enhancing EDSLs with static annotations","downloads":5,"lastUpload":"2020-03-19T17:59:05.904872539Z","maintainers":[{"display":"agustinmista","uri":"/user/agustinmista"}],"name":{"display":"BinderAnn","uri":"/package/BinderAnn"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"compiler-plugin","uri":"/packages/tag/compiler-plugin"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Common bin-packing heuristics.","downloads":14,"lastUpload":"2014-02-07T13:32:35.055121Z","maintainers":[{"display":"BjoernBrandenburg","uri":"/user/BjoernBrandenburg"},{"display":"DavidFeng","uri":"/user/DavidFeng"}],"name":{"display":"Binpack","uri":"/package/Binpack"},"tags":[{"display":"algorithms","uri":"/packages/tag/algorithms"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"heuristics","uri":"/packages/tag/heuristics"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Libary for Hidden Markov Models in HMMER3 format. ","downloads":46,"lastUpload":"2017-06-09T15:26:05.435990496Z","maintainers":[{"display":"FlorianEggenhofer","uri":"/user/FlorianEggenhofer"}],"name":{"display":"BioHMM","uri":"/package/BioHMM"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Base library for bioinformatics","downloads":12,"lastUpload":"2011-04-08T12:46:37Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"Biobase","uri":"/package/Biobase"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"BLAST-related tools","downloads":16,"lastUpload":"2021-06-05T21:06:10.915506997Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"},{"display":"FlorianEggenhofer","uri":"/user/FlorianEggenhofer"}],"name":{"display":"BiobaseBlast","uri":"/package/BiobaseBlast"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Vienna / DotBracket / ExtSS parsers","downloads":3,"lastUpload":"2011-08-22T15:27:13Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"BiobaseDotP","uri":"/package/BiobaseDotP"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"European Nucleotide Archive data","downloads":7,"lastUpload":"2021-06-04T12:37:25.444518495Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"BiobaseENA","uri":"/package/BiobaseENA"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Ensembl related datastructures and functions","downloads":8,"lastUpload":"2020-01-09T19:39:11.497450015Z","maintainers":[{"display":"FlorianEggenhofer","uri":"/user/FlorianEggenhofer"}],"name":{"display":"BiobaseEnsembl","uri":"/package/BiobaseEnsembl"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Importer for FR3D resources","downloads":10,"lastUpload":"2012-02-16T14:20:59Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"BiobaseFR3D","uri":"/package/BiobaseFR3D"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"streaming FASTA parser","downloads":16,"lastUpload":"2021-06-04T13:59:41.393107101Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"BiobaseFasta","uri":"/package/BiobaseFasta"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Libary to interface with the Bioinformatics HTTP services - Entrez Ensembl","downloads":4,"lastUpload":"2019-11-20T21:19:53.584971279Z","maintainers":[{"display":"FlorianEggenhofer","uri":"/user/FlorianEggenhofer"}],"name":{"display":"BiobaseHTTP","uri":"/package/BiobaseHTTP"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"library","uri":"/packages/tag/library"}],"votes":0}]} diff --git a/swh/lister/hackage/tests/data/https_hackage.haskell.org/packages_search_2 b/swh/lister/hackage/tests/data/https_hackage.haskell.org/packages_search_2 new file mode 100644 --- /dev/null +++ b/swh/lister/hackage/tests/data/https_hackage.haskell.org/packages_search_2 @@ -0,0 +1 @@ +{"numberOfResults":150,"pageContents":[{"description":"Tools to query Bioinformatics HTTP services e.g. Entrez, Ensembl.","downloads":8,"lastUpload":"2018-12-13T19:11:11.267301285Z","maintainers":[{"display":"FlorianEggenhofer","uri":"/user/FlorianEggenhofer"}],"name":{"display":"BiobaseHTTPTools","uri":"/package/BiobaseHTTPTools"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Infernal data structures and tools","downloads":36,"lastUpload":"2017-03-14T13:57:23.042537328Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"BiobaseInfernal","uri":"/package/BiobaseInfernal"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Multiple Alignment Format","downloads":2,"lastUpload":"2011-07-29T12:30:35Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"BiobaseMAF","uri":"/package/BiobaseMAF"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Newick file format parser.","downloads":4,"lastUpload":"2017-07-07T17:56:54.930748267Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"BiobaseNewick","uri":"/package/BiobaseNewick"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"RNA folding training data","downloads":10,"lastUpload":"2011-09-29T13:24:59Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"BiobaseTrainingData","uri":"/package/BiobaseTrainingData"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Import Turner RNA parameters","downloads":31,"lastUpload":"2013-04-25T00:42:45Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"BiobaseTurner","uri":"/package/BiobaseTurner"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Collection of types for bioinformatics","downloads":25,"lastUpload":"2021-06-04T12:19:46.84432619Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"BiobaseTypes","uri":"/package/BiobaseTypes"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data-structures","uri":"/packages/tag/data-structures"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Import Vienna energy parameters","downloads":24,"lastUpload":"2013-04-22T01:29:13Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"BiobaseVienna","uri":"/package/BiobaseVienna"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Efficient RNA/DNA/Protein Primary/Secondary Structure","downloads":73,"lastUpload":"2021-06-04T20:20:23.163421103Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"BiobaseXNA","uri":"/package/BiobaseXNA"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"A preprocessor for Bird-style Literate Haskell comments with Haddock markup.","downloads":4,"lastUpload":"2012-08-02T16:36:38Z","maintainers":[{"display":"SeanMcLaughlin","uri":"/user/SeanMcLaughlin"}],"name":{"display":"BirdPP","uri":"/package/BirdPP"},"tags":[{"display":"development","uri":"/packages/tag/development"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"","downloads":18,"lastUpload":"2018-03-03T19:01:52.086048792Z","maintainers":[{"display":"Ofenhed","uri":"/user/Ofenhed"}],"name":{"display":"BitStringRandomMonad","uri":"/package/BitStringRandomMonad"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"crypto","uri":"/packages/tag/crypto"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"A module to aid in the (de)serialisation of binary data","downloads":10,"lastUpload":"2021-01-17T10:52:15.284789745Z","maintainers":[{"display":"AdamLangley","uri":"/user/AdamLangley"},{"display":"joecrayne","uri":"/user/joecrayne"}],"name":{"display":"BitSyntax","uri":"/package/BitSyntax"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"serialization","uri":"/packages/tag/serialization"}],"votes":0},{"description":"A library to access bit.ly URL shortener.","downloads":18,"lastUpload":"2012-02-02T17:42:46Z","maintainers":[{"display":"SergeyAstanin","uri":"/user/SergeyAstanin"}],"name":{"display":"Bitly","uri":"/package/Bitly"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"web","uri":"/packages/tag/web"}],"votes":0},{"description":"Batteries-included Structured Logging library","downloads":38,"lastUpload":"2022-07-20T15:13:36.539640239Z","maintainers":[{"display":"PatrickBrisbin","uri":"/user/PatrickBrisbin"},{"display":"dukerutledge","uri":"/user/dukerutledge"},{"display":"mjgpy3","uri":"/user/mjgpy3"},{"display":"FreckleEngineering","uri":"/user/FreckleEngineering"}],"name":{"display":"Blammo","uri":"/package/Blammo"},"tags":[{"display":"library","uri":"/packages/tag/library"},{"display":"mit","uri":"/packages/tag/mit"},{"display":"utils","uri":"/packages/tag/utils"}],"votes":0},{"description":"Libary to interface with the NCBI blast REST interface","downloads":25,"lastUpload":"2021-06-05T21:19:54.156671184Z","maintainers":[{"display":"FlorianEggenhofer","uri":"/user/FlorianEggenhofer"}],"name":{"display":"BlastHTTP","uri":"/package/BlastHTTP"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Diagram editor","downloads":6,"lastUpload":"2012-06-19T21:00:19Z","maintainers":[{"display":"AlanZimmerman","uri":"/user/AlanZimmerman"}],"name":{"display":"Blobs","uri":"/package/Blobs"},"tags":[{"display":"graphics","uri":"/packages/tag/graphics"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"A tool for posting Haskelly articles to blogs","downloads":143,"lastUpload":"2022-08-26T02:27:45.073759633Z","maintainers":[{"display":"BrentYorgey","uri":"/user/BrentYorgey"},{"display":"RobertGreayer","uri":"/user/RobertGreayer"}],"name":{"display":"BlogLiterately","uri":"/package/BlogLiterately"},"tags":[{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"},{"display":"web","uri":"/packages/tag/web"}],"votes":0},{"description":"Include images in blog posts with inline diagrams code","downloads":51,"lastUpload":"2022-05-24T16:27:56.206098429Z","maintainers":[{"display":"BrentYorgey","uri":"/user/BrentYorgey"}],"name":{"display":"BlogLiterately-diagrams","uri":"/package/BlogLiterately-diagrams"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"},{"display":"web","uri":"/packages/tag/web"}],"votes":0},{"description":"A markdown-like markup language designed for blog posts","downloads":13,"lastUpload":"2018-02-05T06:23:31.042191764Z","maintainers":[{"display":"alexbecker","uri":"/user/alexbecker"}],"name":{"display":"Blogdown","uri":"/package/Blogdown"},"tags":[{"display":"agpl","uri":"/packages/tag/agpl"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"},{"display":"web","uri":"/packages/tag/web"}],"votes":1.5},{"description":"Html document layout library.","downloads":7,"lastUpload":"2010-08-03T08:19:51Z","maintainers":[{"display":"SergeyMironov","uri":"/user/SergeyMironov"}],"name":{"display":"BluePrintCSS","uri":"/package/BluePrintCSS"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"deprecated","uri":"/packages/tag/deprecated"},{"display":"library","uri":"/packages/tag/library"},{"display":"text","uri":"/packages/tag/text"},{"display":"web","uri":"/packages/tag/web"}],"votes":0},{"description":"Preview of a new build system.","downloads":2,"lastUpload":"2009-11-30T14:22:55Z","maintainers":[{"display":"GregoryCrosswhite","uri":"/user/GregoryCrosswhite"}],"name":{"display":"Blueprint","uri":"/package/Blueprint"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"distribution","uri":"/packages/tag/distribution"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"A simple document organizer with some wiki functionality","downloads":26,"lastUpload":"2016-01-11T12:47:27.621179Z","maintainers":[{"display":"EmilAxelsson","uri":"/user/EmilAxelsson"}],"name":{"display":"Bookshelf","uri":"/package/Bookshelf"},"tags":[{"display":"program","uri":"/packages/tag/program"},{"display":"text","uri":"/packages/tag/text"}],"votes":0},{"description":"Generalized booleans and numbers","downloads":125,"lastUpload":"2017-02-19T22:07:32.056861Z","maintainers":[{"display":"ConalElliott","uri":"/user/ConalElliott"}],"name":{"display":"Boolean","uri":"/package/Boolean"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Implementation of bounded channels.","downloads":26,"lastUpload":"2014-05-14T23:30:48.662935Z","maintainers":[{"display":"AdamWick","uri":"/user/AdamWick"}],"name":{"display":"BoundedChan","uri":"/package/BoundedChan"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"concurrency","uri":"/packages/tag/concurrency"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Static text template generation library","downloads":4,"lastUpload":"2010-03-24T01:43:29Z","maintainers":[{"display":"MatthiasReisner","uri":"/user/MatthiasReisner"}],"name":{"display":"Bravo","uri":"/package/Bravo"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"text","uri":"/packages/tag/text"}],"votes":0},{"description":"A socker wrapper that makes the IO of sockets much cleaner","downloads":7,"lastUpload":"2015-08-12T12:31:27.028316Z","maintainers":[{"display":"tmore","uri":"/user/tmore"}],"name":{"display":"BufferedSocket","uri":"/package/BufferedSocket"},"tags":[{"display":"library","uri":"/packages/tag/library"},{"display":"mit","uri":"/packages/tag/mit"},{"display":"network","uri":"/packages/tag/network"}],"votes":0},{"description":"Hits a set of urls periodically to bust caches","downloads":4,"lastUpload":"2013-05-22T06:11:22Z","maintainers":[{"display":"MichaelXavier","uri":"/user/MichaelXavier"}],"name":{"display":"Buster","uri":"/package/Buster"},"tags":[{"display":"mit","uri":"/packages/tag/mit"},{"display":"program","uri":"/packages/tag/program"},{"display":"web","uri":"/packages/tag/web"}],"votes":0},{"description":"C-Structs implementation for Haskell","downloads":7,"lastUpload":"2021-03-30T13:36:33.593597406Z","maintainers":[{"display":"SimonPlakolb","uri":"/user/SimonPlakolb"}],"name":{"display":"C-structs","uri":"/package/C-structs"},"tags":[{"display":"c","uri":"/packages/tag/c"},{"display":"data","uri":"/packages/tag/data"},{"display":"foreign","uri":"/packages/tag/foreign"},{"display":"library","uri":"/packages/tag/library"},{"display":"mit","uri":"/packages/tag/mit"},{"display":"structures","uri":"/packages/tag/structures"}],"votes":2},{"description":"Encode/Decode values to/from CBOR","downloads":10,"lastUpload":"2014-07-24T04:38:49.281736Z","maintainers":[{"display":"KyleMurphy","uri":"/user/KyleMurphy"}],"name":{"display":"CBOR","uri":"/package/CBOR"},"tags":[{"display":"data","uri":"/packages/tag/data"},{"display":"lgpl","uri":"/packages/tag/lgpl"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Delimited continuations and dynamically scoped variables","downloads":16,"lastUpload":"2016-05-11T02:22:41.377133Z","maintainers":[{"display":"DanDoel","uri":"/user/DanDoel"}],"name":{"display":"CC-delcont","uri":"/package/CC-delcont"},"tags":[{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Three new monad transformers for multi-prompt delimited control","downloads":9,"lastUpload":"2012-10-23T14:23:53Z","maintainers":[{"display":"KidoTakahiro","uri":"/user/KidoTakahiro"}],"name":{"display":"CC-delcont-alt","uri":"/package/CC-delcont-alt"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"A monad transformers for multi-prompt delimited control","downloads":6,"lastUpload":"2011-10-12T16:56:51Z","maintainers":[{"display":"KidoTakahiro","uri":"/user/KidoTakahiro"}],"name":{"display":"CC-delcont-cxe","uri":"/package/CC-delcont-cxe"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"A monad transformers for multi-prompt delimited control","downloads":5,"lastUpload":"2011-10-12T16:34:48Z","maintainers":[{"display":"KidoTakahiro","uri":"/user/KidoTakahiro"}],"name":{"display":"CC-delcont-exc","uri":"/package/CC-delcont-exc"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"A monad transformers for multi-prompt delimited control using refercence cells","downloads":2,"lastUpload":"2011-10-12T16:34:17Z","maintainers":[{"display":"KidoTakahiro","uri":"/user/KidoTakahiro"}],"name":{"display":"CC-delcont-ref","uri":"/package/CC-delcont-ref"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"A monad transformers for multi-prompt delimited control using refercence cells","downloads":10,"lastUpload":"2011-10-18T13:32:20Z","maintainers":[{"display":"KidoTakahiro","uri":"/user/KidoTakahiro"}],"name":{"display":"CC-delcont-ref-tf","uri":"/package/CC-delcont-ref-tf"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"control","uri":"/packages/tag/control"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"preprocessor and library for Causal Commutative Arrows (CCA)","downloads":21,"lastUpload":"2015-05-08T03:06:09.667005Z","maintainers":[{"display":"PaulLiu","uri":"/user/PaulLiu"}],"name":{"display":"CCA","uri":"/package/CCA"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"development","uri":"/packages/tag/development"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"A W3C compliant (X)HTML generating library ","downloads":12,"lastUpload":"2011-07-26T02:29:50Z","maintainers":[{"display":"PaulTalaga","uri":"/user/PaulTalaga"}],"name":{"display":"CHXHtml","uri":"/package/CHXHtml"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"web","uri":"/packages/tag/web"}],"votes":0},{"description":"Cursor Library for A Structured Editor","downloads":11,"lastUpload":"2009-02-11T09:56:25Z","maintainers":[{"display":"TristanAllwood","uri":"/user/TristanAllwood"}],"name":{"display":"CLASE","uri":"/package/CLASE"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"CLI tools","downloads":6,"lastUpload":"2015-03-10T04:25:07.585209Z","maintainers":[{"display":"g960059","uri":"/user/g960059"}],"name":{"display":"CLI","uri":"/package/CLI"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Infernal covariance model comparison","downloads":8,"lastUpload":"2012-11-22T14:57:12Z","maintainers":[{"display":"ChristianHoener","uri":"/user/ChristianHoener"}],"name":{"display":"CMCompare","uri":"/package/CMCompare"},"tags":[{"display":"bioinformatics","uri":"/packages/tag/bioinformatics"},{"display":"gpl","uri":"/packages/tag/gpl"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"cwmwl udp message queue","downloads":2,"lastUpload":"2012-07-02T13:30:46Z","maintainers":[{"display":"JoergFritsch","uri":"/user/JoergFritsch"}],"name":{"display":"CMQ","uri":"/package/CMQ"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"library","uri":"/packages/tag/library"},{"display":"system","uri":"/packages/tag/system"}],"votes":0},{"description":"An algebraic data type similar to Prelude Ordering.","downloads":8,"lastUpload":"2008-07-23T19:06:06Z","maintainers":[{"display":"AdrianHey","uri":"/user/AdrianHey"}],"name":{"display":"COrdering","uri":"/package/COrdering"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"data","uri":"/packages/tag/data"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"A simple Brainfuck interpretter.","downloads":9,"lastUpload":"2008-11-06T21:21:39Z","maintainers":[{"display":"ThomasDavie","uri":"/user/ThomasDavie"}],"name":{"display":"CPBrainfuck","uri":"/package/CPBrainfuck"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"compilers-interpreters","uri":"/packages/tag/compilers-interpreters"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"An interpreter of Hagino's Categorical Programming Language (CPL).","downloads":11,"lastUpload":"2018-02-16T04:01:31.731523911Z","maintainers":[{"display":"MasahiroSakai","uri":"/user/MasahiroSakai"}],"name":{"display":"CPL","uri":"/package/CPL"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"compilers-interpreters","uri":"/packages/tag/compilers-interpreters"},{"display":"program","uri":"/packages/tag/program"}],"votes":0},{"description":"Definition of a CSP core-language. ","downloads":21,"lastUpload":"2017-10-26T16:01:57.597214822Z","maintainers":[{"display":"MarcFontaine","uri":"/user/MarcFontaine"}],"name":{"display":"CSPM-CoreLanguage","uri":"/package/CSPM-CoreLanguage"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"concurrency","uri":"/packages/tag/concurrency"},{"display":"formal-methods","uri":"/packages/tag/formal-methods"},{"display":"language","uri":"/packages/tag/language"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"Firing rules semantic of CSPM","downloads":23,"lastUpload":"2017-10-26T16:04:59.008462452Z","maintainers":[{"display":"MarcFontaine","uri":"/user/MarcFontaine"}],"name":{"display":"CSPM-FiringRules","uri":"/package/CSPM-FiringRules"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"concurrency","uri":"/packages/tag/concurrency"},{"display":"formal-methods","uri":"/packages/tag/formal-methods"},{"display":"language","uri":"/packages/tag/language"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"A CSP-M parser compatible with FDR-2.91","downloads":27,"lastUpload":"2017-10-26T16:00:53.247544871Z","maintainers":[{"display":"MarcFontaine","uri":"/user/MarcFontaine"}],"name":{"display":"CSPM-Frontend","uri":"/package/CSPM-Frontend"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"concurrency","uri":"/packages/tag/concurrency"},{"display":"formal-methods","uri":"/packages/tag/formal-methods"},{"display":"language","uri":"/packages/tag/language"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"An interpreter for CSPM","downloads":31,"lastUpload":"2017-10-26T16:06:04.796021721Z","maintainers":[{"display":"MarcFontaine","uri":"/user/MarcFontaine"}],"name":{"display":"CSPM-Interpreter","uri":"/package/CSPM-Interpreter"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"concurrency","uri":"/packages/tag/concurrency"},{"display":"formal-methods","uri":"/packages/tag/formal-methods"},{"display":"language","uri":"/packages/tag/language"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"some modules specific for the ProB tool","downloads":11,"lastUpload":"2017-10-26T16:07:34.663251395Z","maintainers":[{"display":"MarcFontaine","uri":"/user/MarcFontaine"}],"name":{"display":"CSPM-ToProlog","uri":"/package/CSPM-ToProlog"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"formal-methods","uri":"/packages/tag/formal-methods"},{"display":"library","uri":"/packages/tag/library"}],"votes":0},{"description":"cspm command line tool for analyzing CSPM specifications.","downloads":26,"lastUpload":"2017-10-26T16:08:56.855821544Z","maintainers":[{"display":"MarcFontaine","uri":"/user/MarcFontaine"}],"name":{"display":"CSPM-cspm","uri":"/package/CSPM-cspm"},"tags":[{"display":"bsd3","uri":"/packages/tag/bsd3"},{"display":"concurrency","uri":"/packages/tag/concurrency"},{"display":"formal-methods","uri":"/packages/tag/formal-methods"},{"display":"language","uri":"/packages/tag/language"},{"display":"library","uri":"/packages/tag/library"},{"display":"program","uri":"/packages/tag/program"}],"votes":0}]} diff --git a/swh/lister/hackage/tests/test_lister.py b/swh/lister/hackage/tests/test_lister.py new file mode 100644 --- /dev/null +++ b/swh/lister/hackage/tests/test_lister.py @@ -0,0 +1,125 @@ +# Copyright (C) 2022 The Software Heritage developers +# See the AUTHORS file at the top-level directory of this distribution +# License: GNU General Public License version 3, or any later version +# See top-level LICENSE file for more information + +import json +from os import path +from pathlib import Path +from urllib.parse import unquote, urlparse + +import pytest +import requests_mock + +from swh.lister.hackage.lister import HackageLister + + +def json_callback(request, context): + """Callback for requests_mock that load a json file regarding a page number""" + here = path.abspath(path.dirname(__file__)) + datadir = Path(here, "data") + page = request.json()["page"] + + unquoted_url = unquote(request.url) + url = urlparse(unquoted_url) + dirname = "%s_%s" % (url.scheme, url.hostname) + filename = url.path[1:] + if filename.endswith("/"): + filename = filename[:-1] + filename = filename.replace("/", "_") + + return json.loads(Path(datadir, dirname, f"{filename}_{page}").read_text()) + + +@pytest.fixture +def mock_post(): + """Mock `https://hackage.haskell.org/packages/search`""" + with requests_mock.Mocker() as requests_mocker: + requests_mocker.post( + url="https://hackage.haskell.org/packages/search", + status_code=200, + json=json_callback, + ) + yield + + +def test_hackage_lister(swh_scheduler, mock_post, datadir): + + expected_origins = [] + + for page in [0, 1, 2]: + data = json.loads( + Path( + datadir, "https_hackage.haskell.org", f"packages_search_{page}" + ).read_text() + ) + for entry in data["pageContents"]: + pkgname = entry["name"]["display"] + expected_origins.append( + {"url": f"https://hackage.haskell.org/package/{pkgname}"} + ) + + lister = HackageLister(scheduler=swh_scheduler) + res = lister.run() + + assert res.pages == 3 + assert res.origins == 50 + 50 + 50 + + scheduler_origins = swh_scheduler.get_listed_origins(lister.lister_obj.id).results + + assert len(scheduler_origins) == len(expected_origins) + + assert { + ( + scheduled.visit_type, + scheduled.url, + ) + for scheduled in scheduler_origins + } == { + ( + "hackage", + expected["url"], + ) + for expected in expected_origins + } + + +@pytest.fixture +def mock_post_49(): + """Mock 49 entries""" + with requests_mock.Mocker() as requests_mocker: + requests_mocker.post( + url="https://fake49.haskell.org/packages/search", + status_code=200, + json=json_callback, + ) + yield + + +def test_hackage_lister_pagination_49(swh_scheduler, mock_post_49, datadir): + lister = HackageLister(scheduler=swh_scheduler, url="https://fake49.haskell.org/") + pages = list(lister.get_pages()) + # there should be 1 page with 49 entries + assert len(pages) == 1 + assert len(pages[0]) == 49 + + +@pytest.fixture +def mock_post_51(): + """Mock 51 entries""" + with requests_mock.Mocker() as requests_mocker: + requests_mocker.post( + url="https://fake51.haskell.org/packages/search", + status_code=200, + json=json_callback, + ) + yield + + +def test_hackage_lister_pagination_51(swh_scheduler, mock_post_51, datadir): + lister = HackageLister(scheduler=swh_scheduler, url="https://fake51.haskell.org/") + pages = list(lister.get_pages()) + # there should be 2 pages with 50 + 1 entries + assert len(pages) == 2 + assert len(pages[0]) == 50 + assert len(pages[1]) == 1 diff --git a/swh/lister/hackage/tests/test_tasks.py b/swh/lister/hackage/tests/test_tasks.py new file mode 100644 --- /dev/null +++ b/swh/lister/hackage/tests/test_tasks.py @@ -0,0 +1,33 @@ +# Copyright (C) 2022 The Software Heritage developers +# See the AUTHORS file at the top-level directory of this distribution +# License: GNU General Public License version 3, or any later version +# See top-level LICENSE file for more information + +from swh.lister.pattern import ListerStats + + +def test_hackage_ping(swh_scheduler_celery_app, swh_scheduler_celery_worker): + res = swh_scheduler_celery_app.send_task("swh.lister.hackage.tasks.ping") + assert res + res.wait() + assert res.successful() + assert res.result == "OK" + + +def test_hackage_lister(swh_scheduler_celery_app, swh_scheduler_celery_worker, mocker): + # setup the mocked HackageLister + lister = mocker.patch("swh.lister.hackage.tasks.HackageLister") + lister.from_configfile.return_value = lister + stats = ListerStats(pages=42, origins=42) + lister.run.return_value = stats + + res = swh_scheduler_celery_app.send_task( + "swh.lister.hackage.tasks.HackageListerTask" + ) + assert res + res.wait() + assert res.successful() + assert res.result == stats.dict() + + lister.from_configfile.assert_called_once_with() + lister.run.assert_called_once_with()