We created a synchronizer plugin for discourse and it should synchronize backups to the google drive service account.
In order to keep the admin's google drive account clutterfree, we built a method at the end of the synchronizer, that is called remove_old_files
def remove_old_files
google_files = session.files
sorted = google_files.sort_by {|x| x.created_time}
keep = sorted.take(SiteSetting.discourse_sync_to_googledrive_quantity)
trash = google_files - keep
trash.each { |d| d.delete(true) }
end
we memoized the session object before in an instance variable. So with session.files we get an array of all the files in our google drive account. In the sorted variable we sort them from new to old. In the keep variable we take the first few (the admin hat to set the quantity) and in the trash variable we define the rest. Until here the method works in the console.
Now in the documentation for the Google Drive gem there is a delete method for the File object:
File 'lib/google_drive/file.rb', line 182
def delete(permanent = false)
if permanent
#session.drive.delete_file(id)
else
#session.drive.update_file(id, { trashed: true }, {})
end
nil
end
But when I try to delete via the rails console, it tells me Success - nil as if everything went fine. But ! the files are still there when I count them or call them. Even though I tried to delete them setting permanent = true :/
Why doesn't google delete the old backup files?
Related
My google drive storage is running out of space. So, in order to free some space, I created a new google account and transferred the ownership of one of the largest folders in my original drive (~7 GB) to the new account's drive.
The problem is, that after 3 days of waiting, the folder is still consuming the storage of the original account's drive. I made sure that the new account is the owner of the folder, but the problem is still there.
Any ideas?
The problem is that changing the ownership of folder inside google drive does not change it for the subfolders and files, you have to change them separately or write an app script to search for file and subfolders owned by you and change the ownership.
Run the script below as your account, if you are using Google Workspace and you are the admin and need to do it to other accounts, then you need to get a service account first and run the code below.
Note:
This way makes a lot of noise with notifications on both sides, the old owner and the new one.
function ChangeFileOwnership(folder){
// New owner
var new_owner = '<Add new owner email>';
if (folder == null) {
var folderObj = DriveApp.getFolderById('<ID of parent folder>');
return ChangeFileOwnership(folderObj);
}
var fileIt = folder.searchFiles('"me" in owners');
while (fileIt.hasNext()) {
var file = fileIt.next();
Logger.log("Changing ownership of " + file.getName() + " to " + new_owner);
// Set the owner to be the new owner
try {
file.addEditor(new_owner);
}
catch(err){
Logger.log(err.message);
}
try {
file.setOwner(new_owner);
}
catch(err){
Logger.log(err.message);
}
}
// Get all the sub-folders and iterate
var folderIt = folder.getFolders();
while (folderIt.hasNext()) {
fs = ChangeFileOwnership(folderIt.next());
}
}
I tried to create InboundShipment.
client.create_inbound_shipment(id, inbound_shipment_header, inbound_shipment_items)
id is shipplan id created by Shipplan.
inbound_shipment_header = {:shipment_name=>"kum_03_01_2019_AVP1", :ship_from_address=>{:name=>"xxxx", :address_line1=>"xxxx", :address_line2=>"", :city=>"xxxx", :state_or_province_code=>"XX", :postal_code=>"xxxx", :country_code=>"xxxx"}, :destination_fulfillment_center_id=>"AVP1", :label_prep_preference=>"SELLER_LABEL", :are_cases_required=>false, :shipment_status=>"WORKING", :intended_box_contents_source=>"2D_BARCODE"}
inbound_shipment_items = [{:seller_sku=>"SKU", :quantity=>25, :prep_details=>[{:prep_instruction=>"Labeling", :prep_owner=>"SELLER"}]}]
But it return error following as.
#<Peddler::Errors::InvalidRequestException: Error: You must include a valid ShipmentId with a call to the CreateInboundShipment operation. Get ShipmentId values by calling the CreateInboundShipmentPlan operation. The request to CreateInboundShipment must include only items and quantities that have been previously planned through CreateInboundShipmentPlan. If a ShipmentId is not used to create a shipment within 48 hours it will expire.>
When I tried this on MWS scratch pad, it's working normally.
What's the solution to create the Inbound Shipment on RubyOnRails?
I just solved the issue.
There was an mistake when write the inbound_shipment_item.
inbound_shipment_item should be following as.
inbound_shipment_items = [{:seller_sku=>"SKU", :quantity_shipped=>25, :prep_details=>[{:prep_instruction=>"Labeling", :prep_owner=>"SELLER"}]}]
I'm using https://github.com/Azure/azure-sdk-for-ruby in my Rails application. I need to set the container policy but I don't know how to create a Signed Identifier instance for the set_container_acl method.
The comments say to pass in an array of "Azure::Entity::SignedIdentifier instances" but when I try to create an instance I get "uninitialized constant Azure::Storage::Entity". Scoured the net/documentation can't find anything about it.
After digging around in the azure gem files I was able to find a signed identifier file in the service directory. It's not loaded with azure for some reason so you have to require it.
require 'azure'
require 'azure/service/signed_identifier'
def some_method
# Some code here. Create blobs instance.
# blobs = Azure::Blob::BlobService.new
sas = Azure::Service::SignedIdentifier.new
sas.id = identifier
policy = sas.access_policy
policy.start = (Time.now - 5 * 60).utc.iso8601
policy.expiry = (Time.now + 1.years).utc.iso8601
policy.permission = "r"
identifiers = [sas]
options = { timeout: 60, signed_identifiers: identifiers }
container, signed = blobs.set_container_acl(container_name, "", options)
end
In a normal test using human and browser, everything is work as expected. However, when I use rspec, I can see that I have:
D, [2014-08-16T13:48:09.510013 #19418] DEBUG -- : SQL (0.6ms) UPDATE "system_flights_cacheds" SET "client_stuff" = '{"captcha":"656556"}' WHERE "system_flights_cacheds"."guid" = '5647046e-4194-498e-a0d7-512614b147d8'
But I cannot believe that actually my database record is not updated. Previously I used .save, but with no success in fact it creates SAVEPOINT.
My code in trouble is basically an API endpoint:
cache = System::Flights::Cached.search_cache options
# update database, when the captcha is present. this way, the worker
# when updating the database can see the changes and act accordingly!
if cache && params[:captcha]
# remember, anyone can (basically) see the captcha. thus,
# this is a bit paranoid, only allow captcha update
# if the user is same! in the json, if not forgotten,
# captcha is only displayed when the user_id is equal
server_stuff = cache.server_stuff.with_indifferent_access
if server_stuff[:user_id] == current_user.id
cache.time_renewed = 10
cache.client_stuff_will_change!
cache.client_stuff ||= {}
cache.client_stuff[:captcha] = params[:captcha]
# cache.save!
cache.update_columns(client_stuff: cache.client_stuff)
end
else
# only spawn worker if there is no captcha parameter passed
spawn_search_worker({user_id: current_user.id, options: options})
end
The client can reach this anytime and it will span worker. When a new record is already in database but is_processed is false, the worker will quit. Thus, calling this multiple times will be ok as also be a means to check status if the work is done or not.
The worker will wait the client to enter for a captcha. So, we have class like WaitableLogin, that do basically:
max_repeat = 3 # 14
# annul flag, if set to true, the data will not get persisted.
annul = false
while max_repeat > 0
# interval of 5 secs that worker can check the database
sleep 5
max_repeat -= 1
# break if captcha already entered by client
# seek from the database if the client has posted
# the captcha text
cache = System::Flights::Cached.search_cache options
client_stuff = nil
client_stuff = cache.client_stuff.with_indifferent_access if cache && cache.client_stuff
if client_stuff && client_stuff[:captcha]
captcha_text = client_stuff[:captcha]
airline.fill_captcha(captcha_text).finalize_login
puts "SOMEHOW I AM HERE: #{captcha_text}"
# remove all server's stuff
cache.server_stuff_will_change!
cache.server_stuff.clear
cache.save!
annul = airline.in_login_page?
end
end
So, WaitableLogin will check if the client_stuff is updated. If it is, then we know that client has submitted the captcha (through the Endpoint, the worker will check if captcha is a param and will update the database if there's captcha field).
The control then transferred back to the Worker. You can see that there's a lot of code that use cache at many parts of the codes across files, cache is just variable name nothing to do with its semantic meaning in Rails or whatever.
When I run normally on browser, I don't see any problem. In fact, no SAVEPOINT even if I use .save. I thought, it is creating some bug somewhere with that SAVEPOINT so I decided to try using .update_columns. But, again, with no success.
This is what the test looks like
before(:each) do
System::Flights::Cached.delete_all
end
describe "requests" do
it "should process 2a1c1i" do
cached = nil
post("/api/v1/x.json", {
access_token: CommonFlightData::ACCESS_TOKEN,
business_token: CommonFlightData::BUSINESS_TOKEN,
captcha: ""
}.merge!(CommonFlightData.oneway_1a(from: "8-9-2014")))
puts "enter the captcha: "
captcha = STDIN.gets.chomp
puts "Entered: #{captcha}"
post("/api/v1/x.json", {
access_token: CommonFlightData::ACCESS_TOKEN,
business_token: CommonFlightData::BUSINESS_TOKEN,
captcha: captcha
}.merge!(CommonFlightData.oneway_1a(from: "8-9-2014")))
sleep 10
SO what am I missing at, I tired. No error raised. When I check .inspect after update_columns, it seems all is updated. But, when you see at the database, nothing is updated.
EDIT: I put lock_version so that I have optimistic locking (by default, I think). And turn out, as expected, it was set to 2.
EDIT 2: If I command an edit from a rails console at the time when the code asking for captcha, IT UPDATES the data. SO, why the RSpec spec that run the api endpoint to submit a captcha won't update the row. All real-life no spec-in-origin code is finely executed.
I'm trying to upload a new product to mws with the mws api and mws gem
The product is added (like Fix failed listings, because, doen't have a quantity and price)
I'm trying with the next code:
mws = Mws.connect(
merchant: 'merchant',
access: 'access',
secret: 'secret'
)
Later:
product = Mws::Product('11333663') { upc '1234355462233' tax_code
'GEN_TAX_CODE' name 'Some Pduct 034' brand 'Some Bnd' msrp 18.9,
'USD' quantity 10 manufacturer 'Some Mufacturer' category :ce
details {
cable_or_adapter {
cable_length as_distance 5, :feet
} } }
later:
submission_id = mws.feeds.products.add(product)
The product is added, but when I excuted this line:
submission_id = mws.feeds.products.update(product)
The next message is displayed:
=> #<Mws::Apis::Feeds::SubmissionResult:0x9d9ae78 #transaction_id="12345678", #status=#<Mws::EnumEntry:0x9d96170
#sym=:complete, #val="Complete">, #messages_processed=0,
#counts={:success=>0, :error=>1, :warning=>0},
#responses={:"0"=>#, #code=90208, #description="Purge
and replace is not allowed for this feed type.">}>
2.0.0-p195 :050 > result = mws.feeds.get(submission_id.id)
=> #, #messages_processed=1,
#counts={:success=>0, :error=>1, :warning=>0},
#responses={:"0"=>#, #code=90000,
#description="http://sellercentral.amazon.com/myi/search/ErrorListingsSummary?batchId=7564766086">,
:"1"=>#, #code=99042, #description="A
value was not provided for \"item_type\". Please provide a value for
\"item_type\". Please use the Product Classifier or download the
category-specific Browse Tree Guide from Seller Help to see a list of
valid \"item_type\" values. This information tells Amazon where your
product should be classified and affects how easily customers can find
your product.", #additional_info={:sku=>"11333668"}>}>
But, when I tried update the inventory and the price, the follow error ocurred:
result = mws.feeds.get(price_submission_id.id) =>
#sym=:complete, #val="Complete">, #messages_processed=0,
#counts={:success=>0, :error=>1, :warning=>0},
#responses={:"0"=>#, #code=90208, #description="Purge
and replace is not allowed for this feed type.">}>
What can I do?
Without any indepth knowledge of that Ruby Gem (and of Ruby), I can probably still point you in the right direction:
In MWS, feeds automatically update information already in the Amazon database. The call to create a record is identical to a subsequent call to update it. That also means you don't have to keep track of which items were already added to Amazon in the past.
In terms of your Ruby library, you probably should call mws.feeds.products.add(product) for subsequent updates of that product record and not call mws.feeds.products.update(product) at all. The latter seems to create what's called PurgeAndReplace feeds in MWS which you should avoid like the plague.
All other errors you encountered seem to be related to the same root cause.