├── .DS_Store ├── .gitignore ├── Build ├── .DS_Store ├── GenericRestConnector.zip └── GenericRestConnector │ ├── .DS_Store │ ├── GenericRestConnector.exe │ ├── GenericRestConnector.exe.config │ ├── GenericRestConnector.pdb │ ├── GenericRestConnector.vshost.exe │ ├── GenericRestConnector.vshost.exe.config │ ├── GenericRestConnector.vshost.exe.manifest │ ├── Newtonsoft.Json.dll │ ├── QvxLibrary.dll │ └── web │ ├── apiKey.ng.html │ ├── basicAuth.ng.html │ ├── connectdialog.css │ ├── connectdialog.js │ ├── connectdialog.ng.html │ ├── connector-main.js │ ├── dictionary-factory.css │ ├── factory.ttf │ ├── noAuth.ng.html │ ├── oAuth.ng.html │ └── selectdialog.js ├── Factory.png ├── GenericRestConnector ├── .DS_Store ├── .vs │ ├── GenericRestConnector │ │ └── v14 │ │ │ └── .suo │ └── config │ │ └── applicationhost.config ├── Authentication │ ├── APIKeyAuth.cs │ ├── AuthBase.cs │ ├── AuthInfo.cs │ ├── Authentication.cs │ ├── BasicAuth.cs │ ├── NoAuth.cs │ ├── OAuth1Auth.cs │ ├── OAuthAuth.cs │ └── dictionary.json ├── Catalog.cs ├── Connection.cs ├── ErrorHelper.cs ├── GenericRestConnector.csproj ├── GenericRestConnector.sln ├── GenericRestConnector.v12.suo ├── Newtonsoft.Json.dll ├── Paging │ ├── OffsetLimitPaging.cs │ ├── PageInfo.cs │ ├── PagePaging.cs │ ├── Pager.cs │ └── PagingBase.cs ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── QvxLibrary.dll ├── RESTHelper.cs ├── Server.cs ├── TableCache.cs ├── TokenResponse.cs ├── app.config ├── bin │ ├── .DS_Store │ └── x64 │ │ ├── .DS_Store │ │ └── Release │ │ ├── GenericRestConnector.exe │ │ ├── GenericRestConnector.exe.config │ │ ├── GenericRestConnector.pdb │ │ ├── GenericRestConnector.vshost.exe │ │ ├── GenericRestConnector.vshost.exe.config │ │ ├── GenericRestConnector.vshost.exe.manifest │ │ ├── Newtonsoft.Json.dll │ │ ├── QvxLibrary.dll │ │ └── web │ │ ├── apiKey.ng.html │ │ ├── basicAuth.ng.html │ │ ├── connectdialog.css │ │ ├── connectdialog.js │ │ ├── connectdialog.ng.html │ │ ├── connector-main.js │ │ ├── dictionary-factory.css │ │ ├── factory.ttf │ │ ├── noAuth.ng.html │ │ ├── oAuth.ng.html │ │ └── selectdialog.js ├── obj │ ├── Debug │ │ ├── DesignTimeResolveAssemblyReferences.cache │ │ ├── DesignTimeResolveAssemblyReferencesInput.cache │ │ ├── GenericRestConnector.Properties.Resources.resources │ │ ├── GenericRestConnector.csproj.FileListAbsolute.txt │ │ ├── GenericRestConnector.csproj.GenerateResource.Cache │ │ ├── GenericRestConnector.csprojResolveAssemblyReference.cache │ │ ├── GenericRestConnector.exe │ │ ├── GenericRestConnector.pdb │ │ ├── TempPE │ │ │ └── Properties.Resources.Designer.cs.dll │ │ ├── TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs │ │ ├── TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs │ │ ├── TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs │ │ ├── generic-rest-connector.csproj.FileListAbsolute.txt │ │ ├── generic-rest-connector.csproj.GenerateResource.Cache │ │ ├── generic-rest-connector.exe │ │ ├── generic-rest-connector.pdb │ │ └── generic_rest_connector.Properties.Resources.resources │ ├── Release │ │ ├── DesignTimeResolveAssemblyReferencesInput.cache │ │ ├── GenericRestConnector.Properties.Resources.resources │ │ ├── GenericRestConnector.csproj.FileListAbsolute.txt │ │ ├── GenericRestConnector.csproj.GenerateResource.Cache │ │ ├── GenericRestConnector.exe │ │ ├── GenericRestConnector.pdb │ │ ├── TempPE │ │ │ └── Properties.Resources.Designer.cs.dll │ │ ├── TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs │ │ ├── TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs │ │ └── TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs │ └── x64 │ │ ├── Debug │ │ ├── DesignTimeResolveAssemblyReferences.cache │ │ ├── DesignTimeResolveAssemblyReferencesInput.cache │ │ ├── GenericRestConnector.Properties.Resources.resources │ │ ├── GenericRestConnector.csproj.FileListAbsolute.txt │ │ ├── GenericRestConnector.csproj.GenerateResource.Cache │ │ ├── GenericRestConnector.csprojResolveAssemblyReference.cache │ │ ├── GenericRestConnector.exe │ │ ├── GenericRestConnector.pdb │ │ ├── TempPE │ │ │ └── Properties.Resources.Designer.cs.dll │ │ ├── TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs │ │ ├── TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs │ │ └── TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs │ │ └── Release │ │ ├── DesignTimeResolveAssemblyReferencesInput.cache │ │ ├── GenericRestConnector.Properties.Resources.resources │ │ ├── GenericRestConnector.csproj.FileListAbsolute.txt │ │ ├── GenericRestConnector.csproj.GenerateResource.Cache │ │ ├── GenericRestConnector.csprojResolveAssemblyReference.cache │ │ ├── GenericRestConnector.exe │ │ ├── GenericRestConnector.pdb │ │ ├── TempPE │ │ └── Properties.Resources.Designer.cs.dll │ │ ├── TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs │ │ ├── TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs │ │ └── TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs ├── verpatch.exe └── web │ ├── apiKey.ng.html │ ├── basicAuth.ng.html │ ├── connectdialog.css │ ├── connectdialog.js │ ├── connectdialog.ng.html │ ├── connector-main.js │ ├── dictionary-factory.css │ ├── factory.ttf │ ├── noAuth.ng.html │ ├── oAuth.ng.html │ └── selectdialog.js ├── Local.png ├── Public.png ├── README.md └── Thumbs.db /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /Build/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/Build/.DS_Store -------------------------------------------------------------------------------- /Build/GenericRestConnector.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/Build/GenericRestConnector.zip -------------------------------------------------------------------------------- /Build/GenericRestConnector/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/Build/GenericRestConnector/.DS_Store -------------------------------------------------------------------------------- /Build/GenericRestConnector/GenericRestConnector.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/Build/GenericRestConnector/GenericRestConnector.exe -------------------------------------------------------------------------------- /Build/GenericRestConnector/GenericRestConnector.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Build/GenericRestConnector/GenericRestConnector.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/Build/GenericRestConnector/GenericRestConnector.pdb -------------------------------------------------------------------------------- /Build/GenericRestConnector/GenericRestConnector.vshost.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/Build/GenericRestConnector/GenericRestConnector.vshost.exe -------------------------------------------------------------------------------- /Build/GenericRestConnector/GenericRestConnector.vshost.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Build/GenericRestConnector/GenericRestConnector.vshost.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Build/GenericRestConnector/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/Build/GenericRestConnector/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /Build/GenericRestConnector/QvxLibrary.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/Build/GenericRestConnector/QvxLibrary.dll -------------------------------------------------------------------------------- /Build/GenericRestConnector/web/apiKey.ng.html: -------------------------------------------------------------------------------- 1 | 
2 |

Provide a valid API Key for the connection

3 | 4 | 5 |
6 | -------------------------------------------------------------------------------- /Build/GenericRestConnector/web/basicAuth.ng.html: -------------------------------------------------------------------------------- 1 | 
2 |

Provide a Username and Password for the connection

3 | 4 | 5 | 6 | 7 |
8 | 9 | -------------------------------------------------------------------------------- /Build/GenericRestConnector/web/connectdialog.css: -------------------------------------------------------------------------------- 1 | .qrest-connect-dialog-container { 2 | 3 | } 4 | 5 | .qrest-connect-dialog { 6 | width: 70%; 7 | margin: 50px auto; 8 | height: calc(100vh - 100px); 9 | background-color: white; 10 | position: relative; 11 | padding-left: 10px; 12 | padding-right: 10px; 13 | } 14 | 15 | .qrest-authorize{ 16 | text-decoration: none; 17 | } 18 | 19 | .qrest-footer{ 20 | position: absolute; 21 | bottom: 0px; 22 | right: 0px; 23 | } 24 | 25 | .qrest-loader{ 26 | position: absolute; 27 | height: 100px; 28 | width: 100px; 29 | top: calc(50% - 50px); 30 | left: calc(50% - 50px); 31 | } 32 | 33 | .connection-settings input{ 34 | display: block; 35 | width: 96%; 36 | height: 25px; 37 | padding: 6px 12px; 38 | font-size: 14px; 39 | line-height: 1.42857143; 40 | color: #555; 41 | background-color: #fff; 42 | background-image: none; 43 | border: 1px solid #ccc; 44 | border-radius: 4px; 45 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075); 46 | box-shadow: inset 0 1px 1px rgba(0,0,0,.075); 47 | -webkit-transition: border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s; 48 | -o-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s; 49 | transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s; 50 | } 51 | 52 | .select-config-dialog{ 53 | height: calc(100% - 50px); 54 | } 55 | 56 | .select-config-dialog, .connection-settings{ 57 | padding: 5px; 58 | } 59 | 60 | .select-config-source{ 61 | height: 80px; 62 | margin-left: -10px; 63 | margin-right: -10px; 64 | } 65 | 66 | .select-config-source li{ 67 | list-style-type: none; 68 | display: inline-block; 69 | width: 12% !important; 70 | cursor: pointer; 71 | margin-left: 10px; 72 | margin-right: 10px; 73 | line-height: 60px !important; 74 | } 75 | 76 | .select-config{ 77 | overflow-x: hidden; 78 | overflow-y: auto; 79 | padding: 10px 2px; 80 | height: calc(100% - 135px); 81 | } 82 | 83 | .primary-button{ 84 | cursor: pointer; 85 | } 86 | 87 | .select-config ul{ 88 | list-style-type: none; 89 | margin-left: -10px; 90 | margin-right: -10px; 91 | } 92 | 93 | .select-config li{ 94 | display: inline-block; 95 | width: 23%; 96 | margin-left: 10px; 97 | margin-right: 10px; 98 | cursor: pointer; 99 | } 100 | 101 | .subpage{ 102 | margin-top: 20px; 103 | } 104 | 105 | 106 | .loading-container .message{ 107 | position: absolute; 108 | height: 100px; 109 | width: 40%; 110 | top: calc(50% + 100px); 111 | left: calc(30%); 112 | text-align: center; 113 | } -------------------------------------------------------------------------------- /Build/GenericRestConnector/web/connectdialog.js: -------------------------------------------------------------------------------- 1 | define(['qvangular', 'text!./connectdialog.ng.html', 'css!./connectdialog.css', 'css!./dictionary-factory.css'], function (qvangular, template) { 2 | return { 3 | template: template, 4 | controller: ['$scope', 'input', function ($scope, input) { 5 | function init() { 6 | $scope.isEdit = input.editMode; 7 | $scope.isLoading = true; 8 | $scope.auth_method; 9 | $scope.subpageLoading = false; 10 | $scope.id = input.instanceId; 11 | $scope.connectionParameters = {}; 12 | $scope.localDictionaryList = []; 13 | $scope.onlineDictionaryList = []; 14 | $scope.source = "online"; 15 | $scope.dictionaryIndex; 16 | $scope.step = "config-selection"; 17 | $scope.connectionTemplates = { 18 | None: "/customdata/64/GenericRestConnector/web/noAuth.ng.html", 19 | Basic: "/customdata/64/GenericRestConnector/web/basicAuth.ng.html", 20 | "OAuth": "/customdata/64/GenericRestConnector/web/oAuth.ng.html", 21 | Certificate: "", 22 | "API Key": "/customdata/64/GenericRestConnector/web/apiKey.ng.html" 23 | }; 24 | $scope.name; 25 | $scope.username; 26 | $scope.loadingMessage = "Fetching Online and Local dictionaries. Please bare with us."; 27 | $scope.password; 28 | $scope.token; 29 | $scope.consumer_secret; 30 | $scope.key; 31 | $scope.secret; 32 | $scope.tokenRequested = false; 33 | $scope.url; 34 | $scope.dicurl=""; 35 | $scope.config; 36 | $scope.provider = "GenericRestConnector.exe"; 37 | $scope.idForAuthorization = ""; 38 | $scope.subpage = $scope.connectionTemplates["None"]; 39 | 40 | //if the connection is being modified 41 | if (input.editMode) { 42 | input.serverside.getConnection(input.instanceId).then(function (result) { 43 | console.log(result); 44 | var tempArray = result.qConnection.qConnectionString.substring(19, result.qConnection.qConnectionString.length - 1).split(';'); 45 | for (var i = 0; i < tempArray.length; i++) { 46 | var param = tempArray[i].split('='); 47 | $scope.connectionParameters[param[0]] = param[1]; 48 | } 49 | $scope.config = $scope.connectionParameters["config"]; 50 | $scope.name = result.qConnection.qName; 51 | $scope.url = $scope.connectionParameters["url"]; 52 | $scope.dicurl = $scope.connectionParameters["dictionaryurl"]; 53 | $scope.dictionaryId = $scope.connectionParameters["dictionary"];; 54 | $scope.source = $scope.connectionParameters["source"]; 55 | $scope.username = $scope.connectionParameters["username"]; 56 | $scope.isLoading = false; 57 | $scope.subpageLoading = true; 58 | $scope.loadTemplate('connection-settings', $scope.dictionaryId, $scope.dicurl); 59 | }); 60 | } 61 | else { 62 | //get online dictionaries 63 | input.serverside.sendJsonRequest("getOnlineDictionaries").then(function (response) { 64 | $scope.onlineDictionaryList = JSON.parse(response.qMessage).configs; 65 | if ($scope.onlineDictionaryList && $scope.localDictionaryList) { 66 | $scope.isLoading = false; 67 | } 68 | }); 69 | //get local dictionaries 70 | input.serverside.sendJsonRequest("getLocalDictionaries").then(function (response) { 71 | var catalog = JSON.parse(response.qMessage); 72 | $scope.processCatalog(catalog); 73 | if ($scope.onlineDictionaryList && $scope.localDictionaryList) { 74 | $scope.isLoading = false; 75 | } 76 | }); 77 | } 78 | } 79 | 80 | //build the connection string 81 | function buildConnectionString() { 82 | var conn = "CUSTOM CONNECT TO \"provider=GenericRestConnector.exe;dictionary=" + $scope.dictionaryId + ";source=" + $scope.source + ";auth-method="+$scope.auth_method+";"; 83 | $('[data-parameter]').each(function (index, item) { 84 | if ($(item).attr("data-parameter") == "password") { 85 | $scope.password = $(item).val(); 86 | } 87 | else { 88 | conn += $(item).attr("data-parameter") + "=" + $(item).val() + ";"; 89 | } 90 | }); 91 | 92 | if ($scope.dicurl) { 93 | conn += "dictionaryurl=" + $scope.dicurl + ";"; 94 | } 95 | conn += "\""; 96 | console.log(conn); 97 | return conn; 98 | } 99 | 100 | //save the connection 101 | $scope.onOKClicked = function () { 102 | if ($scope.isEdit) { 103 | input.serverside.modifyConnection($scope.instanceId, $scope.name, buildConnectionString(), $scope.provider, true, $scope.username, $scope.password); 104 | $scope.destroyComponent(); 105 | } 106 | else { 107 | input.serverside.createNewConnection($scope.name, buildConnectionString(), $scope.username, $scope.password); 108 | $scope.destroyComponent(); 109 | } 110 | }; 111 | 112 | //close the dialog 113 | $scope.onCancelClicked = function () { 114 | if (!$scope.isLoading) { 115 | $scope.destroyComponent(); 116 | } 117 | }; 118 | 119 | $scope.backToCatalog = function () { 120 | $scope.step = "config-selection"; 121 | $scope.subpage = null; 122 | }; 123 | 124 | //display the appropriate step 125 | $scope.nextStep = function (step) { 126 | $scope.step = step; 127 | }; 128 | 129 | $scope.setSource = function (source) { 130 | $scope.source = source; 131 | }; 132 | 133 | $scope.updateCatalog = function () { 134 | input.serverside.sendJsonRequest("updateLocalCatalog").then(function (response) { 135 | var catalog = JSON.parse(response.qMessage); 136 | $scope.processCatalog(catalog); 137 | if ($scope.onlineDictionaryList && $scope.localDictionaryList) { 138 | $scope.isLoading = false; 139 | } 140 | }); 141 | }; 142 | 143 | //load and display the required template based on the config auth setting 144 | $scope.loadTemplate = function (step, index, dicurl) { 145 | $scope.subpageLoading = true; 146 | this.nextStep(step); 147 | if (!$scope.isEdit) { 148 | if ($scope.source == "online") { 149 | $scope.selectedDictionaryInfo = $scope.onlineDictionaryList[index]; 150 | $scope.dictionaryId = $scope.onlineDictionaryList[index]._id; 151 | $scope.idForAuthorization = $scope.onlineDictionaryList[index]._id; 152 | } 153 | else { 154 | $scope.selectedDictionaryInfo = $scope.localDictionaryList[index]; 155 | $scope.dictionaryId = $scope.localDictionaryList[index].folder; 156 | } 157 | 158 | } 159 | $scope.dicurl = dicurl; 160 | $scope.loadingMessage = "Downloading Dictionary Definition..."; 161 | input.serverside.sendJsonRequest("getDictionaryDef", $scope.dictionaryId, $scope.source).then(function (response) { 162 | $scope.dictionaryDef = JSON.parse(response.qMessage); 163 | $scope.auth_method = $scope.dictionaryDef.auth_method; 164 | $scope.subpage = $scope.connectionTemplates[$scope.dictionaryDef.auth_method]; 165 | $scope.subpageLoading = false; 166 | if ($scope.source == "local") { 167 | $scope.idForAuthorization = $scope.dictionaryDef.id; 168 | } 169 | }); 170 | } 171 | 172 | $scope.processCatalog = function (catalog) { 173 | $scope.localDictionaryList = []; 174 | if (catalog.configs) { 175 | for (var d in catalog.configs) { 176 | $scope.localDictionaryList.push(JSON.parse(catalog.configs[d])); 177 | } 178 | } 179 | } 180 | 181 | init(); 182 | }] 183 | }; 184 | }); -------------------------------------------------------------------------------- /Build/GenericRestConnector/web/connectdialog.ng.html: -------------------------------------------------------------------------------- 1 | 
2 |
3 |
4 |
5 |
{{loadingMessage}}
6 |
7 |
8 |
9 |

Choose a REST Configuration

10 |
    11 | 12 | 13 |
14 |
15 |
16 | 17 |
18 |
19 |
20 |
    21 |
  • 22 |
    23 | {{dic.display_name}} 24 |
    {{dic.owner}}
    25 |
    26 | 27 |
    28 |
    29 |
  • 30 |
31 |
32 |
33 | 34 |
35 |
    36 |
  • 37 |
    38 | {{dic.displayName}} 39 |
    40 | 41 |
    42 |
    43 |
  • 44 |
45 |
46 |
47 |
48 |

Provide a name and the Url for the connection

49 | 50 |
51 | 52 |
53 |
54 |
55 |
{{loadingMessage}}
56 |
57 |
58 | 59 |
60 |
61 |
62 |
63 | 69 |
70 |
71 | -------------------------------------------------------------------------------- /Build/GenericRestConnector/web/connector-main.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 3 | ], 4 | function () { 5 | 6 | }); -------------------------------------------------------------------------------- /Build/GenericRestConnector/web/dictionary-factory.css: -------------------------------------------------------------------------------- 1 | .white{color:white !important}@font-face{font-family:factory;src:url(/resources/factory.ttf)}@font-face{font-family:factory;src:url(factory.ttf)}@font-face{font-family:Stellar;font-weight:lighter;src:url(/resources/Stellar-light.otf)}@font-face{font-family:Stellar;font-weight:normal;src:url(/resources/Stellar-regular.otf)}@font-face{font-family:Aileron;src:url(/resources/Ailerons-Typeface.otf)}.body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:Stellar,"QlikView Sans",sans-serif;font-size:16px;color:#464646;background-color:white;background-image:url(/resources/background.jpg);background-position:bottom;background-attachment:fixed;background-size:40%;background-repeat:repeat-x}.body label{font-weight:normal;margin:3px 0}.body .page{margin-top:80px}.body .content{padding:10px 0}.body .float-right{float:right}.body .float-left{float:left}.body .align-right{text-align:right}.body .primary-button,.body .secondary-button{display:block;width:200px;padding:5px;height:35px;line-height:26px;text-align:center;border-radius:3px;font-weight:normal;border:none;box-sizing:border-box}.body .primary-button{background-color:#CEBDA4;color:white;margin-bottom:3px}.body .secondary-button{background-color:#AEB9C7;color:white;margin-bottom:3px}.body .download-button,.body .delete-button,.body .back-button{display:block;cursor:pointer;background-color:transparent;border:none;height:30px;width:30px;line-height:30px;color:#CCCCCC}.body .download-button:after,.body .delete-button:after,.body .back-button:after{position:absolute;top:0;left:0;font-family:factory;font-size:30px}.body .download-button:after{content:"\E803"}.body .download-button:hover{color:#a3ba49}.body .delete-button:after{content:"\E802"}.body .delete-button:hover{color:#aa3840}.body .back-button{position:relative;color:#CEBDA4;width:auto !important;padding-left:45px;font-size:20px}.body .back-button:after{font-family:factory;content:"\E800"}.body .title{font-size:20px;font-weight:normal;color:#CEBDA4}.body .check-label{height:30px;line-height:30px;display:inline-block;margin:0;padding:0;vertical-align:top}.body input[type=checkbox]{display:inline-block;width:30px;margin:0;height:30px;line-height:30px}.body h1,.body h2,.body h3,.body h4{margin-top:5px;margin-bottom:5px}.body h1{font-size:24px;color:#CEBDA4}.body h2{font-size:20px;color:#464646}.body h3{font-size:18px;color:#908F96}.body h4{font-size:16px;color:#464646;font-weight:bold}.body ul{list-style-type:none}.body .plainlist{margin:0;padding:0}.body .description{padding:10px 0}.body .card{background-color:#F8F9FB;padding:5px 10px;border-radius:3px;box-shadow:0 0 5px #ccc}.body .card.active{box-shadow:0 0 5px #908F96}.body .dictionary{height:220px;position:relative;margin-bottom:15px}.body .dictionary .icon{text-align:center;height:150px;width:100%}.body .dictionary .icon img{margin-top:20px;max-height:100px}.body .dictionary .title{text-align:center;display:block;height:20px;color:#464646}.body .dictionary .sub-title{text-align:center;font-size:14px;font-weight:normal;color:#908F96}.body .dictionary .delete-button{position:absolute;bottom:10px;right:5px}.body .dictionary .download-button{padding-left:45px;position:absolute;bottom:10px;left:10px}.body .dictionary-link{display:block}.body .dictionary-link:hover,.body .dictionary-link:visited{text-decoration:none}.body .hint{color:#908F96;font-size:12px;margin:2px 0}.body .hint strong{color:#464646}.body .inline{display:inline-block;margin-right:5px}.body .spacer{border:1px solid #CCCCCC;margin:5px 0}.body .horizontal-spacer{width:10px;height:1px}.body .vertical-spacer{height:10px}.body .smokescreen{z-index:1000;background-color:rgba(200,200,200,0.8);position:absolute;top:0;left:0;height:100%;width:100%}.body .center{text-align:center}.body .show{display:block}.body .hide{display:none}.body .token-card{margin:0 auto;margin-top:50px;width:auto;padding:20px;text-align:center}.body .token-card.token{font-size:30px}.body .inline{display:inline-block}.body .status{line-height:34px}.body .navbar{min-height:70px;background-color:#908F96;color:#FFFFFF}.body .navbar a{color:#FFFFFF;font-size:16px}.body .navbar a:hover{color:#908F96}.body .navbar .navbar-brand{font-family:Aileron;font-weight:lighter;font-size:24px;letter-spacing:2px;height:70px;line-height:40px}.body .navbar .navbar-brand:hover{color:white}.body .navbar .navbar-nav li a{line-height:40px}.body .navbar .dropdown.open a{color:#908F96}.body .intro{margin-top:70px}.body .intro .title{font-size:36px}.body .intro .intro-option{text-align:center;margin:50px 0;color:#464646;font-size:30px}.body .intro .intro-option a,.body .intro .intro-option a:hover,.body .intro .intro-option a:visited{color:#464646;text-decoration:none}.body .intro .intro-option:hover{-ms-transform:scale(1.2);-webkit-transform:scale(1.2);transform:scale(1.2)}.body .login-container{width:400px;margin:0 auto;padding-top:30px}.body .login-container .login-logo{height:200px;background:url(/resources/Octocat.png) center center no-repeat;background-size:contain;margin-bottom:20px}.body .login-container .login-button{margin:0 100px}.body .dictionary-nav .nav-button{height:60px;display:inline-block;line-height:50px;width:100%;font-size:16px;text-align:center;color:#CEBDA4}.body .dictionary-nav .nav-button a{color:#CEBDA4}.body .dictionary-nav .nav-button.active{background-color:#908F96;color:white}.body .dictionary-nav .nav-button.active:hover{-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1)}.body .dictionary-nav .nav-button:hover{-ms-transform:scale(1.1);-webkit-transform:scale(1.1);transform:scale(1.1)}.body .general .icon img{max-height:100px}.body .wizard .path{font-size:14px;font-weight:normal;color:#CEBDA4}.body .wizard .auth-version span,.body .wizard .auth-version input{line-height:30px;height:30px;padding:0;margin:0;width:auto;min-width:30px;vertical-align:top;box-shadow:none}.body .wizard .auth-version input{margin-right:50px}.body .wizard .auth-method,.body .wizard .paging-method{height:110px;cursor:pointer;background-color:white}.body .wizard .auth-method .auth-type,.body .wizard .paging-method .auth-type,.body .wizard .auth-method .paging-type,.body .wizard .paging-method .paging-type{text-align:center}.body .wizard .auth-method .auth-desc,.body .wizard .paging-method .auth-desc,.body .wizard .auth-method .paging-desc,.body .wizard .paging-method .paging-desc{font-size:12px}.body .wizard .auth-method.active,.body .wizard .paging-method.active{border:2px solid #CEBDA4;box-shadow:0 0 5px #CEBDA4}.body .wizard .save-successful{color:#a3ba49}.body .wizard .table-card,.body .wizard .field-card{background-color:white;position:relative;margin-bottom:5px}.body .wizard .table-card h3,.body .wizard .field-card h3{margin-top:5px;margin-bottom:0}.body .wizard .table-card .delete-button,.body .wizard .field-card .delete-button{position:absolute;top:calc(50% - 15px);height:20px;right:5px}.body .wizard .field-card{position:relative}.body .wizard .field-card input{border:none;width:50%}.body .wizard .field-card select{position:absolute;right:50px;top:calc(50% - 15px);height:30px;border:none;box-shadow:none;width:100px;color:#CCCCCC;font-size:14px}.body .wizard .btn-file{display:inline-block !important;position:relative;overflow:hidden}.body .wizard .btn-file input[type=file]{position:absolute;top:0;right:0;min-width:100%;min-height:100%;font-size:100px;text-align:right;filter:alpha(opacity=0);opacity:0;outline:none;background:white;cursor:inherit;display:block}.body .autodetect-auth{width:500px;margin:80px auto;padding-bottom:20px}.body .summary label{display:block;font-size:14px;font-weight:bold;color:#908F96}.body .error-banner{margin:10px 0}.body .error-banner p{margin:2px 0}.body .error-banner ul{padding:20px;list-style-type:circle}.body .error-banner.card{box-shadow:0 0 5px #aa3840} -------------------------------------------------------------------------------- /Build/GenericRestConnector/web/factory.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/Build/GenericRestConnector/web/factory.ttf -------------------------------------------------------------------------------- /Build/GenericRestConnector/web/noAuth.ng.html: -------------------------------------------------------------------------------- 1 | 
2 |
3 |
4 |
5 |
6 |
7 |
No Authentication Required
8 |
9 | -------------------------------------------------------------------------------- /Build/GenericRestConnector/web/oAuth.ng.html: -------------------------------------------------------------------------------- 1 | 
2 |
3 |
4 | Authorize 5 |

Then enter your Refresh or Access Token

6 | 7 |
8 |
9 |
10 |

Enter your Consumer Key and Secret for the connection and Authorize

11 | 12 | 13 |

If you already have your token and token secret you don't need to authorize, simply enter them below

14 | Authorize 15 |

Then enter your Token and Token Secret

16 | 17 | 18 |
19 |
20 |

Enter your Client Id and Secret for the connection and Authorize

21 | 22 | 23 |

If you already have your access token or refresh you don't need to authorize, simply enter it below

24 | Authorize 25 |

Then enter your Refresh or Access Token

26 | 27 |

If a Refresh Token was provided please use that instead of the Access Token.

28 |
29 |
30 |
-------------------------------------------------------------------------------- /Build/GenericRestConnector/web/selectdialog.js: -------------------------------------------------------------------------------- 1 | define(['qvangular' 2 | ], function (qvangular) { 3 | return ['serverside', 'standardSelectDialogService', '$element', 'connectionId', function (serverside, standardSelectDialogService, element, connectionId) { 4 | var dictionary; 5 | var contentProvider = { 6 | getConnectionInfo: function () { 7 | return { 8 | dbusage: false, 9 | ownerusage: false, 10 | dbfirst: false, 11 | specialchars: '', 12 | dbseparator: '', 13 | defaultdatabase: '', 14 | ownerseparator: '', 15 | quotesuffix: '', 16 | quoteprefix: '', 17 | dbmsname: '', 18 | keywords: '' 19 | }; 20 | }, 21 | getDatabases: function () { 22 | return serverside.sendJsonRequest("getDatabases").then(function (response) { 23 | var data = JSON.parse(response.qMessage); 24 | dictionary = data.dictionary; 25 | return data.qDatabases; 26 | }); 27 | //return { qDatabases: [{qName:"Not Applicable"}] }; 28 | }, 29 | getOwners: function ( /*databaseName*/) { 30 | return qvangular.promise([{ name: "" }]); 31 | }, 32 | getTables: function (databaseName, ownerName) { 33 | return serverside.sendJsonRequest("getTables", dictionary).then(function (response) { 34 | return JSON.parse(response.qMessage); 35 | }); 36 | }, 37 | getFields: function (databaseName, ownerName, tableName) { 38 | return serverside.sendJsonRequest("getFields", tableName, dictionary).then(function (response) { 39 | return JSON.parse(response.qMessage); 40 | }); 41 | }, 42 | getPreview: function (databaseName, ownerName, tableName) { //need to add code for preview 43 | return serverside.sendJsonRequest("getPreview", tableName, dictionary).then(function (response) { 44 | return JSON.parse(response.qMessage); 45 | }); 46 | 47 | 48 | } 49 | }; 50 | 51 | standardSelectDialogService.showStandardDialog(contentProvider); 52 | }]; 53 | }); -------------------------------------------------------------------------------- /Factory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/Factory.png -------------------------------------------------------------------------------- /GenericRestConnector/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/.DS_Store -------------------------------------------------------------------------------- /GenericRestConnector/.vs/GenericRestConnector/v14/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/.vs/GenericRestConnector/v14/.suo -------------------------------------------------------------------------------- /GenericRestConnector/Authentication/APIKeyAuth.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace GenericRestConnector 8 | { 9 | public class APIKeyAuth : AuthBase 10 | { 11 | public override System.Net.WebClient PrepClient(System.Net.WebClient client, AuthInfo info, dynamic options) 12 | { 13 | return client; 14 | } 15 | 16 | public override string PrepUrl(string url, AuthInfo info, dynamic options) 17 | { 18 | if(url.IndexOf("?")==-1) 19 | { 20 | url += "?"; 21 | } 22 | else 23 | { 24 | url += "&"; 25 | } 26 | url += options.api_key_parameter; 27 | url += "="; 28 | url += info.APIKey; 29 | return url; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /GenericRestConnector/Authentication/AuthBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Net; 7 | 8 | namespace GenericRestConnector 9 | { 10 | public abstract class AuthBase 11 | { 12 | public abstract WebClient PrepClient(WebClient client, AuthInfo info, dynamic options); 13 | public abstract String PrepUrl(String url, AuthInfo info, dynamic options); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /GenericRestConnector/Authentication/AuthInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace GenericRestConnector 8 | { 9 | public class AuthInfo 10 | { 11 | public String Url { get; set; } 12 | public String User { get; set; } 13 | public String Password { get; set; } 14 | public String oauth2Token { get; set; } 15 | public String oauth1Token { get; set; } 16 | public String oauth1Secret { get; set; } 17 | public String oauth2Secret { get; set; } 18 | public String ConsumerSecret { get; set; } 19 | public String APIKey { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /GenericRestConnector/Authentication/Authentication.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Net; 7 | using QlikView.Qvx.QvxLibrary; 8 | using System.IO; 9 | using Newtonsoft.Json; 10 | 11 | namespace GenericRestConnector 12 | { 13 | public class Authentication 14 | { 15 | AuthInfo authInfo; 16 | dynamic authOptions; 17 | dynamic Auth; 18 | public Authentication(String authMethod, AuthInfo info, dynamic options) 19 | { 20 | authInfo = info; 21 | authOptions = options; 22 | switch (authMethod) 23 | { 24 | case "Basic": 25 | Auth = new BasicAuth(); 26 | break; 27 | case "API Key": 28 | Auth = new APIKeyAuth(); 29 | break; 30 | case "OAuth": 31 | Auth = new OAuthAuth(); 32 | break; 33 | case "OAuth1.0": 34 | Auth = new OAuth1Auth(); 35 | break; 36 | default: 37 | Auth = new NoAuth(); 38 | break; 39 | } 40 | } 41 | 42 | public WebClient PrepClient(WebClient client, AuthInfo info) 43 | { 44 | if (info!=null) 45 | { 46 | authInfo = info; 47 | } 48 | return Auth.PrepClient(client, authInfo, authOptions); 49 | } 50 | public String PrepUrl(String url) 51 | { 52 | try 53 | { 54 | if (url == null) 55 | { 56 | return null; 57 | } 58 | return Auth.PrepUrl(url, authInfo, authOptions); 59 | } 60 | catch (Exception ex) 61 | { 62 | QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Error, ex.Message); 63 | return null; 64 | } 65 | } 66 | public String GetAccessTokenFromRefreshToken(String tokenEndPoint, AuthInfo info) 67 | { 68 | //string url = string.Format(@"{0}?client_id={1}&client_secret={2}&refresh_token={3}&grant_type=refresh_token", tokenEndPoint, info.User, info.oauth2Secret, info.oauth2Token); 69 | WebRequest client = System.Net.WebRequest.Create(tokenEndPoint) as HttpWebRequest; 70 | client.Method = "POST"; 71 | client.ContentType = "application/x-www-form-urlencoded"; 72 | client.Headers[HttpRequestHeader.Authorization] = "Basic " + Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(String.Format("{0}:{1}", info.User, info.oauth2Secret))); 73 | StreamWriter requestWriter = new StreamWriter(client.GetRequestStream()); 74 | try 75 | { 76 | requestWriter.Write(String.Format("refresh_token={0}&grant_type=refresh_token", info.oauth2Token)); 77 | } 78 | catch 79 | { 80 | throw; 81 | } 82 | finally 83 | { 84 | requestWriter.Close(); 85 | } 86 | StreamReader responseReader = new StreamReader(client.GetResponse().GetResponseStream()); 87 | TokenResponse Tokens = new TokenResponse(); 88 | Tokens = JsonConvert.DeserializeObject(responseReader.ReadToEnd()); 89 | return Tokens.access_token; 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /GenericRestConnector/Authentication/BasicAuth.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Net; 7 | 8 | namespace GenericRestConnector 9 | { 10 | public class BasicAuth: AuthBase 11 | { 12 | public override WebClient PrepClient(System.Net.WebClient client, AuthInfo info, dynamic options) 13 | { 14 | String credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(info.User + ":" + info.Password)); 15 | client.Headers[HttpRequestHeader.Authorization] = string.Format("Basic {0}", credentials); 16 | return client; 17 | } 18 | 19 | public override string PrepUrl(string url, AuthInfo info, dynamic options) 20 | { 21 | return url; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /GenericRestConnector/Authentication/NoAuth.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace GenericRestConnector 8 | { 9 | public class NoAuth: AuthBase 10 | { 11 | public override System.Net.WebClient PrepClient(System.Net.WebClient client, AuthInfo info, dynamic options) 12 | { 13 | return client; 14 | } 15 | 16 | public override string PrepUrl(string url, AuthInfo info, dynamic options) 17 | { 18 | return url; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /GenericRestConnector/Authentication/OAuth1Auth.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Net; 7 | using System.IO; 8 | using System.Security.Cryptography; 9 | using System.Diagnostics; 10 | 11 | namespace GenericRestConnector 12 | { 13 | public class OAuth1Auth: AuthBase 14 | { 15 | public override System.Net.WebClient PrepClient(System.Net.WebClient client, AuthInfo info, dynamic options) 16 | { 17 | String nonce = getNonce(); 18 | String timestamp = getTimestamp(); 19 | 20 | Dictionary oAuthParams = new Dictionary { 21 | { "oauth_consumer_key", info.User }, 22 | { "oauth_consumer_secret", info.ConsumerSecret }, 23 | { "oauth_signature_method", "HMAC-SHA1" }, 24 | { "oauth_timestamp", timestamp }, 25 | { "oauth_nonce", nonce }, 26 | { "oauth_version", "1.0"}, 27 | { "oauth_token", info.oauth1Token}, 28 | { "oauth_token_secret", info.Password} 29 | 30 | }; 31 | Uri uri = new Uri(info.Url); 32 | String signingKey = String.Concat(Uri.EscapeDataString(info.ConsumerSecret), "&", Uri.EscapeDataString(info.Password)); 33 | String signature = generateSignature("GET", uri, oAuthParams, signingKey); 34 | oAuthParams.Add("oauth_signature", signature); 35 | //String oauthHeader = String.Format( 36 | // "OAuth oauth_consumer_key=\"{0}\"," + 37 | // "oauth_nonce=\"{1}\"," + 38 | // "oauth_signature_method=\"HMAC-SHA1\"," + 39 | // "oauth_timestamp=\"{2}\"," + 40 | // "oauth_token=\"{3}\"," + 41 | // "oauth_version=\"1.0\"," + 42 | // "oauth_signature=\"{4}\"", 43 | // Uri.EscapeDataString(info.User), 44 | // Uri.EscapeDataString(nonce), 45 | // Uri.EscapeDataString(timestamp), 46 | // Uri.EscapeDataString(info.oauth1Token), 47 | // Uri.EscapeDataString(signature)); 48 | String oauthHeader = "OAuth "; 49 | foreach (KeyValuePair d in oAuthParams) 50 | { 51 | oauthHeader += String.Format("{0}=\"{1}\",", Uri.EscapeDataString(d.Key), Uri.EscapeDataString(d.Value)); 52 | } 53 | oauthHeader = oauthHeader.Substring(0, oauthHeader.Length - 1); 54 | client.Headers.Add(HttpRequestHeader.Authorization, oauthHeader); 55 | return client; 56 | } 57 | 58 | public override string PrepUrl(string url, AuthInfo info, dynamic options) 59 | { 60 | return url; 61 | } 62 | 63 | private static string generateSignature( 64 | string httpMethod, 65 | Uri url, 66 | IDictionary oauthParams, 67 | string secret 68 | ) 69 | { 70 | // Ensure the HTTP Method is upper-cased 71 | httpMethod = httpMethod.ToUpper(); 72 | 73 | // Construct the URL-encoded OAuth parameter portion of the signature base string 74 | string encodedParams = normalizeParams(httpMethod, url, oauthParams); 75 | 76 | // URL-encode the relative URL 77 | //Debugger.Launch(); 78 | string encodedUri; 79 | if (!String.IsNullOrEmpty(url.Query)) 80 | { 81 | encodedUri = Uri.EscapeDataString(url.OriginalString.Replace(url.Query, "")); 82 | } 83 | else 84 | { 85 | encodedUri = Uri.EscapeDataString(url.OriginalString); 86 | } 87 | 88 | // Build the signature base string to be signed with the Consumer Secret 89 | string baseString = String.Format("{0}&{1}&{2}", httpMethod, encodedUri, encodedParams); 90 | 91 | return generateHmac(secret, baseString); 92 | } 93 | 94 | private static string getNonce() 95 | { 96 | string rtn = Path.GetRandomFileName() + Path.GetRandomFileName() + Path.GetRandomFileName(); 97 | rtn = rtn.Replace(".", ""); 98 | if (rtn.Length > 32) 99 | return rtn.Substring(0, 32); 100 | else 101 | return rtn; 102 | } 103 | 104 | private static string getTimestamp() 105 | { 106 | return ((int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds).ToString(); 107 | } 108 | 109 | private static string normalizeParams( 110 | string httpMethod, 111 | Uri url, 112 | IEnumerable> oauthParams 113 | ) 114 | { 115 | IEnumerable> kvpParams = oauthParams; 116 | 117 | // Place any Query String parameters into a key value pair using equals ("=") to mark 118 | // the key/value relationship and join each paramter with an ampersand ("&") 119 | if (!String.IsNullOrWhiteSpace(url.Query)) 120 | { 121 | IEnumerable> queryParams = 122 | from p in url.Query.Substring(1).Split('&').AsEnumerable() 123 | let key = Uri.EscapeDataString(p.Substring(0, p.IndexOf("="))) 124 | let value = Uri.EscapeDataString(p.Substring(p.IndexOf("=") + 1)) 125 | select new KeyValuePair(key, value); 126 | 127 | kvpParams = kvpParams.Union(queryParams); 128 | } 129 | 130 | 131 | 132 | // Sort the parameters in lexicographical order, 1st by Key then by Value; separate with ("=") 133 | IEnumerable sortedParams = 134 | from p in kvpParams 135 | orderby p.Key ascending, p.Value ascending 136 | select p.Key + "=" + p.Value; 137 | 138 | // Add the ampersand delimiter and then URL-encode the equals ("%3D") and ampersand ("%26") 139 | string stringParams = String.Join("&", sortedParams); 140 | string encodedParams = Uri.EscapeDataString(stringParams); 141 | 142 | return encodedParams; 143 | } 144 | 145 | private static string generateHmac(string key, string msg) 146 | { 147 | byte[] keyBytes = Encoding.UTF8.GetBytes(key); 148 | byte[] msgBytes = Encoding.UTF8.GetBytes(msg); 149 | 150 | HMACSHA1 hmac = new HMACSHA1(keyBytes); 151 | 152 | return Convert.ToBase64String(hmac.ComputeHash(msgBytes)); 153 | } 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /GenericRestConnector/Authentication/OAuthAuth.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Net; 7 | using System.IO; 8 | using Newtonsoft.Json; 9 | 10 | namespace GenericRestConnector 11 | { 12 | public class OAuthAuth: AuthBase 13 | { 14 | public override System.Net.WebClient PrepClient(System.Net.WebClient client, AuthInfo info, dynamic options) 15 | { 16 | if (options.oauth_params_in_query!=null && options.oauth_params_in_query == true) 17 | { 18 | 19 | } 20 | else 21 | { 22 | client.Headers[HttpRequestHeader.Authorization] = string.Format("Bearer {0}", info.oauth2Token); 23 | } 24 | return client; 25 | } 26 | 27 | public override string PrepUrl(string url, AuthInfo info, dynamic options) 28 | { 29 | if (options.oauth_params_in_query!=null && options.oauth_params_in_query == true) 30 | { 31 | if (url.IndexOf("?") == -1) 32 | { 33 | url += "?"; 34 | } 35 | else 36 | { 37 | url += "&"; 38 | } 39 | url += "access_token="; 40 | url += info.oauth2Token; 41 | } 42 | return url; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /GenericRestConnector/Authentication/dictionary.json: -------------------------------------------------------------------------------- 1 | {"name":"spotify-dictionary","display_name":"Spotify","owner":"websy85","auth_method":"OAuth","auth_options":{"auth_version":"2.0","oauth_authorize_url":"https://accounts.spotify.com/authorize","oauth_token_url":"https://accounts.spotify.com/api/token","oauth_additional_params":"response_type=code&scope=user-read-private%20user-read-email%20user-top-read","oauth_params_in_query":false,"oauth_redirect_url_parameter":"","uses_refresh_token":true},"paging_method":"None","paging_options":{},"tables":[{"qName":"profile","endpoint":"me","fields":[{"qName":"country","path":"country","type":"String"},{"qName":"display_name","path":"display_name","type":"String"},{"qName":"email","path":"email","type":"String"},{"qName":"external_urls_spotify","path":"external_urls.spotify","type":"String"},{"qName":"followers_href","path":"followers.href","type":"String"},{"qName":"followers_total","path":"followers.total","type":"String"},{"qName":"href","path":"href","type":"String"},{"qName":"id","path":"id","type":"String"},{"qName":"product","path":"product","type":"String"},{"qName":"type","path":"type","type":"String"},{"qName":"uri","path":"uri","type":"String"}],"has_link_to_child":false},{"qName":"topartists","endpoint":"me/top/artists","data_element_override":"items","fields":[{"qName":"external_urls_spotify","path":"external_urls.spotify","type":"String"},{"qName":"followers_href","path":"followers.href","type":"String"},{"qName":"followers_total","path":"followers.total","type":"String"},{"qName":"href","path":"href","type":"String"},{"qName":"id","path":"id","type":"String"},{"qName":"name","path":"name","type":"String"},{"qName":"popularity","path":"popularity","type":"String"},{"qName":"type","path":"type","type":"String"},{"qName":"uri","path":"uri","type":"String"}]},{"qName":"topartistimages","endpoint":"me/top/artists","data_element_override":"items","child_data_element":"images","fields":[{"qName":"parentId","path":"{parent}.id","type":"String"},{"qName":"height","path":"height","type":"String"},{"qName":"url","path":"url","type":"String"},{"qName":"width","path":"width","type":"String"}]}],"id":"58c80d124ee02e0011247070","base_endpoint":"v1"} -------------------------------------------------------------------------------- /GenericRestConnector/Catalog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.IO; 6 | using System.Threading.Tasks; 7 | using Newtonsoft.Json; 8 | using System.Diagnostics; 9 | 10 | namespace GenericRestConnector 11 | { 12 | public static class Catalog 13 | { 14 | public static dynamic _catalog; 15 | static string _configDirectory = @"C:\Program Files\Common Files\Qlik\Custom Data\GenericRestConnector\configs\"; 16 | 17 | public static void Open() 18 | { 19 | try 20 | { 21 | using (StreamReader sr = new StreamReader(_configDirectory + "catalog.json")) 22 | { 23 | _catalog = JsonConvert.DeserializeObject(sr.ReadToEnd()); 24 | } 25 | } 26 | catch (Exception ex) 27 | { 28 | using (StreamWriter sw = new StreamWriter(_configDirectory + "catalog.json")) 29 | { 30 | sw.WriteLine("{\"configs\":{}}"); 31 | _catalog = JsonConvert.DeserializeObject("{\"configs\":{}}"); 32 | } 33 | } 34 | } 35 | 36 | public static void Update() 37 | { 38 | _catalog = JsonConvert.DeserializeObject("{\"configs\":{}}"); 39 | try 40 | { 41 | String[] dirs = Directory.GetDirectories(_configDirectory); 42 | foreach (String dir in dirs) 43 | { 44 | String dirName = dir.Split(new string[] {"\\"}, StringSplitOptions.RemoveEmptyEntries).Last(); 45 | dynamic dictionary = JsonConvert.DeserializeObject(new StreamReader(dir+"\\dictionary.json").ReadToEnd()); 46 | if(_catalog.configs[dictionary.name.ToString()]==null){ 47 | AddEntry(dictionary.display_name.ToString(), dirName, dictionary.name.ToString()); 48 | } 49 | } 50 | } 51 | catch (Exception ex) 52 | { 53 | 54 | } 55 | } 56 | 57 | public static void AddEntry(String displayName, String name, String id) 58 | { 59 | _catalog.configs[name] = "{\"displayName\":\""+displayName+"\",\"folder\":\"" + name + "\", \"id\":\"" + id + "\"}"; 60 | using (StreamWriter sw = new StreamWriter(_configDirectory + "catalog.json")) 61 | { 62 | using (JsonTextWriter jw = new JsonTextWriter(sw)) 63 | { 64 | jw.WriteRawValue(JsonConvert.SerializeObject(_catalog)); 65 | } 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /GenericRestConnector/ErrorHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace GenericRestConnector 7 | { 8 | public class ErrorHelper 9 | { 10 | public string NoConfigUrl = "{\"err\":\"Could not get public dictionaries. No Url specified in config file.\"}"; 11 | public string ErrorDownloadingData = "{\"err\":\"Could not download data.\"}"; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /GenericRestConnector/GenericRestConnector.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {34DF4DC7-25FD-433F-81BB-C7E58253A6D1} 8 | WinExe 9 | Properties 10 | GenericRestConnector 11 | GenericRestConnector 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | C:\Program Files\Common Files\Qlik\Custom Data\GenericRestConnector\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | ..\..\..\..\..\Documents\GenericRestConnector\ 32 | TRACE 33 | prompt 34 | 4 35 | false 36 | 37 | 38 | 39 | 40 | 41 | 42 | true 43 | C:\Program Files\Common Files\Qlik\Custom Data\GenericRestConnector\ 44 | DEBUG;TRACE 45 | full 46 | x64 47 | prompt 48 | MinimumRecommendedRules.ruleset 49 | 50 | 51 | bin\x64\Release\ 52 | TRACE 53 | true 54 | pdbonly 55 | x64 56 | prompt 57 | MinimumRecommendedRules.ruleset 58 | 59 | 60 | OnBuildSuccess 61 | 62 | 63 | 64 | .\Newtonsoft.Json.dll 65 | 66 | 67 | .\QvxLibrary.dll 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | ResXFileCodeGenerator 108 | Resources.Designer.cs 109 | Designer 110 | 111 | 112 | True 113 | Resources.resx 114 | True 115 | 116 | 117 | Designer 118 | 119 | 120 | 121 | SettingsSingleFileGenerator 122 | Settings.Designer.cs 123 | 124 | 125 | True 126 | Settings.settings 127 | True 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | "$(ProjectDir)verpatch.exe" "$(TargetPath)" /s "QlikView Connector" "Generic Rest Connector" 146 | COPY "$(ProjectDir)web\" "$(TargetDir)web\" 147 | 148 | 149 | 150 | 151 | 152 | 159 | -------------------------------------------------------------------------------- /GenericRestConnector/GenericRestConnector.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.23107.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GenericRestConnector", "GenericRestConnector.csproj", "{34DF4DC7-25FD-433F-81BB-C7E58253A6D1}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x64 = Debug|x64 12 | Release|Any CPU = Release|Any CPU 13 | Release|x64 = Release|x64 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {34DF4DC7-25FD-433F-81BB-C7E58253A6D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {34DF4DC7-25FD-433F-81BB-C7E58253A6D1}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {34DF4DC7-25FD-433F-81BB-C7E58253A6D1}.Debug|x64.ActiveCfg = Debug|x64 19 | {34DF4DC7-25FD-433F-81BB-C7E58253A6D1}.Debug|x64.Build.0 = Debug|x64 20 | {34DF4DC7-25FD-433F-81BB-C7E58253A6D1}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {34DF4DC7-25FD-433F-81BB-C7E58253A6D1}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {34DF4DC7-25FD-433F-81BB-C7E58253A6D1}.Release|x64.ActiveCfg = Release|x64 23 | {34DF4DC7-25FD-433F-81BB-C7E58253A6D1}.Release|x64.Build.0 = Release|x64 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /GenericRestConnector/GenericRestConnector.v12.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/GenericRestConnector.v12.suo -------------------------------------------------------------------------------- /GenericRestConnector/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /GenericRestConnector/Paging/OffsetLimitPaging.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace GenericRestConnector 8 | { 9 | public class OffsetLimitPaging:PagingBase 10 | { 11 | public override string PrepUrl(String url, dynamic options, PageInfo pageInfo) 12 | { 13 | if (options.offset_url_parameter == null || options.offset_url_parameter == "") 14 | { 15 | url += String.Format("/{0}/{1}", pageInfo.CurrentRecord, options.batch_size); 16 | } 17 | else 18 | { 19 | if (url.Contains("?")) 20 | { 21 | url += "&"; 22 | } 23 | else 24 | { 25 | url += "?"; 26 | } 27 | url += String.Format("{0}={1}&{2}={3}", options.offset_url_parameter, pageInfo.CurrentRecord, options.limit_url_parameter, options.batch_size); 28 | } 29 | return url; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /GenericRestConnector/Paging/PageInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace GenericRestConnector 8 | { 9 | public class PageInfo 10 | { 11 | public Int64 CurrentRecord { get; set; } 12 | public Int32 CurrentPage { get; set; } 13 | public Int32 CurrentPageSize { get; set; } 14 | public Int64 LoadLimit { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /GenericRestConnector/Paging/PagePaging.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace GenericRestConnector 8 | { 9 | public class PagePaging:PagingBase 10 | { 11 | public override string PrepUrl(String url, dynamic options, PageInfo pageInfo) 12 | { 13 | if (options.page_url_parameter != null && options.page_url_parameter != "") 14 | { 15 | if (url.IndexOf("?") == -1) 16 | { 17 | url += "?"; 18 | } 19 | url += String.Format("{0}={1}", options.page_url_parameter.ToString(), pageInfo.CurrentPage); 20 | } 21 | 22 | return url; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /GenericRestConnector/Paging/Pager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Diagnostics; 7 | 8 | namespace GenericRestConnector 9 | { 10 | public class Pager 11 | { 12 | dynamic Page; 13 | dynamic pagingOptions; 14 | public Boolean CanPage { get; set; } 15 | public Pager(String pagingMethod, dynamic options) 16 | { 17 | pagingOptions = options; 18 | switch (pagingMethod) 19 | { 20 | case "Pages": 21 | CanPage = true; 22 | Page = new PagePaging(); 23 | break; 24 | case "Offset/Limit": 25 | CanPage = true; 26 | Page = new OffsetLimitPaging(); 27 | break; 28 | default: 29 | CanPage = false; 30 | break; 31 | } 32 | } 33 | 34 | public String PrepUrl(String baseUrl, String baseEndpoint, String table, String where, PageInfo pageInfo) 35 | { 36 | //we'll do some generic checks to see if we should be loading data 37 | //is the current record >= loadlimit 38 | if (pageInfo.CurrentRecord >= pageInfo.LoadLimit) 39 | { 40 | return null; 41 | } 42 | //is the current page size/length zero 43 | if (pageInfo.CurrentPageSize != null && pageInfo.CurrentPageSize == 0) 44 | { 45 | return null; 46 | } 47 | String url; 48 | if (!String.IsNullOrEmpty(baseEndpoint)) 49 | { 50 | url = String.Format("{0}/{1}/{2}", baseUrl, baseEndpoint, table); 51 | } 52 | else 53 | { 54 | url = String.Format("{0}/{1}", baseUrl, table); 55 | } 56 | if (!String.IsNullOrEmpty(where)) 57 | { 58 | url += where; 59 | } 60 | if (Page != null) 61 | { 62 | url = Page.PrepUrl(url, pagingOptions, pageInfo); 63 | } 64 | else 65 | { 66 | if (pageInfo.CurrentRecord > 0) 67 | { 68 | return null; 69 | } 70 | } 71 | 72 | return url; 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /GenericRestConnector/Paging/PagingBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace GenericRestConnector 8 | { 9 | public abstract class PagingBase 10 | { 11 | public abstract string PrepUrl(String url, dynamic options, PageInfo info); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /GenericRestConnector/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Forms; 5 | using QlikView.Qvx.QvxLibrary; 6 | 7 | namespace GenericRestConnector 8 | { 9 | static class Program 10 | { 11 | /// 12 | /// The main entry point for the application. 13 | /// 14 | [STAThread] 15 | static void Main(string[] args) 16 | { 17 | if (args != null && args.Length >= 2) 18 | { 19 | new Server().Run(args[0], args[1]); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /GenericRestConnector/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("GenericRestConnector")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("GenericRestConnector")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("34df4dc7-25fd-433f-81bb-c7e58253a6d1")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /GenericRestConnector/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace GenericRestConnector.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GenericRestConnector.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /GenericRestConnector/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /GenericRestConnector/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace GenericRestConnector.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /GenericRestConnector/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /GenericRestConnector/QvxLibrary.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/QvxLibrary.dll -------------------------------------------------------------------------------- /GenericRestConnector/RESTHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Net; 7 | using System.IO; 8 | using System.Diagnostics; 9 | using System.Configuration; 10 | using Newtonsoft.Json; 11 | using QlikView.Qvx.QvxLibrary; 12 | 13 | namespace GenericRestConnector 14 | { 15 | public class RESTHelper 16 | { 17 | WebClient client; 18 | private dynamic ActiveResults; //Dynamic object to store the active result set in so we don't need to pass it between voids 19 | public dynamic Dictionary { get; set; } //Json config definition 20 | public dynamic ActiveTable { get; set; } //Json definition of the table currently being loaded 21 | public Dictionary ActiveFields { get; set; } //Reorganised Json definition of the fields for the active table 22 | public Boolean IsMore { get; set; } //Boolean that identifies if there is more data to be loaded 23 | public String DataElement { get; set; } //Element that identifies where the data is accessed 24 | public String ActiveUrl { get; set; } //Current Url used for loading Json 25 | public String UrlBase; 26 | private String Where; 27 | 28 | public List tableCacheList = new List(); 29 | public Dictionary cacheEndpointMap = new Dictionary(); 30 | public Dictionary cachedTables = new Dictionary(); 31 | 32 | public AuthInfo authInfo = new AuthInfo(); 33 | public Authentication authentication; 34 | 35 | public PageInfo pageInfo = new PageInfo(); 36 | public Pager pager; 37 | 38 | public RESTHelper(Dictionary MParameters) 39 | { 40 | QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, "Setting up REST Helper"); 41 | client = new WebClient(); 42 | client.Encoding = Encoding.UTF8; 43 | 44 | String UserName; 45 | String Password; 46 | String dictionaryUrl; 47 | String Token; 48 | String Secret; 49 | String consumerSecret; 50 | String source; 51 | String dictionaryId; 52 | 53 | //IsMore should start as false and will be re evaluated in the GetJson routine 54 | IsMore = true; 55 | 56 | //Use MParameters to set extra parameters 57 | MParameters.TryGetValue("username", out UserName); 58 | MParameters.TryGetValue("password", out Password); 59 | MParameters.TryGetValue("token", out Token); 60 | MParameters.TryGetValue("secret", out Secret); 61 | MParameters.TryGetValue("consumer_secret", out consumerSecret); 62 | MParameters.TryGetValue("url", out UrlBase); 63 | MParameters.TryGetValue("dictionaryurl", out dictionaryUrl); 64 | MParameters.TryGetValue("source", out source); 65 | MParameters.TryGetValue("dictionary", out dictionaryId); 66 | 67 | authInfo.User = UserName; 68 | authInfo.Password = Password; 69 | authInfo.oauth2Token = Password; 70 | authInfo.oauth2Secret = Secret; 71 | authInfo.APIKey = Password; 72 | authInfo.ConsumerSecret = consumerSecret; 73 | authInfo.oauth1Token = Token; 74 | authInfo.oauth1Secret = Password; 75 | 76 | pageInfo.CurrentRecord = 0; 77 | pageInfo.CurrentPage = 1; 78 | pageInfo.LoadLimit = 1000000; 79 | 80 | if (String.IsNullOrEmpty(dictionaryUrl)) 81 | { 82 | Dictionary = null; 83 | } 84 | 85 | String dictionary; 86 | if (source == "local") 87 | { 88 | String configDirectory = @"C:\Program Files\Common Files\Qlik\Custom Data\GenericRestConnector\configs\"; 89 | dictionary = new StreamReader(configDirectory + dictionaryId + "\\dictionary.json").ReadToEnd(); 90 | } 91 | else 92 | { 93 | //During an online reload the Dictionary JSON is loaded from GitHub. This helps to reduce traffic to the Heroku Dyno 94 | WebClient gitClient = new WebClient(); 95 | gitClient = AddHeaders(gitClient); 96 | dictionary = gitClient.DownloadString(dictionaryUrl); 97 | } 98 | 99 | 100 | if (!String.IsNullOrEmpty(dictionary)) 101 | { 102 | 103 | Dictionary = JsonConvert.DeserializeObject(dictionary); 104 | if (source == "online") 105 | { 106 | Dictionary = Dictionary.content.ToString(); 107 | Dictionary = Convert.FromBase64String(Dictionary); 108 | Dictionary = Encoding.UTF8.GetString(Dictionary); 109 | Dictionary = JsonConvert.DeserializeObject(Dictionary); 110 | } 111 | String authMethod = Dictionary.auth_method.ToString(); 112 | if (authMethod == "OAuth" && Dictionary.auth_options.auth_version.ToString() == "1.0") 113 | { 114 | authMethod = "OAuth1.0"; 115 | } 116 | authentication = new Authentication(authMethod, authInfo, Dictionary.auth_options); 117 | if (authMethod == "OAuth" && Dictionary.auth_options.uses_refresh_token.ToString()=="True") 118 | { 119 | authInfo.oauth2Token = authentication.GetAccessTokenFromRefreshToken(Dictionary.auth_options.oauth_token_url.ToString(), authInfo); 120 | } 121 | pager = new Pager(Dictionary.paging_method.ToString(), Dictionary.paging_options); 122 | } 123 | } 124 | 125 | public void addTableToCacheList(String tableName) 126 | { 127 | tableCacheList.Add(tableName); 128 | } 129 | 130 | public void cacheTable(String tableName, Int32 pageNumber, dynamic data) 131 | { 132 | if (cachedTables.ContainsKey(tableName + pageNumber)) 133 | { 134 | bool validPage = false; 135 | while (!validPage) 136 | { 137 | pageNumber++; 138 | validPage = !cachedTables.ContainsKey(tableName + pageNumber); 139 | } 140 | } 141 | TableCache t = new TableCache(pageNumber, data); 142 | cachedTables.Add(tableName+pageNumber.ToString(), t); 143 | } 144 | 145 | public dynamic getCachedData(String tableName, Int32 pageNumber) 146 | { 147 | //Debugger.Launch(); 148 | foreach (KeyValuePair kvp in cachedTables.Where(item => item.Key==(tableName+pageNumber.ToString())).ToList()) 149 | { 150 | TableCache tc = kvp.Value; 151 | if (tc.page == pageNumber) 152 | { 153 | return tc.data; 154 | } 155 | } 156 | return null; 157 | } 158 | 159 | public void SetActiveTable(String tableName, String whereClause) 160 | { 161 | pageInfo.CurrentPage = 0; 162 | pageInfo.CurrentRecord = 0; 163 | Where = whereClause; 164 | 165 | foreach (dynamic t in Dictionary.tables) 166 | { 167 | if (t.qName == tableName) 168 | { 169 | ActiveTable = t; 170 | ActiveUrl = String.Concat(UrlBase, "/", Dictionary.base_endpoint, "/", t.endpoint); 171 | //Get the name of the data element or use the override if specified 172 | DataElement = Dictionary.data_element; 173 | if (ActiveTable.data_element_override != null && !String.IsNullOrEmpty(ActiveTable.data_element_override.ToString())) 174 | { 175 | DataElement = ActiveTable.data_element_override; 176 | } 177 | //Check to see if we need to set a load limit 178 | if (ActiveTable.load_limit != null && !String.IsNullOrEmpty(ActiveTable.load_limit.ToString())) 179 | { 180 | pageInfo.LoadLimit = Convert.ToInt64(ActiveTable.load_limit); 181 | } 182 | //create a new object to store the fields in a way that makes them easier to access 183 | 184 | ActiveFields = new Dictionary(); 185 | foreach (dynamic field in ActiveTable.fields) 186 | { 187 | ActiveFields[field.qName.ToString()] = field; 188 | } 189 | break; 190 | } 191 | } 192 | } 193 | 194 | public void Prep() 195 | { 196 | IsMore = true; 197 | pageInfo.CurrentRecord = 0; 198 | pageInfo.CurrentPageSize = -1; 199 | //add the headers to the web client 200 | client = AddHeaders(client); 201 | //build the initial url 202 | ActiveUrl = pager.PrepUrl(UrlBase, Dictionary.base_endpoint.ToString(), ActiveTable.endpoint.ToString(), Where, pageInfo); 203 | //add any authentication url stuff 204 | ActiveUrl = authentication.PrepUrl(ActiveUrl); 205 | //prep the WebClient with any authentication steps. we perform this last in case we're authenticating with oAuth 1.0a 206 | authInfo.Url = ActiveUrl; 207 | client = authentication.PrepClient(client, authInfo); 208 | } 209 | 210 | public dynamic GetJSON() 211 | { 212 | //Debugger.Launch(); 213 | QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Debug, "Getting JSON"); 214 | IsMore = false; 215 | String json = ""; 216 | try 217 | { 218 | json = client.DownloadString(ActiveUrl); 219 | QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, "Json was - " + json); 220 | ActiveResults = JsonConvert.DeserializeObject(json); 221 | //PageActiveUrl(); 222 | return ActiveResults; 223 | } 224 | catch (WebException ex) 225 | { 226 | QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Error, "Downloading Web Response - " + ex.Status + ": " + ex.Message); 227 | QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, "Url was - " + ActiveUrl); 228 | QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, "Json was - " + json); 229 | } 230 | catch (Exception ex) 231 | { 232 | QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Error, "Converting Web Response - " + ex.Message); 233 | QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, "Url was - " + ActiveUrl); 234 | QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, "Json was - " + json); 235 | } 236 | return null; 237 | } 238 | 239 | public void Page() 240 | { 241 | pageInfo.CurrentPage++; 242 | //at present supplied url paging doesn't fit into the 'generic' paging model 243 | if (Dictionary.paging_method.ToString() == "Supplied URL") 244 | { 245 | ActiveUrl = ""; 246 | if (Dictionary.paging_options.supplied_url_element!=null) 247 | { 248 | dynamic temp = ActiveResults; 249 | String suppliedUrlPath = Dictionary.paging_options.supplied_url_element.ToString(); 250 | if (!String.IsNullOrEmpty(suppliedUrlPath)) 251 | { 252 | List pagingElemPath = suppliedUrlPath.Split(new String[] { "." }, StringSplitOptions.RemoveEmptyEntries).ToList(); 253 | foreach (String elem in pagingElemPath) 254 | { 255 | temp = temp[elem]; 256 | } 257 | ActiveUrl = temp; 258 | } 259 | } 260 | } 261 | else 262 | { 263 | ActiveUrl = pager.PrepUrl(UrlBase, Dictionary.base_endpoint.ToString(), ActiveTable.endpoint.ToString(), Where, pageInfo); 264 | } 265 | //add any authentication url stuff 266 | ActiveUrl = authentication.PrepUrl(ActiveUrl); 267 | if(String.IsNullOrEmpty(ActiveUrl)) 268 | { 269 | IsMore = false; 270 | } 271 | else 272 | { 273 | IsMore = true; 274 | } 275 | } 276 | 277 | public QvxField[] createFieldList(String tableName, String fields) 278 | { 279 | List fList = new List(); 280 | dynamic table = getTableByName(tableName); 281 | foreach (dynamic f in table.fields) 282 | { 283 | if (fields == "*") 284 | { 285 | fList.Add(new QvxField(f.qName.ToString(), getFieldType(f.type.ToString()), QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, getFieldAttr(f.type.ToString()))); 286 | } 287 | else 288 | { 289 | if (fields.IndexOf(f.qName.ToString()) != -1) 290 | { 291 | //Need to add functionality for converting types 292 | fList.Add(new QvxField(f.qName.ToString(), getFieldType(f.type.ToString()), QvxNullRepresentation.QVX_NULL_FLAG_SUPPRESS_DATA, getFieldAttr(f.type.ToString()))); 293 | } 294 | } 295 | 296 | } 297 | return fList.ToArray(); 298 | } 299 | 300 | //Method for finding a table by Name 301 | private dynamic getTableByName(String name) 302 | { 303 | foreach (dynamic t in Dictionary.tables) 304 | { 305 | if (t.qName == name) 306 | { 307 | return t; 308 | } 309 | } 310 | return null; 311 | } 312 | 313 | //Method for getting the field type 314 | private QvxFieldType getFieldType(String fieldType) 315 | { 316 | switch (fieldType) 317 | { 318 | case "String": 319 | case "Boolean": 320 | return QvxFieldType.QVX_TEXT; 321 | case "Integer": 322 | return QvxFieldType.QVX_SIGNED_INTEGER; 323 | case "Real": 324 | return QvxFieldType.QVX_IEEE_REAL; 325 | default: 326 | return QvxFieldType.QVX_TEXT; 327 | } 328 | } 329 | 330 | //Method for getting the field type 331 | private FieldAttrType getFieldAttr(String fieldType) 332 | { 333 | switch (fieldType) 334 | { 335 | case "String": 336 | return FieldAttrType.ASCII; 337 | case "Boolean": 338 | case "Integer": 339 | return FieldAttrType.INTEGER; 340 | case "Real": 341 | return FieldAttrType.REAL; 342 | default: 343 | return FieldAttrType.ASCII; 344 | } 345 | } 346 | 347 | private WebClient AddHeaders(WebClient wc) 348 | { 349 | //wc.Headers[HttpRequestHeader.ContentType] = "application/json"; 350 | wc.Headers[HttpRequestHeader.Accept] = "application/json"; 351 | wc.Headers[HttpRequestHeader.UserAgent] = "generic-rest-connector"; 352 | wc.Encoding = System.Text.Encoding.UTF8; 353 | return wc; 354 | } 355 | } 356 | } 357 | -------------------------------------------------------------------------------- /GenericRestConnector/Server.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.IO; 6 | using System.IO.Compression; 7 | using QlikView.Qvx.QvxLibrary; 8 | using Newtonsoft.Json; 9 | using System.Diagnostics; 10 | using System.Dynamic; 11 | using System.Net; 12 | using System.Configuration; 13 | 14 | namespace GenericRestConnector 15 | { 16 | class Server : QvxServer 17 | { 18 | dynamic currentDictionary; 19 | ErrorHelper errorHelper = new ErrorHelper(); 20 | public override QvxConnection CreateConnection() 21 | { 22 | return new Connection(); 23 | } 24 | 25 | public override string CreateConnectionString() 26 | { 27 | return ""; 28 | } 29 | 30 | public QvDataContractResponse getOnlineDictionaries() 31 | { 32 | //Debugger.Launch(); 33 | WebClient client = new WebClient(); 34 | client.Headers.Add("Accept", "application/json"); 35 | 36 | String publicDictionariesUrl = ConfigurationManager.AppSettings["PublicDictionaryHost"]; 37 | publicDictionariesUrl += "/api/public"; 38 | if (String.IsNullOrEmpty(publicDictionariesUrl)) 39 | { 40 | return new Info 41 | { 42 | qMessage = errorHelper.NoConfigUrl 43 | }; 44 | } 45 | try 46 | { 47 | String configs = client.DownloadString(publicDictionariesUrl); 48 | if (!String.IsNullOrEmpty(configs)) 49 | { 50 | return new Info 51 | { 52 | qMessage = configs 53 | }; 54 | } 55 | else 56 | { 57 | return new Info 58 | { 59 | qMessage = errorHelper.ErrorDownloadingData 60 | }; 61 | } 62 | } 63 | catch (Exception ex) 64 | { 65 | return new Info 66 | { 67 | qMessage = "{\"configs\":[]}" 68 | }; 69 | } 70 | 71 | } 72 | 73 | public QvDataContractResponse getLocalDictionaries() 74 | { 75 | Catalog.Open(); 76 | return new Info 77 | { 78 | qMessage = JsonConvert.SerializeObject(Catalog._catalog) 79 | }; 80 | } 81 | 82 | public QvDataContractResponse updateLocalCatalog() 83 | { 84 | Catalog.Update(); 85 | return getLocalDictionaries(); 86 | } 87 | 88 | public QvDataContractResponse getDictionaryDef(String id, String source, QvxConnection connection) 89 | { 90 | //Debugger.Launch(); 91 | String dictionary = getDictionary(id, source, connection); 92 | 93 | if (!String.IsNullOrEmpty(dictionary)) 94 | { 95 | dynamic dic = JsonConvert.DeserializeObject(dictionary); 96 | String factory_oauth_authorize_url; 97 | if (dic.auth_options.auth_version!=null && dic.auth_options.auth_version.ToString() == "1.0") 98 | { 99 | factory_oauth_authorize_url = String.Concat(ConfigurationManager.AppSettings["PublicDictionaryHost"], "/api/oauth1_authorize"); 100 | } 101 | else 102 | { 103 | factory_oauth_authorize_url = String.Concat(ConfigurationManager.AppSettings["PublicDictionaryHost"], "/api/oauth2_authorize"); 104 | } 105 | dic.factory_oauth_authorize_url = factory_oauth_authorize_url; 106 | return new Info 107 | { 108 | qMessage = JsonConvert.SerializeObject(dic) 109 | }; 110 | } 111 | else 112 | { 113 | return new Info 114 | { 115 | qMessage = errorHelper.ErrorDownloadingData 116 | }; 117 | } 118 | } 119 | 120 | public QvDataContractResponse getDatabases(String id, String source, QvxConnection connection) 121 | { 122 | currentDictionary = getDictionary(id, source, connection); 123 | String response = "{\"qDatabases\":[{\"qName\": \"Not Applicable\"}]"; 124 | response += ", \"dictionary\":" + currentDictionary + "}"; 125 | return new Info 126 | { 127 | qMessage = response 128 | }; 129 | 130 | } 131 | 132 | public string getDictionary(string id, String source, QvxConnection connection) 133 | { 134 | QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, "Getting dictionary"); 135 | QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, DateTime.Now.ToLongTimeString()); 136 | string d = ""; 137 | if(source=="online"){ 138 | 139 | WebClient client = new WebClient(); 140 | client.Headers.Add("Accept", "application/json"); 141 | 142 | String dictionaryUrl = ConfigurationManager.AppSettings["PublicDictionaryHost"]; 143 | if (String.IsNullOrEmpty(dictionaryUrl)) 144 | { 145 | return null; 146 | } 147 | dictionaryUrl += "/api/public/dictionary/"; 148 | dictionaryUrl += id; 149 | String dictionary = client.DownloadString(dictionaryUrl); 150 | if (!String.IsNullOrEmpty(dictionary)) 151 | { 152 | // connection.MParameters["fulldictionary"] = dictionary; 153 | QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, "Got dictionary"); 154 | QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, DateTime.Now.ToLongTimeString()); 155 | return dictionary; 156 | } 157 | } 158 | else 159 | { 160 | string configDirectory = @"C:\Program Files\Common Files\Qlik\Custom Data\GenericRestConnector\configs\"; 161 | return new StreamReader(configDirectory + id + "\\dictionary.json").ReadToEnd(); 162 | } 163 | return d; 164 | } 165 | 166 | public QvDataContractResponse getTables() 167 | { 168 | return new Info 169 | { 170 | qMessage = JsonConvert.SerializeObject(currentDictionary.tables) 171 | }; 172 | } 173 | 174 | public QvDataContractResponse getFields(String tableName) 175 | { 176 | return new Info 177 | { 178 | qMessage = JsonConvert.SerializeObject(getFieldsForTable(tableName)) 179 | }; 180 | } 181 | 182 | public QvDataContractResponse getPreview(String tableName) 183 | { 184 | //need to modify this to return an actual preview 185 | string[] fields = getFieldNamesForTable(tableName); 186 | List preview = new List(); 187 | dynamic values = new System.Dynamic.ExpandoObject(); 188 | values.qValues = fields; 189 | preview.Add(values); 190 | return new Info 191 | { 192 | qMessage = JsonConvert.SerializeObject(preview.ToArray()) 193 | }; 194 | } 195 | 196 | public string[] getFieldNamesForTable(String tableName) 197 | { 198 | List fields = new List(); 199 | foreach (dynamic t in currentDictionary.tables) 200 | { 201 | if (t.qName == tableName) 202 | { 203 | foreach (dynamic f in t.fields) 204 | { 205 | fields.Add(f.qName.ToString()); 206 | } 207 | } 208 | } 209 | return fields.ToArray(); 210 | } 211 | 212 | public dynamic getFieldsForTable(String tableName) 213 | { 214 | foreach (dynamic t in currentDictionary.tables) 215 | { 216 | if (t.qName == tableName) 217 | { 218 | return t.fields; 219 | } 220 | } 221 | return null; 222 | } 223 | 224 | public QvDataContractResponse copyDictionaryToLocal(String owner, String name, String displayName) 225 | { 226 | //Debugger.Launch(); 227 | Catalog.Open(); 228 | string dictionaryHost = ConfigurationManager.AppSettings["PublicDictionaryHost"]; 229 | string repo = String.Format("http://github.com/{0}/{1}", owner, name); 230 | string zipurl = String.Format("{0}/archive/master.zip", repo); 231 | string configDirectory = @"C:\Program Files\Common Files\Qlik\Custom Data\GenericRestConnector\configs\"; 232 | WebRequest wr = WebRequest.Create(zipurl) as HttpWebRequest; 233 | wr.Method = "GET"; 234 | String tempPath = Path.GetTempPath(); 235 | String tempZip = String.Format("{0}{1}.zip", tempPath, name); 236 | try 237 | { 238 | using (var responseStream = wr.GetResponse().GetResponseStream()) 239 | { 240 | using (FileStream fs = new FileStream(tempZip, FileMode.Create, FileAccess.Write)) 241 | { 242 | responseStream.CopyTo(fs); 243 | } 244 | } 245 | if (!Directory.Exists(configDirectory + name + "-master")) 246 | { 247 | ZipFile.ExtractToDirectory(tempZip, configDirectory); 248 | } 249 | Catalog.AddEntry(displayName, name, repo); 250 | 251 | return new Info 252 | { 253 | qMessage = "\"status\":1" 254 | }; 255 | 256 | // 257 | } 258 | 259 | catch (Exception ex) 260 | { 261 | Console.Write(ex.Message); 262 | return new Info 263 | { 264 | qMessage = "\"err\":\""+ex.Message+"\"" 265 | }; 266 | } 267 | 268 | 269 | 270 | 271 | } 272 | 273 | public override string HandleJsonRequest(string method, string[] userParameters, QvxConnection connection) 274 | { 275 | connection = (Connection)connection; 276 | //Debugger.Launch(); 277 | QvDataContractResponse response; 278 | string provider, url, username, password, dictionary, source; 279 | connection.MParameters.TryGetValue("provider", out provider); 280 | connection.MParameters.TryGetValue("userid", out username); 281 | connection.MParameters.TryGetValue("password", out password); 282 | connection.MParameters.TryGetValue("url", out url); 283 | connection.MParameters.TryGetValue("dictionary", out dictionary); 284 | connection.MParameters.TryGetValue("source", out source); 285 | 286 | switch (method) 287 | { 288 | case "getLocalDictionaries": 289 | response = getLocalDictionaries(); 290 | break; 291 | case "updateLocalCatalog": 292 | response = updateLocalCatalog(); 293 | break; 294 | case "getOnlineDictionaries": 295 | QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, "getting dictionaries"); 296 | QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, DateTime.Now.ToLongTimeString()); 297 | response = getOnlineDictionaries(); 298 | QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, "got dictionaries"); 299 | QvxLog.Log(QvxLogFacility.Application, QvxLogSeverity.Notice, DateTime.Now.ToLongTimeString()); 300 | break; 301 | case "getDictionaryDef": 302 | response = getDictionaryDef(userParameters[0], userParameters[1], connection); 303 | break; 304 | case "getDatabases": 305 | response = getDatabases(dictionary, source, connection); 306 | break; 307 | case "getTables": 308 | currentDictionary = JsonConvert.DeserializeObject(userParameters[0]); 309 | response = getTables(); 310 | break; 311 | case "getFields": 312 | currentDictionary = JsonConvert.DeserializeObject(userParameters[1]); 313 | response = getFields(userParameters[0]); 314 | break; 315 | case "getPreview": 316 | currentDictionary = JsonConvert.DeserializeObject(userParameters[1]); 317 | response = getPreview(userParameters[0]); 318 | break; 319 | case "copyDictionaryToLocal": 320 | response = copyDictionaryToLocal(userParameters[0], userParameters[1], userParameters[2]); 321 | break; 322 | default: 323 | response = new Info { qMessage = "Unknown command" }; 324 | break; 325 | } 326 | return ToJson(response); // serializes response into JSON string 327 | } 328 | } 329 | } 330 | -------------------------------------------------------------------------------- /GenericRestConnector/TableCache.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace GenericRestConnector 8 | { 9 | public class TableCache 10 | { 11 | public Int32 page {get; set;} 12 | public dynamic data { get; set; } 13 | 14 | public TableCache(Int32 pageNum, dynamic pageData) 15 | { 16 | page = pageNum; 17 | data = pageData; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /GenericRestConnector/TokenResponse.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace GenericRestConnector 8 | { 9 | public class TokenResponse 10 | { 11 | public string refresh_token { get; set; } 12 | public string access_token { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /GenericRestConnector/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /GenericRestConnector/bin/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/bin/.DS_Store -------------------------------------------------------------------------------- /GenericRestConnector/bin/x64/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/bin/x64/.DS_Store -------------------------------------------------------------------------------- /GenericRestConnector/bin/x64/Release/GenericRestConnector.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/bin/x64/Release/GenericRestConnector.exe -------------------------------------------------------------------------------- /GenericRestConnector/bin/x64/Release/GenericRestConnector.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /GenericRestConnector/bin/x64/Release/GenericRestConnector.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/bin/x64/Release/GenericRestConnector.pdb -------------------------------------------------------------------------------- /GenericRestConnector/bin/x64/Release/GenericRestConnector.vshost.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/bin/x64/Release/GenericRestConnector.vshost.exe -------------------------------------------------------------------------------- /GenericRestConnector/bin/x64/Release/GenericRestConnector.vshost.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /GenericRestConnector/bin/x64/Release/GenericRestConnector.vshost.exe.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /GenericRestConnector/bin/x64/Release/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/bin/x64/Release/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /GenericRestConnector/bin/x64/Release/QvxLibrary.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/bin/x64/Release/QvxLibrary.dll -------------------------------------------------------------------------------- /GenericRestConnector/bin/x64/Release/web/apiKey.ng.html: -------------------------------------------------------------------------------- 1 | 
2 |

Provide a valid API Key for the connection

3 | 4 | 5 |
6 | -------------------------------------------------------------------------------- /GenericRestConnector/bin/x64/Release/web/basicAuth.ng.html: -------------------------------------------------------------------------------- 1 | 
2 |

Provide a Username and Password for the connection

3 | 4 | 5 | 6 | 7 |
8 | 9 | -------------------------------------------------------------------------------- /GenericRestConnector/bin/x64/Release/web/connectdialog.css: -------------------------------------------------------------------------------- 1 | .qrest-connect-dialog-container { 2 | 3 | } 4 | 5 | .qrest-connect-dialog { 6 | width: 70%; 7 | margin: 50px auto; 8 | height: calc(100vh - 100px); 9 | background-color: white; 10 | position: relative; 11 | padding-left: 10px; 12 | padding-right: 10px; 13 | } 14 | 15 | .qrest-authorize{ 16 | text-decoration: none; 17 | } 18 | 19 | .qrest-footer{ 20 | position: absolute; 21 | bottom: 0px; 22 | right: 0px; 23 | } 24 | 25 | .qrest-loader{ 26 | position: absolute; 27 | height: 100px; 28 | width: 100px; 29 | top: calc(50% - 50px); 30 | left: calc(50% - 50px); 31 | } 32 | 33 | .connection-settings input{ 34 | display: block; 35 | width: 96%; 36 | height: 25px; 37 | padding: 6px 12px; 38 | font-size: 14px; 39 | line-height: 1.42857143; 40 | color: #555; 41 | background-color: #fff; 42 | background-image: none; 43 | border: 1px solid #ccc; 44 | border-radius: 4px; 45 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075); 46 | box-shadow: inset 0 1px 1px rgba(0,0,0,.075); 47 | -webkit-transition: border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s; 48 | -o-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s; 49 | transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s; 50 | } 51 | 52 | .select-config-dialog{ 53 | height: calc(100% - 50px); 54 | } 55 | 56 | .select-config-dialog, .connection-settings{ 57 | padding: 5px; 58 | } 59 | 60 | .select-config-source{ 61 | height: 80px; 62 | margin-left: -10px; 63 | margin-right: -10px; 64 | } 65 | 66 | .select-config-source li{ 67 | list-style-type: none; 68 | display: inline-block; 69 | width: 12% !important; 70 | cursor: pointer; 71 | margin-left: 10px; 72 | margin-right: 10px; 73 | line-height: 60px !important; 74 | } 75 | 76 | .select-config{ 77 | overflow-x: hidden; 78 | overflow-y: auto; 79 | padding: 10px 2px; 80 | height: calc(100% - 135px); 81 | } 82 | 83 | .primary-button{ 84 | cursor: pointer; 85 | } 86 | 87 | .select-config ul{ 88 | list-style-type: none; 89 | margin-left: -10px; 90 | margin-right: -10px; 91 | } 92 | 93 | .select-config li{ 94 | display: inline-block; 95 | width: 23%; 96 | margin-left: 10px; 97 | margin-right: 10px; 98 | cursor: pointer; 99 | } 100 | 101 | .subpage{ 102 | margin-top: 20px; 103 | } 104 | 105 | 106 | .loading-container .message{ 107 | position: absolute; 108 | height: 100px; 109 | width: 40%; 110 | top: calc(50% + 100px); 111 | left: calc(30%); 112 | text-align: center; 113 | } -------------------------------------------------------------------------------- /GenericRestConnector/bin/x64/Release/web/connectdialog.js: -------------------------------------------------------------------------------- 1 | define(['qvangular', 'text!./connectdialog.ng.html', 'css!./connectdialog.css', 'css!./dictionary-factory.css'], function (qvangular, template) { 2 | return { 3 | template: template, 4 | controller: ['$scope', 'input', function ($scope, input) { 5 | function init() { 6 | $scope.isEdit = input.editMode; 7 | $scope.isLoading = true; 8 | $scope.auth_method; 9 | $scope.subpageLoading = false; 10 | $scope.id = input.instanceId; 11 | $scope.connectionParameters = {}; 12 | $scope.localDictionaryList = []; 13 | $scope.onlineDictionaryList = []; 14 | $scope.source = "online"; 15 | $scope.dictionaryIndex; 16 | $scope.step = "config-selection"; 17 | $scope.connectionTemplates = { 18 | None: "/customdata/64/GenericRestConnector/web/noAuth.ng.html", 19 | Basic: "/customdata/64/GenericRestConnector/web/basicAuth.ng.html", 20 | "OAuth": "/customdata/64/GenericRestConnector/web/oAuth.ng.html", 21 | Certificate: "", 22 | "API Key": "/customdata/64/GenericRestConnector/web/apiKey.ng.html" 23 | }; 24 | $scope.name; 25 | $scope.username; 26 | $scope.loadingMessage = "Fetching Online and Local dictionaries. Please bare with us."; 27 | $scope.password; 28 | $scope.token; 29 | $scope.consumer_secret; 30 | $scope.key; 31 | $scope.secret; 32 | $scope.tokenRequested = false; 33 | $scope.url; 34 | $scope.dicurl=""; 35 | $scope.config; 36 | $scope.provider = "GenericRestConnector.exe"; 37 | $scope.idForAuthorization = ""; 38 | $scope.subpage = $scope.connectionTemplates["None"]; 39 | 40 | //if the connection is being modified 41 | if (input.editMode) { 42 | input.serverside.getConnection(input.instanceId).then(function (result) { 43 | console.log(result); 44 | var tempArray = result.qConnection.qConnectionString.substring(19, result.qConnection.qConnectionString.length - 1).split(';'); 45 | for (var i = 0; i < tempArray.length; i++) { 46 | var param = tempArray[i].split('='); 47 | $scope.connectionParameters[param[0]] = param[1]; 48 | } 49 | $scope.config = $scope.connectionParameters["config"]; 50 | $scope.name = result.qConnection.qName; 51 | $scope.url = $scope.connectionParameters["url"]; 52 | $scope.dicurl = $scope.connectionParameters["dictionaryurl"]; 53 | $scope.dictionaryId = $scope.connectionParameters["dictionary"];; 54 | $scope.source = $scope.connectionParameters["source"]; 55 | $scope.username = $scope.connectionParameters["username"]; 56 | $scope.isLoading = false; 57 | $scope.subpageLoading = true; 58 | $scope.loadTemplate('connection-settings', $scope.dictionaryId, $scope.dicurl); 59 | }); 60 | } 61 | else { 62 | //get online dictionaries 63 | input.serverside.sendJsonRequest("getOnlineDictionaries").then(function (response) { 64 | $scope.onlineDictionaryList = JSON.parse(response.qMessage).configs; 65 | if ($scope.onlineDictionaryList && $scope.localDictionaryList) { 66 | $scope.isLoading = false; 67 | } 68 | }); 69 | //get local dictionaries 70 | input.serverside.sendJsonRequest("getLocalDictionaries").then(function (response) { 71 | var catalog = JSON.parse(response.qMessage); 72 | $scope.processCatalog(catalog); 73 | if ($scope.onlineDictionaryList && $scope.localDictionaryList) { 74 | $scope.isLoading = false; 75 | } 76 | }); 77 | } 78 | } 79 | 80 | //build the connection string 81 | function buildConnectionString() { 82 | var conn = "CUSTOM CONNECT TO \"provider=GenericRestConnector.exe;dictionary=" + $scope.dictionaryId + ";source=" + $scope.source + ";auth-method="+$scope.auth_method+";"; 83 | $('[data-parameter]').each(function (index, item) { 84 | if ($(item).attr("data-parameter") == "password") { 85 | $scope.password = $(item).val(); 86 | } 87 | else { 88 | conn += $(item).attr("data-parameter") + "=" + $(item).val() + ";"; 89 | } 90 | }); 91 | 92 | if ($scope.dicurl) { 93 | conn += "dictionaryurl=" + $scope.dicurl + ";"; 94 | } 95 | conn += "\""; 96 | console.log(conn); 97 | return conn; 98 | } 99 | 100 | //save the connection 101 | $scope.onOKClicked = function () { 102 | if ($scope.isEdit) { 103 | input.serverside.modifyConnection($scope.instanceId, $scope.name, buildConnectionString(), $scope.provider, true, $scope.username, $scope.password); 104 | $scope.destroyComponent(); 105 | } 106 | else { 107 | input.serverside.createNewConnection($scope.name, buildConnectionString(), $scope.username, $scope.password); 108 | $scope.destroyComponent(); 109 | } 110 | }; 111 | 112 | //close the dialog 113 | $scope.onCancelClicked = function () { 114 | if (!$scope.isLoading) { 115 | $scope.destroyComponent(); 116 | } 117 | }; 118 | 119 | $scope.backToCatalog = function () { 120 | $scope.step = "config-selection"; 121 | $scope.subpage = null; 122 | }; 123 | 124 | //display the appropriate step 125 | $scope.nextStep = function (step) { 126 | $scope.step = step; 127 | }; 128 | 129 | $scope.setSource = function (source) { 130 | $scope.source = source; 131 | }; 132 | 133 | $scope.updateCatalog = function () { 134 | input.serverside.sendJsonRequest("updateLocalCatalog").then(function (response) { 135 | var catalog = JSON.parse(response.qMessage); 136 | $scope.processCatalog(catalog); 137 | if ($scope.onlineDictionaryList && $scope.localDictionaryList) { 138 | $scope.isLoading = false; 139 | } 140 | }); 141 | }; 142 | 143 | //load and display the required template based on the config auth setting 144 | $scope.loadTemplate = function (step, index, dicurl) { 145 | $scope.subpageLoading = true; 146 | this.nextStep(step); 147 | if (!$scope.isEdit) { 148 | if ($scope.source == "online") { 149 | $scope.selectedDictionaryInfo = $scope.onlineDictionaryList[index]; 150 | $scope.dictionaryId = $scope.onlineDictionaryList[index]._id; 151 | $scope.idForAuthorization = $scope.onlineDictionaryList[index]._id; 152 | } 153 | else { 154 | $scope.selectedDictionaryInfo = $scope.localDictionaryList[index]; 155 | $scope.dictionaryId = $scope.localDictionaryList[index].folder; 156 | } 157 | 158 | } 159 | $scope.dicurl = dicurl; 160 | $scope.loadingMessage = "Downloading Dictionary Definition..."; 161 | input.serverside.sendJsonRequest("getDictionaryDef", $scope.dictionaryId, $scope.source).then(function (response) { 162 | $scope.dictionaryDef = JSON.parse(response.qMessage); 163 | $scope.auth_method = $scope.dictionaryDef.auth_method; 164 | $scope.subpage = $scope.connectionTemplates[$scope.dictionaryDef.auth_method]; 165 | $scope.subpageLoading = false; 166 | if ($scope.source == "local") { 167 | $scope.idForAuthorization = $scope.dictionaryDef.id; 168 | } 169 | }); 170 | } 171 | 172 | $scope.processCatalog = function (catalog) { 173 | $scope.localDictionaryList = []; 174 | if (catalog.configs) { 175 | for (var d in catalog.configs) { 176 | $scope.localDictionaryList.push(JSON.parse(catalog.configs[d])); 177 | } 178 | } 179 | } 180 | 181 | init(); 182 | }] 183 | }; 184 | }); -------------------------------------------------------------------------------- /GenericRestConnector/bin/x64/Release/web/connectdialog.ng.html: -------------------------------------------------------------------------------- 1 | 
2 |
3 |
4 |
5 |
{{loadingMessage}}
6 |
7 |
8 |
9 |

Choose a REST Configuration

10 |
    11 | 12 | 13 |
14 |
15 |
16 | 17 |
18 |
19 |
20 |
    21 |
  • 22 |
    23 | {{dic.display_name}} 24 |
    {{dic.owner}}
    25 |
    26 | 27 |
    28 |
    29 |
  • 30 |
31 |
32 |
33 | 34 |
35 |
    36 |
  • 37 |
    38 | {{dic.displayName}} 39 |
    40 | 41 |
    42 |
    43 |
  • 44 |
45 |
46 |
47 |
48 |

Provide a name and the Url for the connection

49 | 50 |
51 | 52 |
53 |
54 |
55 |
{{loadingMessage}}
56 |
57 |
58 | 59 |
60 |
61 |
62 |
63 |
64 | 65 | 66 | Save 67 | 68 |
69 |
70 |
71 | -------------------------------------------------------------------------------- /GenericRestConnector/bin/x64/Release/web/connector-main.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 3 | ], 4 | function () { 5 | 6 | }); -------------------------------------------------------------------------------- /GenericRestConnector/bin/x64/Release/web/dictionary-factory.css: -------------------------------------------------------------------------------- 1 | .white{color:white !important}@font-face{font-family:factory;src:url(/resources/factory.ttf)}@font-face{font-family:factory;src:url(factory.ttf)}@font-face{font-family:Stellar;font-weight:lighter;src:url(/resources/Stellar-light.otf)}@font-face{font-family:Stellar;font-weight:normal;src:url(/resources/Stellar-regular.otf)}@font-face{font-family:Aileron;src:url(/resources/Ailerons-Typeface.otf)}.body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:Stellar,"QlikView Sans",sans-serif;font-size:16px;color:#464646;background-color:white;background-image:url(/resources/background.jpg);background-position:bottom;background-attachment:fixed;background-size:40%;background-repeat:repeat-x}.body label{font-weight:normal;margin:3px 0}.body .page{margin-top:80px}.body .content{padding:10px 0}.body .float-right{float:right}.body .float-left{float:left}.body .align-right{text-align:right}.body .primary-button,.body .secondary-button{display:block;width:200px;padding:5px;height:35px;line-height:26px;text-align:center;border-radius:3px;font-weight:normal;border:none;box-sizing:border-box}.body .primary-button{background-color:#CEBDA4;color:white;margin-bottom:3px}.body .secondary-button{background-color:#AEB9C7;color:white;margin-bottom:3px}.body .download-button,.body .delete-button,.body .back-button{display:block;cursor:pointer;background-color:transparent;border:none;height:30px;width:30px;line-height:30px;color:#CCCCCC}.body .download-button:after,.body .delete-button:after,.body .back-button:after{position:absolute;top:0;left:0;font-family:factory;font-size:30px}.body .download-button:after{content:"\E803"}.body .download-button:hover{color:#a3ba49}.body .delete-button:after{content:"\E802"}.body .delete-button:hover{color:#aa3840}.body .back-button{position:relative;color:#CEBDA4;width:auto !important;padding-left:45px;font-size:20px}.body .back-button:after{font-family:factory;content:"\E800"}.body .title{font-size:20px;font-weight:normal;color:#CEBDA4}.body .check-label{height:30px;line-height:30px;display:inline-block;margin:0;padding:0;vertical-align:top}.body input[type=checkbox]{display:inline-block;width:30px;margin:0;height:30px;line-height:30px}.body h1,.body h2,.body h3,.body h4{margin-top:5px;margin-bottom:5px}.body h1{font-size:24px;color:#CEBDA4}.body h2{font-size:20px;color:#464646}.body h3{font-size:18px;color:#908F96}.body h4{font-size:16px;color:#464646;font-weight:bold}.body ul{list-style-type:none}.body .plainlist{margin:0;padding:0}.body .description{padding:10px 0}.body .card{background-color:#F8F9FB;padding:5px 10px;border-radius:3px;box-shadow:0 0 5px #ccc}.body .card.active{box-shadow:0 0 5px #908F96}.body .dictionary{height:220px;position:relative;margin-bottom:15px}.body .dictionary .icon{text-align:center;height:150px;width:100%}.body .dictionary .icon img{margin-top:20px;max-height:100px}.body .dictionary .title{text-align:center;display:block;height:20px;color:#464646}.body .dictionary .sub-title{text-align:center;font-size:14px;font-weight:normal;color:#908F96}.body .dictionary .delete-button{position:absolute;bottom:10px;right:5px}.body .dictionary .download-button{padding-left:45px;position:absolute;bottom:10px;left:10px}.body .dictionary-link{display:block}.body .dictionary-link:hover,.body .dictionary-link:visited{text-decoration:none}.body .hint{color:#908F96;font-size:12px;margin:2px 0}.body .hint strong{color:#464646}.body .inline{display:inline-block;margin-right:5px}.body .spacer{border:1px solid #CCCCCC;margin:5px 0}.body .horizontal-spacer{width:10px;height:1px}.body .vertical-spacer{height:10px}.body .smokescreen{z-index:1000;background-color:rgba(200,200,200,0.8);position:absolute;top:0;left:0;height:100%;width:100%}.body .center{text-align:center}.body .show{display:block}.body .hide{display:none}.body .token-card{margin:0 auto;margin-top:50px;width:auto;padding:20px;text-align:center}.body .token-card.token{font-size:30px}.body .inline{display:inline-block}.body .status{line-height:34px}.body .navbar{min-height:70px;background-color:#908F96;color:#FFFFFF}.body .navbar a{color:#FFFFFF;font-size:16px}.body .navbar a:hover{color:#908F96}.body .navbar .navbar-brand{font-family:Aileron;font-weight:lighter;font-size:24px;letter-spacing:2px;height:70px;line-height:40px}.body .navbar .navbar-brand:hover{color:white}.body .navbar .navbar-nav li a{line-height:40px}.body .navbar .dropdown.open a{color:#908F96}.body .intro{margin-top:70px}.body .intro .title{font-size:36px}.body .intro .intro-option{text-align:center;margin:50px 0;color:#464646;font-size:30px}.body .intro .intro-option a,.body .intro .intro-option a:hover,.body .intro .intro-option a:visited{color:#464646;text-decoration:none}.body .intro .intro-option:hover{-ms-transform:scale(1.2);-webkit-transform:scale(1.2);transform:scale(1.2)}.body .login-container{width:400px;margin:0 auto;padding-top:30px}.body .login-container .login-logo{height:200px;background:url(/resources/Octocat.png) center center no-repeat;background-size:contain;margin-bottom:20px}.body .login-container .login-button{margin:0 100px}.body .dictionary-nav .nav-button{height:60px;display:inline-block;line-height:50px;width:100%;font-size:16px;text-align:center;color:#CEBDA4}.body .dictionary-nav .nav-button a{color:#CEBDA4}.body .dictionary-nav .nav-button.active{background-color:#908F96;color:white}.body .dictionary-nav .nav-button.active:hover{-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1)}.body .dictionary-nav .nav-button:hover{-ms-transform:scale(1.1);-webkit-transform:scale(1.1);transform:scale(1.1)}.body .general .icon img{max-height:100px}.body .wizard .path{font-size:14px;font-weight:normal;color:#CEBDA4}.body .wizard .auth-version span,.body .wizard .auth-version input{line-height:30px;height:30px;padding:0;margin:0;width:auto;min-width:30px;vertical-align:top;box-shadow:none}.body .wizard .auth-version input{margin-right:50px}.body .wizard .auth-method,.body .wizard .paging-method{height:110px;cursor:pointer;background-color:white}.body .wizard .auth-method .auth-type,.body .wizard .paging-method .auth-type,.body .wizard .auth-method .paging-type,.body .wizard .paging-method .paging-type{text-align:center}.body .wizard .auth-method .auth-desc,.body .wizard .paging-method .auth-desc,.body .wizard .auth-method .paging-desc,.body .wizard .paging-method .paging-desc{font-size:12px}.body .wizard .auth-method.active,.body .wizard .paging-method.active{border:2px solid #CEBDA4;box-shadow:0 0 5px #CEBDA4}.body .wizard .save-successful{color:#a3ba49}.body .wizard .table-card,.body .wizard .field-card{background-color:white;position:relative;margin-bottom:5px}.body .wizard .table-card h3,.body .wizard .field-card h3{margin-top:5px;margin-bottom:0}.body .wizard .table-card .delete-button,.body .wizard .field-card .delete-button{position:absolute;top:calc(50% - 15px);height:20px;right:5px}.body .wizard .field-card{position:relative}.body .wizard .field-card input{border:none;width:50%}.body .wizard .field-card select{position:absolute;right:50px;top:calc(50% - 15px);height:30px;border:none;box-shadow:none;width:100px;color:#CCCCCC;font-size:14px}.body .wizard .btn-file{display:inline-block !important;position:relative;overflow:hidden}.body .wizard .btn-file input[type=file]{position:absolute;top:0;right:0;min-width:100%;min-height:100%;font-size:100px;text-align:right;filter:alpha(opacity=0);opacity:0;outline:none;background:white;cursor:inherit;display:block}.body .autodetect-auth{width:500px;margin:80px auto;padding-bottom:20px}.body .summary label{display:block;font-size:14px;font-weight:bold;color:#908F96}.body .error-banner{margin:10px 0}.body .error-banner p{margin:2px 0}.body .error-banner ul{padding:20px;list-style-type:circle}.body .error-banner.card{box-shadow:0 0 5px #aa3840} -------------------------------------------------------------------------------- /GenericRestConnector/bin/x64/Release/web/factory.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/bin/x64/Release/web/factory.ttf -------------------------------------------------------------------------------- /GenericRestConnector/bin/x64/Release/web/noAuth.ng.html: -------------------------------------------------------------------------------- 1 | 
2 |
3 |
4 |
5 |
6 |
7 |
No Authentication Required
8 |
9 | -------------------------------------------------------------------------------- /GenericRestConnector/bin/x64/Release/web/oAuth.ng.html: -------------------------------------------------------------------------------- 1 | 
2 |
3 |
4 | Authorize 5 |

Then enter your Refresh or Access Token

6 | 7 |
8 |
9 |
10 |

Enter your Consumer Key and Secret for the connection and Authorize

11 | 12 | 13 |

If you already have your token and token secret you don't need to authorize, simply enter them below

14 | Authorize 15 |

Then enter your Token and Token Secret

16 | 17 | 18 |
19 |
20 |

Enter your Client Id and Secret for the connection and Authorize

21 | 22 | 23 |

If you already have your access token or refresh you don't need to authorize, simply enter it below

24 | Authorize 25 |

Then enter your Refresh or Access Token

26 | 27 |

If a Refresh Token was provided please use that instead of the Access Token.

28 |
29 |
30 |
-------------------------------------------------------------------------------- /GenericRestConnector/bin/x64/Release/web/selectdialog.js: -------------------------------------------------------------------------------- 1 | define(['qvangular' 2 | ], function (qvangular) { 3 | return ['serverside', 'standardSelectDialogService', '$element', 'connectionId', function (serverside, standardSelectDialogService, element, connectionId) { 4 | var dictionary; 5 | var contentProvider = { 6 | getConnectionInfo: function () { 7 | return { 8 | dbusage: false, 9 | ownerusage: false, 10 | dbfirst: false, 11 | specialchars: '', 12 | dbseparator: '', 13 | defaultdatabase: '', 14 | ownerseparator: '', 15 | quotesuffix: '', 16 | quoteprefix: '', 17 | dbmsname: '', 18 | keywords: '' 19 | }; 20 | }, 21 | getDatabases: function () { 22 | return serverside.sendJsonRequest("getDatabases").then(function (response) { 23 | var data = JSON.parse(response.qMessage); 24 | dictionary = data.dictionary; 25 | return data.qDatabases; 26 | }); 27 | //return { qDatabases: [{qName:"Not Applicable"}] }; 28 | }, 29 | getOwners: function ( /*databaseName*/) { 30 | return qvangular.promise([{ name: "" }]); 31 | }, 32 | getTables: function (databaseName, ownerName) { 33 | return serverside.sendJsonRequest("getTables", dictionary).then(function (response) { 34 | return JSON.parse(response.qMessage); 35 | }); 36 | }, 37 | getFields: function (databaseName, ownerName, tableName) { 38 | return serverside.sendJsonRequest("getFields", tableName, dictionary).then(function (response) { 39 | return JSON.parse(response.qMessage); 40 | }); 41 | }, 42 | getPreview: function (databaseName, ownerName, tableName) { //need to add code for preview 43 | return serverside.sendJsonRequest("getPreview", tableName, dictionary).then(function (response) { 44 | return JSON.parse(response.qMessage); 45 | }); 46 | 47 | 48 | } 49 | }; 50 | 51 | standardSelectDialogService.showStandardDialog(contentProvider); 52 | }]; 53 | }); -------------------------------------------------------------------------------- /GenericRestConnector/obj/Debug/DesignTimeResolveAssemblyReferences.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Debug/DesignTimeResolveAssemblyReferences.cache -------------------------------------------------------------------------------- /GenericRestConnector/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /GenericRestConnector/obj/Debug/GenericRestConnector.Properties.Resources.resources: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Debug/GenericRestConnector.Properties.Resources.resources -------------------------------------------------------------------------------- /GenericRestConnector/obj/Debug/GenericRestConnector.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | C:\Program Files\Common Files\Qlik\Custom Data\generic-rest-connector\generic-rest-connector.exe.config 2 | C:\Program Files\Common Files\Qlik\Custom Data\generic-rest-connector\generic-rest-connector.exe 3 | C:\Program Files\Common Files\Qlik\Custom Data\generic-rest-connector\generic-rest-connector.pdb 4 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\generic-rest-connector\obj\Debug\generic_rest_connector.Properties.Resources.resources 5 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\generic-rest-connector\obj\Debug\GenericRestConnector.csproj.GenerateResource.Cache 6 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\generic-rest-connector\obj\Debug\generic-rest-connector.exe 7 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\generic-rest-connector\obj\Debug\generic-rest-connector.pdb 8 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\generic-rest-connector\obj\Debug\GenericRestConnector.exe 9 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\generic-rest-connector\obj\Debug\GenericRestConnector.pdb 10 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\generic-rest-connector\obj\Debug\GenericRestConnector.Properties.Resources.resources 11 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\Debug\GenericRestConnector.Properties.Resources.resources 12 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\Debug\GenericRestConnector.csproj.GenerateResource.Cache 13 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\Debug\GenericRestConnector.exe 14 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\Debug\GenericRestConnector.pdb 15 | C:\Program Files\Common Files\Qlik\Custom Data\GenericRestConnector\GenericRestConnector.exe.config 16 | C:\Program Files\Common Files\Qlik\Custom Data\GenericRestConnector\GenericRestConnector.exe 17 | C:\Program Files\Common Files\Qlik\Custom Data\GenericRestConnector\GenericRestConnector.pdb 18 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\Debug\GenericRestConnector.csprojResolveAssemblyReference.cache 19 | -------------------------------------------------------------------------------- /GenericRestConnector/obj/Debug/GenericRestConnector.csproj.GenerateResource.Cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Debug/GenericRestConnector.csproj.GenerateResource.Cache -------------------------------------------------------------------------------- /GenericRestConnector/obj/Debug/GenericRestConnector.csprojResolveAssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Debug/GenericRestConnector.csprojResolveAssemblyReference.cache -------------------------------------------------------------------------------- /GenericRestConnector/obj/Debug/GenericRestConnector.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Debug/GenericRestConnector.exe -------------------------------------------------------------------------------- /GenericRestConnector/obj/Debug/GenericRestConnector.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Debug/GenericRestConnector.pdb -------------------------------------------------------------------------------- /GenericRestConnector/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Debug/TempPE/Properties.Resources.Designer.cs.dll -------------------------------------------------------------------------------- /GenericRestConnector/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs -------------------------------------------------------------------------------- /GenericRestConnector/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs -------------------------------------------------------------------------------- /GenericRestConnector/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs -------------------------------------------------------------------------------- /GenericRestConnector/obj/Debug/generic-rest-connector.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\generic-rest-connector\obj\Debug\generic_rest_connector.Properties.Resources.resources 2 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\generic-rest-connector\obj\Debug\generic-rest-connector.csproj.GenerateResource.Cache 3 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\generic-rest-connector\obj\Debug\generic-rest-connector.exe 4 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\generic-rest-connector\obj\Debug\generic-rest-connector.pdb 5 | C:\Program Files\Common Files\Qlik\Custom Data\generic-rest-connector\generic-rest-connector.exe.config 6 | C:\Program Files\Common Files\Qlik\Custom Data\generic-rest-connector\generic-rest-connector.exe 7 | C:\Program Files\Common Files\Qlik\Custom Data\generic-rest-connector\generic-rest-connector.pdb 8 | -------------------------------------------------------------------------------- /GenericRestConnector/obj/Debug/generic-rest-connector.csproj.GenerateResource.Cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Debug/generic-rest-connector.csproj.GenerateResource.Cache -------------------------------------------------------------------------------- /GenericRestConnector/obj/Debug/generic-rest-connector.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Debug/generic-rest-connector.exe -------------------------------------------------------------------------------- /GenericRestConnector/obj/Debug/generic-rest-connector.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Debug/generic-rest-connector.pdb -------------------------------------------------------------------------------- /GenericRestConnector/obj/Debug/generic_rest_connector.Properties.Resources.resources: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Debug/generic_rest_connector.Properties.Resources.resources -------------------------------------------------------------------------------- /GenericRestConnector/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Release/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /GenericRestConnector/obj/Release/GenericRestConnector.Properties.Resources.resources: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Release/GenericRestConnector.Properties.Resources.resources -------------------------------------------------------------------------------- /GenericRestConnector/obj/Release/GenericRestConnector.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\Release\GenericRestConnector.exe.config 2 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\Release\GenericRestConnector.exe 3 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\Release\GenericRestConnector.pdb 4 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\Release\Newtonsoft.Json.dll 5 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\Release\QvxLibrary.dll 6 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\Release\GenericRestConnector.Properties.Resources.resources 7 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\Release\GenericRestConnector.csproj.GenerateResource.Cache 8 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\Release\GenericRestConnector.exe 9 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\Release\GenericRestConnector.pdb 10 | C:\Program Files\Common Files\Qlik\Custom Data\GenericRestConnector\GenericRestConnector.exe.config 11 | C:\Program Files\Common Files\Qlik\Custom Data\GenericRestConnector\GenericRestConnector.exe 12 | C:\Program Files\Common Files\Qlik\Custom Data\GenericRestConnector\GenericRestConnector.pdb 13 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\Release\GenericRestConnector.csprojResolveAssemblyReference.cache 14 | Z:\Users\nwr\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\Release\GenericRestConnector.exe.config 15 | Z:\Users\nwr\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\Release\GenericRestConnector.exe 16 | Z:\Users\nwr\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\Release\GenericRestConnector.pdb 17 | \\psf\Home\Documents\GenericRestConnector\GenericRestConnector.exe.config 18 | \\psf\Home\Documents\GenericRestConnector\GenericRestConnector.exe 19 | \\psf\Home\Documents\GenericRestConnector\GenericRestConnector.pdb 20 | -------------------------------------------------------------------------------- /GenericRestConnector/obj/Release/GenericRestConnector.csproj.GenerateResource.Cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Release/GenericRestConnector.csproj.GenerateResource.Cache -------------------------------------------------------------------------------- /GenericRestConnector/obj/Release/GenericRestConnector.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Release/GenericRestConnector.exe -------------------------------------------------------------------------------- /GenericRestConnector/obj/Release/GenericRestConnector.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Release/GenericRestConnector.pdb -------------------------------------------------------------------------------- /GenericRestConnector/obj/Release/TempPE/Properties.Resources.Designer.cs.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Release/TempPE/Properties.Resources.Designer.cs.dll -------------------------------------------------------------------------------- /GenericRestConnector/obj/Release/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Release/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs -------------------------------------------------------------------------------- /GenericRestConnector/obj/Release/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Release/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs -------------------------------------------------------------------------------- /GenericRestConnector/obj/Release/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/Release/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Debug/DesignTimeResolveAssemblyReferences.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Debug/DesignTimeResolveAssemblyReferences.cache -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Debug/GenericRestConnector.Properties.Resources.resources: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Debug/GenericRestConnector.Properties.Resources.resources -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Debug/GenericRestConnector.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\x64\Debug\GenericRestConnector.exe.config 2 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\x64\Debug\GenericRestConnector.exe 3 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\x64\Debug\GenericRestConnector.pdb 4 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\x64\Debug\Newtonsoft.Json.dll 5 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\x64\Debug\QvxLibrary.dll 6 | C:\GenericRestConnector\GenericRestConnector.exe.config 7 | C:\GenericRestConnector\GenericRestConnector.exe 8 | C:\GenericRestConnector\GenericRestConnector.pdb 9 | C:\Program Files\Common Files\Qlik\Custom Data\GenericRestConnector\GenericRestConnector.exe.config 10 | C:\Program Files\Common Files\Qlik\Custom Data\GenericRestConnector\GenericRestConnector.exe 11 | C:\Program Files\Common Files\Qlik\Custom Data\GenericRestConnector\GenericRestConnector.pdb 12 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\x64\Debug\GenericRestConnector.Properties.Resources.resources 13 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\x64\Debug\GenericRestConnector.csproj.GenerateResource.Cache 14 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\x64\Debug\GenericRestConnector.exe 15 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\x64\Debug\GenericRestConnector.pdb 16 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\x64\Debug\GenericRestConnector.csprojResolveAssemblyReference.cache 17 | \\Mac\Home\Documents\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\x64\Debug\GenericRestConnector.csprojResolveAssemblyReference.cache 18 | \\Mac\Home\Documents\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\x64\Debug\GenericRestConnector.Properties.Resources.resources 19 | \\Mac\Home\Documents\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\x64\Debug\GenericRestConnector.csproj.GenerateResource.Cache 20 | \\Mac\Home\Documents\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\x64\Debug\GenericRestConnector.exe 21 | \\Mac\Home\Documents\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\x64\Debug\GenericRestConnector.pdb 22 | -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Debug/GenericRestConnector.csproj.GenerateResource.Cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Debug/GenericRestConnector.csproj.GenerateResource.Cache -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Debug/GenericRestConnector.csprojResolveAssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Debug/GenericRestConnector.csprojResolveAssemblyReference.cache -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Debug/GenericRestConnector.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Debug/GenericRestConnector.exe -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Debug/GenericRestConnector.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Debug/GenericRestConnector.pdb -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Debug/TempPE/Properties.Resources.Designer.cs.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Debug/TempPE/Properties.Resources.Designer.cs.dll -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Release/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Release/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Release/GenericRestConnector.Properties.Resources.resources: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Release/GenericRestConnector.Properties.Resources.resources -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Release/GenericRestConnector.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\x64\Release\GenericRestConnector.exe.config 2 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\x64\Release\GenericRestConnector.exe 3 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\x64\Release\GenericRestConnector.pdb 4 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\x64\Release\Newtonsoft.Json.dll 5 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\x64\Release\QvxLibrary.dll 6 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\x64\Release\GenericRestConnector.Properties.Resources.resources 7 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\x64\Release\GenericRestConnector.csproj.GenerateResource.Cache 8 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\x64\Release\GenericRestConnector.exe 9 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\x64\Release\GenericRestConnector.pdb 10 | \\psf\Home\Documents\GenericRestConnector\GenericRestConnector.exe.config 11 | \\psf\Home\Documents\GenericRestConnector\GenericRestConnector.exe 12 | \\psf\Home\Documents\GenericRestConnector\GenericRestConnector.pdb 13 | C:\GenericRestConnector\GenericRestConnector.exe.config 14 | C:\GenericRestConnector\GenericRestConnector.exe 15 | C:\GenericRestConnector\GenericRestConnector.pdb 16 | Y:\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\x64\Release\GenericRestConnector.exe.config 17 | Y:\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\x64\Release\GenericRestConnector.exe 18 | Y:\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\x64\Release\GenericRestConnector.pdb 19 | \\psf\Home\2015\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\x64\Release\GenericRestConnector.csprojResolveAssemblyReference.cache 20 | \\Mac\Home\Documents\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\x64\Release\GenericRestConnector.exe 21 | \\Mac\Home\Documents\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\x64\Release\GenericRestConnector.pdb 22 | \\Mac\Home\Documents\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\x64\Release\GenericRestConnector.csprojResolveAssemblyReference.cache 23 | \\Mac\Home\Documents\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\x64\Release\GenericRestConnector.Properties.Resources.resources 24 | \\Mac\Home\Documents\Development\Connectors\generic-rest-connector\GenericRestConnector\obj\x64\Release\GenericRestConnector.csproj.GenerateResource.Cache 25 | \\Mac\Home\Documents\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\x64\Release\GenericRestConnector.exe.config 26 | \\Mac\Home\Documents\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\x64\Release\GenericRestConnector.exe 27 | \\Mac\Home\Documents\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\x64\Release\GenericRestConnector.pdb 28 | \\Mac\Home\Documents\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\x64\Release\Newtonsoft.Json.dll 29 | \\Mac\Home\Documents\Development\Connectors\generic-rest-connector\GenericRestConnector\bin\x64\Release\QvxLibrary.dll 30 | -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Release/GenericRestConnector.csproj.GenerateResource.Cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Release/GenericRestConnector.csproj.GenerateResource.Cache -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Release/GenericRestConnector.csprojResolveAssemblyReference.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Release/GenericRestConnector.csprojResolveAssemblyReference.cache -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Release/GenericRestConnector.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Release/GenericRestConnector.exe -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Release/GenericRestConnector.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Release/GenericRestConnector.pdb -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Release/TempPE/Properties.Resources.Designer.cs.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Release/TempPE/Properties.Resources.Designer.cs.dll -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Release/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Release/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Release/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Release/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs -------------------------------------------------------------------------------- /GenericRestConnector/obj/x64/Release/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/obj/x64/Release/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs -------------------------------------------------------------------------------- /GenericRestConnector/verpatch.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/verpatch.exe -------------------------------------------------------------------------------- /GenericRestConnector/web/apiKey.ng.html: -------------------------------------------------------------------------------- 1 | 
2 |

Provide a valid API Key for the connection

3 | 4 | 5 |
6 | -------------------------------------------------------------------------------- /GenericRestConnector/web/basicAuth.ng.html: -------------------------------------------------------------------------------- 1 | 
2 |

Provide a Username and Password for the connection

3 | 4 | 5 | 6 | 7 |
8 | 9 | -------------------------------------------------------------------------------- /GenericRestConnector/web/connectdialog.css: -------------------------------------------------------------------------------- 1 | .qrest-connect-dialog-container { 2 | 3 | } 4 | 5 | .qrest-connect-dialog { 6 | width: 70%; 7 | margin: 50px auto; 8 | height: calc(100vh - 100px); 9 | background-color: white; 10 | position: relative; 11 | padding-left: 10px; 12 | padding-right: 10px; 13 | } 14 | 15 | .qrest-authorize{ 16 | text-decoration: none; 17 | } 18 | 19 | .qrest-footer{ 20 | position: absolute; 21 | bottom: 0px; 22 | right: 0px; 23 | } 24 | 25 | .qrest-loader{ 26 | position: absolute; 27 | height: 100px; 28 | width: 100px; 29 | top: calc(50% - 50px); 30 | left: calc(50% - 50px); 31 | } 32 | 33 | .connection-settings input{ 34 | display: block; 35 | width: 96%; 36 | height: 25px; 37 | padding: 6px 12px; 38 | font-size: 14px; 39 | line-height: 1.42857143; 40 | color: #555; 41 | background-color: #fff; 42 | background-image: none; 43 | border: 1px solid #ccc; 44 | border-radius: 4px; 45 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075); 46 | box-shadow: inset 0 1px 1px rgba(0,0,0,.075); 47 | -webkit-transition: border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s; 48 | -o-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s; 49 | transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s; 50 | } 51 | 52 | .select-config-dialog{ 53 | height: calc(100% - 50px); 54 | } 55 | 56 | .select-config-dialog, .connection-settings{ 57 | padding: 5px; 58 | } 59 | 60 | .select-config-source{ 61 | height: 80px; 62 | margin-left: -10px; 63 | margin-right: -10px; 64 | } 65 | 66 | .select-config-source li{ 67 | list-style-type: none; 68 | display: inline-block; 69 | width: 12% !important; 70 | cursor: pointer; 71 | margin-left: 10px; 72 | margin-right: 10px; 73 | line-height: 60px !important; 74 | } 75 | 76 | .select-config{ 77 | overflow-x: hidden; 78 | overflow-y: auto; 79 | padding: 10px 2px; 80 | height: calc(100% - 135px); 81 | } 82 | 83 | .primary-button{ 84 | cursor: pointer; 85 | } 86 | 87 | .select-config ul{ 88 | list-style-type: none; 89 | margin-left: -10px; 90 | margin-right: -10px; 91 | } 92 | 93 | .select-config li{ 94 | display: inline-block; 95 | width: 23%; 96 | margin-left: 10px; 97 | margin-right: 10px; 98 | cursor: pointer; 99 | } 100 | 101 | .subpage{ 102 | margin-top: 20px; 103 | } 104 | 105 | 106 | .loading-container .message{ 107 | position: absolute; 108 | height: 100px; 109 | width: 40%; 110 | top: calc(50% + 100px); 111 | left: calc(30%); 112 | text-align: center; 113 | } -------------------------------------------------------------------------------- /GenericRestConnector/web/connectdialog.js: -------------------------------------------------------------------------------- 1 | define(['qvangular', 'text!./connectdialog.ng.html', 'css!./connectdialog.css', 'css!./dictionary-factory.css'], function (qvangular, template) { 2 | return { 3 | template: template, 4 | controller: ['$scope', 'input', function ($scope, input) { 5 | function init() { 6 | $scope.isEdit = input.editMode; 7 | $scope.isLoading = true; 8 | $scope.auth_method; 9 | $scope.subpageLoading = false; 10 | $scope.id = input.instanceId; 11 | $scope.connectionParameters = {}; 12 | $scope.localDictionaryList = []; 13 | $scope.onlineDictionaryList = []; 14 | $scope.source = "online"; 15 | $scope.dictionaryIndex; 16 | $scope.step = "config-selection"; 17 | $scope.connectionTemplates = { 18 | None: "/customdata/64/GenericRestConnector/web/noAuth.ng.html", 19 | Basic: "/customdata/64/GenericRestConnector/web/basicAuth.ng.html", 20 | "OAuth": "/customdata/64/GenericRestConnector/web/oAuth.ng.html", 21 | Certificate: "", 22 | "API Key": "/customdata/64/GenericRestConnector/web/apiKey.ng.html" 23 | }; 24 | $scope.name; 25 | $scope.username; 26 | $scope.loadingMessage = "Fetching Online and Local dictionaries. Please bare with us."; 27 | $scope.password; 28 | $scope.token; 29 | $scope.consumer_secret; 30 | $scope.key; 31 | $scope.secret; 32 | $scope.tokenRequested = false; 33 | $scope.url; 34 | $scope.dicurl=""; 35 | $scope.config; 36 | $scope.provider = "GenericRestConnector.exe"; 37 | $scope.idForAuthorization = ""; 38 | $scope.subpage = $scope.connectionTemplates["None"]; 39 | 40 | //if the connection is being modified 41 | if (input.editMode) { 42 | input.serverside.getConnection(input.instanceId).then(function (result) { 43 | console.log(result); 44 | var tempArray = result.qConnection.qConnectionString.substring(19, result.qConnection.qConnectionString.length - 1).split(';'); 45 | for (var i = 0; i < tempArray.length; i++) { 46 | var param = tempArray[i].split('='); 47 | $scope.connectionParameters[param[0]] = param[1]; 48 | } 49 | $scope.config = $scope.connectionParameters["config"]; 50 | $scope.name = result.qConnection.qName; 51 | $scope.url = $scope.connectionParameters["url"]; 52 | $scope.dicurl = $scope.connectionParameters["dictionaryurl"]; 53 | $scope.dictionaryId = $scope.connectionParameters["dictionary"];; 54 | $scope.source = $scope.connectionParameters["source"]; 55 | $scope.username = $scope.connectionParameters["username"]; 56 | $scope.isLoading = false; 57 | $scope.subpageLoading = true; 58 | $scope.loadTemplate('connection-settings', $scope.dictionaryId, $scope.dicurl); 59 | }); 60 | } 61 | else { 62 | //get online dictionaries 63 | input.serverside.sendJsonRequest("getOnlineDictionaries").then(function (response) { 64 | $scope.onlineDictionaryList = JSON.parse(response.qMessage).configs; 65 | if ($scope.onlineDictionaryList && $scope.localDictionaryList) { 66 | $scope.isLoading = false; 67 | } 68 | }); 69 | //get local dictionaries 70 | input.serverside.sendJsonRequest("getLocalDictionaries").then(function (response) { 71 | var catalog = JSON.parse(response.qMessage); 72 | $scope.processCatalog(catalog); 73 | if ($scope.onlineDictionaryList && $scope.localDictionaryList) { 74 | $scope.isLoading = false; 75 | } 76 | }); 77 | } 78 | } 79 | 80 | //build the connection string 81 | function buildConnectionString() { 82 | var conn = "CUSTOM CONNECT TO \"provider=GenericRestConnector.exe;dictionary=" + $scope.dictionaryId + ";source=" + $scope.source + ";auth-method="+$scope.auth_method+";"; 83 | $('[data-parameter]').each(function (index, item) { 84 | if ($(item).attr("data-parameter") == "password") { 85 | $scope.password = $(item).val(); 86 | } 87 | else { 88 | conn += $(item).attr("data-parameter") + "=" + $(item).val() + ";"; 89 | } 90 | }); 91 | 92 | if ($scope.dicurl) { 93 | conn += "dictionaryurl=" + $scope.dicurl + ";"; 94 | } 95 | conn += "\""; 96 | console.log(conn); 97 | return conn; 98 | } 99 | 100 | //save the connection 101 | $scope.onOKClicked = function () { 102 | if ($scope.isEdit) { 103 | input.serverside.modifyConnection($scope.instanceId, $scope.name, buildConnectionString(), $scope.provider, true, $scope.username, $scope.password); 104 | $scope.destroyComponent(); 105 | } 106 | else { 107 | input.serverside.createNewConnection($scope.name, buildConnectionString(), $scope.username, $scope.password); 108 | $scope.destroyComponent(); 109 | } 110 | }; 111 | 112 | //close the dialog 113 | $scope.onCancelClicked = function () { 114 | if (!$scope.isLoading) { 115 | $scope.destroyComponent(); 116 | } 117 | }; 118 | 119 | $scope.backToCatalog = function () { 120 | $scope.step = "config-selection"; 121 | $scope.subpage = null; 122 | }; 123 | 124 | //display the appropriate step 125 | $scope.nextStep = function (step) { 126 | $scope.step = step; 127 | }; 128 | 129 | $scope.setSource = function (source) { 130 | $scope.source = source; 131 | }; 132 | 133 | $scope.updateCatalog = function () { 134 | input.serverside.sendJsonRequest("updateLocalCatalog").then(function (response) { 135 | var catalog = JSON.parse(response.qMessage); 136 | $scope.processCatalog(catalog); 137 | if ($scope.onlineDictionaryList && $scope.localDictionaryList) { 138 | $scope.isLoading = false; 139 | } 140 | }); 141 | }; 142 | 143 | //load and display the required template based on the config auth setting 144 | $scope.loadTemplate = function (step, index, dicurl) { 145 | $scope.subpageLoading = true; 146 | this.nextStep(step); 147 | if (!$scope.isEdit) { 148 | if ($scope.source == "online") { 149 | $scope.selectedDictionaryInfo = $scope.onlineDictionaryList[index]; 150 | $scope.dictionaryId = $scope.onlineDictionaryList[index]._id; 151 | $scope.idForAuthorization = $scope.onlineDictionaryList[index]._id; 152 | } 153 | else { 154 | $scope.selectedDictionaryInfo = $scope.localDictionaryList[index]; 155 | $scope.dictionaryId = $scope.localDictionaryList[index].folder; 156 | } 157 | 158 | } 159 | $scope.dicurl = dicurl; 160 | $scope.loadingMessage = "Downloading Dictionary Definition..."; 161 | input.serverside.sendJsonRequest("getDictionaryDef", $scope.dictionaryId, $scope.source).then(function (response) { 162 | $scope.dictionaryDef = JSON.parse(response.qMessage); 163 | $scope.auth_method = $scope.dictionaryDef.auth_method; 164 | $scope.subpage = $scope.connectionTemplates[$scope.dictionaryDef.auth_method]; 165 | $scope.subpageLoading = false; 166 | if ($scope.source == "local") { 167 | $scope.idForAuthorization = $scope.dictionaryDef.id; 168 | } 169 | }); 170 | } 171 | 172 | $scope.processCatalog = function (catalog) { 173 | $scope.localDictionaryList = []; 174 | if (catalog.configs) { 175 | for (var d in catalog.configs) { 176 | $scope.localDictionaryList.push(JSON.parse(catalog.configs[d])); 177 | } 178 | } 179 | } 180 | 181 | init(); 182 | }] 183 | }; 184 | }); -------------------------------------------------------------------------------- /GenericRestConnector/web/connectdialog.ng.html: -------------------------------------------------------------------------------- 1 | 
2 |
3 |
4 |
5 |
{{loadingMessage}}
6 |
7 |
8 |
9 |

Choose a REST Configuration

10 |
    11 | 12 | 13 |
14 |
15 |
16 | 17 |
18 |
19 |
20 |
    21 |
  • 22 |
    23 | {{dic.display_name}} 24 |
    {{dic.owner}}
    25 |
    26 | 27 |
    28 |
    29 |
  • 30 |
31 |
32 |
33 | 34 |
35 |
    36 |
  • 37 |
    38 | {{dic.displayName}} 39 |
    40 | 41 |
    42 |
    43 |
  • 44 |
45 |
46 |
47 |
48 |

Provide a name and the Url for the connection

49 | 50 |
51 | 52 |
53 |
54 |
55 |
{{loadingMessage}}
56 |
57 |
58 | 59 |
60 |
61 |
62 |
63 |
64 | 65 | 66 | Save 67 | 68 |
69 |
70 |
71 | -------------------------------------------------------------------------------- /GenericRestConnector/web/connector-main.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 3 | ], 4 | function () { 5 | 6 | }); -------------------------------------------------------------------------------- /GenericRestConnector/web/dictionary-factory.css: -------------------------------------------------------------------------------- 1 | .white{color:white !important}@font-face{font-family:factory;src:url(/resources/factory.ttf)}@font-face{font-family:factory;src:url(factory.ttf)}@font-face{font-family:Stellar;font-weight:lighter;src:url(/resources/Stellar-light.otf)}@font-face{font-family:Stellar;font-weight:normal;src:url(/resources/Stellar-regular.otf)}@font-face{font-family:Aileron;src:url(/resources/Ailerons-Typeface.otf)}.body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:Stellar,"QlikView Sans",sans-serif;font-size:16px;color:#464646;background-color:white;background-image:url(/resources/background.jpg);background-position:bottom;background-attachment:fixed;background-size:40%;background-repeat:repeat-x}.body label{font-weight:normal;margin:3px 0}.body .page{margin-top:80px}.body .content{padding:10px 0}.body .float-right{float:right}.body .float-left{float:left}.body .align-right{text-align:right}.body .primary-button,.body .secondary-button{display:block;width:200px;padding:5px;height:35px;line-height:26px;text-align:center;border-radius:3px;font-weight:normal;border:none;box-sizing:border-box}.body .primary-button{background-color:#CEBDA4;color:white;margin-bottom:3px}.body .secondary-button{background-color:#AEB9C7;color:white;margin-bottom:3px}.body .download-button,.body .delete-button,.body .back-button{display:block;cursor:pointer;background-color:transparent;border:none;height:30px;width:30px;line-height:30px;color:#CCCCCC}.body .download-button:after,.body .delete-button:after,.body .back-button:after{position:absolute;top:0;left:0;font-family:factory;font-size:30px}.body .download-button:after{content:"\E803"}.body .download-button:hover{color:#a3ba49}.body .delete-button:after{content:"\E802"}.body .delete-button:hover{color:#aa3840}.body .back-button{position:relative;color:#CEBDA4;width:auto !important;padding-left:45px;font-size:20px}.body .back-button:after{font-family:factory;content:"\E800"}.body .title{font-size:20px;font-weight:normal;color:#CEBDA4}.body .check-label{height:30px;line-height:30px;display:inline-block;margin:0;padding:0;vertical-align:top}.body input[type=checkbox]{display:inline-block;width:30px;margin:0;height:30px;line-height:30px}.body h1,.body h2,.body h3,.body h4{margin-top:5px;margin-bottom:5px}.body h1{font-size:24px;color:#CEBDA4}.body h2{font-size:20px;color:#464646}.body h3{font-size:18px;color:#908F96}.body h4{font-size:16px;color:#464646;font-weight:bold}.body ul{list-style-type:none}.body .plainlist{margin:0;padding:0}.body .description{padding:10px 0}.body .card{background-color:#F8F9FB;padding:5px 10px;border-radius:3px;box-shadow:0 0 5px #ccc}.body .card.active{box-shadow:0 0 5px #908F96}.body .dictionary{height:220px;position:relative;margin-bottom:15px}.body .dictionary .icon{text-align:center;height:150px;width:100%}.body .dictionary .icon img{margin-top:20px;max-height:100px}.body .dictionary .title{text-align:center;display:block;height:20px;color:#464646}.body .dictionary .sub-title{text-align:center;font-size:14px;font-weight:normal;color:#908F96}.body .dictionary .delete-button{position:absolute;bottom:10px;right:5px}.body .dictionary .download-button{padding-left:45px;position:absolute;bottom:10px;left:10px}.body .dictionary-link{display:block}.body .dictionary-link:hover,.body .dictionary-link:visited{text-decoration:none}.body .hint{color:#908F96;font-size:12px;margin:2px 0}.body .hint strong{color:#464646}.body .inline{display:inline-block;margin-right:5px}.body .spacer{border:1px solid #CCCCCC;margin:5px 0}.body .horizontal-spacer{width:10px;height:1px}.body .vertical-spacer{height:10px}.body .smokescreen{z-index:1000;background-color:rgba(200,200,200,0.8);position:absolute;top:0;left:0;height:100%;width:100%}.body .center{text-align:center}.body .show{display:block}.body .hide{display:none}.body .token-card{margin:0 auto;margin-top:50px;width:auto;padding:20px;text-align:center}.body .token-card.token{font-size:30px}.body .inline{display:inline-block}.body .status{line-height:34px}.body .navbar{min-height:70px;background-color:#908F96;color:#FFFFFF}.body .navbar a{color:#FFFFFF;font-size:16px}.body .navbar a:hover{color:#908F96}.body .navbar .navbar-brand{font-family:Aileron;font-weight:lighter;font-size:24px;letter-spacing:2px;height:70px;line-height:40px}.body .navbar .navbar-brand:hover{color:white}.body .navbar .navbar-nav li a{line-height:40px}.body .navbar .dropdown.open a{color:#908F96}.body .intro{margin-top:70px}.body .intro .title{font-size:36px}.body .intro .intro-option{text-align:center;margin:50px 0;color:#464646;font-size:30px}.body .intro .intro-option a,.body .intro .intro-option a:hover,.body .intro .intro-option a:visited{color:#464646;text-decoration:none}.body .intro .intro-option:hover{-ms-transform:scale(1.2);-webkit-transform:scale(1.2);transform:scale(1.2)}.body .login-container{width:400px;margin:0 auto;padding-top:30px}.body .login-container .login-logo{height:200px;background:url(/resources/Octocat.png) center center no-repeat;background-size:contain;margin-bottom:20px}.body .login-container .login-button{margin:0 100px}.body .dictionary-nav .nav-button{height:60px;display:inline-block;line-height:50px;width:100%;font-size:16px;text-align:center;color:#CEBDA4}.body .dictionary-nav .nav-button a{color:#CEBDA4}.body .dictionary-nav .nav-button.active{background-color:#908F96;color:white}.body .dictionary-nav .nav-button.active:hover{-ms-transform:scale(1);-webkit-transform:scale(1);transform:scale(1)}.body .dictionary-nav .nav-button:hover{-ms-transform:scale(1.1);-webkit-transform:scale(1.1);transform:scale(1.1)}.body .general .icon img{max-height:100px}.body .wizard .path{font-size:14px;font-weight:normal;color:#CEBDA4}.body .wizard .auth-version span,.body .wizard .auth-version input{line-height:30px;height:30px;padding:0;margin:0;width:auto;min-width:30px;vertical-align:top;box-shadow:none}.body .wizard .auth-version input{margin-right:50px}.body .wizard .auth-method,.body .wizard .paging-method{height:110px;cursor:pointer;background-color:white}.body .wizard .auth-method .auth-type,.body .wizard .paging-method .auth-type,.body .wizard .auth-method .paging-type,.body .wizard .paging-method .paging-type{text-align:center}.body .wizard .auth-method .auth-desc,.body .wizard .paging-method .auth-desc,.body .wizard .auth-method .paging-desc,.body .wizard .paging-method .paging-desc{font-size:12px}.body .wizard .auth-method.active,.body .wizard .paging-method.active{border:2px solid #CEBDA4;box-shadow:0 0 5px #CEBDA4}.body .wizard .save-successful{color:#a3ba49}.body .wizard .table-card,.body .wizard .field-card{background-color:white;position:relative;margin-bottom:5px}.body .wizard .table-card h3,.body .wizard .field-card h3{margin-top:5px;margin-bottom:0}.body .wizard .table-card .delete-button,.body .wizard .field-card .delete-button{position:absolute;top:calc(50% - 15px);height:20px;right:5px}.body .wizard .field-card{position:relative}.body .wizard .field-card input{border:none;width:50%}.body .wizard .field-card select{position:absolute;right:50px;top:calc(50% - 15px);height:30px;border:none;box-shadow:none;width:100px;color:#CCCCCC;font-size:14px}.body .wizard .btn-file{display:inline-block !important;position:relative;overflow:hidden}.body .wizard .btn-file input[type=file]{position:absolute;top:0;right:0;min-width:100%;min-height:100%;font-size:100px;text-align:right;filter:alpha(opacity=0);opacity:0;outline:none;background:white;cursor:inherit;display:block}.body .autodetect-auth{width:500px;margin:80px auto;padding-bottom:20px}.body .summary label{display:block;font-size:14px;font-weight:bold;color:#908F96}.body .error-banner{margin:10px 0}.body .error-banner p{margin:2px 0}.body .error-banner ul{padding:20px;list-style-type:circle}.body .error-banner.card{box-shadow:0 0 5px #aa3840} -------------------------------------------------------------------------------- /GenericRestConnector/web/factory.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/GenericRestConnector/web/factory.ttf -------------------------------------------------------------------------------- /GenericRestConnector/web/noAuth.ng.html: -------------------------------------------------------------------------------- 1 | 
2 |
3 |
4 |
5 |
6 |
7 |
No Authentication Required
8 |
9 | -------------------------------------------------------------------------------- /GenericRestConnector/web/oAuth.ng.html: -------------------------------------------------------------------------------- 1 | 
2 |
3 |
4 | Authorize 5 |

Then enter your Refresh or Access Token

6 | 7 |
8 |
9 |
10 |

Enter your Consumer Key and Secret for the connection and Authorize

11 | 12 | 13 |

If you already have your token and token secret you don't need to authorize, simply enter them below

14 | Authorize 15 |

Then enter your Token and Token Secret

16 | 17 | 18 |
19 |
20 |

Enter your Client Id and Secret for the connection and Authorize

21 | 22 | 23 |

If you already have your access token or refresh you don't need to authorize, simply enter it below

24 | Authorize 25 |

Then enter your Refresh or Access Token

26 | 27 |

If a Refresh Token was provided please use that instead of the Access Token.

28 |
29 |
30 |
-------------------------------------------------------------------------------- /GenericRestConnector/web/selectdialog.js: -------------------------------------------------------------------------------- 1 | define(['qvangular' 2 | ], function (qvangular) { 3 | return ['serverside', 'standardSelectDialogService', '$element', 'connectionId', function (serverside, standardSelectDialogService, element, connectionId) { 4 | var dictionary; 5 | var contentProvider = { 6 | getConnectionInfo: function () { 7 | return { 8 | dbusage: false, 9 | ownerusage: false, 10 | dbfirst: false, 11 | specialchars: '', 12 | dbseparator: '', 13 | defaultdatabase: '', 14 | ownerseparator: '', 15 | quotesuffix: '', 16 | quoteprefix: '', 17 | dbmsname: '', 18 | keywords: '' 19 | }; 20 | }, 21 | getDatabases: function () { 22 | return serverside.sendJsonRequest("getDatabases").then(function (response) { 23 | var data = JSON.parse(response.qMessage); 24 | dictionary = data.dictionary; 25 | return data.qDatabases; 26 | }); 27 | //return { qDatabases: [{qName:"Not Applicable"}] }; 28 | }, 29 | getOwners: function ( /*databaseName*/) { 30 | return qvangular.promise([{ name: "" }]); 31 | }, 32 | getTables: function (databaseName, ownerName) { 33 | return serverside.sendJsonRequest("getTables", dictionary).then(function (response) { 34 | return JSON.parse(response.qMessage); 35 | }); 36 | }, 37 | getFields: function (databaseName, ownerName, tableName) { 38 | return serverside.sendJsonRequest("getFields", tableName, dictionary).then(function (response) { 39 | return JSON.parse(response.qMessage); 40 | }); 41 | }, 42 | getPreview: function (databaseName, ownerName, tableName) { //need to add code for preview 43 | return serverside.sendJsonRequest("getPreview", tableName, dictionary).then(function (response) { 44 | return JSON.parse(response.qMessage); 45 | }); 46 | 47 | 48 | } 49 | }; 50 | 51 | standardSelectDialogService.showStandardDialog(contentProvider); 52 | }]; 53 | }); -------------------------------------------------------------------------------- /Local.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/Local.png -------------------------------------------------------------------------------- /Public.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/Public.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Generic REST Connector for Qlik Sense 2 | **Note:** This connector is currently in an experimental state. Please feel free to use and abuse it but remember it may not work with certain REST APIs depending on their configuration. I also can't guarantee the quality of the published dictionaries. 3 | 4 | ### Summary 5 | This connector works by interpreting a definition stored within a "dictionary" in order to retrieve data from the desired REST API. The dictionary contains information about where the REST API lives, the *Authentication* method it uses, how it *Pages* data and what the *Schema* of the different endpoints looks like. 6 | 7 | You can build, publish and download dictionaries using the online [Dictionary Factory](https://rest-dictionary-factory.herokuapp.com). 8 | A catalog of online dictionaries is available directly inside the Connector as well as any downloaded dictionaries. 9 | 10 | Both the **Connector** and **Dictionary Factory** are Open Source so feel free to contribute and add new Authentication or Paging capabilites. 11 | 12 | ### Installation 13 | 1. Download the zipped Connector **[here](https://github.com/websy85/generic-rest-connector/raw/master/Build/GenericRestConnector.zip)**. 14 | 2. Extract the contents of the zip file to **C:\Program Files\Common Files\Qlik\Custom Data**. 15 | 3. Restart the Qlik Sense Engine Service (Server) or restart Qlik Sense Desktop. 16 | 4. In the **Load Editor** you should now see a new **Generic REST Connector** option under the **Create New Connection** menu. 17 | 18 | 19 | ### Online Dictionaries 20 | The online dictionary list is comprised of dictionaries built and published via the [Dictionary Factory](https://rest-dictionary-factory.herokuapp.com). 21 | 22 | ##### Dictionary Factory 23 | ![alt text][factory] 24 | 25 | ##### Connector Online Catalog 26 | ![alt text][public] 27 | 28 | ### Local Dictionaries 29 | All published dictionaries and your own private (unpublished) dictionaries can be downloaded and stored locally to the connector. Local dictionaries should be put into **C:\Program Files\Common Files\Qlik\Custom Data\GenericRESTConnector\configs**. To expose them to the connector - 30 | 31 | 1. Open the **Load Editor**. 32 | 2. Create a new connection, selecting **Generic REST Connector**. 33 | 3. Click on the **Local** tab. 34 | 4. Click **Update Local Catalog**. 35 | 36 | ##### Connector Local Catalog 37 | ![alt text][local] 38 | 39 | ### WHERE Clauses 40 | Currently any where clause added in the Load Script will be appended to the url for the call to the REST API. So for example, if you're connecting to Twitter and using the **search/tweets.json** endpoint, you can add a where clause of 41 | 42 | `?q=qlikbranch` 43 | 44 | ### Additional Info 45 | ##### Authentication 46 | Currently the Connector and [Dictionary Factory](https://rest-dictionary-factory.herokuapp.com) facilitates the following authentication methods 47 | * Basic (Username/Password) 48 | * API Key (Usually a parameter passed in via the url) 49 | * OAuth 1.0a 50 | * OAuth 2.0 51 | 52 | **Note:** Both the Connector and [Dictionary Factory](https://rest-dictionary-factory.herokuapp.com) provide a workflow for getting an Access Token. If you would like to leverage this you can use `https://rest-dictionary-factory.herokuapp.com/auth/oauth` as your OAuth application redirect uri. 53 | 54 | ##### Paging 55 | Currently the Connector and [Dictionary Factory](https://rest-dictionary-factory.herokuapp.com) facilitates the following paging methods 56 | * Page Number 57 | * Offset / Limit 58 | * Url 59 | 60 | Enjoy! 61 | 62 | [factory]: Factory.png "Dictionary Factory Catalog" 63 | [public]: Public.png "Connector Public Catalog" 64 | [local]: Local.png "Connector Local Catalog" 65 | -------------------------------------------------------------------------------- /Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/websy85/generic-rest-connector/cf769699426873ef346f17a45f983e8b05f0811e/Thumbs.db --------------------------------------------------------------------------------