New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Migration: Upload migration files from profile settings and start processing #8274
base: develop
Are you sure you want to change the base?
Conversation
%p | ||
If the pod of the account you are importing is offline, your contacts and posts will still be imported, | ||
but your contacts will receive a notification as if you started sharing with them. | ||
= form_for current_user, url: edit_user_path, html: {method: :put, multipart: true, class: "form-horizontal"} do |f| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line is too long. [126/120]
.clearfix | ||
.btn.btn-default{data: {dismiss: "modal"}} | ||
Cancel | ||
= f.submit 'Import and merge', class: "btn btn-primary.pull-right", id: "change_email_preferences" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.
.btn.btn-default{data: {dismiss: "modal"}} | ||
Cancel | ||
= f.submit 'Import and merge', class: "btn btn-primary.pull-right", id: "change_email_preferences" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line contains trailing whitespace
app/workers/import_profile.rb
Outdated
end | ||
end | ||
|
||
private |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Layout/AccessModifierIndentation: Indent access modifiers like
private
. - Layout/EmptyLinesAroundAccessModifier: Keep a blank line before and after
private
.
app/workers/import_profile.rb
Outdated
photo.remote_photo_name = nil # migration sets this attribute, but file needs to be procesed | ||
photo.unprocessed_image = photo_filename | ||
photo.save(touch: false) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/EmptyLinesAroundBlockBody: Extra empty line detected at block body end.
app/workers/import_profile.rb
Outdated
def unzip_photos_file(photo_file_path) | ||
system("unzip", photo_file_path) | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/EmptyLinesAroundClassBody: Extra empty line detected at class body end.
afa3462
to
92e6d5c
Compare
app/uploaders/exported_photos.rb
Outdated
def filename | ||
"#{model.username}_photos_#{secure_token}.zip" if original_filename.present? | ||
if original_filename.present? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/GuardClause: Use a guard clause (return unless original_filename.present?
) instead of wrapping the code inside a conditional expression.
app/uploaders/exported_user.rb
Outdated
end | ||
|
||
def filename | ||
"#{model.username}_diaspora_data_#{secure_token}.json.gz" if original_filename.present? | ||
if original_filename.present? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/GuardClause: Use a guard clause (return unless original_filename.present?
) instead of wrapping the code inside a conditional expression.
92e6d5c
to
68fad50
Compare
68fad50
to
8ce090e
Compare
app/models/photo.rb
Outdated
def url(name = nil) | ||
if remote_photo_path | ||
name = name.to_s + '_' if name | ||
def url(name=nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Metrics/AbcSize: Assignment Branch Condition size for url is too high. [<2, 19, 7> 20.35/20]
app/models/photo.rb
Outdated
# During migration in bad cases this might be happen | ||
# If this happens, stream loading stops. Better dont show photos as stop loading stream | ||
if remote_photo_path.present? && remote_photo_name.present? | ||
name = "#{name.to_s}_" if name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lint/RedundantStringCoercion: Redundant use of Object#to_s
in interpolation.
I'd like chance to review the text (including code comments) at some point, as Diaspora's (sort of) 'chief proof-reader'. I'll try to do this soon. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've reviewed most of the strings and made suggested changes to some of them. I think I've seen everything, but it's not easy with the text in code files rather than in a separate config file. I'll check again once the text has been extracted.
There are a few comments where I'm not sure exactly what they are supposed to communicate, so I've asked for clarification.
I'll have to think about the two large text blocks at a later date, so I'll come back to them.
Thanks!
app/controllers/users_controller.rb
Outdated
@user.export = user_data[:export] if user_data[:export] | ||
@user.exported_photos_file = user_data[:exported_photos_file] if user_data[:exported_photos_file] | ||
if @user.save | ||
flash.now[:notice] = "A profile migration is scheduled" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assuming this includes data and photos, I suggest using 'account' rather than 'profile'. How about either:
- Your account migration has been scheduled
or - Your account migration is in progress
app/controllers/users_controller.rb
Outdated
if @user.save | ||
flash.now[:notice] = "A profile migration is scheduled" | ||
else | ||
flash.now[:error] = "An error occured scheduling a migration: #{@user.errors.full_messages}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks as though a specific error message is appended to this warning, so I suggest:
- The following error occurred in scheduling your account migration:
or - Your account migration could not be scheduled for the following reason:
(note: two Rs in occurred)
app/models/account_migration.rb
Outdated
@@ -29,6 +29,7 @@ def sender | |||
# executes a migration plan according to this AccountMigration object |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be clearer? Or is it clear to any coder?
app/models/photo.rb
Outdated
else | ||
true | ||
end | ||
end | ||
|
||
def ownership_of_status_message | ||
message = StatusMessage.find_by_guid(self.status_message_guid) | ||
message = StatusMessage.find_by(guid: status_message_guid) | ||
return unless status_message_guid && message && diaspora_handle != message.diaspora_handle | ||
|
||
errors.add(:base, "Photo must have the same owner as status message") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is text in the UI, I'll need to know context in order to be able to polish this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is internally only. I think, a photo must have a reference to a post ('status message' internally) to be valid. This text goes out to an error log.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. That is probably clear enough to a coder or admin.
app/models/photo.rb
Outdated
if remote_photo_path | ||
name = name.to_s + '_' if name | ||
def url(name=nil) | ||
# During migration in bad cases this might be happen |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, these two lines could be clearer, but context would be helpful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A message to a coder. The if clause the next line was changed, because in rare cases a photo can not be processed. Then the stream will not load. Diaspora stops (crashes). Would be nice to use clear words for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about 'If a photo cannot be processed during migration, the migration will fail and the stream will stop loading. If this happens, don't show the photos' ???
app/models/user.rb
Outdated
logger.error "Unexpected error while exporting user '#{username}': #{error.class}: #{error.message}\n" \ | ||
"#{error.backtrace.first(15).join("\n")}" | ||
rescue StandardError => e | ||
logger.error "Unexpected error while exporting user '#{username}': #{e.class}: #{e.message}\n" \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Unexpected error while exporting data for '#{username}':
This mirrors the error message for photos.
app/views/users/_edit.haml
Outdated
%h3= t(".export_data") | ||
%p If you want to migrate this account to another pod, start by exporting your data using the buttons below. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... start by exporting your data and photos ...
app/views/users/_edit.haml
Outdated
Import another account into | ||
= current_user.diaspora_handle | ||
%p | ||
diaspora* allows you to merge an account into another, even if the accounts are in two different pods. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll have to come back to this text block. Do remind me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggested some modified texts here, for discussion: https://discourse.diasporafoundation.org/t/backup-and-restore-account-migration/544/173
%label Select the data archive: | ||
= f.file_field :export, accept: "application/json, application/zip, application/gzip" | ||
.col-md-6 | ||
%label Select the photos archive: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'photo archive'
%label Select the photos archive: | ||
= f.file_field :exported_photos_file, accept: "application/zip" | ||
%h4 | ||
The original account will be imported |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You data will be imported %strong and the original account deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be transferred to config/locales/diaspora/en.yml
. Also, I still think it's better not to repeat 'the original account' in this line, so change the first one to 'Your data will be imported'.
And maybe add 'This cannot be undone.' after this sentence?
app/views/users/_edit.haml
Outdated
%h3= t(".export_data") | ||
%p If you want to migrate this account to another pod, start by exporting your data and photos using the buttons below. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line is too long. [127/120]
@@ -0,0 +1,15 @@ | |||
const profileFileBtn = document.getElementById('profile-file-btn'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strings must use doublequote.
@@ -0,0 +1,15 @@ | |||
const profileFileBtn = document.getElementById('profile-file-btn'); | |||
|
|||
const profileFileChosen = document.getElementById('profile-file-chosen'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strings must use doublequote.
|
||
const profileFileChosen = document.getElementById('profile-file-chosen'); | ||
|
||
profileFileBtn.addEventListener('change', function(){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Strings must use doublequote.
- Missing space before opening brace.
const profileFileChosen = document.getElementById('profile-file-chosen'); | ||
|
||
profileFileBtn.addEventListener('change', function(){ | ||
profileFileChosen.textContent = this.files[0].name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing semicolon.
|
||
profileFileBtn.addEventListener('change', function(){ | ||
profileFileChosen.textContent = this.files[0].name | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing semicolon.
.upload-btn-wrapper | ||
.btn.btn-primary | ||
Select profile archive | ||
= f.file_field :export, accept: "application/json, application/zip, application/gzip", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.
.upload-btn-wrapper | ||
.btn.btn-primary | ||
Select photo archive | ||
= f.file_field :exported_photos_file, accept: "application/zip", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Layout/SpaceAfterColon: Space missing after colon.
- Style/StringLiterals: Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.
app/assets/stylesheets/forms.scss
Outdated
display: inline-block; | ||
} | ||
|
||
.upload-btn-wrapper input[type=file] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Merge rule
.upload-btn-wrapper input[type=file]
with rule on line 21 - Avoid qualifying attribute selectors with an element.
app/assets/stylesheets/forms.scss
Outdated
@@ -18,6 +18,20 @@ textarea { | |||
} | |||
// scss-lint:enable QualifyingElement | |||
|
|||
.upload-btn-wrapper { | |||
position: relative; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Properties should be ordered display, overflow, position
app/assets/stylesheets/forms.scss
Outdated
|
||
.upload-btn-wrapper input[type=file] { | ||
font-size: 100px; | ||
position: absolute; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Properties should be ordered font-size, left, opacity, position, top
lib/archive_importer.rb
Outdated
@@ -36,7 +36,8 @@ def create_user(attr) | |||
profile_attributes: profile_attributes | |||
} | |||
) | |||
self.user = User.build(data) | |||
self.user = User.find_or_build(data) | |||
self.user.getting_started = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/RedundantSelf: Redundant self
detected.
overflow: hidden; | ||
position: relative; | ||
|
||
input[type=file] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid qualifying attribute selectors with an element.
09c7b0d
to
a144219
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. I can only comment on the wording (and the fact that all the text needs to be in config/locales/diaspora/en.yml
.
Fla has said in this Discourse comment that the text is not that accurate, so we might have to rewrite some of it. But with the two minor changes I've just suggested, I think it reads well enough and is clear enough, even if some of it is not yet accurate!
config/locales/diaspora/en.yml
Outdated
list3: "All your aspects and contacts from that account will be added to this account" | ||
list4: "All posts and comments from that account will be added to this account" | ||
closing_text: "The imported account and all its linked data will be deleted from the previous pod.<br> | ||
Your contacts do not need to do anything; they will automatically be connected to this account.<br> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would not have the rest of this text in bold – only 'The imported account and all its linked data will be deleted from the previous pod.'
I also suggest separating this text block into three strings, one for each paragraph, rather than using <br>
, which I think is not favoured.
%label Select the photos archive: | ||
= f.file_field :exported_photos_file, accept: "application/zip" | ||
%h4 | ||
The original account will be imported |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be transferred to config/locales/diaspora/en.yml
. Also, I still think it's better not to repeat 'the original account' in this line, so change the first one to 'Your data will be imported'.
And maybe add 'This cannot be undone.' after this sentence?
Hey, could you please make the rake test to fail when it doesn't find the archive? |
.clearfix | ||
.btn.btn-default{data: {dismiss: "modal"}} | ||
= t("users.import_modal.cancel") | ||
= f.submit t("users.import_modal.start_import"), class: "btn btn-primary.pull-right", id: "change_email_preferences" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Line is too long. [132/120]
|
||
profileFileButton.addEventListener("change", function() { | ||
profileFileChosen.textContent = this.files[0].name; | ||
checkProfileUploadButton(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'checkProfileUploadButton' was used before it was defined
|
||
photosFileButton.addEventListener("change", function() { | ||
photosFileChosen.textContent = this.files[0].name; | ||
checkProfileUploadButton(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'checkProfileUploadButton' was used before it was defined
}); | ||
|
||
const checkProfileUploadButton = function() { | ||
let photo_files = $("#profile-file-btn")[0].files; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Identifier 'photo_files' is not in camel case.
|
||
const checkProfileUploadButton = function() { | ||
let photo_files = $("#profile-file-btn")[0].files; | ||
let profile_files = $("#photos-file-btn")[0].files; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Identifier 'profile_files' is not in camel case.
let photo_files = $("#profile-file-btn")[0].files; | ||
let profile_files = $("#photos-file-btn")[0].files; | ||
|
||
if ((photo_files.size + profile_files.size) === 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Opening curly brace does not appear on the same line as controlling statement.
- Identifier 'photo_files' is not in camel case.
- Identifier 'profile_files' is not in camel case.
|
||
if ((photo_files.size + profile_files.size) === 0) | ||
{ | ||
$("#upload_profile_files").attr('disabled', 'disabled'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strings must use doublequote.
{ | ||
$("#upload_profile_files").attr('disabled', 'disabled'); | ||
} else { | ||
$("#upload_profile_files").removeAttr('disabled'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strings must use doublequote.
$("#upload_profile_files").removeAttr('disabled'); | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Block must not be padded by blank lines.
- Missing semicolon.
e1c57ca
to
f4a3e09
Compare
The datamodel and implementation supports multiple imports from different locations This Commit removes a test and fixes the validation, which is not supported in the datamodel
- Updates (most) texts to goobs proposal - Moved texts to localization file - Fixed file-upload buttons
f4a3e09
to
5255767
Compare
Hey @tclaus could you please extract the rake refactor and the photos import (basically everything only linked to the backend) in a smaller pull request? This would allow me to start doing more tests even if the UI isn't ready yet |
So, I tried the UI locally and it didn't work, the validation took too much time and the HTTP connection "has been reinitialized" (says Firefox). I think we need to split this again. Maybe we could have a different setting page so it's actually easier to find (and to link to) for the user? |
An extra menu is nice. |
But what happens for you when you click the button in the modal then? For me, it does launch the validation, but the modal stays open waiting for it to finish, and with real data, that takes too much time and the http connection expires. |
If you run diaspora locally in dev-mode there is no sidekiq by default (the jobs happen in the request then, which works for most things needed for dev-mode), for certain things like migration (takes too long for being handled in request) and also federation with other local pods (with only 1 unicorn worker that is already busy handling the federation job it doesn't have another worker free to handle a webfinger request from a second pod, so it deadlocks), you need a sidekiq, so you need to enable that in the |
Ok, I was able to enable sidekiq by setting If you like the idea of having all this on a separated page I can create it. |
…_files # Conflicts: # app/controllers/users_controller.rb # app/models/photo.rb # app/models/user.rb # app/services/migration_service.rb # app/uploaders/exported_photos.rb # app/uploaders/exported_user.rb # app/uploaders/secure_uploader.rb # lib/archive_importer.rb # lib/tasks/accounts.rake # spec/models/user_spec.rb
On profile file upload the same fields in the user table are used than for generated exporting files. This conflicts if any export files exists and user wants to import something
app/controllers/users_controller.rb
Outdated
@@ -122,6 +122,10 @@ def confirm_email | |||
redirect_to edit_user_path | |||
end | |||
|
|||
def has_import_parameter?(import_parameters) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming/PredicateName: Rename has_import_parameter?
to import_parameter?
.
app/controllers/users_controller.rb
Outdated
|
||
def copy_import_files(user_data) | ||
{ | ||
profile_path: copy_import_file(user_data[:export]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/FirstHashElementIndentation: Use 2 spaces for indentation in a hash, relative to the start of the line where the left curly brace is.
app/controllers/users_controller.rb
Outdated
def copy_import_files(user_data) | ||
{ | ||
profile_path: copy_import_file(user_data[:export]), | ||
photos_path: copy_import_file(user_data[:exported_photos_file]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Layout/HashAlignment: Align the keys and values of a hash literal if they span more than one line.
app/controllers/users_controller.rb
Outdated
end | ||
|
||
def copy_import_file(tmp_file) | ||
if tmp_file.present? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/GuardClause: Use a guard clause (return unless tmp_file.present?
) instead of wrapping the code inside a conditional expression.
app/controllers/users_controller.rb
Outdated
|
||
def copy_import_file(tmp_file) | ||
if tmp_file.present? | ||
file_path_to_save_to = Rails.root.join("public","uploads", "users", "#{current_user.username}_#{tmp_file.original_filename}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Layout/SpaceAfterComma: Space missing after comma.
- Layout/LineLength: Line is too long. [131/120]
app/services/import_service.rb
Outdated
# @param [*String] files | ||
def remove_import_files(*files) | ||
files.each do |file| | ||
if file && File.exist?(file) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/IfUnlessModifier: Favor modifier if
usage when having a single-line body. Another good alternative is the usage of control flow &&
/||
.
app/services/import_service.rb
Outdated
def remove_import_files(*files) | ||
files.each do |file| | ||
if file && File.exist?(file) | ||
File.delete(file) rescue nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/RescueModifier: Avoid using rescue
in its modifier form.
I merged latest development into it to fix merge errors. There might be a problem when uploading a json.gz - when unzipped, the resulting file is just a messed up binary. Can someone check this? |
This may be an issue with the development environment, I've seen something like that happened while downloading the archive on the dev env. |
Oh yes, if you download the file in the dev env, it is gzipped twice, because rails again gzips it on download, while in production it will be served by your reverse proxy which doesn't do stuff like that. |
Good to be on a team that can help. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So apart from my comments, a few thoughts:
- This PR doesn't add new tests, do we want to add tests here, or we don't consider tests mandatory for everything?
- Do we want to give podmins a configuration option to hide/show import functionality? Is there a reason why a podmin may want to turn off this feature on their pods?
- Could we combine the two archives -- profile and photos -- in one? We can reduce potential issues if we just needed to upload one file.
app/views/users/_edit.haml
Outdated
= t(".import.warning") | ||
.form-group | ||
.btn.btn-primary{id: "import_account", data: {toggle: "modal", target: "#importAccountModal"}} | ||
Import another account... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this needs to be translatable -- wrap into t
method call
app/controllers/users_controller.rb
Outdated
end | ||
|
||
def copy_import_file(tmp_file) | ||
return if tmp_file.empty? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you need to use blank?
here instead
return if tmp_file.empty? | |
return if tmp_file.blank? |
@@ -122,6 +122,10 @@ def confirm_email | |||
redirect_to edit_user_path | |||
end | |||
|
|||
def import_parameter?(import_parameters) | |||
import_parameters[:profile_path] || import_parameters[:photos_path] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we support importing just photos without the profile?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A user could first import his/her account and in another step the photos. These files are huge, that to separate them still makes sense.
After the profile is imported the user could import the photos.
I wouldn't put these files into on (very) big file.
app/services/import_service.rb
Outdated
if path_to_photos.present? | ||
logger.info("Importing photos from import file for '#{username}' from #{path_to_photos}") | ||
import_user_photos(user, path_to_photos) | ||
end | ||
remove_file_references(user) | ||
remove_import_files(path_to_profile, path_to_photos) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cleaning up invalid data -- if the archive is in wrong format. If we don't clean up, then someone could abuse the pod by uploading invalid archives indefinitely.
I guess we could handle at least certain known errors when the archive import fails, and clean up the files. But not in every case, because in some cases we may want to retry the import.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean? The 'import_user_profile' and 'import_user_photos' handle (known) errors. Whenever execution comes here, the uploaded files (I guess the zipped ones) will be removed.
Could you describe your idea or give a suggestion?
app/services/import_service.rb
Outdated
end | ||
|
||
def import_by_files(path_to_profile, path_to_photos, username, opts={}) | ||
user = User.find_by(username: username) | ||
raise ArgumentError, "Username #{username} should exist before uploading photos." if user.nil? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think raising exception from the sidekiq job would schedule this job to retry. If this error is irrecoverable we should instead finish the job without errors, possibly logging some error messages.
app/workers/import_user.rb
Outdated
user = User.find(user_id) | ||
ImportService.new.import_by_user(user) | ||
ImportService.new.import_by_user(user.username, import_parameters) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we have a user object, and then we get it's username
just to look up the user again inside the ImportService
. Maybe we can still pass the user object here?
Instead of changing this signature to username, maybe we could change import_by_files
to accepting user object and in the rake task we could call import_by_files
passing the user
object that we find outside of the service?
@@ -17,6 +17,7 @@ def substitute_author | |||
|
|||
entity_data["photos"].each do |photo| | |||
photo["entity_data"]["author"] = user.diaspora_handle | |||
photo["entity_data"]["remote_photo_path"] = "#{AppConfig.pod_uri}uploads\/images\/" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, so this is how we link uploaded photos. If there are files in the photos archive that weren't in the end linked to any photo record, should we detect and clean them up?
app/services/import_service.rb
Outdated
end | ||
|
||
private | ||
def import_profile_if_present(opts, path_to_photos, path_to_profile, username) | ||
if path_to_profile.present? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style/GuardClause: Use a guard clause (return unless path_to_profile.present?
) instead of wrapping the code inside a conditional expression.
cd1cfa3
to
2e7dbb5
Compare
Currently a import from Settings, while a user already exists.
ToDo: