# All configuration values have a default; values that are commented out
# serve to show the default.
-import sys
-import os
-
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
# built documents.
#
# The short X.Y version.
-version = '0.5.9'
+version = '0.6.0'
# The full version, including alpha/beta/rc tags.
-release = '0.5.9'
+release = '0.6.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
+++ /dev/null
-import os
-from sqlalchemy import create_engine
-from sqlalchemy.orm import sessionmaker
-from sqlalchemy.pool import StaticPool
-from .table_def import *
-
-
-class RainbowDB():
-
- engine = None
-
- def __init__(self):
- """
- Init DB
- """
- if os.path.isfile('rainbow.db'):
- os.system('rm -rf rainbow.db')
- init_db()
- self.engine = create_engine('sqlite:///rainbow.db', echo=False, connect_args={'check_same_thread':False}, poolclass=StaticPool)
-
- def tweet_store(self, tweet_id):
- """
- Store tweet id
- """
- Session = sessionmaker(bind=self.engine)
- session = Session()
- t = Tweet(tweet_id)
- session.add(t)
- session.commit()
-
- def rainbow_to_tweet_query(self, rid):
- """
- Query base of rainbow id
- """
- Session = sessionmaker(bind=self.engine)
- session = Session()
- res = session.query(Tweet).filter_by(rainbow_id=rid).all()
- return res
-
- def tweet_to_rainbow_query(self, tid):
- """
- Query base of tweet id
- """
- Session = sessionmaker(bind=self.engine)
- session = Session()
- res = session.query(Tweet).filter_by(tweet_id=tid).all()
- return res
-
- def message_store(self, message_id):
- """
- Store message id
- """
- Session = sessionmaker(bind=self.engine)
- session = Session()
- m = Message(message_id)
- session.add(m)
- session.commit()
-
- def rainbow_to_message_query(self, rid):
- """
- Query base of rainbow id
- """
- Session = sessionmaker(bind=self.engine)
- session = Session()
- res = session.query(Message).filter_by(rainbow_id=rid).all()
- return res
-
- def message_to_rainbow_query(self, mid):
- """
- Query base of message id
- """
- Session = sessionmaker(bind=self.engine)
- session = Session()
- res = session.query(Message).filter_by(message_id=mid).all()
- return res
-
- def theme_store(self, theme_name):
- """
- Store theme
- """
- Session = sessionmaker(bind=self.engine)
- session = Session()
- th = Theme(theme_name)
- session.add(th)
- session.commit()
-
- def theme_update(self, theme_name):
- """
- Update theme
- """
- Session = sessionmaker(bind=self.engine)
- session = Session()
- res = session.query(Theme).all()
- for r in res:
- r.theme_name = theme_name
- session.commit()
-
- def theme_query(self):
- """
- Query theme
- """
- Session = sessionmaker(bind=self.engine)
- session = Session()
- res = session.query(Theme).all()
- return res
-
- def semaphore_store(self, lock, pause):
- """
- Store semaphore lock
- """
- Session = sessionmaker(bind=self.engine)
- session = Session()
- th = Semaphore(lock, pause)
- session.add(th)
- session.commit()
-
- def semaphore_update_lock(self, lock):
- """
- Update semaphore lock
- """
- Session = sessionmaker(bind=self.engine)
- session = Session()
- res = session.query(Semaphore).all()
- for r in res:
- r.lock = lock
- session.commit()
-
- def semaphore_update_pause(self, pause):
- """
- Update semaphore pause
- """
- Session = sessionmaker(bind=self.engine)
- session = Session()
- res = session.query(Semaphore).all()
- for r in res:
- r.pause = pause
- session.commit()
-
- def semaphore_query_lock(self):
- """
- Query semaphore lock
- """
- Session = sessionmaker(bind=self.engine)
- session = Session()
- res = session.query(Semaphore).all()
- return res[0].lock
-
- def semaphore_query_pause(self):
- """
- Query semaphore pause
- """
- Session = sessionmaker(bind=self.engine)
- session = Session()
- res = session.query(Semaphore).all()
- return res[0].pause
from .c_image import *
from .colors import *
from .config import *
-from .db import *
from .py3patch import *
-
-db = RainbowDB()
-g = {}
+# Draw global variables
+dg = {}
def init_cycle():
"""
Notify from rainbow
"""
- g['cyc'] = init_cycle()
- g['cache'] = {}
+ dg['cyc'] = init_cycle()
+ dg['cache'] = {}
def order_rainbow(s):
"""
@wraps(func)
def wrapper(*args):
- if args not in g['cache']:
- g['cache'][args] = func(*args)
- return g['cache'][args]
+ if args not in dg['cache']:
+ dg['cache'][args] = func(*args)
+ return dg['cache'][args]
return wrapper
"""
Cycle the colors_shuffle
"""
- return next(g['cyc'])(s)
+ return next(dg['cyc'])(s)
def ascii_art(text):
"""
fi = figlet_format(text, font='doom')
print('\n'.join(
- [next(g['cyc'])(i) for i in fi.split('\n')]
+ [next(dg['cyc'])(i) for i in fi.split('\n')]
))
return theme in themes
-def reload_theme(current_config):
+def reload_theme(value, prev):
"""
Check current theme and update if necessary
"""
- exists = db.theme_query()
- themes = [t.theme_name for t in exists]
- if current_config != themes[0]:
+ if value != prev:
config = os.path.dirname(
- __file__) + '/colorset/' + current_config + '.json'
+ __file__) + '/colorset/' + value + '.json'
# Load new config
data = load_config(config)
if data:
for d in data:
c[d] = data[d]
- # Restart color cycle and update db/config
+ # Restart color cycle and update config
start_cycle()
- db.theme_update(current_config)
- set_config('THEME', current_config)
+ set_config('THEME', value)
+ return value
+ return prev
def color_func(func_name):
Draw the rainbow
"""
- # Check the semaphore lock (stream process only)
+ # Check the semaphore pause and lock (stream process only)
if check_semaphore:
- if db.semaphore_query_pause():
+ if c['pause']:
return
- while db.semaphore_query_lock():
+ while c['lock']:
time.sleep(0.5)
- # Check config and theme
+ # Check config
check_config()
- reload_theme(c['THEME'])
# Retrieve tweet
tid = t['id']
return
# Get rainbow id
- res = db.tweet_to_rainbow_query(tid)
- if not res:
- db.tweet_store(tid)
- res = db.tweet_to_rainbow_query(tid)
- rid = res[0].rainbow_id
+ if tid not in c['tweet_dict']:
+ c['tweet_dict'].append(tid)
+ rid = len(c['tweet_dict']) - 1
+ else:
+ rid = c['tweet_dict'].index(tid)
# Format info
name = cycle_color(name)
Print direct message
"""
- # Check the semaphore lock (stream process only)
+ # Check the semaphore pause and lock (stream process only)
if check_semaphore:
- if db.semaphore_query_pause():
+ if c['pause']:
return
- while db.semaphore_query_lock():
+ while c['lock']:
time.sleep(0.5)
# Retrieve message
clock = date.strftime(clock_format)
# Get rainbow id
- res = db.message_to_rainbow_query(mid)
- if not res:
- db.message_store(mid)
- res = db.message_to_rainbow_query(mid)
- rid = res[0].rainbow_id
+ if mid not in c['message_dict']:
+ c['message_dict'].append(mid)
+ rid = len(c['message_dict']) - 1
+ else:
+ rid = c['message_dict'].index(mid)
# Draw
sender_name = cycle_color(sender_name)
"""
Display a list
"""
- for g in group:
+ for grp in group:
# Format
- name = g['full_name']
+ name = grp['full_name']
name = color_func(c['GROUP']['name'])(name + ' : ')
- member = str(g['member_count'])
+ member = str(grp['member_count'])
member = color_func(c['GROUP']['member'])(member + ' member')
- subscriber = str(g['subscriber_count'])
+ subscriber = str(grp['subscriber_count'])
subscriber = color_func(
c['GROUP']['subscriber'])(
subscriber +
' subscriber')
- description = g['description'].strip()
+ description = grp['description'].strip()
description = color_func(c['GROUP']['description'])(description)
- mode = g['mode']
+ mode = grp['mode']
mode = color_func(c['GROUP']['mode'])('Type: ' + mode)
- created_at = g['created_at']
+ created_at = grp['created_at']
date = parser.parse(created_at)
date = date - datetime.timedelta(seconds=time.timezone)
clock = date.strftime('%Y/%m/%d %H:%M:%S')
"""
Colorful user's timeline stream
"""
-from multiprocessing import Process
-
import os
import os.path
import sys
from .config import *
from .consumer import *
from .interactive import *
-from .db import *
from .c_image import *
from .py3patch import *
# Global values
g = {}
-# Database
-db = RainbowDB()
-
# Lock for streams
-
StreamLock = threading.Lock()
# Commands
files = os.listdir(os.path.dirname(__file__) + '/colorset')
themes = [f.split('.')[0] for f in files if f.split('.')[-1] == 'json']
g['themes'] = themes
- db.theme_store(c['THEME'])
+ g['prev_theme'] = c['THEME']
# Semaphore init
- db.semaphore_store(False, False)
+ c['lock'] = False
+ c['pause'] = False
+ # Init tweet dict and message dict
+ c['tweet_dict'] = []
+ c['message_dict'] = []
# Image on term
c['IMAGE_ON_TERM'] = args.image_on_term
except:
printNicely(red('Sorry I can\'t understand.'))
return
- tid = db.rainbow_to_tweet_query(id)[0].tweet_id
+ tid = c['tweet_dict'][id]
t.statuses.retweet(id=tid, include_entities=False, trim_user=True)
except:
printNicely(red('Sorry I can\'t understand.'))
return
- tid = db.rainbow_to_tweet_query(id)[0].tweet_id
+ tid = c['tweet_dict'][id]
tweet = t.statuses.show(id=tid)
screen_name = tweet['user']['screen_name']
text = tweet['text']
except:
printNicely(red('Sorry I can\'t understand.'))
return
- tid = db.rainbow_to_tweet_query(id)[0].tweet_id
+ tid = c['tweet_dict'][id]
# Get display num if exist
try:
num = int(g['stuff'].split()[1])
except:
printNicely(red('Sorry I can\'t understand.'))
return
- tid = db.rainbow_to_tweet_query(id)[0].tweet_id
+ tid = c['tweet_dict'][id]
t.favorites.create(_id=tid, include_entities=False)
printNicely(green('Favorited.'))
draw(t.statuses.show(id=tid))
except:
printNicely(red('Sorry I can\'t understand.'))
return
- tid = db.rainbow_to_tweet_query(id)[0].tweet_id
+ tid = c['tweet_dict'][id]
user = t.statuses.show(id=tid)['user']['screen_name']
status = ' '.join(g['stuff'].split()[1:])
status = '@' + user + ' ' + status.decode('utf-8')
"""
t = Twitter(auth=authen())
try:
- rid = int(g['stuff'].split()[0])
+ id = int(g['stuff'].split()[0])
except:
printNicely(red('Sorry I can\'t understand.'))
return
- tid = db.rainbow_to_tweet_query(rid)[0].tweet_id
+ tid = c['tweet_dict'][id]
t.statuses.destroy(id=tid)
printNicely(green('Okay it\'s gone.'))
except:
printNicely(red('Sorry I can\'t understand.'))
return
- tid = db.rainbow_to_tweet_query(id)[0].tweet_id
+ tid = c['tweet_dict'][id]
t.favorites.destroy(_id=tid)
printNicely(green('Okay it\'s unfavorited.'))
draw(t.statuses.show(id=tid))
if target != 'image':
return
id = int(g['stuff'].split()[1])
- tid = db.rainbow_to_tweet_query(id)[0].tweet_id
+ tid = c['tweet_dict'][id]
tweet = t.statuses.show(id=tid)
media = tweet['entities']['media']
for m in media:
try:
if not g['stuff'].isdigit():
return
- tid = db.rainbow_to_tweet_query(g['stuff'])[0].tweet_id
+ tid = c['tweet_dict'][g['stuff']]
tweet = t.statuses.show(id=tid)
link_ary = [
u for u in tweet['text'].split() if u.startswith('http://')]
"""
t = Twitter(auth=authen())
try:
- rid = int(g['stuff'].split()[0])
+ id = int(g['stuff'].split()[0])
except:
printNicely(red('Sorry I can\'t understand.'))
- mid = db.rainbow_to_message_query(rid)[0].message_id
+ mid = c['message_dict'][id]
t.direct_messages.destroy(id=mid)
printNicely(green('Message deleted.'))
set_config(key, value)
# Apply theme immediately
if key == 'THEME':
- reload_theme(value)
+ c['THEME'] = reload_theme(value,c['THEME'])
g['decorated_name'] = lambda x: color_func(
c['DECORATED_NAME'])(
'[' + x + ']: ')
# Change theme
try:
# Load new theme
- reload_theme(g['stuff'])
+ c['THEME'] = reload_theme(g['stuff'],c['THEME'])
# Redefine decorated_name
g['decorated_name'] = lambda x: color_func(
c['DECORATED_NAME'])(
'[' + x + ']: ')
printNicely(green('Theme changed.'))
- except:
+ except Exception as e:
+ print e
printNicely(red('No such theme exists.'))
"""
Pause stream display
"""
- db.semaphore_update_pause(True)
+ c['pause'] = True
printNicely(green('Stream is paused'))
"""
Replay stream
"""
- db.semaphore_update_pause(False)
+ c['pause'] = False
printNicely(green('Stream is running back now'))
"""
try:
save_history()
- os.system('rm -rf rainbow.db')
printNicely(green('See you next time :)'))
except:
pass
read_history()
reset()
while True:
+ # Prompt redraw is needed when user is typing
+ # raw_input
if g['prefix']:
line = raw_input(g['decorated_name'](c['PREFIX']))
else:
except:
cmd = ''
g['cmd'] = cmd
+ # Prompt redraw not need when raw_input done
try:
# Lock the semaphore
- db.semaphore_update_lock(True)
+ c['lock'] = True
# Save cmd to global variable and call process
g['stuff'] = ' '.join(line.split()[1:])
# Process the command
process(cmd)()
# Not re-display
- if cmd in ['t', 'rt', 'rep']:
+ if cmd in ['switch', 't', 'rt', 'rep']:
g['prefix'] = False
else:
g['prefix'] = True
# Release the semaphore lock
- db.semaphore_update_lock(False)
+ c['lock'] = False
except Exception:
printNicely(red('OMG something is wrong with Twitter right now.'))
StreamLock.acquire()
g['stream_stop'] = False
for tweet in tweet_iter:
- if(g['stream_stop'] == True):
+ if(g['stream_stop']):
StreamLock.release()
break
if tweet is None:
fil=args.filter,
ig=args.ignore,
)
- sys.stdout.write(g['decorated_name'](c['PREFIX']) + readline.get_line_buffer())
- sys.stdout.flush()
elif tweet.get('direct_message'):
print_message(tweet['direct_message'], check_semaphore=True)
except TwitterHTTPError:
magenta("We have maximum connection problem with twitter'stream API right now :("))
printNicely(magenta("Let's try again later."))
save_history()
- os.system('rm -rf rainbow.db')
sys.exit()
# Spawn stream thread
th = threading.Thread(target=stream, args=(c['USER_DOMAIN'], args, g['original_name']))
+++ /dev/null
-from sqlalchemy import *
-from sqlalchemy.ext.declarative import declarative_base
-
-engine = create_engine('sqlite:///rainbow.db', echo=False)
-Base = declarative_base()
-
-
-class Tweet(Base):
-
- __tablename__ = "tweet"
-
- rainbow_id = Column(Integer, primary_key=True)
- tweet_id = Column(Integer)
-
- def __init__(self, tweet_id):
- self.tweet_id = tweet_id
-
-
-class Message(Base):
-
- __tablename__ = "message"
-
- rainbow_id = Column(Integer, primary_key=True)
- message_id = Column(Integer)
-
- def __init__(self, message_id):
- self.message_id = message_id
-
-
-class Theme(Base):
-
- __tablename__ = "theme"
-
- theme_id = Column(Integer, primary_key=True)
- theme_name = Column(String(20))
-
- def __init__(self, theme_name):
- self.theme_name = theme_name
-
-
-class Semaphore(Base):
-
- __tablename__ = "semaphore"
-
- semaphore_id = Column(Integer, primary_key=True)
- lock = Column(Boolean)
- pause = Column(Boolean)
-
- def __init__(self, lock, pause):
- self.lock = lock
- self.pause = pause
-
-
-def init_db():
- Base.metadata.create_all(engine)
import sys
# Bumped version
-version = '0.5.9'
+version = '0.6.0'
# Require
install_requires = [
"python-dateutil",
"requests",
"pyfiglet",
- "SQLAlchemy",
"twitter",
"Pillow",
]