In [ ]:
from __future__ import print_function

import json
import yaml
from itertools import (islice, izip)

import arrow
from gitenberg import metadata
import jinja2
import semantic_version


import requests
from second_folio import (all_repos, 
                          apply_to_repos, 
                          git_pull,
                          travis_template,
                          repo_version,
                          travis_template,
                          slugify,
                          TRAVIS_TEMPLATE_URL
                          )

from github_settings import (username, password, token)

# import github3.py
import github3

GITenberg_ORG = "GITenberg"

# https://github.com/sigmavirus24/github3.py/pull/368/files
# for personal access tokens
gh = github3.login(username, password=token)

In [ ]:
repos = list(islice(all_repos,0,None))
repos

In [ ]:
# git pull to get updated 

results = list(izip(repos, apply_to_repos(git_pull,
                                        repos=repos)))
[result for result in results if isinstance(result[1], Exception) ]

In [ ]:
# which books still at 0.0.1

[(repo, version_info) for (repo, version_info) in 
   izip(repos, apply_to_repos(repo_version, repos=repos, kwargs={'version_type':'minor', 'write_version':False}))
   if version_info[0] == '0.0.1']

In [ ]:
# loop over repos and see which ones need to be updated to 0.1.0

list(apply_to_repos(repo_version, repos=repos, kwargs={'version_type':'minor', 'write_version':False}))

Using github3.py to make changes


In [ ]:
gh = github3.login(username, password=token)
gh.user().name, gh.user().email

Different ways to work with .travis.yml:

  • use the template
  • manipulate directly as a yaml file

In [ ]:
# rewrite function without assuming that there is a local copy of the repo


class MobiPdfBuilder(object):
    def __init__(self, username, token, repo_name, owner_name='GITenberg',
               update_travis_commit_msg = "updated .travis.yml [ci skip]",
               tag_commit_message = "build mobi and pdf"):
        
        self.gh = github3.login(username, password=token)
        self.repo = self.gh.repository(owner_name, repo_name)
        self.repo_name = repo_name
        self.owner_name = owner_name
        self.update_travis_commit_msg = update_travis_commit_msg
        self.tag_commit_message = tag_commit_message
        
    def go (self, write_changes=True, update_travis=True, tag_commit=True):
        if update_travis:
            (template_result, template_written, commit) =  self.update_travis_template(write_changes=write_changes)
        else:
            (template_result, template_written, commit)  = (None, None, None)
        
        if tag_commit:
            (_version, _next_version, metadata_updated, commit, tag) = self.tag_commit(write_changes=write_changes)
        else:
            (_version, _next_version, metadata_updated, commit, tag) = (None, None, None, None, None)
        
        return [(template_result, template_written, commit),
               (_version, _next_version, metadata_updated, commit, tag)]
        
    def metadata(self):
        """
        returns a metadata.pandata.Pandata object for repo
        """
        metadata_url = "https://raw.githubusercontent.com/{owner}/{repo_name}/master/metadata.yaml".format(owner=self.owner_name,
                                                                               repo_name=self.repo_name)

        md = metadata.pandata.Pandata(metadata_url)
        return md

        
    def update_travis_template(self, write_changes=True, template=None):
        """
        compute (and optionally write) .travis.yml based on the template and current metadata.yaml 

        repo: github3.py representation of repository
        """
        template_written = False

        if template is None:
            template = travis_template()
        
        md = self.metadata()
        repo_name = md.metadata.get("_repo")
        epub_title = slugify(md.metadata.get("title"))

        # pick from rep
        encrypted_key = self.repo.contents(".travis.deploy.api_key.txt", ref='master').decoded.decode('utf-8')

        template_vars =  {
            'epub_title': epub_title,
            'encrypted_key': encrypted_key,
            'repo_name': repo_name
        }

        template_result = template.render(**template_vars)

        if write_changes:
            # how to write to file 
            content = self.repo.contents('.travis.yml', ref='master')
            data = {
                'message': self.update_travis_commit_msg,
                'content': template_result.encode('utf-8'),
            }

            commit = content.update(**data)
        else:
            commit = None

        return (template_result, template_written, commit)
    def tag_commit(self, write_changes=True):
        """
        github3.py representation of repository
        returns current version, next version, whether metadata updated, commit
        """

        md = self.metadata()

        # promote to 0.2.0 or next patch if current version is at least a minor version

        _version = semantic_version.Version(md.metadata.get("_version"))
        if _version >= semantic_version.Version("0.2.0"):
            _next_version = unicode(_version.next_patch())
        else:
             _next_version = u"0.2.0"

        if write_changes:

            # how to write to file 
            content = self.repo.contents('metadata.yaml', ref='master')
            md.metadata["_version"] =  _next_version
            data = {
                'message': self.tag_commit_message,
                'content': yaml.safe_dump(md.metadata,default_flow_style=False,allow_unicode=True)
            }
            commit = content.update(**data)

            # also tag the commit
            tag_data =  {
                'tag': _next_version,
                'message': _next_version,
                'sha': commit.sha,
                'obj_type': 'commit',
                'tagger': {
                    'name': self.gh.user().name,
                    'email': gh.user().email,
                    'date': arrow.utcnow().isoformat()
                },
                'lightweight': False
            }

            tag = self.repo.create_tag(**tag_data)

            metadata_updated = True
        else:
            commit = None
            tag = None
            metadata_updated = False

        return (_version, _next_version, metadata_updated, commit, tag)
    
    def url_latest_epub(self):
        """
        repo is a github3.py repo
        """
        
        md = self.metadata()
        epub_title = slugify(md.metadata.get("title"))
        tag = md.metadata.get("_version")
        url = "https://github.com/GITenberg/{}/releases/download/{}/{}.epub".format(self.repo_name, tag, epub_title)
        return url
    
    def status_latest_epub(self):
        return requests.head(self.url_latest_epub()).status_code

In [ ]:
def build_repo(repo_name):
    builder = MobiPdfBuilder(username, token, repo_name)
    try:
        result = builder.go(write_changes=True, update_travis=True, tag_commit=True)
    except Exception as e:
        result = e
    return (result, builder)
    
def epub_status(repo_name):
    builder = MobiPdfBuilder(username, token, repo_name)
    return builder.status_latest_epub()

In [ ]:
all_repos

In [ ]:
repos = all_repos
repos

In [ ]:
for (repo, status) in izip(repos, apply_to_repos(epub_status, repos=repos)):
    print (repo, status)

In [ ]:
results = list(apply_to_repos(build_repo, repos=all_repos[2:]))
list(results)