<commit_before>import sys
import json
import hashlib
import gc
from operator import *

from pyspark.sql import SQLContext
from pyspark.sql.functions import *
from pyspark.sql.types import *

import numpy as np

from subjectivity_clues import clues

def expect(name, var, expected, op=eq):
    if op(var, expected):
        log('[checkpoint] {} = {}'.format(name, expected))
    else:
        log('[error] {} = {}'.format(name, expected))
        raise Exception(name)

def log(message):
    log_file = 'sample_subjectivity_tweets.log'
    with open(log_file, 'a') as f:
        f.write(message)
        f.write('\n')
        f.flush()
        f.close()
    print message

def to_json(name, jsons):
    filename = '{}.json'.format(name)
    with open(filename, 'w') as f:
        for j in jsons:
            f.write(j)
            f.write('\n')

def to_csv(name, jsons):
    filename = '{}.csv'.format(name)
    with open(filename, 'w') as f:
        for tweet in jsons:
            t = json.loads(tweet)
            body = t['body'].replace('\n', ' ').replace('\r', '').replace('"', '""')
            f.write('"{}",{},{},"{}"\n'.format(t['id'], t['verb'], t['postedTime'], body))

def sample(rdd, size, seed):
    items = rdd.collect()
    rand = np.random.RandomState(seed)
    sampled = rand.choice(items, size=size, replace=False)
    expect('sampled', len(set(sampled)), size)
    return sampled.tolist()

def sha(name, ext='json'):
    BUF_SIZE = 65536
    filename = '{}.{}'.format(name, ext)

    sha1 = hashlib.sha1()
    with open(filename, 'rb') as f:
        while True:
            data = f.read(BUF_SIZE)
            if not data:
                break
            sha1.update(data)

    return sha1.hexdigest()

# Make sure Python uses UTF-8 as tweets contains emoticon and unicode
reload(sys)
sys.setdefaultencoding('utf-8')

# Use SQLContext for better support
sqlContext = SQLContext(sc)

# Read GNIP's JSON file
directory = "tweets"
datasets = sqlContext.read.json(directory)
log('# Completed reading JSON files')

# Check checksum count
file_count = datasets.where(datasets['verb'].isNull()).count()
expect('file_count', file_count, 21888)

# Check post count
all_posts = datasets.where(datasets['verb'] == 'post')
all_posts_count = all_posts.count()
expect('all_posts_count', all_posts_count, 1570398)

# Check share count
all_shares = datasets.where(datasets['verb'] == 'share')
all_shares_count = all_shares.count()
expect('all_shares_count', all_shares_count, 1112590)

# Check dataset count
info_dataset = datasets.select('info')
info_dataset.registerTempTable('info')
all_tweets_count = info_dataset.select('info.activity_count').groupBy().sum('activity_count').collect()[0][0]
expect('all_tweets_count', all_tweets_count, 2682988)
expect('all_tweets_count', all_tweets_count, all_posts_count + all_shares_count)
log('# Completed validating tweets count')

# Remove post authored by @ChipotleTweet and news agencies
chipotle_tweet = 'id:twitter.com:141341662'
users_to_remove = [chipotle_tweet, 'id:twitter.com:759251', 'id:twitter.com:91478624', 'id:twitter.com:28785486',
                   'id:twitter.com:1652541', 'id:twitter.com:51241574', 'id:twitter.com:807095',
                   'id:twitter.com:34713362', 'id:twitter.com:3090733766', 'id:twitter.com:1367531',
                   'id:twitter.com:14293310', 'id:twitter.com:3108351', 'id:twitter.com:14173315',
                   'id:twitter.com:292777349', 'id:twitter.com:428333', 'id:twitter.com:624413',
                   'id:twitter.com:20562637', 'id:twitter.com:13918492', 'id:twitter.com:16184358',
                   'id:twitter.com:625697849', 'id:twitter.com:2467791', 'id:twitter.com:9763482',
                   'id:twitter.com:14511951', 'id:twitter.com:6017542', 'id:twitter.com:26574283',
                   'id:twitter.com:115754870']

all_posts_wo_specific_users = all_posts.where(~ col('actor.id').isin(users_to_remove))
all_posts_w_specific_users = all_posts.where(col('actor.id').isin(users_to_remove)).count()
expect('all_posts_wo_specific_users', all_posts_wo_specific_users.count(), all_posts_count - all_posts_w_specific_users)

# Remove share retweet of tweet by @ChipotleTweet and news agencies
all_shares_wo_specific_users = all_shares.where(~ col('object.actor.id').isin(users_to_remove))
all_shares_w_specific_users = all_shares.where(col('object.actor.id').isin(users_to_remove)).count()
expect('all_shares_wo_specific_users', all_shares_wo_specific_users.count(), all_shares_count - all_shares_w_specific_users)

# Generate tweets pool with only English tweet
tweets_pool = all_posts_wo_specific_users.unionAll(all_shares_wo_specific_users).filter("twitter_lang = 'en'")
tweets_pool.cache()
tweets_pool_count = tweets_pool.count()
# Adding all post to all share will be greater than tweet pool because of non-English tweet
expected_tweets_pool_count = all_posts_count - all_posts_w_specific_users + \
                             all_shares_count - all_shares_w_specific_users
expect('tweets_pool_count', tweets_pool_count, expected_tweets_pool_count, op=lt)
log('# Completed constructing tweets pool')

# Check language of tweets
languages = tweets_pool.select('twitter_lang').distinct()
languages_count = languages.count()
language_check = languages.first()['twitter_lang']
expect('languages_count', languages_count, 1)
expect('language_check', language_check, 'en')
log('# Completed validating language variety')

# Take top 80% of tweets by length
tweets_pool_str_lengths = tweets_pool.select(length('body').alias('length')).rdd.map(lambda x: x.length).collect()
lengths_np = np.array(tweets_pool_str_lengths)
p = np.percentile(lengths_np, 20)

final_tweets_pool = tweets_pool.filter(length('body') >= p)
final_tweets_pool.cache()
tweets_pool.unpersist()

final_tweets_pool_count = final_tweets_pool.count()
percentage_kept = float(final_tweets_pool_count) / tweets_pool_count
expect('percentage_kept', percentage_kept, 0.8, op=gt)
log('# Completed sampling top 80% of tweets by body length')

# Sampling
final_tweets_ids = final_tweets_pool.select(final_tweets_pool['id']).rdd.sortBy(lambda x: x.id).map(lambda x: x.id)

# Development tweets
dev_seed = 10102016
number_of_dev_samples = 3000
dev_posts = sample(final_tweets_ids, number_of_dev_samples, dev_seed)
dev_posts_count = len(dev_posts)
expect('dev_posts_count', dev_posts_count, number_of_dev_samples)
log('# Completed sampling dev tweets')

dev_posts_file = "dev_posts"
dev_posts_jsons = final_tweets_pool[final_tweets_pool['id'].isin(dev_posts)].toJSON().collect()
to_json(dev_posts_file, dev_posts_jsons)
to_csv(dev_posts_file, dev_posts_jsons)
expect('dev_posts_file', sha(dev_posts_file), '74447296831c8e3061fc0ee739f549c5b08b85a3')
expect('dev_posts_file', sha(dev_posts_file, ext='csv'), '6acfd1f8d238bc5d25d97d2c9e6f6b177699389a')
log('Exporting dev post to {}'.format(dev_posts_file))
log('# Completed exporting dev tweets')

del dev_posts_jsons
gc.collect()

# Find distinct set of tweets (unique body text)
post_pool = final_tweets_pool.where(final_tweets_pool['verb'] == 'post')
post_pool_ids = post_pool.select(post_pool['id']).rdd.sortBy(lambda x: x.id).map(lambda x: x.id).collect()
expect('post_pool', post_pool.count(), 1124935)

share_pool = final_tweets_pool.where(final_tweets_pool['verb'] == 'share')
expect('share_pool', share_pool.count(), 846141)
broadcast_post_ids = sc.broadcast(set(post_pool_ids))
unique_share_ids = share_pool.select(share_pool['id'], share_pool['object.id'].alias('object_id')).rdd.filter(lambda row: row['object_id'] not in broadcast_post_ids.value).map(lambda row: row.id).collect()
unique_share_pool = share_pool[share_pool['id'].isin(unique_share_ids)]
expect('unique_share_pool', unique_share_pool.count(), 193006)
log('# Completed finding unique share tweet')

# Reconstruct tweet pool
distinct_tweets_pool = post_pool.unionAll(unique_share_pool)

final_tweets_pool.unpersist()
del final_tweets_pool
gc.collect()

distinct_tweets_pool.cache()
expect('distinct_tweets_pool', distinct_tweets_pool.count(), 1124935 + 193006)
log('# Completed constructing distinct tweet pool')

# Calculate subjectivity
c = clues.Clues()
broadcast_clues = sc.broadcast(c)
udfBodyToRelevant = udf(broadcast_clues.value.calculate_relevant, IntegerType())
tweets_lexicon = distinct_tweets_pool.select(distinct_tweets_pool['id'], distinct_tweets_pool['body']).withColumn('score', udfBodyToRelevant('body'))

# Exclude development tweets
tweets_unsampled = tweets_lexicon.where(~ col('id').isin(dev_posts))
expect('tweets_unsampled', tweets_unsampled.count, len(final_tweets_ids) - number_of_dev_samples)
log('# Completed constructing unsampled tweets')

# Take top and bottom
number_of_tweets_each = 1500
positive_tweets = tweets_unsampled.orderBy(desc('score')).take(number_of_tweets_each)

positive_tweet_file = "positive_tweets"
positive_tweet_jsons = distinct_tweets_pool[distinct_tweets_pool['id'].isin(positive_tweets)].toJSON().collect()
to_json(positive_tweet_file, positive_tweet_jsons)
to_csv(positive_tweet_file, positive_tweet_jsons)
log('Exporting positive tweets to {}'.format(positive_tweet_file))
log('# Completed exporting positive tweets')

negative_tweets = tweets_unsampled.orderBy(asc('score')).take(number_of_tweets_each)
negative_tweet_ids = [t['id'] for t in negative_tweets]

negative_tweet_file = "negative_tweets"
negative_tweet_jsons = distinct_tweets_pool[distinct_tweets_pool['id'].isin(negative_tweet_ids)].toJSON().collect()
to_json(negative_tweet_file, negative_tweet_jsons)
to_csv(negative_tweet_file, negative_tweet_jsons)
log('Exporting negative tweets to {}'.format(negative_tweet_file))
log('# Completed exporting negative tweets')<commit_msg>Collect before union<commit_after>import sys
import json
import hashlib
import gc
from operator import *

from pyspark.sql import SQLContext
from pyspark.sql.functions import *
from pyspark.sql.types import *

import numpy as np

from subjectivity_clues import clues

def expect(name, var, expected, op=eq):
    if op(var, expected):
        log('[checkpoint] {} = {}'.format(name, expected))
    else:
        log('[error] {} = {}'.format(name, expected))
        raise Exception(name)

def log(message):
    log_file = 'sample_subjectivity_tweets.log'
    with open(log_file, 'a') as f:
        f.write(message)
        f.write('\n')
        f.flush()
        f.close()
    print message

def to_json(name, jsons):
    filename = '{}.json'.format(name)
    with open(filename, 'w') as f:
        for j in jsons:
            f.write(j)
            f.write('\n')

def to_csv(name, jsons):
    filename = '{}.csv'.format(name)
    with open(filename, 'w') as f:
        for tweet in jsons:
            t = json.loads(tweet)
            body = t['body'].replace('\n', ' ').replace('\r', '').replace('"', '""')
            f.write('"{}",{},{},"{}"\n'.format(t['id'], t['verb'], t['postedTime'], body))

def sample(rdd, size, seed):
    items = rdd.collect()
    rand = np.random.RandomState(seed)
    sampled = rand.choice(items, size=size, replace=False)
    expect('sampled', len(set(sampled)), size)
    return sampled.tolist()

def sha(name, ext='json'):
    BUF_SIZE = 65536
    filename = '{}.{}'.format(name, ext)

    sha1 = hashlib.sha1()
    with open(filename, 'rb') as f:
        while True:
            data = f.read(BUF_SIZE)
            if not data:
                break
            sha1.update(data)

    return sha1.hexdigest()

# Make sure Python uses UTF-8 as tweets contains emoticon and unicode
reload(sys)
sys.setdefaultencoding('utf-8')

# Use SQLContext for better support
sqlContext = SQLContext(sc)

# Read GNIP's JSON file
directory = "tweets"
datasets = sqlContext.read.json(directory)
log('# Completed reading JSON files')

# Check checksum count
file_count = datasets.where(datasets['verb'].isNull()).count()
expect('file_count', file_count, 21888)

# Check post count
all_posts = datasets.where(datasets['verb'] == 'post')
all_posts_count = all_posts.count()
expect('all_posts_count', all_posts_count, 1570398)

# Check share count
all_shares = datasets.where(datasets['verb'] == 'share')
all_shares_count = all_shares.count()
expect('all_shares_count', all_shares_count, 1112590)

# Check dataset count
info_dataset = datasets.select('info')
info_dataset.registerTempTable('info')
all_tweets_count = info_dataset.select('info.activity_count').groupBy().sum('activity_count').collect()[0][0]
expect('all_tweets_count', all_tweets_count, 2682988)
expect('all_tweets_count', all_tweets_count, all_posts_count + all_shares_count)
log('# Completed validating tweets count')

# Remove post authored by @ChipotleTweet and news agencies
chipotle_tweet = 'id:twitter.com:141341662'
users_to_remove = [chipotle_tweet, 'id:twitter.com:759251', 'id:twitter.com:91478624', 'id:twitter.com:28785486',
                   'id:twitter.com:1652541', 'id:twitter.com:51241574', 'id:twitter.com:807095',
                   'id:twitter.com:34713362', 'id:twitter.com:3090733766', 'id:twitter.com:1367531',
                   'id:twitter.com:14293310', 'id:twitter.com:3108351', 'id:twitter.com:14173315',
                   'id:twitter.com:292777349', 'id:twitter.com:428333', 'id:twitter.com:624413',
                   'id:twitter.com:20562637', 'id:twitter.com:13918492', 'id:twitter.com:16184358',
                   'id:twitter.com:625697849', 'id:twitter.com:2467791', 'id:twitter.com:9763482',
                   'id:twitter.com:14511951', 'id:twitter.com:6017542', 'id:twitter.com:26574283',
                   'id:twitter.com:115754870']

all_posts_wo_specific_users = all_posts.where(~ col('actor.id').isin(users_to_remove))
all_posts_w_specific_users = all_posts.where(col('actor.id').isin(users_to_remove)).count()
expect('all_posts_wo_specific_users', all_posts_wo_specific_users.count(), all_posts_count - all_posts_w_specific_users)

# Remove share retweet of tweet by @ChipotleTweet and news agencies
all_shares_wo_specific_users = all_shares.where(~ col('object.actor.id').isin(users_to_remove))
all_shares_w_specific_users = all_shares.where(col('object.actor.id').isin(users_to_remove)).count()
expect('all_shares_wo_specific_users', all_shares_wo_specific_users.count(), all_shares_count - all_shares_w_specific_users)

# Generate tweets pool with only English tweet
tweets_pool = all_posts_wo_specific_users.unionAll(all_shares_wo_specific_users).filter("twitter_lang = 'en'")
tweets_pool.cache()
tweets_pool_count = tweets_pool.count()
# Adding all post to all share will be greater than tweet pool because of non-English tweet
expected_tweets_pool_count = all_posts_count - all_posts_w_specific_users + \
                             all_shares_count - all_shares_w_specific_users
expect('tweets_pool_count', tweets_pool_count, expected_tweets_pool_count, op=lt)
log('# Completed constructing tweets pool')

# Check language of tweets
languages = tweets_pool.select('twitter_lang').distinct()
languages_count = languages.count()
language_check = languages.first()['twitter_lang']
expect('languages_count', languages_count, 1)
expect('language_check', language_check, 'en')
log('# Completed validating language variety')

# Take top 80% of tweets by length
tweets_pool_str_lengths = tweets_pool.select(length('body').alias('length')).rdd.map(lambda x: x.length).collect()
lengths_np = np.array(tweets_pool_str_lengths)
p = np.percentile(lengths_np, 20)

final_tweets_pool = tweets_pool.filter(length('body') >= p)
final_tweets_pool.cache()
tweets_pool.unpersist()

final_tweets_pool_count = final_tweets_pool.count()
percentage_kept = float(final_tweets_pool_count) / tweets_pool_count
expect('percentage_kept', percentage_kept, 0.8, op=gt)
log('# Completed sampling top 80% of tweets by body length')

# Sampling
final_tweets_ids = final_tweets_pool.select(final_tweets_pool['id']).rdd.sortBy(lambda x: x.id).map(lambda x: x.id)

# Development tweets
dev_seed = 10102016
number_of_dev_samples = 3000
dev_posts = sample(final_tweets_ids, number_of_dev_samples, dev_seed)
dev_posts_count = len(dev_posts)
expect('dev_posts_count', dev_posts_count, number_of_dev_samples)
log('# Completed sampling dev tweets')

dev_posts_file = "dev_posts"
dev_posts_jsons = final_tweets_pool[final_tweets_pool['id'].isin(dev_posts)].toJSON().collect()
to_json(dev_posts_file, dev_posts_jsons)
to_csv(dev_posts_file, dev_posts_jsons)
expect('dev_posts_file', sha(dev_posts_file), '74447296831c8e3061fc0ee739f549c5b08b85a3')
expect('dev_posts_file', sha(dev_posts_file, ext='csv'), '6acfd1f8d238bc5d25d97d2c9e6f6b177699389a')
log('Exporting dev post to {}'.format(dev_posts_file))
log('# Completed exporting dev tweets')

del dev_posts_jsons
gc.collect()

# Find distinct set of tweets (unique body text)
post_pool = final_tweets_pool.where(final_tweets_pool['verb'] == 'post')
post_pool_ids = post_pool.select(post_pool['id']).rdd.sortBy(lambda x: x.id).map(lambda x: x.id).collect()
expect('post_pool', post_pool.count(), 1124935)

share_pool = final_tweets_pool.where(final_tweets_pool['verb'] == 'share')
expect('share_pool', share_pool.count(), 846141)
broadcast_post_ids = sc.broadcast(set(post_pool_ids))
unique_share_ids = share_pool.select(share_pool['id'], share_pool['object.id'].alias('object_id')).rdd.filter(lambda row: row['object_id'] not in broadcast_post_ids.value).map(lambda row: row.id).collect()
unique_share_pool = share_pool[share_pool['id'].isin(unique_share_ids)]
expect('unique_share_pool', unique_share_pool.count(), 193006)
log('# Completed finding unique share tweet')

# Reconstruct tweet pool
final_tweets_pool.unpersist()
del final_tweets_pool
gc.collect()

distinct_tweets_pool = post_pool.collect().unionAll(unique_share_pool.collect())
distinct_tweets_pool.cache()
expect('distinct_tweets_pool', distinct_tweets_pool.count(), 1124935 + 193006)
log('# Completed constructing distinct tweet pool')

# Calculate subjectivity
c = clues.Clues()
broadcast_clues = sc.broadcast(c)
udfBodyToRelevant = udf(broadcast_clues.value.calculate_relevant, IntegerType())
tweets_lexicon = distinct_tweets_pool.select(distinct_tweets_pool['id'], distinct_tweets_pool['body']).withColumn('score', udfBodyToRelevant('body'))

# Exclude development tweets
tweets_unsampled = tweets_lexicon.where(~ col('id').isin(dev_posts))
expect('tweets_unsampled', tweets_unsampled.count, len(final_tweets_ids) - number_of_dev_samples)
log('# Completed constructing unsampled tweets')

# Take top and bottom
number_of_tweets_each = 1500
positive_tweets = tweets_unsampled.orderBy(desc('score')).take(number_of_tweets_each)

positive_tweet_file = "positive_tweets"
positive_tweet_jsons = distinct_tweets_pool[distinct_tweets_pool['id'].isin(positive_tweets)].toJSON().collect()
to_json(positive_tweet_file, positive_tweet_jsons)
to_csv(positive_tweet_file, positive_tweet_jsons)
log('Exporting positive tweets to {}'.format(positive_tweet_file))
log('# Completed exporting positive tweets')

negative_tweets = tweets_unsampled.orderBy(asc('score')).take(number_of_tweets_each)
negative_tweet_ids = [t['id'] for t in negative_tweets]

negative_tweet_file = "negative_tweets"
negative_tweet_jsons = distinct_tweets_pool[distinct_tweets_pool['id'].isin(negative_tweet_ids)].toJSON().collect()
to_json(negative_tweet_file, negative_tweet_jsons)
to_csv(negative_tweet_file, negative_tweet_jsons)
log('Exporting negative tweets to {}'.format(negative_tweet_file))
log('# Completed exporting negative tweets')<|endoftext|>


<commit_before>import plugins
import packetFactory
import data.clients
import data.players
from twisted.protocols import basic
from config import JSONConfig

ircSettings = JSONConfig("cfg/gchat-irc.config.json",
                         {'enabled': False, 'nick': "PSO2IRCBot", 'server': '', 'port': 6667, 'channel': ""}, True)

ircMode = ircSettings.get_key('enabled')
ircNick = ircSettings.get_key('nick')
ircServer = (ircSettings.get_key('server'), ircSettings.get_key('port'))
ircChannel = ircSettings.get_key('channel')

chatPreferences = JSONConfig("cfg/gchat.prefs.json")

if ircMode:
    from twisted.words.protocols import irc
    from twisted.internet import reactor, protocol

    ircBot = None

    # noinspection PyUnresolvedReferences
    class GChatIRC(irc.IRCClient):
        currentPid = 0
        userIds = {}

        def __init__(self):
            global ircNick
            self.nickname = ircNick

        def get_user_id(self, user):
            if user not in self.userIds:
                self.userIds[user] = self.currentPid
                self.currentPid += 1
            return self.userIds[user]

        def connectionMade(self):
            irc.IRCClient.connectionMade(self)
            print("[GlobalChat] IRC Connected!")

        def connectionLost(self, reason):
            irc.IRCClient.connectionLost(self, reason)
            print("[GlobalChat] IRC Connection lost!")

        def signedOn(self):
            global ircBot
            self.join(self.factory.channel)
            print("[GlobalChat] Joined %s" % self.factory.channel)
            ircBot = self

        def privmsg(self, user, channel, msg):
            if channel == self.factory.channel:
                print("[GlobalChat] [IRC] <%s> %s" % (user.split("!")[0], msg))
                for client in data.clients.connectedClients.values():
                    if client.get_preferences()['globalChat'] and client.get_handle() is not None:
                        client.get_handle().send_crypto_packet(
                            packetFactory.TeamChatPacket(self.get_user_id(user.split("!")[0]),
                                                         "[GIRC-%s]" % user.split("!")[0], msg).build())

        def action(self, user, channel, msg):
            if channel == self.factory.channel:
                print("[GlobalChat] [IRC] * %s %s" % (user, msg))
                for client in data.clients.connectedClients.values():
                    if client.get_preferences()['globalChat'] and client.get_handle() is not None:
                        client.get_handle().send_crypto_packet(
                            packetFactory.TeamChatPacket(self.get_user_id(user.split("!")[0]),
                                                         "[GIRC-%s]" % user.split("!")[0], "* %s" % msg).build())

        def send_global_message(self, user, message):
            self.msg(self.factory.channel, "[G] <%s> %s" % (user, message))

    class GIRCFactory(protocol.ClientFactory):
        """docstring for ClassName"""

        def __init__(self, channel):
            self.channel = channel

        def buildProtocol(self, addr):
            p = GChatIRC()
            p.factory = self
            return p

        def clientConnectionLost(self, connector, reason):
            connector.connect()

@plugins.on_start_hook
def create_preferences():
    global chatPreferences
    global ircMode
    if ircMode:
        global ircChannel
        global ircServer
        bot = GIRCFactory(ircChannel)
        reactor.connectTCP(ircServer[0], ircServer[1], bot)

# noinspection PyUnresolvedReferences
@plugins.on_connection_hook
def check_config(user):
    global chatPreferences
    if user.playerId in data.clients.connectedClients:
        client_preferences = data.clients.connectedClients[user.playerId].get_preferences()
        if 'globalChat' not in client_preferences:
            if chatPreferences.key_exists(user.playerId):
                client_preferences['globalChat'] = chatPreferences.get_key(user.playerId)['toggle']
            else:
                client_preferences['globalChat'] = True
                chatPreferences.set_key(user.playerId, {'toggle': True})
            if client_preferences['globalChat']:
                user.send_crypto_packet(packetFactory.SystemMessagePacket(
                    "[Proxy] {red}Global chat is enabled, use |g <Message> to chat and |goff to disable it.",
                    0x3).build())
            else:
                user.send_crypto_packet(packetFactory.SystemMessagePacket(
                    "[Proxy] {red}Global chat is disabled, use |gon to enable it and use |g <Message> to chat.",
                    0x3).build())
        data.clients.connectedClients[user.playerId].set_preferences(client_preferences)

# noinspection PyUnresolvedReferences
@plugins.CommandHook("gon", "Enable global chat.")
def enable(context, params):
    global chatPreferences
    preferences = data.clients.connectedClients[context.playerId].get_preferences()
    preferences['globalChat'] = True
    context.send_crypto_packet(
        packetFactory.SystemMessagePacket("[GlobalChat] Global chat enabled for you.", 0x3).build())
    data.clients.connectedClients[context.playerId].set_preferences(preferences)
    new_preferences = chatPreferences.get_key(context.playerId)
    new_preferences['toggle'] = True
    chatPreferences.set_key(context.playerId, new_preferences)
    savePrefs()

# noinspection PyUnresolvedReferences
@plugins.CommandHook("goff", "Disable global chat.")
def disable(context, params):
    preferences = data.clients.connectedClients[context.playerId].get_preferences()
    preferences['globalChat'] = False
    context.send_crypto_packet(
        packetFactory.SystemMessagePacket("[GlobalChat] Global chat disabled for you.", 0x3).build())
    data.clients.connectedClients[context.playerId].set_preferences(preferences)
    new_preferences = chatPreferences.get_key(context.playerId)
    new_preferences['toggle'] = False
    chatPreferences.set_key(context.playerId, new_preferences)

# noinspection PyUnresolvedReferences
@plugins.CommandHook("g", "Chat in global chat.")
def chat(context, params):
    global ircMode
    if isinstance(context, basic.LineReceiver):
        if ircMode:
            global ircBot
            if ircBot is not None:
                import unicodedata

                ircBot.send_global_message(
                    "Console",
                    unicodedata.normalize('NFKD', params[2:]).encode('ascii', 'ignore'))
        for client in data.clients.connectedClients.values():
            if client.get_preferences()['globalChat'] and client.get_handle() is not None:
                client.get_handle().send_crypto_packet(
                    packetFactory.TeamChatPacket(0x1, "[GCONSOLE]",
                                                 params[2:]).build())
        return
    if not data.clients.connectedClients[context.playerId].get_preferences()['globalChat']:
        context.send_crypto_packet(packetFactory.SystemMessagePacket(
            "[GlobalChat] You do not have global chat enabled, and can not send a global message.", 0x3).build())
        return
    print("[GlobalChat] <%s> %s" % (data.players.playerList[context.playerId][0], params[3:]))
    if ircMode:
        global ircBot
        if ircBot is not None:
            import unicodedata

            ircBot.send_global_message(
                unicodedata.normalize('NFKD', data.players.playerList[context.playerId][0]).encode('ascii', 'ignore'),
                unicodedata.normalize('NFKD', params[3:]).encode('ascii', 'ignore'))
    for client in data.clients.connectedClients.values():
        if client.get_preferences()['globalChat'] and client.get_handle() is not None:
            client.get_handle().send_crypto_packet(
                packetFactory.TeamChatPacket(context.playerId, "[G-%s]" % data.players.playerList[context.playerId][0],
                                             params[3:]).build())

<commit_msg>Will IRC work with UTF-8?<commit_after>import plugins
import packetFactory
import data.clients
import data.players
from twisted.protocols import basic
from config import JSONConfig

ircSettings = JSONConfig("cfg/gchat-irc.config.json",
                         {'enabled': False, 'nick': "PSO2IRCBot", 'server': '', 'port': 6667, 'channel': ""}, True)

ircMode = ircSettings.get_key('enabled')
ircNick = ircSettings.get_key('nick')
ircServer = (ircSettings.get_key('server'), ircSettings.get_key('port'))
ircChannel = ircSettings.get_key('channel')

chatPreferences = JSONConfig("cfg/gchat.prefs.json")

if ircMode:
    from twisted.words.protocols import irc
    from twisted.internet import reactor, protocol

    ircBot = None

    # noinspection PyUnresolvedReferences
    class GChatIRC(irc.IRCClient):
        currentPid = 0
        userIds = {}

        def __init__(self):
            global ircNick
            self.nickname = ircNick

        def get_user_id(self, user):
            if user not in self.userIds:
                self.userIds[user] = self.currentPid
                self.currentPid += 1
            return self.userIds[user]

        def connectionMade(self):
            irc.IRCClient.connectionMade(self)
            print("[GlobalChat] IRC Connected!")

        def connectionLost(self, reason):
            irc.IRCClient.connectionLost(self, reason)
            print("[GlobalChat] IRC Connection lost!")

        def signedOn(self):
            global ircBot
            self.join(self.factory.channel)
            print("[GlobalChat] Joined %s" % self.factory.channel)
            ircBot = self

        def privmsg(self, user, channel, msg):
            if channel == self.factory.channel:
                print("[GlobalChat] [IRC] <%s> %s" % (user.split("!")[0], msg))
                for client in data.clients.connectedClients.values():
                    if client.get_preferences()['globalChat'] and client.get_handle() is not None:
                        client.get_handle().send_crypto_packet(
                            packetFactory.TeamChatPacket(self.get_user_id(user.split("!")[0]),
                                                         "[GIRC-%s]" % user.split("!")[0], msg).build())

        def action(self, user, channel, msg):
            if channel == self.factory.channel:
                print("[GlobalChat] [IRC] * %s %s" % (user, msg))
                for client in data.clients.connectedClients.values():
                    if client.get_preferences()['globalChat'] and client.get_handle() is not None:
                        client.get_handle().send_crypto_packet(
                            packetFactory.TeamChatPacket(self.get_user_id(user.split("!")[0]),
                                                         "[GIRC-%s]" % user.split("!")[0], "* %s" % msg).build())

        def send_global_message(self, user, message):
            self.msg(self.factory.channel, "[G] <%s> %s" % (user, message))

    class GIRCFactory(protocol.ClientFactory):
        """docstring for ClassName"""

        def __init__(self, channel):
            self.channel = channel

        def buildProtocol(self, addr):
            p = GChatIRC()
            p.factory = self
            return p

        def clientConnectionLost(self, connector, reason):
            connector.connect()

@plugins.on_start_hook
def create_preferences():
    global chatPreferences
    global ircMode
    if ircMode:
        global ircChannel
        global ircServer
        bot = GIRCFactory(ircChannel)
        reactor.connectTCP(ircServer[0], ircServer[1], bot)

# noinspection PyUnresolvedReferences
@plugins.on_connection_hook
def check_config(user):
    global chatPreferences
    if user.playerId in data.clients.connectedClients:
        client_preferences = data.clients.connectedClients[user.playerId].get_preferences()
        if 'globalChat' not in client_preferences:
            if chatPreferences.key_exists(user.playerId):
                client_preferences['globalChat'] = chatPreferences.get_key(user.playerId)['toggle']
            else:
                client_preferences['globalChat'] = True
                chatPreferences.set_key(user.playerId, {'toggle': True})
            if client_preferences['globalChat']:
                user.send_crypto_packet(packetFactory.SystemMessagePacket(
                    "[Proxy] {red}Global chat is enabled, use |g <Message> to chat and |goff to disable it.",
                    0x3).build())
            else:
                user.send_crypto_packet(packetFactory.SystemMessagePacket(
                    "[Proxy] {red}Global chat is disabled, use |gon to enable it and use |g <Message> to chat.",
                    0x3).build())
        data.clients.connectedClients[user.playerId].set_preferences(client_preferences)

# noinspection PyUnresolvedReferences
@plugins.CommandHook("gon", "Enable global chat.")
def enable(context, params):
    global chatPreferences
    preferences = data.clients.connectedClients[context.playerId].get_preferences()
    preferences['globalChat'] = True
    context.send_crypto_packet(
        packetFactory.SystemMessagePacket("[GlobalChat] Global chat enabled for you.", 0x3).build())
    data.clients.connectedClients[context.playerId].set_preferences(preferences)
    new_preferences = chatPreferences.get_key(context.playerId)
    new_preferences['toggle'] = True
    chatPreferences.set_key(context.playerId, new_preferences)
    savePrefs()

# noinspection PyUnresolvedReferences
@plugins.CommandHook("goff", "Disable global chat.")
def disable(context, params):
    preferences = data.clients.connectedClients[context.playerId].get_preferences()
    preferences['globalChat'] = False
    context.send_crypto_packet(
        packetFactory.SystemMessagePacket("[GlobalChat] Global chat disabled for you.", 0x3).build())
    data.clients.connectedClients[context.playerId].set_preferences(preferences)
    new_preferences = chatPreferences.get_key(context.playerId)
    new_preferences['toggle'] = False
    chatPreferences.set_key(context.playerId, new_preferences)

# noinspection PyUnresolvedReferences
@plugins.CommandHook("g", "Chat in global chat.")
def chat(context, params):
    global ircMode
    if isinstance(context, basic.LineReceiver):
        if ircMode:
            global ircBot
            if ircBot is not None:
                import unicodedata

                ircBot.send_global_message("Console", params[:2].encode('utf-8'))
        for client in data.clients.connectedClients.values():
            if client.get_preferences()['globalChat'] and client.get_handle() is not None:
                client.get_handle().send_crypto_packet(
                    packetFactory.TeamChatPacket(0x1, "[GCONSOLE]",
                                                 params[2:]).build())
        return
    if not data.clients.connectedClients[context.playerId].get_preferences()['globalChat']:
        context.send_crypto_packet(packetFactory.SystemMessagePacket(
            "[GlobalChat] You do not have global chat enabled, and can not send a global message.", 0x3).build())
        return
    print("[GlobalChat] <%s> %s" % (data.players.playerList[context.playerId][0], params[3:]))
    if ircMode:
        global ircBot
        if ircBot is not None:
            import unicodedata

            ircBot.send_global_message(
                data.players.playerList[context.playerId][0].encode('utf-8'), params[3:].encode('utf-8'))
    for client in data.clients.connectedClients.values():
        if client.get_preferences()['globalChat'] and client.get_handle() is not None:
            client.get_handle().send_crypto_packet(
                packetFactory.TeamChatPacket(context.playerId, "[G-%s]" % data.players.playerList[context.playerId][0],
                                             params[3:]).build())

<|endoftext|>


<commit_before>from cassandra.cqlengine import columns
from cassandra.cqlengine import ValidationError
from cassandra.cqlengine.models import Model
from stream_framework.utils.five import long_t

class VarInt(columns.Column):
    db_type = 'varint'

    def validate(self, value):
        val = super(VarInt, self).validate(value)
        if val is None:
            return
        try:
            return long_t(val)
        except (TypeError, ValueError):
            raise ValidationError(
                "{} can't be converted to integer value".format(value))

    def to_python(self, value):
        return self.validate(value)

    def to_database(self, value):
        return self.validate(value)

class BaseActivity(Model):
    feed_id = columns.Ascii(primary_key=True, partition_key=True)
    activity_id = VarInt(primary_key=True, clustering_order='desc')

class Activity(BaseActivity):
    actor = columns.Integer(required=False)
    extra_context = columns.Bytes(required=False)
    object = columns.Integer(required=False)
    target = columns.Integer(required=False)
    time = columns.DateTime(required=False)
    verb = columns.Integer(required=False)

class AggregatedActivity(BaseActivity):
    activities = columns.Bytes(required=False)
    created_at = columns.DateTime(required=False)
    group = columns.Ascii(required=False)
    updated_at = columns.DateTime(required=False)
<commit_msg>remove reimplementation of VarInt.<commit_after>from cassandra.cqlengine import columns
from cassandra.cqlengine.models import Model

class BaseActivity(Model):
    feed_id = columns.Ascii(primary_key=True, partition_key=True)
    activity_id = columns.VarInt(primary_key=True, clustering_order='desc')

class Activity(BaseActivity):
    actor = columns.Integer(required=False)
    extra_context = columns.Bytes(required=False)
    object = columns.Integer(required=False)
    target = columns.Integer(required=False)
    time = columns.DateTime(required=False)
    verb = columns.Integer(required=False)

class AggregatedActivity(BaseActivity):
    activities = columns.Bytes(required=False)
    created_at = columns.DateTime(required=False)
    group = columns.Ascii(required=False)
    updated_at = columns.DateTime(required=False)
<|endoftext|>


<commit_before># This file is part of h5py, a Python interface to the HDF5 library.
#
# http://www.h5py.org
#
# Copyright 2008-2013 Andrew Collette and contributors
#
# License:  Standard 3-clause BSD; see "license.txt" for full license terms
#           and contributor agreement.

"""
    Tests for the (internal) selections module
"""

import numpy as np
import h5py
import h5py._hl.selections2 as sel

from common import TestCase, ut

class TestTypeGeneration(TestCase):

    """
        Internal feature: Determine output types from dataset dtype and fields.
    """

    def test_simple(self):
        """ Non-compound types are handled appropriately """
        dt = np.dtype('i')
        out, format = sel.read_dtypes(dt, ())
        self.assertEqual(out, format)
        self.assertEqual(out, np.dtype('i'))

    def test_simple_fieldexc(self):
        """ Field names for non-field types raises ValueError """
        dt = np.dtype('i')
        with self.assertRaises(ValueError):
            out, format = sel.read_dtypes(dt, ('a',))

    def test_compound_simple(self):
        """ Compound types with elemental subtypes """
        dt = np.dtype( [('a','i'), ('b','f'), ('c','|S10')] )

        # Implicit selection of all fields -> all fields
        out, format = sel.read_dtypes(dt, ())
        self.assertEqual(out, format)
        self.assertEqual(out, dt)

        # Explicit selection of fields -> requested fields
        out, format = sel.read_dtypes(dt, ('a','b'))
        self.assertEqual(out, format)
        self.assertEqual(out, np.dtype( [('a','i'), ('b','f')] ))

        # Explicit selection of exactly one field -> no fields
        out, format = sel.read_dtypes(dt, ('a',))
        self.assertEqual(out, np.dtype('i'))
        self.assertEqual(format, np.dtype( [('a','i')] ))

    def test_objects(self):
        """ Metadata is stripped from object types """
        dt = h5py.special_dtype(ref=h5py.Reference)

        out, format = sel.read_dtypes(dt, ())
        self.assertEqual(out, format)
        self.assertEqual(format, dt)
        self.assertTrue(out.fields is None)
        self.assertTrue(format.fields is not None)

    def test_compound_objects(self):
        """ Metadata is stripped from output in compound types"""
        reftype = h5py.special_dtype(ref=h5py.Reference)

        dt = np.dtype( [('a','i'), ('b',reftype), ('c','|S10')] )

        out, format = sel.read_dtypes(dt, ())
        self.assertEqual(out, format)
        self.assertEqual(format, dt)
        self.assertTrue(all(x[0].fields is None for x in out.fields.values() if x[0].kind == 'O'))

class TestScalarSliceRules(TestCase):

    """
        Internal feature: selections rules for scalar datasets
    """

    def setUp(self):
        self.f = h5py.File(self.mktemp(), 'w')
        self.dsid = self.f.create_dataset('x', ()).id

    def tearDown(self):
        if self.f:
            self.f.close()

    def test_args(self):
        """ Permissible arguments for scalar slicing """
        shape, selection = sel.read_selections_scalar(self.dsid, ())
        self.assertEqual(shape, None)
        self.assertEqual(selection.get_select_npoints(), 1)

        shape, selection = sel.read_selections_scalar(self.dsid, (Ellipsis,))
        self.assertEqual(shape, ())
        self.assertEqual(selection.get_select_npoints(), 1)

        with self.assertRaises(ValueError):
            shape, selection = sel.read_selections_scalar(self.dsid, (1,))

<commit_msg>remove obsolete test cases<commit_after># This file is part of h5py, a Python interface to the HDF5 library.
#
# http://www.h5py.org
#
# Copyright 2008-2013 Andrew Collette and contributors
#
# License:  Standard 3-clause BSD; see "license.txt" for full license terms
#           and contributor agreement.

"""
    Tests for the (internal) selections module
"""

import numpy as np
import h5py
import h5py._hl.selections2 as sel

from common import TestCase, ut

class TestTypeGeneration(TestCase):

    """
        Internal feature: Determine output types from dataset dtype and fields.
    """

    def test_simple(self):
        """ Non-compound types are handled appropriately """
        dt = np.dtype('i')
        out, format = sel.read_dtypes(dt, ())
        self.assertEqual(out, format)
        self.assertEqual(out, np.dtype('i'))

    def test_simple_fieldexc(self):
        """ Field names for non-field types raises ValueError """
        dt = np.dtype('i')
        with self.assertRaises(ValueError):
            out, format = sel.read_dtypes(dt, ('a',))

    def test_compound_simple(self):
        """ Compound types with elemental subtypes """
        dt = np.dtype( [('a','i'), ('b','f'), ('c','|S10')] )

        # Implicit selection of all fields -> all fields
        out, format = sel.read_dtypes(dt, ())
        self.assertEqual(out, format)
        self.assertEqual(out, dt)

        # Explicit selection of fields -> requested fields
        out, format = sel.read_dtypes(dt, ('a','b'))
        self.assertEqual(out, format)
        self.assertEqual(out, np.dtype( [('a','i'), ('b','f')] ))

        # Explicit selection of exactly one field -> no fields
        out, format = sel.read_dtypes(dt, ('a',))
        self.assertEqual(out, np.dtype('i'))
        self.assertEqual(format, np.dtype( [('a','i')] ))

class TestScalarSliceRules(TestCase):

    """
        Internal feature: selections rules for scalar datasets
    """

    def setUp(self):
        self.f = h5py.File(self.mktemp(), 'w')
        self.dsid = self.f.create_dataset('x', ()).id

    def tearDown(self):
        if self.f:
            self.f.close()

    def test_args(self):
        """ Permissible arguments for scalar slicing """
        shape, selection = sel.read_selections_scalar(self.dsid, ())
        self.assertEqual(shape, None)
        self.assertEqual(selection.get_select_npoints(), 1)

        shape, selection = sel.read_selections_scalar(self.dsid, (Ellipsis,))
        self.assertEqual(shape, ())
        self.assertEqual(selection.get_select_npoints(), 1)

        with self.assertRaises(ValueError):
            shape, selection = sel.read_selections_scalar(self.dsid, (1,))

<|endoftext|>


<commit_before>import sys
import os
import os.path as op

from six import moves

from bento.core.utils \
    import \
        subst_vars, virtualenv_prefix
from bento.core.platforms import \
        get_scheme
from bento._config \
    import \
        CONFIGURED_STATE_DUMP, BENTO_SCRIPT

from bento.commands.core \
    import \
        Command, Option
from bento.commands.errors \
    import \
        UsageException

class _ConfigureState(object):
    def __init__(self, bento_script, pkg, paths=None, flags=None, user_data=None):
        self.filename = bento_script.name
        self.pkg = pkg

        if flags is None:
            self.flags = {}
        else:
            self.flags = flags

        if paths is None:
            self.paths = {}
        else:
            self.paths = paths

        if user_data is None:
            self.user_data = {}
        else:
            self.user_data = user_data

    def dump(self, node):
        node.parent.mkdir()
        node.safe_write(moves.cPickle.dumps(self), 'wb')

    @classmethod
    def from_dump(cls, node):
        return moves.cPickle.loads(node.read('rb'))

def set_scheme_unix(scheme, options, package):
    # This mess is the simplest solution I can think of to support:
    #   - /usr/local as default for prefix while using debian/ubuntu changes
    #   (dist-packages instead of site-packages)
    #   - virtualenv support
    #   - arbitrary python install
    #
    # Cases to consider:
    #   - if prefix is given:
    #       - prefix and exec_prefix are customized following their options
    #   - if prefix is not given:
    #       - if under virtualenv: prefix and exec_prefix are set to their sys.* values
    #       - else on unix != darwin: using /usr/local
    #       - else on darwin: using sys values
    if options.prefix is not None:
        scheme["prefix"] = options.prefix
        if options.eprefix is None:
            scheme["eprefix"] = scheme["prefix"]
        else:
            scheme["eprefix"] = options.eprefix
    elif options.prefix is None and options.eprefix is not None:
        raise NotImplementedError("Customizing exec_prefix without " \
                                  "customizing prefix is not implemented yet")
    elif options.prefix is None and options.eprefix is None:
        venv_prefix = virtualenv_prefix()
        if venv_prefix is not None:
            scheme["prefix"] = scheme["eprefix"] = venv_prefix
        elif sys.platform == "darwin":
            scheme["prefix"] = op.normpath(sys.prefix)
            scheme["eprefix"] = op.normpath(sys.exec_prefix)
        else:
            # XXX: unix_local is an ubuntu/debian thing only ?
            from distutils.command.install import INSTALL_SCHEMES
            if "unix_local" in INSTALL_SCHEMES:
                dist_scheme = INSTALL_SCHEMES["unix_local"]
                # This madness is used to support ubuntu/debian customization
                prefix = "/usr/local"
                base = "/usr"
                py_version = sys.version.split()[0]
                py_version_short = py_version[0:3]
                dist_name = package.name
                v = {"base": base, "py_version_short": py_version_short, "dist_name": dist_name}

                scheme["prefix"] = scheme["eprefix"] = prefix
                scheme["sitedir"] = subst_vars(dist_scheme["purelib"], v)
                scheme["includedir"] = subst_vars(dist_scheme["headers"], v)
            else:
                scheme["prefix"] = scheme["eprefix"] = "/usr/local"

def set_scheme_win32(scheme, options, package):
    if options.prefix is not None:
        scheme["prefix"] = options.prefix
        if options.eprefix is None:
            scheme["eprefix"] = scheme["prefix"]
        else:
            scheme["eprefix"] = options.eprefix
    elif options.prefix is None and options.eprefix is not None:
        raise NotImplementedError("Customizing exec_prefix without " \
                                  "customizing prefix is not implemented yet")
    elif options.prefix is None and options.eprefix is None:
        venv_prefix = virtualenv_prefix()
        if venv_prefix is not None:
            scheme["prefix"] = scheme["eprefix"] = venv_prefix
        else:
            scheme["prefix"] = op.normpath(sys.prefix)
            scheme["eprefix"] = op.normpath(sys.exec_prefix)

def set_scheme_options(scheme, options, package):
    """Set path variables given in options in scheme dictionary."""
    for k in scheme:
        if hasattr(options, k):
            val = getattr(options, k)
            if val:
                if not os.path.isabs(val):
                    msg = "value given for path option '%s' " \
                          "should be an absolute path (value " \
                          "given was '%s')" % (k, val)
                    raise UsageException(msg)
                scheme[k] = val

    if os.name == "posix":
        set_scheme_unix(scheme, options, package)
    elif os.name == "nt":
        set_scheme_win32(scheme, options, package)
    else:
        raise NotImplementedError("OS %s not supported" % os.name)

    # XXX: define default somewhere and stick with it
    if options.prefix is not None and options.eprefix is None:
        scheme["eprefix"] = scheme["prefix"]

def get_flag_values(cmd, cmd_argv):
    """Return flag values from the command instance and its arguments.

    Assumes cmd is an instance of Configure."""
    o, a = cmd.options_context.parser.parse_args(cmd_argv)
    flag_values = _get_flag_values(cmd.flags, o)
    return flag_values

def _get_flag_values(flag_names, options):
    """Return flag values as defined by the options."""
    flag_values = {}
    for option_name in flag_names:
        flag_value = getattr(options, option_name, None)
        if flag_value is not None:
            if flag_value.lower() in ["true", "yes"]:
                flag_values[option_name] = True
            elif flag_value.lower() in ["false", "no"]:
                flag_values[option_name] = False
            else:
                msg = """Option %s expects a true or false argument"""
                raise UsageException(msg % "--%s" % option_name)
    return flag_values

def _setup_options_parser(options_context, package_options):
    """Setup the command options parser, merging standard options as well
    as custom options defined in the bento.info file, if any.
    """
    scheme, scheme_opts_d = get_scheme(sys.platform)

    p = options_context

    # Create default path options
    scheme_opts = {}
    for name, opt_d in scheme_opts_d.items():
        o = opt_d.pop("opts")
        opt = Option(*o, **opt_d)
        scheme_opts[name] = opt

    # Add custom path options (as defined in bento.info) to the path scheme
    for name, f in package_options.path_options.items():
        scheme_opts[name] = \
            Option('--%s' % f.name,
                   help='%s [%s]' % (f.description, f.default_value))

    p.add_group("installation_options", "Installation fine tuning")
    for opt in scheme_opts.values():
        p.add_option(opt, "installation_options")

    flag_opts = {}
    if package_options.flag_options:
        flags_group = p.add_group("optional_features", "Optional features")
        for name, v in package_options.flag_options.items():
            flag_opts[name] = Option(
                    "--%s" % v.name,
                    help="%s [default=%s]" % (v.description, v.default_value))
            p.add_option(flag_opts[name], "optional_features")

class ConfigureCommand(Command):
    long_descr = """\
Purpose: configure the project
Usage: bentomaker configure [OPTIONS]"""
    short_descr = "configure the project."

    def __init__(self):
        Command.__init__(self)

    def _setup_flags_and_scheme(self, package_options):
        self.scheme = _compute_scheme(package_options)
        self.flags = package_options.flag_options.keys()

    def run(self, ctx):
        run_node = ctx.run_node
        bento_script = ctx.top_node.find_node(BENTO_SCRIPT)
        if bento_script is None:
            raise IOError("%s not found ?" % BENTO_SCRIPT)

        self._setup_flags_and_scheme(ctx.package_options)
        args = ctx.get_command_arguments()
        o, a = ctx.options_context.parser.parse_args(args)
        if o.help:
            ctx.options_context.parser.print_help()
            return

        set_scheme_options(self.scheme, o, ctx.pkg)
        flag_vals = _get_flag_values(self.flags, o)

        ctx.setup()
        s = _ConfigureState(bento_script, ctx.pkg, self.scheme, flag_vals, {})

        dump_node = ctx.build_node.make_node(CONFIGURED_STATE_DUMP)
        s.dump(dump_node)

def _compute_scheme(package_options):
    """Compute path and flags-related options as defined in the script file(s)

    Parameters
    ----------
    package_options: PackageOptions
    """
    scheme, scheme_opts_d = get_scheme(sys.platform)

    # XXX: abstract away those, as it is copied from distutils
    scheme['py_version_short'] = ".".join(str(part) for part in sys.version_info[:2])
    scheme['pkgname'] = package_options.name

    for name, f in package_options.path_options.items():
        scheme[name] = f.default_value
    return scheme
<commit_msg>REF: remove dead code.<commit_after>import sys
import os
import os.path as op

from six import moves

from bento.core.utils \
    import \
        subst_vars, virtualenv_prefix
from bento.core.platforms import \
        get_scheme
from bento._config \
    import \
        CONFIGURED_STATE_DUMP, BENTO_SCRIPT

from bento.commands.core \
    import \
        Command, Option
from bento.commands.errors \
    import \
        UsageException

class _ConfigureState(object):
    def __init__(self, bento_script, pkg, paths=None, flags=None, user_data=None):
        self.filename = bento_script.name
        self.pkg = pkg

        if flags is None:
            self.flags = {}
        else:
            self.flags = flags

        if paths is None:
            self.paths = {}
        else:
            self.paths = paths

        if user_data is None:
            self.user_data = {}
        else:
            self.user_data = user_data

    def dump(self, node):
        node.parent.mkdir()
        node.safe_write(moves.cPickle.dumps(self), 'wb')

    @classmethod
    def from_dump(cls, node):
        return moves.cPickle.loads(node.read('rb'))

def set_scheme_unix(scheme, options, package):
    # This mess is the simplest solution I can think of to support:
    #   - /usr/local as default for prefix while using debian/ubuntu changes
    #   (dist-packages instead of site-packages)
    #   - virtualenv support
    #   - arbitrary python install
    #
    # Cases to consider:
    #   - if prefix is given:
    #       - prefix and exec_prefix are customized following their options
    #   - if prefix is not given:
    #       - if under virtualenv: prefix and exec_prefix are set to their sys.* values
    #       - else on unix != darwin: using /usr/local
    #       - else on darwin: using sys values
    if options.prefix is not None:
        scheme["prefix"] = options.prefix
        if options.eprefix is None:
            scheme["eprefix"] = scheme["prefix"]
        else:
            scheme["eprefix"] = options.eprefix
    elif options.prefix is None and options.eprefix is not None:
        raise NotImplementedError("Customizing exec_prefix without " \
                                  "customizing prefix is not implemented yet")
    elif options.prefix is None and options.eprefix is None:
        venv_prefix = virtualenv_prefix()
        if venv_prefix is not None:
            scheme["prefix"] = scheme["eprefix"] = venv_prefix
        elif sys.platform == "darwin":
            scheme["prefix"] = op.normpath(sys.prefix)
            scheme["eprefix"] = op.normpath(sys.exec_prefix)
        else:
            # XXX: unix_local is an ubuntu/debian thing only ?
            from distutils.command.install import INSTALL_SCHEMES
            if "unix_local" in INSTALL_SCHEMES:
                dist_scheme = INSTALL_SCHEMES["unix_local"]
                # This madness is used to support ubuntu/debian customization
                prefix = "/usr/local"
                base = "/usr"
                py_version = sys.version.split()[0]
                py_version_short = py_version[0:3]
                dist_name = package.name
                v = {"base": base, "py_version_short": py_version_short, "dist_name": dist_name}

                scheme["prefix"] = scheme["eprefix"] = prefix
                scheme["sitedir"] = subst_vars(dist_scheme["purelib"], v)
                scheme["includedir"] = subst_vars(dist_scheme["headers"], v)
            else:
                scheme["prefix"] = scheme["eprefix"] = "/usr/local"

def set_scheme_win32(scheme, options, package):
    if options.prefix is not None:
        scheme["prefix"] = options.prefix
        if options.eprefix is None:
            scheme["eprefix"] = scheme["prefix"]
        else:
            scheme["eprefix"] = options.eprefix
    elif options.prefix is None and options.eprefix is not None:
        raise NotImplementedError("Customizing exec_prefix without " \
                                  "customizing prefix is not implemented yet")
    elif options.prefix is None and options.eprefix is None:
        venv_prefix = virtualenv_prefix()
        if venv_prefix is not None:
            scheme["prefix"] = scheme["eprefix"] = venv_prefix
        else:
            scheme["prefix"] = op.normpath(sys.prefix)
            scheme["eprefix"] = op.normpath(sys.exec_prefix)

def set_scheme_options(scheme, options, package):
    """Set path variables given in options in scheme dictionary."""
    for k in scheme:
        if hasattr(options, k):
            val = getattr(options, k)
            if val:
                if not os.path.isabs(val):
                    msg = "value given for path option '%s' " \
                          "should be an absolute path (value " \
                          "given was '%s')" % (k, val)
                    raise UsageException(msg)
                scheme[k] = val

    if os.name == "posix":
        set_scheme_unix(scheme, options, package)
    elif os.name == "nt":
        set_scheme_win32(scheme, options, package)
    else:
        raise NotImplementedError("OS %s not supported" % os.name)

    # XXX: define default somewhere and stick with it
    if options.prefix is not None and options.eprefix is None:
        scheme["eprefix"] = scheme["prefix"]

def get_flag_values(cmd, cmd_argv):
    """Return flag values from the command instance and its arguments.

    Assumes cmd is an instance of Configure."""
    o, a = cmd.options_context.parser.parse_args(cmd_argv)
    flag_values = _get_flag_values(cmd.flags, o)
    return flag_values

def _get_flag_values(flag_names, options):
    """Return flag values as defined by the options."""
    flag_values = {}
    for option_name in flag_names:
        flag_value = getattr(options, option_name, None)
        if flag_value is not None:
            if flag_value.lower() in ["true", "yes"]:
                flag_values[option_name] = True
            elif flag_value.lower() in ["false", "no"]:
                flag_values[option_name] = False
            else:
                msg = """Option %s expects a true or false argument"""
                raise UsageException(msg % "--%s" % option_name)
    return flag_values

def _setup_options_parser(options_context, package_options):
    """Setup the command options parser, merging standard options as well
    as custom options defined in the bento.info file, if any.
    """
    scheme, scheme_opts_d = get_scheme(sys.platform)

    p = options_context

    # Create default path options
    scheme_opts = {}
    for name, opt_d in scheme_opts_d.items():
        o = opt_d.pop("opts")
        opt = Option(*o, **opt_d)
        scheme_opts[name] = opt

    # Add custom path options (as defined in bento.info) to the path scheme
    for name, f in package_options.path_options.items():
        scheme_opts[name] = \
            Option('--%s' % f.name,
                   help='%s [%s]' % (f.description, f.default_value))

    p.add_group("installation_options", "Installation fine tuning")
    for opt in scheme_opts.values():
        p.add_option(opt, "installation_options")

    flag_opts = {}
    if package_options.flag_options:
        p.add_group("optional_features", "Optional features")
        for name, v in package_options.flag_options.items():
            flag_opts[name] = Option(
                    "--%s" % v.name,
                    help="%s [default=%s]" % (v.description, v.default_value))
            p.add_option(flag_opts[name], "optional_features")

class ConfigureCommand(Command):
    long_descr = """\
Purpose: configure the project
Usage: bentomaker configure [OPTIONS]"""
    short_descr = "configure the project."

    def __init__(self):
        Command.__init__(self)

    def _setup_flags_and_scheme(self, package_options):
        self.scheme = _compute_scheme(package_options)
        self.flags = package_options.flag_options.keys()

    def run(self, ctx):
        bento_script = ctx.top_node.find_node(BENTO_SCRIPT)
        if bento_script is None:
            raise IOError("%s not found ?" % BENTO_SCRIPT)

        self._setup_flags_and_scheme(ctx.package_options)
        args = ctx.get_command_arguments()
        o, a = ctx.options_context.parser.parse_args(args)
        if o.help:
            ctx.options_context.parser.print_help()
            return

        set_scheme_options(self.scheme, o, ctx.pkg)
        flag_vals = _get_flag_values(self.flags, o)

        ctx.setup()
        s = _ConfigureState(bento_script, ctx.pkg, self.scheme, flag_vals, {})

        dump_node = ctx.build_node.make_node(CONFIGURED_STATE_DUMP)
        s.dump(dump_node)

def _compute_scheme(package_options):
    """Compute path and flags-related options as defined in the script file(s)

    Parameters
    ----------
    package_options: PackageOptions
    """
    scheme, scheme_opts_d = get_scheme(sys.platform)

    # XXX: abstract away those, as it is copied from distutils
    scheme['py_version_short'] = ".".join(str(part) for part in sys.version_info[:2])
    scheme['pkgname'] = package_options.name

    for name, f in package_options.path_options.items():
        scheme[name] = f.default_value
    return scheme
<|endoftext|>


<commit_before>#! /usr/bin/env python
import sys
import os
import getopt
import optparse
import traceback

import bento

from bento.core.utils import \
        subst_vars, pprint
from bento.core.platforms import \
        get_scheme
from bento.core.parser.api import \
        ParseError
from bento.core.package import \
        PackageDescription
from bento._config import \
        BENTO_SCRIPT

from bento.commands.core import \
        Command, HelpCommand, get_usage
from bento.commands.configure import \
        ConfigureCommand, get_configured_state
from bento.commands.build import \
        BuildCommand
from bento.commands.install import \
        InstallCommand
from bento.commands.parse import \
        ParseCommand
from bento.commands.convert import \
        ConvertCommand
from bento.commands.sdist import \
        SdistCommand
from bento.commands.detect_type import \
        DetectTypeCommand
from bento.commands.build_pkg_info import \
        BuildPkgInfoCommand
from bento.commands.build_egg import \
        BuildEggCommand
from bento.commands.build_wininst import \
        BuildWininstCommand
from bento.commands.distcheck import \
        DistCheckCommand
from bento.commands.core import \
        register_command, \
        get_command_names, get_command, \
        get_public_command_names
from bento.commands.errors import \
        ConvertionError, UsageException, CommandExecutionFailure

from bento.commands.hooks \
    import \
        get_pre_hooks, get_post_hooks, get_command_override
import bento.core.errors

if os.environ.get("BENTOMAKER_DEBUG", None) is not None:
    BENTOMAKER_DEBUG = True
else:
    BENTOMAKER_DEBUG = False

SCRIPT_NAME = 'bentomaker'

#================================
#   Create the command line UI
#================================
def register_commands():
    register_command("help", HelpCommand)
    register_command("configure", ConfigureCommand)
    register_command("build", BuildCommand)
    register_command("install", InstallCommand)
    register_command("convert", ConvertCommand)
    register_command("sdist", SdistCommand)
    register_command("build_egg", BuildEggCommand)
    register_command("build_wininst", BuildWininstCommand)
    register_command("distcheck", DistCheckCommand)

    register_command("build_pkg_info", BuildPkgInfoCommand, public=False)
    register_command("parse", ParseCommand, public=False)
    register_command("detect_type", DetectTypeCommand, public=False)

def dummy_startup():
    pass

def dummy_shutdown():
    pass

def set_main():
    import imp

    # Some commands work without a bento description file (convert, help)
    if not os.path.exists(BENTO_SCRIPT):
        return None
    pkg = PackageDescription.from_file(BENTO_SCRIPT)
    main_file = pkg.hook_file

    if main_file is None:
        return None
    else:
        if not os.path.exists(main_file):
            raise ValueError("Hook file %s not found" % main_file)

    module = imp.new_module("toysetup_module")
    code = open(main_file).read()

    sys.path.insert(0, os.path.dirname(main_file))
    try:
        exec(compile(code, main_file, 'exec'), module.__dict__)
    finally:
        sys.path.pop(0)

    module.root_path = main_file
    if not hasattr(module, "startup"):
        module.startup = dummy_startup
    if not hasattr(module, "shutdown"):
        module.shutdown = dummy_shutdown

    return module

def main(argv=None):
    if argv is None:
        argv = sys.argv[1:]
    popts = parse_global_options(argv)
    cmd_name = popts["cmd_name"]
    if cmd_name and cmd_name in ["convert"]:
        _main(popts)
    else:
        _wrapped_main(popts)

def _wrapped_main(popts):
    mod = set_main()
    if mod:
        mod.startup()

    try:
        return _main(popts)
    finally:
        if mod:
            mod.shutdown()

def parse_global_options(argv):
    ret = {"cmd_name": None, "cmd_opts": None,
           "show_version": False, "show_full_version": False,
           "show_usage": False}

    try:
        opts, pargs = getopt.getopt(argv, "hv", ["help", "version", "full-version"])
        for opt, arg in opts:
            if opt in ("--help", "-h"):
                ret["show_usage"] = True
            if opt in ("--version", "-v"):
                ret["show_version"] = True
            if opt in ("--full-version"):
                ret["show_full_version"] = True

        if len(pargs) > 0:
            ret["cmd_name"] = pargs.pop(0)
            ret["cmd_opts"] = pargs
    except getopt.GetoptError, e:
        emsg = "%s: illegal global option: %r" % (SCRIPT_NAME, e.opt)
        raise UsageException(emsg)

    return ret

def _main(popts):
    register_commands()

    if popts["show_version"]:
        print bento.__version__
        return 0

    if popts["show_full_version"]:
        print bento.__version__ + "git" + bento.__git_revision__
        return 0

    if popts["show_usage"]:
        cmd = get_command('help')()
        cmd.run(Context(cmd, []))
        return 0

    cmd_name = popts["cmd_name"]
    cmd_opts = popts["cmd_opts"]

    if not cmd_name:
        print "Type '%s help' for usage." % SCRIPT_NAME
        return 1
    else:
        if not cmd_name in get_command_names():
            raise UsageException("%s: Error: unknown command %s" % (SCRIPT_NAME, cmd_name))
        else:
            run_cmd(cmd_name, cmd_opts)

import yaku.context

# XXX: The yaku configure stuff is ugly, and introduces a lot of global state.
class Context(object):
    def __init__(self, cmd, cmd_opts):
        self.cmd = cmd
        self.cmd_opts = cmd_opts
        self.help = False

    def get_package(self):
        state = get_configured_state()
        return state.pkg

    def get_user_data(self):
        state = get_configured_state()
        return state.user_data

    def store(self):
        pass

class ConfigureContext(Context):
    def __init__(self, cmd, cmd_opts):
        Context.__init__(self, cmd, cmd_opts)
        self.yaku_configure_ctx = yaku.context.get_cfg()

    def store(self):
        Context.store(self)
        self.yaku_configure_ctx.store()

def run_cmd(cmd_name, cmd_opts):
    cmd = get_command(cmd_name)()
    if get_command_override(cmd_name):
        cmd_func = get_command_override(cmd_name)[0]
    else:
        cmd_func = cmd.run

    if cmd_name == "configure":
        ctx = ConfigureContext(cmd, cmd_opts)
    else:
        ctx = Context(cmd, cmd_opts)

    try:
        if get_pre_hooks(cmd_name) is not None:
            for f in get_pre_hooks(cmd_name):
                f[0](ctx)
        cmd_func(ctx)
        if get_post_hooks(cmd_name) is not None:
            for f in get_post_hooks(cmd_name):
                f[0](ctx)
    finally:
        ctx.store()

def noexc_main(argv=None):
    try:
        ret = main(argv)
    except UsageException, e:
        pprint('RED', e)
        sys.exit(1)
    except ParseError, e:
        pprint('RED', "".join(e.args))
        sys.exit(2)
    except ConvertionError, e:
        pprint('RED', "".join(e.args))
        sys.exit(3)
    except CommandExecutionFailure, e:
        pprint('RED', "".join(e.args))
        sys.exit(4)
    except bento.core.errors.BuildError, e:
        pprint('RED', e)
        sys.exit(8)
    except bento.core.errors.InvalidPackage, e:
        pprint('RED', e)
        sys.exit(16)
    except Exception, e:
        if BENTOMAKER_DEBUG:
            tb = sys.exc_info()[2]
            traceback.print_tb(tb)
        pprint('RED', "%s: Error: %s crashed (uncaught exception %s: %s).\n"
                "Please report this on bento issue tracker: \n" \
                "\thttp://github.com/cournape/bento/issues" %
               (SCRIPT_NAME, SCRIPT_NAME, e.__class__, str(e)))
        sys.exit(1)
    sys.exit(ret)

if __name__ == '__main__':
    noexc_main()
<commit_msg>BUG: add __file__ member to hook files.<commit_after>#! /usr/bin/env python
import sys
import os
import getopt
import optparse
import traceback

import bento

from bento.core.utils import \
        subst_vars, pprint
from bento.core.platforms import \
        get_scheme
from bento.core.parser.api import \
        ParseError
from bento.core.package import \
        PackageDescription
from bento._config import \
        BENTO_SCRIPT

from bento.commands.core import \
        Command, HelpCommand, get_usage
from bento.commands.configure import \
        ConfigureCommand, get_configured_state
from bento.commands.build import \
        BuildCommand
from bento.commands.install import \
        InstallCommand
from bento.commands.parse import \
        ParseCommand
from bento.commands.convert import \
        ConvertCommand
from bento.commands.sdist import \
        SdistCommand
from bento.commands.detect_type import \
        DetectTypeCommand
from bento.commands.build_pkg_info import \
        BuildPkgInfoCommand
from bento.commands.build_egg import \
        BuildEggCommand
from bento.commands.build_wininst import \
        BuildWininstCommand
from bento.commands.distcheck import \
        DistCheckCommand
from bento.commands.core import \
        register_command, \
        get_command_names, get_command, \
        get_public_command_names
from bento.commands.errors import \
        ConvertionError, UsageException, CommandExecutionFailure

from bento.commands.hooks \
    import \
        get_pre_hooks, get_post_hooks, get_command_override
import bento.core.errors

if os.environ.get("BENTOMAKER_DEBUG", None) is not None:
    BENTOMAKER_DEBUG = True
else:
    BENTOMAKER_DEBUG = False

SCRIPT_NAME = 'bentomaker'

#================================
#   Create the command line UI
#================================
def register_commands():
    register_command("help", HelpCommand)
    register_command("configure", ConfigureCommand)
    register_command("build", BuildCommand)
    register_command("install", InstallCommand)
    register_command("convert", ConvertCommand)
    register_command("sdist", SdistCommand)
    register_command("build_egg", BuildEggCommand)
    register_command("build_wininst", BuildWininstCommand)
    register_command("distcheck", DistCheckCommand)

    register_command("build_pkg_info", BuildPkgInfoCommand, public=False)
    register_command("parse", ParseCommand, public=False)
    register_command("detect_type", DetectTypeCommand, public=False)

def dummy_startup():
    pass

def dummy_shutdown():
    pass

def set_main():
    import imp

    # Some commands work without a bento description file (convert, help)
    if not os.path.exists(BENTO_SCRIPT):
        return None
    pkg = PackageDescription.from_file(BENTO_SCRIPT)
    main_file = pkg.hook_file

    if main_file is None:
        return None
    else:
        if not os.path.exists(main_file):
            raise ValueError("Hook file %s not found" % main_file)

    module = imp.new_module("toysetup_module")
    module.__file__ = os.path.abspath(main_file)
    code = open(main_file).read()

    sys.path.insert(0, os.path.dirname(main_file))
    try:
        exec(compile(code, main_file, 'exec'), module.__dict__)
    finally:
        sys.path.pop(0)

    module.root_path = main_file
    if not hasattr(module, "startup"):
        module.startup = dummy_startup
    if not hasattr(module, "shutdown"):
        module.shutdown = dummy_shutdown

    return module

def main(argv=None):
    if argv is None:
        argv = sys.argv[1:]
    popts = parse_global_options(argv)
    cmd_name = popts["cmd_name"]
    if cmd_name and cmd_name in ["convert"]:
        _main(popts)
    else:
        _wrapped_main(popts)

def _wrapped_main(popts):
    mod = set_main()
    if mod:
        mod.startup()

    try:
        return _main(popts)
    finally:
        if mod:
            mod.shutdown()

def parse_global_options(argv):
    ret = {"cmd_name": None, "cmd_opts": None,
           "show_version": False, "show_full_version": False,
           "show_usage": False}

    try:
        opts, pargs = getopt.getopt(argv, "hv", ["help", "version", "full-version"])
        for opt, arg in opts:
            if opt in ("--help", "-h"):
                ret["show_usage"] = True
            if opt in ("--version", "-v"):
                ret["show_version"] = True
            if opt in ("--full-version"):
                ret["show_full_version"] = True

        if len(pargs) > 0:
            ret["cmd_name"] = pargs.pop(0)
            ret["cmd_opts"] = pargs
    except getopt.GetoptError, e:
        emsg = "%s: illegal global option: %r" % (SCRIPT_NAME, e.opt)
        raise UsageException(emsg)

    return ret

def _main(popts):
    register_commands()

    if popts["show_version"]:
        print bento.__version__
        return 0

    if popts["show_full_version"]:
        print bento.__version__ + "git" + bento.__git_revision__
        return 0

    if popts["show_usage"]:
        cmd = get_command('help')()
        cmd.run(Context(cmd, []))
        return 0

    cmd_name = popts["cmd_name"]
    cmd_opts = popts["cmd_opts"]

    if not cmd_name:
        print "Type '%s help' for usage." % SCRIPT_NAME
        return 1
    else:
        if not cmd_name in get_command_names():
            raise UsageException("%s: Error: unknown command %s" % (SCRIPT_NAME, cmd_name))
        else:
            run_cmd(cmd_name, cmd_opts)

import yaku.context

# XXX: The yaku configure stuff is ugly, and introduces a lot of global state.
class Context(object):
    def __init__(self, cmd, cmd_opts):
        self.cmd = cmd
        self.cmd_opts = cmd_opts
        self.help = False

    def get_package(self):
        state = get_configured_state()
        return state.pkg

    def get_user_data(self):
        state = get_configured_state()
        return state.user_data

    def store(self):
        pass

class ConfigureContext(Context):
    def __init__(self, cmd, cmd_opts):
        Context.__init__(self, cmd, cmd_opts)
        self.yaku_configure_ctx = yaku.context.get_cfg()

    def store(self):
        Context.store(self)
        self.yaku_configure_ctx.store()

def run_cmd(cmd_name, cmd_opts):
    cmd = get_command(cmd_name)()
    if get_command_override(cmd_name):
        cmd_func = get_command_override(cmd_name)[0]
    else:
        cmd_func = cmd.run

    if cmd_name == "configure":
        ctx = ConfigureContext(cmd, cmd_opts)
    else:
        ctx = Context(cmd, cmd_opts)

    try:
        if get_pre_hooks(cmd_name) is not None:
            for f in get_pre_hooks(cmd_name):
                f[0](ctx)
        cmd_func(ctx)
        if get_post_hooks(cmd_name) is not None:
            for f in get_post_hooks(cmd_name):
                f[0](ctx)
    finally:
        ctx.store()

def noexc_main(argv=None):
    try:
        ret = main(argv)
    except UsageException, e:
        pprint('RED', e)
        sys.exit(1)
    except ParseError, e:
        pprint('RED', "".join(e.args))
        sys.exit(2)
    except ConvertionError, e:
        pprint('RED', "".join(e.args))
        sys.exit(3)
    except CommandExecutionFailure, e:
        pprint('RED', "".join(e.args))
        sys.exit(4)
    except bento.core.errors.BuildError, e:
        pprint('RED', e)
        sys.exit(8)
    except bento.core.errors.InvalidPackage, e:
        pprint('RED', e)
        sys.exit(16)
    except Exception, e:
        if BENTOMAKER_DEBUG:
            tb = sys.exc_info()[2]
            traceback.print_tb(tb)
        pprint('RED', "%s: Error: %s crashed (uncaught exception %s: %s).\n"
                "Please report this on bento issue tracker: \n" \
                "\thttp://github.com/cournape/bento/issues" %
               (SCRIPT_NAME, SCRIPT_NAME, e.__class__, str(e)))
        sys.exit(1)
    sys.exit(ret)

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


<commit_before>from slackbot.bot import respond_to
from slackbot.bot import listen_to
import re
import random

# @listen_to("!주사위 (\d*)?d?(\d+)?", re.IGNORECASE)
@listen_to("!roll ?(\d*d\d+.*)?", re.IGNORECASE)
def roll_dice(msg, roll_exp):
    # msg.reply("DEBUG MODE--")
    # msg.reply(roll_exp)

    if roll_exp is None:
        side_of_die = 6
        num_of_dice = 1
        modifier = "+ 0"

    else:
        captured = re.match("(\d*)?d(\d+) ?([+-] ?\d+)?", roll_exp, re.IGNORECASE)

        side_of_die = int(captured.group(2))

        num_of_dice = captured.group(1)
        if num_of_dice is '':
            num_of_dice = 1
        else:
            num_of_dice = int(num_of_dice)

        modifier = captured.group(3)
        if modifier is None:
            modifier = "+ 0"

    if num_of_dice > 100:
        msg.reply("주사위 갯수가 너무 많습니다! 조금 적게 굴려주세요~")
        return

    if num_of_dice == 0:
        msg.reply("은/는 주사위를 던졌다!")
        number_of_dice_error_messags = [
            "하지만 빈 손이었다...",
            "주사위가 없는데 던질수는 없다...",
            "공갈 주사위!",
            "아무것도 없는 주사위를 던진다는 것은 무엇인가. 봇은 고뇌에 빠지기 시작했다. 주사위가 던져지는 일은 없었다...",
        ]
        msg.reply(random.choice(number_of_dice_error_messags))
        return

    if side_of_die == 0:
        msg.reply("은/는 주사위를 던졌다!")
        die_error_messags = [
            "주사위는 0면체 주사위였기에 뒤틀린 황천으로 사라져버린거 같다...",
            "주사위가 손에서 빠져나오는 순간 디렉에 바다에 빠진거 같다...",
            "던지는 순간 눈부신 빛을 내며 주사위가 소멸했다. 물리적으로 존재할수 없는 주사위었던건가...",
            "주사위의 신의 목소리가 들려온다. `0면체는 던질 수 없다!`",
            "손을 펼쳐보았지만 빈 손바닥만 보인다.",
            "`하지만 무리에요. 0면체라니, 상상도 안간다구요 그런 주사위`, 주사위 봇은 시무룩해졌다..."
        ]
        msg.reply(random.choice(die_error_messags))
        return

    modifier_sign = modifier[0]
    modifier_number = int(modifier[1:].strip())

    # msg.reply(num_of_dice)
    # msg.reply(die)
    # msg.reply(modifier)
    # msg.reply(modifier_sign)
    # msg.reply(modifier_number)

    msg.reply("%d 면체를 %d 개 굴림 " % (side_of_die, num_of_dice))
    roll_result = [random.randrange(1, side_of_die, 1) for i in range(num_of_dice)]
    roll_sum = sum(roll_result)

    modified_result = roll_sum

    if modifier_sign == "+":
        modified_result += modifier_number
    elif modifier_sign == "-":
        modified_result -= modifier_number

    msg.reply("굴림: %s\n합계: %d, 평균: %.2f" % (roll_result, roll_sum, float(roll_sum) / float(len(roll_result))))
    if modifier_number != 0:
        msg.reply("수정치 적용: %d" % modified_result)

@listen_to("!rand ?(\d*)? (.*)", re.IGNORECASE)
def select_random_from_list(msg, n, l):
    if n is None or n == '' or int(n) <= 0:
        n = 1
    else:
        n = int(n)

    l2 = l.split("|")

    if n > len(l2):
        l3 = l2
    else:
        l3 = [i.strip() for i in random.sample(l2, n)]

    msg.reply("%s" % ", ".join(l3))

@respond_to("!rand help", re.IGNORECASE)
def rand_help(msg):
    msg.reply("""```
    주어진 목록에서 랜덤으로 몇개를 뽑아냅니다.
    !rand 1|2|3
    위의 예제는 1,2,3 중 하나를 골라서 돌려줍니다.
    !rand 4 1|2|3|5|6|7|8
    위의 예제는 1,2,3,4,5,6,7,8 중에서 4개를 골라서 돌려줍니다.

    편의상 예시는 숫자로 했지만 다음의 경우처럼 문자열도 가능합니다
    !rand 2 오징어|문어|고등어
    ```""")

@respond_to("!help", re.IGNORECASE)
def test_func(msg):
    msg.reply("주사위를 굴리는 법:")
    msg.reply("`!roll`")
    msg.reply("1d6을 굴립니다. 6면체 하나를 굴립니다.")
    msg.reply("1d6을 설명하면 다음과 같습니다. 6면체(d6)를 1개 굴린다.")
    msg.reply("3d20은 다음과 같습니다. 20면체(d20)를 3개 굴린다.")
    msg.reply("`!roll #d@` ex) `1d8`")
    msg.reply("#d@을 굴립니다. @면체 #개를 굴립니다.")
    msg.reply("`!roll #d@ + $`, ex) `1d12 + 5`")
    msg.reply("`!roll #d@ - $`, ex) `1d12 - 5`")
    msg.reply("#d@을 굴리고 수정치 $를 더하거나 뺍니다. @면체 #개를 굴립니다. 나온 결과의 합에 수정치 $를 더하거나 뺍니다.")
    msg.reply("A개의 B면체를 굴립니다.")
    msg.reply("수정치 M을 더하거나 뺍니다.")
<commit_msg>!rand로 선택된 단어 강조. 헬프 문구 조정<commit_after>from slackbot.bot import respond_to
from slackbot.bot import listen_to
import re
import random

# @listen_to("!주사위 (\d*)?d?(\d+)?", re.IGNORECASE)
@listen_to("!roll ?(\d*d\d+.*)?", re.IGNORECASE)
def roll_dice(msg, roll_exp):
    # msg.reply("DEBUG MODE--")
    # msg.reply(roll_exp)

    if roll_exp is None:
        side_of_die = 6
        num_of_dice = 1
        modifier = "+ 0"

    else:
        captured = re.match("(\d*)?d(\d+) ?([+-] ?\d+)?", roll_exp, re.IGNORECASE)

        side_of_die = int(captured.group(2))

        num_of_dice = captured.group(1)
        if num_of_dice is '':
            num_of_dice = 1
        else:
            num_of_dice = int(num_of_dice)

        modifier = captured.group(3)
        if modifier is None:
            modifier = "+ 0"

    if num_of_dice > 100:
        msg.reply("주사위 갯수가 너무 많습니다! 조금 적게 굴려주세요~")
        return

    if num_of_dice == 0:
        msg.reply("은/는 주사위를 던졌다!")
        number_of_dice_error_messags = [
            "하지만 빈 손이었다...",
            "주사위가 없는데 던질수는 없다...",
            "공갈 주사위!",
            "아무것도 없는 주사위를 던진다는 것은 무엇인가. 봇은 고뇌에 빠지기 시작했다. 주사위가 던져지는 일은 없었다...",
        ]
        msg.reply(random.choice(number_of_dice_error_messags))
        return

    if side_of_die == 0:
        msg.reply("은/는 주사위를 던졌다!")
        die_error_messags = [
            "주사위는 0면체 주사위였기에 뒤틀린 황천으로 사라져버린거 같다...",
            "주사위가 손에서 빠져나오는 순간 디렉에 바다에 빠진거 같다...",
            "던지는 순간 눈부신 빛을 내며 주사위가 소멸했다. 물리적으로 존재할수 없는 주사위었던건가...",
            "주사위의 신의 목소리가 들려온다. `0면체는 던질 수 없다!`",
            "손을 펼쳐보았지만 빈 손바닥만 보인다.",
            "`하지만 무리에요. 0면체라니, 상상도 안간다구요 그런 주사위`, 주사위 봇은 시무룩해졌다..."
        ]
        msg.reply(random.choice(die_error_messags))
        return

    modifier_sign = modifier[0]
    modifier_number = int(modifier[1:].strip())

    # msg.reply(num_of_dice)
    # msg.reply(die)
    # msg.reply(modifier)
    # msg.reply(modifier_sign)
    # msg.reply(modifier_number)

    msg.reply("%d 면체를 %d 개 굴림 " % (side_of_die, num_of_dice))
    roll_result = [random.randrange(1, side_of_die, 1) for i in range(num_of_dice)]
    roll_sum = sum(roll_result)

    modified_result = roll_sum

    if modifier_sign == "+":
        modified_result += modifier_number
    elif modifier_sign == "-":
        modified_result -= modifier_number

    msg.reply("굴림: %s\n합계: %d, 평균: %.2f" % (roll_result, roll_sum, float(roll_sum) / float(len(roll_result))))
    if modifier_number != 0:
        msg.reply("수정치 적용: %d" % modified_result)

@listen_to("!rand ?(\d*)? (.*)", re.IGNORECASE)
def select_random_from_list(msg, n, l):
    if n is None or n == '' or int(n) <= 0:
        n = 1
    else:
        n = int(n)

    l2 = l.split("|")

    if n > len(l2):
        l3 = l2
    else:
        l3 = ["`"+i.strip()+"`" for i in random.sample(l2, n)]

    msg.reply("%s" % ", ".join(l3))

@respond_to("!rand help", re.IGNORECASE)
def rand_help(msg):
    msg.reply("""```
주어진 목록에서 랜덤으로 몇개를 뽑아냅니다. 단어 목록은 | (버티컬 바)로 구별되어있습니다.
!rand 1|2|3
위의 예제는 1,2,3 중 하나를 골라서 돌려줍니다.
!rand 4 1|2|3|5|6|7|8
위의 예제는 1,2,3,4,5,6,7,8 중에서 4개를 골라서 돌려줍니다.

편의상 예시는 숫자로 했지만 다음의 경우처럼 문자열도 가능합니다
!rand 2 오징어|문어|고등어
```""")

@respond_to("!help", re.IGNORECASE)
def test_func(msg):
    msg.reply("주사위를 굴리는 법:")
    msg.reply("`!roll`")
    msg.reply("1d6을 굴립니다. 6면체 하나를 굴립니다.")
    msg.reply("1d6을 설명하면 다음과 같습니다. 6면체(d6)를 1개 굴린다.")
    msg.reply("3d20은 다음과 같습니다. 20면체(d20)를 3개 굴린다.")
    msg.reply("`!roll #d@` ex) `1d8`")
    msg.reply("#d@을 굴립니다. @면체 #개를 굴립니다.")
    msg.reply("`!roll #d@ + $`, ex) `1d12 + 5`")
    msg.reply("`!roll #d@ - $`, ex) `1d12 - 5`")
    msg.reply("#d@을 굴리고 수정치 $를 더하거나 뺍니다. @면체 #개를 굴립니다. 나온 결과의 합에 수정치 $를 더하거나 뺍니다.")
    msg.reply("A개의 B면체를 굴립니다.")
    msg.reply("수정치 M을 더하거나 뺍니다.")
<|endoftext|>


<commit_before>import requests
from slackbot.bot import respond_to
from slackbot.bot import listen_to
import xmltodict
import os
import re
import random

# @listen_to("!주사위 (\d*)?d?(\d+)?", re.IGNORECASE)
@listen_to("!news (.*)", re.IGNORECASE)
def search_news(msg, q):
    url = "https://openapi.naver.com/v1/search/news.xml?query="
    url += '"' + q + '"'
    headers = {
        'X-Naver-Client-Id': os.environ['naver_client_id'],
        'X-Naver-Client-Secret': os.environ['naver_client_secret']
    }

    r = requests.get(url, headers=headers)
    result = r.text
    parsed = xmltodict.parse(result)

    for i in parsed['rss']['channel']['item']:
        msg.reply(i['title'])
        msg.reply(i['link'])
        msg.reply(i['originallink'])

<commit_msg>지식인 검색 추가.<commit_after>import requests
from slackbot.bot import respond_to
from slackbot.bot import listen_to
import xmltodict
import os
import re
import random

@listen_to("!뉴스 (.*)", re.IGNORECASE)
def search_news(msg, q):
    url = "https://openapi.naver.com/v1/search/news.xml?query="
    url += '"' + q + '"'
    headers = {
        'X-Naver-Client-Id': os.environ['naver_client_id'],
        'X-Naver-Client-Secret': os.environ['naver_client_secret']
    }

    r = requests.get(url, headers=headers)
    result = r.text
    parsed = xmltodict.parse(result)

    for i in parsed['rss']['channel']['item']:
        msg.reply(i['title'])
        msg.reply(i['link'])
        # msg.reply(i['originallink'])

@listen_to("!지식인 (.*)", re.IGNORECASE)
def search_news(msg, q):
    url = "https://openapi.naver.com/v1/search/kin.xml?query="
    url += '"' + q + '"'
    headers = {
        'X-Naver-Client-Id': os.environ['naver_client_id'],
        'X-Naver-Client-Secret': os.environ['naver_client_secret']
    }

    r = requests.get(url, headers=headers)
    result = r.text
    parsed = xmltodict.parse(result)

    for i in parsed['rss']['channel']['item']:
        msg.reply(i['title'])
        msg.reply(i['link'])
        msg.reply(i['originallink'])
<|endoftext|>