multistockphoto 0.8.1 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +14 -0
- data/bin/multistockphoto +72 -2
- data/lib/multistockphoto/site_aldi.rb +82 -0
- data/lib/multistockphoto/site_fotolia.rb +2 -2
- data/lib/multistockphoto/site_istockphoto.rb +15 -0
- data/lib/multistockphoto/site_photocase.rb +132 -120
- data/lib/multistockphoto/site_zoonar.rb +13 -4
- data/lib/multistockphoto/version.rb +2 -2
- metadata +90 -71
- data/License.txt +0 -20
- data/Manifest.txt +0 -43
- data/PostInstall.txt +0 -7
- data/Rakefile +0 -4
- data/bin/mondrian.ico +0 -0
- data/bin/mondrian.png +0 -0
- data/bin/multistockphoto-gui +0 -187
- data/config/hoe.rb +0 -78
- data/config/requirements.rb +0 -15
- data/config.yaml +0 -40
- data/script/console +0 -10
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/script/txt2html +0 -82
- data/setup.rb +0 -1585
- data/tasks/deployment.rake +0 -34
- data/tasks/environment.rake +0 -7
- data/tasks/website.rake +0 -17
- data/test/test_helper.rb +0 -6
- data/test/test_multistockphoto.rb +0 -855
- data/website/face_boy.gif +0 -0
- data/website/index.html +0 -884
- data/website/index.txt +0 -1112
- data/website/javascripts/rounded_corners_lite.inc.js +0 -285
- data/website/stylesheets/screen.css +0 -138
- data/website/template.html.erb +0 -48
data/History.txt
CHANGED
@@ -1,4 +1,18 @@
|
|
1
|
+
== 0.9.0 2009-07-08
|
2
|
+
|
3
|
+
* 4 bugfixes
|
4
|
+
* Laeuft jetzt mit Ruby 1.9
|
5
|
+
* Login-Prozedur bei photocase angepasst
|
6
|
+
* Abhaengigkeit von gem 'mini_exiftool' hat gefehlt
|
7
|
+
* Abhaengigkeit von gem 'exifr' hat gefehlt
|
8
|
+
|
9
|
+
== 0.8.2 2008-12-30
|
10
|
+
|
11
|
+
* 1 bugfix
|
12
|
+
* Abhaengigkeit von gem 'choice' hat gefehlt
|
13
|
+
|
1
14
|
== 0.8.1 2008-12-30
|
15
|
+
|
2
16
|
* 1 enhancement
|
3
17
|
* doppelte Tags in Datei nicht mehrfach zaehlen
|
4
18
|
* photocase: bessere Fehleranalyse, falls Upload-Fehler
|
data/bin/multistockphoto
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
2
|
+
# encoding: utf-8
|
3
3
|
require 'rubygems'
|
4
4
|
require 'choice'
|
5
5
|
require 'multistockphoto'
|
@@ -20,7 +20,72 @@ require 'fcntl'
|
|
20
20
|
#STDOUT.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK)
|
21
21
|
|
22
22
|
require 'logger'
|
23
|
-
$log = Logger.new('multistockphoto.log', 'daily', 30)
|
23
|
+
# $log = Logger.new('multistockphoto.log', 'daily', 30)
|
24
|
+
# $log = Logger.new('multistockphoto.log', 5, 1024000)
|
25
|
+
# $log = Logger.new('multistockphoto.log', 'daily', 7)
|
26
|
+
|
27
|
+
|
28
|
+
class Fixnum
|
29
|
+
|
30
|
+
def to_german_word
|
31
|
+
raise "Sorry, I can only count from 1 to 999999." if self < 1 || self > 999999
|
32
|
+
self.to_german + (self % 100 == 1 ? "s" : "")
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
|
37
|
+
def to_german
|
38
|
+
words = {
|
39
|
+
0 => "",
|
40
|
+
1 => "ein",
|
41
|
+
2 => "zwei",
|
42
|
+
3 => "drei",
|
43
|
+
4 => "vier",
|
44
|
+
5 => "fünf",
|
45
|
+
6 => "sechs",
|
46
|
+
7 => "sieben",
|
47
|
+
8 => "acht",
|
48
|
+
9 => "neun",
|
49
|
+
10 => "zehn",
|
50
|
+
11 => "elf",
|
51
|
+
12 => "zwölf",
|
52
|
+
16 => "sechzehn",
|
53
|
+
17 => "siebzehn",
|
54
|
+
20 => "zwanzig",
|
55
|
+
30 => "dreissig",
|
56
|
+
40 => "vierzig",
|
57
|
+
50 => "fünfzig",
|
58
|
+
60 => "sechzig",
|
59
|
+
70 => "siebzig",
|
60
|
+
80 => "achtzig",
|
61
|
+
90 => "neunzig",
|
62
|
+
:join => "und",
|
63
|
+
:hundred => "hundert",
|
64
|
+
:thousand => "tausend",
|
65
|
+
}
|
66
|
+
|
67
|
+
if words[self]
|
68
|
+
words[self]
|
69
|
+
elsif self < 20
|
70
|
+
(self % 10).to_german + words[10]
|
71
|
+
elsif self < 100
|
72
|
+
(self % 10).to_german + words[:join] + ((self / 10) * 10).to_german
|
73
|
+
elsif self < 1000
|
74
|
+
(self / 100).to_german + words[:hundred] + (self % 100).to_german
|
75
|
+
elsif self < 1000000
|
76
|
+
(self / 1000).to_german + words[:thousand] + (self % 1000).to_german
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
# test
|
84
|
+
=begin
|
85
|
+
1.upto(999999) do |n|
|
86
|
+
puts "#{n.to_s}: #{n.to_german_word}"
|
87
|
+
end
|
88
|
+
=end
|
24
89
|
|
25
90
|
# alle Sites komplett bearbeitet?
|
26
91
|
def all_sites_done(sites,n)
|
@@ -417,6 +482,11 @@ def send_all
|
|
417
482
|
end
|
418
483
|
}
|
419
484
|
puts "#{total_transfers} photos sent."
|
485
|
+
if total_transfers == 0
|
486
|
+
puts "keine photos gesendet"
|
487
|
+
else
|
488
|
+
puts "#{total_transfers.to_german_word} photos gesendet}"
|
489
|
+
end
|
420
490
|
end
|
421
491
|
|
422
492
|
# gibt Orientation aller uebergebenen Bilddateien aus
|
@@ -0,0 +1,82 @@
|
|
1
|
+
class Aldi < GenericSite
|
2
|
+
|
3
|
+
def initialize(name)
|
4
|
+
p "creating an ALDI object"
|
5
|
+
super
|
6
|
+
if ENV['MSP_CONFIG']
|
7
|
+
@config = YAML.load_file(ENV['MSP_CONFIG'])
|
8
|
+
p "meine config: #{ENV['MSP_CONFIG']}"
|
9
|
+
else
|
10
|
+
p "standard config"
|
11
|
+
@config = YAML.load_file("config.yaml")
|
12
|
+
end
|
13
|
+
@user = @config[:aldi][:user]
|
14
|
+
@password = @config[:aldi][:password]
|
15
|
+
# kann vom Client ueberschrieben werden
|
16
|
+
end
|
17
|
+
|
18
|
+
def transfer(photo)
|
19
|
+
# falls nicht in config Datei eingetragen dann nicht senden
|
20
|
+
if @user == nil or @password == nil
|
21
|
+
return
|
22
|
+
end
|
23
|
+
|
24
|
+
unless photo.class == Photo
|
25
|
+
raise 'not a Photo object'
|
26
|
+
end
|
27
|
+
unless File.exist?(photo.filename)
|
28
|
+
raise "file #{photo.filename} does not exist"
|
29
|
+
end
|
30
|
+
puts "zoonar:#{photo.filename}"
|
31
|
+
g = `grep "zoonar\t#{photo.filename}" sendeliste.dat`
|
32
|
+
if g.size > 0
|
33
|
+
#puts "INFO: already sent to zoonar"
|
34
|
+
return :duplicate
|
35
|
+
end
|
36
|
+
|
37
|
+
agent = WWW::Mechanize.new
|
38
|
+
agent.user_agent_alias = 'Linux Mozilla'
|
39
|
+
page = agent.get 'https://shop.aldi-fotoservice-druck.de/shop/viewLoginForm.do'
|
40
|
+
|
41
|
+
if page.body.include?('Login/Neuanmeldung')
|
42
|
+
p 'bin auf Login-Seite'
|
43
|
+
end
|
44
|
+
form = page.forms.first #TODO: besser nach Name
|
45
|
+
form.username = @config[:aldi][:user]
|
46
|
+
form.password = @config[:aldi][:password]
|
47
|
+
p form.username
|
48
|
+
p form.password
|
49
|
+
page = agent.submit form
|
50
|
+
if page.body.include?('Ihre Benutzerdaten')
|
51
|
+
p 'bin auf Benutzerdaten-Seite'
|
52
|
+
else
|
53
|
+
html_out(page.body,'out.html')
|
54
|
+
end
|
55
|
+
page = agent.click page.links.text('zum Direkt-Upload')
|
56
|
+
# if page.body.include?('Ihr Warenkorb ist leer.')
|
57
|
+
# p 'bin beim leeren Warenkorb'
|
58
|
+
# end
|
59
|
+
# # page = agent.get('https://shop.aldi-fotoservice-druck.de/shop/viewUploadForm.do')
|
60
|
+
# page = agent.click page.links.text(/viewUploadForm/)
|
61
|
+
if page.body.include?('Bilddateien und Zip-Archive einzeln hochladen')
|
62
|
+
p 'bin auf Upload-Seite'
|
63
|
+
end
|
64
|
+
form = page.forms.first #TODO: besser nach Name
|
65
|
+
pp form
|
66
|
+
#form.file_1 = photo.filename
|
67
|
+
pp form.file_uploads.name('file_1').first
|
68
|
+
form.file_uploads.name('file_1').first.file_name = photo.filename
|
69
|
+
pp form.file_uploads.name('file_1').first
|
70
|
+
#pp form
|
71
|
+
##TODO: derzeit sind in diesem Formular bis zu 5 Photos gleichzeitig moeglich
|
72
|
+
page = agent.submit form
|
73
|
+
if page.body.include?('Ihr Auftrag')
|
74
|
+
p "bin auf Auftrag-Anzeigeseite"
|
75
|
+
html_out(page.body,'out.html')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def html_out(body,html_file)
|
80
|
+
File.open(html_file,"w") {|f| f.print body}
|
81
|
+
end
|
82
|
+
end
|
@@ -50,7 +50,7 @@ class Fotolia < GenericSite
|
|
50
50
|
if site_can_handle_keywords?
|
51
51
|
photo.set_keywords
|
52
52
|
end
|
53
|
-
|
53
|
+
unless dont_send
|
54
54
|
begin
|
55
55
|
ftp = Net::FTP.new(FTP_HOST)
|
56
56
|
ftp.login(@ftp_user,@ftp_password)
|
@@ -139,4 +139,4 @@ class Fotolia < GenericSite
|
|
139
139
|
true
|
140
140
|
end
|
141
141
|
|
142
|
-
end # class
|
142
|
+
end # class
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# require 'net/ftp'
|
2
|
+
=begin
|
3
|
+
Istockphoto stellt dermassen hohe Einstiegshuerden auf:
|
4
|
+
1. Bewerbung mit 3 der eigenen besten Photos, bevor man aufgenommen wirde
|
5
|
+
2. Kopie Ausweis oder Pass zwingend vorgeschrieben (meinen die, ich würde für
|
6
|
+
jemand anderen meine Photos verkaufen? Werde ich nicht im eigenen Interesse
|
7
|
+
meine richtigen Daten angeben, damit ich auch Kohle bekomme?)
|
8
|
+
|
9
|
+
dass ich erstmal darauf verzichtet habe, Istockphoto hier mit aufzunehmen.
|
10
|
+
Aufgeschoben ist aber nicht aufgehoben. Ich werde irgenwann mal darauf zurückkommen.
|
11
|
+
|
12
|
+
=end
|
13
|
+
class Itockphoto < GenericSite
|
14
|
+
|
15
|
+
end # class
|
@@ -26,7 +26,6 @@ class Photocase < GenericSite
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def transfer(photo,dont_send=false,dont_log=false)
|
29
|
-
$log.debug 'Photocase#transfer BEGIN'
|
30
29
|
sav_photo_filename = photo.filename.dup
|
31
30
|
# falls nicht in config Datei eingetragen dann nicht senden
|
32
31
|
if @user == nil or @password == nil
|
@@ -55,130 +54,143 @@ class Photocase < GenericSite
|
|
55
54
|
if ! dont_send
|
56
55
|
begin
|
57
56
|
agent = WWW::Mechanize.new
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
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
|
-
form.
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
57
|
+
agent.user_agent_alias = 'Linux Mozilla'
|
58
|
+
begin
|
59
|
+
page = agent.get 'http://www.photocase.de/en/login.asp'
|
60
|
+
rescue ArgumentError
|
61
|
+
warn "ArgumentError error in mechanize-gem"
|
62
|
+
warn "TODO: mechanize should fix this problem"
|
63
|
+
warn "skipping file"
|
64
|
+
raise UploadException
|
65
|
+
end
|
66
|
+
if !page.body.include?('Log in')
|
67
|
+
raise UploadException, 'not at the login page'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
# form = page.forms.first #TODO: besser nach Name
|
71
|
+
form = page.forms[1] #TODO: es ist jetzt das zweite Formular
|
72
|
+
# form['loginForm[Username]'] = @config[:zoonar][:user]
|
73
|
+
# form['loginForm[Password]'] = @config[:zoonar][:password]
|
74
|
+
form['UserName'] = @config[:photocase][:user]
|
75
|
+
form['UserPassword'] = @config[:photocase][:password]
|
76
|
+
#UserName
|
77
|
+
#UserPassword
|
78
|
+
page = agent.submit form
|
79
|
+
# raise "login error" if ! page.body.include?("Login successful")
|
80
|
+
if (! page.body.include?("Login successful")) and
|
81
|
+
(! page.body.include?("Einloggen erfolgreich"))
|
82
|
+
#2009-07-08 Fehlermeldung kommt jetzt in deutsch
|
83
|
+
|
84
|
+
# obiges kommt anscheinend seit 1.8.2008 nicht mehr auf der Seite.
|
85
|
+
# mit folgendem ersetzt
|
86
|
+
# 2009-06-26: scheint doch wieder zu kommen
|
87
|
+
# if ! page.body.include?('<div id="loggedIn">')
|
88
|
+
raise UploadException, "login error"
|
89
|
+
end
|
90
|
+
# old mechanize version: page = agent.click page.links.text('Upload')
|
91
|
+
page = agent.click page.link_with(:text => 'Upload')
|
92
|
+
if page.body.include?('Upload a photo') or
|
93
|
+
page.body.include?('Foto hochladen')
|
94
|
+
true # alles OK
|
95
|
+
else
|
96
|
+
raise UploadException, "no 'Upload a photo' on page"
|
97
|
+
end
|
98
|
+
form = page.form('Form')
|
99
|
+
if photo.portrait?
|
100
|
+
form.file_uploads.first.file_name = photo.rotated_filename
|
101
|
+
# b = File.basename(photo.filename)
|
102
|
+
# newfilename = photo.filename.sub(b,'')+'rot_'+b
|
103
|
+
# # form.file_uploads.first.file_name = 'r' + photo.filename
|
104
|
+
# form.file_uploads.first.file_name = newfilename
|
105
|
+
else
|
106
|
+
form.file_uploads.first.file_name = photo.filename
|
107
|
+
end
|
108
|
+
#TODO:
|
109
|
+
# 2 Checkboxen
|
110
|
+
#UploadDisclaimerAccepted
|
111
|
+
#HasCopyright
|
112
|
+
# old syntax of mechanize gem: form.checkboxes.name('UploadDisclaimerAccepted').check
|
113
|
+
form.checkbox_with(:name => 'UploadDisclaimerAccepted').check
|
114
|
+
# old syntax of mechanize gem: form.checkboxes.name('HasCopyright').check
|
115
|
+
form.checkbox_with(:name => 'HasCopyright').check
|
116
|
+
page = agent.submit form
|
117
|
+
# if !page.body.include?('Your photo was uploaded successfully.') and
|
118
|
+
# !page.body.include?('Dein Foto wurde erfolgreich hochgeladen')
|
119
|
+
# raise "not successfully uploaded"
|
120
|
+
# end
|
121
|
+
if page.body.include?('Your photo was uploaded successfully.') or
|
122
|
+
page.body.include?('Dein Foto wurde erfolgreich hochgeladen')
|
123
|
+
@@errors = 0
|
124
|
+
puts "OK"
|
125
|
+
else
|
126
|
+
#Fehler aufgetreten
|
127
|
+
@@errors += 1
|
128
|
+
if @@errors > 3
|
129
|
+
raise "too many errors"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
# rescue Net::HTTPInternalServerError, WWW::Mechanize::ResponseCodeError
|
133
|
+
# # Net::HTTPInternalServerError (WWW::Mechanize::ResponseCodeError)
|
134
|
+
# raise UploadException
|
135
|
+
# rescue Iconv::IllegalSequence
|
136
|
+
# warn "Iconv::IllegalSequence error in mechanize-gem"
|
137
|
+
# warn "TODO: mechanize should fix this problem"
|
138
|
+
# warn "skipping file"
|
139
|
+
# raise UploadException
|
140
|
+
# end # rescue
|
141
|
+
else
|
142
|
+
puts "OK"
|
143
|
+
end
|
144
|
+
#'Your photo was uploaded successfully.'
|
145
|
+
if sav_photo_filename != photo.filename
|
146
|
+
raise "photo.filenames has been changed!"
|
147
|
+
end
|
135
148
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
end
|
149
|
+
unless dont_log
|
150
|
+
File.open(SENDLIST,'a') {|f|
|
151
|
+
f.puts "#{SITENAME}\t#{photo.filename}\t#{Time.now}"
|
152
|
+
}
|
153
|
+
end
|
154
|
+
true
|
155
|
+
end
|
144
156
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
157
|
+
# Anzahl heute schon gesendeter Photos
|
158
|
+
def sent_today
|
159
|
+
site = SITENAME
|
160
|
+
return sent_today_site(site)
|
161
|
+
end
|
150
162
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
163
|
+
# wurde dieses Photo schon gesendet?
|
164
|
+
def already_sent?(photo)
|
165
|
+
already_sent_site?(photo,SITENAME)
|
166
|
+
end
|
155
167
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
168
|
+
# can site handle orientation?
|
169
|
+
def self.can_handle_orientation?
|
170
|
+
false
|
171
|
+
end
|
160
172
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
173
|
+
# Site akzeptiert diese Extension
|
174
|
+
def self.accept?(ext)
|
175
|
+
ext = ext.downcase
|
176
|
+
if ext[0,1] == '.'
|
177
|
+
ext = ext[1..-1]
|
178
|
+
end
|
179
|
+
case ext
|
180
|
+
when 'jpg','jpeg' #TODO: pruefen
|
181
|
+
return true
|
182
|
+
else
|
183
|
+
return false
|
184
|
+
end
|
185
|
+
end
|
174
186
|
|
175
|
-
|
176
|
-
|
177
|
-
|
187
|
+
def accept?(ext)
|
188
|
+
Photocase.accept?(ext)
|
189
|
+
end
|
178
190
|
|
179
|
-
|
191
|
+
private
|
180
192
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
end
|
193
|
+
def site_can_handle_keywords?
|
194
|
+
true # TODO: ueberpruefen, ob richtig?
|
195
|
+
end
|
196
|
+
end
|