Skip to content

v1.0.0

Compare
Choose a tag to compare
@geo-martino geo-martino released this 12 Jun 00:45
· 81 commits to master since this release
306d097

Added

  • Custom API caching backend to replace dependency on requests-cache package.
    Currently only supports SQLite backend. More backends can be implemented in future if desired.
  • Cache settings for specific GET request endpoints on :py:class:.SpotifyAPI replacing need
    for per method use_cache parameter.
  • The following classes should now be run as AsyncContextManagers to function correctly:
    • :py:class:.SQLiteCache
    • :py:class:.RequestHandler
    • :py:class:.CachedSession
    • :py:class:.RemoteAPI & :py:class:.SpotifyAPI
  • Introduce print wrapper for logger and remove most bare print statements across package.
  • :py:meth:.SpotifyAPI.extend_items now enriches collection item responses with the parent collection response.
  • ARTISTS field added to LocalTrackField
  • Add compatibility with yarl package for any logic which uses URL logic.
  • Add compatibility for pathlib.Path for any logic which uses path logic.
  • Extended logging on :py:func:.report_playlist_differences
  • source property on :py:class:.Library
  • :py:meth:.RemoteAPI.get_or_create_playlist method for only creating a playlist when it doesn't
    already exist by name. Gets the existing playlist otherwise
  • Added :py:meth:.MusifyCollection.outer_difference method to cover the logic previously handled
    by the mislabelled :py:meth:.MusifyCollection.outer_difference method
  • :py:class:.RemoteDataWrangler and its implementations now handle URL objects from the yarl package
  • :py:meth:.RemoteAPI.follow_playlist method
  • Wait time logic for :py:class:.RequestHandler. This waits by a certain time after each request,
    incrementing this wait time every time a 429 code is returned.
    This allows better handling of rate limits, with the aim of preventing a lock out from a service.

Changed

  • :py:class:.RequestHandler now handles requests asynchronously. These changes to async calls have
    been implemented all the way on :py:class:.RemoteAPI and all other objects that depend on it.
  • All I/O operations on local libraries and their dependent objects now run asynchronously.
  • Dependency injection pattern for :py:class:.RequestHandler.
    Now takes :py:class:.APIAuthoriser and generator for :py:class:.ClientSession objects for instantiation
    instead of kwargs for :py:class:.APIAuthoriser.
  • Dependency injection pattern for :py:class:.RemoteAPI.
    Now takes :py:class:.APIAuthoriser and generator for :py:class:.ResponseCache objects for instantiation
    instead of kwargs for :py:class:.APIAuthoriser.
  • :py:class:.APIAuthoriser kwargs given to :py:class:.SpotifyAPI now merge with default kwargs.
  • Moved remote_wrangler attribute from :py:class:.MusifyCollection to :py:class:.LocalCollection.
    This attribute was only needed by :py:class:.LocalCollection branch of child classes.
  • Moved logger attribute from :py:class:.Library to :py:class:.RemoteLibrary.
  • Switch some dependencies to be optional for groups of operation: progress bars, musicbee, sqlite
  • Replace urllib usages with yarl package.
  • Replace all path logic to use pathlib.Path instead. All
  • :py:class:.SpotifyAPI now logs to the new central :py:meth:.RequestHandler.log method
    to help unify log formatting.
  • user_id and user_name now raise an error when called before setting user_data attribute.
    This is due to avoiding asynchronous calls in a property.
    It is therefore best to now enter the async context of the api to set these automatically.
  • Renamed :py:meth:.LocalGenres.genres to :py:meth:.LocalGenres.related_genres
  • Reduced scope of :py:meth:.TagWriter._delete_tag method to private
  • :py:class:.LocalTrack now removes any loaded embedded image from the mutagen file object.
    This is to reduce memory usage when loading many of these objects.
  • Extend logging on :py:meth:.LocalCollection.log_save_tracks_result to show when no tags
    have been or would be updated.
  • :py:class:.RemoteItemChecker now uses the new :py:meth:.RemoteAPI.get_or_create_playlist method
    when creating playlists to avoid creating many duplicate playlists which could have lead to playlist
    creation explosion in repeated uses. The processor also accounts for any items that may have existed
    in the playlist before it was run and discounts them from any matches.
  • :py:class:.RemoteItemChecker also uses the new :py:meth:.RemoteAPI.follow_playlist method
    when creating playlists to ensure that a user is following the playlists it creates to avoid 'ghost playlist' issue.
  • :py:meth:.SpotifyAPI.create_playlist now returns the full response rather than just the URL of the playlist.
  • Moved :py:class:.RemoteItemChecker and :py:class:.RemoteItemSearcher to musify.processors package.
  • Moved :py:class:.RemoteDataWrangler up a level to musify.libraries.remote.core.
  • Renamed musify.libraries.remote.spotify.processors module to musify.libraries.remote.spotify.wrangle.
  • Moved musify.logger module to musify base package.
  • Restructured contents of musify.core package to modules in musify base package.

Fixed

  • Added missing variables to slots definitions
  • Correctly applied slots pattern to child classes. Now works as expected.
  • :py:class:.LocalTrack now copies tags as expected when calling copy.copy()
  • Bug where loading an M3U playlist with new track objects would force all created track objects
    to have lower case paths
  • :py:meth:.RemoteLibrary.restore_playlists now correctly handles the backup
    output from :py:meth:.RemoteLibrary.backup_playlists
  • Issue detecting stdout_handlers affecting :py:meth:.MusifyLogger.print and :py:meth:.MusifyLogger.get_iterator.
    Now works as expected.
  • :py:meth:.LocalLibrary.artists now generates a :py:class:.LocalArtist object per individual artist
    rather than on combined artists
  • Issue where :py:meth:.SpotifyAPI.extend_items did not show progress when extending some types of responses
  • Fixed logic in :py:meth:.MusifyCollection.intersection and :py:meth:.MusifyCollection.difference

Removed

  • Dependency on requests package in favour of aiohttp for async requests.
  • Dependency on requests-cache package in favour of custom cache implementation.
  • use_cache parameter from all :py:class:.RemoteAPI related methods.
    Cache settings now handled by :py:class:.ResponseCache
  • ThreadPoolExecutor use on :py:class:.RemoteItemSearcher. Now uses asynchronous logic instead.
  • last_modified field as attribute to ignore when getting attributes
    to print on LocalCollection to improve performance
  • Removed logger filters and handlers. Moved to CLI repo.
  • Deleted musify.libraries.remote.core.processors package.

Documentation

  • Updated how-to section to reflect implementation of async logic to underlying code
  • Created a how-to page for installation