├── .dockerignore ├── uploads └── uploads.txt ├── .travis.yml ├── standalone.js ├── docker.env ├── test ├── modules │ ├── hapi-test.js │ ├── uuid-test.js │ ├── inert-test.js │ ├── tap-test.js │ └── unoconv2-test.js ├── routes │ └── routes-test.js └── handlers │ └── handlers-test.js ├── renovate.json ├── index.js ├── config └── index.js ├── Dockerfile ├── .gitignore ├── server.js ├── LICENSE ├── routes └── index.js ├── package.json ├── README.md ├── handlers └── index.js └── lib └── data └── formats.json /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json -------------------------------------------------------------------------------- /uploads/uploads.txt: -------------------------------------------------------------------------------- 1 | This is the uploads directory -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "10" 4 | after_success: 5 | - npm run coveralls -------------------------------------------------------------------------------- /standalone.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const server = require('./server') 4 | 5 | server.start() 6 | -------------------------------------------------------------------------------- /docker.env: -------------------------------------------------------------------------------- 1 | SERVER_PORT=3000 2 | PAYLOAD_MAX_SIZE=1048576 3 | PAYLOAD_TIMEOUT=120000 4 | TIMEOUT_SERVER=120000 5 | TIMEOUT_SOCKET=140000 -------------------------------------------------------------------------------- /test/modules/hapi-test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const tap = require('tap') 4 | const hapi = require('hapi') 5 | 6 | tap.ok(hapi, 'Hapi loads OK') 7 | -------------------------------------------------------------------------------- /test/modules/uuid-test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const tap = require('tap') 4 | const uuid = require('uuid') 5 | 6 | tap.ok(uuid, 'uuid loads OK') 7 | -------------------------------------------------------------------------------- /test/modules/inert-test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const tap = require('tap') 4 | const inert = require('inert') 5 | 6 | tap.ok(inert, 'Inert loads OK') 7 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "github>zrrrzzt/renovate-config" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /test/modules/tap-test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const tap = require('tap') 4 | 5 | tap.ok(tap, 'Tap loads OK') 6 | 7 | tap.equal(true, true, 'Tap works OK') 8 | -------------------------------------------------------------------------------- /test/modules/unoconv2-test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const tap = require('tap') 4 | const unoconv2 = require('unoconv2') 5 | 6 | tap.ok(unoconv2, 'unoconv2 loads OK') 7 | -------------------------------------------------------------------------------- /test/routes/routes-test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const tap = require('tap') 4 | const routes = require('../../routes') 5 | 6 | tap.equal(routes.length, 5, 'There are 5 routes') 7 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const routes = require('./routes') 4 | 5 | exports.register = (server, options, next) => { 6 | server.route(routes) 7 | 8 | next() 9 | } 10 | 11 | exports.register.attributes = { 12 | pkg: require('./package.json') 13 | } 14 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | module.exports = { 4 | SERVER_PORT: process.env.SERVER_PORT || 3000, 5 | PAYLOAD_MAX_SIZE: process.env.PAYLOAD_MAX_SIZE || 1048576, 6 | PAYLOAD_TIMEOUT: process.env.PAYLOAD_TIMEOUT || 60000 * 2, 7 | TIMEOUT_SERVER: process.env.TIMEOUT_SERVER || 60000 * 2, 8 | TIMEOUT_SOCKET: process.env.TIMEOUT_SOCKET || 70000 * 2 9 | } 10 | -------------------------------------------------------------------------------- /test/handlers/handlers-test.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const tap = require('tap') 4 | const handlers = require('../../handlers') 5 | 6 | tap.equal(Object.keys(handlers).length, 5, 'There are 5 handlers') 7 | 8 | tap.ok(handlers.handleUpload, 'Handler has method handleUpload') 9 | 10 | tap.ok(handlers.showFormats, 'Handler has method showFormats') 11 | 12 | tap.ok(handlers.showFormat, 'Handler has method showFormat') 13 | 14 | tap.ok(handlers.showVersions, 'Handler has method showVersions') 15 | 16 | tap.ok(handlers.healthcheck, 'Handler has method healthcheck') 17 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM telemark/docker-node-unoconv:10.20.1 2 | 3 | #### Begin setup #### 4 | 5 | # Bundle app source 6 | COPY . /src 7 | 8 | # Change working directory 9 | WORKDIR /src 10 | 11 | # Install dependencies 12 | RUN npm install --production 13 | 14 | # Env variables 15 | ENV SERVER_PORT 3000 16 | ENV PAYLOAD_MAX_SIZE 1048576 17 | ENV PAYLOAD_TIMEOUT 120000 18 | ENV TIMEOUT_SERVER 120000 19 | ENV TIMEOUT_SOCKET 140000 20 | 21 | # Expose 3000 22 | EXPOSE 3000 23 | 24 | # Startup 25 | ENTRYPOINT /usr/bin/unoconv --listener --server=0.0.0.0 --port=2002 & node standalone.js -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IDE 2 | .idea 3 | .vscode 4 | 5 | # OS X 6 | .DS_Store 7 | 8 | # Logs 9 | logs 10 | *.log 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | 17 | # Directory for instrumented libs generated by jscoverage/JSCover 18 | lib-cov 19 | 20 | # Coverage directory used by tools like istanbul 21 | coverage 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # node-waf configuration 27 | .lock-wscript 28 | 29 | # Compiled binary addons (http://nodejs.org/api/addons.html) 30 | build/Release 31 | 32 | # Dependency directory 33 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 34 | node_modules 35 | 36 | # Lockfiles 37 | package-lock.json 38 | 39 | # .env 40 | .env -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const Hapi = require('hapi') 4 | const Inert = require('inert') 5 | const server = new Hapi.Server() 6 | const config = require('./config') 7 | const unoconvService = require('./index') 8 | 9 | server.connection({ 10 | port: parseInt(config.SERVER_PORT, 10), 11 | routes: { 12 | cors: { 13 | credentials: true 14 | } 15 | } 16 | }) 17 | 18 | server.register([ 19 | { 20 | register: unoconvService, 21 | options: {} 22 | }, 23 | { 24 | register: Inert, 25 | options: {} 26 | } 27 | ], function (err) { 28 | if (err) { 29 | console.error('Failed to load a plugin:', err) 30 | } 31 | }) 32 | 33 | module.exports.start = () => { 34 | server.start(() => { 35 | console.log('Server running at:', server.info.uri) 36 | }) 37 | } 38 | 39 | module.exports.stop = () => { 40 | server.stop(() => { 41 | console.log('Server stopped') 42 | }) 43 | } 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Geir Gåsodden 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /routes/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const config = require('../config') 4 | const handlers = require('../handlers') 5 | 6 | module.exports = [ 7 | { 8 | method: 'POST', 9 | path: '/unoconv/{format}', 10 | config: { 11 | payload: { 12 | output: 'stream', 13 | parse: true, 14 | allow: 'multipart/form-data', 15 | maxBytes: parseInt(config.PAYLOAD_MAX_SIZE, 10), 16 | timeout: parseInt(config.PAYLOAD_TIMEOUT, 10) 17 | }, 18 | timeout: { 19 | server: parseInt(config.TIMEOUT_SERVER, 10), 20 | socket: parseInt(config.TIMEOUT_SOCKET, 10) 21 | }, 22 | handler: handlers.handleUpload 23 | } 24 | }, 25 | { 26 | method: 'GET', 27 | path: '/unoconv/formats', 28 | config: { 29 | handler: handlers.showFormats 30 | } 31 | }, 32 | { 33 | method: 'GET', 34 | path: '/unoconv/formats/{type}', 35 | config: { 36 | handler: handlers.showFormat 37 | } 38 | }, 39 | { 40 | method: 'GET', 41 | path: '/unoconv/versions', 42 | config: { 43 | handler: handlers.showVersions 44 | } 45 | }, 46 | { 47 | method: 'GET', 48 | path: '/healthz', 49 | config: { 50 | handler: handlers.healthcheck 51 | } 52 | } 53 | ] 54 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tfk-api-unoconv", 3 | "version": "3.2.5", 4 | "private": true, 5 | "description": "Unoconv as a webservice", 6 | "author": { 7 | "name": "Geir Gåsodden", 8 | "email": "geir.gasodden@pythonia.no", 9 | "url": "https://github.com/zrrrzzt" 10 | }, 11 | "license": "MIT", 12 | "bugs": { 13 | "url": "https://github.com/zrrrzzt/tfk-api-unoconv/issues" 14 | }, 15 | "homepage": "https://github.com/zrrrzzt/tfk-api-unoconv", 16 | "main": "index.js", 17 | "engines": { 18 | "node": ">=10.20.1" 19 | }, 20 | "scripts": { 21 | "test": "standard && npm audit && tap --reporter=spec test/**/*.js", 22 | "coverage": "tap test/*.js --coverage", 23 | "coveralls": "tap --cov --coverage-report=lcov test/**/*.js && cat coverage/lcov.info | coveralls", 24 | "start": "node standalone.js", 25 | "standard-fix": "standard --fix", 26 | "refresh": "rm -rf node_modules && rm package-lock.json && npm install" 27 | }, 28 | "repository": { 29 | "type": "git", 30 | "url": "git+https://github.com/zrrrzzt/tfk-api-unoconv.git" 31 | }, 32 | "dependencies": { 33 | "hapi": "16.7.0", 34 | "inert": "4.2.1", 35 | "unoconv2": "1.0.0", 36 | "uuid": "8.3.2" 37 | }, 38 | "devDependencies": { 39 | "coveralls": "3.1.1", 40 | "standard": "16.0.4", 41 | "tap": "15.1.5" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/zrrrzzt/tfk-api-unoconv.svg?branch=master)](https://travis-ci.org/zrrrzzt/tfk-api-unoconv) 2 | [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://github.com/feross/standard) 3 | 4 | # tfk-api-unoconv 5 | 6 | Unoconv as a webservice 7 | 8 | ## Docker 9 | 10 | Build image 11 | 12 | ```bash 13 | $ docker build -t unoconv-webservice . 14 | ``` 15 | 16 | Run image 17 | 18 | ```bash 19 | $ docker run -d -p 80:3000 --name unoconv-webservice unoconv-webservice 20 | ``` 21 | 22 | ## Usage 23 | 24 | Post the file you want to convert to the server and get the converted file in return. 25 | 26 | See all possible conversions on the [unoconv website](http://dag.wiee.rs/home-made/unoconv/). 27 | 28 | API for the webservice is /unoconv/{format-to-convert-to} so a docx to pdf would be 29 | 30 | ```bash 31 | $ curl --form file=@myfile.docx http://localhost/unoconv/pdf > myfile.pdf 32 | ``` 33 | 34 | ### Formats 35 | 36 | To see all possible formats for convertion visit ```/unoconv/formats``` 37 | 38 | To see formats for a given type ```/unoconv/formats/{document|graphics|presentation|spreadsheet}``` 39 | 40 | ### Versions 41 | 42 | To see all versions of installed dependencies lookup ```/unoconv/versions``` 43 | 44 | ### Healthz 45 | 46 | Are we alive? ```/healthz``` 47 | 48 | returns 49 | 50 | ```JavaScript 51 | { 52 | uptime: 18.849 53 | } 54 | ``` 55 | 56 | ## Environment 57 | 58 | You can change the webservice port and filesize-limit by changing environment variables. 59 | 60 | SERVER_PORT default is 3000 61 | 62 | PAYLOAD_MAX_SIZE default is 1048576 (1 MB) 63 | 64 | PAYLOAD_TIMEOUT default is 2 minutes (120 000 milliseconds) 65 | 66 | TIMEOUT_SERVER default is 2 minutes (120 000 milliseconds) 67 | 68 | TIMEOUT_SOCKET default is 2 minutes and 20 seconds (140 000 milliseconds) 69 | 70 | Change it in the Dockerfile or create an env-file and load it at containerstart 71 | 72 | ```bash 73 | $ docker run --env-file=docker.env -d -p 80:3000 --name unoconv-webservice unoconv-webservice 74 | ``` 75 | 76 | ## License 77 | 78 | [MIT](LICENSE) 79 | -------------------------------------------------------------------------------- /handlers/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const fs = require('fs') 4 | const { v4: uuid } = require('uuid') 5 | const unoconv = require('unoconv2') 6 | const formats = require('../lib/data/formats.json') 7 | const pkg = require('../package.json') 8 | 9 | module.exports.handleUpload = (request, reply) => { 10 | const convertToFormat = request.params.format 11 | const data = request.payload 12 | if (data.file) { 13 | const nameArray = data.file.hapi.filename.split('.') 14 | const fileEndingOriginal = nameArray.pop() 15 | const temporaryName = uuid() 16 | const pathPre = process.cwd() + '/uploads/' + temporaryName 17 | const fileNameTempOriginal = pathPre + '.' + fileEndingOriginal 18 | const file = fs.createWriteStream(fileNameTempOriginal) 19 | 20 | file.on('error', (error) => { 21 | console.error(error) 22 | }) 23 | 24 | data.file.pipe(file) 25 | 26 | data.file.on('end', (err) => { 27 | if (err) { 28 | console.error(err) 29 | reply(err) 30 | } else { 31 | unoconv.convert(fileNameTempOriginal, convertToFormat, (err, result) => { 32 | if (err) { 33 | console.error(err) 34 | fs.unlink(fileNameTempOriginal, error => { 35 | if (error) { 36 | console.error(error) 37 | } else { 38 | console.log(`${fileNameTempOriginal} deleted`) 39 | } 40 | }) 41 | reply(err) 42 | } else { 43 | console.log('finished converting') 44 | reply(result) 45 | .on('finish', () => { 46 | fs.unlink(fileNameTempOriginal, error => { 47 | if (error) { 48 | console.error(error) 49 | } else { 50 | console.log(`${fileNameTempOriginal} deleted`) 51 | } 52 | }) 53 | }) 54 | } 55 | }) 56 | } 57 | }) 58 | } 59 | } 60 | 61 | module.exports.showFormats = (request, reply) => { 62 | reply(formats) 63 | } 64 | 65 | module.exports.showFormat = (request, reply) => { 66 | const params = request.params 67 | const format = params ? formats[request.params.type] : false 68 | if (!format) { 69 | reply('Format type not found').code(404) 70 | } else { 71 | reply(format) 72 | } 73 | } 74 | 75 | module.exports.showVersions = (request, reply) => { 76 | const versions = {} 77 | Object.keys(pkg.dependencies).forEach((item) => { 78 | versions[item] = pkg.dependencies[item] 79 | }) 80 | reply(versions) 81 | } 82 | 83 | module.exports.healthcheck = (request, reply) => { 84 | reply({ uptime: process.uptime() }) 85 | } 86 | -------------------------------------------------------------------------------- /lib/data/formats.json: -------------------------------------------------------------------------------- 1 | { 2 | "document": [ 3 | { 4 | "format": "bib", 5 | "extension": "bib", 6 | "description": "BibTeX", 7 | "mime": "application/octet-stream" 8 | }, 9 | { 10 | "format": "doc", 11 | "extension": "doc", 12 | "description": "Microsoft Word 97/2000/XP", 13 | "mime": "application/msword" 14 | }, 15 | { 16 | "format": "doc6", 17 | "extension": "doc", 18 | "description": "Microsoft Word 6.0", 19 | "mime": "application/msword" 20 | }, 21 | { 22 | "format": "doc95", 23 | "extension": "doc", 24 | "description": "Microsoft Word 95", 25 | "mime": "application/msword" 26 | }, 27 | { 28 | "format": "docbook", 29 | "extension": "xml", 30 | "description": "DocBook", 31 | "mime": "application/xml" 32 | }, 33 | { 34 | "format": "docx", 35 | "extension": "docx", 36 | "description": "Microsoft Office Open XML", 37 | "mime": "application/vnd.openxmlformats-officedocument.wordprocessingml.document" 38 | }, 39 | { 40 | "format": "docx7", 41 | "extension": "docx", 42 | "description": "Microsoft Office Open XML", 43 | "mime": "application/vnd.openxmlformats-officedocument.wordprocessingml.document" 44 | }, 45 | { 46 | "format": "fodt", 47 | "extension": "fodt", 48 | "description": "OpenDocument Text (Flat XML)", 49 | "mime": "application/octet-stream" 50 | }, 51 | { 52 | "format": "html", 53 | "extension": "html", 54 | "description": "HTML Document (OpenOffice.org Writer)", 55 | "mime": "text/html" 56 | }, 57 | { 58 | "format": "latex", 59 | "extension": "ltx", 60 | "description": "LaTeX 2e", 61 | "mime": "application/octet-stream" 62 | }, 63 | { 64 | "format": "mediawiki", 65 | "extension": "txt", 66 | "description": "MediaWiki", 67 | "mime": "text/plain" 68 | }, 69 | { 70 | "format": "odt", 71 | "extension": "odt", 72 | "description": "ODF Text Document", 73 | "mime": "application/vnd.oasis.opendocument.text" 74 | }, 75 | { 76 | "format": "ooxml", 77 | "extension": "xml", 78 | "description": "Microsoft Office Open XML", 79 | "mime": "application/xml" 80 | }, 81 | { 82 | "format": "ott", 83 | "extension": "ott", 84 | "description": "Open Document Text", 85 | "mime": "application/vnd.oasis.opendocument.text-template" 86 | }, 87 | { 88 | "format": "pdb", 89 | "extension": "pdb", 90 | "description": "AportisDoc (Palm)", 91 | "mime": "application/vnd.palm" 92 | }, 93 | { 94 | "format": "pdf", 95 | "extension": "pdf", 96 | "description": "Portable Document Format", 97 | "mime": "application/pdf" 98 | }, 99 | { 100 | "format": "psw", 101 | "extension": "psw", 102 | "description": "Pocket Word", 103 | "mime": "application/octet-stream" 104 | }, 105 | { 106 | "format": "rtf", 107 | "extension": "rtf", 108 | "description": "Rich Text Format", 109 | "mime": "application/rtf" 110 | }, 111 | { 112 | "format": "sdw", 113 | "extension": "sdw", 114 | "description": "StarWriter 5.0", 115 | "mime": "application/vnd.stardivision.writer" 116 | }, 117 | { 118 | "format": "sdw4", 119 | "extension": "sdw", 120 | "description": "StarWriter 4.0", 121 | "mime": "application/vnd.stardivision.writer" 122 | }, 123 | { 124 | "format": "sdw3", 125 | "extension": "sdw", 126 | "description": "StarWriter 3.0", 127 | "mime": "application/vnd.stardivision.writer" 128 | }, 129 | { 130 | "format": "stw", 131 | "extension": "stw", 132 | "description": "Open Office.org 1.0 Text Document Template", 133 | "mime": "application/vnd.sun.xml.writer.template" 134 | }, 135 | { 136 | "format": "sxw", 137 | "extension": "sxw", 138 | "description": "Open Office.org 1.0 Text Document", 139 | "mime": "application/vnd.sun.xml.writer" 140 | }, 141 | { 142 | "format": "text", 143 | "extension": "txt", 144 | "description": "Text Encoded", 145 | "mime": "text/plain" 146 | }, 147 | { 148 | "format": "txt", 149 | "extension": "txt", 150 | "description": "Text", 151 | "mime": "text/plain" 152 | }, 153 | { 154 | "format": "uot", 155 | "extension": "uot", 156 | "description": "Unified Office Format text", 157 | "mime": "application/octet-stream" 158 | }, 159 | { 160 | "format": "vor", 161 | "extension": "vor", 162 | "description": "StarWriter 5.0 Template", 163 | "mime": "application/vnd.stardivision.writer" 164 | }, 165 | { 166 | "format": "vor4", 167 | "extension": "vor", 168 | "description": "StarWriter 4.0 Template", 169 | "mime": "application/vnd.stardivision.writer" 170 | }, 171 | { 172 | "format": "vor3", 173 | "extension": "vor", 174 | "description": "StarWriter 3.0 Template", 175 | "mime": "application/vnd.stardivision.writer" 176 | }, 177 | { 178 | "format": "wps", 179 | "extension": "wps", 180 | "description": "Microsoft Works", 181 | "mime": "application/vnd.ms-works" 182 | }, 183 | { 184 | "format": "xhtml", 185 | "extension": "html", 186 | "description": "XHTML Document", 187 | "mime": "text/html" 188 | } 189 | ], 190 | "graphics": [ 191 | { 192 | "format": "bmp", 193 | "extension": "bmp", 194 | "description": "Windows Bitmap", 195 | "mime": "image/bmp" 196 | }, 197 | { 198 | "format": "emf", 199 | "extension": "emf", 200 | "description": "Enhanced Metafile", 201 | "mime": "application/x-msmetafile" 202 | }, 203 | { 204 | "format": "eps", 205 | "extension": "eps", 206 | "description": "Encapsulated PostScript", 207 | "mime": "application/postscript" 208 | }, 209 | { 210 | "format": "fodg", 211 | "extension": "fodg", 212 | "description": "OpenDocument Drawing (Flat XML)", 213 | "mime": "application/octet-stream" 214 | }, 215 | { 216 | "format": "gif", 217 | "extension": "gif", 218 | "description": "Graphics Interchange Format", 219 | "mime": "image/gif" 220 | }, 221 | { 222 | "format": "html", 223 | "extension": "html", 224 | "description": "HTML Document (OpenOffice.org Draw)", 225 | "mime": "text/html" 226 | }, 227 | { 228 | "format": "jpg", 229 | "extension": "jpg", 230 | "description": "Joint Photographic Experts Group", 231 | "mime": "image/jpeg" 232 | }, 233 | { 234 | "format": "met", 235 | "extension": "met", 236 | "description": "OS/2 Metafile", 237 | "mime": "application/octet-stream" 238 | }, 239 | { 240 | "format": "odd", 241 | "extension": "odd", 242 | "description": "OpenDocument Drawing", 243 | "mime": "application/octet-stream" 244 | }, 245 | { 246 | "format": "otg", 247 | "extension": "otg", 248 | "description": "OpenDocument Drawing Template", 249 | "mime": "application/vnd.oasis.opendocument.graphics-template" 250 | }, 251 | { 252 | "format": "pbm", 253 | "extension": "pbm", 254 | "description": "Portable Bitmap", 255 | "mime": "image/x-portable-bitmap" 256 | }, 257 | { 258 | "format": "pct", 259 | "extension": "pct", 260 | "description": "Mac Pict", 261 | "mime": "image/x-pict" 262 | }, 263 | { 264 | "format": "pdf", 265 | "extension": "pdf", 266 | "description": "Portable Document Format", 267 | "mime": "application/pdf" 268 | }, 269 | { 270 | "format": "pgm", 271 | "extension": "pgm", 272 | "description": "Portable Graymap", 273 | "mime": "image/x-portable-graymap" 274 | }, 275 | { 276 | "format": "png", 277 | "extension": "png", 278 | "description": "Portable Network Graphic", 279 | "mime": "image/png" 280 | }, 281 | { 282 | "format": "ppm", 283 | "extension": "ppm", 284 | "description": "Portable Pixelmap", 285 | "mime": "image/x-portable-pixmap" 286 | }, 287 | { 288 | "format": "ras", 289 | "extension": "ras", 290 | "description": "Sun Raster Image", 291 | "mime": "image/x-cmu-raster" 292 | }, 293 | { 294 | "format": "std", 295 | "extension": "std", 296 | "description": "OpenOffice.org 1.0 Drawing Template", 297 | "mime": "application/vnd.sun.xml.draw.template" 298 | }, 299 | { 300 | "format": "svg", 301 | "extension": "svg", 302 | "description": "Scalable Vector Graphics", 303 | "mime": "image/svg+xml" 304 | }, 305 | { 306 | "format": "svm", 307 | "extension": "svm", 308 | "description": "StarView Metafile", 309 | "mime": "application/octet-stream" 310 | }, 311 | { 312 | "format": "swf", 313 | "extension": "swf", 314 | "description": "Macromedia Flash (SWF)", 315 | "mime": "application/x-shockwave-flash" 316 | }, 317 | { 318 | "format": "sxd", 319 | "extension": "sxd", 320 | "description": "OpenOffice.org 1.0 Drawing", 321 | "mime": "application/vnd.sun.xml.draw" 322 | }, 323 | { 324 | "format": "sxd3", 325 | "extension": "sxd", 326 | "description": "StarDraw 3.0", 327 | "mime": "application/vnd.sun.xml.draw" 328 | }, 329 | { 330 | "format": "sxd5", 331 | "extension": "sxd", 332 | "description": "StarDraw 5.0", 333 | "mime": "application/vnd.sun.xml.draw" 334 | }, 335 | { 336 | "format": "sxw", 337 | "extension": "sxw", 338 | "description": "StarOffice XML (Draw)", 339 | "mime": "application/vnd.sun.xml.writer" 340 | }, 341 | { 342 | "format": "tiff", 343 | "extension": "tiff", 344 | "description": "Tagged Image File Format", 345 | "mime": "image/tiff" 346 | }, 347 | { 348 | "format": "vor", 349 | "extension": "vor", 350 | "description": "StarDraw 5.0 Template", 351 | "mime": "application/vnd.stardivision.writer" 352 | }, 353 | { 354 | "format": "vor3", 355 | "extension": "vor", 356 | "description": "StarDraw 3.0 Template", 357 | "mime": "application/vnd.stardivision.writer" 358 | }, 359 | { 360 | "format": "wmf", 361 | "extension": "wmf", 362 | "description": "Windows Metafile", 363 | "mime": "application/x-msmetafile" 364 | }, 365 | { 366 | "format": "xhtml", 367 | "extension": "xhtml", 368 | "description": "XHTML", 369 | "mime": "application/xhtml+xml" 370 | }, 371 | { 372 | "format": "xpm", 373 | "extension": "xpm", 374 | "description": "X PixMap", 375 | "mime": "image/x-xpixmap" 376 | } 377 | ], 378 | "presentation": [ 379 | { 380 | "format": "bmp", 381 | "extension": "bmp", 382 | "description": "Windows Bitmap", 383 | "mime": "image/bmp" 384 | }, 385 | { 386 | "format": "emf", 387 | "extension": "emf", 388 | "description": "Enhanced Metafile", 389 | "mime": "application/x-msmetafile" 390 | }, 391 | { 392 | "format": "eps", 393 | "extension": "eps", 394 | "description": "Encapsulated PostScript", 395 | "mime": "application/postscript" 396 | }, 397 | { 398 | "format": "fodp", 399 | "extension": "fodp", 400 | "description": "OpenDocument Presentation (Flat XML)", 401 | "mime": "application/octet-stream" 402 | }, 403 | { 404 | "format": "gif", 405 | "extension": "gif", 406 | "description": "Graphics Interchange Format", 407 | "mime": "image/gif" 408 | }, 409 | { 410 | "format": "html", 411 | "extension": "html", 412 | "description": "HTML Document (OpenOffice.org Impress)", 413 | "mime": "text/html" 414 | }, 415 | { 416 | "format": "jpg", 417 | "extension": "jpg", 418 | "description": "Joint Photographic Experts Group", 419 | "mime": "image/jpeg" 420 | }, 421 | { 422 | "format": "met", 423 | "extension": "met", 424 | "description": "OS/2 Metafile", 425 | "mime": "application/octet-stream" 426 | }, 427 | { 428 | "format": "odg", 429 | "extension": "odg", 430 | "description": "ODF Drawing (Impress)", 431 | "mime": "application/vnd.oasis.opendocument.graphics" 432 | }, 433 | { 434 | "format": "odp", 435 | "extension": "odp", 436 | "description": "ODF Presentation", 437 | "mime": "application/vnd.oasis.opendocument.presentation" 438 | }, 439 | { 440 | "format": "otp", 441 | "extension": "otp", 442 | "description": "ODF Presentation Template", 443 | "mime": "application/vnd.oasis.opendocument.presentation-template" 444 | }, 445 | { 446 | "format": "pbm", 447 | "extension": "pbm", 448 | "description": "Portable Bitmap", 449 | "mime": "image/x-portable-bitmap" 450 | }, 451 | { 452 | "format": "pct", 453 | "extension": "pct", 454 | "description": "Mac Pict", 455 | "mime": "image/x-pict" 456 | }, 457 | { 458 | "format": "pdf", 459 | "extension": "pdf", 460 | "description": "Portable Document Format", 461 | "mime": "application/pdf" 462 | }, 463 | { 464 | "format": "pgm", 465 | "extension": "pgm", 466 | "description": "Portable Graymap", 467 | "mime": "image/x-portable-graymap" 468 | }, 469 | { 470 | "format": "png", 471 | "extension": "png", 472 | "description": "Portable Network Graphic", 473 | "mime": "image/png" 474 | }, 475 | { 476 | "format": "potm", 477 | "extension": "potm", 478 | "description": "Microsoft PowerPoint 2007/2010 XML Template", 479 | "mime": "application/vnd.ms-powerpoint.template.macroenabled.12" 480 | }, 481 | { 482 | "format": "pot", 483 | "extension": "pot", 484 | "description": "Microsoft PowerPoint 97/2000/XP Template", 485 | "mime": "application/vnd.ms-powerpoint" 486 | }, 487 | { 488 | "format": "ppm", 489 | "extension": "ppm", 490 | "description": "Portable Pixelmap", 491 | "mime": "image/x-portable-pixmap" 492 | }, 493 | { 494 | "format": "pptx", 495 | "extension": "pptx", 496 | "description": "Microsoft PowerPoint 2007/2010 XML", 497 | "mime": "application/vnd.openxmlformats-officedocument.presentationml.presentation" 498 | }, 499 | { 500 | "format": "pps", 501 | "extension": "pps", 502 | "description": "Microsoft PowerPoint 97/2000/XP (Autoplay)", 503 | "mime": "application/vnd.ms-powerpoint" 504 | }, 505 | { 506 | "format": "ppt", 507 | "extension": "ppt", 508 | "description": "Microsoft PowerPoint 97/2000/XP", 509 | "mime": "application/vnd.ms-powerpoint" 510 | }, 511 | { 512 | "format": "pwp", 513 | "extension": "pwp", 514 | "description": "PlaceWare", 515 | "mime": "application/octet-stream" 516 | }, 517 | { 518 | "format": "ras", 519 | "extension": "ras", 520 | "description": "Sun Raster Image", 521 | "mime": "image/x-cmu-raster" 522 | }, 523 | { 524 | "format": "sda", 525 | "extension": "sda", 526 | "description": "StarDraw 5.0 (OpenOffice.org Impress)", 527 | "mime": "application/vnd.stardivision.draw" 528 | }, 529 | { 530 | "format": "sdd", 531 | "extension": "sdd", 532 | "description": "StarImpress 5.0", 533 | "mime": "application/vnd.stardivision.impress" 534 | }, 535 | { 536 | "format": "sdd3", 537 | "extension": "sdd", 538 | "description": "StarDraw 3.0 (OpenOffice.org Impress)", 539 | "mime": "application/vnd.stardivision.impress" 540 | }, 541 | { 542 | "format": "sdd4", 543 | "extension": "sdd", 544 | "description": "StarImpress 4.0", 545 | "mime": "application/vnd.stardivision.impress" 546 | }, 547 | { 548 | "format": "sxd", 549 | "extension": "sxd", 550 | "description": "OpenOffice.org 1.0 Drawing (OpenOffice.org Impress)", 551 | "mime": "application/vnd.sun.xml.draw" 552 | }, 553 | { 554 | "format": "sti", 555 | "extension": "sti", 556 | "description": "OpenOffice.org 1.0 Presentation Template", 557 | "mime": "application/vnd.sun.xml.impress.template" 558 | }, 559 | { 560 | "format": "svg", 561 | "extension": "svg", 562 | "description": "Scalable Vector Graphics", 563 | "mime": "image/svg+xml" 564 | }, 565 | { 566 | "format": "svm", 567 | "extension": "svm", 568 | "description": "StarView Metafile", 569 | "mime": "application/octet-stream" 570 | }, 571 | { 572 | "format": "swf", 573 | "extension": "swf", 574 | "description": "Macromedia Flash (SWF)", 575 | "mime": "application/x-shockwave-flash" 576 | }, 577 | { 578 | "format": "sxi", 579 | "extension": "sxi", 580 | "description": "OpenOffice.org 1.0 Presentation", 581 | "mime": "application/vnd.sun.xml.impress" 582 | }, 583 | { 584 | "format": "tiff", 585 | "extension": "tiff", 586 | "description": "Tagged Image File Format", 587 | "mime": "image/tiff" 588 | }, 589 | { 590 | "format": "uop", 591 | "extension": "uop", 592 | "description": "Unified Office Format presentation", 593 | "mime": "application/octet-stream" 594 | }, 595 | { 596 | "format": "vor", 597 | "extension": "vor", 598 | "description": "StarImpress 5.0 Template", 599 | "mime": "application/vnd.stardivision.writer" 600 | }, 601 | { 602 | "format": "vor3", 603 | "extension": "vor", 604 | "description": "StarDraw 3.0 Template (OpenOffice.org Impress)", 605 | "mime": "application/vnd.stardivision.writer" 606 | }, 607 | { 608 | "format": "vor4", 609 | "extension": "vor", 610 | "description": "StarImpress 4.0 Template", 611 | "mime": "application/vnd.stardivision.writer" 612 | }, 613 | { 614 | "format": "vor5", 615 | "extension": "vor", 616 | "description": "StarDraw 5.0 Template (OpenOffice.org Impress)", 617 | "mime": "application/vnd.stardivision.writer" 618 | }, 619 | { 620 | "format": "wmf", 621 | "extension": "wmf", 622 | "description": "Windows Metafile", 623 | "mime": "application/x-msmetafile" 624 | }, 625 | { 626 | "format": "xhtml", 627 | "extension": "xml", 628 | "description": "XHTML", 629 | "mime": "application/xml" 630 | }, 631 | { 632 | "format": "xpm", 633 | "extension": "xpm", 634 | "description": "X PixMap", 635 | "mime": "image/x-xpixmap" 636 | } 637 | ], 638 | "spreadsheet": [ 639 | { 640 | "format": "csv", 641 | "extension": "csv", 642 | "description": "Text CSV", 643 | "mime": "text/csv" 644 | }, 645 | { 646 | "format": "dbf", 647 | "extension": "dbf", 648 | "description": "dBASE", 649 | "mime": "application/octet-stream" 650 | }, 651 | { 652 | "format": "dif", 653 | "extension": "dif", 654 | "description": "Data Interchange Format", 655 | "mime": "application/octet-stream" 656 | }, 657 | { 658 | "format": "fods", 659 | "extension": "fods", 660 | "description": "OpenDocument Spreadsheet (Flat XML)", 661 | "mime": "application/octet-stream" 662 | }, 663 | { 664 | "format": "html", 665 | "extension": "html", 666 | "description": "HTML Document (OpenOffice.org Calc)", 667 | "mime": "text/html" 668 | }, 669 | { 670 | "format": "ods", 671 | "extension": "ods", 672 | "description": "ODF Spreadsheet", 673 | "mime": "application/vnd.oasis.opendocument.spreadsheet" 674 | }, 675 | { 676 | "format": "ooxml", 677 | "extension": "xml", 678 | "description": "Microsoft Excel 2003 XML", 679 | "mime": "application/xml" 680 | }, 681 | { 682 | "format": "ots", 683 | "extension": "ots", 684 | "description": "ODF Spreadsheet Template", 685 | "mime": "application/vnd.oasis.opendocument.spreadsheet-template" 686 | }, 687 | { 688 | "format": "pdf", 689 | "extension": "pdf", 690 | "description": "Portable Document Format", 691 | "mime": "application/pdf" 692 | }, 693 | { 694 | "format": "pxl", 695 | "extension": "pxl", 696 | "description": "Pocket Excel", 697 | "mime": "application/octet-stream" 698 | }, 699 | { 700 | "format": "sdc", 701 | "extension": "sdc", 702 | "description": "StarCalc 5.0", 703 | "mime": "application/vnd.stardivision.calc" 704 | }, 705 | { 706 | "format": "sdc4", 707 | "extension": "sdc", 708 | "description": "StarCalc 4.0", 709 | "mime": "application/vnd.stardivision.calc" 710 | }, 711 | { 712 | "format": "sdc3", 713 | "extension": "sdc", 714 | "description": "StarCalc 3.0", 715 | "mime": "application/vnd.stardivision.calc" 716 | }, 717 | { 718 | "format": "slk", 719 | "extension": "slk", 720 | "description": "SYLK", 721 | "mime": "application/octet-stream" 722 | }, 723 | { 724 | "format": "stc", 725 | "extension": "stc", 726 | "description": "OpenOffice.org 1.0 Spreadsheet Template", 727 | "mime": "application/vnd.sun.xml.calc.template" 728 | }, 729 | { 730 | "format": "sxc", 731 | "extension": "sxc", 732 | "description": "OpenOffice.org 1.0 Spreadsheet", 733 | "mime": "application/vnd.sun.xml.calc" 734 | }, 735 | { 736 | "format": "uos", 737 | "extension": "uos", 738 | "description": "Unified Office Format spreadsheet", 739 | "mime": "application/octet-stream" 740 | }, 741 | { 742 | "format": "vor3", 743 | "extension": "vor", 744 | "description": "StarCalc 3.0 Template", 745 | "mime": "application/vnd.stardivision.writer" 746 | }, 747 | { 748 | "format": "vor4", 749 | "extension": "vor", 750 | "description": "StarCalc 4.0 Template", 751 | "mime": "application/vnd.stardivision.writer" 752 | }, 753 | { 754 | "format": "vor", 755 | "extension": "vor", 756 | "description": "StarCalc 5.0 Template", 757 | "mime": "application/vnd.stardivision.writer" 758 | }, 759 | { 760 | "format": "xhtml", 761 | "extension": "xhtml", 762 | "description": "XHTML", 763 | "mime": "application/xhtml+xml" 764 | }, 765 | { 766 | "format": "xls", 767 | "extension": "xls", 768 | "description": "Microsoft Excel 97/2000/XP", 769 | "mime": "application/vnd.ms-excel" 770 | }, 771 | { 772 | "format": "xls5", 773 | "extension": "xls", 774 | "description": "Microsoft Excel 5.0", 775 | "mime": "application/vnd.ms-excel" 776 | }, 777 | { 778 | "format": "xls95", 779 | "extension": "xls", 780 | "description": "Microsoft Excel 95", 781 | "mime": "application/vnd.ms-excel" 782 | }, 783 | { 784 | "format": "xlt", 785 | "extension": "xlt", 786 | "description": "Microsoft Excel 97/2000/XP Template", 787 | "mime": "application/vnd.ms-excel" 788 | }, 789 | { 790 | "format": "xlt5", 791 | "extension": "xlt", 792 | "description": "Microsoft Excel 5.0 Template", 793 | "mime": "application/vnd.ms-excel" 794 | }, 795 | { 796 | "format": "xlt95", 797 | "extension": "xlt", 798 | "description": "Microsoft Excel 95 Template", 799 | "mime": "application/vnd.ms-excel" 800 | }, 801 | { 802 | "format": "xlsx", 803 | "extension": "xlsx", 804 | "description": "Microsoft Excel 2007/2010 XML", 805 | "mime": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" 806 | } 807 | ] 808 | } --------------------------------------------------------------------------------