Exemplo n.º 1
0
class GUI:
    def __init__(self):
        self.window = Tk()
        self.main_window_init()
        self.client = Snapchat()
        self.start()

    def start(self):
        self.window.mainloop()

    def main_window_init(self):

        # set window title
        self.window.wm_title('pySnap')

        # configure menu
        menu_bar = Menu(self.window)
        self.window.config(menu=menu_bar)

        # File menu
        file_menu = Menu(menu_bar, tearoff=0)
        file_menu.add_command(label='Send media', command=self.send_media)
        file_menu.add_separator()
        file_menu.add_command(label='Exit', command=self.window.quit)
        menu_bar.add_cascade(label='File', menu=file_menu)

        # Edit menu
        account_menu = Menu(menu_bar, tearoff=0)
        account_menu.add_command(
            label='Copy Token',
            command=lambda: [
                pyperclip.copy(self.client.auth_token),
                tkMessageBox.showinfo('Token copied',
                                      'Auth token copied to clipboard!')
            ])
        account_menu.add_command(label='Logout')
        account_menu.add_command(label='Switch user')
        menu_bar.add_cascade(label='Accounts', menu=account_menu)

        # Prepare the image canvas to be replaced by map image
        self.snap_list = Frame(self.window, width=800, height=600)
        self.snap_list.pack(fill=BOTH, expand=1, side=RIGHT)
        self.window.withdraw()

        w = Toplevel(self.window)
        msg = Label(w, text='Login')
        msg.pack()
        username_panel = PanedWindow(w)
        username_panel.pack(fill=BOTH, expand=1)
        password_panel = PanedWindow(w)
        password_panel.pack(fill=BOTH, expand=1)
        token_panel = PanedWindow(w)
        token_panel.pack(fill=BOTH, expand=1)
        Label(username_panel, text='Username').pack(side=LEFT)
        username_entry = Entry(username_panel)
        username_entry.pack(side=RIGHT)
        Label(password_panel, text='Password').pack(side=LEFT)
        password_entry = Entry(password_panel, show='*')
        password_entry.pack(side=RIGHT)
        Label(token_panel, text='Auth Token').pack(side=LEFT)
        token_entry = Entry(token_panel)
        token_entry.pack(side=RIGHT)
        panel = PanedWindow(w)
        panel.pack()
        ok_btn = Button(panel,
                        text=' OK ',
                        command=lambda: self.login(w, username_entry.get(
                        ), password_entry.get(), token_entry.get()))
        ok_btn.pack(side=LEFT)
        cancel_btn = Button(panel,
                            text=' Cancel ',
                            command=lambda: self.cancel_login(w))
        cancel_btn.pack(side=RIGHT)

    def login(self, w, username, password, auth_token):
        w.destroy()
        if password == '':
            if not self.client.login_token(username, auth_token):
                tkMessageBox.showinfo('Failed to login',
                                      'Wrong username or password?')
                self.window.quit()
                return
        else:
            if not self.client.login(username, password):
                tkMessageBox.showinfo('Failed to login',
                                      'Wrong username or password?')
                self.window.quit()
                return
        snaps = self.client.get_snaps()
        if not snaps:
            tkMessageBox.showinfo('Unknown error', 'Something went wrong.')
            self.window.quit()
            return
        Label(self.snap_list,
              text='Logged in as {0}\n'.format(username)).pack()
        for snap in snaps:
            snap_panel = PanedWindow(self.snap_list)
            snap_panel.pack(fill=X, expand=1)
            Label(snap_panel,
                  text='{0} ({1}s, sent {2})'.format(
                      snap['sender'], snap['time'],
                      datetime.fromtimestamp(snap['sent'] /
                                             1000))).pack(side=LEFT)
            open_btn = Button(snap_panel,
                              text=' Open ',
                              command=lambda snap=snap: self.open_snap(snap))
            open_btn.pack(side=RIGHT)
        self.window.update()
        self.window.deiconify()

    def cancel_login(self, w):
        w.destroy()
        self.window.quit()

    @staticmethod
    def route_map_callback(filename, data):
        route_map = PhotoImage(file=filename)
        data.configure(image=route_map)
        data.image = route_map

    def send_media(self):
        options = dict(defaultextension='.jpg',
                       filetypes=[('Image file', '.jpg'),
                                  ('Video file', '.mp4')],
                       parent=self.window,
                       title='Open media file')
        infile = tkFileDialog.askopenfilename(**options)
        # TODO: add checking for filesizes above 1MB
        if infile:
            self.select_recipients(infile)

    def select_recipients(self, path):
        w = Toplevel(self.window)
        msg = Label(w, text='Select recipients')
        msg.pack()
        recipient_list = Listbox(w, selectmode=MULTIPLE)
        recipients = self.client.friends
        for name in recipients:
            recipient_list.insert(END, name)
        recipient_list.pack(fill=BOTH, expand=1)
        timer_panel = PanedWindow(w)
        timer_panel.pack(fill=BOTH, expand=1)
        Label(timer_panel, text='Send delay (s):').pack(side=LEFT)
        timer_spinbox = Spinbox(timer_panel,
                                from_=0,
                                to=3600,
                                width=6,
                                repeatdelay=200,
                                repeatinterval=5)
        timer_spinbox.pack(side=RIGHT)
        panel = PanedWindow(w)
        panel.pack()
        ok_btn = Button(panel,
                        text=' OK ',
                        command=lambda: self.send_to_recipients(
                            w, recipients, recipient_list.curselection(), path,
                            timer_spinbox.get()))
        ok_btn.pack(side=LEFT)
        cancel_btn = Button(panel, text=' Cancel ', command=w.destroy)
        cancel_btn.pack(side=RIGHT)

    def send_to_recipients(self, w, friends, selected, path, timer_time):
        w.destroy()
        recipient_list = []
        for f in selected:
            recipient_list.append(friends[f])
        if timer_time == 0:
            self.send_helper(path, recipient_list)
        else:
            self.window.after(
                int(timer_time) * 1000,
                lambda: self.send_helper(path, recipient_list))

    def send_helper(self, path, recipient_list):
        if self.client.send_snap(path, recipient_list):
            tkMessageBox.showinfo(
                'Send successful',
                'Sent {0} to {1} recipient(s)'.format(path,
                                                      len(recipient_list)))
        else:
            tkMessageBox.showinfo("Failed to send", "An error occurred")

    def open_snap(self, snap):
        dt = datetime.fromtimestamp(snap['sent'] / 1000)
        ext = self.client.media_type(snap['media_type'], binary=False)
        timestamp = str(snap['sent']).replace(':', '-')
        filename = '{}+{}+{}.{}'.format(timestamp, snap['sender'], snap['id'],
                                        ext)
        path = PATH + filename
        if not os.path.isfile(path):
            data = self.client.get_snap(snap['id'])
            with open(path, 'wb') as outfile:
                outfile.write(data)

        snap['path'] = path
        file_path = snap['path']

        # open /dev/null or equivalent so we can redirect stdout/stderr to it
        nullfile = open(os.devnull, 'w')
        scheduler = sched.scheduler(time.time, time.sleep)

        if sys.platform.startswith('linux'):
            p = subprocess.Popen(['xdg-open', file_path],
                                 stdout=nullfile,
                                 stderr=nullfile,
                                 preexec_fn=os.setsid)
        elif sys.platform.startswith('darwin'):
            p = subprocess.Popen(['open', file_path],
                                 stdout=nullfile,
                                 stderr=nullfile)
        elif sys.platform.startswith('win'):
            p = subprocess.Popen(['start /WAIT', file_path],
                                 stdout=nullfile,
                                 stderr=nullfile)
        else:
            print 'I don\'t recognize your operating system: {0}'.format(
                sys.platform)
        self.window.after(snap['time'] * 1000 + 1000,
                          lambda: self.mark_read(snap, p))
        '''
        scheduler.enter(snap['time'], 1, self.mark_read, (snap, p))
        t = threading.Thread(target=lambda: scheduler.run)
        t.start()
        '''

    def mark_read(self, snap, p):
        print 'marking read'
        #        self.client.mark_read(snap)
        os.remove(snap['path'])
        if sys.platform.startswith('linux'):
            os.killpg(p.pid, signal.SIGTERM)
        elif sys.platform.startswith('win'):
            p.kill()
Exemplo n.º 2
0
Arquivo: gui.py Projeto: wchill/pySnap
class GUI:
    def __init__(self):
        self.window = Tk()
        self.main_window_init()
        self.client = Snapchat() 
        self.start()

    def start(self):
        self.window.mainloop()

    def main_window_init(self):

        # set window title
        self.window.wm_title('pySnap')

        # configure menu
        menu_bar = Menu(self.window)
        self.window.config(menu=menu_bar)

        # File menu
        file_menu = Menu(menu_bar, tearoff=0)
        file_menu.add_command(label='Send media', command=self.send_media)
        file_menu.add_separator()
        file_menu.add_command(label='Exit', command=self.window.quit)
        menu_bar.add_cascade(label='File', menu=file_menu)

        # Edit menu
        account_menu = Menu(menu_bar, tearoff=0)
        account_menu.add_command(label='Copy Token', command=
            lambda: [pyperclip.copy(self.client.auth_token),
                     tkMessageBox.showinfo('Token copied',
                                           'Auth token copied to clipboard!')])
        account_menu.add_command(label='Logout')
        account_menu.add_command(label='Switch user')
        menu_bar.add_cascade(label='Accounts', menu=account_menu)

        # Prepare the image canvas to be replaced by map image
        self.snap_list = Frame(self.window, width=800, height=600)
        self.snap_list.pack(fill=BOTH, expand=1, side=RIGHT)
        self.window.withdraw()

        w = Toplevel(self.window)
        msg = Label(w, text='Login')
        msg.pack()
        username_panel = PanedWindow(w)
        username_panel.pack(fill=BOTH, expand=1)
        password_panel = PanedWindow(w)
        password_panel.pack(fill=BOTH, expand=1)
        token_panel = PanedWindow(w)
        token_panel.pack(fill=BOTH, expand=1)
        Label(username_panel, text='Username').pack(side=LEFT)
        username_entry = Entry(username_panel)
        username_entry.pack(side=RIGHT)
        Label(password_panel, text='Password').pack(side=LEFT)
        password_entry= Entry(password_panel, show='*')
        password_entry.pack(side=RIGHT)
        Label(token_panel, text='Auth Token').pack(side=LEFT)
        token_entry = Entry(token_panel)
        token_entry.pack(side=RIGHT)
        panel = PanedWindow(w)
        panel.pack()
        ok_btn = Button(panel, text=' OK ', command=lambda: self.login(w, username_entry.get(), password_entry.get(), token_entry.get()))
        ok_btn.pack(side=LEFT)
        cancel_btn = Button(panel, text=' Cancel ', command=lambda: self.cancel_login(w))
        cancel_btn.pack(side=RIGHT)

    def login(self, w, username, password, auth_token):
        w.destroy()
        if password == '':
            if not self.client.login_token(username, auth_token):
                tkMessageBox.showinfo('Failed to login', 'Wrong username or password?')
                self.window.quit()
                return
        else:
            if not self.client.login(username, password):
                tkMessageBox.showinfo('Failed to login', 'Wrong username or password?')
                self.window.quit()
                return
        snaps = self.client.get_snaps()
        if not snaps:
            tkMessageBox.showinfo('Unknown error', 'Something went wrong.')
            self.window.quit()
            return
        Label(self.snap_list, text='Logged in as {0}\n'.format(username)).pack()
        for snap in snaps:
            snap_panel = PanedWindow(self.snap_list)
            snap_panel.pack(fill=X, expand=1)
            Label(snap_panel, text='{0} ({1}s, sent {2})'.format(snap['sender'], snap['time'], datetime.fromtimestamp(snap['sent']/1000))).pack(side=LEFT)
            open_btn = Button(snap_panel, text=' Open ', command=lambda snap=snap: self.open_snap(snap))
            open_btn.pack(side=RIGHT)
        self.window.update()
        self.window.deiconify()

    def cancel_login(self, w):
        w.destroy()
        self.window.quit()

    @staticmethod
    def route_map_callback(filename, data):
        route_map = PhotoImage(file=filename)
        data.configure(image=route_map)
        data.image = route_map

    def send_media(self):
        options = dict(defaultextension='.jpg', filetypes=[('Image file', '.jpg'), ('Video file', '.mp4')],
                       parent=self.window, title='Open media file')
        infile = tkFileDialog.askopenfilename(**options)
        # TODO: add checking for filesizes above 1MB
        if infile:
            self.select_recipients(infile)

    def select_recipients(self, path):
        w = Toplevel(self.window)
        msg = Label(w, text='Select recipients')
        msg.pack()
        recipient_list = Listbox(w, selectmode=MULTIPLE)
        recipients = self.client.friends
        for name in recipients:
            recipient_list.insert(END, name)
        recipient_list.pack(fill=BOTH, expand=1)
        timer_panel = PanedWindow(w)
        timer_panel.pack(fill=BOTH, expand=1)
        Label(timer_panel, text='Send delay (s):').pack(side=LEFT)
        timer_spinbox = Spinbox(timer_panel, from_=0, to=3600, width=6, repeatdelay=200, repeatinterval=5)
        timer_spinbox.pack(side=RIGHT)
        panel = PanedWindow(w)
        panel.pack()
        ok_btn = Button(panel, text=' OK ', command=lambda: self.send_to_recipients(w, recipients, recipient_list.curselection(), path, timer_spinbox.get()))
        ok_btn.pack(side=LEFT)
        cancel_btn = Button(panel, text=' Cancel ', command=w.destroy)
        cancel_btn.pack(side=RIGHT)

    def send_to_recipients(self, w, friends, selected, path, timer_time):
        w.destroy()
        recipient_list = []
        for f in selected:
            recipient_list.append(friends[f])
        if timer_time == 0:
            self.send_helper(path, recipient_list)
        else:
            self.window.after(int(timer_time) * 1000, lambda: self.send_helper(path, recipient_list))

    def send_helper(self, path, recipient_list):
        if self.client.send_snap(path, recipient_list):
            tkMessageBox.showinfo('Send successful', 'Sent {0} to {1} recipient(s)'.format(path, len(recipient_list)))
        else:
            tkMessageBox.showinfo("Failed to send", "An error occurred")

    def open_snap(self, snap):
        dt = datetime.fromtimestamp(snap['sent'] / 1000)
        ext = self.client.media_type(snap['media_type'], binary=False)
        timestamp = str(snap['sent']).replace(':', '-')
        filename = '{}+{}+{}.{}'.format(timestamp, snap['sender'], snap['id'], ext)
        path = PATH + filename
        if not os.path.isfile(path):
            data = self.client.get_snap(snap['id'])
            with open(path, 'wb') as outfile:
                outfile.write(data)

        snap['path'] = path
        file_path = snap['path']

        # open /dev/null or equivalent so we can redirect stdout/stderr to it
        nullfile = open(os.devnull, 'w')
        scheduler = sched.scheduler(time.time, time.sleep)

        if sys.platform.startswith('linux'):
            p = subprocess.Popen(['xdg-open', file_path], stdout=nullfile, stderr=nullfile, preexec_fn=os.setsid)
        elif sys.platform.startswith('darwin'):
            p = subprocess.Popen(['open', file_path], stdout=nullfile, stderr=nullfile)
        elif sys.platform.startswith('win'):
            p = subprocess.Popen(['start /WAIT', file_path], stdout=nullfile, stderr=nullfile)
        else:
            print 'I don\'t recognize your operating system: {0}'.format(sys.platform)
        self.window.after(snap['time'] * 1000 + 1000, lambda: self.mark_read(snap, p))
        '''
        scheduler.enter(snap['time'], 1, self.mark_read, (snap, p))
        t = threading.Thread(target=lambda: scheduler.run)
        t.start()
        '''

    def mark_read(self, snap, p):
        print 'marking read'
#        self.client.mark_read(snap)
        os.remove(snap['path'])
        if sys.platform.startswith('linux'):
            os.killpg(p.pid, signal.SIGTERM)
        elif sys.platform.startswith('win'):
            p.kill()
Exemplo n.º 3
0
from snapchat import Snapchat
import getpass

PATH = './snaps/'
EXTENSIONS = ['jpeg', 'jpg', 'mp4']
USERNAME = None
PASSWORD = None

s = Snapchat()
if USERNAME is None:
    USERNAME = raw_input('username: '******'password: '******'sc.png', '')
snaps = s.get_snaps()
for snap in snaps:
    data = s.get_snap(snap['id'])
    if data:
        ext = s.media_type(data)
        timestamp = str(snap['sent']).replace(':', '-')
        filename = '{}+{}+{}.{}'.format(timestamp, snap['sender'], snap['id'],
                                        ext)
        path = PATH + filename
        with open(path, 'wb') as outfile:
            outfile.write(data)
Exemplo n.º 4
0
from snapchat import Snapchat
import getpass

PATH = './snaps/'
EXTENSIONS = ['jpeg', 'jpg', 'mp4']
USERNAME = None
PASSWORD = None

s = Snapchat()
if USERNAME is None:
    USERNAME = raw_input('username: '******'password: '******'sc.png', '')
snaps = s.get_snaps()
for snap in snaps:
    data = s.get_snap(snap['id'])
    if data:
        ext = s.media_type(data)
        timestamp = str(snap['sent']).replace(':', '-')
        filename = '{}+{}+{}.{}'.format(timestamp, snap['sender'], snap['id'], ext)
        path = PATH + filename
        with open(path, 'wb') as outfile:
            outfile.write(data)
Exemplo n.º 5
0
def cli():
    clear()
    s = Snapchat()
    username = raw_input('Please enter username: '******'win'):
        password = getpass.getpass('Please enter password: '******'Please enter password (empty for token entry): ')
    if password == '':
        auth_token = raw_input('Please enter auth token: ')
        if not s.login_token(username, auth_token):
            raw_input('Invalid username/auth token combo')
            clear()
            exit()
    else:
        if not s.login(username, password):
            raw_input('Invalid username/password combo')
            clear()
            exit()

    pynotify.init("pySnap")
    queue = Queue.Queue()
    bg_scheduler = sched.scheduler(time.time, time.sleep)
    bg_scheduler.enter(300, 1, check_snaps, (s, bg_scheduler, queue))
    bg_check = threading.Thread(target=bg_scheduler.run)
    bg_check.setDaemon(True)
    bg_check.start()
    snaps = s.get_snaps()
    user_input = None
    functions = {
        'R': lambda: s.get_snaps(),
        'S': send
    }
    clear()
    while user_input != 'X':
        print 'Welcome to Snapchat!'
        print 'Logged in as {0} (token {1})'.format(username, s.auth_token)
        print
        print '{0} pending snaps:'.format(len(snaps))
        num = 1
        for snap in snaps:
            #print snap
            #print snap['media_type']
            dt = datetime.fromtimestamp(snap['sent'] / 1000)
            ext = s.media_type(snap['media_type'], binary=False)
            timestamp = str(snap['sent']).replace(':', '-')
            filename = '{}+{}+{}.{}'.format(timestamp, snap['sender'], snap['id'], ext)
            path = PATH + filename

            # check if file already exists so we don't need to redownload
            '''
            if not os.path.isfile(path):
                data = s.get_snap(snap['id'])
                with open(path, 'wb') as outfile:
                    outfile.write(data)
            '''

            snap['path'] = path
            print '[{0}] Snap from {1} ({2}s, Sent {3})'.format(num, snap['sender'], snap['time'], dt)
            num += 1
        print
        print '[R] - refresh snaps'
        print '[S] - send a snap'
        print '[X] - exit'
        user_input = raw_input('Enter an option: ').upper()
        num_input = int(user_input) if user_input.isdigit() else None
        if len(snaps) >= num_input > 0:
            dt = datetime.fromtimestamp(snap['sent'] / 1000)
            ext = s.media_type(snap['media_type'], binary=False)
            timestamp = str(snap['sent']).replace(':', '-')
            filename = '{}+{}+{}.{}'.format(timestamp, snap['sender'], snap['id'], ext)
            path = PATH + filename
            snap = snaps[num_input - 1]
            if not os.path.isfile(path):
                data = s.get_snap(snap['id'])
                with open(path, 'wb') as outfile:
                    outfile.write(data)

            snap['path'] = path
            file_path = snap['path']

            # open /dev/null or equivalent so we can redirect stdout/stderr to it
            nullfile = open(os.devnull, 'w')

            # cross-platform method to open a media file
            p = None
            scheduler = sched.scheduler(time.time, time.sleep)
#            try:
            if True:
                if sys.platform.startswith('linux'):
                    p = subprocess.Popen(['xdg-open', file_path], stdout=nullfile, stderr=nullfile, preexec_fn=os.setsid)
                elif sys.platform.startswith('darwin'):
                    p = subprocess.Popen(['open', file_path], stdout=nullfile, stderr=nullfile)
                elif sys.platform.startswith('win'):
                    p = subprocess.Popen(['start /WAIT', file_path], stdout=nullfile, stderr=nullfile)
                else:
                    print 'I don\'t recognize your operating system: {0}'.format(sys.platform)
                scheduler.enter(snap['time'], 1, mark_read, (s, snap, p, queue))
                t = threading.Thread(target=scheduler.run)
                t.start()
#            except:
#                print 'Uh oh, I was unable to open the file.'

        elif user_input in functions:
            if user_input == 'R':
                queue.put(functions[user_input]())
                print 'Refreshed!'
            else:
                functions[user_input](s)
        elif user_input != 'X':
            print 'I don\'t recognize that command.'

        if user_input != 'X':
            raw_input('Press enter to continue...')
            clear()

        if not queue.empty():
            while not queue.empty():
                buf = queue.get()
            new_snaps = []
            for st in buf:
                found = False
                for snap in snaps:
                    if st['id'] == snap['id']:
                        found = True
                        break
                if found == True:
                    new_snaps.append(st)
            for snap in new_snaps:
                title = 'New snap from {0}!'.format(snap['sender'])
                dt = datetime.fromtimestamp(snap['sent'] / 1000)
                message = '{0} seconds, sent {1}'.format(snap['time'], dt)
                notice = pynotify.Notification(title, message)
                notice.show()
    #        snaps = buf 
    sys.exit(0)