123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- /*
- * pixiv_down - CLI-based downloading tool for https://www.pixiv.net.
- * Copyright (C) 2023, 2024 Mio
- *
- * 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, version 3 of the License.
- *
- * 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 <https://www.gnu.org/licenses/>.
- */
- module app.util;
- ///
- /// Attempt to make *path* safe for different operating systems.
- ///
- /// This will replace anything that is not: a hyphen ('-'), a period ('.'),
- /// an underscore ('_'), or a "word character" (includes numbers). Any
- /// characters found will be replaced by a hyphen.
- ///
- /// Only tested on Linux and Android.
- ///
- /// Params:
- /// path = The input path to replace characters with.
- ///
- /// Returns: A new string with the replacements made.
- ///
- string makeSafe(string path)
- {
- import std.regex : regex, replaceAll;
- import std.string : chomp, replace, strip;
- enum kReplacement = "-";
- // 2.076 compat: reg must not be 'const'. Doesn't work with replaceAll.
- auto reg = regex(`[^-\w._]`);
- const noSpaces = strip(path).replace(" ", kReplacement);
- const almostSafe = replaceAll(noSpaces, reg, kReplacement);
- return chomp(almostSafe, "._-");
- }
- string[] split(string self, char delimiter, int limit) {
- import std.string : indexOf;
- string[] sections;
- ptrdiff_t pointer = 0;
- ptrdiff_t lastPointer = 0;
- while ((pointer = indexOf(self, delimiter, lastPointer)) != -1) {
- if (sections.length < limit - 1) {
- sections ~= self[lastPointer..pointer];
- lastPointer = pointer + 1;
- } else {
- sections ~= self[lastPointer..$];
- pointer = self.length;
- break;
- }
- }
- if (sections.length == 0) {
- return [self];
- }
- // Final section (mainly if limit == 2)
- if (sections.length < limit) {
- sections ~= self[lastPointer..$];
- }
- return sections;
- }
- ///
- unittest
- {
- import std.format;
- pragma(inline, true)
- void assertEquals(T)(T t1, T t2) {
- assert(t1 == t2, format("Values not equal.\n\tExpected: %s\n\t Actual: %s", t1, t2));
- }
- const noMatch = "no-matches";
- const parts = noMatch.split(' ', 2);
- assertEquals(1, parts.length);
- assertEquals(noMatch, parts[0]);
- const option = "--flag=value";
- const argAndValue = option.split('=', 2);
- assertEquals(2, argAndValue.length);
- assertEquals("--flag", argAndValue[0]);
- assertEquals("value", argAndValue[1]);
- const str = "zero-one-two-three-four-five";
- const numbers = str.split('-', 3);
- assertEquals(3, numbers.length);
- assertEquals("zero", numbers[0]);
- assertEquals("one", numbers[1]);
- assertEquals("two-three-four-five", numbers[2]);
- }
- /**
- * Suspend the current thread for a random value between *lowest* and
- * *largest*.
- *
- * Params:
- * lowest = The lowest value to use for the random sleep duration.
- * largest = The largest value to use for the random sleep duration.
- * print = Print a message to `stderr` with sleep duration.
- */
- void sleep(int lowest, int largest, bool print = true)
- {
- import core.thread : Thread;
- import core.time : seconds;
- import std.random : Random, uniform, unpredictableSeed;
- auto seed = Random(unpredictableSeed);
- const secs = uniform(lowest, largest + 1, seed);
- if (print) {
- import std.stdio : stderr;
- stderr.writefln("Sleeping for %d seconds...", secs);
- }
- Thread.sleep(secs.seconds);
- }
|