Ejemplo n.º 1
0
 /// <summary>
 /// Парсит и преобразовывает указанную строку, представляющую URI, 
 /// и возвращает результат операции через выводной параметр
 /// </summary>
 /// <param name="Input"></param>
 /// <param name="ErrorMessage"></param>
 /// <returns></returns>
 public static Uri TryParseURI(String Input, out String ErrorMessage)
 {
     ErrorMessage = null;
     if (Input.HasAlphaNumericChars() == false)
     {
         ErrorMessage = "Input string has no any alphanumeric character";
         return null;
     }
     Input = Input.CleanString().Trim();
     if (Input.StartsWith("http://", StringComparison.OrdinalIgnoreCase) == false)
     {
         Input = "http://" + Input;
     }
     Uri input_URI;
     Boolean result = Uri.TryCreate(Input, UriKind.Absolute, out input_URI);
     if (result == false)
     {
         ErrorMessage = "Input string is invalid URI";
         return null;
     }
     if (input_URI.Scheme.Equals("http", StringComparison.OrdinalIgnoreCase)==false)
     {
         ErrorMessage = "Only HTTP scheme is valid, but not " + input_URI.Scheme;
         return null;
     }
     if (input_URI.Authority.Equals("myzuka.ru", StringComparison.OrdinalIgnoreCase)==false)
     {
         ErrorMessage = "Only myzuka.ru domain is supported, but not " + input_URI.Authority;
         return null;
     }
     if (input_URI.Segments.Length < 4)
     {
         ErrorMessage = "URI is invalid";
         return null;
     }
     String segment1 = input_URI.Segments[1];
     if (segment1.Trim('/').IsIn(StringComparison.OrdinalIgnoreCase, "album", "song") == false)
     {
         ErrorMessage = "First segment of URI - '"+segment1+"', is invalid";
         return null;
     }
     String segment2 = input_URI.Segments[2];
     if (segment2.Trim('/').TryParseNumber<UInt32>(NumberStyles.None, null)==null)
     {
         ErrorMessage = "Second segment of URI - '" + segment2 + "', is invalid";
         return null;
     }
     return input_URI;
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Создаёт и возвращает новое задание по скачиванию указанных песен и последующему сохранению их на диск по указанному пути
 /// </summary>
 /// <param name="Songs">Список всех хидеров песен, файлы песен для которых следует скачать и вернуть. 
 /// Не может быть NULL или пустым.</param>
 /// <param name="UserAgent">User-Agent, который будет использоваться при выполнении запросов</param>
 /// <param name="FolderPath">Существующий путь на диске, по которому будут сохранены песни. 
 /// Если NULL, некорректный или не существует, будет выброшено исключение.</param>
 /// <param name="GenerateNewFilenames">Определяет, следует ли генерировать новое имя файла на основании тэгов песни (true), 
 /// или же использовать то имя файла, которое "пришло" с сервера (false). Если будет указана генерация нового, однако 
 /// получившееся имя будет некорректным, метод попытается его исправить. 
 /// Если же исправить не получится, будет использовано имя с сервера.</param>
 /// <param name="FilenameTemplate">Шаблон имени файла песни</param>
 /// <returns></returns>
 public static ReactiveDownloader CreateTask
     (IList<OneSongHeader> Songs, String UserAgent, String FolderPath, Boolean GenerateNewFilenames, String FilenameTemplate)
 {
     if (UserAgent.HasAlphaNumericChars() == false) { throw new ArgumentException("User-Agent не может быть пустым", "UserAgent"); }
     if (FilePathTools.IsValidFilePath(FolderPath) == false)
     {
         throw new ArgumentException
             ("Путь для сохранения файлов песен = '" + FolderPath.ToStringS("NULL") + "' некорректен", "FolderPath");
     }
     if(Songs == null) {throw new ArgumentNullException("Songs");}
     if(Songs.Any()==false) {throw new ArgumentException("Список песен для обработки не может быть пустым", "Songs");}
     if(GenerateNewFilenames == true && FilenameTemplate.HasAlphaNumericChars()==false)
     {throw new ArgumentException("Шаблон имени файла не может быть пуст, если требуется клиентская генерация имён файлов");}
     return new ReactiveDownloader(Songs, UserAgent, FolderPath, GenerateNewFilenames, FilenameTemplate);
 }
 public Boolean HasAlphaNumericCharsTest(String input)
 {
     return input.HasAlphaNumericChars();
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Возвращает текстовые данные, вычленяя их из части HTML-кода
 /// </summary>
 /// <param name="Input"></param>
 /// <returns></returns>
 private static String ExtractFromHTML(String Input)
 {
     if(Input.HasAlphaNumericChars()==false) 
     {throw new ArgumentException("Входная строка не содержит цифробуквенных символов", "Input");}
     String temp = Input.MultiReplace(' ', new char[]{'\r', '\n', '\t'}).Trim();
     temp = KlotosLib.HtmlTools.IntelliRemoveHTMLTags(temp);
     temp = StringTools.SubstringHelpers.ShrinkSpaces(temp).Trim();
     temp = HttpUtility.HtmlDecode(temp);
     return temp;
 }
Ejemplo n.º 5
0
 /// <summary>
 /// Пытается очистить от шелухи и возвратить URI
 /// </summary>
 /// <param name="Input"></param>
 /// <param name="ErrorMessage"></param>
 /// <returns></returns>
 internal static Uri TryFixReturnURI(String Input, out String ErrorMessage)
 {
     ErrorMessage = null;
     if (Input.HasAlphaNumericChars() == false)
     {
         ErrorMessage = "URI = '" + Input.ToStringS("NULL") + "' заведомо некорректен";
         return null;
     }
     const String main_domain = "http://myzuka.ru";
     const String download_domain = "http://fp";
     String temp_URI = Input.Trim(new char[2] { ' ', '"' });
     if (temp_URI.StartsWith(main_domain, StringComparison.OrdinalIgnoreCase) == false &&
         temp_URI.StartsWith(download_domain, StringComparison.OrdinalIgnoreCase) == false)
     {
         temp_URI = main_domain + temp_URI;
     }
     temp_URI = HttpTools.DecodeUri(temp_URI);
     Uri link_URI;
     Boolean res = Uri.TryCreate(temp_URI, UriKind.Absolute, out link_URI);
     if (res == false)
     {
         ErrorMessage = String.Format(
           "Невозможно корректно распарсить как абсолютный URI подстроку '{0}', полученную из строки '{1}'",
           temp_URI, Input);
         return null;
     }
     return link_URI;
 }
Ejemplo n.º 6
0
        internal static Dictionary<String, String> TransactionalApply(Boolean UseDistinctFolder, Boolean UseServerFilenames,
            String MaxDownloadThreads, String SavedFilesPath, String UserAgent, String FilenameTemplate)
        {
            Dictionary<String, String> output = new Dictionary<string, string>();
            if (UserAgent.HasAlphaNumericChars() == false)
            {
                output.Add(UserAgent.MemberName(_ => UserAgent), "User-Agent can not be empty");
            }
            if (SavedFilesPath.HasAlphaNumericChars() == false)
            {
                output.Add(SavedFilesPath.MemberName(_ => SavedFilesPath), "File path for saving files can not be empty");
            }
            else if (FilePathTools.IsValidFilePath(SavedFilesPath) == false)
            {
                output.Add(SavedFilesPath.MemberName(_ => SavedFilesPath), "File path is invalid");
            }
            Nullable<Byte> mdt = MaxDownloadThreads.TryParseNumber<Byte>(NumberStyles.None, CultureInfo.InvariantCulture);
            if (mdt == null)
            {
                output.Add(MaxDownloadThreads.MemberName(_ => MaxDownloadThreads), "Value '" + MaxDownloadThreads+"' is invalid");
            }
            Char[] intersects = FilenameTemplate.ToCharArray().Intersect(Path.GetInvalidFileNameChars()).ToArray();
            if (intersects.IsNullOrEmpty()==false)
            {
                output.Add(FilenameTemplate.MemberName(_ => FilenameTemplate)+"1",
                    "Filename template contains next invalid characters: "+intersects.ConcatToString(", ")+".");
            }
            if (FilenameTemplate.Contains(_TITLE_TOKEN, StringComparison.Ordinal) == false &&
                FilenameTemplate.Contains(_NUMBER_TOKEN, StringComparison.Ordinal) == false)
            {
                output.Add(FilenameTemplate.MemberName(_ => FilenameTemplate)+"2",
                    "Filename template must contain "+_TITLE_TOKEN+" or "+_NUMBER_TOKEN+" token");
            }

            if (output.Any() == true)
            {
                return output;
            }
            Byte value = mdt.Value > (Byte)99 ? (Byte)99 : mdt.Value;
            ProgramSettings._instance =
                new ProgramSettings(UseDistinctFolder, UseServerFilenames, value, SavedFilesPath.Trim(), UserAgent.Trim(), FilenameTemplate.Trim());
            return null;
        }
Ejemplo n.º 7
0
 /// <summary>
 /// Декодирует URI, заменяя все escape-последовательности на небезопасные
 /// </summary>
 /// <param name="Input"></param>
 /// <returns></returns>
 public static String DecodeUri(String Input)
 {
     if (Input.HasAlphaNumericChars() == false) { return Input; }
     return HttpUtility.HtmlDecode(HttpUtility.UrlDecode(Input));
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Возвращает все атрибуты вместе с их соответствующими значениями для указанного по имени тэга. 
        /// Если тэгов несколько, будут возвращены атрибуты для первого встретившегося тэга.
        /// </summary>
        /// <param name="InputHTML">Входная HTML-содержащая строка. Не может быть NULL, пустой строкой или не содержать цифробуквенных символов.</param>
        /// <param name="TargetTagName">Имя целевого тэга, все атрибуты со значениями которого следует возвратить. 
        /// Не может быть NULL, пустой строкой или не содержать цифробуквенных символов.</param>
        /// <param name="StartIndex">Начальная позиция входной HTML-содержащей строки, с которой следует начать поиск. Если 0 - поиск ведётся с начала. 
        /// Если меньше 0 или больше длины исходной строки, выбрасывается исключение.</param>
        /// <returns>Список атрибутов вместе с их соответствующими значениями для указанного тэга в виде словаря, 
        /// где ключ - атрибут, а его значение - значение атрибута. Если целевой тэг не найден, возвращает NULL. 
        /// Если тэг найден, но он не содержит атрибутов, возвращается пустой словарь.</returns>
        public static Dictionary<String, String> GetAttributesForTag(String InputHTML, String TargetTagName, Int32 StartIndex)
        {
            if(InputHTML == null) {throw new ArgumentNullException("InputHTML");}
            if(InputHTML.HasAlphaNumericChars()==false)
            { throw new ArgumentException("Входная HTML-содержащая строка не содержит ни одной буквы или цифры и не является валидным HTML документом", "InputHTML"); }
            if (TargetTagName.HasAlphaNumericChars() == false)
            { throw new ArgumentException("Имя целевого тэга некорректно, так как не содержит ни одной буквы или цифры", "TargetTagName");}
            if (StartIndex < 0) { throw new ArgumentOutOfRangeException("StartIndex", StartIndex, "Начальная позиция не может быть меньше 0"); }
            if (StartIndex >= InputHTML.Length)
            { throw new ArgumentOutOfRangeException("StartIndex", StartIndex, String.Format("Начальная позиция ('{0}') не может быть больше или равна длине строки ('{1}')", StartIndex, InputHTML.Length)); }
            String cleared_tag_name = TargetTagName.Trim().ToLowerInvariant();
            if (cleared_tag_name.StartsWith("<") == false)
            {
                cleared_tag_name = "<" + cleared_tag_name;
            }
            Int32 tag_start_pos = InputHTML.IndexOf(cleared_tag_name, StartIndex, StringComparison.OrdinalIgnoreCase);
            if (tag_start_pos == -1)
            {
                return null;
            }
            Int32 closing_bracket_pos = InputHTML.IndexOf(">", tag_start_pos + cleared_tag_name.Length, StringComparison.OrdinalIgnoreCase);
            if (InputHTML[closing_bracket_pos - 1] == '/')
            {
                closing_bracket_pos = closing_bracket_pos - 1;
            }

            string substring_with_attributes = InputHTML.SubstringWithEnd(tag_start_pos + cleared_tag_name.Length, closing_bracket_pos, false, false, false).Trim();
            Dictionary<String, String> output = new Dictionary<String, String>(StringComparer.OrdinalIgnoreCase);
            if (substring_with_attributes.IsStringNullEmptyWhiteSpace())
            {
                return output;
            }
            StringBuilder attribute_key_buffer = new StringBuilder(substring_with_attributes.Length);
            StringBuilder attribute_value_buffer = new StringBuilder(substring_with_attributes.Length);
            
            Boolean key_is_now = true;
            Boolean value_is_now = false;
            Boolean found_equal_sign = false;
            Boolean finished_pair = false;
            Boolean inside_quotes = false;
            Boolean value_without_quotes = false;
            Boolean whitespace_previous = false;

            foreach (Char one in substring_with_attributes)
            {
                if (Char.IsWhiteSpace(one))
                {
                    whitespace_previous = true;
                    if (value_without_quotes == true)
                    {
                        value_without_quotes = false;
                        value_is_now = false;
                        key_is_now = false;
                    }
                    else if (value_is_now == true)
                    {
                        attribute_value_buffer.Append(one);
                    }
                    else
                    {
                        key_is_now = false;
                    }
                    continue;
                }
                if (one == '=')
                {
                    whitespace_previous = false;
                    if (inside_quotes && value_is_now)
                    {
                        attribute_value_buffer.Append(one);
                    }
                    else
                    {
                        key_is_now = false;
                        value_is_now = false;
                        found_equal_sign = true;
                    }
                    continue;
                }
                if (one == '"' || one == '\'')
                {
                    whitespace_previous = false;
                    inside_quotes = !inside_quotes;
                    if (found_equal_sign)
                    {
                        key_is_now = false;
                        value_is_now = true;
                    }
                    else
                    {
                        key_is_now = false;
                        value_is_now = false;

                        String attribute_key = attribute_key_buffer.ToString();
                        if (output.ContainsKey(attribute_key) == false)
                        {
                            output.Add(attribute_key, attribute_value_buffer.ToString());
                        }
                        attribute_key_buffer.Clean();
                        attribute_value_buffer.Clean();
                        finished_pair = true;
                    }
                    found_equal_sign = false;
                    continue;
                }
                if (value_is_now == false && found_equal_sign == false && inside_quotes == false && finished_pair == false && whitespace_previous == true)
                {
                    String attribute_key = attribute_key_buffer.ToString();
                    if (output.ContainsKey(attribute_key) == false)
                    {
                        output.Add(attribute_key, attribute_value_buffer.ToString());
                    }
                    attribute_key_buffer.Clean();
                    attribute_value_buffer.Clean();
                    finished_pair = true;
                }
                whitespace_previous = false;
                if (finished_pair == false && found_equal_sign == true && inside_quotes == false)
                {
                    found_equal_sign = false;
                    value_is_now = true;
                    value_without_quotes = true;
                }
                if (value_is_now)
                {
                    attribute_value_buffer.Append(one);
                    continue;
                }
                if (finished_pair)
                {
                    finished_pair = false;
                    key_is_now = true;
                }
                if ((Char.IsLetterOrDigit(one) || one == '-' || one == ':') && key_is_now)
                {
                    attribute_key_buffer.Append(one);
                    continue;
                }
            }
            if (attribute_key_buffer.Length > 0)
            {
                String attribute_key = attribute_key_buffer.ToString();
                if (output.ContainsKey(attribute_key) == false)
                {
                    output.Add(attribute_key, attribute_value_buffer.ToString());
                }
            }
            return output;
        }