Snippets

Adam Labadorf bitbucket Snippet magic

Created by Adam Labadorf last modified
#https://bitbucket.org/snippets/adamlabadorf/A6gaM
import io
import re

from pybitbucket.auth import BasicAuthenticator
from pybitbucket.bitbucket import Client
from pybitbucket.snippet import Snippet

from IPython.core.magic import register_line_magic, register_cell_magic
from IPython.display import Javascript,HTML,display
from json import dumps

# this replaces the content of the current input cell with txt and the output
# with msg, where msg may be any HTML string
def set_current_input(txt,msg="") :
    js = ("""Jupyter.notebook.get_selected_cell().set_text({});"""
          """element[0].innerHTML={};"""
         ).format(
            dumps(txt)
            ,dumps(msg)
         )
    return Javascript(js)

# this creates a bitbucket snippet and replaces the current input cell
# with a bitbucket_snippet cell magic
@register_line_magic
def create_bitbucket_snippet(line) :
    """Create a new snippet with the given title using the username and authentication
    credentials supplied. The current input of the cell will be replaced with a
    %%bitbucket_snippet magic command that corresponds to the new snippet. The URL to
    the snippet on bitbucket is added as a comment.
    """
    creds_match = re.match(r'"([^"]*)"\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)$',line)
    if not creds_match :
        return "Usage: %create_bitbucket_snippet \"<snippet title>\" <username> <email> <password>"
    creds = creds_match.groups()
    title, user, email, password = creds

    bitbucket =  Client(
        BasicAuthenticator(
            user,
            password,
            email)
    )
    snip = Snippet.create_snippet(
        files=[("file",("jupyter_snippet.py",io.BytesIO()))]
        ,title=title
        ,client=bitbucket
    )
    snippet_line = (title,snip.id,user,email,password)
    new_input = ["%%bitbucket_snippet \"{}\" {} {} {} {}".format(*snippet_line)
                 ,"#{}".format(snip.links['html']['href'])
                ]
    return set_current_input("\n".join(new_input),"Created snippet {}".format(snip.id))

@register_cell_magic
def bitbucket_snippet(line,cell):
    """Cell magic to commit, pull, or source an existing snippet. Usage goes like:
    
    %%bitbucket_snippet "<snippet title>" <snippet_id> <username> <email> <password>
    
    The last line of the cell defines the behavior of the magic. If the last line is:
    
      #COMMIT [<commit message>]
        Take all the input of the cell except the magic line and commit it
        as the current source of the snippet. The snippet title will be changed
        to reflect the title specified in the magic line. The contents of the
        cell are exec'ed into the global scope.
        
      #PULL
        Replace the source of the current cell, excluding the magic line, with
        the content of the snippet and execute it in global scope.
        
      #SOURCE
        Execute the source of the snippet in the global scope and do not replace
        the source of the current cell.
    """
    creds_match = re.match(r'"([^"]*)"\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)$',line)
    if not creds_match :
        return "Usage: %%bitbucket_snippet \"<snippet title>\" <snippet id> <username> <email> <password>"
    creds = creds_match.groups()
    title, snip_id, user, email, password = creds
    
    cell_lines = cell.split("\n")
    
    # the last line of the cell controls what to do
    output = None
    if cell_lines[-1].startswith("#COMMIT") : # commit the contents to the snippet
        bitbucket =  Client(
            BasicAuthenticator(
                user
                ,password
                ,email
            )
        )
        snip = Snippet.find_snippet_by_id_and_owner(snip_id,user,bitbucket)
        # trim off the COMMIT line so we don't accidentally make unnecessary commits
        snip.modify(
            files=[('file',('jupyter_snippet.py',io.BytesIO(cell.encode())))]
            ,title=title
        )
        trimmed_cell = "\n".join(cell_lines[:-1])
        output = set_current_input("%%bitbucket_snippet \"{}\" {} {} {} {}\n".format(*creds)+trimmed_cell
                                   ,"Committed"
                                  )
    elif ( cell_lines[-1].startswith("#PULL") or
           cell_lines[-1].startswith("#SOURCE") ): # pull whatever changes are in the snippet     
        bitbucket =  Client(
            BasicAuthenticator(
                user
                ,password
                ,email
            )
        )
        snip = Snippet.find_snippet_by_id_and_owner(snip_id,user,bitbucket)
        content = snip.content('jupyter_snippet.py').decode('utf-8').split("\n")
        if ( content[-1].startswith("#COMMIT") or
             content[-1].startswith("#SOURCE") or
             content[-1].startswith("#PULL") ) : # strip off last line
            content = content[:-1]
        trimmed_cell = "\n".join(content.decode('utf-8').split("\n"))
        if cell_lines[-1].startswith("#PULL") :
            output = set_current_input("%%bitbucket_snippet \"{}\" {} {} {} {}\n".format(*creds)+trimmed_cell
                                       ,"Pulled"
                                      )
        cell = trimmed_cell
    
    # execute the contents of the cell
    exec(cell,globals())
    
    return output
#COMMIT strip off action commands at the end of input on #PULL or #SOURCE

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.