filament 0.1.0

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.
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
+