<commit_before>import requests
import re
import json
import ast
import os
import ui
import threading
import tarfile
import math
import time
import plistlib
import console
import shutil
import sqlite3

class Cheatsheet (object):
	def __init__(self):
		self.__version = ''
		self.__globalversion = ''
		self.__name = ''
		self.__aliases = []
		self.__icon = None
		self.__id = ''
		self.__path = None
		self.__status = ''
		self.__stats = ''

	@property
	def version(self):
		return self.__version

	@version.setter
	def version(self, version):
		self.__version = version

	@property
	def globalversion(self):
		return self.__globalversion

	@globalversion.setter
	def globalversion(self, globalversion):
		self.__globalversion = globalversion

	@property
	def name(self):
		return self.__name

	@name.setter
	def name(self, name):
		self.__name = name

	@property
	def aliases(self):
		return self.__aliases

	@aliases.setter
	def aliases(self, aliases):
		self.__aliases = aliases

	@property
	def image(self):
		return self.__icon

	@image.setter
	def image(self, icon):
		self.__icon = icon

	@property
	def id(self):
		return self.__id

	@id.setter
	def id(self, id):
		self.__id = id

	@property
	def path(self):
		return self.__path

	@path.setter
	def path(self, path):
		self.__path = path

	@property
	def status(self):
		return self.__status

	@status.setter
	def status(self, status):
		self.__status = status

	@property
	def stats(self):
		return self.__stats

	@stats.setter
	def stats(self, stats):
		self.__stats = stats

class CheatsheetManager (object):
	def __init__(self, serverManager, iconPath, typeIconPath):
		self.serverManager = serverManager
		self.iconPath = iconPath
		self.typeIconPath = typeIconPath
		self.localServer = None
		self.jsonServerLocation = 'zzz/cheatsheets/cheat.json'
		self.downloadServerLocation = 'zzz/cheatsheets/%@.tgz'
		self.plistPath = 'Contents/Info.plist'
		self.indexPath = 'Contents/Resources/docSet.dsidx'
		self.cheatsheetFolder = 'Cheatsheets'
		self.headers = {'User-Agent': 'PyDoc-Pythonista'}
		self.cheatsheets = None
		self.downloading = []
		self.workThreads = []
		self.downloadThreads = []
		self.uiUpdateThreads = []
		self.__createCheatsheetFolder()

	def getAvailableCheatsheets(self):
		cheatsheets = self.__getOnlineCheatsheets()
		for d in self.__getDownloadedCheatsheets():
			for c in cheatsheets:
				if c.name == d['name']:
					c.status = 'installed'
					c.path = d['path']
		for d in self.__getDownloadingCheatsheets():
			for c in cheatsheets:
				if c.name == d.name:
					c.status = d.status
					try:
						c.stats = d.stats
					except KeyError:
						c.stats = 'downloading'
		return cheatsheets

	def __getOnlineCheatsheets(self):
		if self.cheatsheets == None:
			self.cheatsheets = self.__getCheatsheets()
		return self.cheatsheets

	def __getDownloadedCheatsheets(self):
		ds = []
		folder = os.path.join(os.path.abspath('.'), self.cheatsheetFolder)
		for dir in os.listdir(folder):
			if os.path.isdir(os.path.join(folder,dir)):
				pl = plistlib.readPlist(
				os.path.join(folder,dir, self.plistPath))
				name = pl['CFBundleName']
				ds.append({'name':name,'path':os.path.join(folder,dir)})
		return ds

	def __getDownloadingCheatsheets(self):
		return self.downloading

	def getDownloadedCheatsheets(self):
		ds = []
		for dd in self.__getDownloadedCheatsheets():
			for feed in self.__getOnlineCheatsheets():
				if dd['name'] == feed.name:
					feed.path = dd['path']
					ds.append(feed)
		return ds

	def __getCheatsheets(self):
		server = self.serverManager.getDownloadServer(self.localServer)
		url = server.url
		if not url[-1] == '/':
			url = url + '/'
		url = url + self.jsonServerLocation
		data = requests.get(url).text
		data = ast.literal_eval(data)

		cheatsheets = []
		icon = self.__getIconWithName('cheatsheet')
		for k,d in data['cheatsheets'].items():
			c = Cheatsheet()
			c.name = d['name']
			c.aliases = d['aliases']
			c.globalversion = data['global_version']
			c.version = d['version']
			c.image = icon
			c.id = k
			c.status = 'online'
			cheatsheets.append(c)
		return cheatsheets

	def __getIconWithName(self, name):
		imgPath = os.path.join(os.path.abspath('.'), self.iconPath, name+'.png')
		return ui.Image.named(imgPath)

	def __getTypeIconWithName(self, name):
		imgPath = os.path.join(os.path.abspath('.'), self.typeIconPath, name+'.png')
		return ui.Image.named(imgPath)

	def __createCheatsheetFolder(self):
		if not os.path.exists(self.cheatsheetFolder):
			os.mkdir(self.cheatsheetFolder)

	def downloadCheatsheet(self, cheatsheet, action, refresh_main_view):
		if not cheatsheet in self.downloading:
			cheatsheet.status = 'downloading'
			self.downloading.append(cheatsheet)
			action()
			workThread = threading.Thread(target=self.__determineUrlAndDownload, args=(cheatsheet,action,refresh_main_view,))
			self.workThreads.append(workThread)
			workThread.start()

	def __determineUrlAndDownload(self, cheatsheet, action, refresh_main_view):
		cheatsheet.stats = 'getting download link'
		action()
		downloadLink = self.__getDownloadLink(cheatsheet.id)
		print(downloadLink)
		downloadThread = threading.Thread(target=self.downloadFile, args=(downloadLink,cheatsheet,refresh_main_view,))
		self.downloadThreads.append(downloadThread)
		downloadThread.start()
		updateThread = threading.Thread(target=self.updateUi, args=(action,downloadThread,))
		self.uiUpdateThreads.append(updateThread)
		updateThread.start()

	def updateUi(self, action, t):
		while t.is_alive():
			action()
			time.sleep(0.5)
		action()

	def __getDownloadLink(self, id):
		server = self.serverManager.getDownloadServer(self.localServer)
		url = server.url
		if not url[-1] == '/':
			url = url + '/'
		url = url + self.downloadServerLocation
		url = url.replace('%@', id)
		return url

	def downloadFile(self, url, cheatsheet, refresh_main_view):
		local_filename = self.__downloadFile(url, cheatsheet)
		#self.__downloadFile(url+'.tarix', cheatsheet)
		cheatsheet.status = 'waiting for install'
		self.installCheatsheet(local_filename, cheatsheet, refresh_main_view)

	def __downloadFile(self, url, cheatsheet):
		local_filename = self.cheatsheetFolder+'/'+url.split('/')[-1]
		r = requests.get(url, headers = self.headers, stream=True)
		ret = None
		if r.status_code == 200:
			ret = local_filename
			total_length = r.headers.get('content-length')
			dl = 0
			last = 0
			if os.path.exists(local_filename):
				os.remove(local_filename)
			with open(local_filename, 'wb') as f:
				for chunk in r.iter_content(chunk_size=1024):
					if chunk: # filter out keep-alive new chunks
						dl += len(chunk)
						f.write(chunk)
						if not total_length == None:
							done = 100 * dl / int(total_length)
							cheatsheet.stats = str(round(done,2)) + '% ' + str(self.convertSize(dl)) + ' / '+ str(self.convertSize(float(total_length)))
						else:
							 cheatsheet.stats = str(self.convertSize(dl))

		r.close()
		return ret

	def installCheatsheet(self, filename, cheatsheet, refresh_main_view):
		extract_location = self.cheatsheetFolder
		cheatsheet.status = 'Preparing to install: This might take a while.'
		tar = tarfile.open(filename, 'r:gz')
		tar.extractall(path=extract_location, members = self.track_progress(tar, cheatsheet, len(tar.getmembers())))
		tar.close()
		os.remove(filename)
		self.indexCheatsheet(cheatsheet, refresh_main_view)

	def track_progress(self, members, cheatsheet, totalFiles):
		i = 0
		for member in members:
			i = i + 1
			done = 100 * i / totalFiles
			cheatsheet.status = 'installing: ' + str(round(done,2)) + '% ' + str(i) + ' / '+ str(totalFiles)
			yield member

	def indexCheatsheet(self, cheatsheet, refresh_main_view):
		cheatsheet.status = 'indexing'
		self.postProcess(cheatsheet, refresh_main_view)

	def postProcess(self, cheatsheet, refresh_main_view):
		cheatsheet.status = 'installed'
		refresh_main_view()

	def convertSize(self, size):
		if (size == 0):
			return '0B'
		size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
		i = int(math.floor(math.log(size,1024)))
		p = math.pow(1024,i)
		s = round(size/p,2)
		return '%s %s' % (s,size_name[i])

	def deleteCheatsheet(self, cheatsheet, post_action):
		but = console.alert('Are you sure?', 'Would you like to delete the cheatsheet, ' +  cheatsheet.name, 'Ok')
		if but == 1:
			shutil.rmtree(cheatsheet.path)
			cheatsheet.status = 'online'
			post_action()
			cheatsheet.path = None

	def getTypesForCheatsheet(self, cheatsheet):
		types = []
		path = cheatsheet.path
		indexPath = os.path.join(path, self.indexPath)
		conn = sqlite3.connect(indexPath)
		sql = 'SELECT type FROM searchIndex GROUP BY type'
		c = conn.execute(sql)
		data = c.fetchall()
		conn.close()
		for t in data:
			types.append({'name':t[0], 'image':self.__getTypeIconWithName(t[0])})
		return types

	def getIndexesbyTypeForCheatsheet(self, cheatsheet, type):
		indexes = []
		path = cheatsheet.path
		indexPath = os.path.join(path, self.indexPath)
		conn = sqlite3.connect(indexPath)
		sql = 'SELECT type, name, path FROM searchIndex WHERE type = \'' + type['name'] + '\''
		c = conn.execute(sql)
		data = c.fetchall()
		conn.close()
		img = self.__getTypeIconWithName(type['name'])
		for t in data:
			indexes.append({'type':{'name':t[0], 'image':img}, 'name':t[1],'path':t[2]})
		return indexes

	def getIndexesForCheatsheet(self, cheatsheet):
		indexes = []
		path = cheatsheet.path
		indexPath = os.path.join(path, self.indexPath)
		conn = sqlite3.connect(indexPath)
		sql = 'SELECT type, name, path FROM searchIndex'
		c = conn.execute(sql)
		data = c.fetchall()
		conn.close()
		for i in data:
			indexes.append({'type':{'name':t[0], 'image':self.__getTypeIconWithName(t[0])}, 'name':t[1],'path':t[2]})
		return types

if __name__ == '__main__':
	import ServerManager
	c = CheatsheetManager(ServerManager.ServerManager(), '../Images/icons')

<commit_msg>removed debugging lines<commit_after>import requests
import re
import json
import ast
import os
import ui
import threading
import tarfile
import math
import time
import plistlib
import console
import shutil
import sqlite3

class Cheatsheet (object):
	def __init__(self):
		self.__version = ''
		self.__globalversion = ''
		self.__name = ''
		self.__aliases = []
		self.__icon = None
		self.__id = ''
		self.__path = None
		self.__status = ''
		self.__stats = ''

	@property
	def version(self):
		return self.__version

	@version.setter
	def version(self, version):
		self.__version = version

	@property
	def globalversion(self):
		return self.__globalversion

	@globalversion.setter
	def globalversion(self, globalversion):
		self.__globalversion = globalversion

	@property
	def name(self):
		return self.__name

	@name.setter
	def name(self, name):
		self.__name = name

	@property
	def aliases(self):
		return self.__aliases

	@aliases.setter
	def aliases(self, aliases):
		self.__aliases = aliases

	@property
	def image(self):
		return self.__icon

	@image.setter
	def image(self, icon):
		self.__icon = icon

	@property
	def id(self):
		return self.__id

	@id.setter
	def id(self, id):
		self.__id = id

	@property
	def path(self):
		return self.__path

	@path.setter
	def path(self, path):
		self.__path = path

	@property
	def status(self):
		return self.__status

	@status.setter
	def status(self, status):
		self.__status = status

	@property
	def stats(self):
		return self.__stats

	@stats.setter
	def stats(self, stats):
		self.__stats = stats

class CheatsheetManager (object):
	def __init__(self, serverManager, iconPath, typeIconPath):
		self.serverManager = serverManager
		self.iconPath = iconPath
		self.typeIconPath = typeIconPath
		self.localServer = None
		self.jsonServerLocation = 'zzz/cheatsheets/cheat.json'
		self.downloadServerLocation = 'zzz/cheatsheets/%@.tgz'
		self.plistPath = 'Contents/Info.plist'
		self.indexPath = 'Contents/Resources/docSet.dsidx'
		self.cheatsheetFolder = 'Cheatsheets'
		self.headers = {'User-Agent': 'PyDoc-Pythonista'}
		self.cheatsheets = None
		self.downloading = []
		self.workThreads = []
		self.downloadThreads = []
		self.uiUpdateThreads = []
		self.__createCheatsheetFolder()

	def getAvailableCheatsheets(self):
		cheatsheets = self.__getOnlineCheatsheets()
		for d in self.__getDownloadedCheatsheets():
			for c in cheatsheets:
				if c.name == d['name']:
					c.status = 'installed'
					c.path = d['path']
		for d in self.__getDownloadingCheatsheets():
			for c in cheatsheets:
				if c.name == d.name:
					c.status = d.status
					try:
						c.stats = d.stats
					except KeyError:
						c.stats = 'downloading'
		return cheatsheets

	def __getOnlineCheatsheets(self):
		if self.cheatsheets == None:
			self.cheatsheets = self.__getCheatsheets()
		return self.cheatsheets

	def __getDownloadedCheatsheets(self):
		ds = []
		folder = os.path.join(os.path.abspath('.'), self.cheatsheetFolder)
		for dir in os.listdir(folder):
			if os.path.isdir(os.path.join(folder,dir)):
				pl = plistlib.readPlist(
				os.path.join(folder,dir, self.plistPath))
				name = pl['CFBundleName']
				ds.append({'name':name,'path':os.path.join(folder,dir)})
		return ds

	def __getDownloadingCheatsheets(self):
		return self.downloading

	def getDownloadedCheatsheets(self):
		ds = []
		for dd in self.__getDownloadedCheatsheets():
			for feed in self.__getOnlineCheatsheets():
				if dd['name'] == feed.name:
					feed.path = dd['path']
					ds.append(feed)
		return ds

	def __getCheatsheets(self):
		server = self.serverManager.getDownloadServer(self.localServer)
		url = server.url
		if not url[-1] == '/':
			url = url + '/'
		url = url + self.jsonServerLocation
		data = requests.get(url).text
		data = ast.literal_eval(data)

		cheatsheets = []
		icon = self.__getIconWithName('cheatsheet')
		for k,d in data['cheatsheets'].items():
			c = Cheatsheet()
			c.name = d['name']
			c.aliases = d['aliases']
			c.globalversion = data['global_version']
			c.version = d['version']
			c.image = icon
			c.id = k
			c.status = 'online'
			cheatsheets.append(c)
		return cheatsheets

	def __getIconWithName(self, name):
		imgPath = os.path.join(os.path.abspath('.'), self.iconPath, name+'.png')
		return ui.Image.named(imgPath)

	def __getTypeIconWithName(self, name):
		imgPath = os.path.join(os.path.abspath('.'), self.typeIconPath, name+'.png')
		return ui.Image.named(imgPath)

	def __createCheatsheetFolder(self):
		if not os.path.exists(self.cheatsheetFolder):
			os.mkdir(self.cheatsheetFolder)

	def downloadCheatsheet(self, cheatsheet, action, refresh_main_view):
		if not cheatsheet in self.downloading:
			cheatsheet.status = 'downloading'
			self.downloading.append(cheatsheet)
			action()
			workThread = threading.Thread(target=self.__determineUrlAndDownload, args=(cheatsheet,action,refresh_main_view,))
			self.workThreads.append(workThread)
			workThread.start()

	def __determineUrlAndDownload(self, cheatsheet, action, refresh_main_view):
		cheatsheet.stats = 'getting download link'
		action()
		downloadLink = self.__getDownloadLink(cheatsheet.id)
		downloadThread = threading.Thread(target=self.downloadFile, args=(downloadLink,cheatsheet,refresh_main_view,))
		self.downloadThreads.append(downloadThread)
		downloadThread.start()
		updateThread = threading.Thread(target=self.updateUi, args=(action,downloadThread,))
		self.uiUpdateThreads.append(updateThread)
		updateThread.start()

	def updateUi(self, action, t):
		while t.is_alive():
			action()
			time.sleep(0.5)
		action()

	def __getDownloadLink(self, id):
		server = self.serverManager.getDownloadServer(self.localServer)
		url = server.url
		if not url[-1] == '/':
			url = url + '/'
		url = url + self.downloadServerLocation
		url = url.replace('%@', id)
		return url

	def downloadFile(self, url, cheatsheet, refresh_main_view):
		local_filename = self.__downloadFile(url, cheatsheet)
		#self.__downloadFile(url+'.tarix', cheatsheet)
		cheatsheet.status = 'waiting for install'
		self.installCheatsheet(local_filename, cheatsheet, refresh_main_view)

	def __downloadFile(self, url, cheatsheet):
		local_filename = self.cheatsheetFolder+'/'+url.split('/')[-1]
		r = requests.get(url, headers = self.headers, stream=True)
		ret = None
		if r.status_code == 200:
			ret = local_filename
			total_length = r.headers.get('content-length')
			dl = 0
			last = 0
			if os.path.exists(local_filename):
				os.remove(local_filename)
			with open(local_filename, 'wb') as f:
				for chunk in r.iter_content(chunk_size=1024):
					if chunk: # filter out keep-alive new chunks
						dl += len(chunk)
						f.write(chunk)
						if not total_length == None:
							done = 100 * dl / int(total_length)
							cheatsheet.stats = str(round(done,2)) + '% ' + str(self.convertSize(dl)) + ' / '+ str(self.convertSize(float(total_length)))
						else:
							 cheatsheet.stats = str(self.convertSize(dl))

		r.close()
		return ret

	def installCheatsheet(self, filename, cheatsheet, refresh_main_view):
		extract_location = self.cheatsheetFolder
		cheatsheet.status = 'Preparing to install: This might take a while.'
		tar = tarfile.open(filename, 'r:gz')
		tar.extractall(path=extract_location, members = self.track_progress(tar, cheatsheet, len(tar.getmembers())))
		tar.close()
		os.remove(filename)
		self.indexCheatsheet(cheatsheet, refresh_main_view)

	def track_progress(self, members, cheatsheet, totalFiles):
		i = 0
		for member in members:
			i = i + 1
			done = 100 * i / totalFiles
			cheatsheet.status = 'installing: ' + str(round(done,2)) + '% ' + str(i) + ' / '+ str(totalFiles)
			yield member

	def indexCheatsheet(self, cheatsheet, refresh_main_view):
		cheatsheet.status = 'indexing'
		self.postProcess(cheatsheet, refresh_main_view)

	def postProcess(self, cheatsheet, refresh_main_view):
		cheatsheet.status = 'installed'
		refresh_main_view()

	def convertSize(self, size):
		if (size == 0):
			return '0B'
		size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB")
		i = int(math.floor(math.log(size,1024)))
		p = math.pow(1024,i)
		s = round(size/p,2)
		return '%s %s' % (s,size_name[i])

	def deleteCheatsheet(self, cheatsheet, post_action):
		but = console.alert('Are you sure?', 'Would you like to delete the cheatsheet, ' +  cheatsheet.name, 'Ok')
		if but == 1:
			shutil.rmtree(cheatsheet.path)
			cheatsheet.status = 'online'
			post_action()
			cheatsheet.path = None

	def getTypesForCheatsheet(self, cheatsheet):
		types = []
		path = cheatsheet.path
		indexPath = os.path.join(path, self.indexPath)
		conn = sqlite3.connect(indexPath)
		sql = 'SELECT type FROM searchIndex GROUP BY type'
		c = conn.execute(sql)
		data = c.fetchall()
		conn.close()
		for t in data:
			types.append({'name':t[0], 'image':self.__getTypeIconWithName(t[0])})
		return types

	def getIndexesbyTypeForCheatsheet(self, cheatsheet, type):
		indexes = []
		path = cheatsheet.path
		indexPath = os.path.join(path, self.indexPath)
		conn = sqlite3.connect(indexPath)
		sql = 'SELECT type, name, path FROM searchIndex WHERE type = \'' + type['name'] + '\''
		c = conn.execute(sql)
		data = c.fetchall()
		conn.close()
		img = self.__getTypeIconWithName(type['name'])
		for t in data:
			indexes.append({'type':{'name':t[0], 'image':img}, 'name':t[1],'path':t[2]})
		return indexes

	def getIndexesForCheatsheet(self, cheatsheet):
		indexes = []
		path = cheatsheet.path
		indexPath = os.path.join(path, self.indexPath)
		conn = sqlite3.connect(indexPath)
		sql = 'SELECT type, name, path FROM searchIndex'
		c = conn.execute(sql)
		data = c.fetchall()
		conn.close()
		for i in data:
			indexes.append({'type':{'name':t[0], 'image':self.__getTypeIconWithName(t[0])}, 'name':t[1],'path':t[2]})
		return types

if __name__ == '__main__':
	import ServerManager
	c = CheatsheetManager(ServerManager.ServerManager(), '../Images/icons')

<|endoftext|>


<commit_before>#In this Interface script, an object of class "figureCreate" is created for each of
#the ___ models in the journal article titled _______. The name of each of these objects
#is simply "Figure_" + the Figure number (e.g. Figure_1).  Each figureCreate object
#has 4 attributes:
#   1) The Figure number
#   2) The Main Model needed to generate the data within the figure
#   3) The specific cross-bridge model that the main model requires
#   4) The specific Ca2+ model that the main model requires

import numpy as np
import matplotlib.pyplot as plt
import csv
import os
import itertools

class figureCreate:
    def __init__(self, figureNumber, mainModel, xbModel, ca2Model, xVariables, yVariables, ca2Type):
        self.figureNumber = figureNumber #This is an integer value
        self.mainModel = mainModel #This is a cellml file
        self.xbModel = xbModel #This is a cellml file
        self.ca2Model = ca2Model #This is a cellml file
        self.xVariables = xVariables #This is the CSV column title(s) (e.g. [A, A])
        self.yVariables = yVariables #This is the CSV column title(s) (e.g. [B, D])
        self.ca2Type = ca2Type #This is either fixed (F) or Dynamic (D)

def main():
    Figures = []
    Figures.append(figureCreate(1, "Main", "XB", "Ca2", ["xdata1", "xdata2", "xdata3"], ["ydata1", "ydata2", "ydata3"], "D"))
    Figures[1 - 1].afterloads = [0.12, 0.15, 0.2]
    Figures[1 - 1].sarcomereLengths = [1.9359, 2.0139, 2.1054]

    #Depending on the number of figures ("x"), there will be x number of "Figure_x" objects

    #Once each Figure from article ____ has a corresponding object of the class figureCreate,
    #A mechanism will be developed that grabs the appropriate models and runs them on hpc
    #based on what figure (Figure_1, Figure_2, etc...) the user wants to replicate.

    userInput = int(input("Please type the Figure number you wish to reproduce: "))
    fig2Reproduce =  Figures[userInput-1]
    figureNumber = "Figure" + str(userInput)
    print("Reproducing " + "Figure " + str(userInput) + ", please wait...")

    #Run the MeganModel

    #Create the .csv output data file (this could happen in the protocol .py document itself?)

    #Identify which file to access (which file has the data you need) based on an objects attributes and the matching filename
        #To grab the correct file from the Output folder, I need to know:
        # 1) the figureNumber
        # 2) Fixed or dynamic [Ca2+]i (e.g. F, D) --> this also comes from the model version run
        # 3) the contraction type (e.g. WL, Iso, QR) --> this comes from the Model version run
        # 4) The afterload value or sarcomere length(e.g. 0.15)
        # ^ THIS IS THE NAMING CONVENTION FOR THE DATA PRODUCED BY THIS CODE

        # 5) I also need to know the .CSV columns that hold the data.  This information is saved in an object attribute

    #How to determine whether a createFigureobject has a .aftreload attribute (indicating work-loops), a .sarcomereLengths attribute (indicating Isometric contractions), or both
    TorF_WL = hasattr(fig2Reproduce, "afterloads")
    TorF_Iso = hasattr(fig2Reproduce, "sarcomereLengths")

    if TorF_WL == True:
        for i in range(len(fig2Reproduce.afterloads)):
            outputDataFiles = os.listdir("Test_Output")
            dataFile = figureNumber + "_" + str(fig2Reproduce.ca2Type) + "_" + "WL" + str(fig2Reproduce.afterloads[i]) + ".CSV"
            outputDataPath = os.path.join("Test_Output", dataFile)
            print(outputDataPath)

            xData = []
            yData = []
            with open(outputDataPath, 'r') as csvfile:
                plots = csv.reader(csvfile, delimiter=',')
                next(plots, None) #Skip the header line
                #for row in islice(plots, 542859, 571430, None):
                for row in plots:
                    xData.append(float(row[1])/2.3)
                    yData.append(float(row[3]))

            plt.plot(xData, yData, label='Loaded from file!')

        #Plotting the figure:
        plt.xlabel("Normalised Sarcomere Length")
        plt.ylabel("Normalised Total Force")
        plt.title(figureNumber)
        plt.axis([0.75, 1, 0, 0.5])
        plt.show() #plt.show is place after the loop so that all data plotted in the loop will show on one figure

    if TorF_Iso == True:
        for i in range(len(fig2Reproduce.afterloads)):
            #ataFile = Test_Output\ figureNumber + "_" + str(fig2Reproduce.ca2Type) + "_" + "Iso" + str(fig2Reproduce.sarcomereLengths[i]) + ".CSV"
            print("test")

    #Plot the figure!
    lengthData = len(fig2Reproduce.xVariables)
    print(lengthData)

    #data2Plot =
    #plt.plot(
##    plt.plot([0.76,0.79,0.85,0.9], [1,17,30,40], ':')
##    # 'o', '--', ':', '-.'
##    plt.axis([0.75, 1, 0, 60])
##    plt.ylabel('Normalised Force')
##    plt.xlabel('Sarcomere Length (um)')
##    plt.show()

if __name__ == "__main__":
    main()

<commit_msg>I have added a caption attribute to the figureCreate class.  I am not positive that I will keep this...<commit_after>#In this Interface script, an object of class "figureCreate" is created for each of
#the ___ models in the journal article titled _______. The name of each of these objects
#is simply "Figure_" + the Figure number (e.g. Figure_1).  Each figureCreate object
#has 4 attributes:
#   1) The Figure number
#   2) The Main Model needed to generate the data within the figure
#   3) The specific cross-bridge model that the main model requires
#   4) The specific Ca2+ model that the main model requires

import numpy as np
import matplotlib.pyplot as plt
import csv
import os
import itertools

class figureCreate:
    def __init__(self, figureNumber, mainModel, xbModel, ca2Model, xVariables, yVariables, ca2Type, caption):
        self.figureNumber = figureNumber #This is an integer value
        self.mainModel = mainModel #This is a cellml file
        self.xbModel = xbModel #This is a cellml file
        self.ca2Model = ca2Model #This is a cellml file
        self.xVariables = xVariables #This is the CSV column title(s) (e.g. [A, A])
        self.yVariables = yVariables #This is the CSV column title(s) (e.g. [B, D])
        self.ca2Type = ca2Type #This is either fixed (F) or Dynamic (D)
        self.caption = caption

def main():
    Figures = []
    Figures.append(figureCreate(1, "Main", "XB", "Ca2", ["xdata1", "xdata2", "xdata3"], ["ydata1", "ydata2", "ydata3"], "D", "In this figure, work-loop contractions at differing afterlaods and isometric contractions at different sarcomere lengths, are performed"))
    Figures[1 - 1].afterloads = [0.12, 0.15, 0.2]
    Figures[1 - 1].sarcomereLengths = [1.9359, 2.0139, 2.1054]

    #Depending on the number of figures ("x"), there will be x number of "Figure_x" objects

    #Once each Figure from article ____ has a corresponding object of the class figureCreate,
    #A mechanism will be developed that grabs the appropriate models and runs them on hpc
    #based on what figure (Figure_1, Figure_2, etc...) the user wants to replicate.

    userInput = int(input("Please type the Figure number you wish to reproduce: "))
    fig2Reproduce =  Figures[userInput-1]
    figureNumber = "Figure" + str(userInput)
    print("Reproducing " + "Figure " + str(userInput) + ", please wait...")

    #Run the MeganModel

    #Create the .csv output data file (this could happen in the protocol .py document itself?)

    #Identify which file to access (which file has the data you need) based on an objects attributes and the matching filename
        #To grab the correct file from the Output folder, I need to know:
        # 1) the figureNumber
        # 2) Fixed or dynamic [Ca2+]i (e.g. F, D) --> this also comes from the model version run
        # 3) the contraction type (e.g. WL, Iso, QR) --> this comes from the Model version run
        # 4) The afterload value or sarcomere length(e.g. 0.15)
        # ^ THIS IS THE NAMING CONVENTION FOR THE DATA PRODUCED BY THIS CODE

        # 5) I also need to know the .CSV columns that hold the data.  This information is saved in an object attribute

    #How to determine whether a createFigureobject has a .aftreload attribute (indicating work-loops), a .sarcomereLengths attribute (indicating Isometric contractions), or both
    TorF_WL = hasattr(fig2Reproduce, "afterloads")
    TorF_Iso = hasattr(fig2Reproduce, "sarcomereLengths")

    if TorF_WL == True:
        for i in range(len(fig2Reproduce.afterloads)):
            outputDataFiles = os.listdir("Test_Output")
            dataFile = figureNumber + "_" + str(fig2Reproduce.ca2Type) + "_" + "WL" + str(fig2Reproduce.afterloads[i]) + ".CSV"
            outputDataPath = os.path.join("Test_Output", dataFile)
            print(outputDataPath)

            xData = []
            yData = []
            with open(outputDataPath, 'r') as csvfile:
                plots = csv.reader(csvfile, delimiter=',')
                next(plots, None) #Skip the header line
                #for row in islice(plots, 542859, 571430, None):
                for row in plots:
                    xData.append(float(row[1])/2.3)
                    yData.append(float(row[3]))

            plt.plot(xData, yData, label='Loaded from file!')

        #Plotting the figure:
        plt.xlabel("Normalised Sarcomere Length")
        plt.ylabel("Normalised Total Force")
        plt.title(figureNumber)
        plt.axis([0.75, 1, 0, 0.5])
        plt.text(.1,.1,fig2Reproduce.caption)
        F = plt.show() #plt.show is place after the loop so that all data plotted in the loop will show on one figure

    if TorF_Iso == True:
        for i in range(len(fig2Reproduce.afterloads)):
            #ataFile = Test_Output\ figureNumber + "_" + str(fig2Reproduce.ca2Type) + "_" + "Iso" + str(fig2Reproduce.sarcomereLengths[i]) + ".CSV"
            print("test")

    #Plot the figure!
    lengthData = len(fig2Reproduce.xVariables)
    print(lengthData)

    #data2Plot =
    #plt.plot(
##    plt.plot([0.76,0.79,0.85,0.9], [1,17,30,40], ':')
##    # 'o', '--', ':', '-.'
##    plt.axis([0.75, 1, 0, 60])
##    plt.ylabel('Normalised Force')
##    plt.xlabel('Sarcomere Length (um)')
##    plt.show()

if __name__ == "__main__":
    main()

<|endoftext|>


<commit_before>#  Copyright 2008-2011 Nokia Siemens Networks Oyj
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

class Stat(object):

    def __init__(self, name=''):
        self.name = name
        self.passed = 0
        self.failed = 0

    @property
    def _default_attrs(self):
        return {'pass': str(self.passed),
                'fail': str(self.failed)}

    @property
    def total(self):
        return self.passed + self.failed

    def add_stat(self, other):
        self.passed += other.passed
        self.failed += other.failed

    def add_test(self, test):
        if test.status == 'PASS':
            self.passed += 1
        else:
            self.failed += 1

    def fail_all(self):
        self.failed += self.passed
        self.passed = 0

    def add_suite(self, suite):
        for test in suite.tests:
            if self._is_included(test):
                self.add_test(test)
        for suite in suite.suites:
            self.add_stat(self._subsuite_stats(suite))

    def _is_included(self, test):
        return True

    def _subsuite_stats(self, suite):
        return suite.all_stats

    def __cmp__(self, other):
        return cmp(self.name, other.name)

    def __nonzero__(self):
        return self.failed == 0

    def visit(self, visitor):
        visitor.visit_stat(self)

class SuiteStat(Stat):
    type = 'suite'

    def __init__(self, suite):
        Stat.__init__(self, suite.longname)
        self.id = suite.id
        self._attrs = {'name': suite.name, 'idx': suite.id}

    @property
    def attrs(self):
        return dict(self._default_attrs, **self._attrs) # TODO: idx -> id

class TagStat(Stat):
    type = 'tag'

    def __init__(self, name, doc='', links=[], critical=False,
                 non_critical=False, combined=''):
        Stat.__init__(self, name)
        self.doc = doc
        self.links = links
        self.critical = critical
        self.non_critical = non_critical
        self.combined = combined
        self.tests = []

    @property
    def attrs(self):
        return dict(self._default_attrs, info=self._info, links=self._links,
                    doc=self.doc, combined=self.combined)

    @property
    def _info(self):
        if self.critical:
            return 'critical'
        if self.non_critical:
            return 'non-critical'
        if self.combined:
            return 'combined'
        return ''

    @property
    def _links(self):
        return  ':::'.join(':'.join([title, url]) for url, title in self.links)

    def add_test(self, test):
        Stat.add_test(self, test)
        self.tests.append(test)

    def __cmp__(self, other):
        if self.critical != other.critical:
            return cmp(other.critical, self.critical)
        if self.non_critical != other.non_critical:
            return cmp(other.non_critical, self.non_critical)
        if bool(self.combined) != bool(other.combined):
            return cmp(bool(other.combined), bool(self.combined))
        return cmp(self.name, other.name)

class TotalStat(Stat):
    type = 'total'

    def __init__(self, name, suite_stat):
        Stat.__init__(self, name)
        self.passed = suite_stat.passed
        self.failed = suite_stat.failed

    @property
    def attrs(self):
        return self._default_attrs
<commit_msg>cleanup and todos<commit_after>#  Copyright 2008-2011 Nokia Siemens Networks Oyj
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

class Stat(object):

    def __init__(self, name=''):
        self.name = name
        self.passed = 0
        self.failed = 0

    @property
    def _default_attrs(self):
        return {'pass': str(self.passed), 'fail': str(self.failed)}

    @property
    def total(self):
        return self.passed + self.failed

    def add_test(self, test):
        if test.status == 'PASS':
            self.passed += 1
        else:
            self.failed += 1

    # TODO: Are all methods below actually used somewhere??

    def add_stat(self, other):
        self.passed += other.passed
        self.failed += other.failed

    def fail_all(self):
        self.failed += self.passed
        self.passed = 0

    def add_suite(self, suite):
        for test in suite.tests:
            if self._is_included(test):
                self.add_test(test)
        for suite in suite.suites:
            self.add_stat(self._subsuite_stats(suite))

    def _is_included(self, test):
        return True

    def _subsuite_stats(self, suite):
        return suite.all_stats

    def __cmp__(self, other):
        return cmp(self.name, other.name)

    def __nonzero__(self):
        return self.failed == 0

    def visit(self, visitor):
        visitor.visit_stat(self)

class SuiteStat(Stat):
    type = 'suite'

    def __init__(self, suite):
        Stat.__init__(self, suite.longname)
        self.id = suite.id
        self._attrs = {'name': suite.name, 'idx': suite.id}

    @property
    def attrs(self):
        return dict(self._default_attrs, **self._attrs) # TODO: idx -> id

class TagStat(Stat):
    type = 'tag'

    def __init__(self, name, doc='', links=[], critical=False,
                 non_critical=False, combined=''):
        Stat.__init__(self, name)
        self.doc = doc
        self.links = links  # TODO: Are both self.links and self._link_str needed?
        self.critical = critical
        self.non_critical = non_critical
        self.combined = combined
        self.tests = []

    @property
    def attrs(self):
        return dict(self._default_attrs, info=self._info, links=self._link_str,
                    doc=self.doc, combined=self.combined)

    @property
    def _info(self):
        if self.critical:
            return 'critical'
        if self.non_critical:
            return 'non-critical'
        if self.combined:
            return 'combined'
        return ''

    @property
    def _link_str(self):
        return  ':::'.join(':'.join([title, url]) for url, title in self.links)

    def add_test(self, test):
        Stat.add_test(self, test)
        self.tests.append(test)

    def __cmp__(self, other):
        return cmp(other.critical, self.critical) \
            or cmp(other.non_critical, self.non_critical) \
            or cmp(bool(other.combined), bool(self.combined)) \
            or cmp(self.name, other.name)

class TotalStat(Stat):
    type = 'total'

    def __init__(self, name, suite_stat):
        Stat.__init__(self, name)
        self.passed = suite_stat.passed
        self.failed = suite_stat.failed

    @property
    def attrs(self):
        return self._default_attrs
<|endoftext|>


<commit_before>import eliza
import threading
import random
import re

concmd=['/q','/lt','/st','/lg']

doctor=eliza.eliza()
trusted=[]
trustedlock=threading.Lock()
gods=[]
godslock=threading.Lock()
msgs={}
msglock=threading.Lock()
authcmds={}
authcmdlock=threading.Lock()
authfuncs={}
authfunclock=threading.Lock()

die_expr=re.compile("#[0-9]*d([0-9]+|%)")

msglock.acquire()
f=open('msgs.txt','r')
for line in f:
	while len(line)>0 and line[-1]=='\n': line=line[:-1]
	if len(line)>0:
		receiver,sender,msg=line.split('\t')
		if receiver not in msgs:
			msgs[receiver]=[]
		msgs[receiver].append((sender,msg))
f.close()
msglock.release()

def addtrusted(nick):
	trustedlock.acquire()
	if nick not in trusted:
		trusted.append(nick)
	trustedlock.release()

def rmtrusted(nick):
	trustedlock.acquire()
	if nick in trusted:
		trusted.remove(nick)
	trustedlock.release()

def loadtrusted():
	trustedlock.acquire()
	while len(trusted)>0: trusted.pop() #I'm really sorry but trusted=[] created trusted as local variable
	trustedlock.release()
	f=open('trusted.txt','r')
	for line in f:
		while len(line)>0 and line[-1]=='\n': line=line[:-1]
		if len(line)>0:
			addtrusted(line)
	f.close()

def loadgods():
	godslock.acquire()
	while len(gods)>0: gods.pop() #See above
	f=open('gods.txt','r')
	for line in f:
		while len(line)>0 and line[-1]=='\n': line=line[:-1]
		if len(line)>0:
			gods.append(line)
			addtrusted(line)
	f.close()
	godslock.release()

def savetrusted():
	trustedlock.acquire()
	f=open('trusted.txt','w')
	for i in trusted:
		f.write(i+'\n')
	f.close
	trustedlock.release()

loadtrusted()
loadgods()

def addauthcmd(nick,cmd):
	authcmdlock.acquire()
	trustedlock.acquire()
	if nick in trusted:
		if nick not in authcmds:
			authcmds[nick]=[]
		authcmds[nick].append(cmd)
	trustedlock.release()
	authcmdlock.release()

def addauthfunc(nick,f):
	authfunclock.acquire()
	trustedlock.acquire()
	if nick in trusted:
		if nick not in authfuncs:
			authfuncs[nick]=[]
		authfuncs[nick].append(f)
	trustedlock.release()
	authfunclock.release()

def chmode(irc,chan,nick,mode,args):
	if len(args)==0:
		addauthcmd(nick,'MODE %s %s %s'%(chan,mode,nick))
	else:
		for name in args:
			addauthcmd(nick,'MODE %s %s %s'%(chan,mode,name))
	irc.send('PRIVMSG NickServ :ACC '+nick)

def parse((line,irc)):
	line=line.split(' ')
	nick=line[0].split('!')[0][1:]
	chan=line[2] if line[2][0]=='#' else nick
	if line[1]=='PRIVMSG':
		if line[3]==':#echo':
			irc.send('PRIVMSG %s :%s'%(chan,' '.join(line[4:])))
		elif line[3]==':#op':
			chmode(irc,chan,nick,'+o',line[4:])
		elif line[3]==':#deop':
			chmode(irc,chan,nick,'-o',line[4:])
		elif line[3]==':#voice':
			chmode(irc,chan,nick,'+v',line[4:])
		elif line[3]==':#devoice':
			chmode(irc,chan,nick,'-v',line[4:])
		elif line[3]==':#kick':
			if len(line)>4:
				if line[4].lower()=='oonbotti2':
					irc.send('KICK %s %s :Fuck you'%(chan,nick))
				elif random.randint(0,9)==0 and len(line)==5:
					irc.send('KICK %s %s :Bam'%(chan,nick))
				else:
					addauthcmd(nick,'KICK %s %s :%s'%(chan,line[4],' '.join(line[5:])))
					irc.send('PRIVMSG NickServ :ACC '+nick)
			else:
				irc.send('PRIVMSG %s :Usage #kick nick reason'%chan)
		elif line[3]==':#src':
			irc.send('PRIVMSG %s :https://github.com/JuEeHa/oonbotti2'%chan)
		elif line[3]==':#prefix' and chan=='#osdev-offtopic':
			irc.send('PRIVMSG %s :gopher://smar.fi:7070/0/hash-prefix'%chan)
		elif line[3]==':#msg':
			if len(line)>5:
				msglock.acquire()
				if line[4] not in msgs:
					msgs[line[4]]=[]
				msgs[line[4]].append((nick,' '.join(line[5:])))
				msglock.release()
			else:
				irc.send('PRIVMSG %s :Usage: #msg nick message'%chan)
		elif line[3]==':#trusted?':
			addauthcmd(nick,'PRIVMSG %s :%s: You are trusted'%(chan,nick))
			irc.send('PRIVMSG NickServ :ACC '+nick)
		elif line[3]==':#trust':
			if len(line)==5:
				addauthfunc(nick,(lambda :addtrusted(line[4])))
				irc.send('PRIVMSG NickServ :ACC '+nick)
			else:
				irc.send('PRIVMSG %s :Usage #trust nick'%chan)
		elif line[3]==':#untrust':
			if len(line)==5:
				godslock.acquire()
				if line[4] not in gods:
					addauthfunc(nick,(lambda :rmtrusted(line[4])))
					irc.send('PRIVMSG NickServ :ACC '+nick)
				godslock.release()
			else:
				irc.send('PRIVMSG %s :Usage #trust nick'%chan)
		elif line[3]==':#ls-trusted':
			trustedlock.acquire()
			irc.send('PRIVMSG %s :%s'%(nick,', '.join(trusted)))
			trustedlock.release()
		elif line[3]==':#invite':
			if len(line)==5:
				addauthcmd(nick, 'INVITE %s %s'%(line[4], chan))
				irc.send('PRIVMSG NickServ :ACC '+nick)
			else:
				irc.send('PRIVMSG %s :Usage #invite nick'%chan)
		elif line[3]==':#help':
			helptext=help(' '.join(line[4:]))
			if helptext:
				irc.send('PRIVMSG %s : %s'%(chan,helptext))
		elif line[3]==':#esoteric' and chan=='#esoteric':
			irc.send('PRIVMSG %s :Nothing here'%chan)
		elif line[3][1:] in ('oonbotti:', 'oonbotti', 'oonbotti,', 'oonbotti2', 'oonbotti2:', 'oonbotti2,'):
			irc.send('PRIVMSG %s :%s: %s'%(chan,nick,doctor.respond(' '.join(line[4:]))))
		elif die_expr.match(line[3][1:]):
			die=line[3][2:].split('d')
			times=int(die[0]) if die[0] else 1
			die='%' if die[1]=='%' else int(die[1])
			if die=='%':
				if times!=1:
					irc.send('PRIVMSG %s :Not supported'%chan)
				else:
					irc.send('PRIVMSG %s :%s%s'%(chan, random.randint(0,9), random.randint(0,9)))
			elif die<4 or times<1 or times>128:
				irc.send('PRIVMSG %s :Dice are limited to physically possible ones'%chan)
			else:
				rolls=[random.randint(1, die) for i in xrange(times)]
				result=reduce((lambda x,y:x+y), rolls)
				if times>1:
					irc.send('PRIVMSG %s :%s (%s)'%(chan, str(result), ', '.join([str(i) for i in rolls])))
				else:
					irc.send('PRIVMSG %s :%s'%(chan, str(result)))
	elif line[1]=='NOTICE' and line[0].split('!')[0]==':NickServ' and  line[4]=='ACC':
		authfunclock.acquire()
		authcmdlock.acquire()
		if line[5]=='3':
			trustedlock.acquire()
			if line[3][1:] in trusted:
				trustedlock.release()
				if line[3][1:] in authcmds:
					for i in authcmds.pop(line[3][1:]):
						irc.send(i)
				if line[3][1:] in authfuncs:
					for i in authfuncs.pop(line[3][1:]):
						i()
			else:
				trustedlock.release()
		else:
			if line[3][1:] in authcmds:
				authcmds.pop(line[3][1:])
			if line[3][1:] in authfuncs:
				authfuncs.pop(line[3][1:])
			if line[5]=='0':
				irc.send('PRIVMSG %s :Register account with NickServ'%line[3][1:])
			elif line[5]=='1':
				irc.send('PRIVMSG %s :Identify with NickServ'%line[3][1:])
			else:
				irc.send('PRIVMSG %s :WTF, NickServ returned %s'%(line[3][1:],line[5]))
		authcmdlock.release()
		authfunclock.release()
	elif line[1]=='482':
		irc.send('PRIVMSG %s :Not op'%line[3])
	#elif line[1]=='332' or line[1]=='TOPIC':
	#	if line[1]=='332':
	#		ch=line[3]
	#		tp=' '.join(line[4:])[1:]
	#	elif line[1]=='TOPIC':
	#		ch=line[2]
	#		tp=' '.join(line[3:])[1:]
	#	#Do the magic here

	msglock.acquire()
	if (line[1]=='PRIVMSG' or line[1]=='JOIN') and nick in msgs:
		for sender,msg in msgs.pop(nick):
			irc.send('PRIVMSG %s :<%s> %s'%(nick,sender,msg))
	msglock.release()

def execcmd(cmdline):
	if cmdline[0]=='/q':
		msglock.acquire()
		f=open('msgs.txt','w')
		for receiver in msgs:
			for sender, msg in msgs[receiver]:
					f.write('%s\t%s\t%s\n'%(receiver,sender,msg))
		f.close()
		msglock.release()
		savetrusted()
	elif cmdline[0]=='/lt':
		loadtrusted()
	elif cmdline[0]=='/st':
		savetrusted()
	elif cmdline[0]=='/lg':
		loadgods()

def help(cmd):
	if cmd=='':
		return '#echo #op #deop #voice #devoice #kick #src #msg #trusted? #trust #untrust #ls-trusted #invite #help'
	elif cmd=='#echo':
		return '#echo text      echo text back'
	elif cmd=='#op':
		return '#op [nick]      give nick or yourself op rights in case you are trusted by oonbotti2 and identified with NickServ'
	elif cmd=='#deop':
		return '#deop [nick]      remove your/nick\'s op rights (added due to irrational demand by shikhin and sortiecat, nick support added for same reason)'
	elif cmd=='#voice':
		return '#voice [nick]      give nick or yourself voice in case you are trusted by oonbotti2 and identified with NickServ'
	elif cmd=='#devoice':
		return '#devoice [nick]      remove your or nick\'s voice in case you are trusted by oonbotti2 and identified with NickServ'
	elif cmd=='#kick':
		return '#kick nick reason      kicks nick with specified reason'
	elif cmd=='#src':
		return '#src      paste a link to oonbotti2\'s git repo'
	elif cmd=='#msg':
		return '#msg nick message      send a message to nick. messages can be read with #readmsg'
	elif cmd=='#trusted?':
		return '#trusted?      tell you if you are trusted by oonbotti'
	elif cmd=='#trust':
		return '#trust nick      add nick to trusted list'
	elif cmd=='#untrust':
		return '#untrust nick      remove nick from trusted list'
	elif cmd=='#ls-trusted':
		return '#ls-trusted      list nicks that are trusted. use only in a query'
	elif cmd=='#invite':
		return '#invite nick      invites nick to channel'
	elif cmd=='#help':
		return '#help [command]      give short info of command or list commands'
	elif cmd=='me':
		return 'I shall.'
	else:
		return None
<commit_msg>Updated help texts, better error messages for dice, blacklist, null-width space before echoed text (too much trouble to break these to individual commits)<commit_after>import eliza
import threading
import random
import re

concmd=['/q','/lt','/st','/lg']

blacklist=['bslsk05']

doctor=eliza.eliza()
trusted=[]
trustedlock=threading.Lock()
gods=[]
godslock=threading.Lock()
msgs={}
msglock=threading.Lock()
authcmds={}
authcmdlock=threading.Lock()
authfuncs={}
authfunclock=threading.Lock()

die_expr=re.compile("#[0-9]*d([0-9]+|%)")

msglock.acquire()
f=open('msgs.txt','r')
for line in f:
	while len(line)>0 and line[-1]=='\n': line=line[:-1]
	if len(line)>0:
		receiver,sender,msg=line.split('\t')
		if receiver not in msgs:
			msgs[receiver]=[]
		msgs[receiver].append((sender,msg))
f.close()
msglock.release()

def addtrusted(nick):
	trustedlock.acquire()
	if nick not in trusted:
		trusted.append(nick)
	trustedlock.release()

def rmtrusted(nick):
	trustedlock.acquire()
	if nick in trusted:
		trusted.remove(nick)
	trustedlock.release()

def loadtrusted():
	trustedlock.acquire()
	while len(trusted)>0: trusted.pop() #I'm really sorry but trusted=[] created trusted as local variable
	trustedlock.release()
	f=open('trusted.txt','r')
	for line in f:
		while len(line)>0 and line[-1]=='\n': line=line[:-1]
		if len(line)>0:
			addtrusted(line)
	f.close()

def loadgods():
	godslock.acquire()
	while len(gods)>0: gods.pop() #See above
	f=open('gods.txt','r')
	for line in f:
		while len(line)>0 and line[-1]=='\n': line=line[:-1]
		if len(line)>0:
			gods.append(line)
			addtrusted(line)
	f.close()
	godslock.release()

def savetrusted():
	trustedlock.acquire()
	f=open('trusted.txt','w')
	for i in trusted:
		f.write(i+'\n')
	f.close
	trustedlock.release()

loadtrusted()
loadgods()

def addauthcmd(nick,cmd):
	authcmdlock.acquire()
	trustedlock.acquire()
	if nick in trusted:
		if nick not in authcmds:
			authcmds[nick]=[]
		authcmds[nick].append(cmd)
	trustedlock.release()
	authcmdlock.release()

def addauthfunc(nick,f):
	authfunclock.acquire()
	trustedlock.acquire()
	if nick in trusted:
		if nick not in authfuncs:
			authfuncs[nick]=[]
		authfuncs[nick].append(f)
	trustedlock.release()
	authfunclock.release()

def chmode(irc,chan,nick,mode,args):
	if len(args)==0:
		addauthcmd(nick,'MODE %s %s %s'%(chan,mode,nick))
	else:
		for name in args:
			addauthcmd(nick,'MODE %s %s %s'%(chan,mode,name))
	irc.send('PRIVMSG NickServ :ACC '+nick)

def parse((line,irc)):
	line=line.split(' ')
	nick=line[0].split('!')[0][1:]
	chan=line[2] if line[2][0]=='#' else nick

	if nick in blacklist:
		return

	if line[1]=='PRIVMSG':
		if line[3]==':#echo':
			irc.send('PRIVMSG %s :\xe2\x80\x8b%s'%(chan,' '.join(line[4:])))
		elif line[3]==':#op':
			chmode(irc,chan,nick,'+o',line[4:])
		elif line[3]==':#deop':
			chmode(irc,chan,nick,'-o',line[4:])
		elif line[3]==':#voice':
			chmode(irc,chan,nick,'+v',line[4:])
		elif line[3]==':#devoice':
			chmode(irc,chan,nick,'-v',line[4:])
		elif line[3]==':#kick':
			if len(line)>4:
				if line[4].lower()=='oonbotti2':
					irc.send('KICK %s %s :Fuck you'%(chan,nick))
				elif random.randint(0,9)==0 and len(line)==5:
					irc.send('KICK %s %s :Bam'%(chan,nick))
				else:
					addauthcmd(nick,'KICK %s %s :%s'%(chan,line[4],' '.join(line[5:])))
					irc.send('PRIVMSG NickServ :ACC '+nick)
			else:
				irc.send('PRIVMSG %s :Usage #kick nick reason'%chan)
		elif line[3]==':#src':
			irc.send('PRIVMSG %s :https://github.com/JuEeHa/oonbotti2'%chan)
		elif line[3]==':#prefix' and chan=='#osdev-offtopic':
			irc.send('PRIVMSG %s :gopher://smar.fi:7070/0/hash-prefix'%chan)
		elif line[3]==':#msg':
			if len(line)>5:
				msglock.acquire()
				if line[4] not in msgs:
					msgs[line[4]]=[]
				msgs[line[4]].append((nick,' '.join(line[5:])))
				msglock.release()
			else:
				irc.send('PRIVMSG %s :Usage: #msg nick message'%chan)
		elif line[3]==':#trusted?':
			addauthcmd(nick,'PRIVMSG %s :%s: You are trusted'%(chan,nick))
			irc.send('PRIVMSG NickServ :ACC '+nick)
		elif line[3]==':#trust':
			if len(line)==5:
				addauthfunc(nick,(lambda :addtrusted(line[4])))
				irc.send('PRIVMSG NickServ :ACC '+nick)
			else:
				irc.send('PRIVMSG %s :Usage #trust nick'%chan)
		elif line[3]==':#untrust':
			if len(line)==5:
				godslock.acquire()
				if line[4] not in gods:
					addauthfunc(nick,(lambda :rmtrusted(line[4])))
					irc.send('PRIVMSG NickServ :ACC '+nick)
				godslock.release()
			else:
				irc.send('PRIVMSG %s :Usage #trust nick'%chan)
		elif line[3]==':#ls-trusted':
			trustedlock.acquire()
			irc.send('PRIVMSG %s :%s'%(nick,', '.join(trusted)))
			trustedlock.release()
		elif line[3]==':#invite':
			if len(line)==5:
				addauthcmd(nick, 'INVITE %s %s'%(line[4], chan))
				irc.send('PRIVMSG NickServ :ACC '+nick)
			else:
				irc.send('PRIVMSG %s :Usage #invite nick'%chan)
		elif line[3]==':#help':
			helptext=help(' '.join(line[4:]))
			if helptext:
				irc.send('PRIVMSG %s : %s'%(chan,helptext))
		elif line[3]==':#esoteric' and chan=='#esoteric':
			irc.send('PRIVMSG %s :Nothing here'%chan)
		elif line[3][1:] in ('oonbotti:', 'oonbotti', 'oonbotti,', 'oonbotti2', 'oonbotti2:', 'oonbotti2,'):
			irc.send('PRIVMSG %s :%s: %s'%(chan,nick,doctor.respond(' '.join(line[4:]))))
		elif die_expr.match(line[3][1:]):
			die=line[3][2:].split('d')
			times=int(die[0]) if die[0] else 1
			die='%' if die[1]=='%' else int(die[1])
			if die=='%':
				if times!=1:
					irc.send('PRIVMSG %s :Not supported'%chan)
				else:
					irc.send('PRIVMSG %s :%s%s'%(chan, random.randint(0,9), random.randint(0,9)))
			elif die<2:
				irc.send('PRIVMSG %s :This die is not available in your space-time region.'%chan)
			elif times<1:
				irc.send('PRIVMSG %s :What exactly do you want me to do?'%chan)
			elif times>128:
				irc.send('PRIVMSG %s :Sorry, I don\'t have that many. Can I borrow yours?'%chan)
			else:
				rolls=[random.randint(1, die) for i in xrange(times)]
				result=reduce((lambda x,y:x+y), rolls)
				if times>1:
					irc.send('PRIVMSG %s :%s (%s)'%(chan, str(result), ', '.join([str(i) for i in rolls])))
				else:
					irc.send('PRIVMSG %s :%s'%(chan, str(result)))
	elif line[1]=='NOTICE' and line[0].split('!')[0]==':NickServ' and  line[4]=='ACC':
		authfunclock.acquire()
		authcmdlock.acquire()
		if line[5]=='3':
			trustedlock.acquire()
			if line[3][1:] in trusted:
				trustedlock.release()
				if line[3][1:] in authcmds:
					for i in authcmds.pop(line[3][1:]):
						irc.send(i)
				if line[3][1:] in authfuncs:
					for i in authfuncs.pop(line[3][1:]):
						i()
			else:
				trustedlock.release()
		else:
			if line[3][1:] in authcmds:
				authcmds.pop(line[3][1:])
			if line[3][1:] in authfuncs:
				authfuncs.pop(line[3][1:])
			if line[5]=='0':
				irc.send('PRIVMSG %s :Register account with NickServ'%line[3][1:])
			elif line[5]=='1':
				irc.send('PRIVMSG %s :Identify with NickServ'%line[3][1:])
			else:
				irc.send('PRIVMSG %s :WTF, NickServ returned %s'%(line[3][1:],line[5]))
		authcmdlock.release()
		authfunclock.release()
	elif line[1]=='482':
		irc.send('PRIVMSG %s :Not op'%line[3])
	#elif line[1]=='332' or line[1]=='TOPIC':
	#	if line[1]=='332':
	#		ch=line[3]
	#		tp=' '.join(line[4:])[1:]
	#	elif line[1]=='TOPIC':
	#		ch=line[2]
	#		tp=' '.join(line[3:])[1:]
	#	#Do the magic here

	msglock.acquire()
	if (line[1]=='PRIVMSG' or line[1]=='JOIN') and nick in msgs:
		for sender,msg in msgs.pop(nick):
			irc.send('PRIVMSG %s :<%s> %s'%(nick,sender,msg))
	msglock.release()

def execcmd(cmdline):
	if cmdline[0]=='/q':
		msglock.acquire()
		f=open('msgs.txt','w')
		for receiver in msgs:
			for sender, msg in msgs[receiver]:
					f.write('%s\t%s\t%s\n'%(receiver,sender,msg))
		f.close()
		msglock.release()
		savetrusted()
	elif cmdline[0]=='/lt':
		loadtrusted()
	elif cmdline[0]=='/st':
		savetrusted()
	elif cmdline[0]=='/lg':
		loadgods()

def help(cmd):
	if cmd=='':
		return '#echo #op #deop #voice #devoice #kick #src #msg #trusted? #trust #untrust #ls-trusted #invite #help'
	elif cmd=='#echo':
		return '#echo text      echo text back'
	elif cmd=='#op':
		return '#op [nick]      give nick or yourself op rights in case you are trusted by oonbotti2 and identified with NickServ'
	elif cmd=='#deop':
		return '#deop [nick]      remove your/nick\'s op rights'
	elif cmd=='#voice':
		return '#voice [nick]      give nick or yourself voice in case you are trusted by oonbotti2 and identified with NickServ'
	elif cmd=='#devoice':
		return '#devoice [nick]      remove your or nick\'s voice in case you are trusted by oonbotti2 and identified with NickServ'
	elif cmd=='#kick':
		return '#kick nick reason      kicks nick with specified reason'
	elif cmd=='#src':
		return '#src      paste a link to oonbotti2\'s git repo'
	elif cmd=='#msg':
		return '#msg nick message      send a message to nick'
	elif cmd=='#trusted?':
		return '#trusted?      tell you if you are trusted by oonbotti'
	elif cmd=='#trust':
		return '#trust nick      add nick to trusted list'
	elif cmd=='#untrust':
		return '#untrust nick      remove nick from trusted list'
	elif cmd=='#ls-trusted':
		return '#ls-trusted      list nicks that are trusted. use only in a query'
	elif cmd=='#invite':
		return '#invite nick      invites nick to channel'
	elif cmd=='#help':
		return '#help [command]      give short info of command or list commands'
	elif cmd=='me':
		return 'I shall.'
	else:
		return None
<|endoftext|>


<commit_before>"""
Vodka application foundation classes. Each vodka app should extend one
of these.
"""
from builtins import object

import os
import sys
import importlib
import inspect

import pluginmgr

import vodka.config
import vodka.log
import vodka.component
import vodka.util

applications = {}
loaded_paths = []

# FUNCTIONS

class register(vodka.util.register):
    class Meta(object):
        name = "application"
        objects = applications

def get_application(handle):
    """
    Wrapper function to retrieve registered application class

    Args:
        handle (str): application handle as defined in the application class

    Returns:
        the application class with the matching handle

    Raises:
        KeyError: Application with specified handle is not registered
    """

    if handle in applications:
        return applications.get(handle)
    raise KeyError("Application with handle '%s' not registered" % handle)

def load(name, cfg):

    mod = None

    if not cfg.get("module") and not cfg.get("home"):
        cfg["module"] = "%s.application" % name

    if cfg.get("module") and not cfg.get("home"):
        mod = importlib.import_module(cfg.get("module"))
        cfg["home"] = os.path.dirname(inspect.getfile(mod))
    elif cfg.get("home"):
        if cfg.get("home") not in loaded_paths:
            sys.path.append(os.path.split(cfg.get("home").rstrip("/"))[0])
            if cfg.get("module"):
                mod = importlib.import_module(cfg.get("module"))
            else:
                mod = importlib.import_module("%s.application" % name)
            loaded_paths.append(cfg.get("home"))
    else:
        raise KeyError("app config needs to contain 'home' or 'module' key")

def load_all(cfg):
    imported = []

    # load all apps
    for name, app_cfg in list(cfg.get("apps", {}).items()):

        # make sure required apps are loaded first
        for req in app_cfg.get("requires", []):
            if req not in imported:
                load(req, cfg["apps"].get(req))
                imported.append(req)

        # load the app
        if name not in imported:
            load(name, app_cfg)
            imported.append(name)

# CLASSES

class Application(vodka.component.Component):
    """
    Base application class

    Attributes:
        handle (str): unique handle for the application, override when
            extending
    """

    handle = "base"

    class Configuration(vodka.component.Component.Configuration):
        home = vodka.config.Attribute(
            vodka.config.validators.path,
            default="",
            help_text="absolute path to application directory. you can ignore this if application is to be loaded from an installed python package."
        )
        module = vodka.config.Attribute(
            str,
            default="",
            help_text="name of the python module containing this application (usually <namespace>.application)"
        )

        requires = vodka.config.Attribute(
            list,
            default=[],
            help_text="list of vodka apps required by this app"
        )

    def __init__(self, config=None, config_dir=None):

        """
        Kwargs:
            config (dict or MungeConfig): configuration object, note that
                either this or config_dir need to be specified.
            config_dir (str): path to config directory, will attempt to
                read into a new MungeConfig instance from there.
        """

        if config:
            self.config = config
        elif config_dir:
            self.config = config.Config(read=config_dir)
        else:
            raise ValueError("No configuration specified")

    def setup(self):
        """
        Soft initialization method with no arguments that can easily be
        overwritten by extended classes
        """
        pass

class WebApplication(Application):
    """
    Application wrapper for serving content via a web server.
    """

    # Configuration handler

    class Configuration(Application.Configuration):

        templates = vodka.config.Attribute(
            vodka.config.validators.path,
            default=lambda k,i: i.resource(k),
            help_text="location of your template files"
        )

        tmpl_engine = vodka.config.Attribute(
            str,
            default="jinja2",
            choices=["jinja2"],
            help_text="template engine to use to render your templates"
        )

    # class methods and properties

    @property
    def template_path(self):
        """ absolute path to template directory """
        return self.get_config("templates")

    def render(self, tmpl_name, request_env):
        """
        Render the specified template and return the output.

        Args:
            tmpl_name (str): file name of the template
            request_env (dict): request environment

        Returns:
            str - the rendered template
        """
        return self.tmpl._render(tmpl_name, request_env)

    def setup(self):
        import twentyc.tmpl

        # set up the template engine
        eng = twentyc.tmpl.get_engine(self.config.get("tmpl_engine", "jinja2"))
        self.tmpl = eng(tmpl_dir=self.template_path)
<commit_msg>rename tmpl_engine to template_engine<commit_after>"""
Vodka application foundation classes. Each vodka app should extend one
of these.
"""
from builtins import object

import os
import sys
import importlib
import inspect

import pluginmgr

import vodka.config
import vodka.log
import vodka.component
import vodka.util

applications = {}
loaded_paths = []

# FUNCTIONS

class register(vodka.util.register):
    class Meta(object):
        name = "application"
        objects = applications

def get_application(handle):
    """
    Wrapper function to retrieve registered application class

    Args:
        handle (str): application handle as defined in the application class

    Returns:
        the application class with the matching handle

    Raises:
        KeyError: Application with specified handle is not registered
    """

    if handle in applications:
        return applications.get(handle)
    raise KeyError("Application with handle '%s' not registered" % handle)

def load(name, cfg):

    mod = None

    if not cfg.get("module") and not cfg.get("home"):
        cfg["module"] = "%s.application" % name

    if cfg.get("module") and not cfg.get("home"):
        mod = importlib.import_module(cfg.get("module"))
        cfg["home"] = os.path.dirname(inspect.getfile(mod))
    elif cfg.get("home"):
        if cfg.get("home") not in loaded_paths:
            sys.path.append(os.path.split(cfg.get("home").rstrip("/"))[0])
            if cfg.get("module"):
                mod = importlib.import_module(cfg.get("module"))
            else:
                mod = importlib.import_module("%s.application" % name)
            loaded_paths.append(cfg.get("home"))
    else:
        raise KeyError("app config needs to contain 'home' or 'module' key")

def load_all(cfg):
    imported = []

    # load all apps
    for name, app_cfg in list(cfg.get("apps", {}).items()):

        # make sure required apps are loaded first
        for req in app_cfg.get("requires", []):
            if req not in imported:
                load(req, cfg["apps"].get(req))
                imported.append(req)

        # load the app
        if name not in imported:
            load(name, app_cfg)
            imported.append(name)

# CLASSES

class Application(vodka.component.Component):
    """
    Base application class

    Attributes:
        handle (str): unique handle for the application, override when
            extending
    """

    handle = "base"

    class Configuration(vodka.component.Component.Configuration):
        home = vodka.config.Attribute(
            vodka.config.validators.path,
            default="",
            help_text="absolute path to application directory. you can ignore this if application is to be loaded from an installed python package."
        )
        module = vodka.config.Attribute(
            str,
            default="",
            help_text="name of the python module containing this application (usually <namespace>.application)"
        )

        requires = vodka.config.Attribute(
            list,
            default=[],
            help_text="list of vodka apps required by this app"
        )

    def __init__(self, config=None, config_dir=None):

        """
        Kwargs:
            config (dict or MungeConfig): configuration object, note that
                either this or config_dir need to be specified.
            config_dir (str): path to config directory, will attempt to
                read into a new MungeConfig instance from there.
        """

        if config:
            self.config = config
        elif config_dir:
            self.config = config.Config(read=config_dir)
        else:
            raise ValueError("No configuration specified")

    def setup(self):
        """
        Soft initialization method with no arguments that can easily be
        overwritten by extended classes
        """
        pass

class WebApplication(Application):
    """
    Application wrapper for serving content via a web server.
    """

    # Configuration handler

    class Configuration(Application.Configuration):

        templates = vodka.config.Attribute(
            vodka.config.validators.path,
            default=lambda k,i: i.resource(k),
            help_text="location of your template files"
        )

        template_engine = vodka.config.Attribute(
            str,
            default="jinja2",
            choices=["jinja2"],
            help_text="template engine to use to render your templates"
        )

    # class methods and properties

    @property
    def template_path(self):
        """ absolute path to template directory """
        return self.get_config("templates")

    def render(self, tmpl_name, request_env):
        """
        Render the specified template and return the output.

        Args:
            tmpl_name (str): file name of the template
            request_env (dict): request environment

        Returns:
            str - the rendered template
        """
        return self.tmpl._render(tmpl_name, request_env)

    def setup(self):
        import twentyc.tmpl

        # set up the template engine
        eng = twentyc.tmpl.get_engine(self.config.get("template_engine", "jinja2"))
        self.tmpl = eng(tmpl_dir=self.template_path)
<|endoftext|>


<commit_before>try:
    import json
except ImportError:
    import simplejson as json
import time
import urllib
import urlparse
import oauth2 as oauth

class Yammer(object):
    base_url = 'https://www.yammer.com/api/v1/'

    def __init__(self, consumer_key, consumer_secret,
                 oauth_token=None, oauth_token_secret=None,
                 request_token_url=None, access_token_url=None,
                 authorize_url=None):
        self.request_token_url = 'https://www.yammer.com/oauth/request_token' \
            if request_token_url is None else request_token_url
        self.access_token_url = 'https://www.yammer.com/oauth/access_token' \
            if access_token_url is None else access_token_url
        self.authorize_url = 'https://www.yammer.com/oauth/authorize' \
            if authorize_url is None else authorize_url

        self.consumer = oauth.Consumer(consumer_key, consumer_secret)
        if oauth_token and oauth_token_secret:
            self.token = oauth.Token(oauth_token, oauth_token_secret)
        else:
            self.token = None
        self.client = oauth.Client(self.consumer, self.token)

        # connect endpoints
        self.messages = _MessageEndpoint(self)
        self.groups = _GroupEndpoint(self)
        self.users = _UserEndpoint(self)

    # authorization
    @property
    def request_token(self):
        if not hasattr(self, '_request_token'):
            self._request_token = self._get_token(self.request_token_url)
        return self._request_token

    def get_authorize_url(self):
        return "%s?oauth_token=%s" \
            % (self.authorize_url, self.request_token.key)

    def get_access_token(self, oauth_verifier):
        # set verifier
        if not self.token:
            token = self.request_token
        else:
            token = self.token
        token.set_verifier(oauth_verifier)
        self.client = oauth.Client(self.consumer, token)
        return self._get_token(self.access_token_url, "POST")

    def verify(self, oauth_verifier):
        self.token = self.get_access_token(oauth_verifier)
        self.client = oauth.Client(self.consumer, self.token)

    # requests
    def _apicall(self, endpoint, method, **params):
        url = '%s%s' % (self.base_url, endpoint)
        body = ''
        cleaned_params = dict([(k,v) for k,v in params.iteritems() if v])

        if cleaned_params:
            body = urllib.urlencode(cleaned_params)
            if method == 'GET':
                url = '%s?%s' % (url, body)
                body = ''

        resp, content = self.client.request(url, method=method, body=body)
        if resp.status == 401:
            raise UnauthorizedError()
        elif resp.status != 200:
            raise UnknownError('invalid http response: %d' % resp.status)

        try:
            json_obj = json.loads(content)
            if 'response' in json_obj \
                    and json_obj['response'].get('stat', None) == 'fail':
                raise YammerError(json_obj['response']['message'])
            return json_obj
        except ValueError:
            raise UnknownError('invalid response')

    def _get_token(self, url, method="GET"):
        resp, content = self.client.request(url, method)
        if resp['status'] != '200':
            raise Exception("Invalid response %s." % resp['status'])
        d = dict(urlparse.parse_qsl(content))
        return oauth.Token(d['oauth_token'], d['oauth_token_secret'])

class _Endpoint(object):
    def __init__(self, yammer):
        self.yammer = yammer

    def _get(self, endpoint, **params):
        return self.yammer._apicall(endpoint, 'GET', **params)

    def _post(self, endpoint, **params):
        return self.yammer._apicall(endpoint, 'POST', **params)

    def _delete(self, endpoint, **params):
        return self.yammer._apicall(endpoint, 'DELETE', **params)

class _MessageEndpoint(_Endpoint):
    def all(self, **kwargs):
        """Returns all messages

        Keyword arguments:
        older_than -- returned messages must be older than the supplied id
        newer_than -- returned messages must be newer than the supplied id
        threaded -- possible values:
                        true (only show first message of thread)
                        extended (show first/two most recent messages of thread)
        limit -- return only the specified number of messages
        """
        return self._get_msgs('messages.json', **kwargs)

    def sent(self, **kwargs):
        """Returns sent messages; see all() for keywords"""
        return self._get_msgs('messages/sent.json', **kwargs)

    def received(self, **kwargs):
        """Returns received messages; see all() for keywords"""
        return self._get_msgs('messages/received.json', **kwargs)

    def private(self, **kwargs):
        """Returns private messages to the user; see all() for keywords"""
        return self._get_messages('messages/private.json', **kwargs)

    def following(self, **kwargs):
        """Returns followed messages; see all() for keywords"""
        return self._get_msgs('messages/following.json', **kwargs)

    def from_user(self, id, **kwargs):
        """Returns messages from the given user; see all() for keywords"""
        return self._get_msgs('messages/from_user/%d.json' % id, **kwargs)

    def from_bot(self, id, **kwargs):
        """Deprecated; no longer implemented"""
        raise NotImplementedError

    def about_topic(self, id, **kwargs):
        """Returns messages within the given topic; see all() for keywords"""
        return self._get_msgs(
            'messages/about_topic/%d.json' % id, **kwargs)

    def tagged_width(self, id, **kwargs):
        """Alias to about_topic()"""
        return self.about_topic(id)

    def in_group(self, id, **kwargs):
        """Returns messages within the given group; see all() for keywords"""
        return self._get_msgs('messages/in_group/%d.json' % id, **kwargs)

    def liked_by(self, id, **kwargs):
        """Returns liked messages; see all() for keywords"""
        return self._get_msgs('messages/liked_by/%d.json' % id, **kwargs)

    def favorites_of(self, id, **kwargs):
        """Alias to liked_by()"""
        return self.liked_by(id, **kwargs)

    def in_thread(self, id, **kwargs):
        """Returns messages within the thread; see all() for keywords"""
        return self._get_msgs('messages/in_thread/%d.json' % id, **kwargs)

    def post(self, body, **kwargs):
        """Create a message with the given body

        Keyword arguments:
        group_id -- The group id to post the message to
        replied_to_id -- The message id to reply to
        direct_to_id -- The user id to send a private message to
        broadcast -- If message should be broadcast (admin only)
        topics -- A list of topics (max 20)
        pending_attachments -- A list of pending attachment ids (max 20)
        og_<property> -- Open graph properties
        """
        if not kwargs.get('group_id') and not kwargs.get('direct_to_id') \
                and not kwargs.get('replied_to_id'):
            raise ValueError(
                'group_id, replied_to_id, or direct_to_id must be supplied')
        self._convert_list_to_keys(kwargs, 'topics', 'topic', size=20)
        self._convert_list_to_keys(
            kwargs, 'pending_attachments', 'pending_attachment', size=20)

        return self._post('messages.json', **kwargs)

    def delete(self, id):
        """Delete the message with the given id"""
        return self._delete('messages/%d' % id)

    def _get_msgs(self, endpoint, **kwargs):
        rv = self._get(endpoint,
                       older_than=kwargs.get('older_than'),
                       newer_than=kwargs.get('newer_than'),
                       threaded=kwargs.get('threaded'),
                       limit=kwargs.get('limit'))
        return rv

    def _convert_list_to_keys(self, args, list_key, item_key, size=None):
        if not list_key in args:
            return

        if not args.get(list_key):
            args[list_key] = []
        elif not isinstance(args.get(list_key), list):
            args[list_key] = [args.get(list_key)]

        if size is not None and len(args.get(list_key)) > size:
            raise ValueError('%s length must not exceed %d' % (list_key, size))
        for x in range(len(args.get(list_key))):
            args['%s%d' % (item_key, x)] = args.get(list_key)[x]

class _GroupEndpoint(_Endpoint):
    def all(self, **kwargs):
        """Lists all groups

        Keyword arguments:
        page -- return groups on the page, 1-based
        letter -- return only groups starting with the letter
        sort_by -- possible values: messages, members, privacy, created_at,
                   creator
        reverse -- reverse the sort order
        """
        return self._get('groups.json', **kwargs)

    def get(self, id):
        """Get the group with the supplied id"""
        return self._get('groups/%d.json' % id)

    def create(self, name, private=None):
        """Create a new group with the supplied name"""
        return self._post('groups', name=name, private=private)

    def update(self, id, name, private=None):
        """Update an existing group"""
        return self._post('groups/%d' % id, name=name, private=private)

class _UserEndpoint(_Endpoint):
    def all(self, **kwargs):
        """Lists all users

        Keyword arguments:
        page -- return users on the page, 1-based
        letter -- returning users beginning wit the given letter
        sort_by -- possible values: messages, followers
        reverse -- reverse the sort order
        """
        return self._get('users.json', **kwargs)

    def get(self, id):
        """Get the user with the supplied id"""
        return self._get('users/%d.json' % id)

    def current(self):
        """Get the currently logged in user"""
        return self._get('users/current.json')

    def by_email(self, email):
        """Get the user matching the supplied email address"""
        return self._get('users/by_email.json', email=email)

class UnauthorizedError(Exception):
    """Request to Yammer has not been authorized."""
    pass

class YammerError(Exception):
    """Yammer responded with a failure message."""
    pass

class UnknownError(Exception):
    """Unexpected error from Yammer."""
    pass
<commit_msg>modified verify to return the access token<commit_after>try:
    import json
except ImportError:
    import simplejson as json
import time
import urllib
import urlparse
import oauth2 as oauth

class Yammer(object):
    base_url = 'https://www.yammer.com/api/v1/'

    def __init__(self, consumer_key, consumer_secret,
                 oauth_token=None, oauth_token_secret=None,
                 request_token_url=None, access_token_url=None,
                 authorize_url=None):
        self.request_token_url = 'https://www.yammer.com/oauth/request_token' \
            if request_token_url is None else request_token_url
        self.access_token_url = 'https://www.yammer.com/oauth/access_token' \
            if access_token_url is None else access_token_url
        self.authorize_url = 'https://www.yammer.com/oauth/authorize' \
            if authorize_url is None else authorize_url

        self.consumer = oauth.Consumer(consumer_key, consumer_secret)
        if oauth_token and oauth_token_secret:
            self.token = oauth.Token(oauth_token, oauth_token_secret)
        else:
            self.token = None
        self.client = oauth.Client(self.consumer, self.token)

        # connect endpoints
        self.messages = _MessageEndpoint(self)
        self.groups = _GroupEndpoint(self)
        self.users = _UserEndpoint(self)

    # authorization
    @property
    def request_token(self):
        if not hasattr(self, '_request_token'):
            self._request_token = self._get_token(self.request_token_url)
        return self._request_token

    def get_authorize_url(self):
        return "%s?oauth_token=%s" \
            % (self.authorize_url, self.request_token.key)

    def get_access_token(self, oauth_verifier):
        # set verifier
        if not self.token:
            token = self.request_token
        else:
            token = self.token
        token.set_verifier(oauth_verifier)
        self.client = oauth.Client(self.consumer, token)
        return self._get_token(self.access_token_url, "POST")

    def verify(self, oauth_verifier):
        self.token = self.get_access_token(oauth_verifier)
        self.client = oauth.Client(self.consumer, self.token)
        return self.token

    # requests
    def _apicall(self, endpoint, method, **params):
        url = '%s%s' % (self.base_url, endpoint)
        body = ''
        cleaned_params = dict([(k,v) for k,v in params.iteritems() if v])

        if cleaned_params:
            body = urllib.urlencode(cleaned_params)
            if method == 'GET':
                url = '%s?%s' % (url, body)
                body = ''

        resp, content = self.client.request(url, method=method, body=body)
        if resp.status == 401:
            raise UnauthorizedError()
        elif resp.status != 200:
            raise UnknownError('invalid http response: %d' % resp.status)

        try:
            json_obj = json.loads(content)
            if 'response' in json_obj \
                    and json_obj['response'].get('stat', None) == 'fail':
                raise YammerError(json_obj['response']['message'])
            return json_obj
        except ValueError:
            raise UnknownError('invalid response')

    def _get_token(self, url, method="GET"):
        resp, content = self.client.request(url, method)
        if resp['status'] != '200':
            raise Exception("Invalid response %s." % resp['status'])
        d = dict(urlparse.parse_qsl(content))
        return oauth.Token(d['oauth_token'], d['oauth_token_secret'])

class _Endpoint(object):
    def __init__(self, yammer):
        self.yammer = yammer

    def _get(self, endpoint, **params):
        return self.yammer._apicall(endpoint, 'GET', **params)

    def _post(self, endpoint, **params):
        return self.yammer._apicall(endpoint, 'POST', **params)

    def _delete(self, endpoint, **params):
        return self.yammer._apicall(endpoint, 'DELETE', **params)

class _MessageEndpoint(_Endpoint):
    def all(self, **kwargs):
        """Returns all messages

        Keyword arguments:
        older_than -- returned messages must be older than the supplied id
        newer_than -- returned messages must be newer than the supplied id
        threaded -- possible values:
                        true (only show first message of thread)
                        extended (show first/two most recent messages of thread)
        limit -- return only the specified number of messages
        """
        return self._get_msgs('messages.json', **kwargs)

    def sent(self, **kwargs):
        """Returns sent messages; see all() for keywords"""
        return self._get_msgs('messages/sent.json', **kwargs)

    def received(self, **kwargs):
        """Returns received messages; see all() for keywords"""
        return self._get_msgs('messages/received.json', **kwargs)

    def private(self, **kwargs):
        """Returns private messages to the user; see all() for keywords"""
        return self._get_messages('messages/private.json', **kwargs)

    def following(self, **kwargs):
        """Returns followed messages; see all() for keywords"""
        return self._get_msgs('messages/following.json', **kwargs)

    def from_user(self, id, **kwargs):
        """Returns messages from the given user; see all() for keywords"""
        return self._get_msgs('messages/from_user/%d.json' % id, **kwargs)

    def from_bot(self, id, **kwargs):
        """Deprecated; no longer implemented"""
        raise NotImplementedError

    def about_topic(self, id, **kwargs):
        """Returns messages within the given topic; see all() for keywords"""
        return self._get_msgs(
            'messages/about_topic/%d.json' % id, **kwargs)

    def tagged_width(self, id, **kwargs):
        """Alias to about_topic()"""
        return self.about_topic(id)

    def in_group(self, id, **kwargs):
        """Returns messages within the given group; see all() for keywords"""
        return self._get_msgs('messages/in_group/%d.json' % id, **kwargs)

    def liked_by(self, id, **kwargs):
        """Returns liked messages; see all() for keywords"""
        return self._get_msgs('messages/liked_by/%d.json' % id, **kwargs)

    def favorites_of(self, id, **kwargs):
        """Alias to liked_by()"""
        return self.liked_by(id, **kwargs)

    def in_thread(self, id, **kwargs):
        """Returns messages within the thread; see all() for keywords"""
        return self._get_msgs('messages/in_thread/%d.json' % id, **kwargs)

    def post(self, body, **kwargs):
        """Create a message with the given body

        Keyword arguments:
        group_id -- The group id to post the message to
        replied_to_id -- The message id to reply to
        direct_to_id -- The user id to send a private message to
        broadcast -- If message should be broadcast (admin only)
        topics -- A list of topics (max 20)
        pending_attachments -- A list of pending attachment ids (max 20)
        og_<property> -- Open graph properties
        """
        if not kwargs.get('group_id') and not kwargs.get('direct_to_id') \
                and not kwargs.get('replied_to_id'):
            raise ValueError(
                'group_id, replied_to_id, or direct_to_id must be supplied')
        self._convert_list_to_keys(kwargs, 'topics', 'topic', size=20)
        self._convert_list_to_keys(
            kwargs, 'pending_attachments', 'pending_attachment', size=20)

        return self._post('messages.json', **kwargs)

    def delete(self, id):
        """Delete the message with the given id"""
        return self._delete('messages/%d' % id)

    def _get_msgs(self, endpoint, **kwargs):
        rv = self._get(endpoint,
                       older_than=kwargs.get('older_than'),
                       newer_than=kwargs.get('newer_than'),
                       threaded=kwargs.get('threaded'),
                       limit=kwargs.get('limit'))
        return rv

    def _convert_list_to_keys(self, args, list_key, item_key, size=None):
        if not list_key in args:
            return

        if not args.get(list_key):
            args[list_key] = []
        elif not isinstance(args.get(list_key), list):
            args[list_key] = [args.get(list_key)]

        if size is not None and len(args.get(list_key)) > size:
            raise ValueError('%s length must not exceed %d' % (list_key, size))
        for x in range(len(args.get(list_key))):
            args['%s%d' % (item_key, x)] = args.get(list_key)[x]

class _GroupEndpoint(_Endpoint):
    def all(self, **kwargs):
        """Lists all groups

        Keyword arguments:
        page -- return groups on the page, 1-based
        letter -- return only groups starting with the letter
        sort_by -- possible values: messages, members, privacy, created_at,
                   creator
        reverse -- reverse the sort order
        """
        return self._get('groups.json', **kwargs)

    def get(self, id):
        """Get the group with the supplied id"""
        return self._get('groups/%d.json' % id)

    def create(self, name, private=None):
        """Create a new group with the supplied name"""
        return self._post('groups', name=name, private=private)

    def update(self, id, name, private=None):
        """Update an existing group"""
        return self._post('groups/%d' % id, name=name, private=private)

class _UserEndpoint(_Endpoint):
    def all(self, **kwargs):
        """Lists all users

        Keyword arguments:
        page -- return users on the page, 1-based
        letter -- returning users beginning wit the given letter
        sort_by -- possible values: messages, followers
        reverse -- reverse the sort order
        """
        return self._get('users.json', **kwargs)

    def get(self, id):
        """Get the user with the supplied id"""
        return self._get('users/%d.json' % id)

    def current(self):
        """Get the currently logged in user"""
        return self._get('users/current.json')

    def by_email(self, email):
        """Get the user matching the supplied email address"""
        return self._get('users/by_email.json', email=email)

class UnauthorizedError(Exception):
    """Request to Yammer has not been authorized."""
    pass

class YammerError(Exception):
    """Yammer responded with a failure message."""
    pass

class UnknownError(Exception):
    """Unexpected error from Yammer."""
    pass
<|endoftext|>


<commit_before>import requests

from will.plugin import WillPlugin
from will.decorators import respond_to, periodic, hear, randomly, route, rendered_template, require_settings

class PugPlugin(WillPlugin):

    @hear(r'\bpugs?\b')
    def talk_on_pug(self, message):
        req = requests.get('http://pugme.herokuapp.com/random')
        if req.ok:
            pug = req.json()['pug']
            if 'media.tumblr.com' in pug:
                pug = 'https://media.tumblr.com' + pug.split('media.tumblr.com')[1]

            self.say(pug, message=message)
<commit_msg>comments<commit_after>import requests

from will.plugin import WillPlugin
from will.decorators import respond_to, periodic, hear, randomly, route, rendered_template, require_settings

class PugPlugin(WillPlugin):

    @hear(r'\bpugs?\b')
    def talk_on_pug(self, message):
        req = requests.get('http://pugme.herokuapp.com/random')
        if req.ok:
            pug = req.json()['pug']

            if 'media.tumblr.com' in pug:
                # replace *.media.tumblr.com with media.tumblr.com and force ssl
                pug = 'https://media.tumblr.com' + pug.split('media.tumblr.com')[1]

            self.say(pug, message=message)
<|endoftext|>


<commit_before># encoding: utf-8
"""
Views for django-shinxdoc.

"""
import datetime
import json
import os.path

from django.core import urlresolvers
from django.core.exceptions import ObjectDoesNotExist
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext
from django.views.decorators.cache import cache_page
from django.views.static import serve
from haystack.views import SearchView

from sphinxdoc.forms import ProjectSearchForm
from sphinxdoc.models import Project, Document

BUILDDIR = os.path.join('_build', 'json')
CACHE_MINUTES = 5

@cache_page(60 * CACHE_MINUTES)
def documentation(request, slug, path):
    """
    Displays the contents of a :class:`sphinxdoc.models.Document`.

    ``slug`` specifies the project, the document belongs to, ``path`` is the
    path to the original JSON file relative to the builddir and without the
    file extension. ``path`` may also be a directory, so this view checks if
    ``path/index`` exists, before trying to load ``path`` directly.

    """
    project = get_object_or_404(Project, slug=slug)
    path = path.rstrip('/')

    try:
        index = 'index' if path == '' else '%s/index' % path
        doc = Document.objects.get(project=project, path=index)
    except ObjectDoesNotExist:
        doc = get_object_or_404(Document, project=project, path=path)

    # genindex and modindex get a special template
    templates = (
        'sphinxdoc/%s.html' % os.path.basename(path),
        'sphinxdoc/documentation.html',
    )

    data = {
        'project': project,
        'doc': json.loads(doc.content),
        'env': json.load(open(
                os.path.join(project.path, BUILDDIR,
                'globalcontext.json'), 'rb')),
        'update_date':  datetime.datetime.fromtimestamp(
                os.path.getmtime(os.path.join(project.path, BUILDDIR,
                'last_build'))),
        'search': urlresolvers.reverse('doc-search', kwargs={'slug': slug}),
    }

    return render_to_response(templates, data,
            context_instance=RequestContext(request))

@cache_page(60 * CACHE_MINUTES)
def objects_inventory(request, slug):
    """
    Renders the ``objects.inv`` as plain text.

    """
    project = get_object_or_404(Project, slug=slug)
    response = serve(
        request,
        document_root=project.path,
        path='objects.inv',
    )
    response['Content-Type'] = 'text/plain'
    return response

@cache_page(60 * CACHE_MINUTES)
def sphinx_serve(request, slug, type_, path):
    """
    Serves sphinx static and other files.

    """
    project = get_object_or_404(Project, slug=slug)
    return serve(
        request,
        document_root=os.path.join(project.path, BUILDDIR, type_),
        path=path,
    )

class ProjectSearchView(SearchView):
    """
    Inherits :class:`SearchView` and handles a search request and displays the
    results as a simple list.

    """
    def __init__(self):
        SearchView.__init__(self, form_class=ProjectSearchForm,
                template='sphinxdoc/search.html')

    def __call__(self, request, slug):
        self.slug = slug
        return SearchView.__call__(self, request)

    def build_form(self):
        """
        Instantiates the form that should be used to process the search query.

        """
        return self.form_class(self.request.GET, slug=self.slug,
                searchqueryset=self.searchqueryset, load_all=self.load_all)

    def extra_context(self):
        return {
            'project': Project.objects.get(slug=self.slug),
        }
<commit_msg>Fixed path to `objects.inv`.<commit_after># encoding: utf-8
"""
Views for django-shinxdoc.

"""
import datetime
import json
import os.path

from django.core import urlresolvers
from django.core.exceptions import ObjectDoesNotExist
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext
from django.views.decorators.cache import cache_page
from django.views.static import serve
from haystack.views import SearchView

from sphinxdoc.forms import ProjectSearchForm
from sphinxdoc.models import Project, Document

BUILDDIR = os.path.join('_build', 'json')
CACHE_MINUTES = 5

@cache_page(60 * CACHE_MINUTES)
def documentation(request, slug, path):
    """
    Displays the contents of a :class:`sphinxdoc.models.Document`.

    ``slug`` specifies the project, the document belongs to, ``path`` is the
    path to the original JSON file relative to the builddir and without the
    file extension. ``path`` may also be a directory, so this view checks if
    ``path/index`` exists, before trying to load ``path`` directly.

    """
    project = get_object_or_404(Project, slug=slug)
    path = path.rstrip('/')

    try:
        index = 'index' if path == '' else '%s/index' % path
        doc = Document.objects.get(project=project, path=index)
    except ObjectDoesNotExist:
        doc = get_object_or_404(Document, project=project, path=path)

    # genindex and modindex get a special template
    templates = (
        'sphinxdoc/%s.html' % os.path.basename(path),
        'sphinxdoc/documentation.html',
    )

    data = {
        'project': project,
        'doc': json.loads(doc.content),
        'env': json.load(open(
                os.path.join(project.path, BUILDDIR,
                'globalcontext.json'), 'rb')),
        'update_date':  datetime.datetime.fromtimestamp(
                os.path.getmtime(os.path.join(project.path, BUILDDIR,
                'last_build'))),
        'search': urlresolvers.reverse('doc-search', kwargs={'slug': slug}),
    }

    return render_to_response(templates, data,
            context_instance=RequestContext(request))

@cache_page(60 * CACHE_MINUTES)
def objects_inventory(request, slug):
    """
    Renders the ``objects.inv`` as plain text.

    """
    project = get_object_or_404(Project, slug=slug)
    response = serve(
        request,
        document_root=os.path.join(project.path, BUILDDIR),
        path='objects.inv',
    )
    response['Content-Type'] = 'text/plain'
    return response

@cache_page(60 * CACHE_MINUTES)
def sphinx_serve(request, slug, type_, path):
    """
    Serves sphinx static and other files.

    """
    project = get_object_or_404(Project, slug=slug)
    return serve(
        request,
        document_root=os.path.join(project.path, BUILDDIR, type_),
        path=path,
    )

class ProjectSearchView(SearchView):
    """
    Inherits :class:`SearchView` and handles a search request and displays the
    results as a simple list.

    """
    def __init__(self):
        SearchView.__init__(self, form_class=ProjectSearchForm,
                template='sphinxdoc/search.html')

    def __call__(self, request, slug):
        self.slug = slug
        return SearchView.__call__(self, request)

    def build_form(self):
        """
        Instantiates the form that should be used to process the search query.

        """
        return self.form_class(self.request.GET, slug=self.slug,
                searchqueryset=self.searchqueryset, load_all=self.load_all)

    def extra_context(self):
        return {
            'project': Project.objects.get(slug=self.slug),
        }
<|endoftext|>