Initial commit.
This commit is contained in:
commit
2ee3568e40
25 changed files with 882 additions and 0 deletions
5
.gitattributes
vendored
Normal file
5
.gitattributes
vendored
Normal file
|
@ -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
|
29
.gitignore
vendored
Normal file
29
.gitignore
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
**/.idea/dictionaries
|
||||||
|
**/.idea/gradle.xml
|
||||||
|
**/.idea/libraries
|
||||||
|
**/.idea/tasks.xml
|
||||||
|
**/.idea/workspace.xml
|
||||||
|
*.sublime-*
|
||||||
|
*.iws
|
||||||
|
.classpath
|
||||||
|
.DS_Store
|
||||||
|
.gradle
|
||||||
|
.kobalt
|
||||||
|
.nb-gradle
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
/bin
|
||||||
|
/build
|
||||||
|
/deploy
|
||||||
|
/dist
|
||||||
|
/gen
|
||||||
|
/gradle.properties
|
||||||
|
/local.properties
|
||||||
|
/out
|
||||||
|
/proguard-project.txt
|
||||||
|
/project.properties
|
||||||
|
/target
|
||||||
|
/test-output
|
||||||
|
ehthumbs.db
|
||||||
|
kobaltBuild
|
||||||
|
Thumbs.db
|
6
.idea/copyright/Erik_s_Copyright_Notice.xml
generated
Normal file
6
.idea/copyright/Erik_s_Copyright_Notice.xml
generated
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<component name="CopyrightManager">
|
||||||
|
<copyright>
|
||||||
|
<option name="notice" value="&#36;file.fileName Copyright (c) &#36;today.year, 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." />
|
||||||
|
<option name="myName" value="Erik's Copyright Notice" />
|
||||||
|
</copyright>
|
||||||
|
</component>
|
15
.idea/copyright/profiles_settings.xml
generated
Normal file
15
.idea/copyright/profiles_settings.xml
generated
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<component name="CopyrightManager">
|
||||||
|
<settings>
|
||||||
|
<module2copyright>
|
||||||
|
<element module="Source" copyright="Erik's Copyright Notice" />
|
||||||
|
</module2copyright>
|
||||||
|
<LanguageOptions name="JAVA">
|
||||||
|
<option name="fileTypeOverride" value="3" />
|
||||||
|
<option name="addBlankAfter" value="false" />
|
||||||
|
</LanguageOptions>
|
||||||
|
<LanguageOptions name="Kotlin">
|
||||||
|
<option name="fileTypeOverride" value="3" />
|
||||||
|
<option name="addBlankAfter" value="false" />
|
||||||
|
</LanguageOptions>
|
||||||
|
</settings>
|
||||||
|
</component>
|
6
.idea/encodings.xml
generated
Normal file
6
.idea/encodings.xml
generated
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Encoding">
|
||||||
|
<file url="PROJECT" charset="UTF-8" />
|
||||||
|
</component>
|
||||||
|
</project>
|
53
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
53
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<option name="myLocal" value="true" />
|
||||||
|
<inspection_tool class="FieldMayBeFinal" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="TOP_LEVEL_CLASS_OPTIONS">
|
||||||
|
<value>
|
||||||
|
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
|
||||||
|
<option name="REQUIRED_TAGS" value="" />
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="INNER_CLASS_OPTIONS">
|
||||||
|
<value>
|
||||||
|
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
|
||||||
|
<option name="REQUIRED_TAGS" value="" />
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="METHOD_OPTIONS">
|
||||||
|
<value>
|
||||||
|
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
|
||||||
|
<option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="FIELD_OPTIONS">
|
||||||
|
<value>
|
||||||
|
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
|
||||||
|
<option name="REQUIRED_TAGS" value="" />
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="IGNORE_DEPRECATED" value="false" />
|
||||||
|
<option name="IGNORE_JAVADOC_PERIOD" value="true" />
|
||||||
|
<option name="IGNORE_DUPLICATED_THROWS" value="false" />
|
||||||
|
<option name="IGNORE_POINT_TO_ITSELF" value="false" />
|
||||||
|
<option name="myAdditionalJavadocTags" value="created" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="LocalCanBeFinal" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="REPORT_VARIABLES" value="true" />
|
||||||
|
<option name="REPORT_PARAMETERS" value="false" />
|
||||||
|
<option name="REPORT_CATCH_PARAMETERS" value="false" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="LoggerInitializedWithForeignClass" enabled="false" level="WARNING" enabled_by_default="false">
|
||||||
|
<option name="loggerClassName" value="org.apache.log4j.Logger,org.slf4j.LoggerFactory,org.apache.commons.logging.LogFactory,java.util.logging.Logger" />
|
||||||
|
<option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="UnnecessarySemicolon" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="WeakerAccess" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="true" />
|
||||||
|
<option name="SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES" value="false" />
|
||||||
|
<option name="SUGGEST_PRIVATE_FOR_INNERS" value="false" />
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
19
.idea/kobalt.xml
generated
Normal file
19
.idea/kobalt.xml
generated
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="KobaltSettings">
|
||||||
|
<option name="linkedExternalProjectsSettings">
|
||||||
|
<KobaltProjectSettings>
|
||||||
|
<option name="autoDownloadKobalt" value="true" />
|
||||||
|
<option name="downloadSources" value="false" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="kobaltHome" value="$USER_HOME$/.kobalt/wrapper/dist/kobalt-1.0.86" />
|
||||||
|
<option name="modules">
|
||||||
|
<set>
|
||||||
|
<option value="$PROJECT_DIR$" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
<option name="profiles" value="" />
|
||||||
|
</KobaltProjectSettings>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
4
.idea/misc.xml
generated
Normal file
4
.idea/misc.xml
generated
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8.x" project-jdk-type="JavaSDK" />
|
||||||
|
</project>
|
9
.idea/modules.xml
generated
Normal file
9
.idea/modules.xml
generated
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/kobalt/Build.kt.iml" filepath="$PROJECT_DIR$/kobalt/Build.kt.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/pinboard-poster.iml" filepath="$PROJECT_DIR$/pinboard-poster.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
3
.idea/scopes/Source.xml
generated
Normal file
3
.idea/scopes/Source.xml
generated
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<component name="DependencyValidationManager">
|
||||||
|
<scope name="Source" pattern="file[pinboard-poster]:src/main/java//*.java||file[pinboard-poster]:src/main/kotlin//*.kt" />
|
||||||
|
</component>
|
124
.idea/uiDesigner.xml
generated
Normal file
124
.idea/uiDesigner.xml
generated
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Palette2">
|
||||||
|
<group name="Swing">
|
||||||
|
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="Button" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="RadioButton" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="CheckBox" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="Label" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||||
|
<preferred-size width="200" height="200" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||||
|
<preferred-size width="200" height="200" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||||
|
<preferred-size width="-1" height="20" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||||
|
</item>
|
||||||
|
</group>
|
||||||
|
</component>
|
||||||
|
</project>
|
19
.travis.yml
Normal file
19
.travis.yml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
language: java
|
||||||
|
|
||||||
|
jdk:
|
||||||
|
- oraclejdk8
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- chmod +x kobaltw
|
||||||
|
|
||||||
|
install: true
|
||||||
|
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- $HOME/.m2
|
||||||
|
- $HOME/.kobalt
|
||||||
|
|
||||||
|
before_cache:
|
||||||
|
- rm -rf .kobalt/*
|
||||||
|
|
||||||
|
script: ./kobaltw clean assemble
|
113
README.md
Normal file
113
README.md
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
# [Pinboard](https://pinboard.in) Poster for Kotlin/Java
|
||||||
|
|
||||||
|
[](http://opensource.org/licenses/BSD-3-Clause) [](https://travis-ci.org/ethauvin/pinboard-poster) [](https://www.versioneye.com/user/projects/58ff729f6ac171425cd00acf) [ ](https://bintray.com/ethauvin/maven/pinboard-poster/_latestVersion)
|
||||||
|
|
||||||
|
A small Kotlin/Java library for posting to [Pinboard](https://pinboard.in).
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Kotlin
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
|
||||||
|
val poster = PinboardPoster("user:TOKEN")
|
||||||
|
|
||||||
|
poster.addPin("http://www.example.com/foo", "This is a test")
|
||||||
|
poster.deletePin("http:///www.example.com/bar")
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Java
|
||||||
|
```java
|
||||||
|
|
||||||
|
final PinboardPoster poster = new PinBboardPoster("user:TOKEN");
|
||||||
|
|
||||||
|
poster.addPin("http://www.example.com/foo", "This is a test");
|
||||||
|
poster.deletePin("http:///www.example.com/bar");
|
||||||
|
```
|
||||||
|
|
||||||
|
Your API authentication token is available on the [Pinboard settings page](https://pinboard.in/settings/password).
|
||||||
|
|
||||||
|
## Usage with Maven, Gradle and Kobalt
|
||||||
|
|
||||||
|
### Maven
|
||||||
|
|
||||||
|
To install and run from Maven, configure an artifact as follows:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.thauvin.erik</groupId>
|
||||||
|
<artifactId>pinboard-poster</artifactId>
|
||||||
|
<version>0.9.0</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Gradle
|
||||||
|
|
||||||
|
To install and run from Gradle, add the following to the build.gradle file:
|
||||||
|
|
||||||
|
```gradle
|
||||||
|
dependencies {
|
||||||
|
compileOnly 'net.thauvin.erik:pinboard-poster:0.9.0'
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Kobalt
|
||||||
|
|
||||||
|
To install and run from Kobalt, add the following to the Build.kt file:
|
||||||
|
|
||||||
|
```gradle
|
||||||
|
dependencies {
|
||||||
|
compile("net.thauvin.erik:pinboard-poster:0.9.0")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Adding
|
||||||
|
|
||||||
|
The `addPin` function support all of the [Pinboard API parameters](https://pinboard.in/api/#posts_add):
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
poster.addPin(url = "http://www.example.com",
|
||||||
|
description = "This is the title.",
|
||||||
|
extended = "This is the extended description.",
|
||||||
|
tags = "tag1 tag2 tag3",
|
||||||
|
dt = "2010-12-11T19:48:02Z",
|
||||||
|
replace = true,
|
||||||
|
shared = true,
|
||||||
|
toRead = false)
|
||||||
|
```
|
||||||
|
|
||||||
|
`url` and `description` are required.
|
||||||
|
|
||||||
|
It returns `true` if the bookmark was added successfully, `false` otherwise.
|
||||||
|
|
||||||
|
## Deleting
|
||||||
|
|
||||||
|
The `deletePin` function support all of the [Pinboard API parameters](https://pinboard.in/api/#posts_delete):
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
poster.deletePin(url = "http://www.example.com/")
|
||||||
|
```
|
||||||
|
|
||||||
|
It returns `true` if the bookmark was deleted successfully, `false` otherwise.
|
||||||
|
|
||||||
|
## Logging
|
||||||
|
|
||||||
|
The library used [`java.util.logging`](https://docs.oracle.com/javase/8/docs/api/java/util/logging/package-summary.html) to log errors. Logging can be configured as follows:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
with(poster.logger) {
|
||||||
|
addHandler(ConsoleHandler().apply { level = Level.FINE })
|
||||||
|
level = Level.FINE
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
or using a property file.
|
||||||
|
|
||||||
|
## API End Point
|
||||||
|
|
||||||
|
The API end point is automatically configured to `https://api.pinboard.in/v1/`. Since Pinboard uses the `del.ico.us` API, the library could potentially be used with another compatible service. To configure the API end point, use:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
poster.apiEndPoint = "https://www.example.com/v1"
|
||||||
|
```
|
24
kobalt/Build.kt.iml
Normal file
24
kobalt/Build.kt.iml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module external.linked.project.id="Build.kt" external.linked.project.path="$MODULE_DIR$/.." external.root.project.path="$MODULE_DIR$/.." external.system.id="KOBALT" type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<output url="file://$MODULE_DIR$/out/classes" />
|
||||||
|
<output-test url="file://$MODULE_DIR$/out/test-classes" />
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="module-library">
|
||||||
|
<library name="Kobalt: com.beust.kobalt:kobalt:jar:1.0.86">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$USER_HOME$/.kobalt/wrapper/dist/kobalt-1.0.86/kobalt/wrapper/kobalt-1.0.86.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$USER_HOME$/.kobalt/wrapper/dist/kobalt-1.0.86/kobalt/wrapper/kobalt-1.0.86-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</orderEntry>
|
||||||
|
</component>
|
||||||
|
</module>
|
90
kobalt/src/Build.kt
Normal file
90
kobalt/src/Build.kt
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
import com.beust.kobalt.glob
|
||||||
|
import com.beust.kobalt.plugin.application.application
|
||||||
|
import com.beust.kobalt.plugin.packaging.assemble
|
||||||
|
import com.beust.kobalt.plugin.packaging.install
|
||||||
|
import com.beust.kobalt.plugin.publish.autoGitTag
|
||||||
|
import com.beust.kobalt.plugin.publish.bintray
|
||||||
|
import com.beust.kobalt.project
|
||||||
|
import org.apache.maven.model.Developer
|
||||||
|
import org.apache.maven.model.License
|
||||||
|
import org.apache.maven.model.Model
|
||||||
|
import org.apache.maven.model.Scm
|
||||||
|
import java.io.FileInputStream
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
val p = project {
|
||||||
|
name = "pinboard-poster"
|
||||||
|
group = "net.thauvin.erik"
|
||||||
|
artifactId = name
|
||||||
|
version = "0.9.0"
|
||||||
|
|
||||||
|
val localProperties = Properties().apply { FileInputStream("local.properties").use { fis -> load(fis) } }
|
||||||
|
val apiToken = localProperties.getProperty("pinboard-api-token", "")
|
||||||
|
|
||||||
|
pom = Model().apply {
|
||||||
|
description = project.description
|
||||||
|
url = "https://github.com/ethauvin/pinboard-poster"
|
||||||
|
licenses = listOf(License().apply {
|
||||||
|
name = "BSD 3-Clause"
|
||||||
|
url = "https://opensource.org/licenses/BSD-3-Clause"
|
||||||
|
})
|
||||||
|
scm = Scm().apply {
|
||||||
|
url = "https://github.com/ethauvin/pinboard-poster"
|
||||||
|
connection = "https://github.com/ethauvin/pinboard-poster.git"
|
||||||
|
developerConnection = "git@github.com:ethauvin/pinboard-poster.git"
|
||||||
|
}
|
||||||
|
developers = listOf(Developer().apply {
|
||||||
|
id = "ethauvin"
|
||||||
|
name = "Erik C. Thauvin"
|
||||||
|
email = "erik@thauvin.net"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile("org.jetbrains.kotlin:kotlin-stdlib:1.1.2-3")
|
||||||
|
compile("com.squareup.okhttp3:okhttp:3.8.0")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependenciesTest {
|
||||||
|
compile("org.testng:testng:6.11")
|
||||||
|
compile("org.jetbrains.kotlin:kotlin-test:1.1.2-3")
|
||||||
|
}
|
||||||
|
|
||||||
|
assemble {
|
||||||
|
jar { }
|
||||||
|
mavenJars { }
|
||||||
|
}
|
||||||
|
|
||||||
|
application {
|
||||||
|
mainClass = "net.thauvin.erik.pinboard.PinboardPosterKt"
|
||||||
|
args(apiToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
application {
|
||||||
|
taskName = "runJava"
|
||||||
|
mainClass = "net.thauvin.erik.pinboard.JavaExample"
|
||||||
|
args(apiToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
install {
|
||||||
|
target = "deploy"
|
||||||
|
include(from("kobaltBuild/libs"), to(target), glob("**/*"))
|
||||||
|
collect(compileDependencies).forEach {
|
||||||
|
copy(from(it.file.absolutePath), to(target))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
autoGitTag {
|
||||||
|
enabled = true
|
||||||
|
//push = false
|
||||||
|
message = "Version $version"
|
||||||
|
}
|
||||||
|
|
||||||
|
bintray {
|
||||||
|
publish = true
|
||||||
|
description = "Release version $version"
|
||||||
|
issueTrackerUrl = "https://github.com/ethauvin/pinboard-poster/issues"
|
||||||
|
vcsTag = version
|
||||||
|
sign = true
|
||||||
|
}
|
||||||
|
}
|
BIN
kobalt/wrapper/kobalt-wrapper.jar
Normal file
BIN
kobalt/wrapper/kobalt-wrapper.jar
Normal file
Binary file not shown.
1
kobalt/wrapper/kobalt-wrapper.properties
Normal file
1
kobalt/wrapper/kobalt-wrapper.properties
Normal file
|
@ -0,0 +1 @@
|
||||||
|
kobalt.version=1.0.86
|
2
kobaltw
Normal file
2
kobaltw
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
java -jar "`dirname "$0"`/kobalt/wrapper/kobalt-wrapper.jar" $*
|
4
kobaltw.bat
Normal file
4
kobaltw.bat
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
@echo off
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
java -jar "%DIRNAME%/kobalt/wrapper/kobalt-wrapper.jar" %*
|
BIN
lib/kotlin-reflect.jar
Normal file
BIN
lib/kotlin-reflect.jar
Normal file
Binary file not shown.
BIN
lib/kotlin-runtime-sources.jar
Normal file
BIN
lib/kotlin-runtime-sources.jar
Normal file
Binary file not shown.
BIN
lib/kotlin-runtime.jar
Normal file
BIN
lib/kotlin-runtime.jar
Normal file
Binary file not shown.
106
pinboard-poster.iml
Normal file
106
pinboard-poster.iml
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module external.linked.project.id="pinboard-poster" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="KOBALT" type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<output url="file://$MODULE_DIR$/kobaltBuild/classes" />
|
||||||
|
<output-test url="file://$MODULE_DIR$/kobaltBuild/test-classes" />
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/kotlin" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/kotlin" isTestSource="true" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/kobaltBuild" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="module-library">
|
||||||
|
<library name="Kobalt: org.jetbrains.kotlin:kotlin-stdlib:jar:1.1.2-3">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$USER_HOME$/.kobalt/cache/org/jetbrains/kotlin/kotlin-stdlib/1.1.2-3/kotlin-stdlib-1.1.2-3.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</orderEntry>
|
||||||
|
<orderEntry type="module-library" scope="TEST">
|
||||||
|
<library name="Kobalt: org.jetbrains:annotations:jar:13.0">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$USER_HOME$/.kobalt/cache/org/jetbrains/annotations/13.0/annotations-13.0.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</orderEntry>
|
||||||
|
<orderEntry type="module-library" scope="TEST">
|
||||||
|
<library name="Kobalt: org.jetbrains.kotlin:kotlin-stdlib:jar:1.1.2-3">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$USER_HOME$/.kobalt/cache/org/jetbrains/kotlin/kotlin-stdlib/1.1.2-3/kotlin-stdlib-1.1.2-3.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</orderEntry>
|
||||||
|
<orderEntry type="module-library" scope="TEST">
|
||||||
|
<library name="Kobalt: org.yaml:snakeyaml:jar:1.17">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$USER_HOME$/.kobalt/cache/org/yaml/snakeyaml/1.17/snakeyaml-1.17.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</orderEntry>
|
||||||
|
<orderEntry type="module-library" scope="TEST">
|
||||||
|
<library name="Kobalt: com.beust:jcommander:jar:1.64">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$USER_HOME$/.kobalt/cache/com/beust/jcommander/1.64/jcommander-1.64.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</orderEntry>
|
||||||
|
<orderEntry type="module-library">
|
||||||
|
<library name="Kobalt: com.squareup.okio:okio:jar:1.13.0">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$USER_HOME$/.kobalt/cache/com/squareup/okio/okio/1.13.0/okio-1.13.0.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</orderEntry>
|
||||||
|
<orderEntry type="module-library">
|
||||||
|
<library name="Kobalt: org.jetbrains:annotations:jar:13.0">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$USER_HOME$/.kobalt/cache/org/jetbrains/annotations/13.0/annotations-13.0.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</orderEntry>
|
||||||
|
<orderEntry type="module-library" scope="TEST">
|
||||||
|
<library name="Kobalt: org.jetbrains.kotlin:kotlin-test:jar:1.1.2-3">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$USER_HOME$/.kobalt/cache/org/jetbrains/kotlin/kotlin-test/1.1.2-3/kotlin-test-1.1.2-3.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</orderEntry>
|
||||||
|
<orderEntry type="module-library" scope="TEST">
|
||||||
|
<library name="Kobalt: org.testng:testng:jar:6.11">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$USER_HOME$/.kobalt/cache/org/testng/testng/6.11/testng-6.11.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</orderEntry>
|
||||||
|
<orderEntry type="module-library">
|
||||||
|
<library name="Kobalt: com.squareup.okhttp3:okhttp:jar:3.8.0">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$USER_HOME$/.kobalt/cache/com/squareup/okhttp3/okhttp/3.8.0/okhttp-3.8.0.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC />
|
||||||
|
<SOURCES />
|
||||||
|
</library>
|
||||||
|
</orderEntry>
|
||||||
|
</component>
|
||||||
|
</module>
|
47
src/main/java/net/thauvin/erik/pinboard/JavaExample.java
Normal file
47
src/main/java/net/thauvin/erik/pinboard/JavaExample.java
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* JavaExample.java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017, 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.pinboard;
|
||||||
|
|
||||||
|
public class JavaExample {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
final String url = "http://www.example.com/pinboard";
|
||||||
|
final PinboardPoster poster = new PinboardPoster(args[0]);
|
||||||
|
|
||||||
|
if (poster.addPin(url, "Testing", "Extended test", "test koltin")) {
|
||||||
|
System.out.println("Added: " + url);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (poster.deletePin(url)) {
|
||||||
|
System.out.println("Deleted: " + url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
203
src/main/kotlin/net/thauvin/erik/pinboard/PinboardPoster.kt
Normal file
203
src/main/kotlin/net/thauvin/erik/pinboard/PinboardPoster.kt
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
/*
|
||||||
|
* PinboardPoster.kt
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017, 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.pinboard
|
||||||
|
|
||||||
|
import okhttp3.HttpUrl
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import java.net.URL
|
||||||
|
import java.util.logging.ConsoleHandler
|
||||||
|
import java.util.logging.Level
|
||||||
|
import java.util.logging.Logger
|
||||||
|
|
||||||
|
object Constants {
|
||||||
|
const val API_ENDPOINT = "https://api.pinboard.in/v1/"
|
||||||
|
const val AUTH_TOKEN = "auth_token"
|
||||||
|
const val DONE = "done"
|
||||||
|
}
|
||||||
|
|
||||||
|
open class PinboardPoster(val apiToken: String) {
|
||||||
|
var apiEndPoint: String = Constants.API_ENDPOINT
|
||||||
|
|
||||||
|
val logger: Logger by lazy { Logger.getLogger(PinboardPoster::class.java.simpleName) }
|
||||||
|
|
||||||
|
private val client by lazy { OkHttpClient() }
|
||||||
|
|
||||||
|
@JvmOverloads
|
||||||
|
fun addPin(url: String,
|
||||||
|
description: String,
|
||||||
|
extended: String = "",
|
||||||
|
tags: String = "",
|
||||||
|
dt: String = "",
|
||||||
|
replace: Boolean = true,
|
||||||
|
shared: Boolean = true,
|
||||||
|
toRead: Boolean = false): Boolean {
|
||||||
|
if (validate()) {
|
||||||
|
if (!validateUrl(url)) {
|
||||||
|
logger.log(Level.SEVERE, "Please specify a valid URL to pin.")
|
||||||
|
} else if (description.isBlank()) {
|
||||||
|
logger.log(Level.SEVERE, "Please specify a valid description.")
|
||||||
|
} else {
|
||||||
|
val apiUrl = HttpUrl.parse(cleanEndPoint("posts/add"))
|
||||||
|
if (apiUrl != null) {
|
||||||
|
val httpUrl = apiUrl.newBuilder().apply {
|
||||||
|
addQueryParameter("url", url)
|
||||||
|
addQueryParameter("description", description)
|
||||||
|
if (extended.isNotBlank()) {
|
||||||
|
addQueryParameter("extended", extended)
|
||||||
|
}
|
||||||
|
if (tags.isNotBlank()) {
|
||||||
|
addQueryParameter("tags", tags)
|
||||||
|
}
|
||||||
|
if (dt.isNotBlank()) {
|
||||||
|
addQueryParameter("dt", dt)
|
||||||
|
}
|
||||||
|
if (!replace) {
|
||||||
|
addQueryParameter("replace", "no")
|
||||||
|
}
|
||||||
|
if (!shared) {
|
||||||
|
addQueryParameter("shared", "no")
|
||||||
|
}
|
||||||
|
if (toRead) {
|
||||||
|
addQueryParameter("toread", "yes")
|
||||||
|
}
|
||||||
|
addQueryParameter(Constants.AUTH_TOKEN, apiToken)
|
||||||
|
}.build()
|
||||||
|
|
||||||
|
val request = Request.Builder().url(httpUrl).build()
|
||||||
|
val result = client.newCall(request).execute()
|
||||||
|
|
||||||
|
logger.log(Level.FINE, "HTTP Result: ${result.code()}")
|
||||||
|
|
||||||
|
val response = result.body()?.string()
|
||||||
|
|
||||||
|
if (response != null && response.contains(Constants.DONE)) {
|
||||||
|
logger.log(Level.FINE, "HTTP Response:\n$response")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.log(Level.SEVERE, "Invalid API end point: $apiEndPoint")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deletePin(url: String): Boolean {
|
||||||
|
if (validate()) {
|
||||||
|
if (!validateUrl(url)) {
|
||||||
|
logger.log(Level.SEVERE, "Please specify a valid URL to delete.")
|
||||||
|
} else {
|
||||||
|
val apiUrl = HttpUrl.parse(cleanEndPoint("posts/delete"))
|
||||||
|
if (apiUrl != null) {
|
||||||
|
val httpUrl = apiUrl.newBuilder().apply {
|
||||||
|
addQueryParameter("url", url)
|
||||||
|
addQueryParameter(Constants.AUTH_TOKEN, apiToken)
|
||||||
|
}.build()
|
||||||
|
|
||||||
|
val request = Request.Builder().url(httpUrl).build()
|
||||||
|
val result = client.newCall(request).execute()
|
||||||
|
|
||||||
|
logger.log(Level.FINE, "HTTP Result: ${result.code()}")
|
||||||
|
|
||||||
|
val response = result.body()?.string()
|
||||||
|
|
||||||
|
if (response != null && response.contains(Constants.DONE)) {
|
||||||
|
logger.log(Level.FINE, "HTTP Response:\n$response")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.log(Level.SEVERE, "Invalid API end point: $apiEndPoint")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun validateUrl(url: String): Boolean {
|
||||||
|
if (url.isBlank()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
URL(url)
|
||||||
|
} catch(e: Exception) {
|
||||||
|
logger.log(Level.FINE, "Invalid URL: $url", e)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun validate(): Boolean {
|
||||||
|
if (apiToken.isBlank() && !apiToken.contains(':')) {
|
||||||
|
logger.log(Level.SEVERE, "Please specify a valid API token. (eg. user:TOKEN)")
|
||||||
|
return false
|
||||||
|
} else if (!validateUrl(apiEndPoint)) {
|
||||||
|
logger.log(Level.SEVERE, "Please specify a valid API end point. (eg. ${Constants.API_ENDPOINT})")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun cleanEndPoint(method: String): String {
|
||||||
|
if (apiEndPoint.endsWith('/')) {
|
||||||
|
return "$apiEndPoint$method"
|
||||||
|
} else {
|
||||||
|
return "$apiEndPoint/$method"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
if (args.size == 1) {
|
||||||
|
val url = "http://www.example.com/pinboard"
|
||||||
|
val poster = PinboardPoster(args[0])
|
||||||
|
|
||||||
|
with(poster.logger) {
|
||||||
|
addHandler(ConsoleHandler().apply { level = Level.FINE })
|
||||||
|
level = Level.FINE
|
||||||
|
}
|
||||||
|
|
||||||
|
if (poster.addPin(url, "Testing", "Extended test", "test koltin")) {
|
||||||
|
println("Added: $url")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (poster.deletePin(url)) {
|
||||||
|
println("Deleted: $url")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println("Please specify a valid API token. (eg. user:TOKEN)")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue