Skip to content
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

ERROR: personalQuotaReached1 #48

Open
Amniotic3 opened this issue Dec 15, 2024 · 2 comments
Open

ERROR: personalQuotaReached1 #48

Amniotic3 opened this issue Dec 15, 2024 · 2 comments

Comments

@Amniotic3
Copy link

Look this log

(3)(+0000000): HTTP POST http://192.168.1.76:8080/users/1/items/SHYX95XB/file succeeded with 413

(3)(+0000000): File would exceed quota (391.2 > 300)

(3)(+0000000): [ConcurrentCaller] Done with function (0/4 running, 0 queued)

(3)(+0000001): [ConcurrentCaller] All tasks are done

(1)(+0000001): Upload request 1/SHYX95XB failed

(1)(+0000000): Error: 您的 Zotero 文件存储配额已经达到,有些文件将不能上传。Zotero 的其他数据将继续同步到 Zotero 服务器。 在 zotero.org 的帐户设置里查看更多的存储选项。 .pdf (116437 KB) Zotero Error: 您的 Zotero 文件存储配额已经达到,有些文件将不能上传。Zotero 的其他数据将继续同步到 Zotero 服务器。 在 zotero.org 的帐户设置里查看更多的存储选项。 .pdf (116437 KB) (No stack trace) From previous event: runFunc@resource://zotero/concurrentCaller.js:224:27 ConcurrentCaller.prototype._processNext@resource://zotero/concurrentCaller.js:265:3 ConcurrentCaller.prototype.start@resource://zotero/concurrentCaller.js:156:17 serial/<@chrome://zotero/content/xpcom/utilities_internal.js:1779:21 ZoteroPane</this.sync@chrome://zotero/content/zoteroPane.js:2766:26 oncommand@chrome://zotero/content/zoteroPane.xhtml:1:12 reportErrors@chrome://zotero/content/zoteroPane.js:6017:18 oncommand@chrome://zotero/content/zoteroPane.xhtml:1:18

Find the corresponding language translation error mapping as personalQuotaReached1 and find the error throwing function as _getQuotaError.

https://github.com/uniuuu/zotero/blob/54cee37703787ecb3e6d35ca1ea1dd739c33fb36/chrome/content/zotero/xpcom/storage/zfs.js#L634

The Zotero-Storage-Quota assignment comes from the getEffectiveUserQuota function, keep tracking and the assignment function comes from the getUserValues function.

Ok, found the answer.

https://github.com/uniuuu/dataserver/blob/31c5db7d5ab853399062af273e7042b6ef7111e8/model/Storage.inc.php#L798

public static $defaultQuota = 300;

	/**
	 * Get quota and expiration date for a user
	 */
	public static function getUserValues($userID) {
		$sql = “SELECT quota, UNIX_TIMESTAMP(expiration) AS expiration FROM storageAccounts WHERE userID=?” ;
		return Zotero_DB::rowQuery($sql, $userID);
	}
	
	public static function getInstitutionalUserQuota($userID) {
		// TODO: config
		$dev = Z_ENV_TESTING_SITE ? "_dev" : "";
		$databaseName = "zotero_www{$dev}";
		
		// Get maximum institutional quota by e-mail domain
		$sql = "SELECT IFNULL(MAX(storageQuota), 0) FROM $databaseName.users_email "
			. "JOIN $databaseName.storage_institutions "
			. "ON (domain != '' "
				// Domain is treated as a fully matching regexp with an implied optional
				// subdomain prefix. 'mail.school.edu' will match 'school.edu' or
				// '(school.edu|school.org)', but 'abcd.edu' won't match 'bcd.edu'.
				. "AND SUBSTRING_INDEX(email, '@', -1) REGEXP CONCAT('^(.+\\\.)?', domain, '$')"
				// Email doesn't match blacklist if one exists for domain
				. "AND (domainBlacklist = '' "
					. "OR SUBSTRING_INDEX(email, '@', -1) NOT REGEXP domainBlacklist)"
			. ") WHERE userID=?";
		try {
			$institutionalDomainQuota = Zotero_WWW_DB_2::valueQuery($sql, $userID);
		}
		catch (Exception $e) {
			Z_Core::logError("WARNING: $e -- retrying on primary");
			$institutionalDomainQuota = Zotero_WWW_DB_1::valueQuery($sql, $userID);
		}
		
		// Get maximum institutional quota by e-mail address
		$sql = "SELECT IFNULL(MAX(storageQuota), 0) FROM $databaseName.users_email
				JOIN $databaseName.storage_institution_email USING (email)
				JOIN $databaseName.storage_institutions USING (institutionID)
				WHERE userID=?";
		try {
			$institutionalEmailQuota = Zotero_WWW_DB_2::valueQuery($sql, $userID);
		}
		catch (Exception $e) {
			Z_Core::logError("WARNING: $e -- retrying on primary");
			$institutionalEmailQuota = Zotero_WWW_DB_1::valueQuery($sql, $userID);
		}
		
		$quota = max($institutionalDomainQuota, $institutionalEmailQuota);
		return $quota ? $quota : false;
	}

	public static function getEffectiveUserQuota($userID) {
		$cacheKey = "userStorageQuota_" . $userID;
		
		$quota = Z_Core::$MC->get($cacheKey);
		if ($quota) {
			return $quota;
		}
		
		$personalQuota = self::getUserValues($userID);
		if ($personalQuota && $personalQuota['expiration'] < time()) {
			$personalQuota = false;
		}
		$personalQuota = $personalQuota ? $personalQuota['quota'] : 0;
		
		$instQuota = self::getInstitutionalUserQuota($userID);
		if (!$instQuota) {
			$instQuota = 0;
		}
		
		$quota = max($personalQuota, $instQuota);
		$quota = $quota ? $quota : self::$defaultQuota;
		
		Z_Core::$MC->set($cacheKey, $quota, 60);
		
		return $quota;
	}
@Amniotic3
Copy link
Author

I went and queried the database and the zotero_master.storageAccounts table is empty, the corresponding fields have to be referenced in the code.

In case of admin user, the solution is to change [email protected] to [email protected] in the first line of data in zotero_www.storage_institution_email.

Correspondingly, this should count as a data import error during initialization:

@uniuuu

echo "INSERT INTO storage_institution_email (institutionID, email) VALUES (1, '[email protected]')" | $MYSQL zotero_www

echo “INSERT INTO storage_institution_email (institutionID, email) VALUES (1, ‘[email protected]’)” | $MYSQL zotero_www

echo “INSERT INTO storage_institution_email (institutionID, email) VALUES (1, ‘[email protected]’)” | $MYSQL zotero_www

All in all, there should still be a lack of a front-end UI for management 😄

bin/create-user.sh

Maybe this shell needs some modification too.

@Amniotic3
Copy link
Author

In the getUserValues function, when the system cannot find the user's quota or expiration data, it ultimately assigns a default value of 300 MB. Here's a description of how that happens:

  1. The getUserValues function queries the database for the user's storage quota and expiration date.
  2. If no matching record is found in the database (i.e., no quota or expiration is returned), the function will return null or false for the personalQuota.
  3. The getEffectiveUserQuota function checks the validity of the personalQuota:
    • If the personalQuota is not found or has expired (i.e., the expiration date is earlier than the current time), the function sets personalQuota to 0.
  4. The function then checks if an institutional quota (instQuota) exists. If not, it sets instQuota to 0.
  5. After comparing the personal and institutional quotas, the function sets the effective quota to the larger of the two. If both are 0, it assigns the default quota value, which is 300 MB (as defined by the static variable $defaultQuota).

Thus, when no quota data is available for a user (either personal or institutional), the function ensures that the user is assigned the default quota of 300 MB.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant