<commit_before># Vigenère Cipher Hacker
# https://www.nostarch.com/crackingcodes/ (BSD Licensed)

import itertools, re
import vigenereCipher, pyperclip, freqAnalysis, detectEnglish

LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
MAX_KEY_LENGTH = 16  # Will not attempt keys longer than this.
NUM_MOST_FREQ_LETTERS = 4  # Attempt this many letters per subkey.
SILENT_MODE = False  # If set to True, program doesn't print anything.
NONLETTERS_PATTERN = re.compile('[^A-Z]')

def main():
    # Instead of typing this ciphertext out, you can copy & paste it
    # from https://www.nostarch.com/crackingcodes/:
    ciphertext = """Adiz Avtzqeci Tmzubb wsa m Pmilqev halpqavtakuoi, lgouqdaf, kdmktsvmztsl, izr xoexghzr kkusitaaf. Vz wsa twbhdg ubalmmzhdad qz hce vmhsgohuqbo ox kaakulmd gxiwvos, krgdurdny i rcmmstugvtawz ca tzm ocicwxfg jf "stscmilpy" oid "uwydptsbuci" wabt hce Lcdwig eiovdnw. Bgfdny qe kddwtk qjnkqpsmev ba pz tzm roohwz at xoexghzr kkusicw izr vrlqrwxist uboedtuuznum. Pimifo Icmlv Emf DI, Lcdwig owdyzd xwd hce Ywhsmnemzh Xovm mby Cqxtsm Supacg (GUKE) oo Bdmfqclwg Bomk, Tzuhvif'a ocyetzqofifo ositjm. Rcm a lqys ce oie vzav wr Vpt 8, lpq gzclqab mekxabnittq tjr Ymdavn fihog cjgbhvnstkgds. Zm psqikmp o iuejqf jf lmoviiicqg aoj jdsvkavs Uzreiz qdpzmdg, dnutgrdny bts helpar jf lpq pjmtm, mb zlwkffjmwktoiiuix avczqzs ohsb ocplv nuby swbfwigk naf ohw Mzwbms umqcifm. Mtoej bts raj pq kjrcmp oo tzm Zooigvmz Khqauqvl Dincmalwdm, rhwzq vz cjmmhzd gvq ca tzm rwmsl lqgdgfa rcm a kbafzd-hzaumae kaakulmd, hce SKQ. Wi 1948 Tmzubb jgqzsy Msf Zsrmsv'e Qjmhcfwig Dincmalwdm vt Eizqcekbqf Pnadqfnilg, ivzrw pq onsaafsy if bts yenmxckmwvf ca tzm Yoiczmehzr uwydptwze oid tmoohe avfsmekbqr dn eifvzmsbuqvl tqazjgq. Pq kmolm m dvpwz ab ohw ktshiuix pvsaa at hojxtcbefmewn, afl bfzdakfsy okkuzgalqzu xhwuuqvl jmmqoigve gpcz ie hce Tmxcpsgd-Lvvbgbubnkq zqoxtawz, kciup isme xqdgo otaqfqev qz hce 1960k. Bgfdny'a tchokmjivlabk fzsmtfsy if i ofdmavmz krgaqqptawz wi 1952, wzmz vjmgaqlpad iohn wwzq goidt uzgeyix wi tzm Gbdtwl Wwigvwy. Vz aukqdoev bdsvtemzh rilp rshadm tcmmgvqg (xhwuuqvl uiehmalqab) vs sv mzoejvmhdvw ba dmikwz. Hpravs rdev qz 1954, xpsl whsm tow iszkk jqtjrw pug 42id tqdhcdsg, rfjm ugmbddw xawnofqzu. Vn avcizsl lqhzreqzsy tzif vds vmmhc wsa eidcalq; vds ewfvzr svp gjmw wfvzrk jqzdenmp vds vmmhc wsa mqxivmzhvl. Gv 10 Esktwunsm 2009, fgtxcrifo mb Dnlmdbzt uiydviyv, Nfdtaat Dmiem Ywiikbqf Bojlab Wrgez avdw iz cafakuog pmjxwx ahwxcby gv nscadn at ohw Jdwoikp scqejvysit xwd "hce sxboglavs kvy zm ion tjmmhzd." Sa at Haq 2012 i bfdvsbq azmtmd'g widt ion bwnafz tzm Tcpsw wr Zjrva ivdcz eaigd yzmbo Tmzubb a kbmhptgzk dvrvwz wa efiohzd."""
    hackedMessage = hackVigenere(ciphertext)

    if hackedMessage != None:
        print('Copying hacked message to clipboard:')
        print(hackedMessage)
        pyperclip.copy(hackedMessage)
    else:
        print('Failed to hack encryption.')

def findRepeatSequencesSpacings(message):
    # Goes through the message and finds any 3- to 5-letter sequences
    # that are repeated. Returns a dict with the keys of the sequence and
    # values of a list of spacings (num of letters between the repeats).

    # Use a regular expression to remove non-letters from the message:
    message = NONLETTERS_PATTERN.sub('', message.upper())

    # Compile a list of seqLen-letter sequences found in the message:
    seqSpacings = {}  # Keys are sequences; values are lists of int spacings.
    for seqLen in range(3, 6):
        for seqStart in range(len(message) - seqLen):
            # Determine what the sequence is and store it in seq:
            seq = message[seqStart:seqStart + seqLen]

            # Look for this sequence in the rest of the message:
            for i in range(seqStart + seqLen, len(message) - seqLen):
                if message[i:i + seqLen] == seq:
                    # Found a repeated sequence:
                    if seq not in seqSpacings:
                        seqSpacings[seq] = []  # Initialize blank list.

                    # Append the spacing distance between the repeated
                    # sequence and the original sequence:
                    seqSpacings[seq].append(i - seqStart)
    return seqSpacings

def getUsefulFactors(num):
    # Returns a list of useful factors of num. By "useful" we mean factors
    # less than MAX_KEY_LENGTH + 1 and not 1. For example,
    # getUsefulFactors(144) returns [2, 3, 4, 6, 8, 9, 12, 16].

    if num < 2:
        return []  # Numbers less than 2 have no useful factors.

    factors = []  # The list of factors found.

    # When finding factors, you only need to check the integers up to
    # MAX_KEY_LENGTH:
    for i in range(2, MAX_KEY_LENGTH + 1):  # Don't test 1: it's not useful.
        if num % i == 0:
            factors.append(i)
            otherFactor = int(num / i)
            if otherFactor < MAX_KEY_LENGTH + 1 and otherFactor != 1:
                factors.append(otherFactor)
    return list(set(factors))  # Remove duplicate factors.

def getItemAtIndexOne(x):
    return x[1]

def getMostCommonFactors(seqFactors):
    # First, get a count of how many times a factor occurs in seqFactors:
    factorCounts = {}  # Key is a factor; value is how often it occurs.

    # seqFactors keys are sequences; values are lists of factors of the
    # spacings. seqFactors has a value like {'GFD': [2, 3, 4, 6, 9, 12,
    # 18, 23, 36, 46, 69, 92, 138, 207], 'ALW': [2, 3, 4, 6, ...], ...}.
    for seq in seqFactors:
        factorList = seqFactors[seq]
        for factor in factorList:
            if factor not in factorCounts:
                factorCounts[factor] = 0
            factorCounts[factor] += 1

    # Second, put the factor and its count into a tuple and make a list
    # of these tuples so we can sort them:
    factorsByCount = []
    for factor in factorCounts:
        # Exclude factors larger than MAX_KEY_LENGTH:
        if factor <= MAX_KEY_LENGTH:
            # factorsByCount is a list of tuples: (factor, factorCount).
            # factorsByCount has a value like [(3, 497), (2, 487), ...].
            factorsByCount.append( (factor, factorCounts[factor]) )

    # Sort the list by the factor count:
    factorsByCount.sort(key=getItemAtIndexOne, reverse=True)

    return factorsByCount

def kasiskiExamination(ciphertext):
    # Find out the sequences of 3 to 5 letters that occur multiple times
    # in the ciphertext. repeatedSeqSpacings has a value like
    # {'EXG': [192], 'NAF': [339, 972, 633], ... }:
    repeatedSeqSpacings = findRepeatSequencesSpacings(ciphertext)

    # (See getMostCommonFactors() for a description of seqFactors.)
    seqFactors = {}
    for seq in repeatedSeqSpacings:
        seqFactors[seq] = []
        for spacing in repeatedSeqSpacings[seq]:
            seqFactors[seq].extend(getUsefulFactors(spacing))

    # (See getMostCommonFactors() for a description of factorsByCount.)
    factorsByCount = getMostCommonFactors(seqFactors)

    # Now we extract the factor counts from factorsByCount and
    # put them in allLikelyKeyLengths so that they are easier to
    # use later:
    allLikelyKeyLengths = []
    for twoIntTuple in factorsByCount:
        allLikelyKeyLengths.append(twoIntTuple[0])

    return allLikelyKeyLengths

def getNthSubkeysLetters(nth, keyLength, message):
    # Returns every nth letter for each keyLength set of letters in text.
    # E.g. getNthSubkeysLetters(1, 3, 'ABCABCABC') returns 'AAA'
    #      getNthSubkeysLetters(2, 3, 'ABCABCABC') returns 'BBB'
    #      getNthSubkeysLetters(3, 3, 'ABCABCABC') returns 'CCC'
    #      getNthSubkeysLetters(1, 5, 'ABCDEFGHI') returns 'AF'

    # Use a regular expression to remove non-letters from the message:
    message = NONLETTERS_PATTERN.sub('', message)

    i = nth - 1
    letters = []
    while i < len(message):
        letters.append(message[i])
        i += keyLength
    return ''.join(letters)

def attemptHackWithKeyLength(ciphertext, mostLikelyKeyLength):
    # Determine the most likely letters for each letter in the key:
    ciphertextUp = ciphertext.upper()
    # allFreqScores is a list of mostLikelyKeyLength number of lists.
    # These inner lists are the freqScores lists:
    allFreqScores = []
    for nth in range(1, mostLikelyKeyLength + 1):
        nthLetters = getNthSubkeysLetters(nth, mostLikelyKeyLength, ciphertextUp)

        # freqScores is a list of tuples like
        # [(<letter>, <Eng. Freq. match score>), ...]
        # List is sorted by match score. Higher score means better match.
        # See the englishFreqMatchScore() comments in freqAnalysis.py.
        freqScores = []
        for possibleKey in LETTERS:
            decryptedText = vigenereCipher.decryptMessage(possibleKey, nthLetters)
            keyAndFreqMatchTuple = (possibleKey, freqAnalysis.englishFreqMatchScore(decryptedText))
            freqScores.append(keyAndFreqMatchTuple)
        # Sort by match score:
        freqScores.sort(key=getItemAtIndexOne, reverse=True)

        allFreqScores.append(freqScores[:NUM_MOST_FREQ_LETTERS])

    if not SILENT_MODE:
        for i in range(len(allFreqScores)):
            # Use i + 1 so the first letter is not called the "0th" letter:
            print('Possible letters for letter %s of the key: ' % (i + 1), end='')
            for freqScore in allFreqScores[i]:
                print('%s ' % freqScore[0], end='')
            print()  # Print a newline.

    # Try every combination of the most likely letters for each position
    # in the key:
    for indexes in itertools.product(range(NUM_MOST_FREQ_LETTERS), repeat=mostLikelyKeyLength):
        # Create a possible key from the letters in allFreqScores:
        possibleKey = ''
        for i in range(mostLikelyKeyLength):
            possibleKey += allFreqScores[i][indexes[i]][0]

        if not SILENT_MODE:
            print('Attempting with key: %s' % possibleKey)

        decryptedText = vigenereCipher.decryptMessage(possibleKey, ciphertextUp)

        if detectEnglish.isEnglish(decryptedText):
            # Set the hacked ciphertext to the original casing:
            origCase = []
            for i in range(len(ciphertext)):
                if ciphertext[i].isupper():
                    origCase.append(decryptedText[i].upper())
                else:
                    origCase.append(decryptedText[i].lower())
            decryptedText = ''.join(origCase)

            # Check with user to see if the key has been found:
            print('Possible encryption hack with key %s:' % possibleKey)
            print(decryptedText[:200])  # Only show first 200 characters.
            print()
            print('Enter D if done, anything else to continue hacking:')
            response = input('> ')

            if response.strip().upper().startswith('D'):
                return decryptedText

    # No English-looking decryption found, so return None:
    return None

def hackVigenere(ciphertext):
    # First, we need to do Kasiski examination to figure out what the
    # length of the ciphertext's encryption key is:
    allLikelyKeyLengths = kasiskiExamination(ciphertext)
    if not SILENT_MODE:
        keyLengthStr = ''
        for keyLength in allLikelyKeyLengths:
            keyLengthStr += '%s ' % (keyLength)
        print('Kasiski examination results say the most likely key lengths are: ' + keyLengthStr + '\n')
    hackedMessage = None
    for keyLength in allLikelyKeyLengths:
        if not SILENT_MODE:
            print('Attempting hack with key length %s (%s possible keys)...' % (keyLength, NUM_MOST_FREQ_LETTERS ** keyLength))
        hackedMessage = attemptHackWithKeyLength(ciphertext, keyLength)
        if hackedMessage != None:
            break

    # If none of the key lengths found using Kasiski examination
    # worked, start brute-forcing through key lengths:
    if hackedMessage == None:
        if not SILENT_MODE:
            print('Unable to hack message with likely key length(s). Brute-forcing key length...')
        for keyLength in range(1, MAX_KEY_LENGTH + 1):
            # Don't recheck key lengths already tried from Kasiski:
            if keyLength not in allLikelyKeyLengths:
                if not SILENT_MODE:
                    print('Attempting hack with key length %s (%s possible keys)...' % (keyLength, NUM_MOST_FREQ_LETTERS ** keyLength))
                hackedMessage = attemptHackWithKeyLength(ciphertext, keyLength)
                if hackedMessage != None:
                    break
    return hackedMessage

# If vigenereHacker.py is run (instead of imported as a module), call
# the main() function:
if __name__ == '__main__':
    main()
<commit_msg>Update vigenereHacker: fixed comparisons with None using operators<commit_after># Vigenère Cipher Hacker
# https://www.nostarch.com/crackingcodes/ (BSD Licensed)

import itertools, re
import vigenereCipher, pyperclip, freqAnalysis, detectEnglish

LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
MAX_KEY_LENGTH = 16  # Will not attempt keys longer than this.
NUM_MOST_FREQ_LETTERS = 4  # Attempt this many letters per subkey.
SILENT_MODE = False  # If set to True, program doesn't print anything.
NONLETTERS_PATTERN = re.compile('[^A-Z]')

def main():
    # Instead of typing this ciphertext out, you can copy & paste it
    # from https://www.nostarch.com/crackingcodes/:
    ciphertext = """Adiz Avtzqeci Tmzubb wsa m Pmilqev halpqavtakuoi, lgouqdaf, kdmktsvmztsl, izr xoexghzr kkusitaaf. Vz wsa twbhdg ubalmmzhdad qz hce vmhsgohuqbo ox kaakulmd gxiwvos, krgdurdny i rcmmstugvtawz ca tzm ocicwxfg jf "stscmilpy" oid "uwydptsbuci" wabt hce Lcdwig eiovdnw. Bgfdny qe kddwtk qjnkqpsmev ba pz tzm roohwz at xoexghzr kkusicw izr vrlqrwxist uboedtuuznum. Pimifo Icmlv Emf DI, Lcdwig owdyzd xwd hce Ywhsmnemzh Xovm mby Cqxtsm Supacg (GUKE) oo Bdmfqclwg Bomk, Tzuhvif'a ocyetzqofifo ositjm. Rcm a lqys ce oie vzav wr Vpt 8, lpq gzclqab mekxabnittq tjr Ymdavn fihog cjgbhvnstkgds. Zm psqikmp o iuejqf jf lmoviiicqg aoj jdsvkavs Uzreiz qdpzmdg, dnutgrdny bts helpar jf lpq pjmtm, mb zlwkffjmwktoiiuix avczqzs ohsb ocplv nuby swbfwigk naf ohw Mzwbms umqcifm. Mtoej bts raj pq kjrcmp oo tzm Zooigvmz Khqauqvl Dincmalwdm, rhwzq vz cjmmhzd gvq ca tzm rwmsl lqgdgfa rcm a kbafzd-hzaumae kaakulmd, hce SKQ. Wi 1948 Tmzubb jgqzsy Msf Zsrmsv'e Qjmhcfwig Dincmalwdm vt Eizqcekbqf Pnadqfnilg, ivzrw pq onsaafsy if bts yenmxckmwvf ca tzm Yoiczmehzr uwydptwze oid tmoohe avfsmekbqr dn eifvzmsbuqvl tqazjgq. Pq kmolm m dvpwz ab ohw ktshiuix pvsaa at hojxtcbefmewn, afl bfzdakfsy okkuzgalqzu xhwuuqvl jmmqoigve gpcz ie hce Tmxcpsgd-Lvvbgbubnkq zqoxtawz, kciup isme xqdgo otaqfqev qz hce 1960k. Bgfdny'a tchokmjivlabk fzsmtfsy if i ofdmavmz krgaqqptawz wi 1952, wzmz vjmgaqlpad iohn wwzq goidt uzgeyix wi tzm Gbdtwl Wwigvwy. Vz aukqdoev bdsvtemzh rilp rshadm tcmmgvqg (xhwuuqvl uiehmalqab) vs sv mzoejvmhdvw ba dmikwz. Hpravs rdev qz 1954, xpsl whsm tow iszkk jqtjrw pug 42id tqdhcdsg, rfjm ugmbddw xawnofqzu. Vn avcizsl lqhzreqzsy tzif vds vmmhc wsa eidcalq; vds ewfvzr svp gjmw wfvzrk jqzdenmp vds vmmhc wsa mqxivmzhvl. Gv 10 Esktwunsm 2009, fgtxcrifo mb Dnlmdbzt uiydviyv, Nfdtaat Dmiem Ywiikbqf Bojlab Wrgez avdw iz cafakuog pmjxwx ahwxcby gv nscadn at ohw Jdwoikp scqejvysit xwd "hce sxboglavs kvy zm ion tjmmhzd." Sa at Haq 2012 i bfdvsbq azmtmd'g widt ion bwnafz tzm Tcpsw wr Zjrva ivdcz eaigd yzmbo Tmzubb a kbmhptgzk dvrvwz wa efiohzd."""
    hackedMessage = hackVigenere(ciphertext)

    if hackedMessage != None:
        print('Copying hacked message to clipboard:')
        print(hackedMessage)
        pyperclip.copy(hackedMessage)
    else:
        print('Failed to hack encryption.')

def findRepeatSequencesSpacings(message):
    # Goes through the message and finds any 3- to 5-letter sequences
    # that are repeated. Returns a dict with the keys of the sequence and
    # values of a list of spacings (num of letters between the repeats).

    # Use a regular expression to remove non-letters from the message:
    message = NONLETTERS_PATTERN.sub('', message.upper())

    # Compile a list of seqLen-letter sequences found in the message:
    seqSpacings = {}  # Keys are sequences; values are lists of int spacings.
    for seqLen in range(3, 6):
        for seqStart in range(len(message) - seqLen):
            # Determine what the sequence is and store it in seq:
            seq = message[seqStart:seqStart + seqLen]

            # Look for this sequence in the rest of the message:
            for i in range(seqStart + seqLen, len(message) - seqLen):
                if message[i:i + seqLen] == seq:
                    # Found a repeated sequence:
                    if seq not in seqSpacings:
                        seqSpacings[seq] = []  # Initialize blank list.

                    # Append the spacing distance between the repeated
                    # sequence and the original sequence:
                    seqSpacings[seq].append(i - seqStart)
    return seqSpacings

def getUsefulFactors(num):
    # Returns a list of useful factors of num. By "useful" we mean factors
    # less than MAX_KEY_LENGTH + 1 and not 1. For example,
    # getUsefulFactors(144) returns [2, 3, 4, 6, 8, 9, 12, 16].

    if num < 2:
        return []  # Numbers less than 2 have no useful factors.

    factors = []  # The list of factors found.

    # When finding factors, you only need to check the integers up to
    # MAX_KEY_LENGTH:
    for i in range(2, MAX_KEY_LENGTH + 1):  # Don't test 1: it's not useful.
        if num % i == 0:
            factors.append(i)
            otherFactor = int(num / i)
            if otherFactor < MAX_KEY_LENGTH + 1 and otherFactor != 1:
                factors.append(otherFactor)
    return list(set(factors))  # Remove duplicate factors.

def getItemAtIndexOne(x):
    return x[1]

def getMostCommonFactors(seqFactors):
    # First, get a count of how many times a factor occurs in seqFactors:
    factorCounts = {}  # Key is a factor; value is how often it occurs.

    # seqFactors keys are sequences; values are lists of factors of the
    # spacings. seqFactors has a value like {'GFD': [2, 3, 4, 6, 9, 12,
    # 18, 23, 36, 46, 69, 92, 138, 207], 'ALW': [2, 3, 4, 6, ...], ...}.
    for seq in seqFactors:
        factorList = seqFactors[seq]
        for factor in factorList:
            if factor not in factorCounts:
                factorCounts[factor] = 0
            factorCounts[factor] += 1

    # Second, put the factor and its count into a tuple and make a list
    # of these tuples so we can sort them:
    factorsByCount = []
    for factor in factorCounts:
        # Exclude factors larger than MAX_KEY_LENGTH:
        if factor <= MAX_KEY_LENGTH:
            # factorsByCount is a list of tuples: (factor, factorCount).
            # factorsByCount has a value like [(3, 497), (2, 487), ...].
            factorsByCount.append( (factor, factorCounts[factor]) )

    # Sort the list by the factor count:
    factorsByCount.sort(key=getItemAtIndexOne, reverse=True)

    return factorsByCount

def kasiskiExamination(ciphertext):
    # Find out the sequences of 3 to 5 letters that occur multiple times
    # in the ciphertext. repeatedSeqSpacings has a value like
    # {'EXG': [192], 'NAF': [339, 972, 633], ... }:
    repeatedSeqSpacings = findRepeatSequencesSpacings(ciphertext)

    # (See getMostCommonFactors() for a description of seqFactors.)
    seqFactors = {}
    for seq in repeatedSeqSpacings:
        seqFactors[seq] = []
        for spacing in repeatedSeqSpacings[seq]:
            seqFactors[seq].extend(getUsefulFactors(spacing))

    # (See getMostCommonFactors() for a description of factorsByCount.)
    factorsByCount = getMostCommonFactors(seqFactors)

    # Now we extract the factor counts from factorsByCount and
    # put them in allLikelyKeyLengths so that they are easier to
    # use later:
    allLikelyKeyLengths = []
    for twoIntTuple in factorsByCount:
        allLikelyKeyLengths.append(twoIntTuple[0])

    return allLikelyKeyLengths

def getNthSubkeysLetters(nth, keyLength, message):
    # Returns every nth letter for each keyLength set of letters in text.
    # E.g. getNthSubkeysLetters(1, 3, 'ABCABCABC') returns 'AAA'
    #      getNthSubkeysLetters(2, 3, 'ABCABCABC') returns 'BBB'
    #      getNthSubkeysLetters(3, 3, 'ABCABCABC') returns 'CCC'
    #      getNthSubkeysLetters(1, 5, 'ABCDEFGHI') returns 'AF'

    # Use a regular expression to remove non-letters from the message:
    message = NONLETTERS_PATTERN.sub('', message)

    i = nth - 1
    letters = []
    while i < len(message):
        letters.append(message[i])
        i += keyLength
    return ''.join(letters)

def attemptHackWithKeyLength(ciphertext, mostLikelyKeyLength):
    # Determine the most likely letters for each letter in the key:
    ciphertextUp = ciphertext.upper()
    # allFreqScores is a list of mostLikelyKeyLength number of lists.
    # These inner lists are the freqScores lists:
    allFreqScores = []
    for nth in range(1, mostLikelyKeyLength + 1):
        nthLetters = getNthSubkeysLetters(nth, mostLikelyKeyLength, ciphertextUp)

        # freqScores is a list of tuples like
        # [(<letter>, <Eng. Freq. match score>), ...]
        # List is sorted by match score. Higher score means better match.
        # See the englishFreqMatchScore() comments in freqAnalysis.py.
        freqScores = []
        for possibleKey in LETTERS:
            decryptedText = vigenereCipher.decryptMessage(possibleKey, nthLetters)
            keyAndFreqMatchTuple = (possibleKey, freqAnalysis.englishFreqMatchScore(decryptedText))
            freqScores.append(keyAndFreqMatchTuple)
        # Sort by match score:
        freqScores.sort(key=getItemAtIndexOne, reverse=True)

        allFreqScores.append(freqScores[:NUM_MOST_FREQ_LETTERS])

    if not SILENT_MODE:
        for i in range(len(allFreqScores)):
            # Use i + 1 so the first letter is not called the "0th" letter:
            print('Possible letters for letter %s of the key: ' % (i + 1), end='')
            for freqScore in allFreqScores[i]:
                print('%s ' % freqScore[0], end='')
            print()  # Print a newline.

    # Try every combination of the most likely letters for each position
    # in the key:
    for indexes in itertools.product(range(NUM_MOST_FREQ_LETTERS), repeat=mostLikelyKeyLength):
        # Create a possible key from the letters in allFreqScores:
        possibleKey = ''
        for i in range(mostLikelyKeyLength):
            possibleKey += allFreqScores[i][indexes[i]][0]

        if not SILENT_MODE:
            print('Attempting with key: %s' % possibleKey)

        decryptedText = vigenereCipher.decryptMessage(possibleKey, ciphertextUp)

        if detectEnglish.isEnglish(decryptedText):
            # Set the hacked ciphertext to the original casing:
            origCase = []
            for i in range(len(ciphertext)):
                if ciphertext[i].isupper():
                    origCase.append(decryptedText[i].upper())
                else:
                    origCase.append(decryptedText[i].lower())
            decryptedText = ''.join(origCase)

            # Check with user to see if the key has been found:
            print('Possible encryption hack with key %s:' % possibleKey)
            print(decryptedText[:200])  # Only show first 200 characters.
            print()
            print('Enter D if done, anything else to continue hacking:')
            response = input('> ')

            if response.strip().upper().startswith('D'):
                return decryptedText

    # No English-looking decryption found, so return None:
    return None

def hackVigenere(ciphertext):
    # First, we need to do Kasiski examination to figure out what the
    # length of the ciphertext's encryption key is:
    allLikelyKeyLengths = kasiskiExamination(ciphertext)
    if not SILENT_MODE:
        keyLengthStr = ''
        for keyLength in allLikelyKeyLengths:
            keyLengthStr += '%s ' % (keyLength)
        print('Kasiski examination results say the most likely key lengths are: ' + keyLengthStr + '\n')
    hackedMessage = None
    for keyLength in allLikelyKeyLengths:
        if not SILENT_MODE:
            print('Attempting hack with key length %s (%s possible keys)...' % (keyLength, NUM_MOST_FREQ_LETTERS ** keyLength))
        hackedMessage = attemptHackWithKeyLength(ciphertext, keyLength)
        if hackedMessage is not None:
            break

    # If none of the key lengths found using Kasiski examination
    # worked, start brute-forcing through key lengths:
    if hackedMessage is None:
        if not SILENT_MODE:
            print('Unable to hack message with likely key length(s). Brute-forcing key length...')
        for keyLength in range(1, MAX_KEY_LENGTH + 1):
            # Don't recheck key lengths already tried from Kasiski:
            if keyLength not in allLikelyKeyLengths:
                if not SILENT_MODE:
                    print('Attempting hack with key length %s (%s possible keys)...' % (keyLength, NUM_MOST_FREQ_LETTERS ** keyLength))
                hackedMessage = attemptHackWithKeyLength(ciphertext, keyLength)
                if hackedMessage is not None:
                    break
    return hackedMessage

# If vigenereHacker.py is run (instead of imported as a module), call
# the main() function:
if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
#
# pylint: disable=superfluous-parens
#
# Created by: Pavlos Parissis <pavlos.parissis@gmail.com>
#
"""Manage servers

Usage:
    haproxytool server [-D DIR ] (-r | -s | -e | -R | -p | -W | -i) [--backend=<name>...] [NAME...]
    haproxytool server [-D DIR ] -w VALUE [--backend=<name>...] [NAME...]
    haproxytool server [-D DIR -f ] (-d | -t | -n) [--backend=<name>...] [NAME...]
    haproxytool server [-D DIR ] (-l | -M)
    haproxytool server [-D DIR ] -m METRIC [--backend=<name>...] [NAME...]

Arguments:
    DIR     Directory path
    VALUE   Value to set
    METRIC  Name of a metric, use '-M' to get metric names

Options:
    -h, --help                show this screen
    -e, --enable              enable server
    -d, --disable             disable server
    -R, --ready               set server in normal mode
    -n, --drain               drain server
    -t, --maintenance         set server in maintenance mode
    -r, --requests            show requests
    -p, --process             show process number
    -i, --sid                 show server ID
    -s, --status              show status
    -m, --metric              show value of a metric
    -M, --list-metrics        show all metrics
    -l, --list                show all servers
    -w, --weight              change weight for server
    -W, --get-weight          show weight of server
    -f, --force               force an operation
    -D DIR, --socket-dir=DIR  directory with HAProxy socket files
                              [default: /var/lib/haproxy]

"""
import sys
from docopt import docopt
from haproxyadmin import haproxy, exceptions
from operator import methodcaller
from haproxyadmin.exceptions import (SocketApplicationError,
                                     SocketConnectionError,
                                     SocketPermissionError)
from .utils import get_arg_option, abort_command

class ServerCommand(object):
    def __init__(self, hap, args):
        self.hap = hap
        self.args = args
        self.servers = self.build_server_list(
            args['NAME'],
            args['--backend'])

    def build_server_list(self, names=None, backends=None):
        servers = []
        if not names:
            if not backends:
                for server in self.hap.servers():
                    servers.append(server)
            else:
                for backend in backends:
                    for server in self.hap.servers(backend):
                        servers.append(server)
        else:
            if not backends:
                for name in names:
                    try:
                        for server in self.hap.server(name):
                            servers.append(server)
                    except ValueError:
                        print("{} was not found".format(name))
            else:
                for backend in backends:
                    for name in names:
                        try:
                            for server in self.hap.server(name, backend):
                                servers.append(server)
                        except ValueError:
                            print("{} was not found".format(name))

        return servers

    def list(self):
        print("# backendname servername")
        for server in self.servers:
            print("{:<30} {}".format(server.backendname, server.name))

    def status(self):
        print("# backendname servername")
        for server in self.servers:
            print("{:<30} {:<42} {}".format(server.backendname, server.name,
                                            server.status))

    def requests(self):
        print("# backendname servername")
        for server in self.servers:
            print("{:<30} {:<42} {}".format(server.backendname, server.name,
                                            server.requests))

    def sid(self):
        print("# backendname servername")
        for server in self.servers:
            print("{:<30} {:<42} {}".format(server.backendname, server.name,
                                            server.sid))

    def process(self):
        print("# backendname servername")
        for server in self.servers:
            print("{:<30} {:<42} {}".format(server.backendname, server.name,
                                            server.process_nb))

    def enable(self):
        for server in self.servers:
            try:
                server.setstate(haproxy.STATE_ENABLE)
                print("{} enabled in {} backend".format(server.name,
                                                        server.backendname))
            except exceptions.CommandFailed as error:
                print("{} failed to be enabled:{}".format(server.name, error))

    def disable(self):
        if abort_command('disable', 'servers', self.servers,
                         self.args['--force']):
            sys.exit('Aborted by user')

        for server in self.servers:
            try:
                server.setstate(haproxy.STATE_DISABLE)
                print("{} disabled in {} backend".format(server.name,
                                                         server.backendname))
            except exceptions.CommandFailed as error:
                print("{} failed to be disabled:{}".format(server.name, error))

    def ready(self):
        for server in self.servers:
            try:
                server.setstate(haproxy.STATE_READY)
                print("{} set to ready in {} backend".format(
                    server.name, server.backendname)
                )
            except exceptions.CommandFailed as error:
                print("{} failed to set normal state:{}".format(server.name,
                                                                error))

    def drain(self):
        if abort_command('drain', 'servers', self.servers,
                         self.args['--force']):
            sys.exit('Aborted by user')

        for server in self.servers:
            try:
                server.setstate(haproxy.STATE_DRAIN)
                print("{} set to drain in {} backend".format(
                    server.name, server.backendname)
                )
            except exceptions.CommandFailed as error:
                print("{} failed to set in drain state:{}".format(server.name,
                                                                  error))

    def maintenance(self):
        if abort_command('maintenance', 'servers', self.servers,
                         self.args['--force']):
            sys.exit('Aborted by user')

        for server in self.servers:
            try:
                server.setstate(haproxy.STATE_MAINT)
                print("{} set to maintenance in {} backend".format(
                    server.name, server.backendname)
                )
            except exceptions.CommandFailed as error:
                print("{} failed to set to maintenance state:{}".format(
                    server.name, error))

    def weight(self):
        value = self.args['VALUE']
        try:
            value = int(value)
            method_caller = methodcaller('setweight', value)
            for server in self.servers:
                try:
                    method_caller(server)
                    print("{} backend set weight to {} in {} backend".format(
                        server.name, value, server.backendname))
                except exceptions.CommandFailed as error:
                    print("{} failed to change weight:{}".format(server.name,
                                                                 error))
        except ValueError as error:
            sys.exit("{}".format(error))

    def metric(self):
        metric = self.args['METRIC']
        if metric not in haproxy.SERVER_METRICS:
            sys.exit("{} no valid metric".format(metric))

        print("# backendname servername")
        for server in self.servers:
            print("{:<30} {:<42} {}".format(server.backendname, server.name,
                                            server.metric(metric)))

    def getweight(self):
        print("# backendname servername")
        for server in self.servers:
            print("{:<30} {:<42} {}".format(server.backendname, server.name,
                                            server.weight))

    def listmetrics(self):
        for metric in haproxy.SERVER_METRICS:
            print(metric)

def main():
    arguments = docopt(__doc__)
    try:
        hap = haproxy.HAProxy(socket_dir=arguments['--socket-dir'])
    except (SocketApplicationError,
            SocketConnectionError,
            SocketPermissionError) as error:
        print(error, error.socket_file)
        sys.exit(1)
    except ValueError as error:
        print(error)
        sys.exit(1)

    cmd = ServerCommand(hap, arguments)
    method = get_arg_option(arguments)
    getattr(cmd, method)()

# This is the standard boilerplate that calls the main() function.
if __name__ == '__main__':
    main()
<commit_msg>order server options alphabetically<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
#
# pylint: disable=superfluous-parens
#
# Created by: Pavlos Parissis <pavlos.parissis@gmail.com>
#
"""Manage servers

Usage:
    haproxytool server [-D DIR ] (-r | -s | -e | -R | -p | -W | -i) [--backend=<name>...] [NAME...]
    haproxytool server [-D DIR ] -w VALUE [--backend=<name>...] [NAME...]
    haproxytool server [-D DIR -f ] (-d | -t | -n) [--backend=<name>...] [NAME...]
    haproxytool server [-D DIR ] (-l | -M)
    haproxytool server [-D DIR ] -m METRIC [--backend=<name>...] [NAME...]

Arguments:
    DIR     Directory path
    VALUE   Value to set
    METRIC  Name of a metric, use '-M' to get metric names

Options:
    -d, --disable             disable server
    -e, --enable              enable server
    -f, --force               force an operation
    -h, --help                show this screen
    -i, --sid                 show server ID
    -l, --list                show all servers
    -m, --metric              show value of a metric
    -M, --list-metrics        show all metrics
    -n, --drain               drain server
    -p, --process             show process number
    -r, --requests            show requests
    -R, --ready               set server in normal mode
    -s, --status              show status
    -t, --maintenance         set server in maintenance mode
    -w, --weight              change weight for server
    -W, --get-weight          show weight of server
    -D DIR, --socket-dir=DIR  directory with HAProxy socket files
                              [default: /var/lib/haproxy]

"""
import sys
from docopt import docopt
from haproxyadmin import haproxy, exceptions
from operator import methodcaller
from haproxyadmin.exceptions import (SocketApplicationError,
                                     SocketConnectionError,
                                     SocketPermissionError)
from .utils import get_arg_option, abort_command

class ServerCommand(object):
    def __init__(self, hap, args):
        self.hap = hap
        self.args = args
        self.servers = self.build_server_list(
            args['NAME'],
            args['--backend'])

    def build_server_list(self, names=None, backends=None):
        servers = []
        if not names:
            if not backends:
                for server in self.hap.servers():
                    servers.append(server)
            else:
                for backend in backends:
                    for server in self.hap.servers(backend):
                        servers.append(server)
        else:
            if not backends:
                for name in names:
                    try:
                        for server in self.hap.server(name):
                            servers.append(server)
                    except ValueError:
                        print("{} was not found".format(name))
            else:
                for backend in backends:
                    for name in names:
                        try:
                            for server in self.hap.server(name, backend):
                                servers.append(server)
                        except ValueError:
                            print("{} was not found".format(name))

        return servers

    def list(self):
        print("# backendname servername")
        for server in self.servers:
            print("{:<30} {}".format(server.backendname, server.name))

    def status(self):
        print("# backendname servername")
        for server in self.servers:
            print("{:<30} {:<42} {}".format(server.backendname, server.name,
                                            server.status))

    def requests(self):
        print("# backendname servername")
        for server in self.servers:
            print("{:<30} {:<42} {}".format(server.backendname, server.name,
                                            server.requests))

    def sid(self):
        print("# backendname servername")
        for server in self.servers:
            print("{:<30} {:<42} {}".format(server.backendname, server.name,
                                            server.sid))

    def process(self):
        print("# backendname servername")
        for server in self.servers:
            print("{:<30} {:<42} {}".format(server.backendname, server.name,
                                            server.process_nb))

    def enable(self):
        for server in self.servers:
            try:
                server.setstate(haproxy.STATE_ENABLE)
                print("{} enabled in {} backend".format(server.name,
                                                        server.backendname))
            except exceptions.CommandFailed as error:
                print("{} failed to be enabled:{}".format(server.name, error))

    def disable(self):
        if abort_command('disable', 'servers', self.servers,
                         self.args['--force']):
            sys.exit('Aborted by user')

        for server in self.servers:
            try:
                server.setstate(haproxy.STATE_DISABLE)
                print("{} disabled in {} backend".format(server.name,
                                                         server.backendname))
            except exceptions.CommandFailed as error:
                print("{} failed to be disabled:{}".format(server.name, error))

    def ready(self):
        for server in self.servers:
            try:
                server.setstate(haproxy.STATE_READY)
                print("{} set to ready in {} backend".format(
                    server.name, server.backendname)
                )
            except exceptions.CommandFailed as error:
                print("{} failed to set normal state:{}".format(server.name,
                                                                error))

    def drain(self):
        if abort_command('drain', 'servers', self.servers,
                         self.args['--force']):
            sys.exit('Aborted by user')

        for server in self.servers:
            try:
                server.setstate(haproxy.STATE_DRAIN)
                print("{} set to drain in {} backend".format(
                    server.name, server.backendname)
                )
            except exceptions.CommandFailed as error:
                print("{} failed to set in drain state:{}".format(server.name,
                                                                  error))

    def maintenance(self):
        if abort_command('maintenance', 'servers', self.servers,
                         self.args['--force']):
            sys.exit('Aborted by user')

        for server in self.servers:
            try:
                server.setstate(haproxy.STATE_MAINT)
                print("{} set to maintenance in {} backend".format(
                    server.name, server.backendname)
                )
            except exceptions.CommandFailed as error:
                print("{} failed to set to maintenance state:{}".format(
                    server.name, error))

    def weight(self):
        value = self.args['VALUE']
        try:
            value = int(value)
            method_caller = methodcaller('setweight', value)
            for server in self.servers:
                try:
                    method_caller(server)
                    print("{} backend set weight to {} in {} backend".format(
                        server.name, value, server.backendname))
                except exceptions.CommandFailed as error:
                    print("{} failed to change weight:{}".format(server.name,
                                                                 error))
        except ValueError as error:
            sys.exit("{}".format(error))

    def metric(self):
        metric = self.args['METRIC']
        if metric not in haproxy.SERVER_METRICS:
            sys.exit("{} no valid metric".format(metric))

        print("# backendname servername")
        for server in self.servers:
            print("{:<30} {:<42} {}".format(server.backendname, server.name,
                                            server.metric(metric)))

    def getweight(self):
        print("# backendname servername")
        for server in self.servers:
            print("{:<30} {:<42} {}".format(server.backendname, server.name,
                                            server.weight))

    def listmetrics(self):
        for metric in haproxy.SERVER_METRICS:
            print(metric)

def main():
    arguments = docopt(__doc__)
    try:
        hap = haproxy.HAProxy(socket_dir=arguments['--socket-dir'])
    except (SocketApplicationError,
            SocketConnectionError,
            SocketPermissionError) as error:
        print(error, error.socket_file)
        sys.exit(1)
    except ValueError as error:
        print(error)
        sys.exit(1)

    cmd = ServerCommand(hap, arguments)
    method = get_arg_option(arguments)
    getattr(cmd, method)()

# This is the standard boilerplate that calls the main() function.
if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before>"""
Django settings for this project.

Generated by 'django-admin startproject' using Django 1.8.1.

For more information on this file, see
https://docs.djangoproject.com/en/1.8/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.8/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
import logging.config

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
# The SECRET_KEY is provided via an environment variable in OpenShift
SECRET_KEY = os.getenv(
    'DJANGO_SECRET_KEY',
    # safe value used for development when DJANGO_SECRET_KEY might not be set
    '9e4@&tw46$l31)zrqe3wi+-slqm(ruvz&se0^%9#6(_w3ui!c0'
)

# SECURITY WARNING: don't run with debug turned on in production!
#DEBUG = False
DEBUG = os.getenv('DJANGO_DEBUG', 'True') == 'True'

# Controls availability of the data entry functionality
ENABLE_DATA_ENTRY = os.getenv('ENABLE_DATA_ENTRY', 'False') == 'True'

# Controls availability of Google Analytics
ENABLE_GOOGLE_ANALYTICS = os.getenv('ENABLE_GOOGLE_ANALYTICS', 'False') == 'True'

# Controls app context
APP_CONTEXT_ROOT = os.getenv('APP_CONTEXT_ROOT','')

ALLOWED_HOSTS = ['*']

# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'debug_toolbar',
	'django.contrib.postgres',
    'gwells',
    'crispy_forms',
    'formtools',
)

MIDDLEWARE = (
    'debug_toolbar.middleware.DebugToolbarMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
)

ROOT_URLCONF = 'gwells.urls'
INTERNAL_IPS = ('127.0.0.1')

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'wsgi.application'
CRISPY_TEMPLATE_PACK = 'bootstrap3'

# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases

from . import database

DATABASES = {
    'default': database.config()
}

# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/

if APP_CONTEXT_ROOT:
   STATIC_URL = '/'+ APP_CONTEXT_ROOT +'/static/'
else:
   STATIC_URL = '/static/'

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
        },
        'simple': {
            'format': '%(levelname)s %(message)s'
        },
    },
    'handlers': {
        'console_handler': {
            'class': 'logging.StreamHandler',
            'level':'DEBUG',
            'formatter':'verbose',
            'filters': ['require_debug_false']
        }
    },
    'loggers': {
        'django.request': {
            'handlers': ['console_handler'],
            'level': 'DEBUG',
            'propagate': True,
        },
    }
}<commit_msg>Fix for getting the environmnet variables work properly<commit_after>"""
Django settings for this project.

Generated by 'django-admin startproject' using Django 1.8.1.

For more information on this file, see
https://docs.djangoproject.com/en/1.8/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.8/ref/settings/
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
import logging.config

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
# The SECRET_KEY is provided via an environment variable in OpenShift
SECRET_KEY = os.getenv(
    'DJANGO_SECRET_KEY',
    # safe value used for development when DJANGO_SECRET_KEY might not be set
    '9e4@&tw46$l31)zrqe3wi+-slqm(ruvz&se0^%9#6(_w3ui!c0'
)

# SECURITY WARNING: don't run with debug turned on in production!
#DEBUG = False
DEBUG = os.getenv('DJANGO_DEBUG', 'True') == 'True'

# Controls availability of the data entry functionality
ENABLE_DATA_ENTRY = os.getenv('ENABLE_DATA_ENTRY', 'True') == 'True'

# Controls availability of Google Analytics
ENABLE_GOOGLE_ANALYTICS = os.getenv('ENABLE_GOOGLE_ANALYTICS', 'True') == 'True'

# Controls app context
APP_CONTEXT_ROOT = os.getenv('APP_CONTEXT_ROOT','')

ALLOWED_HOSTS = ['*']

# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'debug_toolbar',
	'django.contrib.postgres',
    'gwells',
    'crispy_forms',
    'formtools',
)

MIDDLEWARE = (
    'debug_toolbar.middleware.DebugToolbarMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
)

ROOT_URLCONF = 'gwells.urls'
INTERNAL_IPS = ('127.0.0.1')

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'wsgi.application'
CRISPY_TEMPLATE_PACK = 'bootstrap3'

# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases

from . import database

DATABASES = {
    'default': database.config()
}

# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/

if APP_CONTEXT_ROOT:
   STATIC_URL = '/'+ APP_CONTEXT_ROOT +'/static/'
else:
   STATIC_URL = '/static/'

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
        },
        'simple': {
            'format': '%(levelname)s %(message)s'
        },
    },
    'handlers': {
        'console_handler': {
            'class': 'logging.StreamHandler',
            'level':'DEBUG',
            'formatter':'verbose',
            'filters': ['require_debug_false']
        }
    },
    'loggers': {
        'django.request': {
            'handlers': ['console_handler'],
            'level': 'DEBUG',
            'propagate': True,
        },
    }
}<|endoftext|>


<commit_before># vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
"""
Unit Tests for network code
"""
import IPy
import os
import logging

from nova import db
from nova import exception
from nova import flags
from nova import test
from nova import utils
from nova.auth import manager

FLAGS = flags.FLAGS

class NetworkTestCase(test.TrialTestCase):
    """Test cases for network code"""
    def setUp(self):  # pylint: disable-msg=C0103
        super(NetworkTestCase, self).setUp()
        # NOTE(vish): if you change these flags, make sure to change the
        #             flags in the corresponding section in nova-dhcpbridge
        self.flags(connection_type='fake',
                   fake_storage=True,
                   fake_network=True,
                   auth_driver='nova.auth.ldapdriver.FakeLdapDriver',
                   network_size=16,
                   num_networks=5)
        logging.getLogger().setLevel(logging.DEBUG)
        self.manager = manager.AuthManager()
        self.user = self.manager.create_user('netuser', 'netuser', 'netuser')
        self.projects = []
        self.network = utils.import_object(FLAGS.network_manager)
        self.context = None
        for i in range(5):
            name = 'project%s' % i
            self.projects.append(self.manager.create_project(name,
                                                             'netuser',
                                                             name))
            # create the necessary network data for the project
            self.network.set_network_host(self.context, self.projects[i].id)
        instance_id = db.instance_create(None,
                                         {'mac_address': utils.generate_mac()})
        self.instance_id = instance_id
        instance_id = db.instance_create(None,
                                         {'mac_address': utils.generate_mac()})
        self.instance2_id = instance_id

    def tearDown(self):  # pylint: disable-msg=C0103
        super(NetworkTestCase, self).tearDown()
        # TODO(termie): this should really be instantiating clean datastores
        #               in between runs, one failure kills all the tests
        db.instance_destroy(None, self.instance_id)
        db.instance_destroy(None, self.instance2_id)
        for project in self.projects:
            self.manager.delete_project(project)
        self.manager.delete_user(self.user)

    def _create_address(self, project_num, instance_id=None):
        """Create an address in given project num"""
        net = db.project_get_network(None, self.projects[project_num].id)
        address = db.fixed_ip_allocate(None, net['id'])
        if instance_id is None:
            instance_id = self.instance_id
        db.fixed_ip_instance_associate(None, address, instance_id)
        return address

    def test_public_network_association(self):
        """Makes sure that we can allocaate a public ip"""
        # TODO(vish): better way of adding floating ips
        pubnet = IPy.IP(flags.FLAGS.public_range)
        ip_str = str(pubnet[0])
        try:
            db.floating_ip_get_by_address(None, ip_str)
        except exception.NotFound:
            db.floating_ip_create(None, ip_str, FLAGS.host)
        float_addr = self.network.allocate_floating_ip(self.context,
                                                       self.projects[0].id)
        fix_addr = self._create_address(0)
        self.assertEqual(float_addr, str(pubnet[0]))
        self.network.associate_floating_ip(self.context, float_addr, fix_addr)
        address = db.instance_get_floating_address(None, self.instance_id)
        self.assertEqual(address, float_addr)
        self.network.disassociate_floating_ip(self.context, float_addr)
        address = db.instance_get_floating_address(None, self.instance_id)
        self.assertEqual(address, None)
        self.network.deallocate_floating_ip(self.context, float_addr)
        db.fixed_ip_deallocate(None, fix_addr)

    def test_allocate_deallocate_fixed_ip(self):
        """Makes sure that we can allocate and deallocate a fixed ip"""
        address = self._create_address(0)
        self.assertTrue(is_allocated_in_project(address, self.projects[0].id))
        lease_ip(address)
        db.fixed_ip_deallocate(None, address)

        # Doesn't go away until it's dhcp released
        self.assertTrue(is_allocated_in_project(address, self.projects[0].id))

        release_ip(address)
        self.assertFalse(is_allocated_in_project(address, self.projects[0].id))

    def test_side_effects(self):
        """Ensures allocating and releasing has no side effects"""
        address = self._create_address(0)
        address2 = self._create_address(1, self.instance2_id)

        self.assertTrue(is_allocated_in_project(address, self.projects[0].id))
        self.assertTrue(is_allocated_in_project(address2, self.projects[1].id))
        self.assertFalse(is_allocated_in_project(address, self.projects[1].id))

        # Addresses are allocated before they're issued
        lease_ip(address)
        lease_ip(address2)

        db.fixed_ip_deallocate(None, address)
        release_ip(address)
        self.assertFalse(is_allocated_in_project(address, self.projects[0].id))

        # First address release shouldn't affect the second
        self.assertTrue(is_allocated_in_project(address2, self.projects[1].id))

        db.fixed_ip_deallocate(None, address2)
        release_ip(address2)
        self.assertFalse(is_allocated_in_project(address2,
                                                 self.projects[1].id))

    def test_subnet_edge(self):
        """Makes sure that private ips don't overlap"""
        first = self._create_address(0)
        lease_ip(first)
        for i in range(1, 5):
            address = self._create_address(i)
            address2 = self._create_address(i)
            address3 = self._create_address(i)
            lease_ip(address)
            lease_ip(address2)
            lease_ip(address3)
            self.assertFalse(is_allocated_in_project(address,
                                                     self.projects[0].id))
            self.assertFalse(is_allocated_in_project(address2,
                                                     self.projects[0].id))
            self.assertFalse(is_allocated_in_project(address3,
                                                     self.projects[0].id))
            db.fixed_ip_deallocate(None, address)
            db.fixed_ip_deallocate(None, address2)
            db.fixed_ip_deallocate(None, address3)
            release_ip(address)
            release_ip(address2)
            release_ip(address3)
        release_ip(first)
        db.fixed_ip_deallocate(None, first)

    def test_vpn_ip_and_port_looks_valid(self):
        """Ensure the vpn ip and port are reasonable"""
        self.assert_(self.projects[0].vpn_ip)
        self.assert_(self.projects[0].vpn_port >= FLAGS.vpn_start)
        self.assert_(self.projects[0].vpn_port <= FLAGS.vpn_start +
                                                  FLAGS.num_networks)

    def test_too_many_networks(self):
        """Ensure error is raised if we run out of networks"""
        projects = []
        networks_left = FLAGS.num_networks - db.network_count(None)
        for i in range(networks_left):
            project = self.manager.create_project('many%s' % i, self.user)
            projects.append(project)
        self.assertRaises(db.NoMoreNetworks,
                          self.manager.create_project,
                          'boom',
                          self.user)
        for project in projects:
            self.manager.delete_project(project)

    def test_ips_are_reused(self):
        """Makes sure that ip addresses that are deallocated get reused"""
        address = self._create_address(0)
        lease_ip(address)
        db.fixed_ip_deallocate(None, address)
        release_ip(address)

        address2 = self._create_address(0)
        self.assertEqual(address, address2)
        db.fixed_ip_deallocate(None, address2)

    def test_available_ips(self):
        """Make sure the number of available ips for the network is correct

        The number of available IP addresses depends on the test
        environment's setup.

        Network size is set in test fixture's setUp method.

        There are ips reserved at the bottom and top of the range.
        services (network, gateway, CloudPipe, broadcast)
        """
        network = db.project_get_network(None, self.projects[0].id)
        net_size = flags.FLAGS.network_size
        total_ips = (db.network_count_available_ips(None, network['id']) +
                     db.network_count_reserved_ips(None, network['id']) +
                     db.network_count_allocated_ips(None, network['id']))
        self.assertEqual(total_ips, net_size)

    def test_too_many_addresses(self):
        """Test for a NoMoreAddresses exception when all fixed ips are used.
        """
        network = db.project_get_network(None, self.projects[0].id)
        num_available_ips = db.network_count_available_ips(None,
                                                           network['id'])
        addresses = []
        for i in range(num_available_ips):
            address = self._create_address(0)
            addresses.append(address)
            lease_ip(address)

        self.assertEqual(db.network_count_available_ips(None,
                                                        network['id']), 0)
        self.assertRaises(db.NoMoreAddresses,
                          db.fixed_ip_allocate,
                          None,
                          network['id'])

        for i in range(len(addresses)):
            db.fixed_ip_deallocate(None, addresses[i])
            release_ip(addresses[i])
        self.assertEqual(db.network_count_available_ips(None,
                                                        network['id']),
                         num_available_ips)

def is_allocated_in_project(address, project_id):
    """Returns true if address is in specified project"""
    project_net = db.project_get_network(None, project_id)
    network = db.fixed_ip_get_network(None, address)
    instance = db.fixed_ip_get_instance(None, address)
    # instance exists until release
    return instance is not None and network['id'] == project_net['id']

def binpath(script):
    """Returns the absolute path to a script in bin"""
    return os.path.abspath(os.path.join(__file__, "../../../bin", script))

def lease_ip(private_ip):
    """Run add command on dhcpbridge"""
    network_ref = db.fixed_ip_get_network(None, private_ip)
    cmd = "%s add fake %s fake" % (binpath('nova-dhcpbridge'), private_ip)
    env = {'DNSMASQ_INTERFACE': network_ref['bridge'],
           'TESTING': '1',
           'FLAGFILE': FLAGS.dhcpbridge_flagfile}
    (out, err) = utils.execute(cmd, addl_env=env)
    logging.debug("ISSUE_IP: %s, %s ", out, err)

def release_ip(private_ip):
    """Run del command on dhcpbridge"""
    network_ref = db.fixed_ip_get_network(None, private_ip)
    cmd = "%s del fake %s fake" % (binpath('nova-dhcpbridge'), private_ip)
    env = {'DNSMASQ_INTERFACE': network_ref['bridge'],
           'TESTING': '1',
           'FLAGFILE': FLAGS.dhcpbridge_flagfile}
    (out, err) = utils.execute(cmd, addl_env=env)
    logging.debug("RELEASE_IP: %s, %s ", out, err)
<commit_msg>fix floating_ip to follow standard create pattern<commit_after># vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
"""
Unit Tests for network code
"""
import IPy
import os
import logging

from nova import db
from nova import exception
from nova import flags
from nova import test
from nova import utils
from nova.auth import manager

FLAGS = flags.FLAGS

class NetworkTestCase(test.TrialTestCase):
    """Test cases for network code"""
    def setUp(self):  # pylint: disable-msg=C0103
        super(NetworkTestCase, self).setUp()
        # NOTE(vish): if you change these flags, make sure to change the
        #             flags in the corresponding section in nova-dhcpbridge
        self.flags(connection_type='fake',
                   fake_storage=True,
                   fake_network=True,
                   auth_driver='nova.auth.ldapdriver.FakeLdapDriver',
                   network_size=16,
                   num_networks=5)
        logging.getLogger().setLevel(logging.DEBUG)
        self.manager = manager.AuthManager()
        self.user = self.manager.create_user('netuser', 'netuser', 'netuser')
        self.projects = []
        self.network = utils.import_object(FLAGS.network_manager)
        self.context = None
        for i in range(5):
            name = 'project%s' % i
            self.projects.append(self.manager.create_project(name,
                                                             'netuser',
                                                             name))
            # create the necessary network data for the project
            self.network.set_network_host(self.context, self.projects[i].id)
        instance_id = db.instance_create(None,
                                         {'mac_address': utils.generate_mac()})
        self.instance_id = instance_id
        instance_id = db.instance_create(None,
                                         {'mac_address': utils.generate_mac()})
        self.instance2_id = instance_id

    def tearDown(self):  # pylint: disable-msg=C0103
        super(NetworkTestCase, self).tearDown()
        # TODO(termie): this should really be instantiating clean datastores
        #               in between runs, one failure kills all the tests
        db.instance_destroy(None, self.instance_id)
        db.instance_destroy(None, self.instance2_id)
        for project in self.projects:
            self.manager.delete_project(project)
        self.manager.delete_user(self.user)

    def _create_address(self, project_num, instance_id=None):
        """Create an address in given project num"""
        net = db.project_get_network(None, self.projects[project_num].id)
        address = db.fixed_ip_allocate(None, net['id'])
        if instance_id is None:
            instance_id = self.instance_id
        db.fixed_ip_instance_associate(None, address, instance_id)
        return address

    def test_public_network_association(self):
        """Makes sure that we can allocaate a public ip"""
        # TODO(vish): better way of adding floating ips
        pubnet = IPy.IP(flags.FLAGS.public_range)
        address = str(pubnet[0])
        try:
            db.floating_ip_get_by_address(None, address)
        except exception.NotFound:
            db.floating_ip_create(None, {'address': address,
                                         'host': FLAGS.host})
        float_addr = self.network.allocate_floating_ip(self.context,
                                                       self.projects[0].id)
        fix_addr = self._create_address(0)
        self.assertEqual(float_addr, str(pubnet[0]))
        self.network.associate_floating_ip(self.context, float_addr, fix_addr)
        address = db.instance_get_floating_address(None, self.instance_id)
        self.assertEqual(address, float_addr)
        self.network.disassociate_floating_ip(self.context, float_addr)
        address = db.instance_get_floating_address(None, self.instance_id)
        self.assertEqual(address, None)
        self.network.deallocate_floating_ip(self.context, float_addr)
        db.fixed_ip_deallocate(None, fix_addr)

    def test_allocate_deallocate_fixed_ip(self):
        """Makes sure that we can allocate and deallocate a fixed ip"""
        address = self._create_address(0)
        self.assertTrue(is_allocated_in_project(address, self.projects[0].id))
        lease_ip(address)
        db.fixed_ip_deallocate(None, address)

        # Doesn't go away until it's dhcp released
        self.assertTrue(is_allocated_in_project(address, self.projects[0].id))

        release_ip(address)
        self.assertFalse(is_allocated_in_project(address, self.projects[0].id))

    def test_side_effects(self):
        """Ensures allocating and releasing has no side effects"""
        address = self._create_address(0)
        address2 = self._create_address(1, self.instance2_id)

        self.assertTrue(is_allocated_in_project(address, self.projects[0].id))
        self.assertTrue(is_allocated_in_project(address2, self.projects[1].id))
        self.assertFalse(is_allocated_in_project(address, self.projects[1].id))

        # Addresses are allocated before they're issued
        lease_ip(address)
        lease_ip(address2)

        db.fixed_ip_deallocate(None, address)
        release_ip(address)
        self.assertFalse(is_allocated_in_project(address, self.projects[0].id))

        # First address release shouldn't affect the second
        self.assertTrue(is_allocated_in_project(address2, self.projects[1].id))

        db.fixed_ip_deallocate(None, address2)
        release_ip(address2)
        self.assertFalse(is_allocated_in_project(address2,
                                                 self.projects[1].id))

    def test_subnet_edge(self):
        """Makes sure that private ips don't overlap"""
        first = self._create_address(0)
        lease_ip(first)
        for i in range(1, 5):
            address = self._create_address(i)
            address2 = self._create_address(i)
            address3 = self._create_address(i)
            lease_ip(address)
            lease_ip(address2)
            lease_ip(address3)
            self.assertFalse(is_allocated_in_project(address,
                                                     self.projects[0].id))
            self.assertFalse(is_allocated_in_project(address2,
                                                     self.projects[0].id))
            self.assertFalse(is_allocated_in_project(address3,
                                                     self.projects[0].id))
            db.fixed_ip_deallocate(None, address)
            db.fixed_ip_deallocate(None, address2)
            db.fixed_ip_deallocate(None, address3)
            release_ip(address)
            release_ip(address2)
            release_ip(address3)
        release_ip(first)
        db.fixed_ip_deallocate(None, first)

    def test_vpn_ip_and_port_looks_valid(self):
        """Ensure the vpn ip and port are reasonable"""
        self.assert_(self.projects[0].vpn_ip)
        self.assert_(self.projects[0].vpn_port >= FLAGS.vpn_start)
        self.assert_(self.projects[0].vpn_port <= FLAGS.vpn_start +
                                                  FLAGS.num_networks)

    def test_too_many_networks(self):
        """Ensure error is raised if we run out of networks"""
        projects = []
        networks_left = FLAGS.num_networks - db.network_count(None)
        for i in range(networks_left):
            project = self.manager.create_project('many%s' % i, self.user)
            projects.append(project)
        self.assertRaises(db.NoMoreNetworks,
                          self.manager.create_project,
                          'boom',
                          self.user)
        for project in projects:
            self.manager.delete_project(project)

    def test_ips_are_reused(self):
        """Makes sure that ip addresses that are deallocated get reused"""
        address = self._create_address(0)
        lease_ip(address)
        db.fixed_ip_deallocate(None, address)
        release_ip(address)

        address2 = self._create_address(0)
        self.assertEqual(address, address2)
        db.fixed_ip_deallocate(None, address2)

    def test_available_ips(self):
        """Make sure the number of available ips for the network is correct

        The number of available IP addresses depends on the test
        environment's setup.

        Network size is set in test fixture's setUp method.

        There are ips reserved at the bottom and top of the range.
        services (network, gateway, CloudPipe, broadcast)
        """
        network = db.project_get_network(None, self.projects[0].id)
        net_size = flags.FLAGS.network_size
        total_ips = (db.network_count_available_ips(None, network['id']) +
                     db.network_count_reserved_ips(None, network['id']) +
                     db.network_count_allocated_ips(None, network['id']))
        self.assertEqual(total_ips, net_size)

    def test_too_many_addresses(self):
        """Test for a NoMoreAddresses exception when all fixed ips are used.
        """
        network = db.project_get_network(None, self.projects[0].id)
        num_available_ips = db.network_count_available_ips(None,
                                                           network['id'])
        addresses = []
        for i in range(num_available_ips):
            address = self._create_address(0)
            addresses.append(address)
            lease_ip(address)

        self.assertEqual(db.network_count_available_ips(None,
                                                        network['id']), 0)
        self.assertRaises(db.NoMoreAddresses,
                          db.fixed_ip_allocate,
                          None,
                          network['id'])

        for i in range(len(addresses)):
            db.fixed_ip_deallocate(None, addresses[i])
            release_ip(addresses[i])
        self.assertEqual(db.network_count_available_ips(None,
                                                        network['id']),
                         num_available_ips)

def is_allocated_in_project(address, project_id):
    """Returns true if address is in specified project"""
    project_net = db.project_get_network(None, project_id)
    network = db.fixed_ip_get_network(None, address)
    instance = db.fixed_ip_get_instance(None, address)
    # instance exists until release
    return instance is not None and network['id'] == project_net['id']

def binpath(script):
    """Returns the absolute path to a script in bin"""
    return os.path.abspath(os.path.join(__file__, "../../../bin", script))

def lease_ip(private_ip):
    """Run add command on dhcpbridge"""
    network_ref = db.fixed_ip_get_network(None, private_ip)
    cmd = "%s add fake %s fake" % (binpath('nova-dhcpbridge'), private_ip)
    env = {'DNSMASQ_INTERFACE': network_ref['bridge'],
           'TESTING': '1',
           'FLAGFILE': FLAGS.dhcpbridge_flagfile}
    (out, err) = utils.execute(cmd, addl_env=env)
    logging.debug("ISSUE_IP: %s, %s ", out, err)

def release_ip(private_ip):
    """Run del command on dhcpbridge"""
    network_ref = db.fixed_ip_get_network(None, private_ip)
    cmd = "%s del fake %s fake" % (binpath('nova-dhcpbridge'), private_ip)
    env = {'DNSMASQ_INTERFACE': network_ref['bridge'],
           'TESTING': '1',
           'FLAGFILE': FLAGS.dhcpbridge_flagfile}
    (out, err) = utils.execute(cmd, addl_env=env)
    logging.debug("RELEASE_IP: %s, %s ", out, err)
<|endoftext|>


<commit_before># Copyright (c) 2015 HyperHQ Inc.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

import six
import sys
import json

import requests
import requests.exceptions

from oslo_config import cfg

from novahyper.virt.hyper import api
from novahyper.virt.hyper import errors
from novahyper.virt.hyper import utils
from novahyper.virt.hyper.unixconn import unixconn

CONF = cfg.CONF
DEFAULT_VERSION="1"
TIMEOUT=30

class HyperHTTPClient(
        requests.Session,
        api.HyperClient):

    def __init__(self, url='unix://var/run/hyper.sock'):
        super(HyperHTTPClient, self).__init__()
        self.base_url = url
        self._version = DEFAULT_VERSION
        self.timeout = TIMEOUT

        base_url = utils.parse_host(url, sys.platform)
        if base_url.startswith('http+unix://'):
            self._custom_adapter = unixconn.UnixAdapter(base_url, self.timeout)
            self.mount('http+docker://', self._custom_adapter)
            self.base_url = 'http+docker://localunixsocket'
        else:
            self.base_url = url

    def set_version(self, version):
        self._version = version

    def _raise_for_status(self, response, explanation=None):
        """Raises stored :class:`APIError`, if one occurred."""
        try:
            response.raise_for_status()
        except requests.exceptions.HTTPError as e:
            if e.response.status_code == 404:
                raise errors.NotFound(e, response, explanation=explanation)
            raise errors.APIError(e, response, explanation=explanation)

    def _result(self, response, json=False, binary=False):
        assert not (json and binary)
        self._raise_for_status(response)

        if json:
            return response.json()
        if binary:
            return response.content
        return response.text

    def _set_request_timeout(self, kwargs):
        """Prepare the kwargs for an HTTP request by inserting the timeout
        parameter, if not already present."""
        kwargs.setdefault('timeout', self.timeout)
        return kwargs

    def _post(self, url, **kwargs):
        return self.post(url, **self._set_request_timeout(kwargs))

    def _get(self, url, **kwargs):
        return self.get(url, **self._set_request_timeout(kwargs))

    def _put(self, url, **kwargs):
        return self.put(url, **self._set_request_timeout(kwargs))

    def _delete(self, url, **kwargs):
        return self.delete(url, **self._set_request_timeout(kwargs))

    def _url(self, pathfmt, *args, **kwargs):
        for arg in args:
            if not isinstance(arg, six.string_types):
                raise ValueError(
                    'Expected a string but found {0} ({1}) '
                    'instead'.format(arg, type(arg))
                )

        args = map(six.moves.urllib.parse.quote_plus, args)

        if kwargs.get('versioned_api', True):
            return '{0}/v{1}{2}'.format(
                self.base_url, self._version, pathfmt.format(*args)
            )
        else:
            return '{0}{1}'.format(self.base_url, pathfmt.format(*args))
<commit_msg>change api unix uri<commit_after># Copyright (c) 2015 HyperHQ Inc.
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

import six
import sys
import json

import requests
import requests.exceptions

from oslo_config import cfg

from novahyper.virt.hyper import api
from novahyper.virt.hyper import errors
from novahyper.virt.hyper import utils
from novahyper.virt.hyper.unixconn import unixconn

CONF = cfg.CONF
DEFAULT_VERSION="1"
TIMEOUT=30

class HyperHTTPClient(
        requests.Session,
        api.HyperClient):

    def __init__(self, url='unix://var/run/hyper.sock'):
        super(HyperHTTPClient, self).__init__()
        self.base_url = url
        self._version = DEFAULT_VERSION
        self.timeout = TIMEOUT

        base_url = utils.parse_host(url, sys.platform)
        if base_url.startswith('http+unix://'):
            self._custom_adapter = unixconn.UnixAdapter(base_url, self.timeout)
            self.mount('http+hyper://', self._custom_adapter)
            self.base_url = 'http+hyper://localunixsocket'
        else:
            self.base_url = url

    def set_version(self, version):
        self._version = version

    def _raise_for_status(self, response, explanation=None):
        """Raises stored :class:`APIError`, if one occurred."""
        try:
            response.raise_for_status()
        except requests.exceptions.HTTPError as e:
            if e.response.status_code == 404:
                raise errors.NotFound(e, response, explanation=explanation)
            raise errors.APIError(e, response, explanation=explanation)

    def _result(self, response, json=False, binary=False):
        assert not (json and binary)
        self._raise_for_status(response)

        if json:
            return response.json()
        if binary:
            return response.content
        return response.text

    def _set_request_timeout(self, kwargs):
        """Prepare the kwargs for an HTTP request by inserting the timeout
        parameter, if not already present."""
        kwargs.setdefault('timeout', self.timeout)
        return kwargs

    def _post(self, url, **kwargs):
        return self.post(url, **self._set_request_timeout(kwargs))

    def _get(self, url, **kwargs):
        return self.get(url, **self._set_request_timeout(kwargs))

    def _put(self, url, **kwargs):
        return self.put(url, **self._set_request_timeout(kwargs))

    def _delete(self, url, **kwargs):
        return self.delete(url, **self._set_request_timeout(kwargs))

    def _url(self, pathfmt, *args, **kwargs):
        for arg in args:
            if not isinstance(arg, six.string_types):
                raise ValueError(
                    'Expected a string but found {0} ({1}) '
                    'instead'.format(arg, type(arg))
                )

        args = map(six.moves.urllib.parse.quote_plus, args)

        if kwargs.get('versioned_api', True):
            return '{0}/v{1}{2}'.format(
                self.base_url, self._version, pathfmt.format(*args)
            )
        else:
            return '{0}{1}'.format(self.base_url, pathfmt.format(*args))
<|endoftext|>