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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 248cc59ce0fcae37aa84f3b37d1753d2a37220e6a27be1637e1cf90e10cd7890
4
- data.tar.gz: 9de4f054e4673e3b60efb5ab0d586b866a8be8d955bbb8cbe10ecaf287ada0c0
3
+ metadata.gz: 819272c422885597ec73f8dd633cad031e882f03e9c5ee3d009a48792d1ae6eb
4
+ data.tar.gz: 96e67d9c2cbe9538ca91f30565f8c15553357a7d9c4880c6eccb45454de45917
5
5
  SHA512:
6
- metadata.gz: f89362536a55e4292a4f4508d0d61b90f59d1434b45446b21067d6340c3de1b209e5f65934105ee8928953fba42cf8a959e0eed2cbd80b760dcced051ab6453f
7
- data.tar.gz: 893b60adac0d59cacf29ff37967ec40c1019ae215e94723da80cf00baafd3ebcf4cd0cd8e34148c5ec7cf3a38317c5e495b2133b51432dc40419ade94cde1d75
6
+ metadata.gz: bf920145c28718564c5c207cb98eb4800d651e691340f1e670b3e8f794ae062c66bba5db6027c28aa09292effbe949b0fcb2db9f0aca1b9b0476b2c4ef13f62d
7
+ data.tar.gz: b8db84aa3f9f1c83ab63d524be0ee57b10804d39d573a23c59e9efacdfd6e4c6b8444108bb69c056d7399117aa8ea118451331877cb349c1a47175d14f4fa590
@@ -33,8 +33,8 @@ end
33
33
 
34
34
  fiveapples = Rack::OData::Builder.new do
35
35
 
36
- use Rack::ODataCommonLogger unless ( FiveA.role == :test )
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
- redirects["/ui5/index.html"] = idxh if FiveA.one_way
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"
@@ -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
Binary file
@@ -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
- @apphome = if ( @role == :test )
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
- net = Socket.ip_address_list.detect(&:ipv4_private?)
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
- # this requires safrano ~> 0.3.5
96
- # puts "Safrano version #{Safrano::VERSION}"
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
 
@@ -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
 
@@ -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
@@ -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
+ );