├── test ├── W0JfyHW.gif └── imgur.spec.js ├── .gitattributes ├── LICENSE-MIT ├── README.md ├── package.json ├── Gruntfile.js ├── .gitignore └── lib └── imgur.js /test/W0JfyHW.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamiees2/imgur-node-api/HEAD/test/W0JfyHW.gif -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 adamcoulombe 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | imgur anonymous upload in nodejs using the imgur api. 2 | 3 | ## Getting Started 4 | Install the module with: `npm install imgur-node-api` 5 | 6 | ```javascript 7 | var imgur = require('imgur-node-api'), 8 | path = require('path'); 9 | 10 | imgur.setClientID(myClientID); 11 | imgur.upload(path.join(__dirname, 'someimage.png'), function (err, res) { 12 | console.log(res.data.link); // Log the imgur url 13 | }); 14 | 15 | imgur.upload('http://25.media.tumblr.com/tumblr_md1yfw1Dcz1rsx19no1_1280.png', function (err,res) { 16 | console.log(res.data.link); 17 | }); 18 | 19 | imgur.delete('W0JfyHW', function (err,res) { 20 | console.log(res.data); 21 | }); 22 | 23 | imgur.update({ 24 | id: 'W0JfyHW', 25 | title: 'My Title', 26 | description: 'My Description' 27 | }, function (err,res) { 28 | console.log(res.data); 29 | }); 30 | 31 | imgur.getCredits(function (err, res) { 32 | console.log(res.data); 33 | }); 34 | ``` 35 | 36 | ## Documentation 37 | _(Coming soon)_ 38 | 39 | ## Examples 40 | _(Coming soon)_ 41 | 42 | ## Contributing 43 | In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/). 44 | 45 | ## Release History 46 | _(Nothing yet)_ 47 | 48 | ## License 49 | Copyright (c) 2013 jamiees2 50 | Licensed under the MIT license. 51 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "imgur-node-api", 3 | "description": "Node implementation of the anonymous imgur api", 4 | "version": "0.1.0", 5 | "homepage": "https://github.com/jamiees2/imgur-node-api", 6 | "author": { 7 | "name": "jamiees2", 8 | "email": "jamiees2@gmail.com" 9 | }, 10 | "contributors": { 11 | "name": "brutalhonesty", 12 | "email": "sparky1010+github@gmail.com" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git://github.com/jamiees2/imgur-node-api.git" 17 | }, 18 | "bugs": { 19 | "url": "https://github.com/jamiees2/imgur-node-api/issues" 20 | }, 21 | "licenses": [ 22 | { 23 | "type": "MIT", 24 | "url": "https://github.com/jamiees2/imgur-node-api/blob/master/LICENSE-MIT" 25 | } 26 | ], 27 | "main": "lib/imgur", 28 | "engines": { 29 | "node": ">= 0.8.0" 30 | }, 31 | "keywords": [ 32 | "imgur", 33 | "image", 34 | "sharing", 35 | "upload" 36 | ], 37 | "dependencies": { 38 | "request": "~2.16.6" 39 | }, 40 | "devDependencies": { 41 | "grunt": "~0.4.2", 42 | "grunt-contrib-concat": "~0.3.0", 43 | "grunt-contrib-jshint": "~0.7.2", 44 | "grunt-contrib-nodeunit": "~0.4.1", 45 | "grunt-contrib-uglify": "~0.2.7", 46 | "grunt-contrib-watch": "~0.5.3", 47 | "nock": "^0.51.0" 48 | }, 49 | "scripts": { 50 | "test": "grunt nodeunit" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /test/imgur.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var nock = require('nock'); 4 | var path = require('path'); 5 | var imgur = require('../lib/imgur'); 6 | var clientId = 'myTestId'; 7 | var imageId = 'W0JfyHW'; 8 | 9 | exports.setUp = function(callback) { 10 | imgur.setClientID(clientId); 11 | nock('https://api.imgur.com').post('/3/upload').reply(200, { 12 | success: true, 13 | status: 200, 14 | data: { 15 | link: 'http://i.imgur.com/'+imageId+'.gif' 16 | } 17 | }); 18 | nock('https://api.imgur.com').get('/3/credits').reply(200, { 19 | data: { 20 | UserLimit: 500, 21 | UserRemaining: 500, 22 | UserReset: 1417550317, 23 | ClientLimit: 12500, 24 | ClientRemaining: 12268 25 | }, 26 | success: true, 27 | status: 200 28 | }); 29 | nock('https://api.imgur.com').post('/3/image/' + imageId, { 30 | title: 'MyTitle', 31 | description: 'MyDescription' 32 | }).reply(200, { 33 | success: true, 34 | status: 200 35 | }); 36 | nock('https://api.imgur.com').delete('/3/image/' + imageId).reply(200, { 37 | success: true, 38 | status: 200 39 | }); 40 | callback(); 41 | }; 42 | 43 | exports.testUrlUpload = function(test) { 44 | imgur.upload('http://i.imgur.com/'+imageId+'.gif', function (error, res) { 45 | test.equal(error, null); 46 | test.ok(res.success, 'Should be a successful upload.'); 47 | test.equal(res.status, 200); 48 | test.done(); 49 | }); 50 | }; 51 | 52 | exports.testFileUpload = function(test) { 53 | imgur.upload(path.join(__dirname, (imageId + '.gif')), function (error, res) { 54 | test.equal(error, null); 55 | test.ok(res.success, 'Should be a successful upload.'); 56 | test.equal(res.status, 200); 57 | test.done(); 58 | }); 59 | }; 60 | 61 | exports.delete = function(test) { 62 | imgur.delete(imageId, function (error, res) { 63 | test.equal(error, null); 64 | test.ok(res.success, 'Should successfully delete the image.'); 65 | test.equal(res.status, 200); 66 | test.done(); 67 | }); 68 | }; 69 | 70 | exports.update = function(test) { 71 | imgur.update({ 72 | id: imageId, 73 | title: 'MyTitle', 74 | description: 'MyDescription', 75 | }, function (error, res) { 76 | test.equal(error, null); 77 | test.ok(res.success, 'Should successfully update the image.'); 78 | test.equal(res.status, 200); 79 | test.done(); 80 | }); 81 | }; 82 | 83 | exports.getCredits = function(test) { 84 | imgur.getCredits(function (error, res) { 85 | test.equal(error, null); 86 | test.ok(res.success, 'Should successfully return the credits left.'); 87 | test.equal(res.status, 200); 88 | test.done(); 89 | }); 90 | }; -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | 'use strict'; 3 | // Project configuration 4 | grunt.initConfig({ 5 | // Metadata 6 | pkg: grunt.file.readJSON('package.json'), 7 | banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' + 8 | '<%= grunt.template.today("yyyy-mm-dd") %>\n' + 9 | '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' + 10 | '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' + 11 | ' Licensed <%= pkg.licenses[0].type %> */\n', 12 | // Task configuration 13 | concat: { 14 | options: { 15 | banner: '<%= banner %>', 16 | stripBanners: true 17 | }, 18 | dist: { 19 | src: ['lib/**/*.js'], 20 | dest: 'dist/imgur.js' 21 | } 22 | }, 23 | uglify: { 24 | options: { 25 | banner: '<%= banner %>' 26 | }, 27 | dist: { 28 | src: '<%= concat.dist.dest %>', 29 | dest: 'dist/imgur.min.js' 30 | } 31 | }, 32 | jshint: { 33 | options: { 34 | node: true, 35 | curly: true, 36 | eqeqeq: true, 37 | immed: true, 38 | latedef: true, 39 | newcap: true, 40 | noarg: true, 41 | sub: true, 42 | undef: true, 43 | unused: true, 44 | eqnull: true, 45 | boss: true 46 | }, 47 | gruntfile: { 48 | src: 'gruntfile.js' 49 | }, 50 | lib_test: { 51 | src: ['lib/**/*.js', 'test/**/*.js'] 52 | } 53 | }, 54 | nodeunit: { 55 | files: ['test/**/*.spec.js'] 56 | }, 57 | watch: { 58 | gruntfile: { 59 | files: '<%= jshint.gruntfile.src %>', 60 | tasks: ['jshint:gruntfile'] 61 | }, 62 | lib_test: { 63 | files: '<%= jshint.lib_test.src %>', 64 | tasks: ['jshint:lib_test', 'nodeunit'] 65 | } 66 | } 67 | }); 68 | 69 | // These plugins provide necessary tasks 70 | grunt.loadNpmTasks('grunt-contrib-concat'); 71 | grunt.loadNpmTasks('grunt-contrib-uglify'); 72 | grunt.loadNpmTasks('grunt-contrib-nodeunit'); 73 | grunt.loadNpmTasks('grunt-contrib-jshint'); 74 | grunt.loadNpmTasks('grunt-contrib-watch'); 75 | 76 | // Default task 77 | grunt.registerTask('default', ['jshint', 'nodeunit', 'concat', 'uglify']); 78 | }; 79 | 80 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | [Dd]ebug/ 46 | [Rr]elease/ 47 | *_i.c 48 | *_p.c 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.vspscc 63 | .builds 64 | *.dotCover 65 | 66 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 67 | #packages/ 68 | 69 | # Visual C++ cache files 70 | ipch/ 71 | *.aps 72 | *.ncb 73 | *.opensdf 74 | *.sdf 75 | 76 | # Visual Studio profiler 77 | *.psess 78 | *.vsp 79 | 80 | # ReSharper is a .NET coding add-in 81 | _ReSharper* 82 | 83 | # Installshield output folder 84 | [Ee]xpress 85 | 86 | # DocProject is a documentation generator add-in 87 | DocProject/buildhelp/ 88 | DocProject/Help/*.HxT 89 | DocProject/Help/*.HxC 90 | DocProject/Help/*.hhc 91 | DocProject/Help/*.hhk 92 | DocProject/Help/*.hhp 93 | DocProject/Help/Html2 94 | DocProject/Help/html 95 | 96 | # Click-Once directory 97 | publish 98 | 99 | # Others 100 | [Bb]in 101 | [Oo]bj 102 | sql 103 | TestResults 104 | *.Cache 105 | ClientBin 106 | stylecop.* 107 | ~$* 108 | *.dbmdl 109 | Generated_Code #added for RIA/Silverlight projects 110 | 111 | # Backup & report files from converting an old project file to a newer 112 | # Visual Studio version. Backup files are not needed, because we have git ;-) 113 | _UpgradeReport_Files/ 114 | Backup*/ 115 | UpgradeLog*.XML 116 | 117 | 118 | 119 | ############ 120 | ## Windows 121 | ############ 122 | 123 | # Windows image file caches 124 | Thumbs.db 125 | 126 | # Folder config file 127 | Desktop.ini 128 | 129 | 130 | ############# 131 | ## Python 132 | ############# 133 | 134 | *.py[co] 135 | 136 | # Packages 137 | *.egg 138 | *.egg-info 139 | dist 140 | build 141 | eggs 142 | parts 143 | bin 144 | var 145 | sdist 146 | develop-eggs 147 | .installed.cfg 148 | 149 | # Installer logs 150 | pip-log.txt 151 | 152 | # Unit test / coverage reports 153 | .coverage 154 | .tox 155 | 156 | # Translations 157 | *.mo 158 | 159 | # Mr Developer 160 | .mr.developer.cfg 161 | 162 | # Mac crap 163 | .DS_Store 164 | 165 | 166 | ############ 167 | ## NodeJS 168 | ############ 169 | 170 | # Modules directory 171 | node_modules/ -------------------------------------------------------------------------------- /lib/imgur.js: -------------------------------------------------------------------------------- 1 | /* 2 | * imgur-upload 3 | * https://github.com/jamiees2/imgur-node-api/ 4 | * 5 | * Copyright (c) 2013 jamiees2 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | 'use strict'; 10 | 11 | var fs = require('fs'); 12 | var request = require('request'); 13 | var request = request.defaults({ 14 | json: true 15 | }); 16 | 17 | var imgur = { 18 | _clientID : null, 19 | setClientID : function(clientID){ 20 | this._clientID = clientID; 21 | }, 22 | upload: function(_file,_cb) { 23 | if(this._clientID && _file) { 24 | var options = { 25 | url: 'https://api.imgur.com/3/upload', 26 | headers: { 27 | 'Authorization': 'Client-ID ' + this._clientID 28 | } 29 | }; 30 | var post = request.post(options, function (err, req, body){ 31 | if(err) { 32 | return _cb(err); 33 | } 34 | _cb(null, body); 35 | }); 36 | 37 | var upload = post.form(); 38 | if (_file.match(/^https?:\/\//i)) { 39 | upload.append('type','url'); 40 | upload.append('image',_file); 41 | } else { 42 | upload.append('type', 'file'); 43 | upload.append('image', fs.createReadStream(_file)); 44 | } 45 | } 46 | }, 47 | delete: function(_id, _cb) { 48 | if(this._clientID && _id) { 49 | var options = { 50 | url: 'https://api.imgur.com/3/image/' + _id, 51 | headers: { 52 | 'Authorization': 'Client-ID ' + this._clientID 53 | } 54 | }; 55 | request.del(options, function (err, req, body) { 56 | if(err) { 57 | return _cb(err); 58 | } 59 | _cb(null, body); 60 | }); 61 | } 62 | }, 63 | update: function(_params, _cb) { 64 | if(this._clientID && _params.id && (_params.title || _params.description)) { 65 | var options = { 66 | url: 'https://api.imgur.com/3/image/' + _params.id, 67 | headers: { 68 | 'Authorization': 'Client-ID ' + this._clientID 69 | }, 70 | form: { 71 | title: _params.title ? _params.title : null, 72 | description: _params.description ? _params.description : null 73 | } 74 | }; 75 | request.post(options, function (err, req, body) { 76 | if(err) { 77 | return _cb(err); 78 | } 79 | _cb(null, body); 80 | }); 81 | } 82 | }, 83 | getCredits: function(_cb) { 84 | if(this._clientID) { 85 | var options = { 86 | url: 'https://api.imgur.com/3/credits', 87 | headers: { 88 | 'Authorization': 'Client-ID ' + this._clientID 89 | } 90 | }; 91 | request(options, function (err, req, body) { 92 | if(err) { 93 | return _cb(err); 94 | } 95 | _cb(null, body); 96 | }); 97 | } 98 | } 99 | }; 100 | 101 | exports.setClientID = imgur.setClientID; 102 | exports.upload = imgur.upload; 103 | exports.update = imgur.update; 104 | exports.delete = imgur.delete; 105 | exports.getCredits = imgur.getCredits; --------------------------------------------------------------------------------