import os
import requests
import zipfile
import json

from cStringIO import StringIO
from datetime import datetime
from slyd.gitstorage.repoman import Repoman


DASH_API_URL = None


def set_dash_url(dash_url):
    global DASH_API_URL
    DASH_API_URL = dash_url


def import_project(name, apikey):
    """Download a project from Dash and create a GIT repo for it."""
    archive = zipfile.ZipFile(StringIO(_download_project(name, apikey)))
    repo = Repoman.create_repo(name)
    files = {}
    for filename in archive.namelist():
        contents = archive.read(filename)
        if filename == 'items.json':
            contents = _fix_items(contents)
        files[filename] = contents
    repo.save_files(files, 'master', 'Initial import.')
    return repo


def deploy_project(name, apikey):
    """Archive a GIT project and upload it to Dash."""
    zbuff = StringIO()
    _archive_project(name, zbuff)
    zbuff.reset()
    payload = {'apikey': apikey, 'project': name}
    req = requests.post(DASH_API_URL + 'as/import.json',
        files=[('archive', ('archive', zbuff, 'application/zip'))],
        params=payload)
    project_url = DASH_API_URL.rsplit('/', 2)[0] + '/p/' + name
    return {
        'status': 'ok',
        'schedule_url': project_url,
    }


def _fix_items(raw_items):
    """Fixes issues with the imported items."""
    items = json.loads(raw_items)
    for _, item in items.iteritems():
        if 'url' in item['fields']:
            del item['fields']['url']
    return json.dumps(items) 


def _download_project(name, apikey):
    """Download a zipped project from Dash."""
    payload = {'apikey': apikey, 'project': name, 'version': 'slybot'}
    r = requests.get(DASH_API_URL + 'as/project-slybot.zip', params=payload)
    return r.content


def _add_to_archive(archive, filename, contents, tstamp):
    """Add a file to a zip archive."""
    fileinfo = zipfile.ZipInfo(filename, tstamp)
    fileinfo.external_attr = 0666 << 16L
    archive.writestr(fileinfo, contents, zipfile.ZIP_DEFLATED)


def _archive_project(name, buff):
    """Archive a project stored in GIT into a zip file."""
    repo = Repoman.open_repo(name)
    now = datetime.now().timetuple()[:6]
    archive = zipfile.ZipFile(buff, "w", zipfile.ZIP_DEFLATED)
    for file_path in repo.list_files_for_branch('master'):
        file_contents = repo.file_contents_for_branch(file_path, 'master')
        _add_to_archive(archive, file_path, file_contents, now)
    archive.close()

@@ -153,16 +153,75 @@
 epoman%0A%0A
+from slybot.validation.schema import get_schema_validator%0A%0A
 %0ADASH_AP
@@ -664,16 +664,47 @@
 .json':%0A
+            resource = 'items'%0A
         
@@ -739,16 +739,394 @@
 ntents)%0A
+        elif filename == 'extractors.json':%0A            resource = 'extractors'%0A        elif filename.startswith('spiders'):%0A            resource = 'spider'%0A        else:%0A            resource = None%0A        if resource in %5B'items', 'spider', 'extractors'%5D:%0A            # Validate against slybot schemas.%0A            get_schema_validator(resource).validate(json.loads(contents))%0A
         

Validate resources during project import.