fiveapples 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/config5.ru +8 -5
- data/lib/fa_utils.rb +18 -0
- data/lib/fiveapples.db3 +0 -0
- data/lib/fiveapples.rb +53 -19
- data/lib/model.rb +17 -2
- data/lib/options.rb +5 -2
- data/lib/ui5/Component.js.erb +4 -3
- data/lib/ui5/controller/Base64.js +87 -0
- data/lib/ui5/controller/Breeder.js +74 -0
- data/lib/ui5/controller/BreederList.controller.js +5 -5
- data/lib/ui5/controller/Breeder_Create.controller.js +20 -49
- data/lib/ui5/controller/Breeder_Detail.controller.js +62 -91
- data/lib/ui5/controller/Create.js +41 -0
- data/lib/ui5/controller/CultivarList.controller.js +5 -4
- data/lib/ui5/controller/Cultivar_Create.controller.js +25 -80
- data/lib/ui5/controller/Cultivar_Detail.controller.js +126 -159
- data/lib/ui5/controller/Detail.js +96 -0
- data/lib/ui5/controller/FileUpload.js +40 -0
- data/lib/ui5/controller/Parentage_Create.controller.js +0 -3
- data/lib/ui5/controller/Parentage_Detail.controller.js +10 -37
- data/lib/ui5/view/BreederList.view.xml +8 -1
- data/lib/ui5/view/Breeder_Create.view.xml +6 -3
- data/lib/ui5/view/Breeder_Detail.view.xml +46 -9
- data/lib/ui5/view/CultivarList.view.xml +2 -1
- data/lib/ui5/view/Cultivar_Create.view.xml +6 -3
- data/lib/ui5/view/Cultivar_Detail.view.xml +47 -43
- data/lib/version.rb +1 -1
- metadata +13 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 819272c422885597ec73f8dd633cad031e882f03e9c5ee3d009a48792d1ae6eb
|
4
|
+
data.tar.gz: 96e67d9c2cbe9538ca91f30565f8c15553357a7d9c4880c6eccb45454de45917
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf920145c28718564c5c207cb98eb4800d651e691340f1e670b3e8f794ae062c66bba5db6027c28aa09292effbe949b0fcb2db9f0aca1b9b0476b2c4ef13f62d
|
7
|
+
data.tar.gz: b8db84aa3f9f1c83ab63d524be0ee57b10804d39d573a23c59e9efacdfd6e4c6b8444108bb69c056d7399117aa8ea118451331877cb349c1a47175d14f4fa590
|
data/lib/config5.ru
CHANGED
@@ -33,8 +33,8 @@ end
|
|
33
33
|
|
34
34
|
fiveapples = Rack::OData::Builder.new do
|
35
35
|
|
36
|
-
use Rack::ODataCommonLogger
|
37
|
-
|
36
|
+
use Rack::ODataCommonLogger if FiveA.log
|
37
|
+
|
38
38
|
use Rack::Cors do
|
39
39
|
allow do
|
40
40
|
origins 'localhost:9494', '127.0.0.1:9494'
|
@@ -54,9 +54,12 @@ fiveapples = Rack::OData::Builder.new do
|
|
54
54
|
'/ui5' => idxh,
|
55
55
|
'/ui5/' => idxh}
|
56
56
|
redirects["/#{ui5d}"] = idxh if FiveA.one_way
|
57
|
-
redirects["/#{ui5d}/"] = idxh if FiveA.one_way
|
58
|
-
|
59
|
-
|
57
|
+
redirects["/#{ui5d}/"] = idxh if FiveA.one_way
|
58
|
+
if FiveA.one_way
|
59
|
+
redirects["/ui5/index.html"] = idxh
|
60
|
+
else
|
61
|
+
redirects["/ui5_1way/index.html"] = idxh
|
62
|
+
end
|
60
63
|
# some user friendly redirects
|
61
64
|
# Note: We need this because serving / with /ui5/index.html content does not work
|
62
65
|
# as is produces follow-up javascript resource requests like "/Component.js"
|
data/lib/fa_utils.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'socket'
|
3
|
+
|
4
|
+
# Ruby 2.5 ships String#delete_prefix but lets try to support 2.4
|
5
|
+
class String
|
6
|
+
def del_prefix(prf)
|
7
|
+
if self[0] == prf
|
8
|
+
self[1..-1]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module FiveApples
|
14
|
+
def self.test_host_ip
|
15
|
+
net = Socket.ip_address_list.detect(&:ipv4_private?)
|
16
|
+
net.nil? ? 'localhost' : net.ip_address
|
17
|
+
end
|
18
|
+
end
|
data/lib/fiveapples.db3
CHANGED
Binary file
|
data/lib/fiveapples.rb
CHANGED
@@ -1,28 +1,21 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'rack'
|
4
|
-
|
5
4
|
require 'sequel'
|
6
5
|
require 'fileutils'
|
7
|
-
require 'socket'
|
8
6
|
require 'erb'
|
9
7
|
require_relative 'version'
|
8
|
+
require_relative 'fa_utils'
|
9
|
+
|
10
10
|
require 'safrano.rb'
|
11
11
|
|
12
|
-
# Ruby 2.5 ships String#delete_prefix but lets try to support 2.4
|
13
|
-
class String
|
14
|
-
def del_prefix(prf)
|
15
|
-
if self[0] == prf
|
16
|
-
self[1..-1]
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
12
|
|
21
13
|
module FiveApples
|
22
14
|
class Server
|
23
15
|
CONFIGDIRNAME = 'fiveapples'.freeze
|
24
16
|
DBFILENAME = 'fiveapples.db3'.freeze
|
25
17
|
CONFIGRU = 'config5.ru'.freeze
|
18
|
+
MEDIADIR = 'media'.freeze
|
26
19
|
|
27
20
|
attr_reader :db
|
28
21
|
attr_reader :one_way
|
@@ -31,13 +24,17 @@ module FiveApples
|
|
31
24
|
attr_reader :role
|
32
25
|
attr_reader :host
|
33
26
|
attr_reader :port
|
34
|
-
|
27
|
+
attr_reader :media_root
|
28
|
+
attr_accessor :log
|
29
|
+
|
35
30
|
def initialize(options={})
|
36
31
|
options ||= {}
|
37
32
|
@role = options[:role]
|
33
|
+
# from libdir we readonly. --> can be a system (install) dir
|
38
34
|
@libdir = __dir__.dup
|
39
35
|
|
40
|
-
|
36
|
+
# apphome needs to be user-writeable !
|
37
|
+
@apphome = if ( @role == :test )
|
41
38
|
File.expand_path('testdb', @libdir)
|
42
39
|
else
|
43
40
|
gconfigdir = File.expand_path('.config', Dir.home)
|
@@ -48,18 +45,22 @@ module FiveApples
|
|
48
45
|
|
49
46
|
@systemdbname = File.join(@libdir, DBFILENAME)
|
50
47
|
@homedbname = File.expand_path(DBFILENAME, @apphome)
|
48
|
+
@media_root = File.expand_path(MEDIADIR, @apphome)
|
51
49
|
@configru = File.expand_path(CONFIGRU, @libdir)
|
52
|
-
|
53
50
|
@one_way = options[:one_way]
|
54
51
|
@use_cdn = options[:use_cdn]
|
55
|
-
|
52
|
+
|
53
|
+
# in testmode we dont log per default,
|
54
|
+
# in non testmode we log per default,
|
55
|
+
# but this can be overriden with option
|
56
|
+
@log = ( options[:log] || ( @role != :test ) )
|
57
|
+
|
56
58
|
@resources = @use_cdn ? "https://openui5.hana.ondemand.com/#{OpenUI5::VERSION}/resources/sap-ui-core.js" : '../resources/sap-ui-core.js'
|
57
59
|
|
58
60
|
@ui5d = @one_way ? 'ui5_1way' : 'ui5'
|
59
61
|
@port = 9494
|
60
62
|
@host = if ( ( @role == :test ) && ENV['selenium_remote_url'] )
|
61
|
-
|
62
|
-
net.nil? ? 'localhost' : net.ip_address
|
63
|
+
FiveApples.test_host_ip()
|
63
64
|
else
|
64
65
|
'localhost'
|
65
66
|
end
|
@@ -70,16 +71,46 @@ module FiveApples
|
|
70
71
|
if ( @role == :test )
|
71
72
|
# in test-mode always start with a fresh DB copy
|
72
73
|
FileUtils.cp(@systemdbname, @homedbname)
|
74
|
+
|
75
|
+
# and reset the media directory
|
76
|
+
media_photo_dir = File.absolute_path('Photo', @media_root)
|
77
|
+
FileUtils.remove_entry_secure(media_photo_dir) if File.exists?(media_photo_dir)
|
73
78
|
else
|
74
79
|
FileUtils.cp(@systemdbname, @homedbname) unless File.exist?(@homedbname)
|
75
80
|
end
|
76
81
|
end
|
77
82
|
|
83
|
+
def db_create_photo_table
|
84
|
+
@db.create_table :photo do
|
85
|
+
primary_key :id
|
86
|
+
column :name, :text
|
87
|
+
Integer :cultivar_id
|
88
|
+
column :content_type, :text
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def db_breeder_table_photo_id
|
93
|
+
return if @db.schema(:breeder).find{|col| col[0] == :photo_id }
|
94
|
+
|
95
|
+
@db.alter_table :breeder do
|
96
|
+
add_column :photo_id, Integer
|
97
|
+
add_foreign_key [:photo_id], :photo, key: :id,
|
98
|
+
name: :breeder_photo_id_fkey
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
78
103
|
def startdb
|
79
104
|
setup_db_in_homedir
|
80
105
|
|
81
106
|
@db = Sequel::Model.db = Sequel.sqlite(@homedbname)
|
82
|
-
|
107
|
+
# data model for media entities table and relations
|
108
|
+
unless @db.table_exists? :photo
|
109
|
+
db_create_photo_table
|
110
|
+
end
|
111
|
+
|
112
|
+
db_breeder_table_photo_id
|
113
|
+
|
83
114
|
Kernel.at_exit { Sequel::Model.db.disconnect if Sequel::Model.db }
|
84
115
|
|
85
116
|
end
|
@@ -92,8 +123,11 @@ module FiveApples
|
|
92
123
|
def serve
|
93
124
|
|
94
125
|
puts "Fiveapples version #{FiveApples::VERSION} on #{@host} config #{@configru}"
|
95
|
-
|
96
|
-
#
|
126
|
+
begin
|
127
|
+
# this requires safrano ~> 0.3.5
|
128
|
+
puts "Safrano version #{Safrano::VERSION}"
|
129
|
+
rescue
|
130
|
+
end
|
97
131
|
|
98
132
|
Dir.chdir @libdir do
|
99
133
|
|
data/lib/model.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
|
3
4
|
class Cultivar < Sequel::Model(:cultivar)
|
4
5
|
|
5
6
|
# Navigation attributes
|
6
7
|
one_to_many :parent, :class => :Parentage, :key => :cultivar_id
|
7
8
|
one_to_many :child, :class => :Parentage, :key => :parent_id
|
8
|
-
|
9
|
+
one_to_many :photo, :class => :Photo, :key => :cultivar_id
|
9
10
|
many_to_one :breeder, :key => :breeder_id
|
10
11
|
|
11
12
|
end
|
@@ -15,6 +16,7 @@ end
|
|
15
16
|
|
16
17
|
class Breeder < Sequel::Model(:breeder)
|
17
18
|
one_to_many :cultivar, :key => :breeder_id
|
19
|
+
many_to_one :avatar, :class => :Photo, :key => :photo_id
|
18
20
|
end
|
19
21
|
|
20
22
|
class Parentage < Sequel::Model(:parentage)
|
@@ -27,6 +29,9 @@ class Parentage < Sequel::Model(:parentage)
|
|
27
29
|
|
28
30
|
end
|
29
31
|
|
32
|
+
class Photo < Sequel::Model(:photo)
|
33
|
+
end
|
34
|
+
|
30
35
|
### SERVER Part #############################
|
31
36
|
|
32
37
|
class ODataFiveApples < OData::ServerApp
|
@@ -37,12 +42,21 @@ class ODataFiveApples < OData::ServerApp
|
|
37
42
|
namespace 'ODataFiveApples'
|
38
43
|
path_prefix '/odata'
|
39
44
|
enable_batch
|
45
|
+
publish_media_model Photo do
|
46
|
+
slug :name
|
47
|
+
use OData::Media::Static, :root => FiveA.media_root
|
48
|
+
end
|
49
|
+
|
40
50
|
publish_model Cultivar, :cultivar do
|
41
51
|
add_nav_prop_single :breeder
|
42
52
|
add_nav_prop_collection :parent
|
43
53
|
add_nav_prop_collection :child
|
54
|
+
add_nav_prop_collection :photo
|
55
|
+
end
|
56
|
+
publish_model Breeder, :breeder do
|
57
|
+
add_nav_prop_collection :cultivar
|
58
|
+
add_nav_prop_single :avatar
|
44
59
|
end
|
45
|
-
publish_model Breeder, :breeder do add_nav_prop_collection :cultivar end
|
46
60
|
publish_model ParentageType, :par_type
|
47
61
|
publish_model Parentage, :parentage do
|
48
62
|
add_nav_prop_single :parent
|
@@ -50,5 +64,6 @@ class ODataFiveApples < OData::ServerApp
|
|
50
64
|
add_nav_prop_single :par_type
|
51
65
|
end
|
52
66
|
end
|
67
|
+
|
53
68
|
end
|
54
69
|
|
data/lib/options.rb
CHANGED
@@ -4,7 +4,8 @@ OPTS = GetoptLong.new(
|
|
4
4
|
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
|
5
5
|
[ '--one_way', '-o', GetoptLong::NO_ARGUMENT ],
|
6
6
|
[ '--use_cdn', '-c', GetoptLong::NO_ARGUMENT ],
|
7
|
-
[ '--libdir', '-I', GetoptLong::REQUIRED_ARGUMENT ]
|
7
|
+
[ '--libdir', '-I', GetoptLong::REQUIRED_ARGUMENT ],
|
8
|
+
[ '--test', '-t', GetoptLong::NO_ARGUMENT ]
|
8
9
|
)
|
9
10
|
|
10
11
|
def read_opts
|
@@ -12,7 +13,7 @@ OPTS = GetoptLong.new(
|
|
12
13
|
options[:one_way] = false
|
13
14
|
options[:libdir_add] = nil
|
14
15
|
options[:use_cdn] = false
|
15
|
-
|
16
|
+
|
16
17
|
OPTS.each do |opt, arg|
|
17
18
|
case opt
|
18
19
|
when '--help'
|
@@ -29,6 +30,8 @@ Usage: fiveapples [OPTIONS]
|
|
29
30
|
options[:one_way] = true
|
30
31
|
when '--use_cdn'
|
31
32
|
options[:use_cdn] = true
|
33
|
+
when '--test'
|
34
|
+
options[:role] = :test
|
32
35
|
when '--libdir'
|
33
36
|
options[:libdir_add] = arg
|
34
37
|
if arg
|
data/lib/ui5/Component.js.erb
CHANGED
@@ -2,9 +2,10 @@ sap.ui.define(
|
|
2
2
|
[
|
3
3
|
"sap/ui/core/UIComponent",
|
4
4
|
"sap/ui/model/odata/ODataModel",
|
5
|
-
"sap/ui/model/resource/ResourceModel"
|
5
|
+
"sap/ui/model/resource/ResourceModel",
|
6
|
+
"sap/m/MessageToast"
|
6
7
|
],
|
7
|
-
function(UIComponent, ODataModel, ResourceModel) {
|
8
|
+
function(UIComponent, ODataModel, ResourceModel, MessageToast) {
|
8
9
|
"use strict";
|
9
10
|
return UIComponent.extend("fivea.Component", {
|
10
11
|
metadata: { manifest: "json" },
|
@@ -27,7 +28,7 @@ sap.ui.define(
|
|
27
28
|
mParameters.serviceUrl = "http://<%= @host %>:9494/odata";
|
28
29
|
var oModel = new sap.ui.model.odata.v2.ODataModel(mParameters);
|
29
30
|
oModel.setTokenHandlingEnabled(true);
|
30
|
-
|
31
|
+
|
31
32
|
this.setModel(oModel);
|
32
33
|
|
33
34
|
// set i18n model
|
@@ -0,0 +1,87 @@
|
|
1
|
+
/**
|
2
|
+
*
|
3
|
+
* Base64 encode / decode
|
4
|
+
* http://www.webtoolkit.info/
|
5
|
+
* https://stackoverflow.com/questions/246801/how-can-you-encode-a-string-to-base64-in-javascript
|
6
|
+
**/
|
7
|
+
|
8
|
+
|
9
|
+
/**
|
10
|
+
* https://stackoverflow.com/questions/37376838/how-to-call-utility-functions-in-sapui5-controller
|
11
|
+
*
|
12
|
+
* **/
|
13
|
+
|
14
|
+
sap.ui.define([], function() {
|
15
|
+
|
16
|
+
"use strict";
|
17
|
+
|
18
|
+
var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
19
|
+
|
20
|
+
var _utf8_encode = function (string) {
|
21
|
+
|
22
|
+
var utftext = "", c, n;
|
23
|
+
|
24
|
+
string = string.replace(/\r\n/g,"\n");
|
25
|
+
|
26
|
+
for (n = 0; n < string.length; n++) {
|
27
|
+
|
28
|
+
c = string.charCodeAt(n);
|
29
|
+
|
30
|
+
if (c < 128) {
|
31
|
+
|
32
|
+
utftext += String.fromCharCode(c);
|
33
|
+
|
34
|
+
} else if((c > 127) && (c < 2048)) {
|
35
|
+
|
36
|
+
utftext += String.fromCharCode((c >> 6) | 192);
|
37
|
+
utftext += String.fromCharCode((c & 63) | 128);
|
38
|
+
|
39
|
+
} else {
|
40
|
+
|
41
|
+
utftext += String.fromCharCode((c >> 12) | 224);
|
42
|
+
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
|
43
|
+
utftext += String.fromCharCode((c & 63) | 128);
|
44
|
+
|
45
|
+
}
|
46
|
+
|
47
|
+
}
|
48
|
+
|
49
|
+
return utftext;
|
50
|
+
};
|
51
|
+
|
52
|
+
return {
|
53
|
+
encode: function (input) {
|
54
|
+
var output = "", chr1, chr2, chr3, enc1, enc2, enc3, enc4, i = 0;
|
55
|
+
|
56
|
+
input = _utf8_encode(input);
|
57
|
+
|
58
|
+
while (i < input.length) {
|
59
|
+
|
60
|
+
chr1 = input.charCodeAt(i++);
|
61
|
+
chr2 = input.charCodeAt(i++);
|
62
|
+
chr3 = input.charCodeAt(i++);
|
63
|
+
|
64
|
+
enc1 = chr1 >> 2;
|
65
|
+
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
66
|
+
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
67
|
+
enc4 = chr3 & 63;
|
68
|
+
|
69
|
+
if (isNaN(chr2)) {
|
70
|
+
enc3 = enc4 = 64;
|
71
|
+
} else if (isNaN(chr3)) {
|
72
|
+
enc4 = 64;
|
73
|
+
}
|
74
|
+
|
75
|
+
output += _keyStr.charAt(enc1);
|
76
|
+
output += _keyStr.charAt(enc2);
|
77
|
+
output += _keyStr.charAt(enc3);
|
78
|
+
output += _keyStr.charAt(enc4);
|
79
|
+
|
80
|
+
}
|
81
|
+
|
82
|
+
return output;
|
83
|
+
}
|
84
|
+
|
85
|
+
};
|
86
|
+
}
|
87
|
+
);
|
@@ -0,0 +1,74 @@
|
|
1
|
+
|
2
|
+
/**
|
3
|
+
* Common helper/callbacks for Breeder related functions, eg
|
4
|
+
* reusable search helps
|
5
|
+
*
|
6
|
+
* **/
|
7
|
+
|
8
|
+
sap.ui.define(["sap/m/MessageToast",
|
9
|
+
"sap/ui/commons/Dialog",
|
10
|
+
"sap/ui/core/routing/History"],
|
11
|
+
function(MessageToast, Dialog, History) {
|
12
|
+
|
13
|
+
"use strict";
|
14
|
+
|
15
|
+
return {
|
16
|
+
|
17
|
+
|
18
|
+
onIdValueHelp: function(that, oEvent) {
|
19
|
+
|
20
|
+
that.inputId = oEvent.getSource().getId();
|
21
|
+
that.inputDescrId = that.inputId + "_descr";
|
22
|
+
|
23
|
+
// create value help dialog
|
24
|
+
if (!that._valueHelpDialog) {
|
25
|
+
that._valueHelpDialog = sap.ui.xmlfragment(
|
26
|
+
"fivea.view.BreederOptio", that );
|
27
|
+
that.getView().addDependent(that._valueHelpDialog);
|
28
|
+
}
|
29
|
+
|
30
|
+
that._valueHelpDialog.open("");
|
31
|
+
},
|
32
|
+
_handleValueHelpSearch: function(evt) {
|
33
|
+
var sValue = evt.getParameter("value");
|
34
|
+
var oFilter = new Filter(
|
35
|
+
"name",
|
36
|
+
sap.ui.model.FilterOperator.Contains,
|
37
|
+
sValue
|
38
|
+
);
|
39
|
+
evt.getSource()
|
40
|
+
.getBinding("items")
|
41
|
+
.filter([oFilter]);
|
42
|
+
},
|
43
|
+
|
44
|
+
_handleValueHelpClose: function(that, evt) {
|
45
|
+
var oSelectedItem = evt.getParameter("selectedItem");
|
46
|
+
if (oSelectedItem) {
|
47
|
+
// oSelectedItem.getBindingContextPath();
|
48
|
+
// "/breeder(8)"
|
49
|
+
var oModel = oSelectedItem.getModel();
|
50
|
+
var oPath = oSelectedItem.getBindingContextPath();
|
51
|
+
|
52
|
+
|
53
|
+
function _loadavsuccs(oData, response){
|
54
|
+
that.loadavsuccs(oData, response);
|
55
|
+
};
|
56
|
+
function _loadaverr(oErr){};
|
57
|
+
oModel.read(oPath,
|
58
|
+
{ urlParameters:{$expand: "avatar"},
|
59
|
+
success: _loadavsuccs,
|
60
|
+
error: _loadaverr } );
|
61
|
+
|
62
|
+
var IDInput = that.getView().byId(that.inputId);
|
63
|
+
IDInput.setValue(oSelectedItem.getDescription());
|
64
|
+
|
65
|
+
var oText = that.getView().byId(that.inputDescrId);
|
66
|
+
oText.setText(oSelectedItem.getTitle());
|
67
|
+
}
|
68
|
+
evt.getSource()
|
69
|
+
.getBinding("items")
|
70
|
+
.filter([]);
|
71
|
+
}
|
72
|
+
};
|
73
|
+
}
|
74
|
+
);
|