def save(): """ POST /save """ user_token = request.form["user_token"] enabled = request.form["enabled"] parsed_uri = urlparse(request.form["url"]) # Parse the URL, if lengthy URL get only domain name if parsed_uri.path: domain = parsed_uri.path else: domain = '{uri.scheme}://{uri.netloc}'.format(uri=parsed_uri) # Enabled flag to save in db enabled = 1 if enabled == "true" else 0 webmon_users = Users() users = webmon_users.get(user_token) if users.count() > 0: # If user already exists user = users.first() # If no changes compared to previous change if user.url == domain and user.enabled == enabled: return "URL added successfully" # Update to Db and send notification webmon_users.update(user, user_token, domain, enabled) timeline.send_update_notification(user_token, domain, enabled, update=True) else: # New Registration, add to db and send notification webmon_users.add(user_token, domain, enabled) timeline.send_update_notification(user_token, domain, enabled, update=False) return "URL added successfully"
def getUsers(): conf_ = conf.getInstance() users = Users() if request.method == 'POST': data = dict((k, request.form[k]) for k in request.form.keys()) return jsonify(users.add(data)) else: users.setColumns([ 'id', 'concat_ws(" ", first_name, last_name) as fullname', 'created' ]) users.setOrderBy('id') results = users.getTable() data = { 'users': [{ 'id': r['id'], 'fullname': r['fullname'], 'created': r['created'], 'uri': 'http://%s/users/%s' % (conf_.serverurl, r['id']), } for r in results] } return jsonify(data)
class Client: def __init__(self, room, nick=None, **kwargs): self.room = room self.nick = nick self.account = kwargs.get('account') self.password = kwargs.get('password') self.room_pass = kwargs.get('room_pass') self.proxy = kwargs.get('proxy', None) self.users = Users() self.state = RoomState() self.console = Console(self.room, log_path=config.CONFIG_PATH, chat_logging=config.CHAT_LOGGING, use_colors=config.CONSOLE_COLORS) self._connect_args = None self._ws = None self._is_connected = False self._req = 1 captcha.MAX_TRIES = kwargs.get('captcha_tries', 11) captcha.CAPTCHA_TIMEOUT = kwargs.get('captcha_timeout', 5) if self.nick is None or self.nick == '': self.nick = string_util.create_random_string(3, 20) @property def connected(self): """ True if connected, else False. """ return self._is_connected @property def page_url(self): """ Return the url of the room. """ return 'https://tinychat.com/room/%s' % self.room def login(self): """ Login to tinychat. :return: True if logged in, else False :rtype: bool """ if self.account is not None and self.password is not None: if not string_util.is_valid_string(self.account): raise InvalidAccountNameError( 'account name may only contain letter(a-z) and numbers(0-9)' ) else: account = Account(self.account, self.password, self.proxy) if not account.is_logged_in(): if account.login(): self.console.write('Logged in as `%s`' % self.account, Color.B_GREEN) else: self.console.write( 'Failed to login as `%s`' % self.account, Color.B_RED) return account.is_logged_in() return False def connect(self): """ Connect to the websocket server. """ if not string_util.is_valid_string(self.room): raise InvalidRoomNameError( 'room name may only contain letters(a-z) and numbers(0-9).') else: tc_header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:66.0) Gecko/20100101 Firefox/66.0', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate, br', 'Sec-WebSocket-Protocol': 'tc', 'Sec-WebSocket-Extensions': 'permessage-deflate' } websocket.enableTrace(config.DEBUG_MODE) self._connect_args = TinychatApi.connect_token(self.room) if self._connect_args is not None: self._ws = websocket.WebSocketApp( self._connect_args['endpoint'], header=tc_header, on_open=self.on_open, on_message=self.on_message, on_error=self.on_error, on_pong=self.on_pong) self._ws.run_forever(origin='https://tinychat.com', ping_interval=20, ping_timeout=5) else: log.info('missing connect args %s' % self._connect_args) def disconnect(self): """ Disconnect from the websocket server """ log.info('disconnecting from server') if self._ws is not None: self._ws.close(timeout=0) self._req = 1 self._ws = None self.users.clear() self.users.clear_banlist() def reconnect(self): """ Reconnect to the server. """ log.info('reconnecting') if self.connected: # this check might not be needed anymore self.disconnect() # maybe add a timeout here self.login() self.connect() # Event Dispatcher. def dispatch(self, event, event_data): """ Dispatch an event to a handler. :param event: The event to dispatch. :type event: str :param event_data: The event data. :type event_data: dict """ log.debug('dispatching event: %s' % event) method = 'on_%s' % event if hasattr(self, method): ProcessEvent(self, event, method, event_data).process() else: e = 'no event handler for `%s`' % event log.info(e) if config.DEBUG_MODE: self.console.write(e, Color.B_RED) # Method Caller. def run_method(self, method, *args, **kwargs): """ Call a method. :param method: The name of the method to run. :type method: str """ func = getattr(self, method, None) if func is not None: func(*args, **kwargs) # Error Handler. def error(self, event, error): """ Client event error handler. :param event: The event of the error. :type event: str :param error: Error description. :type error: str """ self.console.write('[ERROR] `%s` %s' % (event, error), Color.B_RED) # Websocket Events. def on_pong(self, data): """ Called in a response to the PING we send. NOTE: For some reason the data param is always empty. Apparently it should be frame.data, what ever that is (websocket._app.py line 278) :param data: I assume this should be PONG data. :type data: str """ _ = 'websocket pong data %s' % data if config.DEBUG_MODE: self.console.write(_, Color.B_GREEN) log.info(_) def on_error(self, error): """ Called if a websocket error occurs. """ if isinstance(error, websocket.WebSocketTimeoutException): self.console.write('%s, reconnecting..' % error, Color.B_RED) self.reconnect() else: self.error(type(error), error) def on_close(self): """ Called when/if the websocket connection gets closed. """ self._is_connected = False self.console.write('[CLOSED] the connection was closed.', Color.B_RED) def on_open(self): """ Called when the websocket handshake has been established. """ log.info('websocket connection connected.') self._is_connected = True self._join() def on_message(self, message): """ Called when we receive a message from the websocket endpoint. :param message: The websocket message. :type message: str """ if message: json_data = json.loads(message) event = json_data['tc'] if event == 'ping': self.on_ping() else: self.dispatch(event, json_data) # Application Events. def on_ping(self): """ Received on application ping. """ self.send_pong() def on_closed(self, data): """ Received when ever the connection gets closed by the server for what ever reason. :param data: The close data. :type data: dict """ code = data.get('error') if code == 0: self.console.write('There is no internet connection.', Color.B_RED) elif code == 1: self.console.write('Oops, chatroom has no free slots for users.', Color.B_RED) elif code == 2: self.console.write('Chatroom has been closed by administrator.', Color.B_RED) elif code == 3: self.console.write('Closed with code %s' % code, Color.B_RED) elif code == 4: self.console.write('You have been banned from the room.', Color.B_RED) elif code == 5: self.console.write('Reconnect code? %s' % code, Color.B_RED) self.reconnect() elif code == 6: self.console.write('Double account sign in.', Color.B_RED) elif code == 7: self.console.write( 'An error occurred while connecting to the server.', Color.B_RED) elif code == 8: # timeout error. usually when not entering # password or captcha within ~60 seconds. self.console.write('Timeout error %s' % code, Color.B_RED) elif code in [9, 10, 11]: # not sure why these occur self.console.write('Something went wrong, code %s' % code, Color.B_RED) elif code == 12: self.console.write('You have been kicked by a moderator.', Color.B_RED) self.reconnect() elif code == 22: self.console.write( 'You must be at least 18 years old and ' 'signed in to a verified Tinychat account to join this room', Color.B_RED) else: self.console.write('Connection was closed, code: %s' % code, Color.B_RED) # is connected is False in any of these cases self._is_connected = False def on_joined(self, data): """ Received when the client have joined the room successfully. :param data: This contains info about the client, such as user role and so on. :type data: dict """ log.info('client info: %s' % data) client = self.users.add(data.get('self'), is_client=True) self.console.write( 'Client joined the room: %s:%s' % (client.nick, client.handle), Color.B_GREEN) if client.is_mod: self.send_banlist() self.on_room_info(data.get('room')) def on_room_info(self, room_info): """ Received when the client have joined the room successfully. This information will only show in the console if debug is enabled. :param room_info: This contains information about the room such as about, profile image and so on. :type room_info: dict """ self.state.update(**room_info) if config.DEBUG_MODE: self.console.write('<Room Information>') self.console.write(self.state.formatted(), ts=False) def on_room_settings(self, room_settings): """ Received when a change has been made to the room settings(privacy page). This information will only show in the console if debug is enabled. :param room_settings: The room settings. :type room_settings: dict """ self.state.update(**room_settings) self.console.write('<Room State Changed>') if config.DEBUG_MODE: self.console.write(self.state.formatted(), ts=False) def on_userlist(self, user_list): # P """ Received upon joining a room. :param user_list: All users in the room. :type user_list: list """ for user in user_list: if user.is_owner: self.console.write( 'Joins room owner: %s:%s:%s' % (user.nick, user.handle, user.account), Color.B_BLUE) elif user.is_mod: self.console.write( 'Joins room moderator: %s:%s:%s' % (user.nick, user.handle, user.account), Color.B_RED) elif user.account: self.console.write( 'Joins: %s:%s:%s' % (user.nick, user.handle, user.account), Color.B_GREEN) else: self.console.write('Joins: %s:%s' % (user.nick, user.handle), Color.B_YELLOW) def on_join(self, user): # P """ Received when a user joins the room. :param user: The user joining as User object. :type user: Users.User """ if user.account: tc_info = TinychatApi.user_info(user.account) if tc_info is not None: self.users.add_tc_info(user.handle, tc_info) if user.is_owner: self.console.write( 'Owner joined: %s:%s:%s' % (user.nick, user.handle, user.account), Color.B_BLUE) elif user.is_mod: self.console.write( 'Moderator joined: %s:%s:%s' % (user.nick, user.handle, user.account), Color.B_RED) elif user.account: self.console.write( 'User joined: %s:%s:%s' % (user.nick, user.handle, user.account), Color.B_GREEN) else: self.console.write( 'Guest joined: %s:%s' % (user.nick, user.handle), Color.B_YELLOW) def on_nick(self, user): # P """ Received when a user changes nick name. :param user: The user changing nick as User object. :type user: Users.User """ old_nick = user.old_nicks[-2] self.console.write( '%s changed nick to %s:%s' % (old_nick, user.nick, user.handle), Color.B_CYAN) def on_quit(self, user): # P """ Received when a user leaves the room. :param user: The user leaving as User object. :type user: Users.User """ if user is not None: # user can be None if user is broadcasting, and then leaves? self.console.write( '%s:%s left the room.' % (user.nick, user.handle), Color.B_CYAN) def on_ban(self, banned): # P """ Received when the client bans a user. TODO: Test this :param banned: The user who was banned. :type banned: Users.BannedUser """ self.console.write('%s was banned.' % banned.nick, Color.B_RED) def on_unban(self, unbanned): # P """ Received when the client un-bans a user. TODO: Test this :param unbanned: The banned user who was unbanned. :type unbanned: Users.BannedUser """ self.console.write('%s was unbanned.' % unbanned.nick, Color.B_MAGENTA) def on_banlist(self, banlist): # P """ Received when a request for the ban list has been made. :param banlist: A list of BannedUser objects. :type banlist: list """ for banned in banlist: if banned.account is not None: self.console.write( 'Nick: %s, Account: %s, Banned By: %s' % (banned.nick, banned.account, banned.banned_by), Color.B_RED) else: self.console.write( 'Nick: %s, Banned By: %s' % (banned.nick, banned.banned_by), Color.B_RED) def on_msg(self, user, msg): # P """ Received when a message is sent to the room. :param user: The user sending a message as User object. :type user: Users.User :param msg: The text message as TextMessage object. :type msg: TextMessage """ self.console.write('%s: %s ' % (user.nick, msg.text), Color.B_GREEN) def on_pvtmsg(self, user, msg): # P """ Received when a user sends the client a private message. :param user: The user sending a private message as User object. :type user: Users.User :param msg: The text message as TextMessage object. :type msg: TextMessage """ self.console.write('[PM] %s: %s' % (user.nick, msg.text), Color.WHITE) def on_publish(self, user): # P """ Received when a user starts broadcasting. :param user: The user broadcasting as User object. :type user: Users.User """ self.console.write('%s:%s is broadcasting.' % (user.nick, user.handle), Color.BLUE) def on_unpublish(self, user): # P """ Received when a user stops broadcasting. :param user: The user who stops broadcasting as User object. :type user: Users.User """ self.console.write( '%s:%s stopped broadcasting.' % (user.nick, user.handle), Color.BLUE) def on_sysmsg(self, msg): """ System messages sent from the server to all clients (users). These messages are special events notifications. :param msg: The special notifications message data. :type msg: dict """ text = msg.get('text') if 'banned' in text and self.users.client.is_mod: self.users.clear_banlist() self.send_banlist() elif 'green room enabled' in text: self.state.set_greenroom(True) elif 'green room disabled' in text: self.state.set_greenroom(False) self.console.write('[SYSTEM]: %s' % text, Color.WHITE) def on_password(self, req_id): # P """ Received when a room is password protected. An on_closed event with code 8 will be called if a password has not been provided within ~60 seconds 3 password attempts can be tried before a reconnect is required. TODO: If the room_pass is correct, add it to RoomState? How? """ self.console.write('Password protected room (%s)' % req_id, Color.B_RED) if self.room_pass is not None and req_id == 1: self.console.write('Sending room password: %s' % self.room_pass, Color.GREEN) elif self.room_pass is not None and req_id > 1: # TODO: Maybe add user input.. self.console.write( 'The room password provided is ' 'incorrect, closing.', Color.B_RED) self.disconnect() def on_pending_moderation(self, user): # P """ Received when a user is waiting in the green room. :param user: The user waiting in the green room as User object. :type user: Users.User """ self.console.write( '%s:%s is waiting for broadcast approval.' % (user.nick, user.handle), Color.B_YELLOW) def on_stream_moder_allow(self, allowed, allowed_by): # P """ Received when a user has been allowed to broadcast in a green room. :param allowed: The user that was allowed to broadcast. :type allowed: Users.User :param allowed_by: The user allowing the broadcast. :type allowed_by: Users.User """ if allowed_by.handle == self.users.client.handle: self.console.write( 'The bot allowed %s:%s to broadcast.' % (allowed.nick, allowed.handle), Color.B_GREEN) else: self.console.write( '%s:%s allowed %s:%s to broadcast.' % (allowed_by.nick, allowed_by.handle, allowed.nick, allowed.handle), Color.B_YELLOW) def on_stream_moder_close(self, closed): # P """ Received when a user has their broadcast closed by the client. :param closed: The user that was closed. :type closed: Users.User """ self.console.write('%s:%s was closed.' % (closed.nick, closed.handle), Color.B_YELLOW) def on_captcha(self, site_key): # P """ Received when a room has captcha enabled. :param site_key: The captcha site key. :type site_key: str """ if config.ANTI_CAPTCHA_KEY is not None: self.console.write( 'Starting captcha solving service, please wait...', Color.B_GREEN) thread_task(self._captcha_service, site_key) else: self.console.write('Captcha %s' % site_key, Color.B_RED, ts=False) self.disconnect() def _captcha_service(self, site_key): try: ac = captcha.AntiCaptcha(self.page_url, config.ANTI_CAPTCHA_KEY) response = ac.solver(site_key) except (captcha.NoFundsError, captcha.MaxTriesError) as e: self.console.write(e) self.disconnect() except captcha.AntiCaptchaApiError as ace: self.console.write(ace.description) self.disconnect() else: if response.token is not None: self.console.write( 'Captcha solved in %s seconds with ' '%s tries and a cost of %s$' % (response.solve_time, response.tries, response.cost), Color.B_GREEN) self.send_captcha(response.token) # Media Events. def on_yut_playlist(self, playlist_data): """ Received when a request for the playlist has been made. The playlist is as, one would see if being a moderator and using a web browser. :param playlist_data: The data of the items in the playlist. :type playlist_data: dict """ pass def on_yut_play(self, user, youtube): # P """ Received when a youtube gets started or searched. :param user: The User object of the user starting or searching the youtube. :type user: Users.User :param youtube: The YoutubeMessage object. :type youtube: YoutubeMessage """ if user is None: self.console.write('[YOUTUBE] %s is playing.' % youtube.title, Color.B_YELLOW) else: if not youtube.is_response: if youtube.offset == 0: self.console.write( '%s is playing %s' % (user.nick, youtube.title), Color.B_YELLOW) elif youtube.offset > 0: self.console.write( '%s searched %s to %s' % (user.nick, youtube.title, youtube.offset), Color.B_YELLOW) def on_yut_pause(self, user, youtube): # P """ Received when a youtube gets paused or searched while paused. :param user: The User object of the user pausing the video. :type user: Users.User :param youtube: The YoutubeMessage object. :type youtube: YoutubeMessage """ if not youtube.is_response: self.console.write( '%s paused %s at %s' % (user.nick, youtube.title, youtube.offset), Color.B_YELLOW) def on_yut_stop(self, youtube): # P """ Received when a youtube is stopped. :param youtube: The YoutubeMessage object. :type youtube: YoutubeMessage """ self.console.write( '%s was stopped at %s (%s)' % (youtube.title, youtube.offset, youtube.duration), Color.B_YELLOW) # Message Construction. def _join(self): """ The initial connect message to the room. The client sends this after the websocket handshake has been established. """ pat = '^[a-zA-Z0-9_]*$' if not string_util.is_valid_string(self.nick, pattern=pat): raise InvalidNickNameError('nick name may only contain a-zA-Z0-9_') else: rtc_version = TinychatApi.rtc_version(self.room) if rtc_version is None: rtc_version = config.FALLBACK_RTC_VERSION log.debug('failed to parse rtc version, using fallback: %s' % rtc_version) payload = { 'tc': 'join', 'req': self._req, 'useragent': 'tinychat-client-webrtc-undefined_win32-' + rtc_version, 'token': self._connect_args['token'], 'room': self.room, 'nick': self.nick } self.send(payload) def send_pong(self): """ Send a response to a ping. """ payload = {'tc': 'pong', 'req': self._req} self.send(payload) def set_nick(self): """ Send a nick message. """ payload = {'tc': 'nick', 'req': self._req, 'nick': self.nick} self.send(payload) def send_chat_msg(self, msg): """ Send a chat message to the room. :param msg: The message to send. :type msg: str """ payload = {'tc': 'msg', 'req': self._req, 'text': msg} self.send(payload) def send_private_msg(self, handle, msg): """ Send a private message to a user. :param handle: The handle of the user to send the message to. :type handle: int :param msg: The private message to send. :type msg: str """ payload = { 'tc': 'pvtmsg', 'req': self._req, 'text': msg, 'handle': handle } self.send(payload) def send_kick_msg(self, handle): """ Send a kick message to kick a user out of the room. :param handle: The handle of the user to kick. :type handle: int """ payload = {'tc': 'kick', 'req': self._req, 'handle': handle} self.send(payload) def send_ban_msg(self, handle): """ Send a ban message to ban a user from the room. :param handle: The handle of the user to ban. :type handle: int """ payload = {'tc': 'ban', 'req': self._req, 'handle': handle} self.send(payload) def send_unban_msg(self, ban_id): """ Send a un-ban message to un-ban a banned user. :param ban_id: The ban ID of the user to un-ban. :type ban_id: int """ payload = {'tc': 'unban', 'req': self._req, 'id': ban_id} self.send(payload) def send_banlist(self): """ Send a banlist request message. """ payload = {'tc': 'banlist', 'req': self._req} self.send(payload) def send_room_password_msg(self, password): """ Send a room password message. :param password: The room password. :type password: str """ payload = {'tc': 'password', 'req': self._req, 'password': password} self.send(payload) def send_cam_approve_msg(self, handle): """ Allow a user to broadcast in green room enabled room. :param handle: The handle of the user. :type handle: int """ payload = { 'tc': 'stream_moder_allow', 'req': self._req, 'handle': handle } self.send(payload) def send_close_user_msg(self, handle): """ Close a users broadcast. :param handle: The handle of the user. :type handle: int """ payload = { 'tc': 'stream_moder_close', 'req': self._req, 'handle': handle } self.send(payload) def send_captcha(self, token): """ Send the captcha token. :param token: The captcha response token. :type token: str """ payload = {'tc': 'captcha', 'req': self._req, 'token': token} self.send(payload) # Media. def send_yut_playlist(self): """ Send a youtube playlist request. """ payload = {'tc': 'yut_playlist', 'req': self._req} self.send(payload) def send_yut_playlist_add(self, video_id, duration, title, image): """ Add a youtube to the web browser playlist. I haven't explored this yet. :param video_id: the ID of the youtube video. :type video_id: str :param duration: The duration of the youtube video (in seconds). :type duration: int :param title: The title of the youtube video. :type title: str :param image: The thumbnail image url of the video. :type image: str """ payload = { 'tc': 'yut_playlist_add', 'req': self._req, 'item': { 'id': video_id, 'duration': duration, 'title': title, 'image': image } } self.send(payload) def send_yut_playlist_remove(self, video_id, duration, title, image): """ Remove a playlist item from the web browser based playlist. I haven't explored this yet. :param video_id: The ID of the youtube video to remove. :type video_id: str :param duration: The duration of the youtube video to remove. :type duration: int | float :param title: The title of the youtube video to remove. :type title: str :param image: The thumbnail image url of the youtube video to remove. :type image: str """ payload = { 'tc': 'yut_playlist_remove', 'req': self._req, 'item': { 'id': video_id, 'duration': duration, 'title': title, 'image': image } } self.send(payload) def send_yut_playlist_mode(self, random_=False, repeat=False): """ Set the mode of the web browser based playlist. I haven't explored this yet. :param random_: Setting this to True will make videos play at random i assume. :type random_: bool :param repeat: Setting this to True will make the playlist repeat itself i assume. :type repeat: bool """ payload = { 'tc': 'yut_playlist_mode', 'req': self._req, 'mode': { 'random': random_, 'repeat': repeat } } self.send(payload) def send_yut_play(self, video_id, duration, title, offset=0): """ Start or search a youtube video. :param video_id: The ID of the youtube video to start or search. :type video_id: str :param duration: The duration of the video in seconds. :type duration: int | float :param title: The title of the youtube. :type title: str :param offset: The offset seconds to start the video at in the case of doing a search. :type offset: int | float """ payload = { 'tc': 'yut_play', 'req': self._req, 'item': { 'id': video_id, 'duration': duration, 'offset': offset, 'title': title } } if offset != 0: del payload['item']['title'] payload['item']['playlist'] = False payload['item']['seek'] = True self.send(payload) def send_yut_pause(self, video_id, duration, offset=0): """ Pause, or search while a youtube video is paused . :param video_id: The ID of the youtube video to pause or search. :type video_id: str :param duration: The duration of the video in seconds. :type duration: int |float :param offset: The offset seconds to pause the video at in case of doing seach while in pause. :type offset: int |float """ payload = { 'tc': 'yut_pause', 'req': self._req, 'item': { 'id': video_id, 'duration': duration, 'offset': offset } } self.send(payload) def send_yut_stop(self, video_id, duration, offset=0): """ Stop a youtube video that is currently playing. :param video_id: The ID of the youtube to stop. :type video_id: str :param duration: The duration of the youtube video in seconds. :type duration: int | float :param offset: The offset seconds when the youtube gets stopped. :type offset: int |float """ payload = { 'tc': 'yut_stop', 'req': self._req, 'item': { 'id': video_id, 'duration': duration, 'offset': offset } } self.send(payload) # Message Sender Wrap. def send(self, payload): """ Message sender wrapper used by all methods that sends. :param payload: The object to send. This should be an object that can be serialized to json. :type payload: dict | object """ if self.connected: _payload = json.dumps(payload) self._ws.send(_payload) self._req += 1 log.debug('%s connected: %s' % (_payload, self.connected))
from users import Users from members import Members from team import Team import smugmug USER_NAME = "*****@*****.**" TEAM_NAME = "ftc16072" PASSWORD = "******" membersList = [ "Andrew", "Chirag", "Eric", "Izaak", "Nithya", "Philip", "Preeti", "Rishi", "Arjun", "Ryan", "Nikhil" ] albumDict = { '2019-04-01': '/api/v2/album/VgQcSw', '2020-03-01': '/api/v2/album/2z78cj' } if __name__ == "__main__": users = Users() members = Members() team = Team(TEAM_NAME) users.add(USER_NAME, TEAM_NAME, PASSWORD) user = users.getUser(USER_NAME, PASSWORD) with user.team.dbConnect() as connection: members.createTable(connection) members.insertMembers(connection, membersList) smugmug.createTable(connection) for date, album in albumDict: smugmug.addEntry(connection, date, album)
class DoorApp(object): def __init__(self): self.users = Users() self.lookup = TemplateLookup( directories=['HTMLTemplates'], default_filters=['h']) self.door = DoorGPIO() def template(self, name, **kwargs): return self.lookup.get_template(name).render(**kwargs) def show_mainpage(self, error=''): return self.template("mainpage.html", error=error) @cherrypy.expose def index(self): Cookie('username').delete() return self.show_mainpage() @cherrypy.expose def admin(self, username=None, password=None): username_sess = Cookie('username').get('') if username_sess: username = username_sess if username_sess or self.users.verify_password(username, password): username = Cookie('username').set(self.users.get(username)) return self.template("admin.html", uname=username, users=self.users.get_users(), error="") return self.show_mainpage("Incorrect user/password combination") @cherrypy.expose def log(self): f = os.popen('tail -n 100 doorapp.log') return self.template("log.html", error="", logFile=f) @cherrypy.expose def addUser(self, uname=None, mac=None, barcode=None, admin=False): if Cookie('username').get(''): if self.users.get(uname): return "Already a user with that name" else: self.users.add(username=uname, mac=mac, password=mac[-5:], barcode=barcode, admin=admin) return "" return "An admin is not currently logged in" @cherrypy.expose def editUser(self, uname=None, mac=None, barcode=None, admin=None): if Cookie('username').get(''): if self.users.get(uname): self.users.edit(uname, mac, admin) return "" else: return "No user with that name" return "An admin is not currently logged in" @cherrypy.expose def add(self): if Cookie('username').get(''): return self.template("user.html", edit=False, uname='', mac='', barcode='', admin=False) return self.show_mainpage("An admin is not currently logged in") @cherrypy.expose def edit(self, uname=None): if Cookie('username').get(''): return self.template("user.html", edit=True, uname=uname, mac=self.users.get_mac(uname), barcode=self.users.get_barcode(uname), admin=self.users.get_admin(uname)) return self.show_mainpage("An admin is not currently logged in") @cherrypy.expose def delete(self, uname=None): if Cookie('username').get(''): self.users.remove(uname) return "" return self.show_mainpage("An admin is not currently logged in") @cherrypy.expose def resetPass(self, uname=None): if Cookie('username').get(''): self.users.change_password(uname, self.users.get_mac(uname)[-5:]) return "" return self.show_mainpage("An admin is not currently logged in") @cherrypy.expose def unlock(self, username=None, password=None): if self.users.verify_password(username, password): if password == self.users.get_mac(username)[-5:]: return "Must change password from default before unlocking" self.door.unlock(username) return "" else: return "Incorrect user/password combination" @cherrypy.expose def changePass(self, username=None, oldpass=None, newpass=None): if self.users.verify_password(username, oldpass): self.users.change_password(username, newpass) return "" else: return "Incorrect user/password combination"