Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Change for Python 3 #144

Draft
wants to merge 44 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
22c311c
Add files via upload
ldsz Apr 26, 2020
5ab2843
Add files via upload
ldsz Jun 10, 2020
599323e
Delete utils.py
ldsz Jun 10, 2020
d8023dd
Delete httpproxy.py
ldsz Jun 10, 2020
d7d8a57
Add files via upload
ldsz Jun 10, 2020
69a9f84
Add files via upload
ldsz Jun 10, 2020
5ef5be2
Modded for Kodi 19
ldsz Jun 10, 2020
9a3f5c6
Modded for Kodi 19
ldsz Jun 10, 2020
f316d9f
Update README.md
ldsz Jun 10, 2020
0e67d94
Modded For Kodi 19
ldsz Jun 10, 2020
81a68db
Merge branch 'master' of https://github.com/ldsz/plugin.audio.spotify
ldsz Jun 10, 2020
97022d0
Search error fix
ldsz Jun 12, 2020
4b6e8c3
Change LOGNOTICE
ldsz Sep 18, 2020
ed1b355
Change LOGNOTICE
ldsz Sep 18, 2020
9f24d08
remove xbmc.translate
ldsz Sep 18, 2020
08ef018
Remove LOGNOTICE
ldsz Sep 18, 2020
193a80c
remove comment
ldsz Sep 18, 2020
5528c21
Remove LOGNOTICE
ldsz Sep 26, 2020
4399457
Update Version
ldsz Dec 31, 2020
f80eb9e
update 1.2.0
ldsz Dec 31, 2020
747020d
update 1.2.1
ldsz Dec 31, 2020
1610e5a
Merge branch 'master' of https://github.com/ldsz/plugin.audio.spotify
ldsz Apr 10, 2021
488a04f
Update addon.xml
ldsz Apr 10, 2021
6d3883c
1.2.2 - Add volume control from Spotify Connect
ldsz Apr 12, 2021
e9b7944
Change volume only if it's changed in the app first
ldsz Apr 12, 2021
0ef3b70
remove decode("utf-8")
Elkropac Apr 18, 2021
b09f4b3
start spotty only if not running
Elkropac Apr 18, 2021
ce6f7dc
move kill_spotty to Spotty class and use detected binary
Elkropac Apr 18, 2021
871035d
use kill_spotty from class
Elkropac Apr 18, 2021
49446c3
Merge pull request #6 from Elkropac/for-ldsz
ldsz Apr 18, 2021
4efe2bb
remove pyc files
Elkropac Apr 20, 2021
e08784b
prevent zombies
Elkropac Apr 20, 2021
456f439
save process to separate variable
Elkropac Apr 20, 2021
fc99aee
expose /lms
Elkropac Apr 20, 2021
9b03dd9
connect to right url
Elkropac Apr 20, 2021
c22a49d
Merge pull request #9 from Elkropac/for-ldsz-connect
ldsz Apr 22, 2021
3e0a7a6
Merge pull request #8 from Elkropac/for-ldsz
ldsz Apr 22, 2021
120d3bb
Merge pull request #7 from Elkropac/for-ldsz-zombies
ldsz Apr 22, 2021
c8f233d
Update addon.xml
ldsz Apr 25, 2021
d48b2f3
Update Cheroot / Cherrypy
ldsz Apr 26, 2021
d4991ca
update cheroot
ldsz Apr 29, 2021
47ad90b
fix proxy
FernetMenta May 19, 2021
1af876d
have videoplayer do the playback. it does not open multiple files at …
FernetMenta May 19, 2021
ddc4a04
Merge pull request #14 from FernetMenta/fix
ldsz Nov 28, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*.pyo
.DS_Store
*.pyc
.DS_Store
16 changes: 2 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,7 @@ Unofficial spotify plugin for Kodi, (for now) not yet available in the official

Based on the opensource Librespot client. Special thanks to mherger for building the special spotty binaries, based on librespot.


## Install with repository
Install the add-on from my Kodi repo:
https://github.com/kodi-community-addons/repository.marcelveldt/raw/master/repository.marcelveldt/repository.marcelveldt-1.0.1.zip

This a fork of [marcelveldt](https://github.com/marcelveldt) version modified to make it work with Kodi 19.

## Support
Support is provided on the Kodi forums:
http://forum.kodi.tv/showthread.php?tid=265356
Or create issue in Github


## Help needed with maintaining !
I am very busy currently so I do not have a lot of time to work on this project or watch the forums.
Be aware that this is a community driven project, so feel free to submit PR's yourself to improve the code and/or help others with support on the forums etc. If you're willing to really participate in the development, please contact me so I can give you write access to the repo. I do my best to maintain the project every once in a while, when I have some spare time left.
Thanks for understanding!
create issue in Github
17 changes: 10 additions & 7 deletions addon.xml
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<addon id="plugin.audio.spotify" version="1.1.59" name="Spotify" provider-name="marcelveldt">
<addon id="plugin.audio.spotify" version="1.2.3" name="Spotify" provider-name="LdSz">
<requires>
<import addon="xbmc.python" version="2.1.0"/>
<import addon="xbmc.python" version="3.0.0"/>
<import addon="xbmc.addon" version="12.0.0"/>
<import addon="script.module.requests" version="2.3.0"/>
<import addon="script.module.simplejson" version="3.3.0"/>
<import addon="script.module.simplecache" version="1.0.0"/>
<import addon="script.module.cherrypy" version="11.0.0"/>
<import addon="script.module.metadatautils" version="1.0.0"/>
<import addon="script.module.requests" version="2.22.0"/>
<import addon="script.module.simplejson" version="3.17.0"/>
<import addon="script.module.simplecache" version="2.0.0"/>
<import addon="script.module.six" version="1.14.0"/>
</requires>
<extension point="xbmc.python.pluginsource" library="plugin.py">
<provides>audio</provides>
Expand All @@ -18,5 +17,9 @@
<summary>Unofficial Spotify music plugin for Kodi</summary>
<description>Requires a Spotify premium account.</description>
<disclaimer>This product uses SPOTIFY(R) CORE but is not endorsed, certified or otherwise approved in any way by Spotify. Spotify is the registered trade mark of the Spotify Group.</disclaimer>
<assets>
<icon>resources/icon.png</icon>
<fanart>resources/fanart.jpg</fanart>
</assets>
</extension>
</addon>
File renamed without changes
File renamed without changes
1 change: 1 addition & 0 deletions resources/lib/backports/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__path__ = __import__('pkgutil').extend_path(__path__, __name__)
184 changes: 184 additions & 0 deletions resources/lib/backports/functools_lru_cache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
from __future__ import absolute_import

import functools
from collections import namedtuple
from threading import RLock

_CacheInfo = namedtuple("CacheInfo", ["hits", "misses", "maxsize", "currsize"])


@functools.wraps(functools.update_wrapper)
def update_wrapper(wrapper,
wrapped,
assigned = functools.WRAPPER_ASSIGNMENTS,
updated = functools.WRAPPER_UPDATES):
"""
Patch two bugs in functools.update_wrapper.
"""
# workaround for http://bugs.python.org/issue3445
assigned = tuple(attr for attr in assigned if hasattr(wrapped, attr))
wrapper = functools.update_wrapper(wrapper, wrapped, assigned, updated)
# workaround for https://bugs.python.org/issue17482
wrapper.__wrapped__ = wrapped
return wrapper


class _HashedSeq(list):
__slots__ = 'hashvalue'

def __init__(self, tup, hash=hash):
self[:] = tup
self.hashvalue = hash(tup)

def __hash__(self):
return self.hashvalue


def _make_key(args, kwds, typed,
kwd_mark=(object(),),
fasttypes=set([int, str, frozenset, type(None)]),
sorted=sorted, tuple=tuple, type=type, len=len):
'Make a cache key from optionally typed positional and keyword arguments'
key = args
if kwds:
sorted_items = sorted(kwds.items())
key += kwd_mark
for item in sorted_items:
key += item
if typed:
key += tuple(type(v) for v in args)
if kwds:
key += tuple(type(v) for k, v in sorted_items)
elif len(key) == 1 and type(key[0]) in fasttypes:
return key[0]
return _HashedSeq(key)


def lru_cache(maxsize=100, typed=False):
"""Least-recently-used cache decorator.

If *maxsize* is set to None, the LRU features are disabled and the cache
can grow without bound.

If *typed* is True, arguments of different types will be cached separately.
For example, f(3.0) and f(3) will be treated as distinct calls with
distinct results.

Arguments to the cached function must be hashable.

View the cache statistics named tuple (hits, misses, maxsize, currsize) with
f.cache_info(). Clear the cache and statistics with f.cache_clear().
Access the underlying function with f.__wrapped__.

See: http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used

"""

# Users should only access the lru_cache through its public API:
# cache_info, cache_clear, and f.__wrapped__
# The internals of the lru_cache are encapsulated for thread safety and
# to allow the implementation to change (including a possible C version).

def decorating_function(user_function):

cache = dict()
stats = [0, 0] # make statistics updateable non-locally
HITS, MISSES = 0, 1 # names for the stats fields
make_key = _make_key
cache_get = cache.get # bound method to lookup key or return None
_len = len # localize the global len() function
lock = RLock() # because linkedlist updates aren't threadsafe
root = [] # root of the circular doubly linked list
root[:] = [root, root, None, None] # initialize by pointing to self
nonlocal_root = [root] # make updateable non-locally
PREV, NEXT, KEY, RESULT = 0, 1, 2, 3 # names for the link fields

if maxsize == 0:

def wrapper(*args, **kwds):
# no caching, just do a statistics update after a successful call
result = user_function(*args, **kwds)
stats[MISSES] += 1
return result

elif maxsize is None:

def wrapper(*args, **kwds):
# simple caching without ordering or size limit
key = make_key(args, kwds, typed)
result = cache_get(key, root) # root used here as a unique not-found sentinel
if result is not root:
stats[HITS] += 1
return result
result = user_function(*args, **kwds)
cache[key] = result
stats[MISSES] += 1
return result

else:

def wrapper(*args, **kwds):
# size limited caching that tracks accesses by recency
key = make_key(args, kwds, typed) if kwds or typed else args
with lock:
link = cache_get(key)
if link is not None:
# record recent use of the key by moving it to the front of the list
root, = nonlocal_root
link_prev, link_next, key, result = link
link_prev[NEXT] = link_next
link_next[PREV] = link_prev
last = root[PREV]
last[NEXT] = root[PREV] = link
link[PREV] = last
link[NEXT] = root
stats[HITS] += 1
return result
result = user_function(*args, **kwds)
with lock:
root, = nonlocal_root
if key in cache:
# getting here means that this same key was added to the
# cache while the lock was released. since the link
# update is already done, we need only return the
# computed result and update the count of misses.
pass
elif _len(cache) >= maxsize:
# use the old root to store the new key and result
oldroot = root
oldroot[KEY] = key
oldroot[RESULT] = result
# empty the oldest link and make it the new root
root = nonlocal_root[0] = oldroot[NEXT]
oldkey = root[KEY]
root[KEY] = root[RESULT] = None
# now update the cache dictionary for the new links
del cache[oldkey]
cache[key] = oldroot
else:
# put result in a new link at the front of the list
last = root[PREV]
link = [last, root, key, result]
last[NEXT] = root[PREV] = cache[key] = link
stats[MISSES] += 1
return result

def cache_info():
"""Report cache statistics"""
with lock:
return _CacheInfo(stats[HITS], stats[MISSES], maxsize, len(cache))

def cache_clear():
"""Clear the cache and cache statistics"""
with lock:
cache.clear()
root = nonlocal_root[0]
root[:] = [root, root, None, None]
stats[:] = [0, 0]

wrapper.__wrapped__ = user_function
wrapper.cache_info = cache_info
wrapper.cache_clear = cache_clear
return update_wrapper(wrapper, user_function)

return decorating_function
15 changes: 15 additions & 0 deletions resources/lib/cheroot/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""High-performance, pure-Python HTTP server used by CherryPy."""

from __future__ import absolute_import, division, print_function
__metaclass__ = type

try:
import pkg_resources
except ImportError:
pass


try:
__version__ = pkg_resources.get_distribution('cheroot').version
except Exception:
__version__ = '8.5.2'
6 changes: 6 additions & 0 deletions resources/lib/cheroot/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
"""Stub for accessing the Cheroot CLI tool."""

from .cli import main

if __name__ == '__main__':
main()
Loading