commit 60c449feed0ddced600d7135766243e7058d683a Author: Erik C. Thauvin Date: Sat Mar 21 19:35:34 2020 -0700 Initial commit. diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..86b3b8f --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,55 @@ +version: 2 +defaults: &defaults + working_directory: ~/repo + environment: + JVM_OPTS: -Xmx3200m + TERM: dumb + CI: true + +defaults_gradle: &defaults_gradle + steps: + - checkout + - restore_cache: + keys: + - gradle-dependencies-{{ checksum "build.gradle.kts" }} + # fallback to using the latest cache if no exact match is found + - gradle-dependencies- + - run: + name: Gradle Dependencies + command: ./gradlew dependencies + - save_cache: + paths: ~/.m2 + key: gradle-dependencies-{{ checksum "build.gradle.kts" }} + - run: + name: Run All Checks + command: ./gradlew check + - store_artifacts: + path: build/reports/ + destination: reports + - store_test_results: + path: build/reports/ + +jobs: + build_gradle_jdk13: + <<: *defaults + + docker: + - image: openjdk:13-jdk + + <<: *defaults_gradle + + build_gradle_jdk8: + <<: *defaults + + docker: + - image: circleci/openjdk:8-jdk + + <<: *defaults_gradle + +workflows: + version: 2 + gradle: + jobs: + - build_gradle_jdk8 + - build_gradle_jdk13 + diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..a6971e1 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,2 @@ +[*] +insert_final_newline=true diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6ec2ae2 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto + +# batch files are specific to windows and always crlf +*.bat eol=crlf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f007981 --- /dev/null +++ b/.gitignore @@ -0,0 +1,84 @@ +.vscode/* +!.vscode/extensions.json +!.vscode/launch.json +!.vscode/settings.json +!.vscode/tasks.json + +__pycache__ +.classpath +.DS_Store +.gradle +.history +.kobalt +.mtj.tmp/ +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +.nb-gradle +.project +.scannerwork +.settings +*.class +*.code-workspace +*.ctxt +*.iws +*.log +*.nar +*.rar +*.sublime-* +*.tar.gz +*.zip +/**/.idea_modules/ +/**/.idea/**/caches/build_file_checksums.ser +/**/.idea/**/contentModel.xml +/**/.idea/**/dataSources.ids +/**/.idea/**/dataSources.local.xml +/**/.idea/**/dataSources/ +/**/.idea/**/dbnavigator.xml +/**/.idea/**/dictionaries +/**/.idea/**/dynamic.xml +/**/.idea/**/gradle.xml +/**/.idea/**/httpRequests +/**/.idea/**/libraries +/**/.idea/**/mongoSettings.xml +/**/.idea/**/replstate.xml +/**/.idea/**/shelf +/**/.idea/**/shelf/ +/**/.idea/**/sqlDataSources.xml +/**/.idea/**/tasks.xml +/**/.idea/**/uiDesigner.xml +/**/.idea/**/usage.statistics.xml +/**/.idea/**/workspace.xml +/**/.idea/$CACHE_FILE$ +/**/.idea/$PRODUCT_WORKSPACE_FILE$ +atlassian-ide-plugin.xml +bin/ +build/ +cmake-build-*/ +com_crashlytics_export_strings.xml +crashlytics-build.properties +crashlytics.properties +dependency-reduced-pom.xml +deploy/ +dist/ +ehthumbs.db +fabric.properties +gen/ +gradle.properties +hs_err_pid* +kobaltBuild +kobaltw*-test +lib/kotlin* +libs/ +local.properties +out/ +pom.xml.next +pom.xml.releaseBackup +pom.xml.tag +pom.xml.versionsBackup +proguard-project.txt +project.properties +release.properties +target/ +test-output +Thumbs.db +venv diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..61a9130 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/copyright/Erik_s_Copyright_Notice.xml b/.idea/copyright/Erik_s_Copyright_Notice.xml new file mode 100644 index 0000000..08660a1 --- /dev/null +++ b/.idea/copyright/Erik_s_Copyright_Notice.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..1419e40 --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..9c38803 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,50 @@ + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..d6c5981 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..f126aa3 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/isgd-shorten_main.iml b/.idea/modules/isgd-shorten_main.iml new file mode 100644 index 0000000..e5db6f3 --- /dev/null +++ b/.idea/modules/isgd-shorten_main.iml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules/isgd-shorten_test.iml b/.idea/modules/isgd-shorten_test.iml new file mode 100644 index 0000000..13cc4d1 --- /dev/null +++ b/.idea/modules/isgd-shorten_test.iml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..86e6f1a --- /dev/null +++ b/.travis.yml @@ -0,0 +1,26 @@ +language: java +dist: trusty + +env: + global: + - CI=true + +#install: +# - git fetch --unshallow --tags + +addons: + sonarcloud: + organization: "ethauvin-github" + +jdk: + - oraclejdk8 + - openjdk13 + +before_install: + - chmod +x gradlew + +after_success: + - | + if [ "${TRAVIS_TEST_RESULT}" == 0 ] && [ "$TRAVIS_JDK_VERSION" == oraclejdk8 ]; then + ./gradlew sonarqube + fi diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..2fadd27 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,27 @@ +Copyright (c) 2020, Erik C. Thauvin (erik@thauvin.net) +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of this project nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..5fcf727 --- /dev/null +++ b/README.md @@ -0,0 +1,55 @@ +[![License (3-Clause BSD)](https://img.shields.io/badge/license-BSD%203--Clause-blue.svg?style=flat-square)](http://opensource.org/licenses/BSD-3-Clause) +[![Known Vulnerabilities](https://snyk.io/test/github/ethauvin/isgd-shorten/badge.svg?targetFile=pom.xml)](https://snyk.io/test/github/ethauvin/isgd-shorten?targetFile=pom.xml) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=ethauvin_isgd-shorten&metric=alert_status)](https://sonarcloud.io/dashboard?id=ethauvin_isgd-shorten) [![Build Status](https://travis-ci.org/ethauvin/isgd-shorten.svg?branch=master)](https://travis-ci.org/ethauvin/isgd-shorten) [![CircleCI](https://circleci.com/gh/ethauvin/isgd-shorten/tree/master.svg?style=shield)](https://circleci.com/gh/ethauvin/isgd-shorten/tree/master) + +# [is.gd](https://is.gd/developers.php) Shortener for Kotlin/Java. + +A simple implementation of the [is.gd API](https://is.gd/developers.php). + +## Examples (TL;DR) + +```kotlin +import net.thauvin.erik.isgd.Isgd + +... + +Isgd.shorten("https://www.example.com/") // returns https://is.gd/Pt2sET +Isgd.lookup("https://is.gd/Pt2sET") // returns https://www.example.com + +``` + + - View [Kotlin](https://github.com/ethauvin/isgd-shorten/blob/master/examples/src/main/kotlin/com/example/IsgdExample.kt) or [Java](https://github.com/ethauvin/isgd-shorten/blob/master/examples/src/main/java/com/example/IsgdSample.java) Examples. + + +### JSON or XML + +The [is.gd API](https://is.gd/developers.php) can return data in plain text (default), JSON or XML. + +```kotlin +Isgd.shorten("https://www.example.com/", format = Format.JSON) +``` +```json +{ + "shorturl": "https://is.gd/Pt2sET" +} +``` + +### Parameters + +All of the [is.gd API](https://is.gd/developers.php) parameters are supported: + +```kotlin +Isgd.shorten(url = url, shorturl="foobar", callback = "test", logstats = true, format = Format.JSON) +``` +```json +{ + "shorturl": "https://is.gd/foobar" +} +``` + +### v.gd + +Additionally, link can be shorten using v.gd by setting the `isVgd` flag: + +```kotlin +Isgd.shorten("https://www.example.com/", isVgd = true) // returns https://v.gd/2z2ncj +``` diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..cd7eb3d --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,230 @@ +import com.jfrog.bintray.gradle.tasks.BintrayUploadTask +import org.jetbrains.dokka.gradle.DokkaTask +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import java.io.FileInputStream +import java.util.Properties + +plugins { + jacoco + `java-library` + `maven-publish` + id("com.github.ben-manes.versions") version "0.28.0" + id("com.jfrog.bintray") version "1.8.4" + id("io.gitlab.arturbosch.detekt") version "1.7.0-beta2" + id("net.thauvin.erik.gradle.semver") version "1.0.4" + id("org.jetbrains.dokka") version "0.10.1" + id("org.jetbrains.kotlin.jvm") version "1.3.70" + id("org.jetbrains.kotlin.kapt") version "1.3.70" + id("org.sonarqube") version "2.8" +} + +group = "net.thauvin.erik" +description = "is.gd Shortener for Kotlin/Java" + +val gitHub = "ethauvin/$name" +val mavenUrl = "https://github.com/$gitHub" +val deployDir = "deploy" +var isRelease = "release" in gradle.startParameter.taskNames + +val publicationName = "mavenJava" + +var semverProcessor = "net.thauvin.erik:semver:1.2.0" + +// Load local.properties +File("local.properties").apply { + if (exists()) { + FileInputStream(this).use { fis -> + Properties().apply { + load(fis) + forEach { (k, v) -> + extra[k as String] = v + } + } + } + } +} + +repositories { + jcenter() +} + +dependencies { + // Align versions of all Kotlin components + implementation(platform("org.jetbrains.kotlin:kotlin-bom")) + + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") + + testImplementation("org.jetbrains.kotlin:kotlin-test") + testImplementation("org.jetbrains.kotlin:kotlin-test-junit") +} + +kapt { + arguments { + arg("semver.project.dir", projectDir) + } +} + +detekt { + baseline = project.rootDir.resolve("detekt-baseline.xml") +} + +jacoco { + toolVersion = "0.8.3" +} + +sonarqube { + properties { + property("sonar.projectKey", "ethauvin_$name") + property("sonar.sourceEncoding", "UTF-8") + } +} + +val sourcesJar by tasks.creating(Jar::class) { + archiveClassifier.set("sources") + from(sourceSets.getByName("main").allSource) +} + +val javadocJar by tasks.creating(Jar::class) { + dependsOn(tasks.dokka) + from(tasks.dokka) + archiveClassifier.set("javadoc") + description = "Assembles a JAR of the generated Javadoc." + group = JavaBasePlugin.DOCUMENTATION_GROUP +} + +tasks { + withType { + reports { + xml.isEnabled = true + html.isEnabled = true + } + } + + withType().configureEach { + kotlinOptions.jvmTarget = "1.8" + } + + withType { + destination = file("$projectDir/pom.xml") + } + + assemble { + dependsOn(sourcesJar, javadocJar) + } + + clean { + doLast { + project.delete(fileTree(deployDir)) + } + } + + val copyToDeploy by registering(Copy::class) { + from(configurations.runtimeClasspath) { + exclude("annotations-*.jar") + } + from(jar) + into(deployDir) + } + + val bintrayUpload by existing(BintrayUploadTask::class) { + dependsOn(publishToMavenLocal) + } + + register("deploy") { + description = "Copies all needed files to the $deployDir directory." + group = PublishingPlugin.PUBLISH_TASK_GROUP + dependsOn("build", "jar") + outputs.dir(deployDir) + inputs.files(copyToDeploy) + mustRunAfter("clean") + } + + register("release") { + description = "Publishes version ${project.version} to Bintray." + group = PublishingPlugin.PUBLISH_TASK_GROUP + dependsOn("wrapper", bintrayUpload) + } + + "sonarqube" { + dependsOn("jacocoTestReport") + } +} + +fun findProperty(s: String) = project.findProperty(s) as String? +bintray { + user = findProperty("bintray.user") + key = findProperty("bintray.apikey") + publish = isRelease + setPublications(publicationName) + pkg.apply { + repo = "maven" + name = project.name + desc = description + websiteUrl = mavenUrl + issueTrackerUrl = "$mavenUrl/issues" + githubRepo = gitHub + githubReleaseNotesFile = "README.md" + vcsUrl = "$mavenUrl.git" + setLabels( + "is.gd", + "v.gd", + "java", + "kotlin", + "shorten", + "shorten-urls", + "shortener", + "shortener-service", + "shortens-links", + "shorturl", + "url-shortener" + ) + publicDownloadNumbers = true + version.apply { + name = project.version as String + desc = description + vcsTag = project.version as String + gpg.apply { + sign = true + } + } + } +} + +publishing { + publications { + create(publicationName) { + from(components["java"]) + artifact(sourcesJar) + artifact(javadocJar) + pom.withXml { + asNode().apply { + appendNode("name", project.name) + appendNode("description", project.description) + appendNode("url", mavenUrl) + + appendNode("licenses").appendNode("license").apply { + appendNode("name", "BSD 3-Clause") + appendNode("url", "https://opensource.org/licenses/BSD-3-Clause") + } + + appendNode("developers").appendNode("developer").apply { + appendNode("id", "ethauvin") + appendNode("name", "Erik C. Thauvin") + appendNode("email", "erik@thauvin.net") + } + + appendNode("scm").apply { + appendNode("connection", "scm:git:$mavenUrl.git") + appendNode("developerConnection", "scm:git:git@github.com:$gitHub.git") + appendNode("url", mavenUrl) + } + + appendNode("issueManagement").apply { + appendNode("system", "GitHub") + appendNode("url", "$mavenUrl/issues") + } + } + } + } + } +} \ No newline at end of file diff --git a/detekt-baseline.xml b/detekt-baseline.xml new file mode 100644 index 0000000..7a2ff7e --- /dev/null +++ b/detekt-baseline.xml @@ -0,0 +1,7 @@ + + + + + LongParameterList:Isgd.kt$Isgd.Companion$( url: String, shorturl: String = "", callback: String = "", logstats: Boolean = false, format: Format = Format.SIMPLE, isVgd: Boolean = false ) + + diff --git a/examples/.gitattributes b/examples/.gitattributes new file mode 100644 index 0000000..00a51af --- /dev/null +++ b/examples/.gitattributes @@ -0,0 +1,6 @@ +# +# https://help.github.com/articles/dealing-with-line-endings/ +# +# These are explicitly windows files and should use crlf +*.bat text eol=crlf + diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 0000000..1b6985c --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1,5 @@ +# Ignore Gradle project-specific cache directory +.gradle + +# Ignore Gradle build output directory +build diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts new file mode 100644 index 0000000..15372a8 --- /dev/null +++ b/examples/build.gradle.kts @@ -0,0 +1,32 @@ +plugins { + id("org.jetbrains.kotlin.jvm") version "1.3.70" + id("com.github.ben-manes.versions") version "0.28.0" + application +} + +// ./gradlew run --args='https://wwwcom.example. https://is.gd/Pt2sET' +// ./gradlew runJava --args='https://www.example.com https://is.gd/Pt2sET' + +repositories { + mavenLocal() + jcenter() +} + +dependencies { + implementation(platform("org.jetbrains.kotlin:kotlin-bom")) + implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") + + implementation("net.thauvin.erik:isgd-shorten:0.9.0-beta") +} + +application { + mainClassName = "com.example.IsgdExampleKt" +} + +tasks { + register("runJava", JavaExec::class) { + group = "application" + main = "com.example.IsgdSample" + classpath = sourceSets["main"].runtimeClasspath + } +} diff --git a/examples/gradle/wrapper/gradle-wrapper.jar b/examples/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..490fda8 Binary files /dev/null and b/examples/gradle/wrapper/gradle-wrapper.jar differ diff --git a/examples/gradle/wrapper/gradle-wrapper.properties b/examples/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..b43cc6e --- /dev/null +++ b/examples/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-rc-4-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/examples/gradlew b/examples/gradlew new file mode 100644 index 0000000..2fe81a7 --- /dev/null +++ b/examples/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/examples/gradlew.bat b/examples/gradlew.bat new file mode 100644 index 0000000..62bd9b9 --- /dev/null +++ b/examples/gradlew.bat @@ -0,0 +1,103 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/examples/settings.gradle.kts b/examples/settings.gradle.kts new file mode 100644 index 0000000..4ddea20 --- /dev/null +++ b/examples/settings.gradle.kts @@ -0,0 +1,10 @@ +/* + * This file was generated by the Gradle 'init' task. + * + * The settings file is used to specify which projects to include in your build. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user manual at https://docs.gradle.org/6.2/userguide/multi_project_builds.html + */ + +rootProject.name = "isgd-examples" diff --git a/examples/src/main/java/com/example/IsgdSample.java b/examples/src/main/java/com/example/IsgdSample.java new file mode 100644 index 0000000..2328776 --- /dev/null +++ b/examples/src/main/java/com/example/IsgdSample.java @@ -0,0 +1,20 @@ +package com.example; + +import net.thauvin.erik.isgd.Isgd; + +public final class IsgdSample { + public static void main(final String[] args) { + if (args.length > 0) { + for (final String arg : args) { + if (arg.contains("is.gd")) { + System.out.println(arg + " <-- " + Isgd.lookup(arg)); + } else { + System.out.println(arg + " --> " + Isgd.shorten(arg)); + } + } + } else { + System.err.println("Try specifying one or more URLs as arguments."); + } + System.exit(0); + } +} diff --git a/examples/src/main/kotlin/com/example/IsgdExample.kt b/examples/src/main/kotlin/com/example/IsgdExample.kt new file mode 100644 index 0000000..5acaad5 --- /dev/null +++ b/examples/src/main/kotlin/com/example/IsgdExample.kt @@ -0,0 +1,18 @@ +package com.example + +import net.thauvin.erik.isgd.Isgd +import kotlin.system.exitProcess + +fun main(args: Array) { + if (args.isNotEmpty()) { + args.forEach { + if (it.contains("is.gd")) + println(it + " <-- " + Isgd.lookup(it)) + else + println(it + " --> " + Isgd.shorten(it)) + } + } else { + println("Try specifying one or more URLs as arguments.") + } + exitProcess(0) +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..490fda8 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..b43cc6e --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-rc-4-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..2fe81a7 --- /dev/null +++ b/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..62bd9b9 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,103 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..9c8935f --- /dev/null +++ b/pom.xml @@ -0,0 +1,56 @@ + + + + + + + + 4.0.0 + net.thauvin.erik + isgd-shorten + 0.9.0-beta + + + + org.jetbrains.kotlin + kotlin-bom + 1.3.70 + pom + import + + + + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + 1.3.70 + runtime + + + isgd-shorten + is.gd Shortener for Kotlin/Java + https://github.com/ethauvin/isgd-shorten + + + BSD 3-Clause + https://opensource.org/licenses/BSD-3-Clause + + + + + ethauvin + Erik C. Thauvin + erik@thauvin.net + + + + scm:git:https://github.com/ethauvin/isgd-shorten.git + scm:git:git@github.com:ethauvin/isgd-shorten.git + https://github.com/ethauvin/isgd-shorten + + + GitHub + https://github.com/ethauvin/isgd-shorten/issues + + diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..4383f65 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "isgd-shorten" diff --git a/src/main/kotlin/net/thauvin/erik/isgd/Isgd.kt b/src/main/kotlin/net/thauvin/erik/isgd/Isgd.kt new file mode 100644 index 0000000..ebe82c8 --- /dev/null +++ b/src/main/kotlin/net/thauvin/erik/isgd/Isgd.kt @@ -0,0 +1,129 @@ +/* + * Isgd.kt + * + * Copyright (c) 2020, Erik C. Thauvin (erik@thauvin.net) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of this project nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package net.thauvin.erik.isgd + +import java.net.HttpURLConnection +import java.net.URL +import java.net.URLEncoder +import java.nio.charset.StandardCharsets + +/** + * See the [is.gd API](https://is.gd/apishorteningreference.php) + */ +enum class Format(val type: String) { + WEB("web"), SIMPLE("simple"), XML("xml"), JSON("json") +} + +fun String.encode(): String { + return URLEncoder.encode(this, StandardCharsets.UTF_8.name()) +} + +class Isgd private constructor() { + companion object { + private fun callApi(url: String): String { + val connection = URL(url).openConnection() as HttpURLConnection + connection.setRequestProperty( + "User-Agent", + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)" + + "Chrome/80.0.3987.149 Safari/537.36" + ) + return connection.inputStream.bufferedReader().readText() + } + + private fun host(isVgd: Boolean = false): String { + return if (isVgd) "v.gd" else "is.gd" + } + + /** + * See the [is.gd API](https://is.gd/apilookupreference.php). + */ + @JvmStatic + @JvmOverloads + fun lookup( + shorturl: String, + callback: String = "", + format: Format = Format.SIMPLE, + isVgd: Boolean = false + ): String { + if (shorturl.isEmpty()) { + throw IllegalArgumentException("Please specify a valid short URL to lookup.") + } + + val sb = StringBuilder("https://${host(isVgd)}/forward.php?shorturl=${shorturl.encode()}") + + if (callback.isNotEmpty()) { + sb.append("&callback=${callback.encode()}") + } + + sb.append("&format=${format.type.encode()}") + + return callApi(sb.toString()) + } + + /** + * See the [is.gd API](https://is.gd/apishorteningreference.php). + */ + @JvmStatic + @JvmOverloads + fun shorten( + url: String, + shorturl: String = "", + callback: String = "", + logstats: Boolean = false, + format: Format = Format.SIMPLE, + isVgd: Boolean = false + ): String { + if (url.isEmpty()) { + throw IllegalArgumentException("Please enter a valid URL to shorten.") + } + + val sb = StringBuilder("https://${host(isVgd)}/create.php?url=${url.encode()}") + + if (shorturl.isNotEmpty()) { + sb.append("&shorturl=${shorturl.encode()}") + } + + if (callback.isNotEmpty()) { + sb.append("&callback=${callback.encode()}") + } + + if (logstats) { + sb.append("&logstats=1") + } + + sb.append("&format=${format.type.encode()}") + + return callApi(sb.toString()) + } + } +} diff --git a/src/test/kotlin/net/thauvin/erik/isgd/IsgdTest.kt b/src/test/kotlin/net/thauvin/erik/isgd/IsgdTest.kt new file mode 100644 index 0000000..399030b --- /dev/null +++ b/src/test/kotlin/net/thauvin/erik/isgd/IsgdTest.kt @@ -0,0 +1,96 @@ +/* + * IsgdTest.kt + * + * Copyright (c) 2020, Erik C. Thauvin (erik@thauvin.net) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of this project nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package net.thauvin.erik.isgd + +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class IsgdTest { + private val url = "https://www.example.com" + private val shortUrl = "https://is.gd/Pt2sET" + private val shortVgdUrl = "https://v.gd/2z2ncj" + + @Test + fun testLookupDefault() { + assertEquals(url, Isgd.lookup(shortUrl)) + assertEquals(url, Isgd.lookup(shortVgdUrl, isVgd = true), "v.gd") + } + + @Test + fun testLookupJson() { + assertEquals("{ \"url\": \"$url\" }", Isgd.lookup(shortUrl, format = Format.JSON)) + assertEquals( + "test({ \"url\": \"$url\" });", + Isgd.lookup(shortUrl, callback = "test", format = Format.JSON), + "with callback" + ) + } + + @Test + fun testLookupXml() { + assertEquals( + "$url", + Isgd.lookup(shortUrl, format = Format.XML) + ) + } + + @Test + fun testShortenDefault() { + assertEquals(shortUrl, Isgd.shorten(url)) + assertEquals(shortVgdUrl, Isgd.shorten(url, isVgd = true), "v.gd") + } + + @Test + fun testShortenJson() { + assertEquals("{ \"shorturl\": \"$shortUrl\" }", Isgd.shorten(url, format = Format.JSON)) + assertEquals( + "test({ \"shorturl\": \"$shortUrl\" });", + Isgd.shorten(url, callback = "test", format = Format.JSON), + "with callback" + ) + } + + @Test + fun testShortenXml() { + assertEquals( + "$shortUrl", + Isgd.shorten(url, format = Format.XML) + ) + } + + @Test + fun testShortenWeb() { + assertTrue(Isgd.shorten(url, format = Format.WEB).contains(shortUrl)) + } +} diff --git a/version.properties b/version.properties new file mode 100644 index 0000000..ea386b3 --- /dev/null +++ b/version.properties @@ -0,0 +1,8 @@ +#Generated by the Semver Plugin for Gradle +#Sat Mar 21 16:36:23 PDT 2020 +version.buildmeta= +version.major=0 +version.minor=9 +version.patch=0 +version.prerelease=beta +version.semver=0.0.9-beta