filament 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/README +7 -0
  2. data/bin/filament +11 -0
  3. data/bin/filament-dbg +3 -0
  4. data/bin/filament-opt +3 -0
  5. data/bin/filament-test +3 -0
  6. data/bin/init +4 -0
  7. data/lib/filament/artifact.rb +49 -0
  8. data/lib/filament/context.rb +46 -0
  9. data/lib/filament/package/svn.rb +123 -0
  10. data/lib/filament/package.rb +326 -0
  11. data/lib/filament/platform.rb +79 -0
  12. data/lib/filament/plugins.rb +32 -0
  13. data/lib/filament/resolver.rb +91 -0
  14. data/lib/filament/target.rb +117 -0
  15. data/lib/filament/util/filelist2.rb +39 -0
  16. data/lib/filament/util/fileutils.rb +51 -0
  17. data/lib/filament/util/lazy_list.rb +74 -0
  18. data/lib/filament/workspace.rb +57 -0
  19. data/lib/filament.rb +199 -0
  20. data/lib/inflector.rb +124 -0
  21. data/lib/svn.rb +78 -0
  22. data/plugins/00util/lib/init.rb +47 -0
  23. data/plugins/01java/lib/filament/java/mixins/java_mixin.rb +19 -0
  24. data/plugins/01java/lib/filament/java/tools/compile.rb +41 -0
  25. data/plugins/01java/lib/filament/java/tools/execute.rb +37 -0
  26. data/plugins/01java/lib/filament/java/tools/jar.rb +59 -0
  27. data/plugins/01java/lib/filament/java/tools.rb +28 -0
  28. data/plugins/01java/lib/init.rb +1 -0
  29. data/plugins/02javame/lib/filament/javame/library.rb +16 -0
  30. data/plugins/02javame/lib/filament/javame/mixins/library_mixin.rb +144 -0
  31. data/plugins/02javame/lib/filament/javame/mixins/suite_mixin.rb +125 -0
  32. data/plugins/02javame/lib/filament/javame/platform.rb +105 -0
  33. data/plugins/02javame/lib/filament/javame/suite.rb +16 -0
  34. data/plugins/02javame/lib/filament/javame/tasks.rb +6 -0
  35. data/plugins/02javame/lib/filament/javame/tools/descriptor.rb +146 -0
  36. data/plugins/02javame/lib/filament/javame/tools/emulator.rb +36 -0
  37. data/plugins/02javame/lib/filament/javame/tools/external/mpp_sdk.rb +39 -0
  38. data/plugins/02javame/lib/filament/javame/tools/external/wtk.rb +60 -0
  39. data/plugins/02javame/lib/filament/javame/tools/preverifier.rb +43 -0
  40. data/plugins/02javame/lib/filament/javame/tools.rb +8 -0
  41. data/plugins/02javame/lib/init.rb +27 -0
  42. data/plugins/05push/lib/bluetooth.rb +66 -0
  43. data/plugins/05push/lib/filament/push/conduits/bluetooth_conduit.rb +25 -0
  44. data/plugins/05push/lib/filament/push/conduits/filter_conduit.rb +20 -0
  45. data/plugins/05push/lib/filament/push/conduits/scp_conduit.rb +35 -0
  46. data/plugins/05push/lib/filament/push.rb +21 -0
  47. data/plugins/05push/lib/init.rb +29 -0
  48. data/tests/build/artifact_name_test.rb +85 -0
  49. data/tests/build/artifact_test.rb +23 -0
  50. data/tests/gen/java/block_test.rb +42 -0
  51. data/tests/gen/java/callable_test.rb +23 -0
  52. data/tests/gen/java/method_test.rb +25 -0
  53. data/tests/gen/java/statement_test.rb +16 -0
  54. data/tests/java/tools_test.rb +8 -0
  55. data/tests/platform_test.rb +25 -0
  56. metadata +135 -0
@@ -0,0 +1,125 @@
1
+ require 'filament/javame/mixins/library_mixin'
2
+
3
+ class Module
4
+ def attr_accessor2(*symbols)
5
+ # attr_writer(*symbols)
6
+ symbols.each do |sym|
7
+ attr_sym = "@#{sym.to_s}".to_sym
8
+ define_method(sym) do |*val|
9
+ if val.empty?
10
+ return instance_variable_get(attr_sym)
11
+ else
12
+ return instance_variable_set(attr_sym, val.first)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+
20
+ module Filament::JavaME::Mixins
21
+ module SuiteMixin
22
+ include JavaME::Mixins::LibraryMixin
23
+
24
+ attr_accessor2 :defaultmidlet_class,
25
+ :suite_version, :suite_name, :suite_icon, :suite_vendor,
26
+ :me_configuration, :me_profile
27
+
28
+ # adds a midlet hash with keys :icon, :classname, and :name
29
+ def add_midlet(midlet)
30
+ if midlet == :default
31
+ midlet = { :classname => defaultmidlet_class,
32
+ :icon => suite_icon,
33
+ :name => suite_name }
34
+ end
35
+
36
+ @midlets << midlet
37
+ end
38
+
39
+ def init_suite
40
+ init_library
41
+ @descriptor_config = Proc.new {}
42
+ @package_deps = true
43
+ @defaultmidlet_class = nil
44
+ @midlets = []
45
+
46
+ @me_configuration = 'CLDC-1.0'
47
+ @me_profile = 'MIDP-2.0'
48
+ end
49
+
50
+ def jad_path
51
+ jad_name = Pathname.new(jar_path).basename(".*").to_s + '.jad'
52
+ return "#{output_dir}/#{jad_name}"
53
+ end
54
+
55
+ def manifest_path
56
+ return "#{working_dir}/MANIFEST.MF"
57
+ end
58
+
59
+ def descriptor_config(&block)
60
+ @descriptor_config = block
61
+ end
62
+
63
+ def define_jad(target)
64
+ # create a list for imported jad configs
65
+ configs = []
66
+ target.flattened_deps.each do |dep|
67
+ # ask each dep for its contribution
68
+ config = dep[:jad_config]
69
+ configs << config unless config.nil?
70
+ end
71
+
72
+ full_config = Proc.new do |d|
73
+ d.suite_version = @suite_version
74
+ d.suite_name = @suite_name
75
+ d.suite_icon = @suite_icon
76
+ d.suite_vendor = @suite_vendor
77
+ d.me_configuration = @me_configuration
78
+ d.me_profile = @me_profile
79
+
80
+ @midlets.each do |midlet|
81
+ d.add_midlet(midlet)
82
+ end
83
+
84
+ @descriptor_config.call(d)
85
+
86
+ configs.each do |config|
87
+ config.call(d)
88
+ end
89
+ end
90
+
91
+ jad_task = file jad_path => jar_path do |t|
92
+ JavaME::Tools::write_manifest(manifest_path, &full_config)
93
+ Java::Tools::Jar.new(jar_path) do |jar|
94
+ jar.update = true
95
+ jar.manifest = manifest_path
96
+ end
97
+ JavaME::Tools::write_jad(jad_path, jar_path, &full_config)
98
+ end
99
+
100
+ target.output :tag => :jad,
101
+ :output => jad_path,
102
+ :deployable => true
103
+
104
+ @tasks << jad_task
105
+ return jad_task
106
+ end
107
+
108
+ def define_suite(target)
109
+ # define all the tasks
110
+ # and add extra dependencies
111
+
112
+ jad_task = define_jad(target)
113
+ library_task = define_library(target)
114
+
115
+ target.output(:tag => :execute,
116
+ :output => Proc.new do; emulate; end)
117
+
118
+ return jad_task, library_task
119
+ end
120
+
121
+ def emulate(midletclass=@defaultmidlet_class)
122
+ JavaME::Tools::emulate(jad_path, midletclass)
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,105 @@
1
+ require 'filament/platform'
2
+
3
+ module Filament::JavaME
4
+ module Tools
5
+ def self.vendor_dir(name)
6
+ return "#{$workspace.realpath}/vendor/libraries/javame/#{name}"
7
+ end
8
+
9
+ def self.jsr_classpath(jsr)
10
+ return ["#{vendor_dir('jsr')}/#{jsr}/#{jsr}.jar"]
11
+ end
12
+
13
+ SUN_DIR = vendor_dir('sun')
14
+ MPP_DIR = vendor_dir('mpp-sdk')
15
+ MOTOROLA_DIR = vendor_dir('motorola')
16
+
17
+ TAGS = {
18
+ :midp1 => ["#{SUN_DIR}/midpapi10.jar"],
19
+ :midp2 => ["#{SUN_DIR}/midpapi20.jar"],
20
+ :jsr_75 => jsr_classpath(75),
21
+ :jsr_82 => jsr_classpath(82),
22
+ :jsr_120 => jsr_classpath(120),
23
+ :jsr_135 => jsr_classpath(135),
24
+ :jsr_172 => jsr_classpath(172),
25
+ :jsr_184 => jsr_classpath(184),
26
+ }
27
+
28
+ TARGET_PLATFORMS[:wtk2_2] = {
29
+ :tags => [:wtk, :midp2, :jsr_82],
30
+ :cldc_version => 1.1
31
+ }
32
+
33
+ TARGET_PLATFORMS[:mpp_sdk] = {
34
+ :tags => [:mpp, :midp2, :jsr_82],
35
+ :cldc_version => 1.1
36
+ }
37
+
38
+ TARGET_PLATFORMS[:a1000] = {
39
+ :tags => [:midp2, :jsr_82, :jsr_120, :jsr_185, :jsr_135],
40
+ :cldc_version => 1.0
41
+ }
42
+
43
+ TARGET_PLATFORMS[:weme] = {
44
+ :tags => [:midp2, :jsr_75, :jsr_172],
45
+ :cldc_version => 1.1
46
+ }
47
+
48
+ TARGET_PLATFORMS[:i860] = {
49
+ :tags => [:iden],
50
+ :cldc_version => 1.0,
51
+ :classpath => ["#{MOTOROLA_DIR}/i860/i860.jar"]
52
+ }
53
+
54
+ TARGET_PLATFORMS[:e398] = {
55
+ :tags => [:midp2, :jsr_120, :jsr_135],
56
+ :cldc_version => 1.0
57
+ }
58
+
59
+ TARGET_PLATFORMS[:e680] = {
60
+ :tags => [:midp2, :jsr_120, :jsr_135, :jsr_184, :jsr_185],
61
+ :cldc_version => 1.0
62
+ }
63
+
64
+ class << self
65
+ def platform(model)
66
+ p = TARGET_PLATFORMS[model]
67
+ raise "Unknown target platform #{model}" if p.nil?
68
+ return p
69
+ end
70
+
71
+ def tags_for(model)
72
+ return platform(model)[:tags].clone
73
+ end
74
+
75
+ def cldc_version_for(model)
76
+ return platform(model)[:cldc_version]
77
+ end
78
+
79
+ def classpath_for(model)
80
+ cldc_version = cldc_version_for(model)
81
+
82
+ base_classpath = platform(model)[:classpath]
83
+
84
+ classpath = []
85
+ classpath += base_classpath unless base_classpath.nil?
86
+
87
+ case cldc_version
88
+ when 1.0
89
+ classpath << "#{SUN_DIR}/cldcapi10.jar"
90
+ when 1.1
91
+ classpath << "#{SUN_DIR}/cldcapi11.jar"
92
+ end
93
+
94
+ tags = tags_for(model)
95
+
96
+ tags.each do |tag|
97
+ tag_classpath = TAGS[tag]
98
+ classpath += tag_classpath unless tag_classpath.nil?
99
+ end
100
+
101
+ return classpath
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,16 @@
1
+ require 'filament/javame/mixins/suite_mixin'
2
+
3
+ module Filament::JavaME
4
+ class Suite < Filament::Artifact
5
+ include JavaME::Mixins::SuiteMixin
6
+
7
+ def init
8
+ init_suite
9
+ end
10
+
11
+ def build_artifact
12
+ define_suite(self)
13
+ invoke_tasks
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,6 @@
1
+ require 'pathname'
2
+ require 'filament/java/tools'
3
+
4
+ require 'filament/javame/tools'
5
+ require 'filament/javame/library'
6
+ require 'filament/javame/suite'
@@ -0,0 +1,146 @@
1
+ require 'filament/javame/tools'
2
+
3
+ module Filament::JavaME::Tools
4
+ class Descriptor
5
+ SUITE_ENTRIES = { :suite_version => 'MIDlet-Version',
6
+ :suite_name => 'MIDlet-Name',
7
+ :suite_icon => 'MIDlet-Icon',
8
+ :suite_vendor => 'MIDlet-Vendor',
9
+ :suite_jar_url => 'MIDlet-Jar-URL',
10
+ :suite_jar_size => 'MIDlet-Jar-Size',
11
+ :me_configuration => 'MicroEdition-Configuration',
12
+ :me_profile => 'MicroEdition-Profile' }
13
+
14
+ SUITE_ENTRIES.each do |tag, desc|
15
+ get_meth = tag
16
+ set_meth = "#{tag.to_s}=".to_sym
17
+ define_method(set_meth) do |*args|
18
+ return @entries.[]=(tag, *args)
19
+ end
20
+
21
+ define_method(get_meth) do
22
+ return @entries[tag]
23
+ end
24
+ end
25
+
26
+ attr_writer :path
27
+
28
+ def initialize(path=nil, jar_path=nil)
29
+ @custom = Hash.new
30
+ @entries = Hash.new
31
+ @midlets = []
32
+ @path = path
33
+
34
+ self.jar_path = jar_path unless jar_path.nil?
35
+
36
+ yield self if block_given?
37
+ end
38
+
39
+ def jar_path=(path)
40
+ if path.nil?
41
+ self.suite_jar_url = nil
42
+ self.suite_jar_size = nil
43
+ else
44
+ jar_pn = Pathname.new(path)
45
+ self.suite_jar_url = jar_pn.basename.to_s
46
+ self.suite_jar_size = jar_pn.size
47
+ end
48
+ end
49
+
50
+ def write(h = {})
51
+ pn = Pathname.new(h[:path] || @path)
52
+
53
+ pn.open(File::CREAT|File::TRUNC|File::WRONLY) do |f|
54
+ f << to_s(h)
55
+ end
56
+ end
57
+
58
+ def to_s(h = {})
59
+ raise "me_profile must be set!" if self.me_profile.nil?
60
+ raise "me_configuration must be set!" if self.me_configuration.nil?
61
+
62
+ s = ""
63
+
64
+ keys = h[:include] || @entries.keys.sort { |a,b| b.to_s <=> a.to_s }
65
+ if h.key?(:exclude)
66
+ h[:exclude].each do |exc|
67
+ keys.delete(exc)
68
+ end
69
+ end
70
+
71
+ keys.each do |k|
72
+ v = @entries[k]
73
+ s << "#{entry_name(k)}: #{v}\n" unless v.nil?
74
+ end
75
+
76
+ @midlets.each_index do |index|
77
+ midlet = @midlets[index]
78
+ s << midlet_entry(index, midlet) << "\n"
79
+ end
80
+
81
+ return s
82
+ end
83
+
84
+ def custom_entries(h)
85
+ h.keys.each do |key|
86
+ custom(key, h[key])
87
+ end
88
+ end
89
+
90
+ def append_entries(h)
91
+ delim = h[:delim] || ', '
92
+ h.keys.each do |key|
93
+ value = h[key]
94
+ if value.is_a?(Array)
95
+ value = value.join(delim)
96
+ end
97
+ if @entries.key?(key)
98
+ h[key] = @entries[key] + delim + value
99
+ else
100
+ h[key] = value
101
+ end
102
+ end
103
+ custom_entries(h)
104
+ end
105
+
106
+ def custom(name, value=nil, symbol=nil)
107
+ symbol = name.to_sym if symbol.nil?
108
+
109
+ @custom[symbol] = name
110
+ @entries[symbol] = value unless value.nil?
111
+ end
112
+
113
+ # adds a midlet hash with keys :icon, :classname, and :name
114
+ def add_midlet(midlet)
115
+ @midlets << midlet
116
+ end
117
+
118
+ def entry_name(symbol)
119
+ return @custom[symbol] || SUITE_ENTRIES[symbol]
120
+ end
121
+
122
+ def midlet_entry(index, midlet)
123
+ return "MIDlet-#{index+1}: #{midlet[:name]},#{midlet[:icon]},#{midlet[:classname]}"
124
+ end
125
+ end
126
+
127
+ class << self
128
+ def write_jad(*args, &block)
129
+ Descriptor.new(*args) do |d|
130
+ block.call(d)
131
+ d.write
132
+ end
133
+ end
134
+
135
+ def write_manifest(*args, &block)
136
+ Descriptor.new(*args) do |d|
137
+ block.call(d)
138
+ d.write(:include => [:me_configuration,
139
+ :me_profile,
140
+ :suite_name,
141
+ :suite_vendor,
142
+ :suite_version])
143
+ end
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,36 @@
1
+ require 'filament/javame/tools'
2
+ require 'filament/javame/platform'
3
+
4
+ module Filament::JavaME::Tools
5
+ class << self
6
+ def emulate(*args)
7
+ Emulator.emulate(*args)
8
+ end
9
+ end
10
+
11
+ class Emulator
12
+ @@emulators = {}
13
+
14
+ def self.inherited(subklass)
15
+ name = subklass.name.split(/::/).last
16
+ name = name.split(/Emulator/).first
17
+ @@emulators[name.to_sym] = subklass
18
+ end
19
+
20
+ def self.set_type(type)
21
+ @@type = type.to_sym
22
+ end
23
+
24
+ def self.emulate(jad_path, midletclass=nil)
25
+ emulator = @@emulators[@@type]
26
+ emulator.new(jad_path, midletclass).run
27
+ end
28
+
29
+ attr_writer :jad_path, :midletclass
30
+
31
+ def initialize(jad_path, midletclass=nil)
32
+ @jad_path = fix_paths(jad_path)
33
+ @midletclass = midletclass
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,39 @@
1
+ require 'filament/javame/platform'
2
+ require 'filament/javame/tools/emulator'
3
+
4
+ module Filament::JavaME::Tools
5
+ module MppSdk
6
+ def self.home
7
+ mpp_home_env = ENV['MPP_SDK_HOME']
8
+
9
+ return mpp_home_env unless mpp_home_env.nil?
10
+
11
+ base_dir = "#{$workspace.realpath}/vendor/applications/mpp-sdk"
12
+ version = Pathname.new("#{base_dir}/VERSION").read.chomp
13
+
14
+ return "#{base_dir}/#{version}"
15
+ end
16
+
17
+ class MppSdkEmulator < Emulator
18
+ def run
19
+ cd MppSdk::home do |d|
20
+ c = "java -jar player.jar #{@jad_path}"
21
+ sys c
22
+ end
23
+ end
24
+ end
25
+
26
+ class MppSdkPreverifier < Preverifier
27
+ def preverify
28
+ raise "MppSdkPreverifier only works on darwin" unless darwin?
29
+
30
+ c = "#{MppSdk::home}/osx/preverify/preverify"
31
+ c << " -classpath #{join_paths(@classpath)}" unless @classpath.empty?
32
+ c << " -d #{fix_paths(@output_dir)}"
33
+ c << " -cldc1.0" if @cldc_version == 1.0
34
+ c << " #{fix_paths(@classes)}"
35
+ sys c
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,60 @@
1
+ require 'filament/javame/platform'
2
+ require 'filament/javame/tools/emulator'
3
+ require 'filament/javame/tools/preverifier'
4
+
5
+ module Filament::JavaME::Tools
6
+ module Wtk
7
+ def self.home
8
+ wtk_home_env = ENV['WTK_HOME']
9
+
10
+ return wtk_home_env unless wtk_home_env.nil?
11
+
12
+ wtk_base = "#{$workspace.realpath}/vendor/applications/wtk"
13
+
14
+ return "#{wtk_base}/windows/2.3" if windows?
15
+ return "#{wtk_base}/linux/2.2"
16
+ end
17
+
18
+ def self.bin(path=nil)
19
+ wtk_bin = home + '/bin'
20
+ return wtk_bin if path.nil?
21
+ return to_exec_path("#{wtk_bin}/#{path}")
22
+ end
23
+
24
+ class WtkEmulator < Emulator
25
+ def run
26
+ raise "Wtk does not support darwin" if darwin?
27
+
28
+ if windows?
29
+ c = Wtk.bin('emulator.exe')
30
+ else
31
+ c = "sh " + Wtk.bin('emulator')
32
+ end
33
+
34
+ c << " -Xdescriptor:#{@jad_path} "
35
+ c << " -Xdomain:maximum "
36
+ c << " #{@midletclass}" unless @midletclass.nil?
37
+
38
+ sys c
39
+ end
40
+ end
41
+
42
+ class WtkPreverifier < Preverifier
43
+ def preverify
44
+ raise "Wtk does not support darwin" if darwin?
45
+
46
+ if windows?
47
+ c = Wtk.bin('preverify.exe')
48
+ else
49
+ c = Wtk.bin('preverify')
50
+ end
51
+
52
+ # TODO cldc_version is not used!
53
+ c << " -classpath #{join_paths(@classpath)}" unless @classpath.empty?
54
+ c << " -d #{fix_paths(@output_dir)}"
55
+ c << " #{fix_paths(@classes)}"
56
+ sys c
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,43 @@
1
+ require 'filament/javame/platform'
2
+
3
+ module Filament::JavaME::Tools
4
+ class << self
5
+ def preverify(*args, &block)
6
+ Preverifier.preverify(*args, &block)
7
+ end
8
+ end
9
+
10
+ # preverify class files or an entire directory
11
+ class Preverifier
12
+ @@preverifiers = {}
13
+
14
+ def self.inherited(subklass)
15
+ name = subklass.name.split(/::/).last
16
+ name = name.split(/Preverifier/).first
17
+ @@preverifiers[name.to_sym] = subklass
18
+ end
19
+
20
+ def self.set_type(type)
21
+ @@type = type.to_sym
22
+ end
23
+
24
+ def self.preverify(classes=nil, output_dir=nil, &block)
25
+ preverifier = @@preverifiers[@@type]
26
+ preverifier.new(classes, output_dir, &block)
27
+ end
28
+
29
+ attr_writer :output_dir, :cldc_version, :classpath, :classes
30
+
31
+ def initialize(classes=nil, output_dir=nil, &block)
32
+ @classes = classes
33
+ @output_dir = output_dir
34
+ @cldc_version = nil
35
+ @classpath = []
36
+
37
+ yield self if block_given?
38
+
39
+ preverify unless @classes.nil? or @output_dir.nil?
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,8 @@
1
+ module Filament::JavaME
2
+ module Tools; end
3
+ end
4
+
5
+ require 'filament/javame/tools/descriptor'
6
+
7
+ require 'filament/javame/tools/external/wtk'
8
+ require 'filament/javame/tools/external/mpp_sdk'
@@ -0,0 +1,27 @@
1
+ require 'pathname'
2
+
3
+ require 'filament/platform'
4
+
5
+ module Filament::JavaME
6
+ HOME = Pathname.new(__FILE__).parent.parent.realpath
7
+ end
8
+ require 'filament/javame/tools'
9
+ require 'filament/javame/tasks'
10
+
11
+ def default_emulator
12
+ return :MppSdk if darwin?
13
+ return :Wtk
14
+ end
15
+
16
+ def default_preverifier
17
+ return :MppSdk if darwin?
18
+ return :Wtk
19
+ end
20
+
21
+ module Filament::JavaME
22
+ emulator = ENV['JAVAME_EMULATOR'] || default_emulator
23
+ Tools::Emulator::set_type(emulator.to_sym)
24
+
25
+ preverifier = ENV['JAVAME_PREVERIFIER'] || default_preverifier
26
+ Tools::Preverifier::set_type(preverifier.to_sym)
27
+ end
@@ -0,0 +1,66 @@
1
+ class Bluetooth
2
+ def self.add_adapter(adapter_class)
3
+ @@adapters ||= []
4
+ @@adapters << adapter_class
5
+ end
6
+
7
+ def self.get_adapter
8
+ @@adapters.each do |adapter|
9
+ if adapter.applicable?
10
+ return adapter.new
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ class BlueZ < Bluetooth
17
+ Bluetooth.add_adapter(self)
18
+
19
+ def self.applicable?
20
+ return /linux/ =~ PLATFORM
21
+ end
22
+
23
+ def push_file(h)
24
+ file = h[:file]
25
+ bluetooth_device = h[:device] || ENV['BLUETOOTH_DEVICE']
26
+ bluetooth_channel = h[:channel] || ENV['BLUETOOTH_CHANNEL']
27
+
28
+ raise "BLUETOOTH_DEVICE must be set" if bluetooth_device.nil?
29
+ raise "BLUETOOTH_CHANNEL must be set" if bluetooth_channel.nil?
30
+
31
+ file_name = File.basename(file)
32
+
33
+ puts "sending #{file} to #{bluetooth_device} (#{bluetooth_channel}) as #{file_name} ..."
34
+ system("ussp-push \"#{bluetooth_device}\"@#{bluetooth_channel} #{file} #{file_name}")
35
+ end
36
+ end
37
+
38
+ class BluetoothOSX < Bluetooth
39
+ Bluetooth.add_adapter(self)
40
+
41
+ def self.applicable?
42
+ return /darwin/ =~ PLATFORM
43
+ end
44
+
45
+ def running?
46
+ s = IO.popen('ps x | grep -v grep | grep "Bluetooth File Exchange"', 'r')
47
+ data = s.read.strip
48
+ s.close
49
+
50
+ return data != ""
51
+ end
52
+
53
+ def push_file(h)
54
+ file = h[:file]
55
+ STDOUT.write("sending #{file} ...")
56
+
57
+ system("open -a /Applications/Utilities/Bluetooth\\ File\\ Exchange.app '#{file}'")
58
+ while running?
59
+ sleep(3)
60
+ STDOUT.write(".")
61
+ STDOUT.flush
62
+ end
63
+ puts "done"
64
+ end
65
+ end
66
+