├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── values
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── strings.xml
│ │ │ │ ├── colors.xml
│ │ │ │ └── styles.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ ├── menu
│ │ │ │ └── menu_main.xml
│ │ │ ├── layout
│ │ │ │ ├── content_main.xml
│ │ │ │ ├── list_item.xml
│ │ │ │ └── activity_main.xml
│ │ │ ├── drawable-v24
│ │ │ │ └── ic_launcher_foreground.xml
│ │ │ └── drawable
│ │ │ │ └── ic_launcher_background.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── munkurious
│ │ │ │ └── sheetplayer
│ │ │ │ ├── ListData.kt
│ │ │ │ ├── RecyclerViewAdapter.kt
│ │ │ │ ├── FilePathFromUri.java
│ │ │ │ └── MainActivity.kt
│ │ └── AndroidManifest.xml
│ ├── test
│ │ └── java
│ │ │ └── com
│ │ │ └── munkurious
│ │ │ └── sheetplayer
│ │ │ └── ExampleUnitTest.kt
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── munkurious
│ │ └── sheetplayer
│ │ └── ExampleInstrumentedTest.kt
├── release
│ └── output.json
├── proguard-rules.pro
└── build.gradle
├── settings.gradle
├── keystore.jks
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── sheetplayer-server
├── sheetplayer-server
│ ├── func.js.save
│ ├── func.js
│ ├── package.json
│ ├── app.js
│ ├── yes
│ ├── routes.js
│ └── package-lock.json
└── audiveris
│ └── test04.py
├── .idea
├── runConfigurations.xml
└── gradle.xml
├── gradle.properties
├── README.md
├── gradlew.bat
├── .gitignore
└── gradlew
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':scanlibrary'
2 |
--------------------------------------------------------------------------------
/keystore.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bstncartwright/SheetPlayer-ocr/HEAD/keystore.jks
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 16dp
3 |
4 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bstncartwright/SheetPlayer-ocr/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bstncartwright/SheetPlayer-ocr/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bstncartwright/SheetPlayer-ocr/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bstncartwright/SheetPlayer-ocr/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bstncartwright/SheetPlayer-ocr/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bstncartwright/SheetPlayer-ocr/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bstncartwright/SheetPlayer-ocr/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bstncartwright/SheetPlayer-ocr/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bstncartwright/SheetPlayer-ocr/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bstncartwright/SheetPlayer-ocr/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bstncartwright/SheetPlayer-ocr/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/release/output.json:
--------------------------------------------------------------------------------
1 | [{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1},"path":"app-release.apk","properties":{"packageId":"com.munkurious.sheetplayer","split":"","minSdkVersion":"23"}}]
--------------------------------------------------------------------------------
/app/src/main/java/com/munkurious/sheetplayer/ListData.kt:
--------------------------------------------------------------------------------
1 | package com.munkurious.sheetplayer
2 |
3 | import android.graphics.Bitmap
4 |
5 | /**
6 | * Created by Boston on 10/23/2017.
7 | */
8 | data class MyData(var text:String, var image:Bitmap)
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | SheetPlayer
3 | Settings
4 | Choose from Files
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Oct 23 13:46:01 EDT 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/test/java/com/munkurious/sheetplayer/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.munkurious.sheetplayer
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest
13 | {
14 | @Test
15 | fun addition_isCorrect()
16 | {
17 | assertEquals(4, 2 + 2)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/sheetplayer-server/sheetplayer-server/func.js.save:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 |
3 |
4 | async function sendTransfer(file) {
5 | const util = require('util');
6 |
7 |
8 | const { stdout, stderr } = await exec("/home/kd0euh/audiveris/audiveris/test04.py" + " " + file + " " + dirname + "/outs/");
9 | const exec = util.promisify(require('child_process').exec);
10 |
11 |
12 | console.log('stdout:', stdout);
13 | var dirname = "C:/Users/Boston/Documents/sheetplayer-server/";
14 |
15 | console.log('stderr:', stderr);
16 |
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/sheetplayer-server/sheetplayer-server/func.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 |
3 | const util = require('util');
4 |
5 | const exec = util.promisify(require('child_process').exec);
6 |
7 | var dirname = "C:/Users/Boston/Documents/sheetplayer-server/";
8 |
9 | async function sendTransfer(file) {
10 |
11 |
12 | const { stdout, stderr } = await exec("/home/kd0euh/audiveris/audiveris/test04.py" + " " + file + " " + dirname + "/outs/");
13 |
14 |
15 | console.log('stdout:', stdout);
16 |
17 |
18 | console.log('stderr:', stderr);
19 |
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/sheetplayer-server/audiveris/test04.py:
--------------------------------------------------------------------------------
1 | import sys
2 | import os
3 | import subprocess
4 | import music21
5 |
6 | fpath = sys.argv[1]
7 | spath = sys.argv[2]
8 |
9 | returncode = subprocess.call(['gradle run -p /home/kd0euh/audiveris/audiveris -PcmdLineArgs=-batch,-export,-output,/home/kd0euh/audiveris/audiveris/output/,--,' + fpath], shell=True)
10 |
11 | base = os.path.basename(fpath)
12 | das = os.path.splitext(base)[0]
13 |
14 | c = music21.converter.parse('/home/kd0euh/audiveris/audiveris/output/' + das + '/' + das + '.mxl')
15 |
16 | c.write('midi', spath + '.mid')
17 |
18 | print('DONE')
19 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/sheetplayer-server/sheetplayer-server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sheetplayer-server",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "app.js",
6 | "dependencies": {
7 | "body-parser": "^1.18.2",
8 | "connect": "^3.6.5",
9 | "connect-multiparty": "^2.1.0",
10 | "cookie-parser": "^1.4.3",
11 | "express": "^4.16.2",
12 | "morgan": "^1.9.0",
13 | "python-shell": "^0.4.0",
14 | "system": "^2.0.1"
15 | },
16 | "devDependencies": {},
17 | "scripts": {
18 | "test": "echo \"Error: no test specified\" && exit 1"
19 | },
20 | "author": "",
21 | "license": "ISC"
22 | }
23 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/munkurious/sheetplayer/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.munkurious.sheetplayer
2 |
3 | import android.support.test.InstrumentationRegistry
4 | import android.support.test.runner.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest
18 | {
19 | @Test
20 | fun useAppContext()
21 | {
22 | // Context of the app under test.
23 | val appContext = InstrumentationRegistry.getTargetContext()
24 | assertEquals("com.munkurious.sheetplayer", appContext.packageName)
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/sheetplayer-server/sheetplayer-server/app.js:
--------------------------------------------------------------------------------
1 | //Based on tutorial from https://www.learn2crack.com/2014/08/android-upload-image-node-js-server.html
2 |
3 | /**
4 |
5 | * Module dependencies.
6 |
7 | */
8 |
9 | var express = require('express');
10 |
11 | var connect = require('connect');
12 |
13 | var cookieParser = require('cookie-parser');
14 |
15 | var logger = require('morgan');
16 |
17 | var bodyParser = require('body-parser');
18 |
19 | var app = express();
20 |
21 | var port = process.env.PORT || 8080;
22 |
23 |
24 | // Configuration
25 |
26 | app.use(express.static(__dirname + '/public'));
27 |
28 | app.use(cookieParser());
29 |
30 | app.use(logger('dev'));
31 |
32 | app.use(bodyParser());
33 |
34 |
35 | app.use(bodyParser.json());
36 |
37 | app.use(bodyParser.urlencoded());
38 |
39 |
40 | // Routes
41 |
42 |
43 | require('./routes.js')(app);
44 |
45 |
46 | app.listen(port);
47 |
48 | console.log('The App runs on port ' + port);
49 |
50 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
16 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
11 |
12 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SheetPlayer-ocr
2 | Reading pictures of sheet music and outputting them in audio files (midi).
3 |
4 | This was a personal project for me that I had motivation to do, and to learn lots of different things.
5 |
6 | In essence, the idea is that you can take a picture of a piece of sheet music with your android phone, and it would play it back to you audibly.
7 | It turned out to be a much larger project than I expected, and than I had the knowledge to do. However, thanks to great open source libraries I was able to get it to work, generally.
8 |
9 | ## Special thanks to:
10 |
11 | + [Audiveris (does all of the transcribing)](https://github.com/Audiveris/audiveris)
12 | + [Music21](http://web.mit.edu/music21/)
13 | + Stack Overflow (for teaching me how to do pretty much everything)
14 |
15 | ### Interested in using?
16 | It's actually kind of complicated but here is the general flow:
17 |
18 | Picture taken from phone >> Uploaded to Nodejs server >> nodejs server calls python script that calls Audiveris >> Audiveris transcribes >>
19 | once transcribing is done, python then converts a .mxl to a .midi for listening >> phone can download new .midi file for listening
20 |
21 | In order to use you would have to set up the nodejs server (found in /sheetplayer-server/) and edit the android application to connect to your server.
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/munkurious/sheetplayer/RecyclerViewAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.munkurious.sheetplayer
2 |
3 | import android.support.v7.widget.RecyclerView
4 | import android.util.Log
5 | import android.view.LayoutInflater
6 | import android.view.View
7 | import android.view.ViewGroup
8 | import android.widget.ImageView
9 | import android.widget.TextView
10 |
11 | /**
12 | * Created by Boston on 10/23/2017.
13 | */
14 | class RecyclerViewAdapter(val list:ArrayList, val activity:MainActivity):RecyclerView.Adapter() {
15 |
16 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewAdapter.ViewHolder {
17 | val v = LayoutInflater.from(parent.context).inflate(R.layout.list_item, parent, false)
18 | return ViewHolder(v, activity)
19 | }
20 |
21 | //this method is binding the data on the list
22 | override fun onBindViewHolder(holder: RecyclerViewAdapter.ViewHolder, position: Int) {
23 | holder.bindItems(list[position])
24 | }
25 |
26 | //this method is giving the size of the list
27 | override fun getItemCount(): Int {
28 | return list.size
29 | }
30 |
31 | class ViewHolder(view: View, val activity: MainActivity): RecyclerView.ViewHolder(view) {
32 | fun bindItems(data : MyData){
33 | val _textView:TextView = itemView.findViewById(R.id.textview)
34 | val _imageView:ImageView = itemView.findViewById(R.id.imageview)
35 | _textView.text = data.text
36 | _imageView.setImageBitmap(data.image)
37 |
38 | //set the onclick listener for the singlt list item
39 | itemView.setOnClickListener({
40 | Log.e("ItemClicked", data.text)
41 | activity.playSong(data.text)
42 | })
43 | }
44 |
45 | }
46 | }
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
13 |
14 |
18 |
19 |
26 |
27 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
21 |
22 |
23 |
24 |
27 |
28 |
38 |
39 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/sheetplayer-server/sheetplayer-server/yes:
--------------------------------------------------------------------------------
1 | //Based on tutorial from https://www.learn2crack.com/2014/08/android-upload-image-node-js-server.html
2 |
3 | var fs = require('fs');
4 |
5 | const util = require('util');
6 |
7 | const exec = util.promisify(require('child_process').exec);
8 |
9 | var dirname = "/home/kd0euh/audiveris/sheetplayer-server";
10 |
11 |
12 |
13 | module.exports = function(app) {
14 |
15 |
16 |
17 | app.get('/',function(req,res){
18 |
19 | res.end("Node-File-Upload");
20 |
21 |
22 | });
23 |
24 | app.post('/upload', function(req, res) {
25 |
26 | console.log(req.files.image.originalFilename);
27 |
28 | console.log(req.files.image.path);
29 |
30 | fs.readFile(req.files.image.path, function (err, data){
31 |
32 | var newPath = dirname + "/uploads/" + req.files.image.originalFilename;
33 |
34 | fs.writeFile(newPath, data, function (err) {
35 |
36 | if(err){
37 |
38 | res.json({'response':"Error"});
39 |
40 | }else {
41 |
42 | res.json({'response':"Saved"});
43 |
44 | sendTransfer(req.files.image.originalFilename);
45 |
46 | }
47 |
48 | });
49 |
50 | });
51 |
52 | });
53 |
54 |
55 |
56 | app.get('/uploads/:file', function (req, res){
57 |
58 | file = req.params.file;
59 |
60 | var img = fs.readFileSync(dirname + "/uploads/" + file);
61 |
62 | res.writeHead(200, {'Content-Type': 'image/jpg' });
63 |
64 | res.end(img, 'binary');
65 |
66 |
67 | });
68 |
69 | };
70 |
71 |
72 | app.get('/outs/:file', function (req, res){
73 |
74 | file = req.params.file;
75 |
76 | var img = fs.readFileSync(dirname + "/outs/" + file);
77 |
78 | res.writeHead(200, {'Content-Type': 'audio/midi' });
79 |
80 | res.end(img, 'binary');
81 |
82 |
83 | });
84 |
85 | };
86 |
87 |
88 | async function sendTransfer(file) {
89 |
90 | const { stdout, stderr } = await exec("/home/kd0euh/audiveris/audiveris/transfer.py" + " " + file + " " + dirname + "/outs/");
91 |
92 | console.log('stdout:', stdout);
93 |
94 | console.log('stderr:', stderr);
95 |
96 | }
97 |
98 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | apply plugin: 'kotlin-android'
4 |
5 | apply plugin: 'kotlin-android-extensions'
6 |
7 | android {
8 | compileSdkVersion 26
9 | buildToolsVersion "26.0.2"
10 | defaultConfig {
11 | applicationId "com.munkurious.sheetplayer"
12 | minSdkVersion 23
13 | targetSdkVersion 26
14 | versionCode 1
15 | versionName "1.0"
16 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
17 | }
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 | packagingOptions {
25 | exclude 'META-INF/NOTICE' // will not include NOTICE file
26 | exclude 'META-INF/LICENSE' // will not include LICENSE file
27 | // as noted by @Vishnuvathsan you may also need to include
28 | // variations on the file name. It depends on your dependencies.
29 | // Some other common variations on notice and license file names
30 | exclude 'META-INF/notice'
31 | exclude 'META-INF/notice.txt'
32 | exclude 'META-INF/license'
33 | exclude 'META-INF/license.txt'
34 | exclude 'META-INF/DEPENDENCIES'
35 | }
36 | }
37 |
38 | dependencies {
39 | implementation fileTree(dir: 'libs', include: ['*.jar'])
40 | implementation"org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
41 | implementation 'com.android.support:appcompat-v7:26.1.0'
42 | implementation 'com.android.support.constraint:constraint-layout:1.0.2'
43 | implementation 'com.android.support:design:26.1.0'
44 | testImplementation 'junit:junit:4.12'
45 | androidTestImplementation 'com.android.support.test:runner:1.0.1'
46 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
47 | implementation 'com.android.support:cardview-v7:26.1.0'
48 | compile 'net.the4thdimension:audio-wife:1.0.3'
49 | compile 'com.karumi:dexter:4.2.0'
50 | compile 'com.koushikdutta.async:androidasync:2.+'
51 | compile 'com.koushikdutta.ion:ion:2.+'
52 | compile 'org.apache.httpcomponents:httpcore:4.4'
53 | compile 'org.apache.httpcomponents:httpmime:4.4'
54 | compile project(':scanlibrary')
55 | }
56 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/sheetplayer-server/sheetplayer-server/routes.js:
--------------------------------------------------------------------------------
1 | //Based on tutorial from https://www.learn2crack.com/2014/08/android-upload-image-node-js-server.html
2 |
3 | var fs = require('fs');
4 |
5 | const util = require('util');
6 |
7 | var dirname = "/home/kd0euh/audiveris/sheetplayer-server";
8 |
9 | var multipart = require('connect-multiparty');
10 |
11 | const exec = util.promisify(require('child_process').exec);
12 |
13 | var pythonShell = require('python-shell');
14 |
15 | module.exports = function(app) {
16 |
17 |
18 |
19 | app.get('/',function(req,res){
20 |
21 | res.end("Node-File-Upload");
22 |
23 |
24 | });
25 |
26 | app.post('/upload', multipart(), function(req, res) {
27 |
28 | console.log(req.files.image.originalFilename);
29 |
30 | console.log(req.files.image.path);
31 |
32 | fs.readFile(req.files.image.path, function (err, data){
33 |
34 | var newPath = dirname + "/uploads/" + req.files.image.originalFilename;
35 |
36 | fs.writeFile(newPath, data, function (err) {
37 |
38 | if(err){
39 |
40 | res.json({'response':"Error"});
41 |
42 | }else {
43 |
44 | res.json({'response':"Saved"});
45 |
46 | sendTransfer(req.files.image.originalFilename);
47 |
48 | }
49 |
50 | });
51 |
52 | });
53 |
54 | });
55 |
56 |
57 |
58 | app.get('/uploads/:file', function (req, res){
59 |
60 | file = req.params.file;
61 |
62 | var img = fs.readFileSync(dirname + "/uploads/" + file);
63 |
64 | res.writeHead(200, {'Content-Type': 'image/*' });
65 |
66 | res.end(img, 'binary');
67 |
68 |
69 | });
70 |
71 |
72 | app.get('/outs/:file', function (req, res){
73 |
74 | file = req.params.file;
75 |
76 | var img = fs.readFileSync(dirname + "/outs/" + file);
77 |
78 | res.writeHead(200, {'Content-Type': 'audio/midi' });
79 |
80 | res.end(img, 'binary');
81 |
82 |
83 | });
84 |
85 | app.get('/outs', function (req, res){
86 |
87 | fs.readdir(dirname + "/outs/", function(err, items) {
88 | console.log("CALLED FOR OUTS LIST, SENDING");
89 | res.send(items);
90 | });
91 | });
92 |
93 | };
94 |
95 |
96 | async function sendTransfer(file) {
97 |
98 | console.log("CALLING PYTHON FUNCTION" + file);
99 | console.log("ARUGMENTS " + dirname + "/uploads/" + file + " --- " + dirname + "/outs/" + file);
100 |
101 | var options = {
102 | mode: 'text',
103 | scriptPath: '/home/kd0euh/audiveris/audiveris/',
104 | pythonPath: '/usr/bin/python3',
105 | args: [dirname + "/uploads/" + file, dirname + "/outs/" + file]};
106 |
107 | var pyShell = new pythonShell('test04.py', options);
108 | pyShell.on('message', function (message) {
109 | console.log(message);
110 | });
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.gitignore.io/api/node,androidstudio
3 |
4 | ### AndroidStudio ###
5 | # Covers files to be ignored for android development using Android Studio.
6 |
7 | # Built application files
8 | *.apk
9 | *.ap_
10 |
11 | # Files for the ART/Dalvik VM
12 | *.dex
13 |
14 | # Java class files
15 | *.class
16 |
17 | # Generated files
18 | bin/
19 | gen/
20 | out/
21 |
22 | # Gradle files
23 | .gradle
24 | .gradle/
25 | build/
26 |
27 | # Signing files
28 | .signing/
29 |
30 | # Local configuration file (sdk path, etc)
31 | local.properties
32 |
33 | # Proguard folder generated by Eclipse
34 | proguard/
35 |
36 | # Log Files
37 | *.log
38 |
39 | # Android Studio
40 | /*/build/
41 | /*/local.properties
42 | /*/out
43 | /*/*/build
44 | /*/*/production
45 | captures/
46 | .navigation/
47 | *.ipr
48 | *~
49 | *.swp
50 |
51 | # Android Patch
52 | gen-external-apklibs
53 |
54 | # External native build folder generated in Android Studio 2.2 and later
55 | .externalNativeBuild
56 |
57 | # NDK
58 | obj/
59 |
60 | # IntelliJ IDEA
61 | *.iml
62 | *.iws
63 | /out/
64 |
65 | # User-specific configurations
66 | .idea/libraries/
67 | .idea/workspace.xml
68 | .idea/tasks.xml
69 | .idea/.name
70 | .idea/compiler.xml
71 | .idea/copyright/profiles_settings.xml
72 | .idea/encodings.xml
73 | .idea/misc.xml
74 | .idea/modules.xml
75 | .idea/scopes/scope_settings.xml
76 | .idea/dictionaries
77 | .idea/vcs.xml
78 | .idea/jsLibraryMappings.xml
79 | .idea/datasources.xml
80 | .idea/dataSources.ids
81 | .idea/sqlDataSources.xml
82 | .idea/dynamic.xml
83 | .idea/uiDesigner.xml
84 |
85 | # OS-specific files
86 | .DS_Store
87 | .DS_Store?
88 | ._*
89 | .Spotlight-V100
90 | .Trashes
91 | ehthumbs.db
92 | Thumbs.db
93 |
94 | # Legacy Eclipse project files
95 | .classpath
96 | .project
97 |
98 | # Mobile Tools for Java (J2ME)
99 | .mtj.tmp/
100 |
101 | # Package Files #
102 | *.war
103 | *.ear
104 |
105 | # virtual machine crash logs (Reference: http://www.java.com/en/download/help/error_hotspot.xml)
106 | hs_err_pid*
107 |
108 | ## Plugin-specific files:
109 |
110 | # mpeltonen/sbt-idea plugin
111 | .idea_modules/
112 |
113 | # JIRA plugin
114 | atlassian-ide-plugin.xml
115 |
116 | # Mongo Explorer plugin
117 | .idea/mongoSettings.xml
118 |
119 | # Crashlytics plugin (for Android Studio and IntelliJ)
120 | com_crashlytics_export_strings.xml
121 | crashlytics.properties
122 | crashlytics-build.properties
123 | fabric.properties
124 |
125 | ### AndroidStudio Patch ###
126 |
127 | !/gradle/wrapper/gradle-wrapper.jar
128 |
129 | ### Node ###
130 | # Logs
131 | logs
132 | npm-debug.log*
133 | yarn-debug.log*
134 | yarn-error.log*
135 |
136 | # Runtime data
137 | pids
138 | *.pid
139 | *.seed
140 | *.pid.lock
141 |
142 | # Directory for instrumented libs generated by jscoverage/JSCover
143 | lib-cov
144 |
145 | # Coverage directory used by tools like istanbul
146 | coverage
147 |
148 | # nyc test coverage
149 | .nyc_output
150 |
151 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
152 | .grunt
153 |
154 | # Bower dependency directory (https://bower.io/)
155 | bower_components
156 |
157 | # node-waf configuration
158 | .lock-wscript
159 |
160 | # Compiled binary addons (http://nodejs.org/api/addons.html)
161 | build/Release
162 |
163 | # Dependency directories
164 | node_modules/
165 | jspm_packages/
166 |
167 | # Typescript v1 declaration files
168 | typings/
169 |
170 | # Optional npm cache directory
171 | .npm
172 |
173 | # Optional eslint cache
174 | .eslintcache
175 |
176 | # Optional REPL history
177 | .node_repl_history
178 |
179 | # Output of 'npm pack'
180 | *.tgz
181 |
182 | # Yarn Integrity file
183 | .yarn-integrity
184 |
185 | # dotenv environment variables file
186 | .env
187 |
188 |
189 | # End of https://www.gitignore.io/api/node,androidstudio
190 |
191 | scanlibrary/
192 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
11 |
16 |
21 |
26 |
31 |
36 |
41 |
46 |
51 |
56 |
61 |
66 |
71 |
76 |
81 |
86 |
91 |
96 |
101 |
106 |
111 |
116 |
121 |
126 |
131 |
136 |
141 |
146 |
151 |
156 |
161 |
166 |
171 |
172 |
--------------------------------------------------------------------------------
/app/src/main/java/com/munkurious/sheetplayer/FilePathFromUri.java:
--------------------------------------------------------------------------------
1 | package com.munkurious.sheetplayer;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.ContentUris;
5 | import android.content.Context;
6 | import android.database.Cursor;
7 | import android.net.Uri;
8 | import android.os.Build;
9 | import android.os.Environment;
10 | import android.provider.DocumentsContract;
11 | import android.provider.MediaStore;
12 |
13 | /**
14 | * Taken from https://stackoverflow.com/a/30829857/8697342
15 | */
16 |
17 | public class FilePathFromUri
18 | {
19 | FilePathFromUri()
20 | {
21 |
22 | }
23 |
24 | /**
25 | * Method for return file path of Gallery image
26 | *
27 | * @param context
28 | * @param uri
29 | * @return path of the selected image file from gallery
30 | */
31 | @SuppressLint("NewApi")
32 | public static String getPath(final Context context, final Uri uri) {
33 |
34 | // check here to KITKAT or new version
35 | final boolean isKitKatorUp = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
36 |
37 | // DocumentProvider
38 | if (isKitKatorUp && DocumentsContract.isDocumentUri(context, uri)) {
39 |
40 | // ExternalStorageProvider
41 | if (isExternalStorageDocument(uri)) {
42 | final String docId = DocumentsContract.getDocumentId(uri);
43 | final String[] split = docId.split(":");
44 | final String type = split[0];
45 |
46 | if ("primary".equalsIgnoreCase(type)) {
47 | return Environment.getExternalStorageDirectory() + "/"
48 | + split[1];
49 | }
50 | }
51 | // DownloadsProvider
52 | else if (isDownloadsDocument(uri)) {
53 |
54 | final String id = DocumentsContract.getDocumentId(uri);
55 | final Uri contentUri = ContentUris.withAppendedId(
56 | Uri.parse("content://downloads/public_downloads"),
57 | Long.valueOf(id));
58 |
59 | return getDataColumn(context, contentUri, null, null);
60 | }
61 | // MediaProvider
62 | else if (isMediaDocument(uri)) {
63 | final String docId = DocumentsContract.getDocumentId(uri);
64 | final String[] split = docId.split(":");
65 | final String type = split[0];
66 |
67 | Uri contentUri = null;
68 | if ("image".equals(type)) {
69 | contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
70 | } else if ("video".equals(type)) {
71 | contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
72 | } else if ("audio".equals(type)) {
73 | contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
74 | }
75 |
76 | final String selection = "_id=?";
77 | final String[] selectionArgs = new String[] { split[1] };
78 |
79 | return getDataColumn(context, contentUri, selection,
80 | selectionArgs);
81 | }
82 | }
83 |
84 | // MediaStore (and general)
85 | else if ("content".equalsIgnoreCase(uri.getScheme())) {
86 |
87 | // Return the remote address
88 | if (isGooglePhotosUri(uri))
89 | return uri.getLastPathSegment();
90 |
91 | return getDataColumn(context, uri, null, null);
92 | }
93 | // File
94 | else if ("file".equalsIgnoreCase(uri.getScheme())) {
95 | return uri.getPath();
96 | }
97 |
98 | return null;
99 | }
100 |
101 | /**
102 | * Get the value of the data column for this Uri. This is useful for
103 | * MediaStore Uris, and other file-based ContentProviders.
104 | *
105 | * @param context
106 | * The context.
107 | * @param uri
108 | * The Uri to query.
109 | * @param selection
110 | * (Optional) Filter used in the query.
111 | * @param selectionArgs
112 | * (Optional) Selection arguments used in the query.
113 | * @return The value of the _data column, which is typically a file path.
114 | */
115 | public static String getDataColumn(Context context, Uri uri,
116 | String selection, String[] selectionArgs) {
117 |
118 | Cursor cursor = null;
119 | final String column = "_data";
120 | final String[] projection = { column };
121 |
122 | try {
123 | cursor = context.getContentResolver().query(uri, projection,
124 | selection, selectionArgs, null);
125 | if (cursor != null && cursor.moveToFirst()) {
126 | final int index = cursor.getColumnIndexOrThrow(column);
127 | return cursor.getString(index);
128 | }
129 | } finally {
130 | if (cursor != null)
131 | cursor.close();
132 | }
133 | return null;
134 | }
135 |
136 | /**
137 | * @param uri
138 | * The Uri to check.
139 | * @return Whether the Uri authority is ExternalStorageProvider.
140 | */
141 | public static boolean isExternalStorageDocument(Uri uri) {
142 | return "com.android.externalstorage.documents".equals(uri
143 | .getAuthority());
144 | }
145 |
146 | /**
147 | * @param uri
148 | * The Uri to check.
149 | * @return Whether the Uri authority is DownloadsProvider.
150 | */
151 | public static boolean isDownloadsDocument(Uri uri) {
152 | return "com.android.providers.downloads.documents".equals(uri
153 | .getAuthority());
154 | }
155 |
156 | /**
157 | * @param uri
158 | * The Uri to check.
159 | * @return Whether the Uri authority is MediaProvider.
160 | */
161 | public static boolean isMediaDocument(Uri uri) {
162 | return "com.android.providers.media.documents".equals(uri
163 | .getAuthority());
164 | }
165 |
166 | /**
167 | * @param uri
168 | * The Uri to check.
169 | * @return Whether the Uri authority is Google Photos.
170 | */
171 | public static boolean isGooglePhotosUri(Uri uri) {
172 | return "com.google.android.apps.photos.content".equals(uri
173 | .getAuthority());
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/app/src/main/java/com/munkurious/sheetplayer/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.munkurious.sheetplayer
2 |
3 | import android.Manifest
4 | import android.app.Activity
5 | import android.content.Intent
6 | import android.content.pm.PackageManager
7 | import android.graphics.BitmapFactory
8 | import android.media.MediaPlayer
9 | import android.net.Uri
10 | import android.os.Bundle
11 | import android.os.Environment
12 | import android.support.design.widget.Snackbar
13 | import android.support.v4.widget.SwipeRefreshLayout
14 | import android.support.v7.app.AppCompatActivity
15 | import android.support.v7.widget.LinearLayoutManager
16 | import android.support.v7.widget.RecyclerView
17 | import android.util.Log
18 | import android.view.Menu
19 | import android.view.MenuItem
20 | import android.view.View
21 | import android.widget.LinearLayout
22 | import android.widget.Toast
23 | import com.koushikdutta.ion.Ion
24 | import com.munkurious.sheetplayer.FilePathFromUri.getPath
25 | import com.scanlibrary.ScanActivity
26 | import com.scanlibrary.ScanConstants
27 | import kotlinx.android.synthetic.main.activity_main.*
28 | import nl.changer.audiowife.AudioWife
29 | import org.json.JSONException
30 | import org.json.JSONObject
31 | import java.io.File
32 | import kotlin.properties.Delegates
33 |
34 |
35 | class MainActivity : AppCompatActivity()
36 | {
37 |
38 | val items = ArrayList()
39 | private var adapter : RecyclerViewAdapter by Delegates.notNull()
40 | private var refreshLayout : SwipeRefreshLayout by Delegates.notNull()
41 | //private var mediaPlayerView : MediaPlayerView by Delegates.notNull()
42 |
43 |
44 |
45 | private var MY_PERMISSIONS_REQUEST_STORAGE: Int = 0
46 |
47 | override fun onCreate(savedInstanceState: Bundle?)
48 | {
49 | super.onCreate(savedInstanceState)
50 | setContentView(R.layout.activity_main)
51 | setSupportActionBar(toolbar)
52 |
53 | fab.setOnClickListener { view ->
54 | //Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
55 | // .setAction("Action", null).show()
56 | openCameraScanner()
57 | }
58 |
59 |
60 | val recyclerView: RecyclerView = findViewById(R.id.recycler)
61 | recyclerView.layoutManager = LinearLayoutManager(this, LinearLayout.VERTICAL, false)
62 |
63 | refreshLayout = findViewById(R.id.swipeRefreshLayout)
64 |
65 | refreshLayout.setOnRefreshListener(SwipeRefreshLayout.OnRefreshListener {
66 | refreshData()
67 | })
68 |
69 | adapter = RecyclerViewAdapter(items, this@MainActivity)
70 | recyclerView.adapter = adapter
71 |
72 | refreshData()
73 |
74 | if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
75 | != PackageManager.PERMISSION_GRANTED) {
76 | requestPermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA),
77 | MY_PERMISSIONS_REQUEST_STORAGE)
78 | }
79 |
80 | }
81 |
82 | fun refreshData()
83 | {
84 | Ion.with(this@MainActivity)
85 | .load("http://sheettomidi.eastus.cloudapp.azure.com:8080/outs")
86 | .asString()
87 | .setCallback { e, result ->
88 | // do stuff with the result or error
89 | //Log.v("HERERE", result.toString())
90 | val list = convertToArray(result)
91 | //Log.v("HEREE", list.toString())
92 | finishDataRefresh(list)
93 | }
94 | }
95 |
96 | fun playSong(name: String)
97 | {
98 | Log.v("PLAYSONG", "attempting to play song" + name)
99 | //val thread = Thread({
100 | // val conn = URL("http://sheettomidi.eastus.cloudapp.azure.com:8080/outs/$name.mid").openConnection()
101 | // val input = conn.getInputStream()
102 | // val output = this.openFileOutput(name + ".mid", android.content.Context.MODE_PRIVATE)
103 | // val buffer = ByteArray(4096)
104 | // while (true) {
105 | // val len = input.read(buffer)
106 | // if (len <= 0) {
107 | // break
108 | // }
109 | // output.write(buffer, 0, len)
110 | // output.flush()
111 | // }
112 | // output.close()
113 | // input.close()
114 | //
115 | // this.filesDir.listFiles().forEach {
116 | // if (it.name.contains(name)) {
117 | // Log.v("PLAYSONG", "ATTEMPTING TO PLAY" + it.absolutePath)
118 | // mediaPlayerView.releasePlayer()
119 | // mediaPlayerView.setupPlayer(it.absolutePath)
120 | // }
121 | // }
122 | //})
123 | //thread.start()
124 |
125 |
126 |
127 | val fo = File(Environment.getExternalStorageDirectory().path + "/" + name + ".mid")
128 | //Log.v("DOWNLOADING", "http://sheettomidi.eastus.cloudapp.azure.com:8080/outs/" + name + ".mid")
129 | Ion.with(this@MainActivity)
130 | .load("http://sheettomidi.eastus.cloudapp.azure.com:8080/outs/" + name + ".mid")
131 | .write(fo)
132 | .setCallback { e, file2 ->
133 | if(file2 != null)
134 | {
135 | //mediaPlayerView.setupPlayer(file2.absolutePath)
136 | AudioWife.getInstance().init(this@MainActivity, Uri.fromFile(file2))
137 | .useDefaultUi(playerContainer, layoutInflater)
138 | AudioWife.getInstance().addOnCompletionListener(object : MediaPlayer.OnCompletionListener
139 | {
140 |
141 | override fun onCompletion(mp: MediaPlayer)
142 | {
143 | Toast.makeText(baseContext, "Completed", Toast.LENGTH_SHORT)
144 | .show()
145 | fab.show()
146 | // do you stuff
147 | }
148 | })
149 |
150 | AudioWife.getInstance().addOnPlayClickListener(object : View.OnClickListener
151 | {
152 |
153 | override fun onClick(v: View)
154 | {
155 | Toast.makeText(baseContext, "Play", Toast.LENGTH_SHORT)
156 | .show()
157 | fab.hide()
158 | // Lights-Camera-Action. Lets dance.
159 | }
160 | })
161 |
162 | AudioWife.getInstance().addOnPauseClickListener(object : View.OnClickListener
163 | {
164 |
165 | override fun onClick(v: View)
166 | {
167 | Toast.makeText(baseContext, "Pause", Toast.LENGTH_SHORT)
168 | .show()
169 | fab.show()
170 | // Your on audio pause stuff.
171 | }
172 | })
173 | //Log.v("PLAYSONG", "PLAYINGS SONG WOO")
174 | }
175 | else
176 | {
177 | Log.v("ERROROROR", e.toString())
178 | }
179 | }
180 | }//
181 |
182 | fun finishDataRefresh(list : List)
183 | {
184 | items.clear()
185 |
186 | for(e: String in list)
187 | {
188 | val str = e.replace(".mid", "")
189 | items.add(MyData(str, BitmapFactory.decodeResource(resources, android.R.drawable.ic_media_play)))
190 | //Log.v("ADDING ITEM", str)
191 | }
192 |
193 | onItemsLoadComplete()
194 | }
195 |
196 | fun onItemsLoadComplete()
197 | {
198 | adapter.notifyDataSetChanged()
199 | refreshLayout.isRefreshing = false
200 | }
201 |
202 | fun convertToArray(res: String): List
203 | {
204 | val step2 = res.replace("[", "")
205 | //Log.v("CONVERTING", step2)
206 | val step3 = step2.replace("\"", "")
207 | //Log.v("CONVERTING", step3)
208 | val step4 = step3.replace("]", "")
209 | val array = step4.split(",")
210 | //Log.v("CONVERTING", array.toString())
211 | return array
212 | }
213 |
214 | override fun onCreateOptionsMenu(menu: Menu): Boolean
215 | {
216 | // Inflate the menu; this adds items to the action bar if it is present.
217 | menuInflater.inflate(R.menu.menu_main, menu)
218 | return true
219 | }
220 |
221 | override fun onOptionsItemSelected(item: MenuItem): Boolean
222 | {
223 | // Handle action bar item clicks here. The action bar will
224 | // automatically handle clicks on the Home/Up button, so long
225 | // as you specify a parent activity in AndroidManifest.xml.
226 | return when (item.itemId)
227 | {
228 | R.id.action_settings -> openImageSelector()
229 | else -> super.onOptionsItemSelected(item)
230 | }
231 | }
232 |
233 | private val PICK_IMAGE: Int = 0
234 |
235 | private fun openImageSelector(): Boolean
236 | {
237 | val photoPickerIntent = Intent(Intent.ACTION_GET_CONTENT)
238 | photoPickerIntent.type = "image/*"
239 | startActivityForResult(photoPickerIntent, PICK_IMAGE)
240 | return true
241 | }
242 |
243 | private fun openCameraScanner(): Boolean
244 | {
245 | val REQUEST_CODE = 99
246 | val preference = ScanConstants.OPEN_CAMERA
247 | val intent = Intent(this, ScanActivity::class.java)
248 | intent.putExtra(ScanConstants.OPEN_INTENT_PREFERENCE, preference)
249 | startActivityForResult(intent, REQUEST_CODE)
250 | return true;
251 | }
252 |
253 |
254 | public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent)
255 | {
256 | super.onActivityResult(requestCode, resultCode, data)
257 | if (resultCode == Activity.RESULT_OK && requestCode == PICK_IMAGE)
258 | {
259 | val imageURI = data.data
260 | //Log.v("SHEETPLAYER", "msg" + imageURI);
261 | uploadImage(imageURI)
262 | }
263 | if (requestCode === 99 && resultCode === Activity.RESULT_OK)
264 | {
265 | val uri = data.extras.getParcelable(ScanConstants.SCANNED_RESULT)
266 | uploadImage(uri)
267 | }
268 | }
269 |
270 | fun uploadImage(imageURI: Uri)
271 | {
272 | val filePath = getPath(applicationContext, imageURI)
273 | Snackbar.make(findViewById(android.R.id.content), "Uploading...", Snackbar.LENGTH_LONG).show()
274 | //Log.v("SHEETPLAYER", "msg UPLOAD IMAGE" + filePath)
275 |
276 | val f = File(filePath)
277 |
278 | //Log.d("DEBUG", "Choose: " + f.path)
279 |
280 |
281 |
282 | //Log.v("SHEETPLAYER", "file " + f.nameWithoutExtension)
283 | val uploading = Ion.with(this@MainActivity)
284 | .load("http://sheettomidi.eastus.cloudapp.azure.com:8080/upload")
285 | .setMultipartFile("image", f)
286 | .asString()
287 | .withResponse()
288 | .setCallback { e, result ->
289 | try
290 | {
291 | val jobj = JSONObject(result.result)
292 | Toast.makeText(applicationContext, jobj.getString("response"), Toast.LENGTH_SHORT).show()
293 |
294 | }
295 | catch (e1: JSONException)
296 | {
297 | e1.printStackTrace()
298 | }
299 | }
300 | }
301 |
302 |
303 | }
304 |
--------------------------------------------------------------------------------
/sheetplayer-server/sheetplayer-server/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sheetplayer-server",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "accepts": {
8 | "version": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz",
9 | "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=",
10 | "requires": {
11 | "mime-types": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
12 | "negotiator": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz"
13 | }
14 | },
15 | "array-flatten": {
16 | "version": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
17 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
18 | },
19 | "basic-auth": {
20 | "version": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz",
21 | "integrity": "sha1-AV2z81PgLlY3d1X5YnQuiYHnu7o=",
22 | "requires": {
23 | "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz"
24 | }
25 | },
26 | "body-parser": {
27 | "version": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
28 | "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
29 | "requires": {
30 | "bytes": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
31 | "content-type": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
32 | "debug": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
33 | "depd": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
34 | "http-errors": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
35 | "iconv-lite": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
36 | "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
37 | "qs": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
38 | "raw-body": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
39 | "type-is": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz"
40 | }
41 | },
42 | "bytes": {
43 | "version": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
44 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
45 | },
46 | "connect": {
47 | "version": "https://registry.npmjs.org/connect/-/connect-3.6.5.tgz",
48 | "integrity": "sha1-+43ee6B2OHfQ7J352sC0tA5yx9o=",
49 | "requires": {
50 | "debug": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
51 | "finalhandler": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.6.tgz",
52 | "parseurl": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
53 | "utils-merge": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz"
54 | },
55 | "dependencies": {
56 | "finalhandler": {
57 | "version": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.6.tgz",
58 | "integrity": "sha1-AHrqM9Gk0+QgF/YkhIrVjSEvgU8=",
59 | "requires": {
60 | "debug": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
61 | "encodeurl": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
62 | "escape-html": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
63 | "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
64 | "parseurl": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
65 | "statuses": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
66 | "unpipe": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz"
67 | }
68 | }
69 | }
70 | },
71 | "connect-multiparty": {
72 | "version": "2.1.0",
73 | "resolved": "https://registry.npmjs.org/connect-multiparty/-/connect-multiparty-2.1.0.tgz",
74 | "integrity": "sha512-DLzhq7mcQKKk/Y83NLY5dp0kxO0xTxA5yu3oMgFBfpWLQR1NArrXMBcEXignTcNFVaXrjkgfepNG3nkfEy9Sow==",
75 | "requires": {
76 | "multiparty": "4.1.3",
77 | "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
78 | "qs": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
79 | "type-is": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz"
80 | }
81 | },
82 | "content-disposition": {
83 | "version": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
84 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
85 | },
86 | "content-type": {
87 | "version": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
88 | "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js="
89 | },
90 | "cookie": {
91 | "version": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
92 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
93 | },
94 | "cookie-parser": {
95 | "version": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.3.tgz",
96 | "integrity": "sha1-D+MfoZ0AC5X0qt8fU/3CuKIDuqU=",
97 | "requires": {
98 | "cookie": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
99 | "cookie-signature": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz"
100 | }
101 | },
102 | "cookie-signature": {
103 | "version": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
104 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
105 | },
106 | "debug": {
107 | "version": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
108 | "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=",
109 | "requires": {
110 | "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"
111 | }
112 | },
113 | "depd": {
114 | "version": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
115 | "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
116 | },
117 | "destroy": {
118 | "version": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
119 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
120 | },
121 | "ee-first": {
122 | "version": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
123 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
124 | },
125 | "encodeurl": {
126 | "version": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
127 | "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA="
128 | },
129 | "escape-html": {
130 | "version": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
131 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
132 | },
133 | "etag": {
134 | "version": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
135 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
136 | },
137 | "express": {
138 | "version": "https://registry.npmjs.org/express/-/express-4.16.2.tgz",
139 | "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=",
140 | "requires": {
141 | "accepts": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz",
142 | "array-flatten": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
143 | "body-parser": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
144 | "content-disposition": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
145 | "content-type": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
146 | "cookie": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
147 | "cookie-signature": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
148 | "debug": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
149 | "depd": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
150 | "encodeurl": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
151 | "escape-html": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
152 | "etag": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
153 | "finalhandler": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
154 | "fresh": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
155 | "merge-descriptors": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
156 | "methods": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
157 | "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
158 | "parseurl": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
159 | "path-to-regexp": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
160 | "proxy-addr": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz",
161 | "qs": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
162 | "range-parser": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
163 | "safe-buffer": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
164 | "send": "https://registry.npmjs.org/send/-/send-0.16.1.tgz",
165 | "serve-static": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz",
166 | "setprototypeof": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
167 | "statuses": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
168 | "type-is": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
169 | "utils-merge": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
170 | "vary": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz"
171 | }
172 | },
173 | "fd-slicer": {
174 | "version": "1.0.1",
175 | "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
176 | "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
177 | "requires": {
178 | "pend": "1.2.0"
179 | }
180 | },
181 | "finalhandler": {
182 | "version": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
183 | "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
184 | "requires": {
185 | "debug": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
186 | "encodeurl": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
187 | "escape-html": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
188 | "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
189 | "parseurl": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
190 | "statuses": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
191 | "unpipe": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz"
192 | }
193 | },
194 | "forwarded": {
195 | "version": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
196 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
197 | },
198 | "fresh": {
199 | "version": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
200 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
201 | },
202 | "http-errors": {
203 | "version": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
204 | "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
205 | "requires": {
206 | "depd": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
207 | "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
208 | "setprototypeof": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
209 | "statuses": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz"
210 | },
211 | "dependencies": {
212 | "setprototypeof": {
213 | "version": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
214 | "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
215 | }
216 | }
217 | },
218 | "iconv-lite": {
219 | "version": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
220 | "integrity": "sha1-90aPYBNfXl2tM5nAqBvpoWA6CCs="
221 | },
222 | "inherits": {
223 | "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
224 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
225 | },
226 | "ipaddr.js": {
227 | "version": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz",
228 | "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A="
229 | },
230 | "media-typer": {
231 | "version": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
232 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
233 | },
234 | "merge-descriptors": {
235 | "version": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
236 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
237 | },
238 | "methods": {
239 | "version": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
240 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
241 | },
242 | "mime": {
243 | "version": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
244 | "integrity": "sha1-Eh+evEnjdm8xGnbh+hyAA8SwOqY="
245 | },
246 | "mime-db": {
247 | "version": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
248 | "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE="
249 | },
250 | "mime-types": {
251 | "version": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
252 | "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
253 | "requires": {
254 | "mime-db": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz"
255 | }
256 | },
257 | "morgan": {
258 | "version": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz",
259 | "integrity": "sha1-0B+mxlhZt2/PMbPLU6OCGjEdgFE=",
260 | "requires": {
261 | "basic-auth": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz",
262 | "debug": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
263 | "depd": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
264 | "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
265 | "on-headers": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz"
266 | }
267 | },
268 | "ms": {
269 | "version": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
270 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
271 | },
272 | "multiparty": {
273 | "version": "4.1.3",
274 | "resolved": "https://registry.npmjs.org/multiparty/-/multiparty-4.1.3.tgz",
275 | "integrity": "sha1-PEPH/LGJbhdGBDap3Qtu8WaOT5Q=",
276 | "requires": {
277 | "fd-slicer": "1.0.1"
278 | }
279 | },
280 | "negotiator": {
281 | "version": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
282 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
283 | },
284 | "on-finished": {
285 | "version": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
286 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
287 | "requires": {
288 | "ee-first": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz"
289 | }
290 | },
291 | "on-headers": {
292 | "version": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
293 | "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c="
294 | },
295 | "parseurl": {
296 | "version": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
297 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
298 | },
299 | "path-to-regexp": {
300 | "version": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
301 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
302 | },
303 | "pend": {
304 | "version": "1.2.0",
305 | "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
306 | "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA="
307 | },
308 | "proxy-addr": {
309 | "version": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz",
310 | "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=",
311 | "requires": {
312 | "forwarded": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
313 | "ipaddr.js": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz"
314 | }
315 | },
316 | "python-shell": {
317 | "version": "0.4.0",
318 | "resolved": "https://registry.npmjs.org/python-shell/-/python-shell-0.4.0.tgz",
319 | "integrity": "sha1-JZxUcNiFKSsi6QalewhfZRdS+VY="
320 | },
321 | "qs": {
322 | "version": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
323 | "integrity": "sha1-NJzfbu+J7EXBLX1es/wMhwNDptg="
324 | },
325 | "range-parser": {
326 | "version": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
327 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
328 | },
329 | "raw-body": {
330 | "version": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
331 | "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
332 | "requires": {
333 | "bytes": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
334 | "http-errors": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
335 | "iconv-lite": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
336 | "unpipe": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz"
337 | }
338 | },
339 | "safe-buffer": {
340 | "version": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
341 | "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM="
342 | },
343 | "send": {
344 | "version": "https://registry.npmjs.org/send/-/send-0.16.1.tgz",
345 | "integrity": "sha1-pw4coh0TgsEdDZ9iMd6ygQgNerM=",
346 | "requires": {
347 | "debug": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
348 | "depd": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
349 | "destroy": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
350 | "encodeurl": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
351 | "escape-html": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
352 | "etag": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
353 | "fresh": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
354 | "http-errors": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
355 | "mime": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
356 | "ms": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
357 | "on-finished": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
358 | "range-parser": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
359 | "statuses": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz"
360 | }
361 | },
362 | "serve-static": {
363 | "version": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz",
364 | "integrity": "sha1-TFfVNASnYdjy58HooYpH2/J4pxk=",
365 | "requires": {
366 | "encodeurl": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
367 | "escape-html": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
368 | "parseurl": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
369 | "send": "https://registry.npmjs.org/send/-/send-0.16.1.tgz"
370 | }
371 | },
372 | "setprototypeof": {
373 | "version": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
374 | "integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY="
375 | },
376 | "statuses": {
377 | "version": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
378 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
379 | },
380 | "system": {
381 | "version": "https://registry.npmjs.org/system/-/system-2.0.1.tgz",
382 | "integrity": "sha1-0mqFE17n824FTn8O7ERn87Hdl0I="
383 | },
384 | "type-is": {
385 | "version": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
386 | "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=",
387 | "requires": {
388 | "media-typer": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
389 | "mime-types": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz"
390 | }
391 | },
392 | "unpipe": {
393 | "version": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
394 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
395 | },
396 | "utils-merge": {
397 | "version": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
398 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
399 | },
400 | "vary": {
401 | "version": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
402 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
403 | }
404 | }
405 | }
406 |
--------------------------------------------------------------------------------