<commit_before>package gocipher

/*
 * https://en.wikipedia.org/wiki/Morse_code
 * https://en.wikipedia.org/wiki/Morse_code_for_non-Latin_alphabets
 * https://en.wikipedia.org/wiki/Russian_Morse_code
 * https://fa.wikipedia.org/wiki/%DA%A9%D8%AF_%D9%85%D9%88%D8%B1%D8%B3
 * https://en.wikipedia.org/wiki/Wabun_code
 */

type MorseAlphabet uint

const (
	// MorseInternational is the International Morse code Remommendation ITU-R M.1677-1
	// http://www.itu.int/rec/R-REC-M.1677-1-200910-I/
	MorseInternational MorseAlphabet = iota
	MorseSymbols
	MorseProsigns
	MorseNonEnglish
	MorseGreek
	MorseRussian
	MorseBulgarian
	MorseHebrew
	MorseArabic
	MorsePersian
)

var morseAlphabets = [][][]string{
	MorseInternational: morseInternational,
	MorseSymbols:       morseSymbols,
	MorseProsigns:      morseProsigns,
	MorseNonEnglish:    morseNonEnglish,
	MorseGreek:         morseGreek,
	MorseRussian:       morseRussian,
	MorseBulgarian:     morseBulgarian,
	MorseHebrew:        morseHebrew,
	MorseArabic:        morseArabic,
	MorsePersian:       morsePersian,
}

var morseInternational = [][]string{
	// Letters
	{"A", ".-"},
	{"B", "-..."},
	{"C", "-.-."},
	{"D", "-.."},
	{"E", "."},
	{"É", "..-.."}, // accented
	{"F", "..-."},
	{"G", "--."},
	{"H", "...."},
	{"I", ".."},
	{"J", ".---"},
	{"K", "-.-"},
	{"L", ".-.."},
	{"M", "--"},
	{"N", "-."},
	{"O", "---"},
	{"P", ".--."},
	{"Q", "--.-"},
	{"R", ".-."},
	{"S", "..."},
	{"T", "-"},
	{"U", "..-"},
	{"V", "...-"},
	{"W", ".--"},
	{"X", "-..-"},
	{"Y", "-.--"},
	{"Z", "--.."},
	// Figures
	{"1", ".----"},
	{"2", "..---"},
	{"3", "...--"},
	{"4", "....-"},
	{"5", "....."},
	{"6", "-...."},
	{"7", "--..."},
	{"8", "---.."},
	{"9", "----."},
	{"0", "-----"},
	// Punctuation marks and miscellaneous signs
	{".", ".-.-.-"},                // Full stop (period)
	{",", "--..--"},                // Comma
	{":", "---..."},                // Colon or division sign
	{"?", "..--.."},                // Question mark (note of interrogation or request for repetition of a transmission not understood)
	{"'", ".----."},                // Apostrophe ’
	{"-", "-....-"},                // Hyphen or dash or subtraction sign –
	{"/", "-..-."},                 // Fraction bar or division sign
	{"(", "-.--."},                 // Left-hand bracket (parenthesis)
	{")", "-.--.-"},                // Right-hand bracket (parenthesis)
	{"\"", ".-..-."},               // Inverted commas (quotation marks) (before and after the words) “”
	{"=", "-...-"},                 // Double hyphen
	{"<Understood>", "...-."},      // Understood
	{"<Error>", "........"},        // Error (eight dots)
	{"+", ".-.-."},                 // Cross or addition sign
	{"K", "-.-"},                   // Invitation to transmit
	{"<Wait>", ".-..."},            // Wait
	{"<End of work>", "...-.-"},    // End of work
	{"<Starting signal>", "-.-.-"}, // Starting signal (to precede every transmission)
	{"×", "-..-"},                  // Multiplication sign
	{"@", ".--.-."},                // Commercial at
}

var morseSymbols = [][]string{
	{"!", "-.-.--"}, // <KW>
	{"&", ".-..."},  // <AS>, Not in ITU-R recommendation
	{";", "-.-.-."},
	{"+", ".-.-."},   // <AR>
	{"_", "..--.-"},  // Not in ITU-R recommendation
	{"$", "...-..-"}, // <SX>, Not in ITU-R recommendation
	{"@", ".--.-."},  // <AC>
}

// https://en.wikipedia.org/wiki/Prosigns_for_Morse_code
// http://www.kent-engineers.com/prosigns.htm
var morseProsigns = [][]string{
	{"<AA>", ".-.-"},                   // New Line (space down one line)
	{"<AR>", ".-.-."},                  // New Page (space down several lines); End of transmission
	{"<AS>", ".-..."},                  // Wait
	{"<BK>", "-...-.-"},                // Break; Invite receiving station to transmit
	{"<BT>", "-...-"},                  // New Paragraph (space down two lines); Pause
	{"<CL>", "-.-..-.."},               // Closing
	{"<CQ>", "-.-.--.-"},               // Calling any amateur radio station
	{"<CT>", "<KA>", "-.-.-"},          // Attention
	{"<HH>", "<EEEEEEEE>", "........"}, // Error
	{"<K>", "-.-"},                     // Invitation for any station to transmit
	{"<KN>", "-.--."},                  // Invitation for named station to transmit
	{"<NJ>", "<DO>", "-..---"},         // Shift to Wabun code
	{"<R>", ".-."},                     // All received OK
	{"<SK>", "<VA>", "...-.-"},         // End of contact
	{"<SN>", "<VE>", "...-."},          // Understood
	{"<SOS>", "...---..."},             // International distress signal
}

var morseNonEnglish = [][]string{
	{"À", "Å", ".--.-"},
	{"Ä", "Æ", "Ą", ".-.-"},
	{"Ć", "Ĉ", "Ç", "-.-.."},
	{"CH", "Ĥ", "Š", "----"},
	{"Đ", "É", "Ę", "..-.."},
	{"Ð", "..--."},
	{"È", "Ł", ".-..-"},
	{"Ĝ", "--.-."},
	{"Ĵ", ".---."},
	{"Ń", "Ñ", "--.--"},
	{"Ó", "Ö", "Ø", "---."},
	{"Ś", "...-..."},
	{"Ŝ", "...-."}, // <SN> <VE>
	{"Þ", ".--.."},
	{"Ü", "Ŭ", "..--"},
	{"Ź", "--..-."},
	{"Ż", "--..-"},
}

var morseGreek = [][]string{
	// Letters
	{"Α", ".-"},
	{"Β", "-..."},
	{"Γ", "--."},
	{"Δ", "-.."},
	{"Ε", "."},
	{"Ζ", "--.."},
	{"Η", "...."},
	{"Θ", "-.-."},
	{"Ι", ".."},
	{"Κ", "-.-"},
	{"Λ", ".-.."},
	{"Μ", "--"},
	{"Ν", "-."},
	{"Ξ", "-..-"},
	{"Ο", "---"},
	{"Π", ".--."},
	{"Ρ", ".-."},
	{"Σ", "..."},
	{"Τ", "-"},
	{"Υ", "-.--"},
	{"Φ", "..-."},
	{"Χ", "----"},
	{"Ψ", "--.-"},
	{"Ω", ".--"},
	// Diphthongs
	// The Greek diphthongs are specified in old Greek Morse-code tables
	// but they are never used in actual communication,
	// the two vowels being sent separately.
	{"HY", "...-"},
	{"OI", "---.."},
	{"AY", "..--"},
	{"YI", ".---"},
	{"EI", "..."},
	{"EY", "---."},
	{"OY", "..-"},
	{"AI", ".-.-"},
}

var morseCyrillicPartA = [][]string{
	{"A", ".-"},
	{"Б", "-..."},
	{"В", ".--"},
	{"Г", "--."},
	{"Д", "-.."},
	{"Е", "."},
	{"Ж", "...-"},
	{"З", "--.."},
	{"И", ".."},
	{"Й", ".---"},
	{"К", "-.-"},
	{"Л", ".-.."},
	{"М", "--"},
	{"H", "-."},
	{"О", "---"},
	{"П", ".--."},
	{"P", ".-."},
	{"С", "..."},
	{"Т", "-"},
	{"У", "..-"},
	{"Ф", "..-."},
	{"Х", "...."},
	{"Ц", "-.-."},
	{"Ч", "---."},
	{"Ш", "----"},
	{"Щ", "--.-"}}
var morseRussianPart = [][]string{
	{"Ъ", "--.--"},
	{"Ы", "-.--"},
	{"Ь", "-..-"}}
var morseBulgarianPart = [][]string{
	{"Ъ", "-..-"},
	{"Ь", "-.--"}}
var morseCyrillicPartB = [][]string{
	{"Э", "..-.."},
	{"Ю", "..--"},
	{"Я", ".-.-"},
	{"1", ".----"},
	{"2", "..---"},
	{"3", "...--"},
	{"4", "....-"},
	{"5", "....."},
	{"6", "-...."},
	{"7", "--..."},
	{"8", "---.."},
	{"9", "----."},
	{"0", "-----"},
	{".", "......"},
	{",", ".-.-.-"},
	{":", "---..."},
	{";", "-.-.-"},
	{"(", "-.--.-"},
	{")", "-.--.-"},
	{"'", ".----."},
	{"\"", ".-..-."},
	{"-", "-....-"},
	{"/", "-..-."},
	{"?", "..--.."},
	{"!", "--..--"},
	{"Hyphen", "-...-"}, // Hyphen is above, so...
	{"Error/redo", "........"},
	{"@", ".--.-."},
}

var morseRussian = append(append(morseCyrillicPartA, morseRussianPart...), morseCyrillicPartB...)
var morseBulgarian = append(append(morseCyrillicPartA, morseBulgarianPart...), morseCyrillicPartB...)

var morseHebrew = [][]string{
	{"א", ".-"},
	{"ב", "-..."},
	{"ג", "--."},
	{"ד", "-.."},
	{"ה", "---"},
	{"ו", "."},
	{"ז", "--.."},
	{"ח", "...."},
	{"ט", "..-"},
	{"י", ".."},
	{"כ", "-.-"},
	{"ל", ".-.."},
	{"מ", "--"},
	{"נ", "-."},
	{"ס", "-.-."},
	{"ע", ".---"},
	{"פ", ".--."},
	{"צ", ".--"},
	{"ק", "--.-"},
	{"ר", ".-."},
	{"ש", "..."},
	{"ת", "-"},
}

var morseArabic = [][]string{
	{"ا", ".-"},
	{"ب", "-..."},
	{"ت", "-"},
	{"ث", "-.-."},
	{"ج", ".---"},
	{"ح", "...."},
	{"خ", "---"},
	{"د", "-.."},
	{"ذ", "--.."},
	{"ر", ".-."},
	{"ز", "---."},
	{"س", "..."},
	{"ش", "----"},
	{"ص", "-..-"},
	{"ض", "...-"},
	{"ط", "..-"},
	{"ظ", "-.--"},
	{"ع", ".-.-"},
	{"غ", "--."},
	{"ف", "..-."},
	{"ق", "--.-"},
	{"ك", "-.-"},
	{"ل", ".-.."},
	{"م", "--"},
	{"ن", "-."},
	{"ه", "..-.."},
	{"و", ".--"},
	{"ي", ".."},
	{"ﺀ", "."},
}

var morsePersian = [][]string{
	{"ا", ".-"},    // A
	{"ب", "-..."},  // B
	{"پ", ".--."},  // P
	{"ت", "-"},     // T
	{"ث", "-.-."},  // C
	{"ج", ".---"},  // J
	{"چ", "---."},  // Ö
	{"ح", "...."},  // H
	{"خ", "-..-"},  // X
	{"د", "-.."},   // D
	{"ذ", "...-"},  // V
	{"ر", ".-."},   // R
	{"ز", "--.."},  // Z
	{"ژ", "--."},   // G
	{"س", "..."},   // S
	{"ش", "----"},  // Š
	{"ص", ".-.-"},  // Ä
	{"ض", "..-.."}, // É
	{"ط", "..-"},   // U
	{"ظ", "-.--"},  // Y
	{"ع", "---"},   // O
	{"غ", "..--"},  // Ü
	{"ف", "..-."},  // F
	{"ق", "---..."},
	{"ک", "-.-"},  // K
	{"گ", "--.-"}, // Q
	{"ل", ".-.."}, // L
	{"م", "--"},   // M
	{"ن", "-."},   // N
	{"و", ".--"},  // W
	{"ه", "."},    // E
	{"ی", ".."},   // I

	{"۰", "-----"}, // 0
	{"۱", ".----"}, // 1
	{"۲", "..---"}, // 2
	{"۳", "...--"}, // 3
	{"۴", "....-"}, // 4
	{"۵", "....."}, // 5
	{"۶", "-...."}, // 6
	{"۷", "--..."}, // 7
	{"۸", "---.."}, // 8
	{"۹", "----."}, // 9

	{".", "......"},
	{"،", ".-.-.-"}, // translates to ,
	{"؛", "-.-.-"},  // translates to ;
	{":", "---..."},
	{"؟", "..--.."}, // translates to ?
	{"!", "--..--"},
	{"\n", ".-.-."},
	{"-", "-....-"},
	{"/", "------"},
	{"ـ", "..--.-"}, // translates to _
	{"(", "-.--.-"},
	{")", "-.--.-"},
}

var wabun = [][]string{}
<commit_msg>Add abbreviated numbers and alternate chars for ITU-R Intl Morse punctuation<commit_after>package gocipher

/*
 * https://en.wikipedia.org/wiki/Morse_code
 * https://en.wikipedia.org/wiki/Morse_code_for_non-Latin_alphabets
 * https://en.wikipedia.org/wiki/Russian_Morse_code
 * https://fa.wikipedia.org/wiki/%DA%A9%D8%AF_%D9%85%D9%88%D8%B1%D8%B3
 * https://en.wikipedia.org/wiki/Wabun_code
 */

type MorseAlphabet uint

const (
	// MorseInternational is the International Morse code Remommendation ITU-R M.1677-1
	// http://www.itu.int/rec/R-REC-M.1677-1-200910-I/
	MorseInternational MorseAlphabet = iota
	MorseSymbols
	MorseProsigns
	MorseAbbrNumbers
	MorseNonEnglish
	MorseGreek
	MorseRussian
	MorseBulgarian
	MorseHebrew
	MorseArabic
	MorsePersian
)

var morseAlphabets = [][][]string{
	MorseInternational: morseInternational,
	MorseSymbols:       morseSymbols,
	MorseProsigns:      morseProsigns,
	MorseAbbrNumbers:   morseAbbrNumbers,
	MorseNonEnglish:    morseNonEnglish,
	MorseGreek:         morseGreek,
	MorseRussian:       morseRussian,
	MorseBulgarian:     morseBulgarian,
	MorseHebrew:        morseHebrew,
	MorseArabic:        morseArabic,
	MorsePersian:       morsePersian,
}

var morseInternational = [][]string{
	// Letters
	{"A", ".-"},
	{"B", "-..."},
	{"C", "-.-."},
	{"D", "-.."},
	{"E", "."},
	{"É", "..-.."}, // Accented
	{"F", "..-."},
	{"G", "--."},
	{"H", "...."},
	{"I", ".."},
	{"J", ".---"},
	{"K", "-.-"},
	{"L", ".-.."},
	{"M", "--"},
	{"N", "-."},
	{"O", "---"},
	{"P", ".--."},
	{"Q", "--.-"},
	{"R", ".-."},
	{"S", "..."},
	{"T", "-"},
	{"U", "..-"},
	{"V", "...-"},
	{"W", ".--"},
	{"X", "-..-"},
	{"Y", "-.--"},
	{"Z", "--.."},
	// Figures
	{"1", ".----"},
	{"2", "..---"},
	{"3", "...--"},
	{"4", "....-"},
	{"5", "....."},
	{"6", "-...."},
	{"7", "--..."},
	{"8", "---.."},
	{"9", "----."},
	{"0", "-----"},
	// Punctuation marks and miscellaneous signs
	{".", ".-.-.-"},                    // Full stop (period)
	{",", "--..--"},                    // Comma
	{":", "---..."},                    // Colon or division sign
	{"?", "..--.."},                    // Question mark (note of interrogation or request for repetition of a transmission not understood)
	{"'", "’", ".----."},               // Apostrophe
	{"-", "–", "-....-"},               // Hyphen or dash or subtraction sign
	{"/", "-..-."},                     // Fraction bar or division sign
	{"(", "-.--."},                     // Left-hand bracket (parenthesis)
	{")", "-.--.-"},                    // Right-hand bracket (parenthesis)
	{"\"", "“", "”", ".-..-."},         // Inverted commas (quotation marks) (before and after the words)
	{"=", "-...-"},                     // Double hyphen
	{"<SN>", "<VE>", "...-."},          // Understood
	{"<HH>", "<EEEEEEEE>", "........"}, // Error (eight dots)
	{"+", ".-.-."},                     // Cross or addition sign (<AR> digraph)
	{"<K>", "-.-"},                     // Invitation to transmit
	{"<AS>", ".-..."},                  // Wait
	{"<SK>", "<VA>", "...-.-"},         // End of work
	{"<CT>", "<KA>", "-.-.-"},          // Starting signal (to precede every transmission)
	{"×", "-..-"},                      // Multiplication sign
	{"@", ".--.-."},                    // Commercial at (<AC> digraph)
}

var morseSymbols = [][]string{
	{"!", "-.-.--"}, // <KW> digraph, Not in ITU-R recommendation
	{"&", ".-..."},  // <AS> digraph, Not in ITU-R recommendation
	{";", "-.-.-."},
	{"_", "..--.-"},  // Not in ITU-R recommendation
	{"$", "...-..-"}, // <SX>, Not in ITU-R recommendation
}

// https://en.wikipedia.org/wiki/Prosigns_for_Morse_code
// http://www.kent-engineers.com/prosigns.htm
var morseProsigns = [][]string{
	{"<AA>", ".-.-"},                   // New Line (space down one line)
	{"<AR>", ".-.-."},                  // New Page (space down several lines); End of transmission
	{"<AS>", ".-..."},                  // Wait
	{"<BK>", "-...-.-"},                // Break; Invite receiving station to transmit
	{"<BT>", "-...-"},                  // New Paragraph (space down two lines); Pause
	{"<CL>", "-.-..-.."},               // Closing
	{"<CQ>", "-.-.--.-"},               // Calling any amateur radio station
	{"<CT>", "<KA>", "-.-.-"},          // Attention
	{"<HH>", "<EEEEEEEE>", "........"}, // Error
	{"<K>", "-.-"},                     // Invitation for any station to transmit
	{"<KN>", "-.--."},                  // Invitation for named station to transmit
	{"<NJ>", "<DO>", "-..---"},         // Shift to Wabun code
	{"<R>", ".-."},                     // All received OK
	{"<SK>", "<VA>", "...-.-"},         // End of contact
	{"<SN>", "<VE>", "...-."},          // Understood
	{"<SOS>", "...---..."},             // International distress signal
}

// Conflicts with ABDGNSTUVW
// http://www.kent-engineers.com/thecode.htm
var morseAbbrNumbers = [][]string{
	{"1", ".-"},   // Conflicts with A
	{"2", "..-"},  // Conflicts with U
	{"3", ".--"},  // Conflicts with W
	{"4", "...-"}, // Conflicts with V
	{"5", "..."},  // Conflicts with S
	{"6", "-..."}, // Conflicts with B
	{"7", "--."},  // Conflicts with G
	{"8", "-.."},  // Conflicts with D
	{"9", "-."},   // Conflicts with N
	{"0", "-"},    // Conflicts with T
}

var morseNonEnglish = [][]string{
	{"À", "Å", ".--.-"},
	{"Ä", "Æ", "Ą", ".-.-"},
	{"Ć", "Ĉ", "Ç", "-.-.."},
	{"CH", "Ĥ", "Š", "----"},
	{"Đ", "É", "Ę", "..-.."},
	{"Ð", "..--."},
	{"È", "Ł", ".-..-"},
	{"Ĝ", "--.-."},
	{"Ĵ", ".---."},
	{"Ń", "Ñ", "--.--"},
	{"Ó", "Ö", "Ø", "---."},
	{"Ś", "...-..."},
	{"Ŝ", "...-."}, // <SN> <VE>
	{"Þ", ".--.."},
	{"Ü", "Ŭ", "..--"},
	{"Ź", "--..-."},
	{"Ż", "--..-"},
}

var morseGreek = [][]string{
	// Letters
	{"Α", ".-"},
	{"Β", "-..."},
	{"Γ", "--."},
	{"Δ", "-.."},
	{"Ε", "."},
	{"Ζ", "--.."},
	{"Η", "...."},
	{"Θ", "-.-."},
	{"Ι", ".."},
	{"Κ", "-.-"},
	{"Λ", ".-.."},
	{"Μ", "--"},
	{"Ν", "-."},
	{"Ξ", "-..-"},
	{"Ο", "---"},
	{"Π", ".--."},
	{"Ρ", ".-."},
	{"Σ", "..."},
	{"Τ", "-"},
	{"Υ", "-.--"},
	{"Φ", "..-."},
	{"Χ", "----"},
	{"Ψ", "--.-"},
	{"Ω", ".--"},
	// Diphthongs
	// The Greek diphthongs are specified in old Greek Morse-code tables
	// but they are never used in actual communication,
	// the two vowels being sent separately.
	{"HY", "...-"},
	{"OI", "---.."},
	{"AY", "..--"},
	{"YI", ".---"},
	{"EI", "..."},
	{"EY", "---."},
	{"OY", "..-"},
	{"AI", ".-.-"},
}

var morseCyrillicPartA = [][]string{
	{"A", ".-"},
	{"Б", "-..."},
	{"В", ".--"},
	{"Г", "--."},
	{"Д", "-.."},
	{"Е", "."},
	{"Ж", "...-"},
	{"З", "--.."},
	{"И", ".."},
	{"Й", ".---"},
	{"К", "-.-"},
	{"Л", ".-.."},
	{"М", "--"},
	{"H", "-."},
	{"О", "---"},
	{"П", ".--."},
	{"P", ".-."},
	{"С", "..."},
	{"Т", "-"},
	{"У", "..-"},
	{"Ф", "..-."},
	{"Х", "...."},
	{"Ц", "-.-."},
	{"Ч", "---."},
	{"Ш", "----"},
	{"Щ", "--.-"}}
var morseRussianPart = [][]string{
	{"Ъ", "--.--"},
	{"Ы", "-.--"},
	{"Ь", "-..-"}}
var morseBulgarianPart = [][]string{
	{"Ъ", "-..-"},
	{"Ь", "-.--"}}
var morseCyrillicPartB = [][]string{
	{"Э", "..-.."},
	{"Ю", "..--"},
	{"Я", ".-.-"},
	{"1", ".----"},
	{"2", "..---"},
	{"3", "...--"},
	{"4", "....-"},
	{"5", "....."},
	{"6", "-...."},
	{"7", "--..."},
	{"8", "---.."},
	{"9", "----."},
	{"0", "-----"},
	{".", "......"},
	{",", ".-.-.-"},
	{":", "---..."},
	{";", "-.-.-"},
	{"(", "-.--.-"},
	{")", "-.--.-"},
	{"'", ".----."},
	{"\"", ".-..-."},
	{"-", "-....-"},
	{"/", "-..-."},
	{"?", "..--.."},
	{"!", "--..--"},
	{"Hyphen", "-...-"}, // Hyphen is above, so...
	{"Error/redo", "........"},
	{"@", ".--.-."},
}

var morseRussian = append(append(morseCyrillicPartA, morseRussianPart...), morseCyrillicPartB...)
var morseBulgarian = append(append(morseCyrillicPartA, morseBulgarianPart...), morseCyrillicPartB...)

var morseHebrew = [][]string{
	{"א", ".-"},
	{"ב", "-..."},
	{"ג", "--."},
	{"ד", "-.."},
	{"ה", "---"},
	{"ו", "."},
	{"ז", "--.."},
	{"ח", "...."},
	{"ט", "..-"},
	{"י", ".."},
	{"כ", "-.-"},
	{"ל", ".-.."},
	{"מ", "--"},
	{"נ", "-."},
	{"ס", "-.-."},
	{"ע", ".---"},
	{"פ", ".--."},
	{"צ", ".--"},
	{"ק", "--.-"},
	{"ר", ".-."},
	{"ש", "..."},
	{"ת", "-"},
}

var morseArabic = [][]string{
	{"ا", ".-"},
	{"ب", "-..."},
	{"ت", "-"},
	{"ث", "-.-."},
	{"ج", ".---"},
	{"ح", "...."},
	{"خ", "---"},
	{"د", "-.."},
	{"ذ", "--.."},
	{"ر", ".-."},
	{"ز", "---."},
	{"س", "..."},
	{"ش", "----"},
	{"ص", "-..-"},
	{"ض", "...-"},
	{"ط", "..-"},
	{"ظ", "-.--"},
	{"ع", ".-.-"},
	{"غ", "--."},
	{"ف", "..-."},
	{"ق", "--.-"},
	{"ك", "-.-"},
	{"ل", ".-.."},
	{"م", "--"},
	{"ن", "-."},
	{"ه", "..-.."},
	{"و", ".--"},
	{"ي", ".."},
	{"ﺀ", "."},
}

var morsePersian = [][]string{
	{"ا", ".-"},    // A
	{"ب", "-..."},  // B
	{"پ", ".--."},  // P
	{"ت", "-"},     // T
	{"ث", "-.-."},  // C
	{"ج", ".---"},  // J
	{"چ", "---."},  // Ö
	{"ح", "...."},  // H
	{"خ", "-..-"},  // X
	{"د", "-.."},   // D
	{"ذ", "...-"},  // V
	{"ر", ".-."},   // R
	{"ز", "--.."},  // Z
	{"ژ", "--."},   // G
	{"س", "..."},   // S
	{"ش", "----"},  // Š
	{"ص", ".-.-"},  // Ä
	{"ض", "..-.."}, // É
	{"ط", "..-"},   // U
	{"ظ", "-.--"},  // Y
	{"ع", "---"},   // O
	{"غ", "..--"},  // Ü
	{"ف", "..-."},  // F
	{"ق", "---..."},
	{"ک", "-.-"},  // K
	{"گ", "--.-"}, // Q
	{"ل", ".-.."}, // L
	{"م", "--"},   // M
	{"ن", "-."},   // N
	{"و", ".--"},  // W
	{"ه", "."},    // E
	{"ی", ".."},   // I

	{"۰", "-----"}, // 0
	{"۱", ".----"}, // 1
	{"۲", "..---"}, // 2
	{"۳", "...--"}, // 3
	{"۴", "....-"}, // 4
	{"۵", "....."}, // 5
	{"۶", "-...."}, // 6
	{"۷", "--..."}, // 7
	{"۸", "---.."}, // 8
	{"۹", "----."}, // 9

	{".", "......"},
	{"،", ".-.-.-"}, // translates to ,
	{"؛", "-.-.-"},  // translates to ;
	{":", "---..."},
	{"؟", "..--.."}, // translates to ?
	{"!", "--..--"},
	{"\n", ".-.-."},
	{"-", "-....-"},
	{"/", "------"},
	{"ـ", "..--.-"}, // translates to _
	{"(", "-.--.-"},
	{")", "-.--.-"},
}

var wabun = [][]string{}
<|endoftext|>


<commit_before>package plugin

import (
	"strings"
	"testing"

	. "github.com/smartystreets/goconvey/convey"
)

func TestMetric(t *testing.T) {
	Convey("error on invalid pulse content type", t, func() {
		m := []PluginMetricType{
			*NewPluginMetricType([]string{"foo", "bar"}, 1),
			*NewPluginMetricType([]string{"foo", "baz"}, 2),
		}
		a, c, e := MarshallPluginMetricTypes("foo", m)
		So(e, ShouldNotBeNil)
		So(e.Error(), ShouldEqual, "invlaid pulse content type: foo")
		So(a, ShouldBeNil)
		So(c, ShouldEqual, "")
	})

	Convey("error on empty metric slice", t, func() {
		m := []PluginMetricType{}
		a, c, e := MarshallPluginMetricTypes("foo", m)
		So(e, ShouldNotBeNil)
		So(e.Error(), ShouldEqual, "attempt to marshall empty slice of metrics: foo")
		So(a, ShouldBeNil)
		So(c, ShouldEqual, "")
	})

	Convey("marshall using pulse.* default to pulse.gob", t, func() {
		m := []PluginMetricType{
			*NewPluginMetricType([]string{"foo", "bar"}, 1),
			*NewPluginMetricType([]string{"foo", "baz"}, "2"),
		}
		a, c, e := MarshallPluginMetricTypes("pulse.*", m)
		So(e, ShouldBeNil)
		So(a, ShouldNotBeNil)
		So(len(a), ShouldBeGreaterThan, 0)
		So(c, ShouldEqual, "pulse.gob")

		Convey("unmarshal pulse.gob", func() {
			m, e = UnmarshallPluginMetricTypes("pulse.gob", a)
			So(e, ShouldBeNil)
			So(strings.Join(m[0].Namespace(), "/"), ShouldResemble, "foo/bar")
			So(m[0].Data(), ShouldResemble, 1)
			So(strings.Join(m[1].Namespace(), "/"), ShouldResemble, "foo/baz")
			So(m[1].Data(), ShouldResemble, "2")
		})

	})

	Convey("marshall using pulse.gob", t, func() {
		m := []PluginMetricType{
			*NewPluginMetricType([]string{"foo", "bar"}, 1),
			*NewPluginMetricType([]string{"foo", "baz"}, "2"),
		}
		a, c, e := MarshallPluginMetricTypes("pulse.gob", m)
		So(e, ShouldBeNil)
		So(a, ShouldNotBeNil)
		So(len(a), ShouldBeGreaterThan, 0)
		So(c, ShouldEqual, "pulse.gob")

		Convey("unmarshal pulse.gob", func() {
			m, e = UnmarshallPluginMetricTypes("pulse.gob", a)
			So(e, ShouldBeNil)
			So(strings.Join(m[0].Namespace(), "/"), ShouldResemble, "foo/bar")
			So(m[0].Data(), ShouldResemble, 1)
			So(strings.Join(m[1].Namespace(), "/"), ShouldResemble, "foo/baz")
			So(m[1].Data(), ShouldResemble, "2")
		})

		Convey("error on bad corrupt data", func() {
			a = []byte{1, 0, 1, 1, 1, 1, 1, 0, 0, 1}
			m, e = UnmarshallPluginMetricTypes("pulse.gob", a)
			So(e, ShouldNotBeNil)
			So(e.Error(), ShouldResemble, "gob: decoding into local type *[]plugin.PluginMetricType, received remote type unknown type")
		})
	})

	Convey("marshall using pulse.json", t, func() {
		m := []PluginMetricType{
			*NewPluginMetricType([]string{"foo", "bar"}, 1),
			*NewPluginMetricType([]string{"foo", "baz"}, "2"),
		}
		a, c, e := MarshallPluginMetricTypes("pulse.json", m)
		So(e, ShouldBeNil)
		So(a, ShouldNotBeNil)
		So(len(a), ShouldBeGreaterThan, 0)
		So(c, ShouldEqual, "pulse.json")

		Convey("unmarshal pulse.json", func() {
			m, e = UnmarshallPluginMetricTypes("pulse.json", a)
			So(e, ShouldBeNil)
			So(strings.Join(m[0].Namespace(), "/"), ShouldResemble, "foo/bar")
			So(m[0].Data(), ShouldResemble, float64(1))
			So(strings.Join(m[1].Namespace(), "/"), ShouldResemble, "foo/baz")
			So(m[1].Data(), ShouldResemble, "2")
		})

		Convey("error on bad corrupt data", func() {
			a = []byte{1, 0, 1, 1, 1, 1, 1, 0, 0, 1}
			m, e = UnmarshallPluginMetricTypes("pulse.json", a)
			So(e, ShouldNotBeNil)
			So(e.Error(), ShouldResemble, "invalid character '\\x01' looking for beginning of value")
		})
	})

	Convey("error on unmarshall using bad content type", t, func() {
		m := []PluginMetricType{
			*NewPluginMetricType([]string{"foo", "bar"}, 1),
			*NewPluginMetricType([]string{"foo", "baz"}, "2"),
		}
		a, c, e := MarshallPluginMetricTypes("pulse.json", m)
		So(e, ShouldBeNil)
		So(a, ShouldNotBeNil)
		So(len(a), ShouldBeGreaterThan, 0)
		So(c, ShouldEqual, "pulse.json")

		m, e = UnmarshallPluginMetricTypes("pulse.wat", a)
		So(e, ShouldNotBeNil)
		So(e.Error(), ShouldEqual, "invlaid pulse content type for unmarshalling: pulse.wat")
		So(m, ShouldBeNil)
	})

	Convey("swap from pulse.gob to pulse.json", t, func() {
		m := []PluginMetricType{
			*NewPluginMetricType([]string{"foo", "bar"}, 1),
			*NewPluginMetricType([]string{"foo", "baz"}, "2"),
		}
		a, c, e := MarshallPluginMetricTypes("pulse.gob", m)
		So(e, ShouldBeNil)
		So(a, ShouldNotBeNil)
		So(len(a), ShouldBeGreaterThan, 0)
		So(c, ShouldEqual, "pulse.gob")

		b, c, e := SwapPluginMetricContentType(c, "pulse.json", a)
		So(e, ShouldBeNil)
		So(c, ShouldResemble, "pulse.json")
		So(b, ShouldNotBeNil)

		m, e = UnmarshallPluginMetricTypes(c, b)
		So(e, ShouldBeNil)
		So(strings.Join(m[0].Namespace(), "/"), ShouldResemble, "foo/bar")
		So(m[0].Data(), ShouldResemble, float64(1))
		So(strings.Join(m[1].Namespace(), "/"), ShouldResemble, "foo/baz")
		So(m[1].Data(), ShouldResemble, "2")
	})

	Convey("swap from pulse.json to pulse.*", t, func() {
		m := []PluginMetricType{
			*NewPluginMetricType([]string{"foo", "bar"}, 1),
			*NewPluginMetricType([]string{"foo", "baz"}, "2"),
		}
		a, c, e := MarshallPluginMetricTypes("pulse.json", m)
		So(e, ShouldBeNil)
		So(a, ShouldNotBeNil)
		So(len(a), ShouldBeGreaterThan, 0)
		So(c, ShouldEqual, "pulse.json")

		b, c, e := SwapPluginMetricContentType(c, "pulse.*", a)
		So(e, ShouldBeNil)
		So(c, ShouldResemble, "pulse.gob")
		So(b, ShouldNotBeNil)

		m, e = UnmarshallPluginMetricTypes(c, b)
		So(e, ShouldBeNil)
		So(strings.Join(m[0].Namespace(), "/"), ShouldResemble, "foo/bar")
		So(m[0].Data(), ShouldResemble, float64(1))
		So(strings.Join(m[1].Namespace(), "/"), ShouldResemble, "foo/baz")
		So(m[1].Data(), ShouldResemble, "2")
	})

	Convey("swap from pulse.json to pulse.gob", t, func() {
		m := []PluginMetricType{
			*NewPluginMetricType([]string{"foo", "bar"}, 1),
			*NewPluginMetricType([]string{"foo", "baz"}, "2"),
		}
		a, c, e := MarshallPluginMetricTypes("pulse.json", m)
		So(e, ShouldBeNil)
		So(a, ShouldNotBeNil)
		So(len(a), ShouldBeGreaterThan, 0)
		So(c, ShouldEqual, "pulse.json")

		b, c, e := SwapPluginMetricContentType(c, "pulse.gob", a)
		So(e, ShouldBeNil)
		So(c, ShouldResemble, "pulse.gob")
		So(b, ShouldNotBeNil)

		m, e = UnmarshallPluginMetricTypes(c, b)
		So(e, ShouldBeNil)
		So(strings.Join(m[0].Namespace(), "/"), ShouldResemble, "foo/bar")
		So(m[0].Data(), ShouldResemble, float64(1))
		So(strings.Join(m[1].Namespace(), "/"), ShouldResemble, "foo/baz")
		So(m[1].Data(), ShouldResemble, "2")
	})

	Convey("error on bad content type to swap", t, func() {
		m := []PluginMetricType{
			*NewPluginMetricType([]string{"foo", "bar"}, 1),
			*NewPluginMetricType([]string{"foo", "baz"}, "2"),
		}
		a, c, e := MarshallPluginMetricTypes("pulse.json", m)
		So(e, ShouldBeNil)
		So(a, ShouldNotBeNil)
		So(len(a), ShouldBeGreaterThan, 0)
		So(c, ShouldEqual, "pulse.json")

		b, c, e := SwapPluginMetricContentType("pulse.wat", "pulse.gob", a)
		So(e, ShouldNotBeNil)
		So(e.Error(), ShouldResemble, "invlaid pulse content type for unmarshalling: pulse.wat")
		So(b, ShouldBeNil)
	})
}
<commit_msg>Slightly increasing the coverage for metric.go<commit_after>package plugin

import (
	"github.com/intelsdi-x/pulse/core/cdata"
	"github.com/intelsdi-x/pulse/core/ctypes"
	"strings"
	"testing"

	. "github.com/smartystreets/goconvey/convey"
)

func TestMetric(t *testing.T) {
	Convey("error on invalid pulse content type", t, func() {
		m := []PluginMetricType{
			*NewPluginMetricType([]string{"foo", "bar"}, 1),
			*NewPluginMetricType([]string{"foo", "baz"}, 2),
		}
		a, c, e := MarshallPluginMetricTypes("foo", m)
		m[0].Version_ = 1
		m[0].AddData(3)
		configNewNode := cdata.NewNode()
		configNewNode.AddItem("user", ctypes.ConfigValueStr{Value: "foo"})

		m[0].Config_ = configNewNode
		So(e, ShouldNotBeNil)
		So(e.Error(), ShouldEqual, "invlaid pulse content type: foo")
		So(a, ShouldBeNil)
		So(c, ShouldEqual, "")
		So(m[0].Version(), ShouldResemble, 1)
		So(m[0].Data(), ShouldResemble, 3)
		So(m[0].Config(), ShouldNotBeNil)

	})

	Convey("error on empty metric slice", t, func() {
		m := []PluginMetricType{}
		a, c, e := MarshallPluginMetricTypes("foo", m)
		So(e, ShouldNotBeNil)
		So(e.Error(), ShouldEqual, "attempt to marshall empty slice of metrics: foo")
		So(a, ShouldBeNil)
		So(c, ShouldEqual, "")
	})

	Convey("marshall using pulse.* default to pulse.gob", t, func() {
		m := []PluginMetricType{
			*NewPluginMetricType([]string{"foo", "bar"}, 1),
			*NewPluginMetricType([]string{"foo", "baz"}, "2"),
		}
		a, c, e := MarshallPluginMetricTypes("pulse.*", m)
		So(e, ShouldBeNil)
		So(a, ShouldNotBeNil)
		So(len(a), ShouldBeGreaterThan, 0)
		So(c, ShouldEqual, "pulse.gob")

		Convey("unmarshal pulse.gob", func() {
			m, e = UnmarshallPluginMetricTypes("pulse.gob", a)
			So(e, ShouldBeNil)
			So(strings.Join(m[0].Namespace(), "/"), ShouldResemble, "foo/bar")
			So(m[0].Data(), ShouldResemble, 1)
			So(strings.Join(m[1].Namespace(), "/"), ShouldResemble, "foo/baz")
			So(m[1].Data(), ShouldResemble, "2")
		})

	})

	Convey("marshall using pulse.gob", t, func() {
		m := []PluginMetricType{
			*NewPluginMetricType([]string{"foo", "bar"}, 1),
			*NewPluginMetricType([]string{"foo", "baz"}, "2"),
		}
		a, c, e := MarshallPluginMetricTypes("pulse.gob", m)
		So(e, ShouldBeNil)
		So(a, ShouldNotBeNil)
		So(len(a), ShouldBeGreaterThan, 0)
		So(c, ShouldEqual, "pulse.gob")

		Convey("unmarshal pulse.gob", func() {
			m, e = UnmarshallPluginMetricTypes("pulse.gob", a)
			So(e, ShouldBeNil)
			So(strings.Join(m[0].Namespace(), "/"), ShouldResemble, "foo/bar")
			So(m[0].Data(), ShouldResemble, 1)
			So(strings.Join(m[1].Namespace(), "/"), ShouldResemble, "foo/baz")
			So(m[1].Data(), ShouldResemble, "2")
		})

		Convey("error on bad corrupt data", func() {
			a = []byte{1, 0, 1, 1, 1, 1, 1, 0, 0, 1}
			m, e = UnmarshallPluginMetricTypes("pulse.gob", a)
			So(e, ShouldNotBeNil)
			So(e.Error(), ShouldResemble, "gob: decoding into local type *[]plugin.PluginMetricType, received remote type unknown type")
		})
	})

	Convey("marshall using pulse.json", t, func() {
		m := []PluginMetricType{
			*NewPluginMetricType([]string{"foo", "bar"}, 1),
			*NewPluginMetricType([]string{"foo", "baz"}, "2"),
		}
		a, c, e := MarshallPluginMetricTypes("pulse.json", m)
		So(e, ShouldBeNil)
		So(a, ShouldNotBeNil)
		So(len(a), ShouldBeGreaterThan, 0)
		So(c, ShouldEqual, "pulse.json")

		Convey("unmarshal pulse.json", func() {
			m, e = UnmarshallPluginMetricTypes("pulse.json", a)
			So(e, ShouldBeNil)
			So(strings.Join(m[0].Namespace(), "/"), ShouldResemble, "foo/bar")
			So(m[0].Data(), ShouldResemble, float64(1))
			So(strings.Join(m[1].Namespace(), "/"), ShouldResemble, "foo/baz")
			So(m[1].Data(), ShouldResemble, "2")
		})

		Convey("error on bad corrupt data", func() {
			a = []byte{1, 0, 1, 1, 1, 1, 1, 0, 0, 1}
			m, e = UnmarshallPluginMetricTypes("pulse.json", a)
			So(e, ShouldNotBeNil)
			So(e.Error(), ShouldResemble, "invalid character '\\x01' looking for beginning of value")
		})
	})

	Convey("error on unmarshall using bad content type", t, func() {
		m := []PluginMetricType{
			*NewPluginMetricType([]string{"foo", "bar"}, 1),
			*NewPluginMetricType([]string{"foo", "baz"}, "2"),
		}
		a, c, e := MarshallPluginMetricTypes("pulse.json", m)
		So(e, ShouldBeNil)
		So(a, ShouldNotBeNil)
		So(len(a), ShouldBeGreaterThan, 0)
		So(c, ShouldEqual, "pulse.json")

		m, e = UnmarshallPluginMetricTypes("pulse.wat", a)
		So(e, ShouldNotBeNil)
		So(e.Error(), ShouldEqual, "invlaid pulse content type for unmarshalling: pulse.wat")
		So(m, ShouldBeNil)
	})

	Convey("swap from pulse.gob to pulse.json", t, func() {
		m := []PluginMetricType{
			*NewPluginMetricType([]string{"foo", "bar"}, 1),
			*NewPluginMetricType([]string{"foo", "baz"}, "2"),
		}
		a, c, e := MarshallPluginMetricTypes("pulse.gob", m)
		So(e, ShouldBeNil)
		So(a, ShouldNotBeNil)
		So(len(a), ShouldBeGreaterThan, 0)
		So(c, ShouldEqual, "pulse.gob")

		b, c, e := SwapPluginMetricContentType(c, "pulse.json", a)
		So(e, ShouldBeNil)
		So(c, ShouldResemble, "pulse.json")
		So(b, ShouldNotBeNil)

		m, e = UnmarshallPluginMetricTypes(c, b)
		So(e, ShouldBeNil)
		So(strings.Join(m[0].Namespace(), "/"), ShouldResemble, "foo/bar")
		So(m[0].Data(), ShouldResemble, float64(1))
		So(strings.Join(m[1].Namespace(), "/"), ShouldResemble, "foo/baz")
		So(m[1].Data(), ShouldResemble, "2")
	})

	Convey("swap from pulse.json to pulse.*", t, func() {
		m := []PluginMetricType{
			*NewPluginMetricType([]string{"foo", "bar"}, 1),
			*NewPluginMetricType([]string{"foo", "baz"}, "2"),
		}
		a, c, e := MarshallPluginMetricTypes("pulse.json", m)
		So(e, ShouldBeNil)
		So(a, ShouldNotBeNil)
		So(len(a), ShouldBeGreaterThan, 0)
		So(c, ShouldEqual, "pulse.json")

		b, c, e := SwapPluginMetricContentType(c, "pulse.*", a)
		So(e, ShouldBeNil)
		So(c, ShouldResemble, "pulse.gob")
		So(b, ShouldNotBeNil)

		m, e = UnmarshallPluginMetricTypes(c, b)
		So(e, ShouldBeNil)
		So(strings.Join(m[0].Namespace(), "/"), ShouldResemble, "foo/bar")
		So(m[0].Data(), ShouldResemble, float64(1))
		So(strings.Join(m[1].Namespace(), "/"), ShouldResemble, "foo/baz")
		So(m[1].Data(), ShouldResemble, "2")
	})

	Convey("swap from pulse.json to pulse.gob", t, func() {
		m := []PluginMetricType{
			*NewPluginMetricType([]string{"foo", "bar"}, 1),
			*NewPluginMetricType([]string{"foo", "baz"}, "2"),
		}
		a, c, e := MarshallPluginMetricTypes("pulse.json", m)
		So(e, ShouldBeNil)
		So(a, ShouldNotBeNil)
		So(len(a), ShouldBeGreaterThan, 0)
		So(c, ShouldEqual, "pulse.json")

		b, c, e := SwapPluginMetricContentType(c, "pulse.gob", a)
		So(e, ShouldBeNil)
		So(c, ShouldResemble, "pulse.gob")
		So(b, ShouldNotBeNil)

		m, e = UnmarshallPluginMetricTypes(c, b)
		So(e, ShouldBeNil)
		So(strings.Join(m[0].Namespace(), "/"), ShouldResemble, "foo/bar")
		So(m[0].Data(), ShouldResemble, float64(1))
		So(strings.Join(m[1].Namespace(), "/"), ShouldResemble, "foo/baz")
		So(m[1].Data(), ShouldResemble, "2")
	})

	Convey("error on bad content type to swap", t, func() {
		m := []PluginMetricType{
			*NewPluginMetricType([]string{"foo", "bar"}, 1),
			*NewPluginMetricType([]string{"foo", "baz"}, "2"),
		}
		a, c, e := MarshallPluginMetricTypes("pulse.json", m)
		So(e, ShouldBeNil)
		So(a, ShouldNotBeNil)
		So(len(a), ShouldBeGreaterThan, 0)
		So(c, ShouldEqual, "pulse.json")

		b, c, e := SwapPluginMetricContentType("pulse.wat", "pulse.gob", a)
		So(e, ShouldNotBeNil)
		So(e.Error(), ShouldResemble, "invlaid pulse content type for unmarshalling: pulse.wat")
		So(b, ShouldBeNil)
	})
}
<|endoftext|>


<commit_before>package bongo

import (
	"github.com/koding/broker"
	"github.com/koding/logging"

	"github.com/jinzhu/gorm"
)

var B *Bongo

type Bongo struct {
	Broker *broker.Broker
	DB     *gorm.DB
	log    logging.Logger
	Cache  Cache
}

func New(b *broker.Broker, db *gorm.DB, l logging.Logger) *Bongo {
	return &Bongo{
		Broker: b,
		DB:     db,
		log:    l,
	}
}

func (b *Bongo) Connect() error {
	if err := b.Broker.Connect(); err != nil {
		return err
	}
	B = b

	b.log.Info("Bongo connected %t", true)
	// todo add gorm Connect()
	return nil
}

func (b *Bongo) Close() error {
	if err := b.Broker.Close(); err != nil {
		return err
	}
	b.log.Info("Bongo dis-connected %t", true)

	// todo add gorm Close()
	return nil
}
<commit_msg>Bongo: add backoff-support while connecting to the broker<commit_after>package bongo

import (
	"github.com/cenkalti/backoff"
	"github.com/koding/broker"
	"github.com/koding/logging"

	"github.com/jinzhu/gorm"
)

var B *Bongo

type Bongo struct {
	Broker *broker.Broker
	DB     *gorm.DB
	log    logging.Logger
	Cache  Cache
}

func New(b *broker.Broker, db *gorm.DB, l logging.Logger) *Bongo {
	return &Bongo{
		Broker: b,
		DB:     db,
		log:    l,
	}
}

func (b *Bongo) Connect() error {

	bo := backoff.NewExponentialBackOff()
	ticker := backoff.NewTicker(bo)

	var err error
	for _ = range ticker.C {
		if err = b.Broker.Connect(); err != nil {
			b.log.Error("err while connecting: %s  will retry...", err.Error())
			continue
		}

		break
	}

	if err != nil {
		return err
	}

	B = b

	b.log.Info("Bongo connected %t", true)
	// todo add gorm Connect()
	return nil
}

func (b *Bongo) Close() error {
	if err := b.Broker.Close(); err != nil {
		return err
	}
	b.log.Info("Bongo dis-connected %t", true)

	// todo add gorm Close()
	return nil
}
<|endoftext|>


<commit_before>package models

import (
	"errors"
	"time"

	"github.com/koding/bongo"
)

type MessageReply struct {
	// unique identifier of the MessageReply
	Id int64 `json:"id"`

	// Id of the interacted message
	MessageId int64 `json:"messageId"             sql:"NOT NULL"`

	// Id of the reply
	ReplyId int64 `json:"replyId"                 sql:"NOT NULL"`

	// Creation of the MessageReply
	CreatedAt time.Time `json:"createdAt"         sql:"NOT NULL"`
}

func (m *MessageReply) GetId() int64 {
	return m.Id
}

func (m MessageReply) TableName() string {
	return "api.message_reply"
}

func NewMessageReply() *MessageReply {
	return &MessageReply{}
}

func (m *MessageReply) AfterCreate() {
	bongo.B.AfterCreate(m)
}

func (m *MessageReply) AfterUpdate() {
	bongo.B.AfterUpdate(m)
}

func (m *MessageReply) AfterDelete() {
	bongo.B.AfterDelete(m)
}

func (m *MessageReply) Fetch() error {
	return bongo.B.Fetch(m)
}

func (m *MessageReply) Create() error {
	return bongo.B.Create(m)
}

func (m *MessageReply) Delete() error {
	if err := bongo.B.DB.
		Where("message_id = ? and reply_id = ?", m.MessageId, m.ReplyId).
		Delete(m).Error; err != nil {
		return err
	}
	return nil
}

func (m *MessageReply) List() ([]ChannelMessage, error) {
	var replies []int64

	if m.MessageId == 0 {
		return nil, errors.New("MessageId is not set")
	}

	if err := bongo.B.DB.Table(m.TableName()).
		Where("message_id = ?", m.MessageId).
		Pluck("reply_id", &replies).
		Error; err != nil {
		return nil, err
	}

	parent := NewChannelMessage()
	channelMessageReplies, err := parent.FetchByIds(replies)
	if err != nil {
		return nil, err
	}

	return channelMessageReplies, nil
}
<commit_msg>SocialApi: FetchReplyIds method is added for MessageReply<commit_after>package models

import (
	"errors"
	"time"

	"github.com/koding/bongo"
)

type MessageReply struct {
	// unique identifier of the MessageReply
	Id int64 `json:"id"`

	// Id of the interacted message
	MessageId int64 `json:"messageId"             sql:"NOT NULL"`

	// Id of the reply
	ReplyId int64 `json:"replyId"                 sql:"NOT NULL"`

	// Creation of the MessageReply
	CreatedAt time.Time `json:"createdAt"         sql:"NOT NULL"`
}

func (m *MessageReply) GetId() int64 {
	return m.Id
}

func (m MessageReply) TableName() string {
	return "api.message_reply"
}

func NewMessageReply() *MessageReply {
	return &MessageReply{}
}

func (m *MessageReply) AfterCreate() {
	bongo.B.AfterCreate(m)
}

func (m *MessageReply) AfterUpdate() {
	bongo.B.AfterUpdate(m)
}

func (m *MessageReply) AfterDelete() {
	bongo.B.AfterDelete(m)
}

func (m *MessageReply) Fetch() error {
	return bongo.B.Fetch(m)
}

func (m *MessageReply) Create() error {
	return bongo.B.Create(m)
}

func (m *MessageReply) Delete() error {
	if err := bongo.B.DB.
		Where("message_id = ? and reply_id = ?", m.MessageId, m.ReplyId).
		Delete(m).Error; err != nil {
		return err
	}
	return nil
}

func (m *MessageReply) Some(data interface{}, q *bongo.Query) error {

	return bongo.B.Some(m, data, q)
}

func (m *MessageReply) List() ([]ChannelMessage, error) {
	var replies []int64

	if m.MessageId == 0 {
		return nil, errors.New("MessageId is not set")
	}

	// TODO change this with FetchReplyIds methods
	if err := bongo.B.DB.Table(m.TableName()).
		Where("message_id = ?", m.MessageId).
		Pluck("reply_id", &replies).
		Error; err != nil {
		return nil, err
	}

	parent := NewChannelMessage()
	channelMessageReplies, err := parent.FetchByIds(replies)
	if err != nil {
		return nil, err
	}

	return channelMessageReplies, nil
}

func (m *MessageReply) FetchReplyIds() ([]int64, error) {
	var replyIds []int64
	q := &bongo.Query{
		Selector: map[string]interface{}{
			"message_id": m.MessageId,
		},
		Pluck: "reply_id",
	}
	if err := m.Some(&replyIds, q); err != nil {
		return nil, err
	}

	return replyIds, nil
}
<|endoftext|>


<commit_before>// Package neat implements NeuroEvolution of Augmenting Topologies (NEAT) method which can be used to evolve
// Artificial Neural Networks to perform specific task using genetic algorithms.
package neat

import (
	"math/rand"
	"fmt"
	"io"
	"log"
	"os"
)

// LoggerLevel type to specify logger output level
type LoggerLevel byte

const (
	// The Debug log level
	LogLevelDebug LoggerLevel = iota
	// The Info log level
	LogLevelInfo
	// The Warning log level
	LogLevelWarning
	// The Error log level
	LogLevelError
)

var (
	// The current log level of the context
	LogLevel LoggerLevel

	loggerDebug = log.New(os.Stdout, "DEBUG: ", log.Ltime | log.Lshortfile)
	loggerInfo = log.New(os.Stdout, "INFO: ", log.Ltime | log.Lshortfile)
	loggerWarn = log.New(os.Stdout, "ALERT: ", log.Ltime | log.Lshortfile)
	loggerError = log.New(os.Stderr, "ERROR: ", log.Ltime | log.Lshortfile)

	// The logger to output all messages
	DebugLog = func(message string) {
		if LogLevel <= LogLevelDebug {
			loggerDebug.Output(2, message)
		}
	}
	// The logger to output messages with Info and up level
	InfoLog = func(message string) {
		if LogLevel <= LogLevelInfo {
			loggerInfo.Output(2, message)
		}
	}
	// The logger to output messages with Warn and up level
	WarnLog = func(message string) {
		if LogLevel <= LogLevelWarning {
			loggerWarn.Output(2, message)
		}
	}
	// The logger to output messages with Error and up level
	ErrorLog = func(message string) {
		if LogLevel <= LogLevelError {
			loggerError.Output(2, message)
		}
	}
)

// The NEAT execution context holding common configuration parameters, etc.
type NeatContext struct {
				       // Probability of mutating a single trait param
	TraitParamMutProb      float64
				       // Power of mutation on a single trait param
	TraitMutationPower     float64
				       // The power of a linkweight mutation
	WeightMutPower         float64

				       // These 3 global coefficients are used to determine the formula for
				       // computing the compatibility between 2 genomes.  The formula is:
				       // disjoint_coeff * pdg + excess_coeff * peg + mutdiff_coeff * mdmg.
				       // See the compatibility method in the Genome class for more info
				       // They can be thought of as the importance of disjoint Genes,
				       // excess Genes, and parametric difference between Genes of the
				       // same function, respectively.
	DisjointCoeff          float64
	ExcessCoeff            float64
	MutdiffCoeff           float64

				       // This global tells compatibility threshold under which
				       // two Genomes are considered the same species */
	CompatThreshold        float64

				       /* Globals involved in the epoch cycle - mating, reproduction, etc.. */

				       // How much does age matter?
	AgeSignificance        float64
				       // Percent of ave fitness for survival
	SurvivalThresh         float64

				       // Probabilities of a non-mating reproduction
	MutateOnlyProb         float64
	MutateRandomTraitProb  float64
	MutateLinkTraitProb    float64
	MutateNodeTraitProb    float64
	MutateLinkWeightsProb  float64
	MutateToggleEnableProb float64
	MutateGeneReenableProb float64
	MutateAddNodeProb      float64
	MutateAddLinkProb      float64
	MutateConnectSensors   float64 // probability of mutation involving disconnected inputs connection

				       // Probabilities of a mate being outside species
	InterspeciesMateRate   float64
	MateMultipointProb     float64
	MateMultipointAvgProb  float64
	MateSinglepointProb    float64

				       // Prob. of mating without mutation
	MateOnlyProb           float64
				       // Probability of forcing selection of ONLY links that are naturally recurrent
	RecurOnlyProb          float64

				       // Size of population
	PopSize                int
				       // Age when Species starts to be penalized
	DropOffAge             int
				       // Number of tries mutate_add_link will attempt to find an open link
	NewLinkTries           int

				       // Tells to print population to file every n generations
	PrintEvery             int

				       // The number of babies to stolen off to the champions
	BabiesStolen           int

				       // The number of runs to average over in an experiment
	NumRuns                int

				       // The number of epochs (generations) to execute training
	NumGenerations         int
}

// Loads context configuration from provided reader
func LoadContext(r io.Reader) *NeatContext {
	c := NeatContext{}
	// read configuration
	var name string
	var param float64;
	for true {
		_, err := fmt.Fscanf(r, "%s %f", &name, &param)
		if err == io.EOF {
			break
		}
		switch name {
		case "trait_param_mut_prob":
			c.TraitParamMutProb = param
		case "trait_mutation_power":
			c.TraitMutationPower = param
		case "weight_mut_power":
			c.WeightMutPower = param
		case "disjoint_coeff":
			c.DisjointCoeff = param
		case "excess_coeff":
			c.ExcessCoeff = param
		case "mutdiff_coeff":
			c.MutdiffCoeff = param
		case "compat_threshold":
			c.CompatThreshold = param
		case "age_significance":
			c.AgeSignificance = param
		case "survival_thresh":
			c.SurvivalThresh = param
		case "mutate_only_prob":
			c.MutateOnlyProb = param
		case "mutate_random_trait_prob":
			c.MutateRandomTraitProb = param
		case "mutate_link_trait_prob":
			c.MutateLinkTraitProb = param
		case "mutate_node_trait_prob":
			c.MutateNodeTraitProb = param
		case "mutate_link_weights_prob":
			c.MutateLinkWeightsProb = param
		case "mutate_toggle_enable_prob":
			c.MutateToggleEnableProb = param
		case "mutate_gene_reenable_prob":
			c.MutateGeneReenableProb = param
		case "mutate_add_node_prob":
			c.MutateAddNodeProb = param
		case "mutate_add_link_prob":
			c.MutateAddLinkProb = param
		case "mutate_connect_sensors":
			c.MutateConnectSensors = param
		case "interspecies_mate_rate":
			c.InterspeciesMateRate = param
		case "mate_multipoint_prob":
			c.MateMultipointProb = param
		case "mate_multipoint_avg_prob":
			c.MateMultipointAvgProb = param
		case "mate_singlepoint_prob":
			c.MateSinglepointProb = param
		case "mate_only_prob":
			c.MateOnlyProb = param
		case "recur_only_prob":
			c.RecurOnlyProb = param
		case "pop_size":
			c.PopSize = int(param)
		case "dropoff_age":
			c.DropOffAge = int(param)
		case "newlink_tries":
			c.NewLinkTries = int(param)
		case "print_every":
			c.PrintEvery = int(param)
		case "babies_stolen":
			c.BabiesStolen = int(param)
		case "num_runs":
			c.NumRuns = int(param)
		case "num_generations":
			c.NumGenerations = int(param)
		case "log_level":
			LogLevel = LoggerLevel(param)
		default:
			fmt.Printf("WARNING! Unknown configuration parameter found: %s = %.f\n", name, param)
		}
	}

	return &c
}

// Returns
func RandPosNeg() int32 {
	v := rand.Int()
	if (v % 2) == 0 {
		return -1
	} else {
		return 1
	}
}
<commit_msg>Added output path configuration to the NEAT execution context<commit_after>// Package neat implements NeuroEvolution of Augmenting Topologies (NEAT) method which can be used to evolve
// Artificial Neural Networks to perform specific task using genetic algorithms.
package neat

import (
	"math/rand"
	"fmt"
	"io"
	"log"
	"os"
)

// LoggerLevel type to specify logger output level
type LoggerLevel byte

const (
	// The Debug log level
	LogLevelDebug LoggerLevel = iota
	// The Info log level
	LogLevelInfo
	// The Warning log level
	LogLevelWarning
	// The Error log level
	LogLevelError
)

var (
	// The current log level of the context
	LogLevel LoggerLevel

	loggerDebug = log.New(os.Stdout, "DEBUG: ", log.Ltime | log.Lshortfile)
	loggerInfo = log.New(os.Stdout, "INFO: ", log.Ltime | log.Lshortfile)
	loggerWarn = log.New(os.Stdout, "ALERT: ", log.Ltime | log.Lshortfile)
	loggerError = log.New(os.Stderr, "ERROR: ", log.Ltime | log.Lshortfile)

	// The logger to output all messages
	DebugLog = func(message string) {
		if LogLevel <= LogLevelDebug {
			loggerDebug.Output(2, message)
		}
	}
	// The logger to output messages with Info and up level
	InfoLog = func(message string) {
		if LogLevel <= LogLevelInfo {
			loggerInfo.Output(2, message)
		}
	}
	// The logger to output messages with Warn and up level
	WarnLog = func(message string) {
		if LogLevel <= LogLevelWarning {
			loggerWarn.Output(2, message)
		}
	}
	// The logger to output messages with Error and up level
	ErrorLog = func(message string) {
		if LogLevel <= LogLevelError {
			loggerError.Output(2, message)
		}
	}
)

// The NEAT execution context holding common configuration parameters, etc.
type NeatContext struct {
				       // Probability of mutating a single trait param
	TraitParamMutProb      float64
				       // Power of mutation on a single trait param
	TraitMutationPower     float64
				       // The power of a linkweight mutation
	WeightMutPower         float64

				       // These 3 global coefficients are used to determine the formula for
				       // computing the compatibility between 2 genomes.  The formula is:
				       // disjoint_coeff * pdg + excess_coeff * peg + mutdiff_coeff * mdmg.
				       // See the compatibility method in the Genome class for more info
				       // They can be thought of as the importance of disjoint Genes,
				       // excess Genes, and parametric difference between Genes of the
				       // same function, respectively.
	DisjointCoeff          float64
	ExcessCoeff            float64
	MutdiffCoeff           float64

				       // This global tells compatibility threshold under which
				       // two Genomes are considered the same species */
	CompatThreshold        float64

				       /* Globals involved in the epoch cycle - mating, reproduction, etc.. */

				       // How much does age matter?
	AgeSignificance        float64
				       // Percent of ave fitness for survival
	SurvivalThresh         float64

				       // Probabilities of a non-mating reproduction
	MutateOnlyProb         float64
	MutateRandomTraitProb  float64
	MutateLinkTraitProb    float64
	MutateNodeTraitProb    float64
	MutateLinkWeightsProb  float64
	MutateToggleEnableProb float64
	MutateGeneReenableProb float64
	MutateAddNodeProb      float64
	MutateAddLinkProb      float64
	MutateConnectSensors   float64 // probability of mutation involving disconnected inputs connection

				       // Probabilities of a mate being outside species
	InterspeciesMateRate   float64
	MateMultipointProb     float64
	MateMultipointAvgProb  float64
	MateSinglepointProb    float64

				       // Prob. of mating without mutation
	MateOnlyProb           float64
				       // Probability of forcing selection of ONLY links that are naturally recurrent
	RecurOnlyProb          float64

				       // Size of population
	PopSize                int
				       // Age when Species starts to be penalized
	DropOffAge             int
				       // Number of tries mutate_add_link will attempt to find an open link
	NewLinkTries           int

				       // Tells to print population to file every n generations
	PrintEvery             int

				       // The number of babies to stolen off to the champions
	BabiesStolen           int

				       // The number of runs to average over in an experiment
	NumRuns                int

				       // The number of epochs (generations) to execute training
	NumGenerations         int

				       // The output path to store execution results
	OutputPath             string
}

// Loads context configuration from provided reader
func LoadContext(r io.Reader) *NeatContext {
	c := NeatContext{}
	// read configuration
	var name string
	var param float64;
	for true {
		_, err := fmt.Fscanf(r, "%s %f", &name, &param)
		if err == io.EOF {
			break
		}
		switch name {
		case "trait_param_mut_prob":
			c.TraitParamMutProb = param
		case "trait_mutation_power":
			c.TraitMutationPower = param
		case "weight_mut_power":
			c.WeightMutPower = param
		case "disjoint_coeff":
			c.DisjointCoeff = param
		case "excess_coeff":
			c.ExcessCoeff = param
		case "mutdiff_coeff":
			c.MutdiffCoeff = param
		case "compat_threshold":
			c.CompatThreshold = param
		case "age_significance":
			c.AgeSignificance = param
		case "survival_thresh":
			c.SurvivalThresh = param
		case "mutate_only_prob":
			c.MutateOnlyProb = param
		case "mutate_random_trait_prob":
			c.MutateRandomTraitProb = param
		case "mutate_link_trait_prob":
			c.MutateLinkTraitProb = param
		case "mutate_node_trait_prob":
			c.MutateNodeTraitProb = param
		case "mutate_link_weights_prob":
			c.MutateLinkWeightsProb = param
		case "mutate_toggle_enable_prob":
			c.MutateToggleEnableProb = param
		case "mutate_gene_reenable_prob":
			c.MutateGeneReenableProb = param
		case "mutate_add_node_prob":
			c.MutateAddNodeProb = param
		case "mutate_add_link_prob":
			c.MutateAddLinkProb = param
		case "mutate_connect_sensors":
			c.MutateConnectSensors = param
		case "interspecies_mate_rate":
			c.InterspeciesMateRate = param
		case "mate_multipoint_prob":
			c.MateMultipointProb = param
		case "mate_multipoint_avg_prob":
			c.MateMultipointAvgProb = param
		case "mate_singlepoint_prob":
			c.MateSinglepointProb = param
		case "mate_only_prob":
			c.MateOnlyProb = param
		case "recur_only_prob":
			c.RecurOnlyProb = param
		case "pop_size":
			c.PopSize = int(param)
		case "dropoff_age":
			c.DropOffAge = int(param)
		case "newlink_tries":
			c.NewLinkTries = int(param)
		case "print_every":
			c.PrintEvery = int(param)
		case "babies_stolen":
			c.BabiesStolen = int(param)
		case "num_runs":
			c.NumRuns = int(param)
		case "num_generations":
			c.NumGenerations = int(param)
		case "output_path":
			c.OutputPath = param
		case "log_level":
			LogLevel = LoggerLevel(param)
		default:
			fmt.Printf("WARNING! Unknown configuration parameter found: %s = %.f\n", name, param)
		}
	}

	return &c
}

// Returns
func RandPosNeg() int32 {
	v := rand.Int()
	if (v % 2) == 0 {
		return -1
	} else {
		return 1
	}
}
<|endoftext|>


<commit_before>package core

import (
	"fmt"
)

// writer points a shared state. sharedStateSink will point to the same shared state
// even after the state is removed from the context.
type sharedStateSink struct {
	writer Writer
}

// NewSharedStateSink creates a sink that writes to SharedState.
func NewSharedStateSink(ctx *Context, name string) (Sink, error) {
	// Get SharedState by name
	state, err := ctx.SharedStates.Get(name)
	if err != nil {
		return nil, err
	}

	// It fails if the shared state cannot be written
	writer, ok := state.(Writer)
	if !ok {
		return nil, fmt.Errorf("'%v' state cannot be written")
	}

	s := &sharedStateSink{
		writer: writer,
	}
	return s, nil
}

func (s *sharedStateSink) Write(ctx *Context, t *Tuple) error {
	return s.writer.Write(ctx, t)
}

func (s *sharedStateSink) Close(ctx *Context) error {
	closer, ok := s.writer.(WriteCloser)
	if !ok {
		return nil
	}
	return closer.Close(ctx)
}
<commit_msg>Make sharedStateSink.Close return nil immediately<commit_after>package core

import (
	"fmt"
)

// writer points a shared state. sharedStateSink will point to the same shared state
// even after the state is removed from the context.
type sharedStateSink struct {
	writer Writer
}

// NewSharedStateSink creates a sink that writes to SharedState.
func NewSharedStateSink(ctx *Context, name string) (Sink, error) {
	// Get SharedState by name
	state, err := ctx.SharedStates.Get(name)
	if err != nil {
		return nil, err
	}

	// It fails if the shared state cannot be written
	writer, ok := state.(Writer)
	if !ok {
		return nil, fmt.Errorf("'%v' state cannot be written")
	}

	s := &sharedStateSink{
		writer: writer,
	}
	return s, nil
}

func (s *sharedStateSink) Write(ctx *Context, t *Tuple) error {
	return s.writer.Write(ctx, t)
}

func (s *sharedStateSink) Close(ctx *Context) error {
	return nil
}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"io"
	"log"
	"logyard"
	"logyard/clients/sieve"
	"logyard/util/pubsub"
	"net/http"
	"stackato/server"
)

var NodeID string

type Event struct {
	Id     string `json:"id"`
	Status string `json:"status"`
	From   string `json:"from"`
	Time   int64  `json:"time"`
}

func SendToLogyard(pub *pubsub.Publisher, event *Event) {
	log.Printf("Event: %+v", event)
	(&sieve.Event{
		Type:     event.Status,
		Process:  "docker_events",
		Severity: "INFO",
		UnixTime: event.Time,
		NodeID:   NodeID,
		Desc: fmt.Sprintf("%v status for container %v (image: %v)",
			event.Status, event.Id, event.From),
	}).MustPublish(pub)
}

func main() {
	pub := logyard.Broker.NewPublisherMust()
	defer pub.Stop()

	c := http.Client{}
	res, err := c.Get("http://localhost:4243/events")
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()

	// Read the streaming json from the events endpoint
	// http://docs.docker.io/en/latest/api/docker_remote_api_v1.3/#monitor-docker-s-events
	d := json.NewDecoder(res.Body)
	for {
		var event Event
		if err := d.Decode(&event); err != nil {
			if err == io.EOF {
				break
			}
			log.Fatal(err)
		}
		SendToLogyard(pub, &event)
	}
}

func init() {
	var err error
	NodeID, err = server.LocalIP()
	if err != nil {
		log.Fatalf("Failed to determine IP addr: %v", err)
	}
}
<commit_msg>use our logging package<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"github.com/ActiveState/log"
	"io"
	"logyard"
	"logyard/clients/sieve"
	"logyard/util/pubsub"
	"net/http"
	"stackato/server"
)

var NodeID string

type Event struct {
	Id     string `json:"id"`
	Status string `json:"status"`
	From   string `json:"from"`
	Time   int64  `json:"time"`
}

func SendToLogyard(pub *pubsub.Publisher, event *Event) {
	log.Infof("Event: %+v", event)
	(&sieve.Event{
		Type:     event.Status,
		Process:  "docker_events",
		Severity: "INFO",
		UnixTime: event.Time,
		NodeID:   NodeID,
		Desc: fmt.Sprintf("%v status for container %v (image: %v)",
			event.Status, event.Id, event.From),
	}).MustPublish(pub)
}

func main() {
	pub := logyard.Broker.NewPublisherMust()
	defer pub.Stop()

	c := http.Client{}
	res, err := c.Get("http://localhost:4243/events")
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()

	// Read the streaming json from the events endpoint
	// http://docs.docker.io/en/latest/api/docker_remote_api_v1.3/#monitor-docker-s-events
	d := json.NewDecoder(res.Body)
	for {
		var event Event
		if err := d.Decode(&event); err != nil {
			if err == io.EOF {
				break
			}
			log.Fatal(err)
		}
		SendToLogyard(pub, &event)
	}
}

func init() {
	var err error
	NodeID, err = server.LocalIP()
	if err != nil {
		log.Fatalf("Failed to determine IP addr: %v", err)
	}
}
<|endoftext|>


<commit_before>package dockerclient

import (
	"archive/tar"
	"bufio"
	"bytes"
	"fmt"
	"github.com/dynport/dgtk/dockerclient/docker"
	"io"
	"net/http"
	"net/url"
	"regexp"
	"time"
)

var (
	imageIdRegexp   = regexp.MustCompile("Successfully built (.*)")
	imageNameRegexp = regexp.MustCompile("([\\w.]+(?::\\d+)?/)?(\\w+)(:[\\w.]+)?")
)

// Get the list of all images available on the this host.
func (dh *DockerHost) Images() (images []*docker.Image, e error) {
	e = dh.getJSON(dh.url()+"/images/json", &images)
	return images, e
}

// Get the details for image with the given id (either hash or name).
func (dh *DockerHost) ImageDetails(id string) (imageDetails *docker.ImageDetails, e error) {
	imageDetails = &docker.ImageDetails{}
	e = dh.getJSON(dh.url()+"/images/"+id+"/json", imageDetails)
	return imageDetails, e
}

// Get the given image's history.
func (dh *DockerHost) ImageHistory(id string) (imageHistory *docker.ImageHistory, e error) {
	imageHistory = &docker.ImageHistory{}
	e = dh.getJSON(dh.url()+"/images/"+id+"/history", imageHistory)
	return imageHistory, e
}

type BuildImageOptions struct {
	Tag     string
	Quite   bool
	NoCache bool

	Callback func(s *JSONMessage)
}

func (opts *BuildImageOptions) encode() string {
	v := url.Values{}
	if opts != nil {
		if opts.Tag != "" {
			v.Add("t", opts.Tag)
		}
		if opts.NoCache {
			v.Add("nocache", "true")
		}
		if opts.Quite {
			v.Add("quiet", "true")
		}
	}
	return v.Encode()
}

// Create a new image from the given dockerfile. If name is non empty the new image is named accordingly. If a writer is
// given it is used to send the docker output to.
func (dh *DockerHost) BuildDockerfile(dockerfile string, opts *BuildImageOptions) (imageId string, e error) {
	r, e := dh.createDockerfileArchive(dockerfile)
	if e != nil {
		return "", e
	}
	return dh.Build(r, opts)

}

// Build a container image from a tar or tar.gz Reader
func (dh *DockerHost) Build(r io.Reader, opts *BuildImageOptions) (imageId string, e error) {
	u := dh.url() + "/build"
	if opts == nil {
		opts = &BuildImageOptions{}
	}
	if enc := opts.encode(); enc != "" {
		u += "?" + enc
	}
	rsp, e := dh.httpClient.Post(u, "application/tar", r)
	if e != nil {
		return "", e
	}
	defer rsp.Body.Close()

	if !success(rsp) {
		return "", fmt.Errorf("failed to send command to %q: %s", u, rsp.Status)
	}

	v, e := dh.ServerVersion()
	if e != nil {
		return "", e
	}

	var buildResponse BuildResponse
	if v.jsonBuildStream() {
		buildResponse, e = dh.handleBuildImageJson(rsp.Body, opts.Callback)
	} else {
		buildResponse, e = dh.handleBuildImagePlain(rsp.Body, opts.Callback)
	}

	if imageId = buildResponse.ImageId(); imageId == "" {
		return "", fmt.Errorf("unable to extract image id from response: %v", buildResponse)
	}
	return imageId, nil
}

// Tag the image with the given repository and tag. The tag is optional.
func (dh *DockerHost) TagImage(imageId, repository, tag string) (e error) {
	if repository == "" {
		return fmt.Errorf("empty repository given")
	}
	url := dh.url() + "/images/" + imageId + "/tag?repo=" + repository

	if tag != "" {
		url += "&tag=" + tag
	}
	rsp, e := dh.post(url)
	defer rsp.Body.Close()
	return e
}

// Pull the given image from the registry (part of the image name).
func (dh *DockerHost) PullImage(name string) error {
	if name == "" {
		return fmt.Errorf("no image name given")
	}

	registry, repository, tag := splitImageName(name)

	reqUrl := dh.url() + "/images/create"
	values := &url.Values{}
	values.Add("fromImage", registry+"/"+repository)
	values.Add("repo", repository)
	if registry != "" {
		values.Add("registry", registry)
	}
	if tag != "" {
		values.Add("tag", tag)
	}

	rsp, e := dh.post(reqUrl + "?" + values.Encode())
	if e != nil {
		return e
	}
	defer rsp.Body.Close()
	if !success(rsp) {
		return fmt.Errorf("failed to fetch image")
	}

	messages, e := splitDockerStatusMessages(rsp.Body)
	if e != nil {
		return e
	}

	for i := range messages {
		if messages[i].Error != "" {
			return fmt.Errorf("failed to pull image: %s", messages[i].Error)
		}
	}

	return dh.waitForTag(registry+"/"+repository, tag, 10)
}

// Push the given image to the registry. The name should be <registry>/<repository>.
func (dh *DockerHost) PushImage(name string) error {
	if name == "" {
		return fmt.Errorf("no image name given")
	}
	registry, _, _ := splitImageName(name)
	if registry == "" {
		return fmt.Errorf("no registry given")
	}

	dh.Logger.Infof("pushing image %s to registry %s", name, registry)
	buf := &bytes.Buffer{}
	buf.WriteString(FAKE_AUTH)
	url := dh.url() + "/images/" + name + "/push?registry=" + registry

	rsp, e := dh.postWithBuffer(url, buf)
	if e != nil {
		return e
	}
	defer rsp.Body.Close()
	if !success(rsp) {
		scanner := bufio.NewScanner(rsp.Body)
		for scanner.Scan() {
			dh.Logger.Debug(scanner.Text())
		}
		return fmt.Errorf("failed to push image:", rsp.Status)
	}
	return nil
}

// Delete the given image from the docker host.
func (dh *DockerHost) DeleteImage(name string) error {
	if name == "" {
		return fmt.Errorf("no image name given")
	}

	req, e := http.NewRequest("DELETE", dh.url()+"/images/"+name, nil)
	if e != nil {
		return e
	}

	resp, e := dh.httpClient.Do(req)
	if e != nil {
		return e
	}
	defer resp.Body.Close()

	if !success(resp) {
		return fmt.Errorf("failed to delete image %s", name)
	}

	scanner := bufio.NewScanner(resp.Body)
	for scanner.Scan() {
		line := scanner.Text()
		dh.Logger.Debug(line)
	}

	return nil
}

func (self *DockerHost) createDockerfileArchive(dockerfile string) (buf *bytes.Buffer, e error) {
	body := []byte(dockerfile)
	buf = new(bytes.Buffer)
	tw := tar.NewWriter(buf)
	header := &tar.Header{Name: "Dockerfile", Size: int64(len(body))}
	if e = tw.WriteHeader(header); e != nil {
		return nil, e
	}
	if _, e = tw.Write(body); e != nil {
		return nil, e
	}
	if e = tw.Close(); e != nil {
		return nil, e
	}
	return buf, nil
}

func (dh *DockerHost) waitForTag(repository, tag string, timeout int) error {
	for {
		dh.Logger.Debug("waiting for tag", tag)
		imageDetails, e := dh.ImageDetails(repository + ":" + tag)
		if e != nil {
			if e.Error() == "resource not found" {
				dh.Logger.Debug("got not found, waiting")
				time.Sleep(1 * time.Second)
				continue
			}
			return e
		}
		dh.Logger.Debug("got image details:", imageDetails)
		return nil
	}
}

// Every image is named after the following pattern:
//   <registry>/<repository>:<tag>
// with registry being of the form "<hostname>:<port>" and repository being a string of [A-Za-z0-9_].
func splitImageName(name string) (registry, repository, tag string) {
	s := imageNameRegexp.FindStringSubmatch(name)
	if len(s[3]) > 0 {
		tag = s[3][1:]
	}
	repository = s[2]
	if len(s[1]) > 0 {
		registry = s[1][0 : len(s[1])-1]
	}
	return registry, repository, tag
}
<commit_msg>only print last line when unable to extract<commit_after>package dockerclient

import (
	"archive/tar"
	"bufio"
	"bytes"
	"fmt"
	"github.com/dynport/dgtk/dockerclient/docker"
	"io"
	"net/http"
	"net/url"
	"regexp"
	"time"
)

var (
	imageIdRegexp   = regexp.MustCompile("Successfully built (.*)")
	imageNameRegexp = regexp.MustCompile("([\\w.]+(?::\\d+)?/)?(\\w+)(:[\\w.]+)?")
)

// Get the list of all images available on the this host.
func (dh *DockerHost) Images() (images []*docker.Image, e error) {
	e = dh.getJSON(dh.url()+"/images/json", &images)
	return images, e
}

// Get the details for image with the given id (either hash or name).
func (dh *DockerHost) ImageDetails(id string) (imageDetails *docker.ImageDetails, e error) {
	imageDetails = &docker.ImageDetails{}
	e = dh.getJSON(dh.url()+"/images/"+id+"/json", imageDetails)
	return imageDetails, e
}

// Get the given image's history.
func (dh *DockerHost) ImageHistory(id string) (imageHistory *docker.ImageHistory, e error) {
	imageHistory = &docker.ImageHistory{}
	e = dh.getJSON(dh.url()+"/images/"+id+"/history", imageHistory)
	return imageHistory, e
}

type BuildImageOptions struct {
	Tag     string
	Quite   bool
	NoCache bool

	Callback func(s *JSONMessage)
}

func (opts *BuildImageOptions) encode() string {
	v := url.Values{}
	if opts != nil {
		if opts.Tag != "" {
			v.Add("t", opts.Tag)
		}
		if opts.NoCache {
			v.Add("nocache", "true")
		}
		if opts.Quite {
			v.Add("quiet", "true")
		}
	}
	return v.Encode()
}

// Create a new image from the given dockerfile. If name is non empty the new image is named accordingly. If a writer is
// given it is used to send the docker output to.
func (dh *DockerHost) BuildDockerfile(dockerfile string, opts *BuildImageOptions) (imageId string, e error) {
	r, e := dh.createDockerfileArchive(dockerfile)
	if e != nil {
		return "", e
	}
	return dh.Build(r, opts)

}

// Build a container image from a tar or tar.gz Reader
func (dh *DockerHost) Build(r io.Reader, opts *BuildImageOptions) (imageId string, e error) {
	u := dh.url() + "/build"
	if opts == nil {
		opts = &BuildImageOptions{}
	}
	if enc := opts.encode(); enc != "" {
		u += "?" + enc
	}
	rsp, e := dh.httpClient.Post(u, "application/tar", r)
	if e != nil {
		return "", e
	}
	defer rsp.Body.Close()

	if !success(rsp) {
		return "", fmt.Errorf("failed to send command to %q: %s", u, rsp.Status)
	}

	v, e := dh.ServerVersion()
	if e != nil {
		return "", e
	}

	var buildResponse BuildResponse
	if v.jsonBuildStream() {
		buildResponse, e = dh.handleBuildImageJson(rsp.Body, opts.Callback)
	} else {
		buildResponse, e = dh.handleBuildImagePlain(rsp.Body, opts.Callback)
	}

	if imageId = buildResponse.ImageId(); imageId == "" {
		return "", fmt.Errorf("unable to extract image id from response: %v", buildResponse.Last())
	}
	return imageId, nil
}

// Tag the image with the given repository and tag. The tag is optional.
func (dh *DockerHost) TagImage(imageId, repository, tag string) (e error) {
	if repository == "" {
		return fmt.Errorf("empty repository given")
	}
	url := dh.url() + "/images/" + imageId + "/tag?repo=" + repository

	if tag != "" {
		url += "&tag=" + tag
	}
	rsp, e := dh.post(url)
	defer rsp.Body.Close()
	return e
}

// Pull the given image from the registry (part of the image name).
func (dh *DockerHost) PullImage(name string) error {
	if name == "" {
		return fmt.Errorf("no image name given")
	}

	registry, repository, tag := splitImageName(name)

	reqUrl := dh.url() + "/images/create"
	values := &url.Values{}
	values.Add("fromImage", registry+"/"+repository)
	values.Add("repo", repository)
	if registry != "" {
		values.Add("registry", registry)
	}
	if tag != "" {
		values.Add("tag", tag)
	}

	rsp, e := dh.post(reqUrl + "?" + values.Encode())
	if e != nil {
		return e
	}
	defer rsp.Body.Close()
	if !success(rsp) {
		return fmt.Errorf("failed to fetch image")
	}

	messages, e := splitDockerStatusMessages(rsp.Body)
	if e != nil {
		return e
	}

	for i := range messages {
		if messages[i].Error != "" {
			return fmt.Errorf("failed to pull image: %s", messages[i].Error)
		}
	}

	return dh.waitForTag(registry+"/"+repository, tag, 10)
}

// Push the given image to the registry. The name should be <registry>/<repository>.
func (dh *DockerHost) PushImage(name string) error {
	if name == "" {
		return fmt.Errorf("no image name given")
	}
	registry, _, _ := splitImageName(name)
	if registry == "" {
		return fmt.Errorf("no registry given")
	}

	dh.Logger.Infof("pushing image %s to registry %s", name, registry)
	buf := &bytes.Buffer{}
	buf.WriteString(FAKE_AUTH)
	url := dh.url() + "/images/" + name + "/push?registry=" + registry

	rsp, e := dh.postWithBuffer(url, buf)
	if e != nil {
		return e
	}
	defer rsp.Body.Close()
	if !success(rsp) {
		scanner := bufio.NewScanner(rsp.Body)
		for scanner.Scan() {
			dh.Logger.Debug(scanner.Text())
		}
		return fmt.Errorf("failed to push image:", rsp.Status)
	}
	return nil
}

// Delete the given image from the docker host.
func (dh *DockerHost) DeleteImage(name string) error {
	if name == "" {
		return fmt.Errorf("no image name given")
	}

	req, e := http.NewRequest("DELETE", dh.url()+"/images/"+name, nil)
	if e != nil {
		return e
	}

	resp, e := dh.httpClient.Do(req)
	if e != nil {
		return e
	}
	defer resp.Body.Close()

	if !success(resp) {
		return fmt.Errorf("failed to delete image %s", name)
	}

	scanner := bufio.NewScanner(resp.Body)
	for scanner.Scan() {
		line := scanner.Text()
		dh.Logger.Debug(line)
	}

	return nil
}

func (self *DockerHost) createDockerfileArchive(dockerfile string) (buf *bytes.Buffer, e error) {
	body := []byte(dockerfile)
	buf = new(bytes.Buffer)
	tw := tar.NewWriter(buf)
	header := &tar.Header{Name: "Dockerfile", Size: int64(len(body))}
	if e = tw.WriteHeader(header); e != nil {
		return nil, e
	}
	if _, e = tw.Write(body); e != nil {
		return nil, e
	}
	if e = tw.Close(); e != nil {
		return nil, e
	}
	return buf, nil
}

func (dh *DockerHost) waitForTag(repository, tag string, timeout int) error {
	for {
		dh.Logger.Debug("waiting for tag", tag)
		imageDetails, e := dh.ImageDetails(repository + ":" + tag)
		if e != nil {
			if e.Error() == "resource not found" {
				dh.Logger.Debug("got not found, waiting")
				time.Sleep(1 * time.Second)
				continue
			}
			return e
		}
		dh.Logger.Debug("got image details:", imageDetails)
		return nil
	}
}

// Every image is named after the following pattern:
//   <registry>/<repository>:<tag>
// with registry being of the form "<hostname>:<port>" and repository being a string of [A-Za-z0-9_].
func splitImageName(name string) (registry, repository, tag string) {
	s := imageNameRegexp.FindStringSubmatch(name)
	if len(s[3]) > 0 {
		tag = s[3][1:]
	}
	repository = s[2]
	if len(s[1]) > 0 {
		registry = s[1][0 : len(s[1])-1]
	}
	return registry, repository, tag
}
<|endoftext|>


<commit_before>package handlers

import (
	"bytes"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	log "github.com/Sirupsen/logrus"
	"io/ioutil"
	"net/http"

	"github.com/stellar/gateway/protocols"
	"github.com/stellar/gateway/protocols/compliance"
	"github.com/stellar/gateway/protocols/memo"
	"github.com/stellar/gateway/server"
	"github.com/stellar/gateway/submitter"
	b "github.com/stellar/go-stellar-base/build"
	"github.com/stellar/go-stellar-base/xdr"
	"github.com/zenazn/goji/web"
)

// HandlerSend implements /send endpoint
func (rh *RequestHandler) HandlerSend(c web.C, w http.ResponseWriter, r *http.Request) {
	request := &compliance.SendRequest{}
	request.FromRequest(r)

	err := request.Validate()
	if err != nil {
		errorResponse := err.(*protocols.ErrorResponse)
		log.WithFields(errorResponse.LogData).Error(errorResponse.Error())
		server.Write(w, errorResponse)
		return
	}

	destinationObject, stellarToml, err := rh.FederationResolver.Resolve(request.Destination)
	if err != nil {
		log.WithFields(log.Fields{
			"destination": request.Destination,
			"err":         err,
		}).Print("Cannot resolve address")
		server.Write(w, compliance.CannotResolveDestination)
		return
	}

	if stellarToml.AuthServer == "" {
		log.Print("No AUTH_SERVER in stellar.toml")
		server.Write(w, compliance.AuthServerNotDefined)
		return
	}

	var payWithMutator *b.PayWithPath

	if request.SendMax != "" {
		// Path payment
		var sendAsset b.Asset
		if request.SendAssetCode != "" && request.SendAssetIssuer != "" {
			sendAsset = b.CreditAsset(request.SendAssetCode, request.SendAssetIssuer)
		} else if request.SendAssetCode == "" && request.SendAssetIssuer == "" {
			sendAsset = b.NativeAsset()
		} else {
			log.Print("Missing send asset param.")
			server.Write(w, protocols.MissingParameterError)
			return
		}

		payWith := b.PayWith(sendAsset, request.SendMax)

		for _, asset := range request.Path {
			if asset.Code == "" && asset.Issuer == "" {
				payWith = payWith.Through(b.NativeAsset())
			} else {
				payWith = payWith.Through(b.CreditAsset(asset.Code, asset.Issuer))
			}
		}

		payWithMutator = &payWith
	}

	mutators := []interface{}{
		b.Destination{destinationObject.AccountID},
		b.CreditAmount{
			request.AssetCode,
			request.AssetIssuer,
			request.Amount,
		},
	}

	if payWithMutator != nil {
		mutators = append(mutators, *payWithMutator)
	}

	operationMutator := b.Payment(mutators...)
	if operationMutator.Err != nil {
		log.WithFields(log.Fields{
			"err": operationMutator.Err,
		}).Error("Error creating operation")
		server.Write(w, protocols.InternalServerError)
		return
	}

	// Fetch Sender Info
	senderInfo := ""

	if rh.Config.Callbacks.FetchInfo != "" {
		fetchInfoRequest := compliance.FetchInfoRequest{Address: request.Sender}
		resp, err := rh.Client.PostForm(
			rh.Config.Callbacks.FetchInfo,
			fetchInfoRequest.ToValues(),
		)
		if err != nil {
			log.WithFields(log.Fields{
				"fetch_info": rh.Config.Callbacks.FetchInfo,
				"err":        err,
			}).Error("Error sending request to fetch_info server")
			server.Write(w, protocols.InternalServerError)
			return
		}

		defer resp.Body.Close()
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			log.WithFields(log.Fields{
				"fetch_info": rh.Config.Callbacks.FetchInfo,
				"err":        err,
			}).Error("Error reading fetch_info server response")
			server.Write(w, protocols.InternalServerError)
			return
		}

		if resp.StatusCode != http.StatusOK {
			log.WithFields(log.Fields{
				"fetch_info": rh.Config.Callbacks.FetchInfo,
				"status":     resp.StatusCode,
				"body":       string(body),
			}).Error("Error response from fetch_info server")
			server.Write(w, protocols.InternalServerError)
			return
		}

		senderInfo = string(body)
	}

	memoPreimage := &memo.Memo{
		Transaction: memo.Transaction{
			SenderInfo: senderInfo,
			Route:      request.Destination,
			Extra:      request.ExtraMemo,
		},
	}

	memoJSON := memoPreimage.Marshal()
	memoHashBytes := sha256.Sum256(memoJSON)
	memoMutator := &b.MemoHash{xdr.Hash(memoHashBytes)}

	transaction, err := submitter.BuildTransaction(
		request.Source,
		rh.Config.NetworkPassphrase,
		operationMutator,
		memoMutator,
	)

	var txBytes bytes.Buffer
	_, err = xdr.Marshal(&txBytes, transaction)
	if err != nil {
		log.Error("Error mashaling transaction")
		server.Write(w, protocols.InternalServerError)
		return
	}

	txBase64 := base64.StdEncoding.EncodeToString(txBytes.Bytes())

	authData := compliance.AuthData{
		Sender:   request.Sender,
		NeedInfo: rh.Config.NeedsAuth,
		Tx:       txBase64,
		Memo:     string(memoJSON),
	}

	data, err := json.Marshal(authData)
	if err != nil {
		log.Error("Error mashaling authData")
		server.Write(w, protocols.InternalServerError)
		return
	}

	sig, err := rh.SignatureSignerVerifier.Sign(rh.Config.Keys.SigningSeed, data)
	if err != nil {
		log.Error("Error signing authData")
		server.Write(w, protocols.InternalServerError)
		return
	}

	authRequest := compliance.AuthRequest{
		Data:      string(data),
		Signature: sig,
	}
	resp, err := rh.Client.PostForm(
		stellarToml.AuthServer,
		authRequest.ToValues(),
	)
	if err != nil {
		log.WithFields(log.Fields{
			"auth_server": stellarToml.AuthServer,
			"err":         err,
		}).Error("Error sending request to auth server")
		server.Write(w, protocols.InternalServerError)
		return
	}

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Error("Error reading auth server response")
		server.Write(w, protocols.InternalServerError)
		return
	}

	if resp.StatusCode != 200 {
		log.WithFields(log.Fields{
			"status": resp.StatusCode,
			"body":   string(body),
		}).Error("Error response from auth server")
		server.Write(w, protocols.InternalServerError)
		return
	}

	var authResponse compliance.AuthResponse
	err = json.Unmarshal(body, &authResponse)
	if err != nil {
		log.WithFields(log.Fields{
			"status": resp.StatusCode,
			"body":   string(body),
		}).Error("Error unmarshalling auth response")
		server.Write(w, protocols.InternalServerError)
		return
	}

	response := compliance.SendResponse{
		AuthResponse:   authResponse,
		TransactionXdr: txBase64,
	}
	server.Write(w, &response)
}
<commit_msg>Use the federation memo for the "route" value in the memo protocol<commit_after>package handlers

import (
	"bytes"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"io/ioutil"
	"net/http"

	log "github.com/Sirupsen/logrus"
	"github.com/stellar/gateway/protocols"
	"github.com/stellar/gateway/protocols/compliance"
	"github.com/stellar/gateway/protocols/memo"
	"github.com/stellar/gateway/server"
	"github.com/stellar/gateway/submitter"
	b "github.com/stellar/go-stellar-base/build"
	"github.com/stellar/go-stellar-base/xdr"
	"github.com/zenazn/goji/web"
)

// HandlerSend implements /send endpoint
func (rh *RequestHandler) HandlerSend(c web.C, w http.ResponseWriter, r *http.Request) {
	request := &compliance.SendRequest{}
	request.FromRequest(r)

	err := request.Validate()
	if err != nil {
		errorResponse := err.(*protocols.ErrorResponse)
		log.WithFields(errorResponse.LogData).Error(errorResponse.Error())
		server.Write(w, errorResponse)
		return
	}

	destinationObject, stellarToml, err := rh.FederationResolver.Resolve(request.Destination)
	if err != nil {
		log.WithFields(log.Fields{
			"destination": request.Destination,
			"err":         err,
		}).Print("Cannot resolve address")
		server.Write(w, compliance.CannotResolveDestination)
		return
	}

	if stellarToml.AuthServer == "" {
		log.Print("No AUTH_SERVER in stellar.toml")
		server.Write(w, compliance.AuthServerNotDefined)
		return
	}

	var payWithMutator *b.PayWithPath

	if request.SendMax != "" {
		// Path payment
		var sendAsset b.Asset
		if request.SendAssetCode != "" && request.SendAssetIssuer != "" {
			sendAsset = b.CreditAsset(request.SendAssetCode, request.SendAssetIssuer)
		} else if request.SendAssetCode == "" && request.SendAssetIssuer == "" {
			sendAsset = b.NativeAsset()
		} else {
			log.Print("Missing send asset param.")
			server.Write(w, protocols.MissingParameterError)
			return
		}

		payWith := b.PayWith(sendAsset, request.SendMax)

		for _, asset := range request.Path {
			if asset.Code == "" && asset.Issuer == "" {
				payWith = payWith.Through(b.NativeAsset())
			} else {
				payWith = payWith.Through(b.CreditAsset(asset.Code, asset.Issuer))
			}
		}

		payWithMutator = &payWith
	}

	mutators := []interface{}{
		b.Destination{destinationObject.AccountID},
		b.CreditAmount{
			request.AssetCode,
			request.AssetIssuer,
			request.Amount,
		},
	}

	if payWithMutator != nil {
		mutators = append(mutators, *payWithMutator)
	}

	operationMutator := b.Payment(mutators...)
	if operationMutator.Err != nil {
		log.WithFields(log.Fields{
			"err": operationMutator.Err,
		}).Error("Error creating operation")
		server.Write(w, protocols.InternalServerError)
		return
	}

	// Fetch Sender Info
	senderInfo := ""

	if rh.Config.Callbacks.FetchInfo != "" {
		fetchInfoRequest := compliance.FetchInfoRequest{Address: request.Sender}
		resp, err := rh.Client.PostForm(
			rh.Config.Callbacks.FetchInfo,
			fetchInfoRequest.ToValues(),
		)
		if err != nil {
			log.WithFields(log.Fields{
				"fetch_info": rh.Config.Callbacks.FetchInfo,
				"err":        err,
			}).Error("Error sending request to fetch_info server")
			server.Write(w, protocols.InternalServerError)
			return
		}

		defer resp.Body.Close()
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			log.WithFields(log.Fields{
				"fetch_info": rh.Config.Callbacks.FetchInfo,
				"err":        err,
			}).Error("Error reading fetch_info server response")
			server.Write(w, protocols.InternalServerError)
			return
		}

		if resp.StatusCode != http.StatusOK {
			log.WithFields(log.Fields{
				"fetch_info": rh.Config.Callbacks.FetchInfo,
				"status":     resp.StatusCode,
				"body":       string(body),
			}).Error("Error response from fetch_info server")
			server.Write(w, protocols.InternalServerError)
			return
		}

		senderInfo = string(body)
	}

	memoPreimage := &memo.Memo{
		Transaction: memo.Transaction{
			SenderInfo: senderInfo,
			Route:      destinationObject.Memo,
			Extra:      request.ExtraMemo,
		},
	}

	memoJSON := memoPreimage.Marshal()
	memoHashBytes := sha256.Sum256(memoJSON)
	memoMutator := &b.MemoHash{xdr.Hash(memoHashBytes)}

	transaction, err := submitter.BuildTransaction(
		request.Source,
		rh.Config.NetworkPassphrase,
		operationMutator,
		memoMutator,
	)

	var txBytes bytes.Buffer
	_, err = xdr.Marshal(&txBytes, transaction)
	if err != nil {
		log.Error("Error mashaling transaction")
		server.Write(w, protocols.InternalServerError)
		return
	}

	txBase64 := base64.StdEncoding.EncodeToString(txBytes.Bytes())

	authData := compliance.AuthData{
		Sender:   request.Sender,
		NeedInfo: rh.Config.NeedsAuth,
		Tx:       txBase64,
		Memo:     string(memoJSON),
	}

	data, err := json.Marshal(authData)
	if err != nil {
		log.Error("Error mashaling authData")
		server.Write(w, protocols.InternalServerError)
		return
	}
	sig, err := rh.SignatureSignerVerifier.Sign(rh.Config.Keys.SigningSeed, data)
	if err != nil {
		log.Error("Error signing authData")
		server.Write(w, protocols.InternalServerError)
		return
	}

	authRequest := compliance.AuthRequest{
		Data:      string(data),
		Signature: sig,
	}
	resp, err := rh.Client.PostForm(
		stellarToml.AuthServer,
		authRequest.ToValues(),
	)
	if err != nil {
		log.WithFields(log.Fields{
			"auth_server": stellarToml.AuthServer,
			"err":         err,
		}).Error("Error sending request to auth server")
		server.Write(w, protocols.InternalServerError)
		return
	}

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Error("Error reading auth server response")
		server.Write(w, protocols.InternalServerError)
		return
	}

	if resp.StatusCode != 200 {
		log.WithFields(log.Fields{
			"status": resp.StatusCode,
			"body":   string(body),
		}).Error("Error response from auth server")
		server.Write(w, protocols.InternalServerError)
		return
	}

	var authResponse compliance.AuthResponse
	err = json.Unmarshal(body, &authResponse)
	if err != nil {
		log.WithFields(log.Fields{
			"status": resp.StatusCode,
			"body":   string(body),
		}).Error("Error unmarshalling auth response")
		server.Write(w, protocols.InternalServerError)
		return
	}

	response := compliance.SendResponse{
		AuthResponse:   authResponse,
		TransactionXdr: txBase64,
	}
	server.Write(w, &response)
}
<|endoftext|>


<commit_before>package session

import (
	"fmt"
	"net/http"
	"time"

	"code.google.com/p/go.net/context"
	"github.com/dgrijalva/jwt-go"
	"github.com/drone/config"
	"github.com/drone/drone/server/datastore"
	"github.com/drone/drone/shared/httputil"
	"github.com/drone/drone/shared/model"
	"github.com/gorilla/securecookie"
)

// random key used to create jwt if none
// provided in the configuration.
var random = securecookie.GenerateRandomKey(32)

var (
	secret  = config.String("session-secret", string(random))
	expires = config.Duration("session-expires", time.Hour*72)
)

// GetUser gets the currently authenticated user for the
// http.Request. The user details will be stored as either
// a simple API token or JWT bearer token.
func GetUser(c context.Context, r *http.Request) *model.User {
	switch {
	case r.Header.Get("Authorization") != "":
		return getUserBearer(c, r)
	case r.FormValue("access_token") != "":
		return getUserToken(c, r)
	default:
		return nil
	}
}

// GenerateToken generates a JWT token for the user session
// that can be appended to the #access_token segment to
// facilitate client-based OAuth2.
func GenerateToken(c context.Context, r *http.Request, user *model.User) (string, error) {
	token := jwt.New(jwt.GetSigningMethod("HS256"))
	token.Claims["user_id"] = user.ID
	token.Claims["audience"] = httputil.GetURL(r)
	token.Claims["expires"] = time.Now().UTC().Add(time.Hour * 72).Unix()
	return token.SignedString([]byte(*secret))
}

// getUserToken gets the currently authenticated user for the given
// auth token.
func getUserToken(c context.Context, r *http.Request) *model.User {
	var token = r.FormValue("access_token")
	var user = getUserJwtToken(c, token)
	// TODO: is it needed to fallback to user_token query?
	if user == nil {
		user, _ = datastore.GetUserToken(c, token)
	}
	return user
}

// getUserBearer gets the currently authenticated user for the given
// bearer token (JWT)
func getUserBearer(c context.Context, r *http.Request) *model.User {
	var tokenstr = r.Header.Get("Authorization")
	fmt.Sscanf(tokenstr, "Bearer %s", &tokenstr)
	var user = getUserJwtToken(c, tokenstr)
	return user
}

// getUserAccessToken gets the currently authenticated user for the given
// auth token in jwt format.
func getUserJwtToken(c context.Context, tokenstr string) *model.User {
	var token, err = jwt.Parse(tokenstr, func(t *jwt.Token) (interface{}, error) {
		return []byte(*secret), nil
	})
	if err != nil || !token.Valid {
		return nil
	}
	var userid, ok = token.Claims["user_id"].(float64)
	if !ok {
		return nil
	}
	var user, _ = datastore.GetUser(c, int64(userid))
	return user
}
<commit_msg>minor session refactoring in prep for upcoming changes discussed in #590<commit_after>package session

import (
	"fmt"
	"net/http"
	"time"

	"code.google.com/p/go.net/context"
	"github.com/dgrijalva/jwt-go"
	"github.com/drone/config"
	"github.com/drone/drone/server/datastore"
	"github.com/drone/drone/shared/httputil"
	"github.com/drone/drone/shared/model"
	"github.com/gorilla/securecookie"
)

// random key used to create jwt if none
// provided in the configuration.
var random = securecookie.GenerateRandomKey(32)

var (
	secret  = config.String("session-secret", string(random))
	expires = config.Duration("session-expires", time.Hour*72)
)

// GetUser gets the currently authenticated user for the
// http.Request. The user details will be stored as either
// a simple API token or JWT bearer token.
func GetUser(c context.Context, r *http.Request) *model.User {
	switch {
	case r.Header.Get("Authorization") != "":
		return getUserBearer(c, r)
	case r.FormValue("access_token") != "":
		return getUserToken(c, r)
	default:
		return nil
	}
}

// GenerateToken generates a JWT token for the user session
// that can be appended to the #access_token segment to
// facilitate client-based OAuth2.
func GenerateToken(c context.Context, r *http.Request, user *model.User) (string, error) {
	token := jwt.New(jwt.GetSigningMethod("HS256"))
	token.Claims["user_id"] = user.ID
	token.Claims["audience"] = httputil.GetURL(r)
	token.Claims["expires"] = time.Now().UTC().Add(time.Hour * 72).Unix()
	return token.SignedString([]byte(*secret))
}

// getUserToken gets the currently authenticated user for the given
// auth token.
func getUserToken(c context.Context, r *http.Request) *model.User {
	var token = r.FormValue("access_token")
	var user = getUserJWT(c, token)
	if user != nil {
		return user
	}
	user, _ = datastore.GetUserToken(c, token)
	return user
}

// getUserBearer gets the currently authenticated user for the given
// bearer token (JWT)
func getUserBearer(c context.Context, r *http.Request) *model.User {
	var tokenstr = r.Header.Get("Authorization")
	fmt.Sscanf(tokenstr, "Bearer %s", &tokenstr)
	return getUserJWT(c, tokenstr)
}

// getUserJWT is a helper function that parses the User ID
// and retrieves the User data from a JWT Token.
func getUserJWT(c context.Context, token string) *model.User {
	var t, err = jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {
		return []byte(*secret), nil
	})
	if err != nil || !t.Valid {
		return nil
	}
	var userid, ok = t.Claims["user_id"].(float64)
	if !ok {
		return nil
	}
	var user, _ = datastore.GetUser(c, int64(userid))
	return user
}
<|endoftext|>


<commit_before>/*
 * Cryptographically strong source of randomness: Based on the
 * io.Reader instance assigned to "rand.Reader"; usually "/dev/urandom"
 *
 * (c) 2012 Bernd Fix   >Y<
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package crypto

///////////////////////////////////////////////////////////////////////
// Import external declarations.

import (
	"crypto/rand"
	"math/big"
)

///////////////////////////////////////////////////////////////////////
// Cryptographically strong source of random bits

/*
 * Source of randomness:
 */
type prng struct {
	mask	*big.Int
}

//=====================================================================
/*
 * Get next (unsigned) 64-bit integer value.
 * @return int64 - random integer
 */
func (p *prng) Int63() int64 {

	val,err := rand.Int (rand.Reader, mask)
	if err != nil {
		panic("PRNG failure: " + err.Error())
	}
	return val.Int64()
}

//---------------------------------------------------------------------
/*
 * Seeding a source: not necessary, because random bits are generated
 * on a system level by either a hardware RNG or a cryptographically
 * secure PRNG algorithm.
 * @param seed int64 - seeding value
 */
func (p *prng) Seed(seed int64) {
	// intentionally not implemented
}

//=====================================================================
/*
 * Instantiate a new source for random bits.
 * @return *prng - reference to rand.Source instance
 */
func NewPrngSource() *prng {
	return &prng {
		mask:	new(big.Int).Lsh (big.NewInt(1), 63),
	}
}
<commit_msg>Fixed mask bug.<commit_after>/*
 * Cryptographically strong source of randomness: Based on the
 * io.Reader instance assigned to "rand.Reader"; usually "/dev/urandom"
 *
 * (c) 2012 Bernd Fix   >Y<
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package crypto

///////////////////////////////////////////////////////////////////////
// Import external declarations.

import (
	"crypto/rand"
	"math/big"
)

///////////////////////////////////////////////////////////////////////
// Cryptographically strong source of random bits

/*
 * Source of randomness:
 */
type prng struct {
	mask	*big.Int
}

//=====================================================================
/*
 * Get next (unsigned) 64-bit integer value.
 * @return int64 - random integer
 */
func (p *prng) Int63() int64 {

	val,err := rand.Int (rand.Reader, p.mask)
	if err != nil {
		panic("PRNG failure: " + err.Error())
	}
	return val.Int64()
}

//---------------------------------------------------------------------
/*
 * Seeding a source: not necessary, because random bits are generated
 * on a system level by either a hardware RNG or a cryptographically
 * secure PRNG algorithm.
 * @param seed int64 - seeding value
 */
func (p *prng) Seed(seed int64) {
	// intentionally not implemented
}

//=====================================================================
/*
 * Instantiate a new source for random bits.
 * @return *prng - reference to rand.Source instance
 */
func NewPrngSource() *prng {
	return &prng {
		mask:	new(big.Int).Lsh (big.NewInt(1), 63),
	}
}
<|endoftext|>


<commit_before>package tracer

import (
// 	"errors"
	"fmt"
	"io"
	"os"
)

const (
	k_FATAL	= "FATAL: "
	k_ERROR = "E: "
	k_WARNING="W: "
	k_TRACE	= "TRACE%d:: "
)

var (
	threshold	uint = 0
	x1	io.Writer
	x2	io.Writer

)

func init() {
	x1 = os.Stdout
	x2 = os.Stderr
}

func SetLevel(x int) uint {
	o := threshold
	if x < 0 {
		threshold = 0
	} else {
		threshold = uint(x)
	}
	return o
}

func SetupTrace(out io.Writer, n uint) {
	if nil != out {
		x1 = out
	}
	threshold = n
}

func Fatal(x string) {
	// FATAL: ...
	fmt.Fprintf(x2, k_FATAL)
	fmt.Fprintln(x2, x)
	os.Exit(255)
}

func FatalErr(e error) {
	// FATAL: ...
	fmt.Fprintf(x2, k_FATAL)
	fmt.Fprintln(x2, e.Error())
	fmt.Fprintln(x2, "")
	os.Exit(255)
}

func Error(x string) {
	fmt.Fprintf(x2, k_ERROR)
	fmt.Fprintln(x2, x)
}

func Warn(x string) {
	fmt.Fprintf(x2, k_WARNING)
	fmt.Fprintln(x2, x)
}

func Trace(n uint, s string) {
	if n > threshold {
		return
	}
	fmt.Fprintf(x1, k_TRACE, n)
	fmt.Fprint(x1, s)
}

func TraceV(n uint, s string, x ...interface{}) {
	if n > threshold {
		return
	}
	fmt.Fprintf(x1, k_TRACE, n)
	fmt.Fprint(x1, s)
	for _,v := range x {
		fmt.Fprint(x1,v)
	}
	fmt.Fprintln(x1)
}
<commit_msg>tracer: minor output formatting improvement<commit_after>package tracer

import (
// 	"errors"
	"fmt"
	"io"
	"os"
)

const (
	k_FATAL	= "FATAL: "
	k_ERROR = "E: "
	k_WARNING="W: "
	k_TRACE	= "TRACE%u"
)

var (
	threshold	uint = 0
	x1	io.Writer
	x2	io.Writer

)

func init() {
	x1 = os.Stdout
	x2 = os.Stderr
}

func SetLevel(x int) uint {
	o := threshold
	if x < 0 {
		threshold = 0
	} else {
		threshold = uint(x)
	}
	return o
}

func SetupTrace(out io.Writer, n uint) {
	if nil != out {
		x1 = out
	}
	threshold = n
}

func Fatal(x string) {
	// FATAL: ...
	fmt.Fprintf(x2, k_FATAL)
	fmt.Fprintln(x2, x)
	os.Exit(255)
}

func FatalErr(e error) {
	// FATAL: ...
	fmt.Fprintf(x2, k_FATAL)
	fmt.Fprintln(x2, e.Error())
	fmt.Fprintln(x2, "")
	os.Exit(255)
}

func Error(x string) {
	fmt.Fprintf(x2, k_ERROR)
	fmt.Fprintln(x2, x)
}

func Warn(x string) {
	fmt.Fprintf(x2, k_WARNING)
	fmt.Fprintln(x2, x)
}

func Trace(n uint, s string) {
	if n > threshold {
		return
	}
	fmt.Fprintf(x1, k_TRACE, n)
	fmt.Fprint(x1, s)
}

func TraceV(n uint, s string, x ...interface{}) {
	if n > threshold {
		return
	}
	fmt.Fprintf(x1, k_TRACE, n)
	fmt.Fprint(x1, s)
	for _,v := range x {
		fmt.Fprint(x1,v)
	}
}
<|endoftext|>