Esempio n. 1
0
def get_cat_id(wp_obj):
    pr3('\nCATEGORY')
    pr3('Retrieving Categories From Server')
    cat_list = wp_obj.getCategoryList()
    cat_counter = 1
    dict = {}
    for cat in cat_list:
        print(str(cat_counter) + '.  ' + cat.name)
        dict[cat_counter] = cat.id
        cat_counter += 1
    output_list = []
    while (1):
        try:
            pr3('Please enter the NUMBER next to the category for this post')
            pr3('To select multiple categories, separate with commas')
            cat_response = sys.stdin.readline().replace('\n', '')
            cat_response_list = cat_response.split(',')
            for cat in cat_response_list:
                cat_int = int(cat)
                cat_id = cat_list[cat_int - 1].id
                output_list.append(cat_id)
                print('Category Selected: ' + cat_list[cat_int - 1].name +
                      '\n')
            break
        except ValueError:
            pr3("Category Response Not Understood.\n")
    assert (len(output_list) > 0)
    return output_list
Esempio n. 2
0
def get_cat_id(wp_obj):
    pr3 ('\nCATEGORY')
    pr3 ('Retrieving Categories From Server')
    cat_list = wp_obj.getCategoryList()
    cat_counter = 1
    dict = {}
    for cat in cat_list:
        print (str(cat_counter) + '.  ' + cat.name)
        dict[cat_counter] = cat.id
        cat_counter += 1
    output_list = []
    while (1):
        try:
            pr3 ('Please enter the NUMBER next to the category for this post')
            pr3 ('To select multiple categories, separate with commas')
            cat_response = sys.stdin.readline().replace('\n', '')
            cat_response_list = cat_response.split(',')
            for cat in cat_response_list:
                cat_int = int(cat)
                cat_id = cat_list[cat_int-1].id
                output_list.append(cat_id)
                print ('Category Selected: ' + cat_list[cat_int-1].name + '\n')
            break
        except ValueError:
            pr3 ("Category Response Not Understood.\n")
    assert(len(output_list) > 0)
    return output_list
Esempio n. 3
0
def get_local_image_url(img_tag, ELYXER_ENGINE):
    # Find local address of image
    # The only difference between the two is single vs double quotes
    if (ELYXER_ENGINE):
        add_exp = re.compile(
            '''
            src="   # The beginning of the address
            ..*?    # Non-greedy rest of the address
            "       # The (first) closing (double) quotation mark
            ''', re.VERBOSE)
    else:
        add_exp = re.compile(
            '''
            src='   # The beginning of the address
            ..*?    # Non-greedy rest of the address
            '       # The (first) closing (single) quotation mark
            ''', re.VERBOSE)
    add_obj = add_exp.search(img_tag)
    if (add_obj == None):
        pr3("Error parsing img tag: " + img_tag)
        msg = "LyXBlogger failed to find src attribute in <img> tag"
        raise Exception(msg)
    long_address = add_obj.group()
    short_address = long_address[5:-1]  # Strip off the src="
    return (short_address)
Esempio n. 4
0
 def test_up_images(self):
     # A typical eLyXer image tag : ELYXER_ENGINER = True
     # A typical LyXHTML image tag : ELYXER_ENGINE = False
     dict = {'<img class="embedded" src="test_files/images/table.jpg" />' : True,
         "<img src='test_files/images/table.jpg' />" : False}
     wp = wordpresslib.WordPressClient(
         'http://blogtest.twomorelines.com/xmlrpc.php', 'test', 'test')
     for html, ELYXER_ENGINE in dict.iteritems():
         pr3('\n\n***   Testing the upload of a single image   ***')
         up_images(html, wp, ELYXER_ENGINE, in_DIR_OFFSET = '')
Esempio n. 5
0
 def test_up_images(self):
     # A typical eLyXer image tag : ELYXER_ENGINER = True
     # A typical LyXHTML image tag : ELYXER_ENGINE = False
     dict = {
         '<img class="embedded" src="test_files/images/table.jpg" />': True,
         "<img src='test_files/images/table.jpg' />": False
     }
     wp = wordpresslib.WordPressClient(
         'http://blogtest.twomorelines.com/xmlrpc.php', 'test', 'test')
     for html, ELYXER_ENGINE in dict.iteritems():
         pr3('\n\n***   Testing the upload of a single image   ***')
         up_images(html, wp, ELYXER_ENGINE, in_DIR_OFFSET='')
Esempio n. 6
0
def init_config(in_config_file):
    config = ConfigParser.ConfigParser()
    if not os.path.exists(in_config_file):
        # Set up initial config file
        config.set('DEFAULT', 'delay', '1.0') # wait while showing author info
        config.set('DEFAULT', 'cut_flag', '#! CUT MATERIAL') # we remove anything after this in the html
        config.set('DEFAULT', 'last_profile', '0') # use as default input option
        config.set('DEFAULT', 'next_section_n', '1') # next usable profile section number
        with open(in_config_file, 'wb') as configfile: config.write(configfile)
        pr3 ("Default config file created in " + in_config_file + '\n' )

    config.read(in_config_file)
    return config
Esempio n. 7
0
def init_config(in_config_file):
    config = ConfigParser.ConfigParser()
    if not os.path.exists(in_config_file):
        # Set up initial config file
        config.set('DEFAULT', 'delay', '1.0') # wait while showing author info
        config.set('DEFAULT', 'cut_flag', '#! CUT MATERIAL') # we remove anything after this in the html
        config.set('DEFAULT', 'last_profile', '0') # use as default input option
        config.set('DEFAULT', 'next_section_n', '1') # next usable profile section number
        with open(in_config_file, 'wb') as configfile: config.write(configfile)
        pr3 ("Default config file created in " + in_config_file + '\n' )

    config.read(in_config_file)
    return config
Esempio n. 8
0
def init_config(in_config_file):
    config = ConfigParser.ConfigParser()
    if not os.path.exists(in_config_file):
        # Set up initial config file
        config.set("DEFAULT", "delay", "1.0")  # wait while showing author info
        config.set("DEFAULT", "cut_flag", "#! CUT MATERIAL")  # we remove anything after this in the html
        config.set("DEFAULT", "last_profile", "0")  # use as default input option
        config.set("DEFAULT", "next_section_n", "1")  # next usable profile section number
        with open(in_config_file, "wb") as configfile:
            config.write(configfile)
        pr3("Default config file created in " + in_config_file + "\n")

    config.read(in_config_file)
    return config
Esempio n. 9
0
def new_shell():
    # Determine which operating system is in use
    system = sys.platform
    if sys.platform == "win32":
        pr3("Running on Windows")
        return 'start "LyXBlogger" python.exe %s %s %s '
    elif sys.platform == "darwin":
        pr3("Running on OSX")
    elif sys.platform == "linux2":
        pr3("Running on GNU/Linux")
    else:
        pr3("I'm not sure what operating system you are running on.")
        pr3("Please write the author at [email protected] to report possible bug")
    # GNU/Linux, Mac, and unidentified OS's call xterm
    return 'xterm -T "LyXBlogger" -fg gold -bg black -fn 10x20 -e python %s %s %s '
Esempio n. 10
0
def display_profiles(config):
    last_serial = config.get('DEFAULT', 'last_profile')

    disp_0 = '0. ' + str(Credentials.defaults())
    if last_serial == '0':
        disp_0 += "  **"
    pr3(disp_0)
    config_ctr = 1  # Zero is reserved for the test site, so we start one higher
    cfg_dict = {'0':'0'}  # This is to make sure the test site is reachable
    for section in config.sections():
        cfg_dict[str(config_ctr)] = section
        disp = str(config_ctr) + '. ' + str(Credentials.fromconfig(config,section))
        if section == last_serial:
            disp += "  **"
        pr3(disp)
        config_ctr += 1
    return cfg_dict
Esempio n. 11
0
def display_profiles(config):
    last_serial = config.get('DEFAULT', 'last_profile')

    disp_0 = '0. ' + str(Credentials.defaults())
    if last_serial == '0':
        disp_0 += "  **"
    pr3(disp_0)
    config_ctr = 1  # Zero is reserved for the test site, so we start one higher
    cfg_dict = {'0':'0'}  # This is to make sure the test site is reachable
    for section in config.sections():
        cfg_dict[str(config_ctr)] = section
        disp = str(config_ctr) + '. ' + str(Credentials.fromconfig(config,section))
        if section == last_serial:
            disp += "  **"
        pr3(disp)
        config_ctr += 1
    return cfg_dict
Esempio n. 12
0
def new_shell():
    # Determine which operating system is in use
    system = sys.platform
    if (sys.platform == 'win32'):
        pr3('Running on Windows')
        return ('start "LyXBlogger" python.exe %s %s %s ')
    elif (sys.platform == 'darwin'):
        pr3('Running on OSX')
    elif (sys.platform == 'linux2'):
        pr3('Running on GNU/Linux')
    else:
        pr3('I\'m not sure what operating system you are running on.')
        pr3('Please write the author at [email protected] to report possible bug'
            )
    # GNU/Linux, Mac, and unidentified OS's call xterm
    return (
        'xterm -T "LyXBlogger" -fg gold -bg black -fn 10x20 -e python %s %s %s '
    )
Esempio n. 13
0
def up_images(in_html, wp_client_obj, ELYXER_ENGINE, in_DIR_OFFSET):
    # Find local location of a single image within the (x)html file
    img_tag = find_local_image_tag(in_html, ELYXER_ENGINE)
    imageSrc = None
    if(img_tag):
        pr3 ("\nIMAGES\nLet's upload your images")
    while(img_tag):
        local_image_url = get_local_image_url(img_tag, ELYXER_ENGINE)
        valid_local_image_url = validate_url(local_image_url, in_DIR_OFFSET)
        filesize = str(os.path.getsize(valid_local_image_url) / 1024) + ' kB'
        short_name = get_short_name(valid_local_image_url)
        pr3("Uploading image: " + short_name + '.  Size: ' + filesize )
        # upload image for post
        try:
            imageSrc = wp_client_obj.newMediaObject(valid_local_image_url)
        except (gaierror, WordPressException):
            handle_gaierror()
        try:
            assert(imageSrc.startswith('http://'))
        except AssertionError:
            print("There was a problem uploading your image.")
            print("imageSrc should start with http://")
            print("Please contact the author at [email protected]")
            handle_general_error()
        try:
            assert(local_image_url in in_html)
        except AssertionError:
            print("There was a problem uploading your image.")
            print("local_image_url not found in in_html")
            print("Please contact the author at [email protected]")
            handle_general_error()
        snapshot = in_html
        in_html = in_html.replace(local_image_url, imageSrc)
        try:
            assert(in_html != snapshot)
        except AssertionError:
            print("There was a problem uploading your image.")
            print("local_image_url not replaced with imageSrc in post")
            print("Please contact the author at [email protected]")
            handle_general_error()

        img_tag = find_local_image_tag(in_html, ELYXER_ENGINE)
    return(in_html)
Esempio n. 14
0
def term_open(in_input_file):

    CALLED_FROM_XTERM = '--run-here'
    CALL_MODULE = '-m lyxblogger'
    # If already called from xterm, run the program as normal.
    # Otherwise, call the program from xterm so it's visible
    if (len(sys.argv) >= 3) and (sys.argv[2] == CALLED_FROM_XTERM):
        pass  # Called correctly, so code will execute
    else:
        # Spawn a new xterm window to run this program in
        # -hold means leave window open after process completes
        # -fg is foreground color
        # -bg is background color
        # -fn is font (size)
        # -e means call a program
        command = new_shell() % (CALL_MODULE, in_input_file, CALLED_FROM_XTERM)
        pr3('command is ' + command)
        os.system(command)
        sys.exit(0)  # Exit so program is not repeated.
Esempio n. 15
0
def term_open(in_input_file):

    CALLED_FROM_XTERM = "--run-here"
    CALL_MODULE = "-m lyxblogger"
    # If already called from xterm, run the program as normal.
    # Otherwise, call the program from xterm so it's visible
    if (len(sys.argv) >= 3) and (sys.argv[2] == CALLED_FROM_XTERM):
        pass  # Called correctly, so code will execute
    else:
        # Spawn a new xterm window to run this program in
        # -hold means leave window open after process completes
        # -fg is foreground color
        # -bg is background color
        # -fn is font (size)
        # -e means call a program
        command = new_shell() % (CALL_MODULE, in_input_file, CALLED_FROM_XTERM)
        pr3("command is " + command)
        os.system(command)
        sys.exit(0)  # Exit so program is not repeated.
Esempio n. 16
0
def up_images(in_html, wp_client_obj, ELYXER_ENGINE, in_DIR_OFFSET):
    # Find local location of a single image within the (x)html file
    img_tag = find_local_image_tag(in_html, ELYXER_ENGINE)
    imageSrc = None
    if (img_tag):
        pr3("\nIMAGES\nLet's upload your images")
    while (img_tag):
        local_image_url = get_local_image_url(img_tag, ELYXER_ENGINE)
        valid_local_image_url = validate_url(local_image_url, in_DIR_OFFSET)
        filesize = str(os.path.getsize(valid_local_image_url) / 1024) + ' kB'
        short_name = get_short_name(valid_local_image_url)
        pr3("Uploading image: " + short_name + '.  Size: ' + filesize)
        # upload image for post
        try:
            imageSrc = wp_client_obj.newMediaObject(valid_local_image_url)
        except (gaierror, WordPressException):
            handle_gaierror()
        try:
            assert (imageSrc.startswith('http://'))
        except AssertionError:
            print("There was a problem uploading your image.")
            print("imageSrc should start with http://")
            print("Please contact the author at [email protected]")
            handle_general_error()
        try:
            assert (local_image_url in in_html)
        except AssertionError:
            print("There was a problem uploading your image.")
            print("local_image_url not found in in_html")
            print("Please contact the author at [email protected]")
            handle_general_error()
        snapshot = in_html
        in_html = in_html.replace(local_image_url, imageSrc)
        try:
            assert (in_html != snapshot)
        except AssertionError:
            print("There was a problem uploading your image.")
            print("local_image_url not replaced with imageSrc in post")
            print("Please contact the author at [email protected]")
            handle_general_error()

        img_tag = find_local_image_tag(in_html, ELYXER_ENGINE)
    return (in_html)
Esempio n. 17
0
def get_local_image_url(img_tag, ELYXER_ENGINE):
    # Find local address of image
    # The only difference between the two is single vs double quotes
    if (ELYXER_ENGINE):
        add_exp = re.compile('''
            src="   # The beginning of the address
            ..*?    # Non-greedy rest of the address
            "       # The (first) closing (double) quotation mark
            ''', re.VERBOSE)
    else:
        add_exp = re.compile('''
            src='   # The beginning of the address
            ..*?    # Non-greedy rest of the address
            '       # The (first) closing (single) quotation mark
            ''', re.VERBOSE)
    add_obj = add_exp.search(img_tag)
    if (add_obj == None):
        pr3 ("Error parsing img tag: " + img_tag)
        msg = "LyXBlogger failed to find src attribute in <img> tag"
        raise Exception(msg)
    long_address = add_obj.group()
    short_address = long_address[5:-1]  # Strip off the src="
    return(short_address)
Esempio n. 18
0
def handle_general_error(name_string='', suggestion_string=''):
    pr3('\nAn error has occurred. If this error persists, please ')
    pr3('contact the author at [email protected].')
    pr3('The nutshell version is listed way down below. But here')
    pr3('are the details if you are interested:')
    print(traceback.print_exc())
    print('\n\n\n\n\n')
    print("\n************************************************************")
    if name_string == '':
        print("*******                     ERROR                    *******\n")
    else:
        print(name_string)
    exc_type, exc_value, exc_traceback = sys.exc_info()
    msg = traceback.format_exception_only(exc_type,
                                          exc_value)[0].replace('\n', '')
    print("System says: " + msg)
    if suggestion_string != '':
        print(suggestion_string + '\n')
    wait_for_consumer()
Esempio n. 19
0
def get_configpath():
    # Determine which operating system is in use
    system = sys.platform
    if system == "win32":
        pr3("Running on Windows")
        return "~\\lyxblogger\\config.cfg"
    elif system == "darwin":
        # pr3('Running on OSX')
        return "~/.lyxblogger/config.cfg"
    elif system == "linux2":
        # pr3('Running on GNU/Linux')
        return "~/.lyxblogger/config.cfg"
    else:
        pr3("I'm not sure what operating system you are running on.")
        pr3("Please write the author at [email protected] to report possible bug")
        wait_for_consumer()
Esempio n. 20
0
def get_configpath():
    # Determine which operating system is in use
    system = sys.platform
    if (system == 'win32'):
        pr3('Running on Windows')
        return("~\\lyxblogger\\config.cfg")
    elif (system == 'darwin'):
        # pr3('Running on OSX')
        return "~/.lyxblogger/config.cfg"
    elif (system == 'linux2'):
        # pr3('Running on GNU/Linux')
        return "~/.lyxblogger/config.cfg"
    else:
        pr3('I\'m not sure what operating system you are running on.')
        pr3('Please write the author at [email protected] to report possible bug')
        wait_for_consumer()
Esempio n. 21
0
def get_configpath():
    # Determine which operating system is in use
    system = sys.platform
    if (system == 'win32'):
        pr3('Running on Windows')
        return("~\\lyxblogger\\config.cfg")
    elif (system == 'darwin'):
        # pr3('Running on OSX')
        return "~/.lyxblogger/config.cfg"
    elif (system == 'linux2'):
        # pr3('Running on GNU/Linux')
        return "~/.lyxblogger/config.cfg"
    else:
        pr3('I\'m not sure what operating system you are running on.')
        pr3('Please write the author at [email protected] to report possible bug')
        wait_for_consumer()
Esempio n. 22
0
 def ask(cls):
     "Initialize Credentials with values given by user"
     pr3 ('\nCREATING NEW PROFILE.')
     pr3 ("\nUSERNAME")
     while (1):
         pr3 ("Please enter your WordPress username")
         user = sys.stdin.readline().replace('\n', '')
         if user != '': break
     pr3 ("Username is " + user + '.')
     pr3 ("\nURL")
     while (1):
         pr3 ("Please enter your WordPress URL")
         pr3 ("Example: cool_site.wordpress.com")
         url = sys.stdin.readline().replace('\n', '')
         if url != '': break
     url = url.replace('http://', '')
     url = url.replace('www.', '')
     if url.endswith('/'):
         url = 'http://' + url + 'xmlrpc.php'
     else:
         url = 'http://' + url + '/xmlrpc.php'
     pr3 ("The PhP page we'll be talking to is " + url)
     pr3 ("\nPROMPT for PASSWORD?")
     pr3 ("Press ENTER now to be prompted each time (recommended).")
     pr3 ("Or type your precious password here, to be saved as plain text on you computer.")
     password = getpass.getpass()
     return cls(url, user, password)
Esempio n. 23
0
def delete_config_file():
    rel_path = get_configpath()
    abs_path = os.path.expanduser(rel_path)
    pr3("abs_path is " + abs_path)
    if os.path.exists(abs_path):
        os.remove(abs_path)
Esempio n. 24
0
def url_passes(selected, CHECK_PASSWORD = False):
    # prepare client object
    # verify that credentials work by getting info
    if CHECK_PASSWORD == False or CHECK_PASSWORD == '':
        pr3("Making sure " + selected.url + " exists and is reachable.")
    else:
        pr3("Verifying host, username, and password.")
    rpc_server = xmlrpclib.ServerProxy(selected.url)
    try:
        userinfo = rpc_server.blogger.getUserInfo('', selected.user, selected.password)
        return True
    except gaierror:    # gaierror caught if no connection to host
        exc_type, exc_value, exc_traceback = sys.exc_info()
        # print(exc_type, exc_value, exc_traceback)   # Use print intead of pr3 because print can take three args
        pr3("\n" + selected.url + " is unreachable.")
        pr3("Please check the spelling and make sure your Internet is working.")
        pr3("Working example: http://cool_url.com/xmlrpc.php")
        pr3("You may try again in just a moment.")
        time.sleep(3)
        return False
    except xmlFault:    # xmlFault caught if host found but user/pass mismatch
        if CHECK_PASSWORD == False or CHECK_PASSWORD == '':
            # Don't bother checking if password is correct
            return True
        else:
            exc_type, exc_value, exc_traceback = sys.exc_info()
            print(exc_value)    # Using PRINT on purpose
            pr3("\nIncorrect Password. Please try again in just a moment.")
            time.sleep(3)
            return False
    except xmlrpcProtocolError:
            pr3("\nHTTP Protocol Error. Probably not your fault. Please try again in just a moment.")
            time.sleep(3)
            return False
Esempio n. 25
0
def get_credentials(config):
    configpath = os.path.expanduser(get_configpath())

    # Select existing profile (and setting last_profile to that)
    # or create a new profile in the config file
    while (1):
        pr3 ('\nSELECT BLOG')
        cfg_dict = display_profiles(config)

        last_serial = config.get('DEFAULT', 'last_profile')
        pr3 ('\nEnter the number next to the desired profile.')
        pr3 ('(**latest) N = New, D = Delete')
        cat_response = sys.stdin.readline().replace('\n', '')

        if cat_response == 'D' or cat_response == 'd':
            cfg_dict = display_profiles(config)
            pr3 ('Enter a number to delete that profile, N to cancel')
            del_response = sys.stdin.readline().replace('\n', '')
            d_serial = get_serial(del_response, cfg_dict)
            if del_response == '0':
                pr3 ('Default section 0 cannot be deleted\n')
                pr3("Keyboard control will resume in 5 seconds")
                time.sleep(3)
            elif d_serial:
                config.remove_section(d_serial)
                if d_serial == config.get('DEFAULT', 'last_profile'):
                    config.set('DEFAULT', 'last_profile', '0')
                with open(configpath, 'wb') as configfile: config.write(configfile)
                pr3 ('Profile ' + del_response + ' removed!\n')
            else:
                pr3 (del_response + " Is Not A Profile Number.\n")

        elif cat_response == 'N' or cat_response == 'n':
            section = config.get('DEFAULT', 'next_section_n')
            new = Credentials.ask()
            pr3("Your password is: " + len(new.password)*"*")
            if url_passes(new, new.password):
                config.set('DEFAULT', 'last_profile', section)
                config.add_section(section)
                config.set(section, 'url',      new.url)
                config.set(section, 'user',     new.user)
                config.set(section, 'password', new.password)                # make a previously unused number to be used by the next section created:
                config.set('DEFAULT', 'next_section_n', str(int(section)+1))
                with open(configpath, 'wb') as configfile: config.write(configfile)
                pr3 ("Profile created, config file saved to " + configpath + '\n')
            else:
                time.sleep(3)
        # USE THIS PROFILE
        elif get_serial(cat_response, cfg_dict) or cat_response == '':
            if cat_response == '':
                u_serial = config.get('DEFAULT', 'last_profile')
            else:
                u_serial = get_serial(cat_response, cfg_dict)
            selected = Credentials.fromconfig(config, u_serial)
            config.set('DEFAULT', 'last_profile', u_serial)
            with open(configpath, 'wb') as configfile: config.write(configfile)
            break

        else:
            pr3 ("Response " + cat_response + " Not Understood.\n")
            time.sleep(1)

    pr3 ('Profile selected:  ' + str(selected))
    if selected.password == '':
            pr3 ("Profile has no password set. Please enter your WordPress password")
            selected.password = getpass.getpass()
    # Repeat process until credentials pass
    while not url_passes(selected, CHECK_PASSWORD = True):
        selected = get_credentials(config)

    pr3("Credentials Passed")
    return selected
Esempio n. 26
0
def get_post_id(wp_obj, history = 9):
    DATE_FLAG = "DATE"
    pr3 ('\nUPDATE A PREVIOUS POST')
    pr3 ('Retrieving Previous Posts From Server')
    #~ post_list = wp_obj.getpostegoryList()
    post_counter = 1
    post_list = []
    posts = wp_obj.getRecentPosts(history)
    dict = {}   # This dictionary matches display number with post_id
    try:
        while True:
            a = posts.next()
            # Make note in the dictionary which post id (a.id) each displayed title represents
            date_string = ''
            if a.date:
                mon = str(a.date[1])
                day = str(a.date[2])
                if len(day) == 1:   # Formatting
                    day = '0' + day
                yr = str(a.date[0])
                date_string = '    ' + mon  + '/' + day + '/' + yr
            key = str(post_counter)
            dict[key] = MiniPost(in_post_id = a.id, in_title = a.title, in_date = date_string)
            display = key + '.  ' + dict[key].title + DATE_FLAG + dict[key].date
            post_list.append(display)
            post_counter += 1
    except StopIteration:
        # The StopIteration exception is called once all the function generator entries have passed
        formatted_list = same_length(post_list, DATE_FLAG)
        if history != 0:
            formatted_list.append('A.    --  Show All Entries  --  ')
        for item in formatted_list:
            try:
                print(item)
            except UnicodeEncodeError:
                print("This line skipped because the Unicode would not display properly")

    while (1):
        pr3 ('\nPlease enter the NUMBER next to the post to overwrite')
        if (len(formatted_list) > 12 and sys.platform != 'win32'):
            pr3('Hint: SHIFT + PageUp scrolls screen')
        response = sys.stdin.readline().replace('\n', '')
        if (response == 'a' or response == 'A'):
            pr3('\nPlease allow up to a minute to download all post headers')
            post_id = get_post_id(wp_obj, 0)  # List all entries
            break
        else:
            try:
                post_id = dict[response].post_id
                # Print used on this instead of pr3 to prevent erros with Unicode titles
                print ('Selected: ' + dict[response].title + dict[response].date)
                break
            except KeyError:
                pr3 ("Post Selection Not Understood.\n")
    return post_id
Esempio n. 27
0
def get_html(input_file, CUT_FLAG):

    # Read data from file
    f = open(input_file, 'r')
    html = f.read()
    f.close()

    pr3("FORMAT")
    ELYXER_ENGINE = get_format(html)

    # Trim designated cut material from bottom of post
    html = trim_cut_material(html, CUT_FLAG, ELYXER_ENGINE)

    # RECORD TITLE FROM HEADER TO USE AS POST
    tit_exp = re.compile('''
        <title>         # Start of the <title> tag
        ..{1,}?         # Anything in the middle (non-greedy)
        </title>        # Closing </title> tag
        ''', re.VERBOSE)  # VERBOSE allows ''' '''
    tit_obj = tit_exp.search(html)
    # eLyXer uses 'Converted document' as the default title in the head
    # and body. LyXHTML uses 'LyX Document' as the default, but only
    # puts it in the head. The following code detects these default
    # titles and asks for a real title
    TITLE_EXPECTED_IN_BODY, TITLE_PROMPT = False, True
    pr3("\nTITLE")
    if (tit_obj):
        TITLE_EXPECTED_IN_BODY = True
        TITLE_PROMPT = False
        full_title_tag = tit_obj.group()
        blog_title = full_title_tag[7:-8]  # Strip tags off
        if (blog_title == 'Converted document'
            ):  # eLyXer's default (head and body)
            TITLE_PROMPT = True
        if (blog_title == 'LyX Document'):  # LyXHTML's default (only in head)
            TITLE_PROMPT = True
            TITLE_EXPECTED_IN_BODY = False
    if (TITLE_PROMPT):
        pr3('No title found in document.')
        pr3('Please enter a title now')
        blog_title = sys.stdin.readline().replace('\n', '')
    pr3('Using title: ' + blog_title)

    # REMOVING TITLE FROM BODY
    # Typical body title using ENGINE_INTERNAL:
    #   <h1 class="title"><a id='magicparlabel-309' />
    #   Example Article Title</h1>
    #   <h1 class="title">
    # Typical body title using ELYXER_ENGINE using optional sizing:
    #   <h1 class="title">
    #   <span class="footnotesize">Hi Brian</span>
    #
    #   </h1>
    exp = re.compile('''
        <h1\                   # Beginning of tag with space
        class="title">         # The rest of the tag
        ..{1,}?                # Anything (non-greedy)
        </h1>                  # Closing tag
        ''', re.VERBOSE | re.DOTALL)  # .. can include linebreaks
    bt_obj = exp.search(html)
    if (bt_obj):
        entire_bt_tag = bt_obj.group()
        html = html.replace(entire_bt_tag, '')
    elif (TITLE_EXPECTED_IN_BODY):
        pass
        #~ pr3 ('\nWARNING! The title of your entry may appear twice.')
        #~ pr3 ('Please notify the author at [email protected] to')
        #~ pr3 ('have this bug squashed.\n\n Press Enter to continue uploading.')
        #~ sys.stdin.readline()
        # What this really means is an opening title tag was found, but
        # no title tag was found in the body.

    # Eliminate everything outside the <body></body> tags
    START_TAG = '<body>'
    END_TAG = '</body>'
    if (START_TAG in html):
        html = html.partition(START_TAG)[2]
    html = html.partition(END_TAG)[0]

    # Reinvoke <code> and </code> tags from their escape sequence counterparts
    html = html.replace('&lt;code&gt;', '<code>')
    html = html.replace('&lt;/code&gt;', '</code>')

    # Remove Arrows from footnotes and margin notes
    html = html.replace('[→', '[')
    html = html.replace('→]', ']')

    # Change the elyxer-generated id to a class, since wordpresslib appears to
    # strip out all ids upon upload
    html = html.replace("<div class=\"footer\" id=\"generated-by\">",
                        "<div class=\"footer generated-by-elyxer\">")

    return html, blog_title, ELYXER_ENGINE
Esempio n. 28
0
def get_credentials(config):
    configpath = os.path.expanduser(get_configpath())

    # Select existing profile (and setting last_profile to that)
    # or create a new profile in the config file
    while (1):
        pr3 ('\nPROFILES')
        cfg_dict = display_profiles(config)

        last_serial = config.get('DEFAULT', 'last_profile')
        pr3 ('\nEnter the number next to the desired profile.')
        pr3 ('(**latest) N = New, D = Delete')
        cat_response = sys.stdin.readline().replace('\n', '')

        if cat_response == 'D' or cat_response == 'd':
            cfg_dict = display_profiles(config)
            pr3 ('Enter a number to delete that profile, N to cancel')
            del_response = sys.stdin.readline().replace('\n', '')
            d_serial = get_serial(del_response, cfg_dict)
            if del_response == '0':
                pr3 ('Default section 0 cannot be deleted\n')
                pr3("Keyboard control will resume in 5 seconds")
                time.sleep(3)
            elif d_serial:
                config.remove_section(d_serial)
                if d_serial == config.get('DEFAULT', 'last_profile'):
                    config.set('DEFAULT', 'last_profile', '0')
                with open(configpath, 'wb') as configfile: config.write(configfile)
                pr3 ('Profile ' + del_response + ' removed!\n')
            else:
                pr3 (del_response + " Is Not A Profile Number.\n")

        elif cat_response == 'N' or cat_response == 'n':
            section = config.get('DEFAULT', 'next_section_n')
            new = Credentials.ask()
            pr3("Your password is: " + len(new.password)*"*")
            if url_passes(new, new.password):
                config.set('DEFAULT', 'last_profile', section)
                config.add_section(section)
                config.set(section, 'url',      new.url)
                config.set(section, 'user',     new.user)
                config.set(section, 'password', new.password)                # make a previously unused number to be used by the next section created:
                config.set('DEFAULT', 'next_section_n', str(int(section)+1))
                with open(configpath, 'wb') as configfile: config.write(configfile)
                pr3 ("Profile created, config file saved to " + configpath + '\n')
            else:
                time.sleep(3)
        # USE THIS PROFILE
        elif get_serial(cat_response, cfg_dict) or cat_response == '':
            if cat_response == '':
                u_serial = config.get('DEFAULT', 'last_profile')
            else:
                u_serial = get_serial(cat_response, cfg_dict)
            selected = Credentials.fromconfig(config, u_serial)
            config.set('DEFAULT', 'last_profile', u_serial)
            with open(configpath, 'wb') as configfile: config.write(configfile)
            break

        else:
            pr3 ("Response " + cat_response + " Not Understood.\n")
            time.sleep(1)

    pr3 ('Profile selected:  ' + str(selected))
    if selected.password == '':
            pr3 ("Profile has no password set. Please enter your WordPress password")
            selected.password = getpass.getpass()
    # Repeat process until credentials pass
    while not url_passes(selected, CHECK_PASSWORD = True):
        selected = get_credentials(config)

    pr3("Credentials Passed")
    return selected
Esempio n. 29
0
def get_post_id(wp_obj, history=9):
    DATE_FLAG = "DATE"
    pr3('\nUPDATE A PREVIOUS POST')
    pr3('Retrieving Previous Posts From Server')
    #~ post_list = wp_obj.getpostegoryList()
    post_counter = 1
    post_list = []
    posts = wp_obj.getRecentPosts(history)
    dict = {}  # This dictionary matches display number with post_id
    try:
        while True:
            a = posts.next()
            # Make note in the dictionary which post id (a.id) each displayed title represents
            date_string = ''
            if a.date:
                mon = str(a.date[1])
                day = str(a.date[2])
                if len(day) == 1:  # Formatting
                    day = '0' + day
                yr = str(a.date[0])
                date_string = '    ' + mon + '/' + day + '/' + yr
            key = str(post_counter)
            dict[key] = MiniPost(in_post_id=a.id,
                                 in_title=a.title,
                                 in_date=date_string)
            display = key + '.  ' + dict[key].title + DATE_FLAG + dict[key].date
            post_list.append(display)
            post_counter += 1
    except StopIteration:
        # The StopIteration exception is called once all the function generator entries have passed
        formatted_list = same_length(post_list, DATE_FLAG)
        if history != 0:
            formatted_list.append('A.    --  Show All Entries  --  ')
        for item in formatted_list:
            try:
                print(item)
            except UnicodeEncodeError:
                print(
                    "This line skipped because the Unicode would not display properly"
                )

    while (1):
        pr3('\nPlease enter the NUMBER next to the post to overwrite')
        if (len(formatted_list) > 12 and sys.platform != 'win32'):
            pr3('Hint: SHIFT + PageUp scrolls screen')
        response = sys.stdin.readline().replace('\n', '')
        if (response == 'a' or response == 'A'):
            pr3('\nPlease allow up to a minute to download all post headers')
            post_id = get_post_id(wp_obj, 0)  # List all entries
            break
        else:
            try:
                post_id = dict[response].post_id
                # Print used on this instead of pr3 to prevent erros with Unicode titles
                print('Selected: ' + dict[response].title +
                      dict[response].date)
                break
            except KeyError:
                pr3("Post Selection Not Understood.\n")
    return post_id
Esempio n. 30
0
 def ask(cls):
     "Initialize Credentials with values given by user"
     pr3 ('\nCREATING NEW PROFILE.')
     pr3 ("\nUSERNAME")
     while (1):
         pr3 ("Please enter your WordPress username")
         user = sys.stdin.readline().replace('\n', '')
         if user != '': break
     pr3 ("Username is " + user + '.')
     pr3 ("\nURL")
     while (1):
         pr3 ("Please enter your WordPress URL")
         pr3 ("Example: cool_site.wordpress.com")
         url = sys.stdin.readline().replace('\n', '')
         if url != '': break
     url = url.replace('http://', '')
     url = url.replace('www.', '')
     if url.endswith('/'):
         url = 'http://' + url + 'xmlrpc.php'
     else:
         url = 'http://' + url + '/xmlrpc.php'
     pr3 ("The PhP page we'll be talking to is " + url)
     pr3 ("\nPROMPT for PASSWORD?")
     pr3 ("Press ENTER now to be prompted each time (recommended).")
     pr3 ("Or type your precious password here, to be saved as plain text on you computer.")
     password = getpass.getpass()
     return cls(url, user, password)
Esempio n. 31
0
def delete_config_file():
    rel_path = get_configpath()
    abs_path = os.path.expanduser(rel_path)
    pr3("abs_path is " + abs_path)
    if os.path.exists(abs_path):
        os.remove(abs_path)
Esempio n. 32
0
def get_credentials(config):
    configpath = os.path.expanduser(get_configpath())

    # Select existing profile (and setting last_profile to that)
    # or create a new profile in the config file
    while 1:
        pr3("\nPROFILES")
        cfg_dict = display_profiles(config)

        last_serial = config.get("DEFAULT", "last_profile")
        pr3("\nEnter the number next to the desired profile.")
        pr3("(**latest) N = New, D = Delete")
        cat_response = sys.stdin.readline().replace("\n", "")

        if cat_response == "D" or cat_response == "d":
            cfg_dict = display_profiles(config)
            pr3("Enter a number to delete that profile, N to cancel")
            del_response = sys.stdin.readline().replace("\n", "")
            d_serial = get_serial(del_response, cfg_dict)
            if del_response == "0":
                pr3("Default section 0 cannot be deleted\n")
                pr3("Keyboard control will resume in 5 seconds")
                time.sleep(3)
            elif d_serial:
                config.remove_section(d_serial)
                if d_serial == config.get("DEFAULT", "last_profile"):
                    config.set("DEFAULT", "last_profile", "0")
                with open(configpath, "wb") as configfile:
                    config.write(configfile)
                pr3("Profile " + del_response + " removed!\n")
            else:
                pr3(del_response + " Is Not A Profile Number.\n")

        elif cat_response == "N" or cat_response == "n":
            section = config.get("DEFAULT", "next_section_n")
            new = Credentials.ask()
            pr3("Your password is: " + len(new.password) * "*")
            if url_passes(new, new.password):
                config.set("DEFAULT", "last_profile", section)
                config.add_section(section)
                config.set(section, "url", new.url)
                config.set(section, "user", new.user)
                config.set(
                    section, "password", new.password
                )  # make a previously unused number to be used by the next section created:
                config.set("DEFAULT", "next_section_n", str(int(section) + 1))
                with open(configpath, "wb") as configfile:
                    config.write(configfile)
                pr3("Profile created, config file saved to " + configpath + "\n")
            else:
                time.sleep(3)
        # USE THIS PROFILE
        elif get_serial(cat_response, cfg_dict) or cat_response == "":
            if cat_response == "":
                u_serial = config.get("DEFAULT", "last_profile")
            else:
                u_serial = get_serial(cat_response, cfg_dict)
            selected = Credentials.fromconfig(config, u_serial)
            config.set("DEFAULT", "last_profile", u_serial)
            with open(configpath, "wb") as configfile:
                config.write(configfile)
            break

        else:
            pr3("Response " + cat_response + " Not Understood.\n")
            time.sleep(1)

    pr3("Profile selected:  " + str(selected))
    if selected.password == "":
        pr3("Profile has no password set. Please enter your WordPress password")
        selected.password = getpass.getpass()
    # Repeat process until credentials pass
    while not url_passes(selected, CHECK_PASSWORD=True):
        selected = get_credentials(config)

    pr3("Credentials Passed")
    return selected
Esempio n. 33
0
def url_passes(selected, CHECK_PASSWORD = False):
    # prepare client object
    # verify that credentials work by getting info
    if CHECK_PASSWORD == False or CHECK_PASSWORD == '':
        pr3("Making sure " + selected.url + " exists and is reachable.")
    else:
        pr3("Verifying host, username, and password.")
    rpc_server = xmlrpclib.ServerProxy(selected.url)
    try:
        userinfo = rpc_server.blogger.getUserInfo('', selected.user, selected.password)
        return True
    except gaierror:    # gaierror caught if no connection to host
        exc_type, exc_value, exc_traceback = sys.exc_info()
        # print(exc_type, exc_value, exc_traceback)   # Use print intead of pr3 because print can take three args
        pr3("\n" + selected.url + " is unreachable.")
        pr3("Please check the spelling and make sure your Internet is working.")
        pr3("Working example: http://cool_url.com/xmlrpc.php")
        pr3("You may try again in just a moment.")
        time.sleep(3)
        return False
    except xmlFault:    # xmlFault caught if host found but user/pass mismatch
        if CHECK_PASSWORD == False or CHECK_PASSWORD == '':
            # Don't bother checking if password is correct
            return True
        else:
            exc_type, exc_value, exc_traceback = sys.exc_info()
            print(exc_value)    # Using PRINT on purpose
            pr3("\nIncorrect Password. Please try again in just a moment.")
            time.sleep(3)
            return False
    except xmlrpcProtocolError:
            pr3("\nHTTP Protocol Error. Probably not your fault. Please try again in just a moment.")
            time.sleep(3)
            return False
Esempio n. 34
0
def get_html(input_file, CUT_FLAG):

    # Read data from file
    f = open(input_file, 'r')
    html = f.read()
    f.close()

    pr3 ("FORMAT")
    ELYXER_ENGINE = get_format(html)

    # Trim designated cut material from bottom of post
    html = trim_cut_material(html, CUT_FLAG, ELYXER_ENGINE)

    # RECORD TITLE FROM HEADER TO USE AS POST
    tit_exp = re.compile('''
        <title>         # Start of the <title> tag
        ..{1,}?         # Anything in the middle (non-greedy)
        </title>        # Closing </title> tag
        ''', re.VERBOSE)    # VERBOSE allows ''' '''
    tit_obj = tit_exp.search(html)
    # eLyXer uses 'Converted document' as the default title in the head
    # and body. LyXHTML uses 'LyX Document' as the default, but only
    # puts it in the head. The following code detects these default
    # titles and asks for a real title
    TITLE_EXPECTED_IN_BODY, TITLE_PROMPT = False, True
    pr3 ("\nTITLE")
    if(tit_obj):
        TITLE_EXPECTED_IN_BODY = True
        TITLE_PROMPT = False
        full_title_tag = tit_obj.group()
        blog_title = full_title_tag[7:-8]   # Strip tags off
        if (blog_title == 'Converted document'):    # eLyXer's default (head and body)
            TITLE_PROMPT = True
        if (blog_title == 'LyX Document'):  # LyXHTML's default (only in head)
            TITLE_PROMPT = True
            TITLE_EXPECTED_IN_BODY = False
    if(TITLE_PROMPT):
        pr3 ('No title found in document.')
        pr3 ('Please enter a title now')
        blog_title = sys.stdin.readline().replace('\n', '')
    pr3 ('Using title: ' + blog_title)

    # REMOVING TITLE FROM BODY
    # Typical body title using ENGINE_INTERNAL:
    #   <h1 class="title"><a id='magicparlabel-309' />
    #   Example Article Title</h1>
    #   <h1 class="title">
    # Typical body title using ELYXER_ENGINE using optional sizing:
    #   <h1 class="title">
    #   <span class="footnotesize">Hi Brian</span>
    #
    #   </h1>
    exp = re.compile('''
        <h1\                   # Beginning of tag with space
        class="title">         # The rest of the tag
        ..{1,}?                # Anything (non-greedy)
        </h1>                  # Closing tag
        ''', re.VERBOSE | re.DOTALL)                 # .. can include linebreaks
    bt_obj = exp.search(html)
    if(bt_obj):
        entire_bt_tag = bt_obj.group()
        html = html.replace(entire_bt_tag, '')
    elif (TITLE_EXPECTED_IN_BODY):
        pass
        #~ pr3 ('\nWARNING! The title of your entry may appear twice.')
        #~ pr3 ('Please notify the author at [email protected] to')
        #~ pr3 ('have this bug squashed.\n\n Press Enter to continue uploading.')
        #~ sys.stdin.readline()
        # What this really means is an opening title tag was found, but
        # no title tag was found in the body.

    # Eliminate everything outside the <body></body> tags
    START_TAG = '<body>'
    END_TAG = '</body>'
    if (START_TAG in html):
        html = html.partition(START_TAG)[2]
    html = html.partition(END_TAG)[0]

    # Reinvoke <code> and </code> tags from their escape sequence counterparts
    html = html.replace('&lt;code&gt;', '<code>')
    html = html.replace('&lt;/code&gt;', '</code>')

    # Remove Arrows from footnotes and margin notes
    html = html.replace('[→', '[')
    html = html.replace('→]', ']')
    
    # Change the elyxer-generated id to a class, since wordpresslib appears to 
    # strip out all ids upon upload
    html = html.replace("<div class=\"footer\" id=\"generated-by\">", "<div class=\"footer generated-by-elyxer\">")

    return html, blog_title, ELYXER_ENGINE