#!/usr/bin/python
# Author: Anthony Ruhier

import os
import mpd
import multiprocessing
from multiprocessing.managers import BaseManager
from .muspy_api import Muspy_api
from .artist_db import Artist_db
from . import _current_dir
from config import ARTISTS_JSON, SERVER, PORT

ARTISTS_JSON = os.path.join(_current_dir, ARTISTS_JSON)
NB_MULTIPROCESS = 3


class SyncManager(BaseManager):
    pass

SyncManager.register('Artist_db', Artist_db)
SyncManager.register('Muspy_api', Muspy_api)


def chunks(l, n):
    """
    Yield successive n-sized chunks from l.
    """
    for i in range(0, len(l), n):
        yield l[i:i+n]


def mpd_get_artists(artist_db, mpdclient):
    mpdclient.connect(SERVER, PORT)
    try:
        artists = set(str(artist).lower()
                      for artist in mpdclient.list("artist") if len(artist))
    except mpd.ConnectionError:
        mpdclient.connect(SERVER, PORT)
        artists = set(str(artist).lower()
                      for artist in mpdclient.list("artist") if len(artist))
    return artists


def process_task(artists, artist_db, muspy_api, lock):
    for artist in artists:
        try:
            muspy_api.add_artist(artist)
            lock.acquire()
            artist_db.mark_as_uploaded(artist)
            artist_db.save()
            lock.release()
            print("Artist:", artist, ". Done...")
        except Exception as e:
            print(e)
            pass


def start_process(non_uploaded_artists, artist_db):
    process_list = []
    lock = multiprocessing.Lock()
    process_list = []
    muspy_api = Muspy_api()
    nb_artists_by_split = int(len(non_uploaded_artists) / NB_MULTIPROCESS)
    for l in chunks(non_uploaded_artists, nb_artists_by_split):
        process = multiprocessing.Process(
            target=process_task,
            kwargs={"artists": l, "artist_db": artist_db,
                    "muspy_api": muspy_api, "lock": lock}
        )
        process.daemon = True
        process.start()
        process_list.append(process)

    for process in process_list:
        process.join()


def run():
    process_manager = SyncManager()
    process_manager.start()
    artist_db = process_manager.Artist_db(jsonpath=ARTISTS_JSON)
    mpdclient = mpd.MPDClient()

    artists = mpd_get_artists(artist_db, mpdclient)
    artists_removed, artists_added = artist_db.merge(artists)
    artist_db.save()
    non_uploaded_artists = artist_db.get_non_uploaded()
    artists = None

    print(len(non_uploaded_artists), "artist(s) non uploaded on muspy")
    print(len(artists_added), "artist(s) added")
    print(len(artists_removed), "artist(s) removed")

    start_process(non_uploaded_artists, artist_db)
    print("Done: ",
          len(non_uploaded_artists) - len(artist_db.get_non_uploaded()),
          "artist(s) updated")

@@ -1055,32 +1055,44 @@
 ss_task(artists,
+ artists_nb,
  artist_db, musp
@@ -1102,16 +1102,25 @@
 pi, lock
+, counter
 ):%0A    f
@@ -1141,16 +1141,35 @@
 rtists:%0A
+        error = %22%22%0A
         
@@ -1230,23 +1230,23 @@
     
-lock.acquire()%0A
+with lock:%0A    
     
@@ -1292,32 +1292,36 @@
 st)%0A            
+    
 artist_db.save()
@@ -1333,129 +1333,265 @@
     
-    lock.release()%0A            print(%22Artist:%22, artist, %22. Done...%22)%0A        except Exception as e:%0A            print(e)%0A
+except Exception as e:%0A            error = %22Error: %22 + str(e)%0A            pass%0A        finally:%0A            with lock:%0A                counter.value += 1%0A            print(%22%5B%22, counter.value, %22/%22, artists_nb, %22%5D:%22, artist.title())%0A            if error:%0A    
     
@@ -1599,19 +1599,27 @@
        p
-ass
+rint(error)
 %0A%0A%0Adef s
@@ -1779,59 +1779,131 @@
     
-nb_artists_by_split = int(len(non_uploaded_artists)
+counter = multiprocessing.Value(%22i%22, 0)%0A    artists_nb = len(non_uploaded_artists)%0A    artists_nb_by_split = int(artists_nb
  / N
@@ -1964,19 +1964,16 @@
 ts, 
-nb_
 artists_
 by_s
@@ -1968,16 +1968,19 @@
 artists_
+nb_
 by_split
@@ -2099,18 +2099,19 @@
  %22artist
-_d
+s_n
 b%22: arti
@@ -2112,18 +2112,19 @@
 : artist
-_d
+s_n
 b,%0A     
@@ -2143,43 +2143,107 @@
    %22
-muspy_api%22: muspy_api, %22lock%22: lock
+artist_db%22: artist_db, %22muspy_api%22: muspy_api,%0A                    %22lock%22: lock, %22counter%22: counter
 %7D%0A  
@@ -2959,16 +2959,72 @@
 oved%22)%0A%0A
+    print(%22%5Cn   Start syncing  %5Cn =================%5Cn%22)%0A
     star

Improve output