<commit_before>import sublime
import sublime_plugin
import json

def achievement_dialog(message):
    message = "YOU GOT A NEW ACHIEVEMENT\n\n" + message
    sublime.message_dialog(message)

class EventAchievementChecker(sublime_plugin.EventListener):
    def on_post_save_async(self, view):
        setting = sublime.load_settings("achievement.sublime-settings")
        count = setting.get("save_count", 0) + 1
        self.count_achievement_function("save_count", count, (1,), "Hello save world!")
        self.count_achievement_function("save_count", count, (10, 100, 300, 500, 1000, 10000, 100000), "Save {num} times!")
        self.count_achievement_function("save_count", count, (99999999,), "Oversave!!!")
        setting.set("save_count", count)
        sublime.save_settings("achievement.sublime-settings")

    def on_load_async(self, view):
        setting = sublime.load_settings("achievement.sublime-settings")
        count = setting.get("load_count", 0) + 1
        self.count_achievement_function("load_count", count, (1,), "Hello load world!")
        self.count_achievement_function("load_count", count, (10, 100, 300, 500, 1000, 10000, 100000), "Load {num} times!")
        self.count_achievement_function("load_count", count, (99999999,), "Overload!!!")
        setting.set("load_count", count)
        sublime.save_settings("achievement.sublime-settings")

    def on_new_async(self, view):
        setting = sublime.load_settings("achievement.sublime-settings")
        count = setting.get("new_file_count", 0) + 1
        self.count_achievement_function("new_file_count", count, (1,), "Hello World!")
        self.count_achievement_function("new_file_count", count, (10, 100, 300, 500, 1000, 10000, 100000), "Create new file {num} times!")
        self.count_achievement_function("new_file_count", count, (99999999,), "THE MAKER")
        setting.set("new_file_count", count)
        sublime.save_settings("achievement.sublime-settings")

    def on_clone_async(self, view):
        setting = sublime.load_settings("achievement.sublime-settings")
        count = setting.get("clone_file_count", 0) + 1
        self.count_achievement_function("clone_file_count", count, (1,), "Duplicate Window!")
        self.count_achievement_function("clone_file_count", count, (10, 100, 300, 500, 1000, 10000, 100000), "Create new file {num} times!")
        self.count_achievement_function("clone_file_count", count, (99999999,), "Cloned Human")
        setting.set("clone_file_count", count)
        sublime.save_settings("achievement.sublime-settings")

    def count_achievement_function(self, setting_name, count, achieving_counts, message):
        u"""
        setting_name(str): 'load_count'
        achieving_counts(int list): (1, 10, 100, 5000, 1000)
        message(str): 'save {num} times!'
            message can contain integer number{num}
        """
        if count in achieving_counts:
            message = message.format(num=count)
            achievement_dialog(message)
            unlocked_settings = sublime.load_settings("unlocked.sublime-settings")
            unlocked_titles = unlocked_settings.get("unlocked_titles", [])
            if setting_name in unlocked_titles:
                c_setting = unlocked_settings.get(setting_name, [])
                c_setting.append(message)
                unlocked_settings.set(setting_name, c_setting)
            else:
                unlocked_titles.append(setting_name)
                unlocked_settings.set("unlocked_titles", unlocked_titles)
                unlocked_settings.set(setting_name, [message])
            sublime.save_settings("unlocked.sublime-settings")

class ViewAchievementCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        w = self.view.window()
        achievement_window = w.new_file()
        # write unlocked achievement
        unlocked_settings = sublime.load_settings("unlocked.sublime-settings")
        unlocked_titles = unlocked_settings.get("unlocked_titles", [])
        for unlocked_title in sorted(unlocked_titles):
            for unlock in reversed(sorted(unlocked_settings.get(unlocked_title, []))):
                line = "*\t{unlock}\n".format(unlock=unlock)
                achievement_window.insert(edit, 0, line)

            line = "\n+=+=+=+=+=+=+=+ {unlocked_title} +=+=+=+=+=+=+=+\n".format(unlocked_title=unlocked_title)
            achievement_window.insert(edit, 0, line)

        message = "*=*=*=*=*=*=*=* UNLOCKED ACHIEVEMENTS *=*=*=*=*=*=*=*\n"
        achievement_window.insert(edit, 0, message)
<commit_msg>fix: some message typo and capital<commit_after>import sublime
import sublime_plugin
import json

def achievement_dialog(message):
    message = "YOU GOT A NEW ACHIEVEMENT\n\n" + message
    sublime.message_dialog(message)

class EventAchievementChecker(sublime_plugin.EventListener):
    def on_post_save_async(self, view):
        setting = sublime.load_settings("achievement.sublime-settings")
        count = setting.get("save_count", 0) + 1
        self.count_achievement_function("save_count", count, (1,), "Hello Save World!")
        self.count_achievement_function("save_count", count, (10, 100, 300, 500, 1000, 10000, 100000), "Save {num} times!")
        self.count_achievement_function("save_count", count, (99999999,), "Oversave!!!")
        setting.set("save_count", count)
        sublime.save_settings("achievement.sublime-settings")

    def on_load_async(self, view):
        setting = sublime.load_settings("achievement.sublime-settings")
        count = setting.get("load_count", 0) + 1
        self.count_achievement_function("load_count", count, (1,), "Helload World!")
        self.count_achievement_function("load_count", count, (10, 100, 300, 500, 1000, 10000, 100000), "Load {num} times!")
        self.count_achievement_function("load_count", count, (99999999,), "Overload!!!")
        setting.set("load_count", count)
        sublime.save_settings("achievement.sublime-settings")

    def on_new_async(self, view):
        setting = sublime.load_settings("achievement.sublime-settings")
        count = setting.get("new_file_count", 0) + 1
        self.count_achievement_function("new_file_count", count, (1,), "Hello World!")
        self.count_achievement_function("new_file_count", count, (10, 100, 300, 500, 1000, 10000, 100000), "Create new file {num} times!")
        self.count_achievement_function("new_file_count", count, (99999999,), "THE MAKER")
        setting.set("new_file_count", count)
        sublime.save_settings("achievement.sublime-settings")

    def on_clone_async(self, view):
        setting = sublime.load_settings("achievement.sublime-settings")
        count = setting.get("clone_file_count", 0) + 1
        self.count_achievement_function("clone_file_count", count, (1,), "Duplicate Window!")
        self.count_achievement_function("clone_file_count", count, (10, 100, 300, 500, 1000, 10000, 100000), "Duplicate file {num} times!")
        self.count_achievement_function("clone_file_count", count, (99999999,), "Cloned Human")
        setting.set("clone_file_count", count)
        sublime.save_settings("achievement.sublime-settings")

    def count_achievement_function(self, setting_name, count, achieving_counts, message):
        u"""
        setting_name(str): 'load_count'
        achieving_counts(int list): (1, 10, 100, 5000, 1000)
        message(str): 'save {num} times!'
            message can contain integer number{num}
        """
        if count in achieving_counts:
            message = message.format(num=count)
            achievement_dialog(message)
            unlocked_settings = sublime.load_settings("unlocked.sublime-settings")
            unlocked_titles = unlocked_settings.get("unlocked_titles", [])
            if setting_name in unlocked_titles:
                c_setting = unlocked_settings.get(setting_name, [])
                c_setting.append(message)
                unlocked_settings.set(setting_name, c_setting)
            else:
                unlocked_titles.append(setting_name)
                unlocked_settings.set("unlocked_titles", unlocked_titles)
                unlocked_settings.set(setting_name, [message])
            sublime.save_settings("unlocked.sublime-settings")

class ViewAchievementCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        w = self.view.window()
        achievement_window = w.new_file()
        # write unlocked achievement
        unlocked_settings = sublime.load_settings("unlocked.sublime-settings")
        unlocked_titles = unlocked_settings.get("unlocked_titles", [])
        for unlocked_title in sorted(unlocked_titles):
            for unlock in reversed(sorted(unlocked_settings.get(unlocked_title, []))):
                line = "*\t{unlock}\n".format(unlock=unlock)
                achievement_window.insert(edit, 0, line)

            line = "\n+=+=+=+=+=+=+=+ {unlocked_title} +=+=+=+=+=+=+=+\n".format(unlocked_title=unlocked_title)
            achievement_window.insert(edit, 0, line)

        message = "*=*=*=*=*=*=*=* UNLOCKED ACHIEVEMENTS *=*=*=*=*=*=*=*\n"
        achievement_window.insert(edit, 0, message)
<|endoftext|>


<commit_before># ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (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.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is the Narcissus JavaScript engine, written in Javascript.
#
# The Initial Developer of the Original Code is
# Brendan Eich <brendan@mozilla.org>.
# Portions created by the Initial Developer are Copyright (C) 2004
# the Initial Developer. All Rights Reserved.
#
# The Python version of the code was created by JT Olds <jtolds@xnet5.com>,
# and is a direct translation from the Javascript version.
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK ***** */

import re, sys, types
from narcissus.Lang import *

class Token:
    pass

class ParseError(Exception):
    def __init__(self, message, filename, lineno):
        Exception.__init__(self, "Syntax error: %s\n%s:%s" % (message, filename, lineno))

class Tokenizer(object):
    def __init__(self, source, filename):
        self.cursor = 0
        self.source = str(source)
        self.tokens = {}
        self.tokenIndex = 0
        self.lookahead = 0
        self.scanNewlines = False
        self.scanOperand = True
        self.filename = filename
        self.lineno = 1

    input_ = property(lambda self: self.source[self.cursor:])
    done = property(lambda self: self.peek() == END)
    token = property(lambda self: self.tokens.get(self.tokenIndex))

    def match(self, tokenType):
        return self.get() == tokenType or self.unget()

    def mustMatch(self, tokenType):
        if not self.match(tokenType):
            raise ParseError("Missing " + tokens.get(tokenType).lower(), self.filename, self.lineno)
        return self.token

    def peek(self):
        if self.lookahead:
            next = self.tokens.get((self.tokenIndex + self.lookahead) & 3)
            if self.scanNewlines and (getattr(next, "lineno", None) != getattr(self, "lineno", None)):
                tokenType = NEWLINE
            else:
                tokenType = getattr(next, "type_", None)
        else:
            tokenType = self.get()
            self.unget()

        return tokenType

    def peekOnSameLine(self):
        self.scanNewlines = True
        tokenType = self.peek()
        self.scanNewlines = False
        return tokenType

    def get(self):
        while self.lookahead:
            self.lookahead -= 1
            self.tokenIndex = (self.tokenIndex + 1) & 3
            token = self.tokens.get(self.tokenIndex)
            if getattr(token, "type_", None) != NEWLINE or self.scanNewlines:
                return getattr(token, "type_", None)

        comments = []
        while True:
            input__ = self.input_
            if self.scanNewlines:
                match = re.match(r'^[ \t]+', input__)
            else:
                match = re.match(r'^\s+', input__)
            if match:
                spaces = match.group(0)
                self.cursor += len(spaces)
                newlines = newlineMatcher.findall(spaces)
                if newlines:
                    self.lineno += len(newlines)
                input__ = self.input_

            match = commentMatcher.match(input__)
            if not match:
                break

            comment = match.group(0)
            comments.append(comment)
            self.cursor += len(comment)
            newlines = newlineMatcher.findall(comment)
            if newlines:
                self.lineno += len(newlines)

        self.tokenIndex = (self.tokenIndex + 1) & 3
        token = self.tokens.get(self.tokenIndex)
        if not token:
            token = Token()
            self.tokens[self.tokenIndex] = token

        # Store comments
        if len(comments) > 0:
            token.comments = comments;

        # Update token
        if input__:
            token.start = self.cursor
            self.cursor += len(self.matchInput(token, input__))
            token.end = self.cursor
            token.lineno = self.lineno
        else:
            token.type_ = END

        # Return token type
        return getattr(token, "type_", None)

    def matchInput(self, token, text):
        match = floatMatcher.match(text)
        if match:
            token.type_ = NUMBER
            token.value = float(match.group(0))
            return match.group(0)

        match = numberMatcher.match(text)
        if match:
            token.type_ = NUMBER
            token.value = eval(match.group(0))
            return match.group(0)

        match = identifierMatcher.match(text)
        if match:
            id_ = match.group(0)
            print id_
            token.type_ = keywords.get(id_, IDENTIFIER)
            token.value = id_
            return match.group(0)

        match = stringMatcher.match(text)
        if match:
            token.type_ = STRING
            token.value = eval(match.group(0))
            if match.group(0)[0] == "'":
                token.variant = "single"
            else:
                token.variant = "double"
            return match.group(0)

        if self.scanOperand:
            match = regularExprMatcher.match(text)
            if match:
                token.type_ = REGEXP
                token.value = {"regexp": match.group(1), "modifiers": match.group(2)}
                return match.group(0)

        match = symbolMatcher.match(text)
        if match:
            op = match.group(0)
            if assignOps.has_key(op) and text[len(op)] == '=':
                token.type_ = ASSIGN
                token.assignOp = globals()[operatorPunctuatorNames[op]]
                token.value = op
                return match.group(0) + "="
            token.type_ = globals()[operatorPunctuatorNames[op]]
            if self.scanOperand and (token.type_ in (PLUS, MINUS)):
                token.type_ += UNARY_PLUS - PLUS
            token.assignOp = None
            token.value = op
            return match.group(0)

        if self.scanNewlines:
            match = re.match(r'^\n', text)
            if match:
                token.type_ = NEWLINE
                return match.group(0)

        raise ParseError("Illegal token", self.filename, self.lineno)

    def unget(self):
        self.lookahead += 1

        if self.lookahead == 4:
            raise "PANIC: too much lookahead!"

        self.tokenIndex = (self.tokenIndex - 1) & 3
<commit_msg>Minor<commit_after># ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (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.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is the Narcissus JavaScript engine, written in Javascript.
#
# The Initial Developer of the Original Code is
# Brendan Eich <brendan@mozilla.org>.
# Portions created by the Initial Developer are Copyright (C) 2004
# the Initial Developer. All Rights Reserved.
#
# The Python version of the code was created by JT Olds <jtolds@xnet5.com>,
# and is a direct translation from the Javascript version.
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK ***** */

import re, sys, types
from narcissus.Lang import *

class Token:
    pass

class ParseError(Exception):
    def __init__(self, message, filename, lineno):
        Exception.__init__(self, "Syntax error: %s\n%s:%s" % (message, filename, lineno))

class Tokenizer(object):
    def __init__(self, source, filename):
        self.cursor = 0
        self.source = str(source)
        self.tokens = {}
        self.tokenIndex = 0
        self.lookahead = 0
        self.scanNewlines = False
        self.scanOperand = True
        self.filename = filename
        self.lineno = 1

    input_ = property(lambda self: self.source[self.cursor:])
    done = property(lambda self: self.peek() == END)
    token = property(lambda self: self.tokens.get(self.tokenIndex))

    def match(self, tokenType):
        return self.get() == tokenType or self.unget()

    def mustMatch(self, tokenType):
        if not self.match(tokenType):
            raise ParseError("Missing " + tokens.get(tokenType).lower(), self.filename, self.lineno)
        return self.token

    def peek(self):
        if self.lookahead:
            next = self.tokens.get((self.tokenIndex + self.lookahead) & 3)
            if self.scanNewlines and (getattr(next, "lineno", None) != getattr(self, "lineno", None)):
                tokenType = NEWLINE
            else:
                tokenType = getattr(next, "type_", None)
        else:
            tokenType = self.get()
            self.unget()

        return tokenType

    def peekOnSameLine(self):
        self.scanNewlines = True
        tokenType = self.peek()
        self.scanNewlines = False
        return tokenType

    def get(self):
        while self.lookahead:
            self.lookahead -= 1
            self.tokenIndex = (self.tokenIndex + 1) & 3
            token = self.tokens.get(self.tokenIndex)
            if getattr(token, "type_", None) != NEWLINE or self.scanNewlines:
                return getattr(token, "type_", None)

        comments = []
        while True:
            input__ = self.input_
            if self.scanNewlines:
                match = re.match(r'^[ \t]+', input__)
            else:
                match = re.match(r'^\s+', input__)
            if match:
                spaces = match.group(0)
                self.cursor += len(spaces)
                newlines = newlineMatcher.findall(spaces)
                if newlines:
                    self.lineno += len(newlines)
                input__ = self.input_

            match = commentMatcher.match(input__)
            if not match:
                break

            comment = match.group(0)
            comments.append(comment)
            self.cursor += len(comment)
            newlines = newlineMatcher.findall(comment)
            if newlines:
                self.lineno += len(newlines)

        self.tokenIndex = (self.tokenIndex + 1) & 3
        token = self.tokens.get(self.tokenIndex)
        if not token:
            token = Token()
            self.tokens[self.tokenIndex] = token

        # Store comments
        if len(comments) > 0:
            token.comments = comments;

        # Update token
        if input__:
            token.start = self.cursor
            self.cursor += len(self.matchInput(token, input__))
            token.end = self.cursor
            token.lineno = self.lineno
        else:
            token.type_ = END

        # Return token type
        return getattr(token, "type_", None)

    def matchInput(self, token, text):
        match = floatMatcher.match(text)
        if match:
            token.type_ = NUMBER
            token.value = float(match.group(0))
            return match.group(0)

        match = numberMatcher.match(text)
        if match:
            token.type_ = NUMBER
            token.value = eval(match.group(0))
            return match.group(0)

        match = identifierMatcher.match(text)
        if match:
            id_ = match.group(0)
            print "xx: %s - yy: %s" % (id_, IDENTIFIER)
            token.type_ = keywords.get(id_, IDENTIFIER)
            token.value = id_
            return match.group(0)

        match = stringMatcher.match(text)
        if match:
            token.type_ = STRING
            token.value = eval(match.group(0))
            if match.group(0)[0] == "'":
                token.variant = "single"
            else:
                token.variant = "double"
            return match.group(0)

        if self.scanOperand:
            match = regularExprMatcher.match(text)
            if match:
                token.type_ = REGEXP
                token.value = {"regexp": match.group(1), "modifiers": match.group(2)}
                return match.group(0)

        match = symbolMatcher.match(text)
        if match:
            op = match.group(0)
            if assignOps.has_key(op) and text[len(op)] == '=':
                token.type_ = ASSIGN
                token.assignOp = globals()[operatorPunctuatorNames[op]]
                token.value = op
                return match.group(0) + "="
            token.type_ = globals()[operatorPunctuatorNames[op]]
            if self.scanOperand and (token.type_ in (PLUS, MINUS)):
                token.type_ += UNARY_PLUS - PLUS
            token.assignOp = None
            token.value = op
            return match.group(0)

        if self.scanNewlines:
            match = re.match(r'^\n', text)
            if match:
                token.type_ = NEWLINE
                return match.group(0)

        raise ParseError("Illegal token", self.filename, self.lineno)

    def unget(self):
        self.lookahead += 1

        if self.lookahead == 4:
            raise "PANIC: too much lookahead!"

        self.tokenIndex = (self.tokenIndex - 1) & 3
<|endoftext|>


<commit_before>import types
from functools import wraps

from . import mathfuncs
from .pvector import PVector
from .sketch import Sketch, processing_func_name
from .utils import processing_func_name

# TODO: Add an __all__ variable to make sure everything doesn't get imported
#       when the user does an import *

_sketch = Sketch()

# Adding global variables to the __builtin__ module
import __builtin__
__builtin__.width = _sketch.width
__builtin__.height = _sketch.height
# TODO: is there a way to have a frameRate function and variable on __builtin__?
__builtin__.frame_rate = _sketch.frame_rate

def size(width, height):
    __builtin__.width = _sketch.width = width
    __builtin__.height = _sketch.height = height

def frameRate(frame_rate):
    __builtin__.frameRate = _sketch.frame_rate = frame_rate

def _bind(fn, obj):
    """Turns a function into a bound method and adds it to the given object.
    """
    @wraps(fn)
    def method(self, *args, **kwargs):
        return fn(*args, **kwargs)

    bound_method = types.MethodType(method, obj, obj.__class__)
    setattr(obj, bound_method.__name__, bound_method)

def run():
    import __main__
    main_globals = dir(__main__)

    # TODO: Replace this with something a bit more dynamic
    if 'setup' in main_globals:
        _bind(__main__.setup, _sketch)
    if 'draw' in main_globals:
        _bind(__main__.draw, _sketch)

    _sketch.run()

# Add the processing functions to the current module
self = __import__(__name__)
for func in _sketch.processing_functions:
    setattr(self, func.processing_name, func)

for func_name in filter(lambda s: not s.startswith('_'), dir(mathfuncs)):
    func = getattr(mathfuncs, func_name)
    processing_func_name = ''.join(func_name.split('_')[:1] + [s.capitalize() for s in func_name.split('_')[1:]])

    # if the new function's name matches a builtin one, add a preceding
    # underscore to the builtin functions name so we don't overwrite it.
    if processing_func_name in dir(__builtin__):
        builtin_func = getattr(__builtin__, processing_func_name)
        setattr(__builtin__, '_%s' % processing_func_name, builtin_func)

    setattr(self, processing_func_name, func)
<commit_msg>Cleanup<commit_after>import types
from functools import wraps

from . import mathfuncs
from .pvector import PVector
from .sketch import Sketch
from .utils import processing_func_name

# TODO: Add an __all__ variable to make sure everything doesn't get imported
#       when the user does an import *

_sketch = Sketch()

# Adding global variables to the __builtin__ module
import __builtin__
__builtin__.width = _sketch.width
__builtin__.height = _sketch.height
# TODO: is there a way to have a frameRate function and variable on __builtin__?
__builtin__.frame_rate = _sketch.frame_rate

def size(width, height):
    __builtin__.width = _sketch.width = width
    __builtin__.height = _sketch.height = height

def frameRate(frame_rate):
    __builtin__.frameRate = _sketch.frame_rate = frame_rate

def _bind(fn, obj):
    """Turns a function into a bound method and adds it to the given object.
    """
    @wraps(fn)
    def method(self, *args, **kwargs):
        return fn(*args, **kwargs)

    bound_method = types.MethodType(method, obj, obj.__class__)
    setattr(obj, bound_method.__name__, bound_method)

def run():
    import __main__
    main_globals = dir(__main__)

    # TODO: Replace this with something a bit more dynamic
    if 'setup' in main_globals:
        _bind(__main__.setup, _sketch)
    if 'draw' in main_globals:
        _bind(__main__.draw, _sketch)

    _sketch.run()

# Add the processing functions to the current module
self = __import__(__name__)
for func in _sketch.processing_functions:
    setattr(self, func.processing_name, func)

for func_name in filter(lambda s: not s.startswith('_'), dir(mathfuncs)):
    func = getattr(mathfuncs, func_name)
    processing_name = processing_func_name(func_name)

    # if the new function's name matches a builtin one, add a preceding
    # underscore to the builtin functions name so we don't overwrite it.
    if processing_name in dir(__builtin__):
        builtin_func = getattr(__builtin__, processing_name)
        setattr(__builtin__, '_%s' % processing_name, builtin_func)

    setattr(self, processing_name, func)
<|endoftext|>


<commit_before>#!/usr/bin/env python

import os
import re
import sys
import time
import json
import zipfile
import platform
import distutils.version
import subprocess

# You can adjust some setting here. Default is for QOwnNotes app.
link_prepend = 'file://'
media_dir = 'media'
md_file_ext = 'md'
insert_title = True
force_windows_filename_limitations = False

try:
    pandoc_ver = subprocess.check_output(['pandoc', '-v'], timeout=3).decode('utf-8')[7:].split('\n', 1)[0]
    print('Found pandoc ' + pandoc_ver)
except Exception:
    print('Can\'t find pandoc. Please install pandoc or place it to the directory, where the script is.')
    exit()

if distutils.version.LooseVersion(pandoc_ver) < distutils.version.LooseVersion('1.16'):
    pandoc_args = ['pandoc', '-f', 'html', '-t', 'markdown_strict+pipe_tables-raw_html', '--no-wrap']
elif distutils.version.LooseVersion(pandoc_ver) < distutils.version.LooseVersion('1.19'):
    pandoc_args = ['pandoc', '-f', 'html', '-t', 'markdown_strict+pipe_tables-raw_html', '--wrap=none']
else:
    pandoc_args = ['pandoc', '-f', 'html', '-t', 'markdown_strict+pipe_tables-raw_html', '--wrap=none', '--atx-headers']

if len(sys.argv) > 1:
    files = sys.argv[1:]
else:
    files = os.listdir()

for file in files:
    if not file.endswith('.nsx'):
        continue

    nsx = zipfile.ZipFile(file)
    config_data = json.loads(nsx.read('config.json').decode('utf-8'))

    for notebook in config_data['notebook']:
        notebook_data = json.loads(nsx.read(notebook).decode('utf-8'))

        if notebook_data['title']:
            notebook_title = notebook_data['title']
        else:
            notebook_title = 'Untitled'

        print('Converting notebook "{}"'.format(notebook_title))

        if os.path.isdir(notebook_title):
            notebook_title = str(round(time.time())) + '-' + notebook_title

        os.makedirs(notebook_title + '/' + media_dir)

        for note in config_data['note']:
            note_data = json.loads(nsx.read(note).decode('utf-8'))
            note_title = note_data['title']

            if note_data['parent_id'] != notebook:
                continue

            content = re.sub(']*ref="',
                             '<img src="', note_data.get('content', ''))

            pandoc = subprocess.Popen(pandoc_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
            content = pandoc.communicate(input=content.encode('utf-8'))[0].decode('utf-8')

            attachment_list = []

            for attachment in note_data.get('attachment', ''):

                ref = note_data['attachment'][attachment].get('ref', '')
                md5 = note_data['attachment'][attachment]['md5']
                name = note_data['attachment'][attachment]['name']

                try:
                    nsx.extract('file_' + md5, notebook_title + '/' + media_dir)
                except Exception:
                    print('  Can\'t find attachment "{}" of note "{}"'.format(name, note_title))
                    attachment_list.append('[NOT FOUND]([{}{}/{})'.format(link_prepend, media_dir, name))
                else:
                    if os.path.isfile('{}/{}/{}'.format(notebook_title, media_dir, name)):
                        name = str(round(time.time())) + '-' + name

                    os.rename('{}/{}/file_{}'.format(notebook_title, media_dir, md5),
                              '{}/{}/{}'.format(notebook_title, media_dir, name))
                    attachment_list.append('[{}]([{}{}/{})'.format(name, link_prepend, media_dir, name))

                if ref:
                    content = content.replace(ref, '{}{}/{}'.format(link_prepend, media_dir, name))

            if note_data.get('tag', '') or attachment_list or insert_title:
                content = '\n' + content

            if attachment_list:
                content = 'Attachments: {}  \n{}'.format(' '.join(attachment_list), content)
            if note_data.get('tag', ''):
                content = 'Tags: {}  \n{}'.format(', '.join(note_data['tag']), content)
            if insert_title:
                content = note_title + '\n' + ('=' * len(note_title)) + '\n' + content

            if platform.system() == 'Linux' and not force_windows_filename_limitations:
                md_file_name = note_title.replace('/', '-')
            elif platform.system() == 'Darwin' and not force_windows_filename_limitations:
                md_file_name = note_title.replace('/', '-').replace(':', '-')
            else:
                md_file_name = note_title
                for char in (':', '/', '\\', '|'):
                    md_file_name = md_file_name.replace(char, '-')
                for char in ('?', '*'):
                    md_file_name = md_file_name.replace(char, '')
                md_file_name = md_file_name.replace('<', '(')
                md_file_name = md_file_name.replace('>', ')')
                md_file_name = md_file_name.replace('"', "'")

            if note_title != md_file_name:
                print('  Note "{}" saved as "{}.{}" for compatibility with your OS'.format(note_title, md_file_name, md_file_ext))

            with open('{}/{}.{}'.format(notebook_title, md_file_name, md_file_ext), 'w') as md_note:
                md_note.write(content)

        try:
            os.rmdir(notebook_title + '/' + media_dir)
        except OSError:
            pass

input('Conversion finished. Press Enter to quit...')
<commit_msg>Fixed console bugs, added time stamps<commit_after>#!/usr/bin/env python

import os
import re
import sys
import time
import json
import shutil
import zipfile
import tempfile
import platform
import subprocess
import distutils.version

# You can adjust some setting here. Default is for QOwnNotes app.
link_prepend = 'file://'
media_dir = 'media'
md_file_ext = 'md'
insert_title = True
insert_ctime = False
insert_mtime = False
force_windows_filename_limitations = False

input_file = tempfile.NamedTemporaryFile(delete=False)
output_file = tempfile.NamedTemporaryFile(delete=False)

if not shutil.which('pandoc') and not os.path.isfile('pandoc'):
    print('Can\'t find pandoc. Please install pandoc or place it to the directory, where the script is.')
    exit()

try:
    pandoc_ver = subprocess.check_output(['pandoc', '-v'], timeout=3).decode('utf-8')[7:].split('\n', 1)[0]
    print('Found pandoc ' + pandoc_ver)
except Exception:
    pandoc_ver = '1.19.2.1'

if distutils.version.LooseVersion(pandoc_ver) < distutils.version.LooseVersion('1.16'):
    pandoc_args = ['pandoc', '-f', 'html', '-t', 'markdown_strict+pipe_tables-raw_html', '--no-wrap',
                   '-o', output_file.name, input_file.name]
elif distutils.version.LooseVersion(pandoc_ver) < distutils.version.LooseVersion('1.19'):
    pandoc_args = ['pandoc', '-f', 'html', '-t', 'markdown_strict+pipe_tables-raw_html', '--wrap=none',
                   '-o', output_file.name, input_file.name]
else:
    pandoc_args = ['pandoc', '-f', 'html', '-t', 'markdown_strict+pipe_tables-raw_html', '--wrap=none', '--atx-headers',
                   '-o', output_file.name, input_file.name]

if len(sys.argv) > 1:
    files = sys.argv[1:]
else:
    files = os.listdir()

for file in files:
    if not file.endswith('.nsx'):
        continue

    nsx = zipfile.ZipFile(file)
    config_data = json.loads(nsx.read('config.json').decode('utf-8'))

    for notebook in config_data['notebook']:
        notebook_data = json.loads(nsx.read(notebook).decode('utf-8'))

        if notebook_data['title']:
            notebook_title = notebook_data['title']
        else:
            notebook_title = 'Untitled'

        print('Converting notebook "{}"'.format(notebook_title))

        if os.path.isdir(notebook_title):
            notebook_title = str(round(time.time())) + '-' + notebook_title

        os.makedirs(notebook_title + os.sep + media_dir)

        for note in config_data['note']:
            note_data = json.loads(nsx.read(note).decode('utf-8'))
            note_title = note_data['title']
            note_ctime = note_data.get('ctime', '')
            note_mtime = note_data.get('mtime', '')

            if note_data['parent_id'] != notebook:
                continue

            content = re.sub(']*ref="',
                             '<img src="', note_data.get('content', ''))

            with open(input_file.name, 'w') as input_text:
                input_text.write(content)

            pandoc = subprocess.Popen(pandoc_args)
            pandoc.wait(5)

            with open(output_file.name, 'r') as output_text:
                content = output_text.read()

            attachment_list = []

            for attachment in note_data.get('attachment', ''):

                ref = note_data['attachment'][attachment].get('ref', '')
                md5 = note_data['attachment'][attachment]['md5']
                name = note_data['attachment'][attachment]['name']

                try:
                    nsx.extract('file_' + md5, notebook_title + os.sep + media_dir)
                except Exception:
                    print('  Can\'t find attachment "{}" of note "{}"'.format(name, note_title))
                    attachment_list.append('[NOT FOUND]([{}{}/{})'.format(link_prepend, media_dir, name))
                else:
                    if os.path.isfile('{}/{}/{}'.format(notebook_title, media_dir, name)):
                        name = str(round(time.time())) + '-' + name

                    os.rename('{}/{}/file_{}'.format(notebook_title, media_dir, md5),
                              '{}/{}/{}'.format(notebook_title, media_dir, name))
                    attachment_list.append('[{}]([{}{}/{})'.format(name, link_prepend, media_dir, name))

                if ref:
                    content = content.replace(ref, '{}{}/{}'.format(link_prepend, media_dir, name))

            if note_data.get('tag', '') or attachment_list or insert_title or insert_ctime or insert_mtime:
                content = '\n' + content

            if insert_mtime and note_mtime:
                text_mtime = time.strftime('%Y-%m-%d %H:%M', time.localtime(note_mtime))
                content = 'Modified: {}  \n{}'.format(text_mtime, content)
            if insert_ctime and note_ctime:
                text_ctime = time.strftime('%Y-%m-%d %H:%M', time.localtime(note_mtime))
                content = 'Created: {}  \n{}'.format(text_ctime, content)
            if attachment_list:
                content = 'Attachments: {}  \n{}'.format(' '.join(attachment_list), content)
            if note_data.get('tag', ''):
                content = 'Tags: {}  \n{}'.format(', '.join(note_data['tag']), content)
            if insert_title:
                content = note_title + '\n' + ('=' * len(note_title)) + '\n' + content

            if platform.system() == 'Linux' and not force_windows_filename_limitations:
                md_file_name = note_title.replace('/', '-')
            elif platform.system() == 'Darwin' and not force_windows_filename_limitations:
                md_file_name = note_title.replace('/', '-').replace(':', '-')
            else:
                md_file_name = note_title
                for char in (':', '/', '\\', '|'):
                    md_file_name = md_file_name.replace(char, '-')
                for char in ('?', '*'):
                    md_file_name = md_file_name.replace(char, '')
                md_file_name = md_file_name.replace('<', '(')
                md_file_name = md_file_name.replace('>', ')')
                md_file_name = md_file_name.replace('"', "'")

            if note_title != md_file_name:
                print('  Note "{}" saved as "{}.{}" for compatibility with your OS'.format(note_title, md_file_name, md_file_ext))

            with open('{}/{}.{}'.format(notebook_title, md_file_name, md_file_ext), 'w') as md_note:
                md_note.write(content)

        try:
            os.rmdir(notebook_title + os.sep + media_dir)
        except OSError:
            pass

input_file.close()
output_file.close()
os.unlink(input_file.name)
os.unlink(output_file.name)

input('Conversion finished. Press Enter to quit...')
<|endoftext|>


<commit_before>#!/usr/bin/env python

import os
import re
import sys
import time
import json
import shutil
import zipfile
import tempfile
import platform
import subprocess
import distutils.version

# You can adjust some setting here. Default is for QOwnNotes app.
link_prepend = 'file://'
media_dir = 'media'
md_file_ext = 'md'
insert_title = True
insert_ctime = False
insert_mtime = False
creation_date_in_filename = False
force_windows_filename_limitations = False

if not shutil.which('pandoc') and not os.path.isfile('pandoc'):
    print('Can\'t find pandoc. Please install pandoc or place it to the directory, where the script is.')
    exit()

input_file = tempfile.NamedTemporaryFile(delete=False)
output_file = tempfile.NamedTemporaryFile(delete=False)

try:
    pandoc_ver = subprocess.check_output(['pandoc', '-v'], timeout=3).decode('utf-8')[7:].split('\n', 1)[0]
    print('Found pandoc ' + pandoc_ver)
except Exception:
    pandoc_ver = '1.19.2.1'

if distutils.version.LooseVersion(pandoc_ver) < distutils.version.LooseVersion('1.16'):
    pandoc_args = ['pandoc', '-f', 'html', '-t', 'markdown_strict+pipe_tables-raw_html', '--no-wrap',
                   '-o', output_file.name, input_file.name]
elif distutils.version.LooseVersion(pandoc_ver) < distutils.version.LooseVersion('1.19'):
    pandoc_args = ['pandoc', '-f', 'html', '-t', 'markdown_strict+pipe_tables-raw_html', '--wrap=none',
                   '-o', output_file.name, input_file.name]
else:
    pandoc_args = ['pandoc', '-f', 'html', '-t', 'markdown_strict+pipe_tables-raw_html', '--wrap=none', '--atx-headers',
                   '-o', output_file.name, input_file.name]

if len(sys.argv) > 1:
    files = sys.argv[1:]
else:
    files = os.listdir()

for file in files:
    if not file.endswith('.nsx'):
        continue

    nsx = zipfile.ZipFile(file)
    config_data = json.loads(nsx.read('config.json').decode('utf-8'))

    for notebook in config_data['notebook']:
        notebook_data = json.loads(nsx.read(notebook).decode('utf-8'))

        if notebook_data['title']:
            notebook_title = notebook_data['title']
        else:
            notebook_title = 'Untitled'

        print('Converting notebook "{}"'.format(notebook_title))

        if os.path.isdir(notebook_title):
            notebook_title = str(round(time.time())) + '-' + notebook_title

        os.makedirs(notebook_title + os.sep + media_dir)

        for note in config_data['note']:
            note_data = json.loads(nsx.read(note).decode('utf-8'))
            note_title = note_data['title']
            note_ctime = note_data.get('ctime', '')
            note_mtime = note_data.get('mtime', '')

            if note_data['parent_id'] != notebook:
                continue

            content = re.sub(']*ref="',
                             '<img src="', note_data.get('content', ''))

            with open(input_file.name, 'w') as input_text:
                input_text.write(content)

            pandoc = subprocess.Popen(pandoc_args)
            pandoc.wait(5)

            with open(output_file.name, 'r') as output_text:
                content = output_text.read()

            attachment_list = []

            for attachment in note_data.get('attachment', ''):

                ref = note_data['attachment'][attachment].get('ref', '')
                md5 = note_data['attachment'][attachment]['md5']
                name = note_data['attachment'][attachment]['name']

                try:
                    nsx.extract('file_' + md5, notebook_title + os.sep + media_dir)
                except Exception:
                    print('  Can\'t find attachment "{}" of note "{}"'.format(name, note_title))
                    attachment_list.append('[NOT FOUND]([{}{}/{})'.format(link_prepend, media_dir, name))
                else:
                    if os.path.isfile('{}/{}/{}'.format(notebook_title, media_dir, name)):
                        name = str(round(time.time())) + '-' + name

                    os.rename('{}/{}/file_{}'.format(notebook_title, media_dir, md5),
                              '{}/{}/{}'.format(notebook_title, media_dir, name))
                    attachment_list.append('[{}]([{}{}/{})'.format(name, link_prepend, media_dir, name))

                if ref:
                    content = content.replace(ref, '{}{}/{}'.format(link_prepend, media_dir, name))

            if note_data.get('tag', '') or attachment_list or insert_title or insert_ctime or insert_mtime:
                content = '\n' + content

            if insert_mtime and note_mtime:
                text_mtime = time.strftime('%Y-%m-%d %H:%M', time.localtime(note_mtime))
                content = 'Modified: {}  \n{}'.format(text_mtime, content)
            if insert_ctime and note_ctime:
                text_ctime = time.strftime('%Y-%m-%d %H:%M', time.localtime(note_ctime))
                content = 'Created: {}  \n{}'.format(text_ctime, content)
            if attachment_list:
                content = 'Attachments: {}  \n{}'.format(' '.join(attachment_list), content)
            if note_data.get('tag', ''):
                content = 'Tags: {}  \n{}'.format(', '.join(note_data['tag']), content)
            if insert_title:
                content = note_title + '\n' + ('=' * len(note_title)) + '\n' + content

            if creation_date_in_filename and note_ctime:
                note_title = time.strftime('%Y-%m-%d ', time.localtime(note_ctime)) + note_title

            if platform.system() == 'Linux' and not force_windows_filename_limitations:
                md_file_name = note_title.replace('/', '-')
            elif platform.system() == 'Darwin' and not force_windows_filename_limitations:
                md_file_name = note_title.replace('/', '-').replace(':', '-')
            else:
                md_file_name = note_title
                for char in (':', '/', '\\', '|'):
                    md_file_name = md_file_name.replace(char, '-')
                for char in ('?', '*'):
                    md_file_name = md_file_name.replace(char, '')
                md_file_name = md_file_name.replace('<', '(')
                md_file_name = md_file_name.replace('>', ')')
                md_file_name = md_file_name.replace('"', "'")

            if note_title != md_file_name:
                print('  Note "{}" saved as "{}.{}" for compatibility with your OS'.format(note_title, md_file_name, md_file_ext))

            with open('{}/{}.{}'.format(notebook_title, md_file_name, md_file_ext), 'w') as md_note:
                md_note.write(content)

        try:
            os.rmdir(notebook_title + os.sep + media_dir)
        except OSError:
            pass

input_file.close()
output_file.close()
os.unlink(input_file.name)
os.unlink(output_file.name)

input('Conversion finished. Press Enter to quit...')
<commit_msg>Fix UnicodeDecodeError when notes contains latin charmap<commit_after>#!/usr/bin/env python

import os
import re
import sys
import time
import json
import shutil
import zipfile
import tempfile
import platform
import subprocess
import distutils.version

# You can adjust some setting here. Default is for QOwnNotes app.
link_prepend = 'file://'
media_dir = 'media'
md_file_ext = 'md'
insert_title = True
insert_ctime = False
insert_mtime = False
creation_date_in_filename = False
force_windows_filename_limitations = False

if not shutil.which('pandoc') and not os.path.isfile('pandoc'):
    print('Can\'t find pandoc. Please install pandoc or place it to the directory, where the script is.')
    exit()

input_file = tempfile.NamedTemporaryFile(delete=False)
output_file = tempfile.NamedTemporaryFile(delete=False)

try:
    pandoc_ver = subprocess.check_output(['pandoc', '-v'], timeout=3).decode('utf-8')[7:].split('\n', 1)[0]
    print('Found pandoc ' + pandoc_ver)
except Exception:
    pandoc_ver = '1.19.2.1'

if distutils.version.LooseVersion(pandoc_ver) < distutils.version.LooseVersion('1.16'):
    pandoc_args = ['pandoc', '-f', 'html', '-t', 'markdown_strict+pipe_tables-raw_html', '--no-wrap',
                   '-o', output_file.name, input_file.name]
elif distutils.version.LooseVersion(pandoc_ver) < distutils.version.LooseVersion('1.19'):
    pandoc_args = ['pandoc', '-f', 'html', '-t', 'markdown_strict+pipe_tables-raw_html', '--wrap=none',
                   '-o', output_file.name, input_file.name]
else:
    pandoc_args = ['pandoc', '-f', 'html', '-t', 'markdown_strict+pipe_tables-raw_html', '--wrap=none', '--atx-headers',
                   '-o', output_file.name, input_file.name]

if len(sys.argv) > 1:
    files = sys.argv[1:]
else:
    files = os.listdir()

for file in files:
    if not file.endswith('.nsx'):
        continue

    nsx = zipfile.ZipFile(file)
    config_data = json.loads(nsx.read('config.json').decode('utf-8'))

    for notebook in config_data['notebook']:
        notebook_data = json.loads(nsx.read(notebook).decode('utf-8'))

        if notebook_data['title']:
            notebook_title = notebook_data['title']
        else:
            notebook_title = 'Untitled'

        print('Converting notebook "{}"'.format(notebook_title))

        if os.path.isdir(notebook_title):
            notebook_title = str(round(time.time())) + '-' + notebook_title

        os.makedirs(notebook_title + os.sep + media_dir)

        for note in config_data['note']:
            note_data = json.loads(nsx.read(note).decode('utf-8'))
            note_title = note_data['title']
            note_ctime = note_data.get('ctime', '')
            note_mtime = note_data.get('mtime', '')

            if note_data['parent_id'] != notebook:
                continue

            content = re.sub(']*ref="',
                             '<img src="', note_data.get('content', ''))

            with open(input_file.name, 'w', encoding='utf8') as input_text:
                input_text.write(content)

            pandoc = subprocess.Popen(pandoc_args)
            pandoc.wait(5)

            with open(output_file.name, 'r', encoding='utf8') as output_text:
                content = output_text.read()

            attachment_list = []

            for attachment in note_data.get('attachment', ''):

                ref = note_data['attachment'][attachment].get('ref', '')
                md5 = note_data['attachment'][attachment]['md5']
                name = note_data['attachment'][attachment]['name']

                try:
                    nsx.extract('file_' + md5, notebook_title + os.sep + media_dir)
                except Exception:
                    print('  Can\'t find attachment "{}" of note "{}"'.format(name, note_title))
                    attachment_list.append('[NOT FOUND]([{}{}/{})'.format(link_prepend, media_dir, name))
                else:
                    if os.path.isfile('{}/{}/{}'.format(notebook_title, media_dir, name)):
                        name = str(round(time.time())) + '-' + name

                    os.rename('{}/{}/file_{}'.format(notebook_title, media_dir, md5),
                              '{}/{}/{}'.format(notebook_title, media_dir, name))
                    attachment_list.append('[{}]([{}{}/{})'.format(name, link_prepend, media_dir, name))

                if ref:
                    content = content.replace(ref, '{}{}/{}'.format(link_prepend, media_dir, name))

            if note_data.get('tag', '') or attachment_list or insert_title or insert_ctime or insert_mtime:
                content = '\n' + content

            if insert_mtime and note_mtime:
                text_mtime = time.strftime('%Y-%m-%d %H:%M', time.localtime(note_mtime))
                content = 'Modified: {}  \n{}'.format(text_mtime, content)
            if insert_ctime and note_ctime:
                text_ctime = time.strftime('%Y-%m-%d %H:%M', time.localtime(note_ctime))
                content = 'Created: {}  \n{}'.format(text_ctime, content)
            if attachment_list:
                content = 'Attachments: {}  \n{}'.format(' '.join(attachment_list), content)
            if note_data.get('tag', ''):
                content = 'Tags: {}  \n{}'.format(', '.join(note_data['tag']), content)
            if insert_title:
                content = note_title + '\n' + ('=' * len(note_title)) + '\n' + content

            if creation_date_in_filename and note_ctime:
                note_title = time.strftime('%Y-%m-%d ', time.localtime(note_ctime)) + note_title

            if platform.system() == 'Linux' and not force_windows_filename_limitations:
                md_file_name = note_title.replace('/', '-')
            elif platform.system() == 'Darwin' and not force_windows_filename_limitations:
                md_file_name = note_title.replace('/', '-').replace(':', '-')
            else:
                md_file_name = note_title
                for char in (':', '/', '\\', '|'):
                    md_file_name = md_file_name.replace(char, '-')
                for char in ('?', '*'):
                    md_file_name = md_file_name.replace(char, '')
                md_file_name = md_file_name.replace('<', '(')
                md_file_name = md_file_name.replace('>', ')')
                md_file_name = md_file_name.replace('"', "'")

            if note_title != md_file_name:
                print('  Note "{}" saved as "{}.{}" for compatibility with your OS'.format(note_title, md_file_name, md_file_ext))

            with open('{}/{}.{}'.format(notebook_title, md_file_name, md_file_ext), 'w', encoding='utf8') as md_note:
                md_note.write(content)

        try:
            os.rmdir(notebook_title + os.sep + media_dir)
        except OSError:
            pass

input_file.close()
output_file.close()
os.unlink(input_file.name)
os.unlink(output_file.name)

input('Conversion finished. Press Enter to quit...')
<|endoftext|>


<commit_before># Copyright (C) 2010 Google Inc.
#
# 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.
from apiclient.discovery import build
from apiclient.oauth import FlowThreeLegged

import datetime
import httplib2
import logging
import oauth_wrap
import optparse
import os
import sys

def load_properties_file(path):
  properties = {}
  for line in open(path):
    line = line.strip()
    if line.startswith('#'):
      continue

    key,value = line.split('=')
    properties[key.strip()] = value.strip()
  return properties

def save_properties(consumer_key, consumer_secret, token_key, token_secret, path):
  file = open(path, 'w')

  # File format and order is based on oacurl.java's defaults
  now = datetime.datetime.today()
  now_string = now.strftime('%a %b %d %H:%m:%S %Z %Y')
  file.write('#%s\n' % now_string)
  file.write('consumerSecret=%s\n' % consumer_secret)
  file.write('accessToken=%s\n' % token_key)
  file.write('consumerKey=%s\n' % consumer_key)
  file.write('accessTokenSecret=%s\n' % token_secret)
  file.close()

def fetch(url):
  logging.debug('Now fetching: %s' % url)

  path = os.path.expanduser('~/.oacurl.properties')
  if not os.path.exists(path):
    logging.debug('User is not logged in.')

    print 'You are not logged in'
    sys.exit(1)

  properties = load_properties_file(path)
  oauth_parameters = {
    'consumer_key': properties['consumerKey'],
    'consumer_secret' : properties['consumerSecret'],
    'oauth_token' : properties['accessToken'],
    'oauth_token_secret':properties['accessTokenSecret']}

  http = oauth_wrap.get_authorised_http(oauth_parameters)
  response, content = http.request(url)
  logging.debug(response)
  logging.debug(content)

  return response,content

def buzz_login():
  buzz_discovery = build("buzz", "v1").auth_discovery()

  flow = FlowThreeLegged(buzz_discovery,
                         consumer_key='anonymous',
                         consumer_secret='anonymous',
                         user_agent='google-api-client-python-buzz-cmdline/1.0',
                         domain='anonymous',
                         scope='https://www.googleapis.com/auth/buzz',
                         xoauth_displayname='oacurl.py')

  authorize_url = flow.step1_get_authorize_url()

  print 'Go to the following link in your browser:'
  print authorize_url
  print

  accepted = 'n'
  while accepted.lower() == 'n':
      accepted = raw_input('Have you authorized me? (y/n) ')
  verification = raw_input('What is the verification code? ').strip()

  credentials = flow.step2_exchange(verification)
  path = os.path.expanduser('~/.oacurl.properties')
  save_properties('anonymous', 'anonymous', credentials.token.key, credentials.token.secret,path)

def generic_login():
  #TODO(ade) Implement support for other services
  print 'Support for services other than Buzz is not implemented yet. Sorry.'

def login(options):
  if options.buzz:
    buzz_login()
  else:
    generic_login()

def get_command(args):
  if args and args[0] == 'login':
    return 'login'
  if args and args[0] == 'fetch':
    return 'fetch'
  return None

def configure_logging(options):
  if options.verbose:
    logging.basicConfig(level=logging.DEBUG)

def main():
  usage = '''Usage: %prog [options] fetch <url>
  Example: %prog -v fetch "https://www.googleapis.com/buzz/v1/people/@me/@self?alt=json&pp=1"
  '''
  parser = optparse.OptionParser(usage=usage)
  parser.set_defaults(verbose=False)
  parser.add_option('-v', '--verbose', action='store_true', dest='verbose')
  parser.add_option('-q', '--quiet', action='store_false', dest='verbose')
  parser.add_option('--buzz', action='store_true', dest='buzz')

  (options, args) = parser.parse_args()

  configure_logging(options)
  logging.debug('Options: %s and Args: %s' % (str(options), str(args)))

  command = get_command(args)

  if not command:
    parser.error('Invalid arguments')
    return

  if command == 'fetch':
    response, content = fetch(args[1])
    print response
    print content
    return

  if command == 'login':
    login(options)

if __name__ == '__main__':
  main()<commit_msg>Updated the useage instructions to mention that you need to use the python interpreter to run it<commit_after># Copyright (C) 2010 Google Inc.
#
# 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.
from apiclient.discovery import build
from apiclient.oauth import FlowThreeLegged

import datetime
import httplib2
import logging
import oauth_wrap
import optparse
import os
import sys

def load_properties_file(path):
  properties = {}
  for line in open(path):
    line = line.strip()
    if line.startswith('#'):
      continue

    key,value = line.split('=')
    properties[key.strip()] = value.strip()
  return properties

def save_properties(consumer_key, consumer_secret, token_key, token_secret, path):
  file = open(path, 'w')

  # File format and order is based on oacurl.java's defaults
  now = datetime.datetime.today()
  now_string = now.strftime('%a %b %d %H:%m:%S %Z %Y')
  file.write('#%s\n' % now_string)
  file.write('consumerSecret=%s\n' % consumer_secret)
  file.write('accessToken=%s\n' % token_key)
  file.write('consumerKey=%s\n' % consumer_key)
  file.write('accessTokenSecret=%s\n' % token_secret)
  file.close()

def fetch(url):
  logging.debug('Now fetching: %s' % url)

  path = os.path.expanduser('~/.oacurl.properties')
  if not os.path.exists(path):
    logging.debug('User is not logged in.')

    print 'You are not logged in'
    sys.exit(1)

  properties = load_properties_file(path)
  oauth_parameters = {
    'consumer_key': properties['consumerKey'],
    'consumer_secret' : properties['consumerSecret'],
    'oauth_token' : properties['accessToken'],
    'oauth_token_secret':properties['accessTokenSecret']}

  http = oauth_wrap.get_authorised_http(oauth_parameters)
  response, content = http.request(url)
  logging.debug(response)
  logging.debug(content)

  return response,content

def buzz_login():
  buzz_discovery = build("buzz", "v1").auth_discovery()

  flow = FlowThreeLegged(buzz_discovery,
                         consumer_key='anonymous',
                         consumer_secret='anonymous',
                         user_agent='google-api-client-python-buzz-cmdline/1.0',
                         domain='anonymous',
                         scope='https://www.googleapis.com/auth/buzz',
                         xoauth_displayname='oacurl.py')

  authorize_url = flow.step1_get_authorize_url()

  print 'Go to the following link in your browser:'
  print authorize_url
  print

  accepted = 'n'
  while accepted.lower() == 'n':
      accepted = raw_input('Have you authorized me? (y/n) ')
  verification = raw_input('What is the verification code? ').strip()

  credentials = flow.step2_exchange(verification)
  path = os.path.expanduser('~/.oacurl.properties')
  save_properties('anonymous', 'anonymous', credentials.token.key, credentials.token.secret,path)

def generic_login():
  #TODO(ade) Implement support for other services
  print 'Support for services other than Buzz is not implemented yet. Sorry.'

def login(options):
  if options.buzz:
    buzz_login()
  else:
    generic_login()

def get_command(args):
  if args and args[0] == 'login':
    return 'login'
  if args and args[0] == 'fetch':
    return 'fetch'
  return None

def configure_logging(options):
  if options.verbose:
    logging.basicConfig(level=logging.DEBUG)

def main():
  usage = '''Usage: python %prog [options] fetch <url>
  Example: python %prog -v fetch "https://www.googleapis.com/buzz/v1/people/@me/@self?alt=json&pp=1"
  '''
  parser = optparse.OptionParser(usage=usage)
  parser.set_defaults(verbose=False)
  parser.add_option('-v', '--verbose', action='store_true', dest='verbose')
  parser.add_option('-q', '--quiet', action='store_false', dest='verbose')
  parser.add_option('--buzz', action='store_true', dest='buzz')

  (options, args) = parser.parse_args()

  configure_logging(options)
  logging.debug('Options: %s and Args: %s' % (str(options), str(args)))

  command = get_command(args)

  if not command:
    parser.error('Invalid arguments')
    return

  if command == 'fetch':
    response, content = fetch(args[1])
    print response
    print content
    return

  if command == 'login':
    login(options)

if __name__ == '__main__':
  main()<|endoftext|>


<commit_before>import datetime
import logging
from email.utils import parseaddr

from django.contrib.auth.models import User
from django.contrib.sites.models import Site
from django.conf import settings
from django.core.cache import cache
from django.core.mail import EmailMultiAlternatives
from django.template.loader import get_template
from django.utils import timezone

import contacts as contact_settings
from contacts.models import (
    Book,
    Contact,
    ContactField,
    LogEntry,
)
from .utils import pull_google_contacts

sentry = logging.getLogger("sentry")

def import_google_contacts(message):
    try:
        user = User.objects.get(id=message.get('user_id'))
        book = Book.objects.get(bookowner__user=user, id=message.get('book_id'))
    except Book.DoesNotExist:
        sentry.error("Bad book passed to google import job", exc_info=True)
        return
    except User.DoesNotExist:
        sentry.error("Bad user passed to google import job", exc_info=True)
        return
    try:
        success = pull_google_contacts(user=user, book=book)
        success = True
        if success:
            cache.delete("{}::google-import".format(user))
            try:
                context = {
                    'domain': Site.objects.get_current().domain,
                }
                txt = get_template('email/google_import_done.txt').render(context)
                html = get_template('email/google_import_done.html').render(context)
                message = EmailMultiAlternatives(
                    subject='Contact import finished!',
                    body=txt,
                    from_email="ContactOtter <import@contactotter.com>",
                    to=[user.email],
                    headers={
                        'Reply-To': "ContactOtter <support@contactotter.com>",
                    },
                )
                message.attach_alternative(html, "text/html")
                message.send()
            except:
                sentry.error("Error sending import success email", exc_info=True)
    except:
        cache.set("{}::google-import".format(user), "error", 86400)

def process_incoming_email(message):
    _, sender = parseaddr(message.get('sender', ''))
    _, recipient = parseaddr(message.get('recipient', ''))

    try:
        user = User.objects.get(email=sender)
    except User.DoesNotExist:
        pass

    try:
        book_id = recipient.split('@')[0].split('-')[1]
        book = Book.objects.filter_for_user(user).get(id=book_id)
    except (Book.DoesNotExist, IndexError):
        pass

    if not (user and book):
        return

    to = message.get('To', '').split(',')
    to += (message.get('Cc', '').split(','))
    to += (message.get('Bcc', '').split(','))
    for item in set(to):
        name, email = parseaddr(item)
        if email and email != recipient:
            try:
                contact = ContactField.objects.filter(
                    kind=contact_settings.FIELD_TYPE_EMAIL,
                    value=email,
                    contact__book=book,
                )[0].contact
            except (ContactField.DoesNotExist, IndexError):
                if not name:
                    name = email
                contact = Contact.objects.create(
                    name=name,
                    book=book,
                )
                ContactField.objects.create(
                    contact=contact,
                    kind=contact_settings.FIELD_TYPE_EMAIL,
                    value=email,
                    label="Email",
                    preferred=True,
                )
            LogEntry.objects.create(
                contact=contact,
                kind='email',
                logged_by=user,
                time=timezone.now(),
                notes='Subject: {}'.format(message.get('subject')),
            )

<commit_msg>See if a simple change fixes things<commit_after>import datetime
import logging
from email.utils import parseaddr

from django.contrib.auth.models import User
from django.contrib.sites.models import Site
from django.conf import settings
from django.core.cache import cache
from django.core.mail import EmailMultiAlternatives
from django.template.loader import get_template
from django.utils import timezone

import contacts as contact_settings
from contacts.models import (
    Book,
    Contact,
    ContactField,
    LogEntry,
)
from .utils import pull_google_contacts

sentry = logging.getLogger("sentry")

def import_google_contacts(message):
    try:
        user = User.objects.get(id=message.get('user_id'))
        book = Book.objects.get(bookowner__user=user, id=message.get('book_id'))
    except Book.DoesNotExist:
        sentry.error("Bad book passed to google import job", exc_info=True)
        return
    except User.DoesNotExist:
        sentry.error("Bad user passed to google import job", exc_info=True)
        return
    try:
        success = pull_google_contacts(user=user, book=book)
        success = True
        if success:
            cache.delete("{}::google-import".format(user))
            try:
                context = {
                    'domain': Site.objects.get_current().domain,
                }
                txt = get_template('email/google_import_done.txt').render(context)
                html = get_template('email/google_import_done.html').render(context)
                message = EmailMultiAlternatives(
                    subject='Contact import finished!',
                    body=txt,
                    from_email="ContactOtter <import@contactotter.com>",
                    to=[user.email],
                    headers={
                        'Reply-To': "ContactOtter <support@contactotter.com>",
                    },
                )
                message.attach_alternative(html, "text/html")
                message.send()
            except:
                sentry.error("Error sending import success email", exc_info=True)
    except:
        cache.set("{}::google-import".format(user), "error", 86400)

def process_incoming_email(message):
    _, sender = parseaddr(message.get('sender', ''))
    _, recipient = parseaddr(message.get('recipient', ''))

    try:
        user = User.objects.get(email=sender)
    except User.DoesNotExist:
        pass

    try:
        book_id = recipient.split('@')[0].split('-')[-1]
        book = Book.objects.filter_for_user(user).get(id=book_id)
    except (Book.DoesNotExist, IndexError):
        pass

    if not (user and book):
        return

    to = message.get('To', '').split(',')
    to += (message.get('Cc', '').split(','))
    to += (message.get('Bcc', '').split(','))
    for item in set(to):
        name, email = parseaddr(item)
        if email and email != recipient:
            try:
                contact = ContactField.objects.filter(
                    kind=contact_settings.FIELD_TYPE_EMAIL,
                    value=email,
                    contact__book=book,
                )[0].contact
            except (ContactField.DoesNotExist, IndexError):
                if not name:
                    name = email
                contact = Contact.objects.create(
                    name=name,
                    book=book,
                )
                ContactField.objects.create(
                    contact=contact,
                    kind=contact_settings.FIELD_TYPE_EMAIL,
                    value=email,
                    label="Email",
                    preferred=True,
                )
            LogEntry.objects.create(
                contact=contact,
                kind='email',
                logged_by=user,
                time=timezone.now(),
                notes='Subject: {}'.format(message.get('subject')),
            )

<|endoftext|>


<commit_before># This file is part of Indico.
# Copyright (C) 2002 - 2015 European Organization for Nuclear Research (CERN).
#
# Indico is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# Indico is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Indico; if not, see <http://www.gnu.org/licenses/>.

from __future__ import unicode_literals

from datetime import date, timedelta
from HTMLParser import HTMLParser
from operator import attrgetter
from uuid import uuid4

from indico.core.db import db
from indico.modules.events import EventSetting
from indico.modules.events.surveys.models.surveys import Survey
from indico.modules.events.surveys.models.items import SurveyQuestion, SurveySection
from indico.modules.events.surveys.models.submissions import SurveySubmission, SurveyAnswer
from indico.modules.users import User
from indico.util.console import cformat, verbose_iterator
from indico.util.date_time import localize_as_utc
from indico.util.struct.iterables import committing_iterator
from indico.web.flask.templating import strip_tags
from indico_zodbimport import Importer, convert_to_unicode

def _sanitize(title):
    return HTMLParser().unescape(strip_tags(convert_to_unicode(title))).strip()

class SurveyImporter(Importer):
    def has_data(self):
        return Survey.has_rows

    def migrate(self):
        self.migrate_surveys()
        self.update_merged_users(SurveySubmission.user, "survey submissions")

    def migrate_surveys(self):
        self.print_step("Migrating old event evaluations")
        notification_pending = {es.event_id: es.value for es in EventSetting.find_all(module='evaluation',
                                                                                name='send_notification')}
        for event, evaluation in committing_iterator(self._iter_evaluations(), 10):
            survey = self.migrate_survey(evaluation, event)
            if (survey.notifications_enabled and survey.start_notification_emails and
                    not notification_pending.get(survey.event_id)):
                survey.start_notification_sent = True
            db.session.add(survey)

    def migrate_survey(self, evaluation, event):
        survey = Survey(event_id=int(event.id))
        survey.title = _sanitize(evaluation.title) if evaluation.title else "Evaluation"
        survey.introduction = _sanitize(evaluation.announcement)
        if evaluation.contactInfo:
            contact_text = "Contact: ".format(_sanitize(evaluation.contactInfo))
            survey.introduction += "\n\n{}".format(contact_text) if survey.introduction else contact_text
        survey.submission_limit = evaluation.submissionsLimit if evaluation.submissionsLimit else None
        survey.anonymous = evaluation.anonymous
        # Guest users can only submit if survey is not anonymous
        survey.require_user = not survey.anonymous and not evaluation.mandatoryAccount

        if evaluation.startDate.date() == date.min or evaluation.endDate.date() == date.min:
            survey.start_dt = event.endDate
            survey.end_dt = survey.start_dt + timedelta(days=7)
        else:
            survey.start_dt = localize_as_utc(evaluation.startDate, event.tz)
            survey.end_dt = localize_as_utc(evaluation.endDate, event.tz)
        if survey.end_dt < survey.start_dt:
            survey.end_dt = survey.end_dt + timedelta(days=7)

        for kind, notification in evaluation.notifications.iteritems():
            survey.notifications_enabled = True
            recipients = set(notification._toList) | set(notification._ccList)
            if kind == 'evaluationStartNotify':
                survey.start_notification_emails = list(recipients)
            elif kind == 'newSubmissionNotify':
                survey.new_submission_emails = list(recipients)

        self.print_success(cformat('%{cyan}{}%{reset}').format(survey), always=True, event_id=event.id)

        question_map = {}
        section = SurveySection(survey=survey, title='')
        for position, old_question in enumerate(evaluation._questions):
            question = self.migrate_question(old_question, position)
            question_map[old_question] = question
            section.children.append(question)

        for old_submission in evaluation._submissions:
            submission = self.migrate_submission(old_submission, question_map, event.tz)
            survey.submissions.append(submission)

        return survey

    def migrate_question(self, old_question, position):
        question = SurveyQuestion()
        question.position = position
        question.title = _sanitize(old_question.questionValue)
        question.description = _sanitize(old_question.description)
        if old_question.help:
            help_text = _sanitize(old_question.help)
            question.description += "\n\nHelp: {}".format(help_text) if question.description else help_text
        question.is_required = old_question.required
        question.field_data = {}
        class_name = old_question.__class__.__name__
        if class_name == 'Textbox':
            question.field_type = 'text'
        elif class_name == 'Textarea':
            question.field_type = 'text'
            question.field_data['multiline'] = True
        elif class_name == 'Password':
            question.field_type = 'text'
        elif class_name in ('Checkbox', 'Radio', 'Select'):
            question.field_data['options'] = []
            question.field_type = 'single_choice' if class_name in ('Radio', 'Select') else 'multiselect'
            if question.field_type == 'single_choice':
                question.field_data['display_type'] = class_name.lower()
            if class_name == 'Radio':
                question.field_data['radio_display_type'] = 'vertical'
            for option in old_question.choiceItems:
                question.field_data['options'].append({'option': option, 'id': unicode(uuid4())})
        self.print_success(" - Question: {}".format(question.title))
        return question

    def migrate_submission(self, old_submission, question_map, timezone):
        submission = SurveySubmission()
        submitted_dt = old_submission.submissionDate
        submission.submitted_dt = submitted_dt if submitted_dt.tzinfo else localize_as_utc(submitted_dt, timezone)
        if not old_submission.anonymous and old_submission._submitter:
            avatar = old_submission._submitter
            with db.session.no_autoflush:
                submission.user = User.get(int(avatar.id))
        self.print_success(" - Submission from user {}".format(submission.user_id or 'anonymous'))
        for old_answer in old_submission._answers:
            question = question_map[old_answer._question]
            answer = self.migrate_answer(old_answer, question)
            submission.answers.append(answer)
            question.answers.append(answer)
        return submission

    def migrate_answer(self, old_answer, question):
        answer = SurveyAnswer()
        if old_answer.__class__.__name__ == 'MultipleChoicesAnswer':
            answer.data = []
            for option in old_answer._selectedChoiceItems:
                answer.data.append(self._get_option_id(question, option))
        elif old_answer._question.__class__.__name__ in ('Radio', 'Select'):
            if old_answer._answerValue:
                answer.data = self._get_option_id(question, old_answer._answerValue)
        else:
            answer.data = _sanitize(old_answer._answerValue)
        self.print_success("   - Answer: {}".format(answer.data))
        return answer

    def _iter_evaluations(self):
        it = self.zodb_root['conferences'].itervalues()
        if self.quiet:
            it = verbose_iterator(it, len(self.zodb_root['conferences']), attrgetter('id'), attrgetter('title'))
        for event in self.flushing_iterator(it):
            for evaluation in getattr(event, '_evaluations', []):
                if evaluation._questions:
                    yield event, evaluation

    def _get_option_id(self, question, option):
        return next((opt['id'] for opt in question.field_data['options'] if opt['option'] == option), None)
<commit_msg>Skip default survey titles during migration<commit_after># This file is part of Indico.
# Copyright (C) 2002 - 2015 European Organization for Nuclear Research (CERN).
#
# Indico is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# Indico is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Indico; if not, see <http://www.gnu.org/licenses/>.

from __future__ import unicode_literals

from datetime import date, timedelta
from HTMLParser import HTMLParser
from operator import attrgetter
from uuid import uuid4

from indico.core.db import db
from indico.modules.events import EventSetting
from indico.modules.events.surveys.models.surveys import Survey
from indico.modules.events.surveys.models.items import SurveyQuestion, SurveySection
from indico.modules.events.surveys.models.submissions import SurveySubmission, SurveyAnswer
from indico.modules.users import User
from indico.util.console import cformat, verbose_iterator
from indico.util.date_time import localize_as_utc
from indico.util.struct.iterables import committing_iterator
from indico.web.flask.templating import strip_tags
from indico_zodbimport import Importer, convert_to_unicode

def _sanitize(title):
    return HTMLParser().unescape(strip_tags(convert_to_unicode(title))).strip()

class SurveyImporter(Importer):
    def has_data(self):
        return Survey.has_rows

    def migrate(self):
        self.migrate_surveys()
        self.update_merged_users(SurveySubmission.user, "survey submissions")

    def migrate_surveys(self):
        self.print_step("Migrating old event evaluations")
        notification_pending = {es.event_id: es.value for es in EventSetting.find_all(module='evaluation',
                                                                                name='send_notification')}
        for event, evaluation in committing_iterator(self._iter_evaluations(), 10):
            survey = self.migrate_survey(evaluation, event)
            if (survey.notifications_enabled and survey.start_notification_emails and
                    not notification_pending.get(survey.event_id)):
                survey.start_notification_sent = True
            db.session.add(survey)

    def migrate_survey(self, evaluation, event):
        survey = Survey(event_id=int(event.id))
        if evaluation.title and not evaluation.title.startswith('Evaluation for '):
            survey.title = _sanitize(evaluation.title)
        if not survey.title:
            survey.title = "Evaluation"
        survey.introduction = _sanitize(evaluation.announcement)
        if evaluation.contactInfo:
            contact_text = "Contact: ".format(_sanitize(evaluation.contactInfo))
            survey.introduction += "\n\n{}".format(contact_text) if survey.introduction else contact_text
        survey.submission_limit = evaluation.submissionsLimit if evaluation.submissionsLimit else None
        survey.anonymous = evaluation.anonymous
        # Guest users can only submit if survey is not anonymous
        survey.require_user = not survey.anonymous and not evaluation.mandatoryAccount

        if evaluation.startDate.date() == date.min or evaluation.endDate.date() == date.min:
            survey.start_dt = event.endDate
            survey.end_dt = survey.start_dt + timedelta(days=7)
        else:
            survey.start_dt = localize_as_utc(evaluation.startDate, event.tz)
            survey.end_dt = localize_as_utc(evaluation.endDate, event.tz)
        if survey.end_dt < survey.start_dt:
            survey.end_dt = survey.end_dt + timedelta(days=7)

        for kind, notification in evaluation.notifications.iteritems():
            survey.notifications_enabled = True
            recipients = set(notification._toList) | set(notification._ccList)
            if kind == 'evaluationStartNotify':
                survey.start_notification_emails = list(recipients)
            elif kind == 'newSubmissionNotify':
                survey.new_submission_emails = list(recipients)

        self.print_success(cformat('%{cyan}{}%{reset}').format(survey), always=True, event_id=event.id)

        question_map = {}
        section = SurveySection(survey=survey, title='')
        for position, old_question in enumerate(evaluation._questions):
            question = self.migrate_question(old_question, position)
            question_map[old_question] = question
            section.children.append(question)

        for old_submission in evaluation._submissions:
            submission = self.migrate_submission(old_submission, question_map, event.tz)
            survey.submissions.append(submission)

        return survey

    def migrate_question(self, old_question, position):
        question = SurveyQuestion()
        question.position = position
        question.title = _sanitize(old_question.questionValue)
        question.description = _sanitize(old_question.description)
        if old_question.help:
            help_text = _sanitize(old_question.help)
            question.description += "\n\nHelp: {}".format(help_text) if question.description else help_text
        question.is_required = old_question.required
        question.field_data = {}
        class_name = old_question.__class__.__name__
        if class_name == 'Textbox':
            question.field_type = 'text'
        elif class_name == 'Textarea':
            question.field_type = 'text'
            question.field_data['multiline'] = True
        elif class_name == 'Password':
            question.field_type = 'text'
        elif class_name in ('Checkbox', 'Radio', 'Select'):
            question.field_data['options'] = []
            question.field_type = 'single_choice' if class_name in ('Radio', 'Select') else 'multiselect'
            if question.field_type == 'single_choice':
                question.field_data['display_type'] = class_name.lower()
            if class_name == 'Radio':
                question.field_data['radio_display_type'] = 'vertical'
            for option in old_question.choiceItems:
                question.field_data['options'].append({'option': option, 'id': unicode(uuid4())})
        self.print_success(" - Question: {}".format(question.title))
        return question

    def migrate_submission(self, old_submission, question_map, timezone):
        submission = SurveySubmission()
        submitted_dt = old_submission.submissionDate
        submission.submitted_dt = submitted_dt if submitted_dt.tzinfo else localize_as_utc(submitted_dt, timezone)
        if not old_submission.anonymous and old_submission._submitter:
            avatar = old_submission._submitter
            with db.session.no_autoflush:
                submission.user = User.get(int(avatar.id))
        self.print_success(" - Submission from user {}".format(submission.user_id or 'anonymous'))
        for old_answer in old_submission._answers:
            question = question_map[old_answer._question]
            answer = self.migrate_answer(old_answer, question)
            submission.answers.append(answer)
            question.answers.append(answer)
        return submission

    def migrate_answer(self, old_answer, question):
        answer = SurveyAnswer()
        if old_answer.__class__.__name__ == 'MultipleChoicesAnswer':
            answer.data = []
            for option in old_answer._selectedChoiceItems:
                answer.data.append(self._get_option_id(question, option))
        elif old_answer._question.__class__.__name__ in ('Radio', 'Select'):
            if old_answer._answerValue:
                answer.data = self._get_option_id(question, old_answer._answerValue)
        else:
            answer.data = _sanitize(old_answer._answerValue)
        self.print_success("   - Answer: {}".format(answer.data))
        return answer

    def _iter_evaluations(self):
        it = self.zodb_root['conferences'].itervalues()
        if self.quiet:
            it = verbose_iterator(it, len(self.zodb_root['conferences']), attrgetter('id'), attrgetter('title'))
        for event in self.flushing_iterator(it):
            for evaluation in getattr(event, '_evaluations', []):
                if evaluation._questions:
                    yield event, evaluation

    def _get_option_id(self, question, option):
        return next((opt['id'] for opt in question.field_data['options'] if opt['option'] == option), None)
<|endoftext|>


<commit_before>import os

class Sensor(object):
    """
    Take in a root path, and the paths to the input and label files
    Provides a simple interface to accessing temperature data from a sensor

    :param root: root directory of this sensor
    :type root: str

    :param input_path: path to the sensor data file
    :type input_path: str

    :param label_path: path to the label for this sensor
    :type label_path: str
    """
    def __init__(self, root, sid):
        self.root = root
        self.sid = sid

        self.input_path = os.path.join(self.root, "{0}_input".format(self.sid))
        self.label_path = os.path.join(self.root, "{0}_label".format(self.sid))

    @property
    def label(self):
        try:
            with open(self.label_path, 'r') as f:
                label_data = f.read()
        except:
            with open(os.path.join(self.root, "name"), 'r') as f:
                label_data = f.read()
        return label_data.strip()

    @property
    def raw(self):
        with open(self.input_path, 'r') as f:
            temp = float(f.read())
        return temp

    @property
    def tempc(self):
        temp = self.raw
        return temp / 1000.0  # change for millidegrees to degrees

    @property
    def tempf(self):
        return (self.tempc * 1.8) + 32.0

    def __repr__(self):
        return self.label

    @classmethod
    def from_ids(cls, root, ids):
        """
        Take in a list of sensor ids, and the root directory they are in
        then make a list of sensors out of them

        :param root: root directory of these sensors
        :type root: str

        :param ids: list of sensor ids to turn into sensor objs
        :type ids: [str]

        :returns [Sensor]
        """
        sensors = []
        for _id in ids:
            sensors.append(Sensor(root, _id))
        return sensors

def find_sensors():
    """
    Find all temperature sensors on the machine
    """
    locations = [
        '/proc/acpi/thermal_zone',
        '/sys/class/hwmon']
    sensors = []
    for loc in locations:
        for root, dirs, files in os.walk(loc, followlinks=True):
            if 'subsystem' in dirs:
                dirs.remove('subsystem')
            if 'power' in dirs:
                dirs.remove('power')
            if 'driver' in dirs:
                dirs.remove('driver')
            if 'hwmon' in dirs:
                dirs.remove('hwmon')
            if 'device' in dirs and any(map(lambda f: f.startswith('temp'), files)):
                dirs.remove('device')
            temperature_things = filter(lambda f: "temp" in f, files)
            sensor_ids = set(map(
                lambda f: f.split("_")[0], temperature_things))
            sensors.extend(Sensor.from_ids(root, sensor_ids))
    return sensors
<commit_msg>Fix issue when the file names contain "temp"<commit_after>import os

class Sensor(object):
    """
    Take in a root path, and the paths to the input and label files
    Provides a simple interface to accessing temperature data from a sensor

    :param root: root directory of this sensor
    :type root: str

    :param input_path: path to the sensor data file
    :type input_path: str

    :param label_path: path to the label for this sensor
    :type label_path: str
    """
    def __init__(self, root, sid):
        self.root = root
        self.sid = sid

        self.input_path = os.path.join(self.root, "{0}_input".format(self.sid))
        self.label_path = os.path.join(self.root, "{0}_label".format(self.sid))

    @property
    def label(self):
        try:
            with open(self.label_path, 'r') as f:
                label_data = f.read()
        except:
            with open(os.path.join(self.root, "name"), 'r') as f:
                label_data = f.read()
        return label_data.strip()

    @property
    def raw(self):
        with open(self.input_path, 'r') as f:
            temp = float(f.read())
        return temp

    @property
    def tempc(self):
        temp = self.raw
        return temp / 1000.0  # change for millidegrees to degrees

    @property
    def tempf(self):
        return (self.tempc * 1.8) + 32.0

    def __repr__(self):
        return self.label

    @classmethod
    def from_ids(cls, root, ids):
        """
        Take in a list of sensor ids, and the root directory they are in
        then make a list of sensors out of them

        :param root: root directory of these sensors
        :type root: str

        :param ids: list of sensor ids to turn into sensor objs
        :type ids: [str]

        :returns [Sensor]
        """
        sensors = []
        for _id in ids:
            sensors.append(Sensor(root, _id))
        return sensors

def find_sensors():
    """
    Find all temperature sensors on the machine
    """
    locations = [
        '/proc/acpi/thermal_zone',
        '/sys/class/hwmon']
    sensors = []
    for loc in locations:
        for root, dirs, files in os.walk(loc, followlinks=True):
            if 'subsystem' in dirs:
                dirs.remove('subsystem')
            if 'power' in dirs:
                dirs.remove('power')
            if 'driver' in dirs:
                dirs.remove('driver')
            if 'hwmon' in dirs:
                dirs.remove('hwmon')
            if 'device' in dirs and any(map(lambda f: f.startswith('temp'), files)):
                dirs.remove('device')
            temperature_things = filter(lambda f: f.startswith('temp'), files)
            sensor_ids = set(map(
                lambda f: f.split("_")[0], temperature_things))
            sensors.extend(Sensor.from_ids(root, sensor_ids))
    return sensors
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

from . import errors

class Singleton(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class Thermostat(metaclass=Singleton):
    MIN_TEMP = 0
    MAX_TEMP = 35

    def __init__(self):
        self._is_on = False
        self._current_temp = 0.0
        self._user_temp_range = (0.0, 0.0)

    def run(self):
        low, high = self.user_temp_range
        if self.current_temp < low:
            print('Thermostat is heating.')
        elif self.current_temp > high:
            print('Thermostat is cooling.')
        else:
            print('Thermostat is inactive.')

    @classmethod
    def validate_temp(cls, value):
        if value < cls.MIN_TEMP:
            raise errors.TemperatureValidationError('Temperature cannot be below {}'.format(cls.MIN_TEMP))
        if value > cls.MAX_TEMP:
            raise errors.TemperatureValidationError('Temperature cannot be above {}'.format(cls.MAX_TEMP))

    @property
    def is_on(self):
        return self._is_on

    @property
    def current_temp(self):
        return self._current_temp

    @current_temp.setter
    def current_temp(self, value):
        self.validate_temp(value)
        self._current_temp = value

    @property
    def user_temp_range(self):
        return self._user_temp_range

    @user_temp_range.setter
    def user_temp_range(self, temp_range):
        low, high = temp_range
        if high < low:
            raise errors.TemperatureValidationError('Invalid range.')
        self.validate_temp(low)
        self.validate_temp(high)
        self._user_temp_range = temp_range
<commit_msg>Test Flake8 violation<commit_after># -*- coding: utf-8 -*-

from . import errors

class Singleton( type ):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class Thermostat(metaclass=Singleton):
    MIN_TEMP = 0
    MAX_TEMP = 35

    def __init__(self):
        self._is_on = False
        self._current_temp = 0.0
        self._user_temp_range = (0.0, 0.0)

    def run(self):
        low, high = self.user_temp_range
        if self.current_temp < low:
            print('Thermostat is heating.')
        elif self.current_temp > high:
            print('Thermostat is cooling.')
        else:
            print('Thermostat is inactive.')

    @classmethod
    def validate_temp(cls, value):
        if value < cls.MIN_TEMP:
            raise errors.TemperatureValidationError('Temperature cannot be below {}'.format(cls.MIN_TEMP))
        if value > cls.MAX_TEMP:
            raise errors.TemperatureValidationError('Temperature cannot be above {}'.format(cls.MAX_TEMP))

    @property
    def is_on(self):
        return self._is_on

    @property
    def current_temp(self):
        return self._current_temp

    @current_temp.setter
    def current_temp(self, value):
        self.validate_temp(value)
        self._current_temp = value

    @property
    def user_temp_range(self):
        return self._user_temp_range

    @user_temp_range.setter
    def user_temp_range(self, temp_range):
        low, high = temp_range
        if high < low:
            raise errors.TemperatureValidationError('Invalid range.')
        self.validate_temp(low)
        self.validate_temp(high)
        self._user_temp_range = temp_range
<|endoftext|>